Skip to content
Updated Aug 22, 2026

Schema deep-dives

One page per core entity: what every field is and why it exists, the invariants (DB-enforced vs convention), lifecycle flows, a populated JSON example, and design determinations - with every claim carrying an inline citation pinned to the codebase. Living documents: the code link is the anchor, the page keeps up.

The purpose of the series is to document the platform's architectural flexibility and extensibility: what the model can already absorb, and where to make the change when a need arrives. The schema deliberately carries capability ahead of product maturity. Tables that are empty today are designed headroom, and each page's extension-point table (When we need ... | What to add | Where) names the trigger, the change and the surface to touch. That is a property of the design, not a shortfall.

Read them in order - the sequence builds the domain the same way the ERD story does, one concept at a time, each new entity motivated by what the previous ones cannot express.

Reading sequence

#Deep-diveTablesStatus
1Partypartiespublished
2Scheme & rosterschemes, scheme_memberspublished
3Product & catalogueproducts, product_versions, clinical_termspublished
4Quote & Policyquotes, policiespublished
5Terms, transactions & elementspolicy_terms, policy_transactions, policy_elementspublished
6Eligibility projectionmember_coverage, coverage_accumulatorspublished
7Claimclaims, claim_lines, claim_eventspublished
8Billing account & chargesaccounts, chargespublished
9Invoices, payments & ledgerinvoices, invoice_line_items, payments, ledger_entriespublished
10Providerproviderspublished
11Careepisodes, appointmentspublished
12Consent, documents & notificationsconsent_records, documents, notification_logpublished

Phase 2 - transactional depth

The twelve pages above introduce each core entity once. These eight go a layer deeper on the domains already built - the workflow tables, audit ledgers, and config that sit beside a head table. Each is best read after the Phase-1 page it extends, not in strict numeric order. Several model capability ahead of the stage that exercises it: the tables are coded and migrated, and each page names the trigger that switches them on.

#Deep-diveTablesExtends
13Prior authorizationprior_auths, claim_documentsClaim
14Billing lifecycleadjustments, installment_schedules, installment_items, autopay_preferences, quote_payments, stripe_events, reconciliation_driftsInvoices, payments & ledger
15Enrollment: dynamic fields & underwritingpolicy_field_values, quote_field_values, transaction_field_values, quote_events, underwriting_flagsTerms, transactions & elements
16Care fulfilmentprescriptions, diagnostics_referrals, provider_slots, appointment_reminders_sentCare
17Consent audit & data-subject rightsconsent_audit, deletion_requestsConsent, documents & notifications
18Provider credentialing & reviewscredentialing_requests, provider_reviewsProvider
19Scheme operationsbulk_enrollment_jobs, slack_workspaces, slack_member_linksScheme & roster
20Operational depthnotification_preferences, templates, accumulator_applicationsEligibility · Claim · Consent, docs & notifications

Phase 3 - wearable streams

A separate domain from the insurance spine above. The balance service ingests raw wearable samples and compacts them into episodes, rollups, baselines, scores and findings. These five pages read as a pipeline - each stage feeds the next

  • so read them in order, though they stand apart from the Phase-1/2 sequence. Owner throughout: the balance service (runs on dev-1; data on dev-2, schema streams). Much of the analysis layer is modelled ahead of the stage that exercises it: coded and migrated, with each page naming where it switches on.
#Deep-diveTablesStage
21Model & ingestevent_raw, sync_state, connection, deletion_lograw sample intake
22Registriesmetric, episode_type, met_activity, metric_alias, activity_aliasthe reference vocabulary
23Compaction pipelineepisode, rollup, baselineraw to derived
24Movement & shape scoresmovement_score, shape_score, shape_contributionscoring
25Findings & profilefinding, finding_evidence, insight, knowledge_gap, profile, onboarding_state, self_assessmentanalysis + member state

Companions: the ERD story (slide-per-step visual walk), the full ERD, and worked examples - a real policy · a real product.

On the product side two companion notes go deeper than a schema page should: Product catalogue: the shape for why every module carries the same keys, and What a UK product specification has to say for what a product sold in the UK must state beyond its cover.

The format

Each page follows the same contract (adapted from FHIR resource pages, in Oxide living-doc discipline, with GoCardless-style flow diagrams):

  1. Scope and usage - what the entity is for
  2. Boundaries and relationships - what it is not, and where that concern lives
  3. Structure - every field: what and why
  4. Invariants - DB-enforced vs application vs convention, stated honestly
  5. Lifecycle - states and flows (mermaid)
  6. Populated example - real-shape JSON
  7. Who references it - the locator fan-out
  8. Design determinations - numbered, linked to decision records
  9. Caveats and extensibility - honest caveats, plus an extension-point table (When we need ... | What to add | Where) for every capability not yet exercised, including how group and individual cover share the design
  10. References - every citation pinned to a commit SHA

Citations are checked mechanically rather than by eye. check-code-refs.py resolves each cited range at the pinned commit and at current main and reports anything that moved or changed, so a claim cannot quietly outlive the code it points at. The Phase-1 pages (#1-#12) pin to 8329d7b (2026-08-19); the Phase-2 and Phase-3 pages (#13-#25) pin to b61c5802 (2026-08-21), where they all resolve clean. As main advances a pin drifts by design - the check surfaces it, and it is re-read on a repin pass rather than silently re-aimed.

Pages #14, #21, #23 and #24 (billing-lifecycle, streams-overview-ingest, streams-compaction, streams-scores) were re-read and repinned to 08e65216 (2026-08-28), after the D2C billing write path landed (olly#1739) and the wearable-sync compaction trigger moved from the in-process APScheduler to a Temporal workflow run by its own worker. The rest of the series still pins as above. Sections describing unmerged branches (billing-lifecycle §3.1 and invoices-payments-ledger §10/§10.1, both ENG-454) cite plain path:line and pin when that work merges.

Olly Health Insurance Platform