canopy-medicaid Data Model
On this page
Cross-link: canopy-medicaid API Reference · Source: migrations/
Tables
| Table | Purpose |
|---|---|
|
Medicaid/CHIP application intake records. One row per application from canopy-eligibility. |
|
MAGI income records for budget-group members. Carries gross + monthly-normalized amounts, |
|
Non-MAGI eligibility factors for ABD COAs (FBR and non-FBR). |
|
FTI from IRS for Medicaid/CHIP. All access MUST be wrapped with FTI audit logging. Carries |
|
Federal Data Services Hub verification results. |
|
HIPAA-scoped clinical data. |
|
Per-individual evaluation outcomes against each Medicaid COA. Multiple COAs may apply; the CMD cascade evaluates all of them; the EE15 hierarchy picks the most advantageous. Carries |
|
CHIP-specific child enrollment records (children above Medicaid limit, below CHIP limit). |
|
PeachCare premium schedule rows. Loaded from |
|
Pathways-to-Coverage qualifying-activity log. Must demonstrate 80 hours/month. |
|
Pathways HIPP (Health Insurance Premium Payment) cost-effectiveness determinations. |
|
Signed Medicaid/CHIP determinations. |
|
Immutable determination input snapshots (T2-4). One row per determination — i.e. per member (PK = FK |
|
Per-value DEK store for crypto-shred redaction. One row per per-determination DEK: |
|
Audit trail of the CMD (Categorical Medicaid Determination) cascade evaluation path. One row per (person, evaluated COA). |
|
Transitional Medical Assistance coverage records. Created when canopy-medicaid receives a |
|
Durable applicant consent to Express Lane Eligibility. Written by the |
|
Current durable ELE snapshot per child — the 1-year flag. |
|
Append-only, SHA-256 hash-chained source-of-truth log for every ELE grant/extend/renew/lapse/revoke. |
|
Deferred source-program approvals for the consent-after-approval race. When a |
|
Change in Circumstances (CMD) lifecycle rows: |
|
FTI access audit log. Schema identical to canopy-tanf’s. ADR-014 added |
|
Retention archive table ( |
|
Per-program overpayment claims. Byte-identical schema across all five program services. |
|
One or more repayment plans per claim. |
|
Append-only ledger of recoupment events. |
|
Append-only principal corrections (signed |
|
Per-service transactional outbox (ADR-018), schema single-sourced in |
|
Per-service consumer inbox (#433 / ADR-018 amendment). |
Cross-service FKs (ADR-001 boundary)
Per ADR-001, canopy-medicaid holds no Postgres-level foreign keys to other services. DB-level FKs are intra-database only: every medicaid_application_id column references medicaid_applications(id); determination_snapshots.determination_id → medicaid_determinations(id); repayment_plans.overpayment_claim_id → overpayment_claims(id); recoupment_ledger.overpayment_claim_id → overpayment_claims(id) + repayment_plan_id → repayment_plans(id). Every other UUID column referencing a foreign service — household_id / person_id / applicant_person_id / tax_filer_person_id / spouse_person_id / child_person_id and the dependents_person_ids / pregnant_member_ids / ssi_recipient_ids UUID arrays (canopy-persons), application_id on medicaid_applications (canopy-applications), overpayment_claims.determination_id (this service’s medicaid_determinations, unconstrained for back-rebill flows) — is application-level only. Note also tanf_tma_coverage, ele_consents, ele_status, ele_grant_events, and ele_deferred_approvals deliberately have no FKs back to medicaid_applications: they’re populated by cross-program event subscribers (from canopy-tanf / canopy-snap / canopy-applications) and pre-date any Medicaid application of record.
Retention
canopy-medicaid is the most data-class-dense service in the system. It holds:
-
FTI (IRC §6103(l)(12); IRS Publication 1075) in
fti_tax_data. FTI audit access is logged tofti_audit_logper Pub 1075 §4; minimum 7-year retention applies per Pub 1075 AU-11 (ADR-004 Amendment 2), with rows aging intofti_audit_log_archiveand the ADR-014 hash chain extending across the boundary. -
HIPAA-scoped PHI in
clinical_assessments. Minimum-necessary standard enforced at the schema level — only the eligibility-relevant outcome is stored; no clinical narrative, diagnosis, or treatment plan. HIPAA 45 CFR 164.530(j) requires 6-year retention of compliance documentation; Medicaid claim records per 42 CFR 431.17 require 3-year minimum from claim closure. -
FDSH data in
fdsh_results. Retained per the CMS data-use-agreement schedule.
The longest applicable floor governs. Archive moves and FTI-expiry purges are operator-driven; ADR-016 forbids destructive migrations.
Indexes
-
idx_medicaid_applications_{application,household,status}— application list endpoints -
idx_magi_income_{application,person}— MAGI income lookups -
idx_non_magi_factors_{application,person}— non-MAGI factor lookups -
idx_fti_tax_data_{application,person}— FTI lookups (audit-wrapped) -
idx_fdsh_results_{application,person}— FDSH lookups -
idx_clinical_assessments_application— HIPAA-scoped assessment lookup -
idx_medicaid_categories_{application,person,coa}— eligible-categories lookup + COA filter -
idx_chip_applications_{medicaid,child}— CHIP enrollment lookup -
idx_pathways_activities_application,idx_pathways_hipp_application— Pathways lookups -
idx_medicaid_determinations_{application,person,status}— determination lookups -
idx_medicaid_determinations_determined_at_id((determined_at DESC, id DESC), migration 20260817000000) — the keyset cursor backing the paginatedGET /v1/determinationslist (#1195); serves the newest-first page (and the T-MSIS extractor’s month-scoped page-loop) as an index scan with no top-N sort -
idx_determination_snapshots_as_of— input-snapshot lookup by evaluation date (ADR-028) -
idx_cmd_cascade_{application,person}— CMD cascade audit replay -
idx_tma_coverage_{household,person},idx_tma_coverage_status(partial on active) — TMA listings -
idx_ele_household— Express Lane Eligibility evaluation history (DESC byevaluated_at) -
idx_medicaid_cmd_events_household,idx_medicaid_cmd_events_unresolved(partial,WHERE state IN ('received','requested')— the #1506 lifecycle replaced the retired_unprocessedpicker index) — CMD event worklist -
idx_fti_audit_{accessed_at,accessed_by,purpose_code}— FTI audit query shapes -
idx_fti_audit_created_at—(created_at)for the ADR-014 §9 in-lock predecessor-hash lookup (ORDER BY created_at DESC LIMIT 1, held under the per-originating_systemadvisory lock on every FTI-bearing determination/ELE commit) andverify_chain’s ascending walk; #1197, migration 20260811000000. Closes the ADR-014 §9 doc/schema drift (the §9 budget asserted a `created_at DESCindex that did not exist) -
idx_fti_audit_event_hash,idx_fti_audit_archive_event_hash— ADR-014 hash-chain verification -
overpayment_claims_status,repayment_plans_by_claim,recoupment_ledger_by_claim— overpayment lifecycle -
event_outbox_*— the three generated partial outbox indexes (drainer hot path, lease-aware claim, ADR-039 held-skip); documented once in the data-models index -
event_inbox_unprocessed_idx(partial,WHERE processed_at IS NULL) — replay / janitor hot path
Migration files
-
20260326000001_create_fti_audit_log.sql— Pub 1075 §4 audit log + archive table (LIKE … INCLUDING ALL); identical schema to canopy-tanf’s -
20260407000000_create_medicaid_tables.sql— original 14-table schema (applications, MAGI household + income, non-MAGI factors, FTI tax data, FDSH results, clinical assessments, eligible categories, CHIP applications, PeachCare premium schedule, Pathways activities + HIPP referrals, determinations, CMD cascade log) -
20260413000000_create_tanf_tma_coverage.sql—tanf_tma_coverage(PAMMS 2166 / 42 CFR 435.112) populated by thetanf.case_closedsubscriber -
20260417000000_create_express_lane_evaluations.sql—express_lane_evaluations(42 CFR 435.1102) evaluation log — dropped in20260606000000(Plan 2 MR5; superseded by the durableele_tables)* -
20260425000000_add_fti_audit_hash_chain.sql— ADR-014previous_hash+event_hashonfti_audit_log+ archive -
20260508000000_create_event_outbox.sql+20260518004851_event_outbox_lease_columns.sql+20260713000000_event_outbox_hold.sql— the generated ADR-039 single-sourced outbox migrations (cargo xtask outbox-migrations --write); documented once in the data-models index -
20260510000001_create_overpayments.sql— canonical overpayment schema per 42 CFR 433.300 -
20260727000000_claim_provenance_adjustments.sql— #1104: claim provenance + partial UNIQUEs, the void path, andclaim_adjustments(canonical copy incrates/canopy-overpayments/migrations/; byte-parity crate-tested) -
20260512000000_create_medicaid_cmd_events.sql— #448 worker-portal-initiated CMD event ingest -
20261126000000_medicaid_determinations_trigger.sql— #1505 ADR-002 D9 provenance columns (triggerw/ kebab CHECK,previous_determination_id, the per-person-latest index, the one-successor-per-prior supersession unique) -
20261127000000_cmd_events_lifecycle.sql— #1506 CMD lifecycle (statereceived→requested→completed|failed|legacy,deadline_at= the PAMMS 2750 10-day clock,application_id,determination_request_id,failure_code; pre-subsystem rows explicitlylegacy) -
20260516000000_create_event_inbox.sql— #433 consumer-side inbox (ADR-018 amendment) -
20260605000000_create_ele_consents.sql/20260605000001_create_ele_status.sql/20260605000002_create_ele_grant_events.sql— Plan 2 durable Express Lane Eligibility: consent + per-child status + hash-chained grant events (42 CFR 435.1102, ADR-014) -
20260606000000_drop_express_lane_evaluations.sql— Plan 2 MR5 expand-contract: drop the superseded pre-Plan-2 evaluation log -
20260606010000_fti_audit_append_only_guard.sql— statement-level append-only guard onfti_audit_log+ archive (GUCcanopy.audit_maintenance) -
20260624000000_create_determination_snapshots.sql—medicaid_determinations.snapshot_hashcolumn + the immutabledetermination_snapshotstable + its append-only trigger (T2-4 #685; ADR-028) -
20260624140000_create_redaction_keys.sql— the per-serviceredaction_keystable + its one-way-tombstone trigger (T2-6 #687, ADR-036) -
20260630000000_drop_magi_household_snapshots.sql— drops the dead-on-arrivalmagi_household_snapshotstable (created in20260407000000, never wired to a read/write path); superseded in intent bydetermination_snapshots(D9 #883, ADR-016 expand→contract) -
20260701000000_create_ele_deferred_approvals.sql—ele_deferred_approvalsfor the ELE consent-after-approval race: express-lane defers an approval that arrives before consent, the ele-consent subscriber replays it (#649) -
20260811000000_fti_audit_created_at_idx.sql—idx_fti_audit_created_atfor the ADR-014 §9 in-lock predecessor lookup + verify walk (#1197, scale audit H13; closes the §9 doc/schema drift). Transactional (NOTCONCURRENTLY) for the same reason as the #1196 eligibility index migration -
20260817000000_medicaid_determinations_list_keyset_idx.sql—idx_medicaid_determinations_determined_at_id (determined_at DESC, id DESC)backing the keyset-paginatedGET /v1/determinationslist (#1195, scale audit C1). Transactional (NOTCONCURRENTLY), same rationale -
20260902000000_overpayment_claims_keyset_idx.sql— #1222 (scale audit M11):overpayment_claims_keyset (created_at DESC, id DESC)serving the roll-up keyset page; transactionalCREATE INDEX(notCONCURRENTLY— the sqlx migrator’s advisory lock deadlocks againstCONCURRENTLY’s snapshot wait); canonical copy in `crates/canopy-overpayments/migrations/, byte-parity asserted by the crate’s tests -
20260910000000_chain_v2_substrate.sql— #1246 MR-2 (ADR-014 Amendment 6): the dormant chain-v2ftisubstrate — see the chain-v2 section below
All migrations are forward-only per ADR-016.
chain-v2 substrate (dormant, #1246 / ADR-014 Amendment 6)
Installed by 20260910000000_chain_v2_substrate.sql — the fti-family copy
(canopy-medicaid is a chain SOURCE; the anchor store + C6 verification state live only
in canopy_security). Dormant until the #1279 cutover.
| Table | Purpose |
|---|---|
|
The shared registry substrate (identical DDL to the canopy-security copy): instance history, active pointer, fenced epochs, the source registry |
|
The FTI family’s strict-from-row-one event store (same constraint set as the audit copy). Hashed business columns are DERIVED from the payload — including the row |
Ownership: every object is owned by NOLOGIN canopy_chain_owner_medicaid;
the canopy_medicaid_app runtime role appends ONLY through the SECURITY
DEFINER function (C8). Details: ADR-014
Amendment 6.