Skip to content
Updated Jun 9, 2026

Policies & Coverage

A Policy is the master insurance contract between the insurer and an Account (an employer group or an individual). This page covers the enrollment domain: the quote-to-cancellation lifecycle and the effective-dated versioning model that lets coverage change over time without losing history.

Field reference: exhaustive columns, types and nullability for every entity here live in the catalog: glossary terms Policy, PolicyTerm, PolicyElement, PolicyTransaction, Quote, Product, ProductVersion, Coverage, MemberCoverage. This page is the narrative.

Who owns what

ConceptOwning service
Policy, PolicyTerm, PolicyElement, PolicyTransaction, Quote, UnderwritingFlagenrollment
Product, ProductVersionpolicy-admin
Coverage (abstract), MemberCoverage (read-model)eligibility

Policy lifecycle

A policy begins as a Quote (a priced proposal). Once accepted and underwritten, the quote converts to an active Policy. The policy accrues a PolicyTerm for each coverage period as it renews. At any point it can be endorsed (changed mid-term), lapsed for non-payment, or cancelled.

StatusMeaning
ACTIVECoverage is in force; claims are adjudicable.
LAPSEDPremium unpaid beyond the grace period; coverage suspended, new claims rejected; reinstatement possible.
CANCELLEDIrrevocably terminated.
EXPIREDTerm ended and renewal was not completed.

The effective-dated versioning model

Olly follows a Socotra-style effective-dated model, the core of the enrollment domain: changes do not mutate records in place; they create new versions.

  • PolicyTerm is the coverage period and the adjudication anchor. Accumulators, ClaimLines and MemberCoverage are all scoped to a term, and adjudication resolves benefits against the term in force on the claim's incident date. A renewal opens a new term, not a new policy.
  • PolicyElement is one insured unit within a term (an employee or a dependant; element_type is employee | dependent). An endorsement (adding a dependant, changing a benefit) does not edit the element; it writes a new version (a new row) carrying the same static_id.
  • static_id is the continuity key. It is stable across an element's versions, so accumulators (deductible / out-of-pocket spend) and ClaimLine.elementId resolve continuously even as the element is re-versioned mid-term.
  • PolicyTransaction is the unit of change that produces those versions: issuance, renewal, endorsement, cancellation, reinstatement, reversal. Unlike the quote audit trail, a transaction is not immutable; it carries a mutable status (default DRAFT) and progresses through states. Its effective_date controls when the change takes economic effect, which may differ from the processing date.

Statuses and categories are conventions, not enforced enums

PolicyTransaction.category / .status and PolicyTerm.status / PolicyElement.status are free TEXT with no DB CHECK and no Go enum. The value sets below are documented conventions the services apply, not constraints the database rejects bad values against.

PolicyTransaction.categoryWhenTypical status progression
ISSUANCEPolicy first boundDRAFT → PRICED → UNDERWRITTEN → APPLIED
RENEWALTerm rolloverDRAFT → PRICED → APPLIED
ENDORSEMENTMid-term changeDRAFT → PRICED → APPLIED
CANCELLATIONPolicy terminatedDRAFT → APPLIED
REINSTATEMENTLapsed policy restoredDRAFT → APPLIED
REVERSALCorrects a prior transactionDRAFT → REVERSED

Quote → policy issuance

  • Quote holds a status, a pinned ProductVersion, and a document JSONB blob with the rated premium, benefit schedule and applicant data.
  • QuoteEvent is an append-only audit trail of status changes on the quote.
  • UnderwritingFlag records an individual underwriter decision applied to a quote; multiple can coexist and the strictest wins.
  • Policy is created when the quote is accepted and the first premium is collected; Policy.quoteId links back to the originating quote.

Product and ProductVersion

A Product (owned by policy-admin) is the plan definition (e.g. "Olly Select PMI"). Its status is ACTIVE | INACTIVE only (a real DB CHECK; there is no DRAFT/RETIRED). The versioned benefit schema lives on ProductVersion (status DRAFT → PUBLISHED, immutable once published). Quotes and Policies pin a ProductVersion so their benefit schedule stays stable as the parent product evolves.

Coverage vs MemberCoverage

Coverage is the abstract entitlement (FHIR/FIBO-aligned). It is realised at runtime as MemberCoverage rows in the eligibility service, a denormalised projection of a member's in-force benefits, built by consuming enrollment events. Adjudication reads MemberCoverage (fast, term-scoped), not the enrollment tables directly. See Eligibility & Accumulators.

Invariants

  • A Policy belongs to exactly one Account; a PolicyTerm belongs to exactly one Policy; a PolicyElement to exactly one term.
  • static_id is stable across a PolicyElement's effective-dated versions and is the join key for continuous accumulators and for ClaimLine.elementId.
  • A PolicyElement's effective_to is null while the version is open-ended; party_id is nullable (null for non-person elements such as a coverage).
  • A Policy/Quote references a specific ProductVersion, never the mutable Product.

Caveats

  • Term vs PolicyTerm. Claims code references olly:Term, but the physical coverage-period record is PolicyTerm (enrollment.policy_terms). This naming is unreconciled; see the catalog caveats.
  • US-style benefit vocabulary. PolicyElement.coverage_terms uses copay / coinsurance / deductible / OOP-max keys; on this UK-context platform those are placeholder semantics and the real keys may differ.
  • locator (external, unique-per-DB) and id (internal UUID) are distinct identities, consistently across these entities.

Olly Health Insurance Platform