Data Model: Financial & Claims

On this page

Overview

The financial service manages foster care maintenance payments, adoption and guardianship assistance, Title IV-E eligibility tracking, payment adjustments, and federal fiscal claiming records for CFS-2 submission.

Rate tables define jurisdiction-specific daily rates by payment type and age range. Payments are generated from placements (per-diem origin) and — since #1068/ADR-053 — from active subsidy agreements (monthly subsidy origin) and approved through the same multi-step workflow. Adjustments modify payment amounts with supervisor approval. Claiming records aggregate issued payments for federal reimbursement.

The federal FFP figure payments.ffp_amount is a GENERATED ALWAYS column (#861): the DB derives it as CASE WHEN ive_eligible THEN round(net_amount * ffp_rate, 2) ELSE 0 on every write, so no handler computes or writes it and the IV-E claim can never drift from net_amount/ffp_rate/eligibility. DB-level backstops (#861) additionally reject malformed writes from any writer: CHECK (period_end >= period_start), CHECK (daily_rate >= 0), CHECK (ffp_rate >= 0 AND ffp_rate ⇐ 1), and CHECK (day_count >= 1) on payments; CHECK (age_min ⇐ age_max) and CHECK (effective_date ⇐ end_date) on rate_tables.

Since #1068 (ADR-053) payments is a NULLABLE-ORIGIN table: placement-origin rows carry the NOT-NULL case_id/placement_id/foster_home_id trio, subsidy-origin rows carry agreement_id + term_id (the term REVISION that priced the row — composite-FK-pinned to the same agreement) with a NULL placement pair (case_id optional — post-case children); payments_origin_exclusive admits exactly those two shapes. Subsidy rows are UNIT-MONTH rows: one exact calendar month (payments_subsidy_calendar_month) with day_count = 1 and daily_rate = gross_amount = the monthly award (payments_subsidy_unit_month) — the per-diem day×rate reading never applies — and are structurally never IV-E (payments_subsidy_never_ive; TANF-funded per 22.8). At most one LIVE subsidy row exists per agreement-month: the key is payments_one_subsidy_per_agreement_month_v2 on (agreement_id, payment_month) (the F9 month-identity GENERATED column) — a partial unique EXCLUDING voided rows, because the ADR-053 correction protocol voids a stale undisbursed month and regenerates it under the freed key. The legacy (agreement_id, period_start) twin that covered old replicas' ON CONFLICT targets through the rolling deploy was dropped by the #1106 contract step, which also raised schema_compat_floor to #1069 M1’s version — recording that a pre-M1 binary (whose conflict target no longer exists) is incompatible with the post-drop schema. No released binary is newly refused: pre-M1 binaries predate verify-only boot and were already VersionMissing-refused against any ahead database.

Placement-origin (per-diem) rows carry the OPPOSITE uniqueness semantics (#1179): payments_one_perdiem_per_placement_period on (placement_id, period_start) WHERE agreement_id IS NULL is a LIFETIME key with no status filter — a voided row still holds it. It is a replay guard, not a correction protocol: placement.activated is at-most-once per placement (no re-activation transition exists), so a key collision is always a replayed/duplicate execution — and because placement.ended voids the row while an ended placement can never re-emit events, a voided-exclusive key would let a stale replay mint a fresh payment nothing ever voids again. The placement.activated consumer inserts through ON CONFLICT … DO NOTHING against this key and stages its payment_created event iff the row was actually inserted. The companion payments_dedupe_repairs ledger (same migration) records any rows the one-time fail-closed dedupe removed.

Tables

The catalog below covers the domain tables. The fleet-standard platform tables also live in this schema and are documented centrally: event_outbox / event_inbox / event_inbox_collisions (ADR-022 and the ADR-062 §A attempt machine), request_claims (ADR-062 §B), and schema_compat_floor (ADR-063).

Table Purpose

placement_terminations

#1193 durable placement-termination tombstone: placement.ended records the ending even when it arrives BEFORE placement.activated (out-of-order delivery/replay), so the later activation can refuse to mint a live payment nothing would ever void.

rate_tables

Jurisdiction-specific daily payment rates by type and age range

payments

Foster care maintenance, adoption assistance, and guardianship assistance payments

payment_adjustments

Corrections or supplements to payment amounts (e.g., clothing allowance)

payments_dedupe_repairs

#1179 one-time-migration audit ledger: each per-diem duplicate the fail-closed dedupe deleted (canonical id, duplicate id, prior status, full row snapshot, reason — incl. a note when a published payment_created had already left the system)

claiming_records

Aggregated IV-E/non-IV-E expenditures for federal fiscal claiming (CFS-2). #1357: each row stamps the aggregation window it was generated over (period_start/period_end, both-or-neither by CHECK) — the claim_totals_drift invariant recomputes the totals over that window and queues any drift (report-only operator queue); submitted/accepted claims FREEZE their covered payments (adjustment approval refuses 409 claimed-payment-frozen; the amendment vehicle is #1073); SUBMISSION of a stale or windowless draft refuses 409 claim-totals-stale (draft-gated — regeneration is the remedy)

subsidy_agreements

Kinship-subsidy agreement IDENTITY (GA 22.8/22.9; ADR-052) — immutable signed-artifact metadata, import provenance, predecessor lineage; current_status is a projection of the interval ledger

subsidy_agreement_parties

Agreement signatories (caregiver / co-caregiver; never the child)

subsidy_agreement_terms

Effective-dated immutable term revisions (amount + basis, review schedule, education extension, approval binding); half-open windows, close-only

subsidy_agreement_status_intervals

Business-effective status ledger (pending/active/suspended/terminated/withdrawn/declined + reason codes + approvals); the authoritative status record

subsidy_agreement_reviews

22.9 review chain (renewal_12mo/paper_6mo): three-state rows — completed / open slot / superseded — with cycle identity, derived approval_level, the supervisor pair, and exact outcome linkage (resulting_term_id / resulting_interval_id, same-agreement composite FKs). See ADR-054

subsidy_reconcile_queue

Durable payment-repair feed (#1081/ADR-054): one live (agreement, month) pair per coverage-changing mutation, cause-tagged (transition/term_append/reinstatement, plus perdiem_change #1069 M1 and create_active #1069 M2 — the one-shot ERR creation’s backdated birth months ride the same durable queue), drained by the #1068 generator inside its run lease. Settled rows (processed_at IS NOT NULL) prune at the service’s outbox retention window (#1129 A3 / ADR-058); live rows and the dead-letter operator queue never age out

subsidy_sweep_runs

Durable sweep run records (state machine observed/previewed/executing/completed/failed/expired, execute-token digest, affected ids + counters + errors) — DDL lands with #1094; the U4 sweep (#1096) writes them. mode_per_diem_handoff snapshots the leg-3 consent knob per run (#1069 M3; DEFAULT false backfills historical rows truthfully — no run before the migration could enforce the leg)

subsidy_perdiem_handoffs

Durable per-diem handoff fact ledger (#1069 M3/ADR-055): one detection row per (agreement, payment), stamped by the enforcing run and — after a state-office reinstatement — the correction. Rows are never deleted

subsidy_import_batches

Conversion-batch ledger (#1071/ADR-057): one row per SHINES conversion run — source_system vocabulary (shines), snapshot_date (the named review baseline), cutover_month (month-start CHECK, > snapshot), expected_count (1..50000), manifest_checksum (sha256 over the sorted reference/hash pairs), state machine staging|finalizing|finalized|aborted with terminal-timestamp shape CHECKs

subsidy_import_records

Conversion-record staging ledger (#1071/ADR-057 D1/D4): one row per source record — external_reference, the IMMUTABLE canonical_payload + canonical_hash (the replay evidence; post-finalize replays compare HERE, never against mutable live rows), state staged|rejected|materialized|superseded, persisted warnings/blockers, and agreement_id once materialized (shape CHECK). The live ledger is untouched until finalize

The five subsidy_agreement* tables form a close-only temporal ledger with a single-writer store (craig_financial::subsidy::store) — see ADR-052 for the window semantics, coverage predicate, and blocking invariants, and ADR-054 for the review chain
verified-office authority (proof-typed writers; nothing approval-shaped is caller-supplied). The store primitives (transition, term append, schedule / complete / reschedule-supersede) land with #1094; the mutation API arrives with U2 (#1095), creation with the eligibility flows (ERR landed with #1069 M2; the SG/NRSG two-step + witnessed activation with #1070/ADR-056; the #1071/ADR-057 closed-cohort conversion import’s substrate — proof-typed materialization over the staging ledger below — with MR-A, its staging/finalize surface with MR-B).

#1069 M2 (ADR-055) adds six nullable columns to subsidy_agreements — written only by native creation (originally the one-shot ERR create; since #1070 the two-step guardianship create shares placement_started_on, relationship_evidence_key, and the F8 pair); all six are NULL for imports and every pre-existing row. The clock snapshot placement_started_on
foster_home_approval_due (the first day of the qualifying placement and the policy-derived 120-day approval due date) is both-or-neither and forward-running for ERR — originally CHECK subsidy_agreements_approval_clock_valid, reworked by #1070 into the three-shape subsidy_agreements_program_snapshot_valid below. custody_evidence_key / relationship_evidence_key are UNVERIFIED evidence references — object-store keys recorded as supplied; existence is deliberately NOT verified (a recorded ADR-055 non-goal). The F8 idempotency pair create_request_id + create_request_hash (client-supplied request id
canonical-payload SHA-256 hex) is paired by CHECK (subsidy_agreements_create_request_pair) so a replay row can never exist half-keyed, and backed by the partial unique below — the endpoint checks BEFORE volatile dependencies, and the unique turns a two-writers race into a typed replay, never a double enrollment.

#1070 (ADR-056) adds five more nullable columns to subsidy_agreements — the native SG/NRSG guardianship flow is the only writer; all five are NULL for ERR, imports (#1071), and every pre-existing row. The CREATE step (the two-step PENDING mint) writes caregiver_assessment_evidence_key (UNVERIFIED evidence reference: the approved kinship assessment / foster-home evaluation) alongside the shared residence snapshot + F8 pair; the witnessed ACTIVATION writes the rest atomically with the pending → active interval: guardianship_transfer_on (the anchoring placement’s derived end date — the transfer proxy, ⁂ #1073; the first Active interval opens here), payments_begin_month (the F2 money boundary: max(month after transfer, month after TANF termination) — the generator pays nothing before it), court_order_evidence_key (UNVERIFIED reference: the permanent-guardianship court order), and tanf_terminated_on (operator ATTESTATION, unverified — CRAIG holds no TANF data). Three CHECKs shape the columns: the ERR-only approval-clock CHECK is DROPPED and replaced by the three-shape program snapshot subsidy_agreements_program_snapshot_valid — all-NULL (legacy/import) | the ERR clock pair (both set, due > start) | the guardianship residence shape (program IN ('sg','nrsg')placement_started_on set ∧ clock column NULL — SG has no 120-day clock); subsidy_agreements_guardianship_flow_shape couples the flow (a transfer snapshot exists ONLY on a flow-created family agreement with the full activation record — residence snapshot, F8 key, court evidence, money boundary, transfer > placement_started_on, and the F1 strict signed_at < transfer); and subsidy_agreements_payments_begin_month_valid pins the boundary to a month START strictly after a PRESENT transfer (TANF can only push it later, and the explicit presence arm avoids a silent > NULL pass). The F12 family-exclusivity partial unique (subsidy_agreements_one_open_guardianship_family, below) is the race backstop. Three REPORT-ONLY invariants watch the flow’s facts, keyed on the flow-written columns so legacy/seed rows never fire: sg_transfer_matches_activation (transfer = the earliest Active interval’s start, plus a flow-scoped completeness arm keyed on Active-interval EXISTENCE — a later termination cannot hide the gap — and a snapshot-without-any-Active bypass arm), sg_no_payment_before_boundary (no live payment with payment_month < payments_begin_month), and sg_residence_floor (GA devstack: placement_started_on + 6 months ≤ transfer; Postgres interval clamping is equivalent to the store’s chrono checked_add_months clamping).

#1071 (ADR-057) adds the conversion substrate (migration 20260725090000_subsidy_import_ledger.sql): the two staging tables above, plus ONE column on subsidy_agreementspayment_cutover_month, the machine money boundary written by the materializing identity insert (SHINES pays every month strictly before it, CRAIG from it onward; the generator’s BeforeCutover rule enforces CRAIG’s side on the scheduled, manual, AND reconcile paths). Two CHECKs shape it: subsidy_agreements_cutover_iff_imported (present exactly when source_system is set — provenance all-or-none extends to the money boundary) and subsidy_agreements_cutover_month_start. Family exclusivity widens to the full taxonomy (ADR-057 D8): the #1070 guardianship one-open index is RECREATED over ('sg','nrsg','ersg','enrsg') and a NEW relative-care one-open index covers ('rcs','ercs') — safe pre-1.0 because import is the only path that can mint enhanced/relative-care rows. idx_subsidy_agreements_import_batch (partial, WHERE import_batch_id IS NOT NULL) serves batch reconciliation. Four BLOCKING invariants guard the substrate: subsidy_active_missing_review_slot (every active/suspended head holds a live renewal slot, plus a paper slot for non-ERR programs when the head terms carry a paper anchor — scoped to imported rows and any row whose review chain already exists, so a native row whose chain never materialized is exempt), subsidy_terms_cover_active (every Active interval priced from its first day), subsidy_closed_cohort_qualifying_date (rcs/ercs first received before 2014-01-01, ersg/enrsg before 2014-08-01 — earliest Active start, signed_at fallback), and subsidy_cutover_iff_imported (the DDL shape plus the money consequence: no live payment before the cutover).

#1072 adds the UAS payment classification (migration 20260725160000_subsidy_uas_classification.sql): subsidy_agreements.uas_code TEXT NOT NULL — derived by the service at the only write boundaries (native create + conversion import) from the active state bundle’s effective-dated vocabulary as of the write’s business date, immutable thereafter (as-of snapshot: a vocabulary change never re-derives a row) — and payments.uas_code TEXT, denormalized from the AGREEMENT at the generator’s single insert site (deliberately outside the RowShape derivation compare, so vocabulary changes can never void/regenerate rows). The migration backfilled pre-#1072 rows with GA literals (every historical row is GA-shaped — subsidy writes have been jurisdiction-gated since the table’s birth), drift-pinned against the GA bundle by uas_backfill_matches_the_georgia_bundle. Shapes: subsidy_agreements_uas_code_nonblank and payments_uas_iff_subsidy_origin ((uas_code IS NULL) = (agreement_id IS NULL) — per-diem billing rows have no enrollment to classify). One new BLOCKING invariant: subsidy_payment_uas_consistent (a payment’s code always equals its agreement’s).

subsidy_perdiem_handoffs (#1069 M3/ADR-055) is the durable "per diem began" fact ledger: a mutable billing row is not the fact — the payment can be voided, repriced, or re-pointed after the sweep acted on it. Columns: agreement_id (FK subsidy_agreements ON DELETE CASCADE, like every agreement child table — production never deletes agreements; a dev/test delete takes the ledger with it), payment_id (FK payments), perdiem_started_on (the per diem’s period_start as detected — the F6 termination truth date, max’d with head start + 1 day at enforcement), detected_run_id and nullable enforced_run_id (both FK subsidy_sweep_runs), and the correction pair corrected_at
correction_note. Its writers are the M3 sweep engine and store: detection inserts once per (agreement, payment) on every scheduled sweep scan (subsidy_perdiem_handoffs_once UNIQUE); leg-3 enforcement stamps enforced_run_id (NULL while detected-only — knob off, or an operator acted manually); a state-office reinstatement out of a per_diem_begins termination stamps corrected_at + correction_note on every uncorrected fact on the agreement (the per diem itself must be voided/ended first). A note cannot exist unstamped (CHECK subsidy_perdiem_handoffs_note_shape). Rows are never deleted.

ER Diagram

rate_tablesuuididPKtextjurisdictiontextpayment_typeintegerage_minintegerage_maxnumericdaily_ratedateeffective_datedateend_datenullablebigintversionIf-Match CAS counter (ADR-062 §G3)timestamptzcreated_atpaymentsuuididPKuuidcase_idnullable; FK to craig_casesuuidchild_idFK to craig_casesuuidplacement_idnullable; FK to craig_placementuuidfoster_home_idnullable; FK to craig_placementuuidagreement_idnullable; FK subsidy_agreements (#1068)uuidterm_idnullable; composite FK subsidy_agreement_termstextpayment_typedateperiod_startdateperiod_endnumericdaily_rateintegerday_countnumericgross_amountnumericadjustmentsnumericnet_amountbooleanive_eligiblenumericffp_ratenumericffp_amountGENERATEDtextstatuspending|approved|issued|cleared|voidedtextapproved_bynullabletextapproved_by_namenullabletimestamptzapproved_atnullabletextissued_bynullabletextissued_by_namenullabletimestamptzissued_atnullabletextcleared_bynullabletextcleared_by_namenullabletimestamptzcleared_atnullabletextvoided_bynullable; manual void only (#1028)textvoided_by_namenullabletimestamptzvoided_atnullabletextvoid_reasonnullable; row-only, never on eventstextcreated_bytimestamptzcreated_attimestamptzupdated_atuuidassigned_worker_subnullable; authz denorm (Plan A D6)uuidsupervisor_subnullable; authz denorm (#1084)bigintassignment_revision#1312 ordering guardpayment_adjustmentsuuididPKuuidpayment_idFKtextreasonnumericamounttextrequested_bytextapproved_bynullabletimestamptzapproved_atnullabletextstatuspending|approved|deniedtimestamptzcreated_atuuidassigned_worker_subnullable; authz denormuuidsupervisor_subnullable; authz denorm (#1084)bigintassignment_revision#1312 ordering guardclaiming_recordsuuididPKtextclaiming_periodtextpayment_typenumerictotal_expenditurenumericive_eligible_amountnumericffp_claimednumericnon_ive_amountnumericccwis_operations_costtextstatusdraft|submitted|acceptedtimestamptzsubmitted_atnullabledateperiod_startnullable; aggregation window (#1357)dateperiod_endnullable; both-or-neither CHECKtimestamptzcreated_athas

The subsidy-agreement ledger (ADR-052) is a separate cluster:

subsidy_agreementsuuididPKuuidchild_idcases.personsuuidcase_idnullabletextprogramerr|sg|nrsg|ersg|enrsg|rcs|ercstextcurrent_statusprojection of interval headtextform_numberdatesigned_attextsource_systemimport provenance, all-or-noneuuidpredecessor_agreement_idFKnullable, uniqueuuidassigned_worker_subnullableuuidsupervisor_subnullable (#1084)dateplacement_started_onnullable; residence snapshot (#1069/#1070)datefoster_home_approval_duenullable; ERR-only clock duetextcustody_evidence_keynullable; UNVERIFIED store keytextrelationship_evidence_keynullable; UNVERIFIED store keyuuidcreate_request_idnullable; F8 pair, partial uniquetextcreate_request_hashnullable; payload SHA-256 hexdateguardianship_transfer_onnullable; activation snapshot (#1070)datepayments_begin_monthnullable; F2 money boundary (#1070)textcourt_order_evidence_keynullable; UNVERIFIED store keydatetanf_terminated_onnullable; operator attestation (#1070)textcaregiver_assessment_evidence_keynullable; UNVERIFIED store keydatepayment_cutover_monthnullable; iff imported (#1071)subsidy_import_batchesuuididPKtextsource_systemvocabulary: shinesdatesnapshot_datethe review baseline (#1071)datecutover_monthmonth start, > snapshotintegerexpected_count1..50000textmanifest_checksumsha256 hextextstatusstaging|finalizing|finalized|abortedsubsidy_import_recordsuuididPKuuidbatch_idFKtextexternal_referencelive-unique across batchesjsonbcanonical_payloadimmutable replay evidencetextcanonical_hashsha256 hextextstatusstaged|rejected|materialized|supersededjsonbwarningsjsonbblockersuuidagreement_idnullable; set when materializedsubsidy_agreement_partiesuuididPKuuidagreement_idFKuuidperson_idcases.persons, never the childtextrolecaregiver|co_caregiversubsidy_agreement_termsuuididPKuuidagreement_idFKintegerrevisioncontiguous 1..ndateeffective_fromhalf-open windowdateeffective_untilnullable = opennumericmonthly_amountdaterenewal_review_duedatepaper_review_dueNULL for ERRtextapproved_bytextapproval_levelsubsidy_agreement_status_intervalsuuididPKuuidagreement_idFKtextstatus6-token vocabularydateeffective_frombusiness timedateeffective_untilnullable = opentextreason_coderequired for reason statusestextapproved_bysubsidy_agreement_reviewsuuididPKuuidagreement_idFKtextreview_typerenewal_12mo|paper_6mointcyclechain identity, >= 1datedue_onstatutory data, never shifteddatecompleted_onnullable; open slot when NULLtextapproval_levelderived office | system | NULLtextsupervisor_approved_bypair with _atuuidresulting_term_idFKcomposite, same agreementuuidresulting_interval_idFKcomposite, same agreementtimestamptzsuperseded_atall-or-none with _by/_reasonsubsidy_perdiem_handoffsuuididPKuuidagreement_idFKON DELETE CASCADEuuidpayment_idFK paymentsdateperdiem_started_onF6 truth dateuuiddetected_run_idFK subsidy_sweep_runsuuidenforced_run_idnullable = detected-onlytimestamptzcorrected_atnullabletextcorrection_notenullable; requires corrected_atsigned byterm revisionsstatus ledgerreviews (22.9)handoff facts (#1069 M3)predecessor (re-application)stages (#1071)materialized as (#1071)

State Machines

Payment Status

pending → approved → issued → cleared
    * → voided
  • pending: Payment calculated, awaiting supervisor approval

  • approved: Supervisor approved, queued for issuance

  • issued: Payment disbursed to foster parent/provider

  • cleared: Payment confirmed received/settled

  • voided: Payment cancelled (from any state)

Adjustment Status

pending → approved
pending → denied
  • pending: Adjustment requested, awaiting supervisor review

  • approved: Adjustment approved, payment net_amount updated

  • denied: Adjustment rejected

Claiming Record Status

draft → submitted → accepted
  • draft: Claim generated, expenditures aggregated, under review

  • submitted: Claim submitted to ACF for federal reimbursement

  • accepted: Claim accepted by ACF

Indexes

Index Columns

idx_payments_case

payments(case_id)

idx_payments_child

payments(child_id)

idx_payments_foster_home

payments(foster_home_id)

idx_payments_status

payments(status)

idx_payments_period

payments(period_start, period_end)

idx_payments_perdiem_by_child

partial payments(child_id, period_start, id) WHERE agreement_id IS NULL AND status <> 'voided' — leg 3’s access path: the scan and the enforce-time re-verify both want "earliest live placement-origin payment for a child" (#1069 M3)

idx_claiming_period

claiming_records(claiming_period)

subsidy_agreements_one_open_per_child_program

partial UNIQUE subsidy_agreements(child_id, program) WHERE current_status NOT IN (terminal) — one open episode

subsidy_agreements_import_replay_key

partial UNIQUE subsidy_agreements(source_system, external_reference) — idempotent import

subsidy_agreements_one_successor

partial UNIQUE subsidy_agreements(predecessor_agreement_id) — no lineage branching

idx_subsidy_agreements_{child,case,status,worker,supervisor}

subsidy_agreements filter columns (worker/supervisor partial NOT NULL)

subsidy_agreements_create_request_id

partial UNIQUE subsidy_agreements(create_request_id) WHERE create_request_id IS NOT NULL — F8 backstop: one agreement per create request; a two-writers race becomes a typed replay, never a double enrollment (#1069 M2)

subsidy_agreements_err_clock

partial subsidy_agreements(foster_home_approval_due) WHERE program = 'err' AND current_status = 'active' — the operator clock queue: active ERR agreements ordered by approval due date (#1069 M2)

subsidy_agreements_one_open_guardianship_family

partial UNIQUE subsidy_agreements(child_id) WHERE program IN ('sg', 'nrsg', 'ersg', 'enrsg') AND current_status IN ('pending', 'active', 'suspended') — family exclusivity: at most ONE open guardianship-family enrollment per child (alternative classifications of the same enrollment, not parallel programs). Created by #1070 (F12, sg/nrsg), RECREATED by #1071/ADR-057 D8 over all four family tokens (safe pre-1.0 — import is the only path that can mint the enhanced variants); the store takes family history locks in the canonical order first, so racing writers serialize before this backstop fires

subsidy_agreements_one_open_relative_care_family

partial UNIQUE subsidy_agreements(child_id) WHERE program IN ('rcs', 'ercs') AND current_status IN ('pending', 'active', 'suspended') — the relative-care family’s one-open backstop (#1071/ADR-057 D8)

idx_subsidy_agreements_import_batch

partial subsidy_agreements(import_batch_id) WHERE import_batch_id IS NOT NULL — batch reconciliation queries were full-table scans (#1071 G10)

subsidy_import_records_live_reference

partial UNIQUE subsidy_import_records(external_reference) WHERE status IN ('staged', 'materialized') — one LIVE claim per source record across ALL batches; superseded/rejected rows free the key for corrections and re-imports (#1071/ADR-057 D4)

idx_subsidy_import_records_batch

subsidy_import_records(batch_id, status) — the finalize keyset loop + batch reconciliation listing (#1071)

subsidy_agreement_{terms,intervals}_one_open

partial UNIQUE (agreement_id) WHERE effective_until IS NULL — at-most-one open head each

idx_subsidy_agreement_{terms,intervals}_window

(agreement_id, effective_from) — as-of scans

idx_subsidy_agreement_reviews_due

partial (due_on) WHERE completed_on IS NULL AND superseded_at IS NULL — global due-work scan (superseded slots leave the scan, #1094)

subsidy_agreement_reviews_one_open

partial UNIQUE (agreement_id, review_type) WHERE completed_on IS NULL AND superseded_at IS NULL — one open slot per type, race-free replay target

subsidy_agreement_reviews_cycle_live

partial UNIQUE (agreement_id, review_type, cycle) WHERE superseded_at IS NULL — one live-or-completed row per cycle (supersession history keeps its cycle). The old (agreement_id, review_type, due_on) unique is DROPPED (pre-1.0): statutory due dates are data, never shifted for key collisions

subsidy_agreement_intervals_agreement_id_id_key

UNIQUE subsidy_agreement_status_intervals(agreement_id, id) — the composite-FK target resulting_interval_id needs (terms-side mirror pre-existed)

subsidy_reconcile_queue_live

partial UNIQUE subsidy_reconcile_queue(agreement_id, month) WHERE processed_at IS NULL — one live pair; enqueue replays no-op (ON CONFLICT DO NOTHING)

idx_subsidy_reconcile_queue_pending

partial subsidy_reconcile_queue(enqueued_at) WHERE processed_at IS NULL — the generator drain’s fetch order

subsidy_perdiem_handoffs_once

UNIQUE subsidy_perdiem_handoffs(agreement_id, payment_id) — detect-once: one fact per (agreement, payment) forever (#1069 M3)

idx_subsidy_perdiem_handoffs_agreement

subsidy_perdiem_handoffs(agreement_id) — correction stamping + operator lookups walk by agreement (#1069 M3)

Cross-Service References

The financial service references entities from other services by UUID (no foreign keys across databases):

  • payments.case_idcraig_cases.cases.id

  • payments.child_idcraig_cases.persons.id

  • subsidy_agreements.child_idcraig_cases.persons.id

  • subsidy_agreements.case_idcraig_cases.cases.id

  • subsidy_agreements.placement_idcraig_placement.placements.id

  • subsidy_agreement_parties.person_idcraig_cases.persons.id

The four subsidy references are walked by cargo xtask reconcile (cross-service reconciliation). * payments.placement_idcraig_placement.placements.id * payments.foster_home_idcraig_placement.foster_homes.id

Rate table lookups use jurisdiction (from CRAIG_FINANCIAL__JURISDICTION env var) and payment_type to match the appropriate daily rate for a child’s age.

Edit this page · latest