9e775c0150
The claim_acks join table is the durable record of which inbound 999 / 277CA / TA1 ack acknowledged which claim (or, for TA1, which originating 837 Batch). One row per AK2 set-response / ClaimStatus / envelope. The match granularity is per-AK2 so the operator can answer 'which claims does this ack acknowledge?' with a single SELECT and so the ClaimDrawer panel can show per-segment accept / reject status without re-parsing raw_json. Schema mirrors spec §3.1: - claim_id NULLable + batch_id NULLable (TA1 envelope links land on batch_id; CHECK enforces at least one populated) - unique partial index ux_claim_acks_dedup enforces idempotent re-ingest of the same 999 file - set_control_number stores the value the upstream ack ACTUALLY CARRIED (== source 837 ST02 for Gainwell batches) for orphan traceability — the link survives even when the join had to fall back from ST02 to PCN matching Mirrored on the ORM via Index(..., sqlite_where=text(...)) so Base.metadata.create_all (the test-time safety net) emits the same partial-unique constraint as the migration. Step 1.1/1.2/1.3 of the SP28 implementation plan.
53 lines
2.6 KiB
SQL
53 lines
2.6 KiB
SQL
-- version: 18
|
|
-- SP28: per-ACK auto-link join table.
|
|
--
|
|
-- Closes the operator gap where every inbound 999 / 277CA / TA1 ack was
|
|
-- persisted but never durably linked back to the claim it
|
|
-- acknowledges. One row per AK2 set-response for 999, per ClaimStatus
|
|
-- for 277CA, per TA1 envelope (with claim_id NULL + batch_id set).
|
|
--
|
|
-- Granularity (per-AK2) is preserved by ``ak2_index`` and the unique
|
|
-- index ``ux_claim_acks_dedup`` — an auto-link of
|
|
-- (claim, 999, ak2_index=3) is idempotent on re-ingest of the same
|
|
-- 999 file (the index enforces this at the DB layer; the helper
|
|
-- pre-checks to avoid IntegrityError log noise).
|
|
--
|
|
-- Notes:
|
|
-- * ``claim_id`` is nullable so TA1 envelope-level links to the
|
|
-- originating Batch can land here (FK to batches.id). The
|
|
-- CHECK constraint makes sure at least one of (claim_id,
|
|
-- batch_id) is set on every row — see spec §3.1.
|
|
-- * ``set_control_number`` records the value the upstream ACK
|
|
-- ACTUALLY CARRIED (== source 837 ST02 for Gainwell batches). It
|
|
-- is the orphan-traceability field — the link survives even when
|
|
-- the join had to fall back from ST02 to PCN matching.
|
|
-- * ``set_accept_reject_code`` carries the AK5 code (A/E/R/X) for
|
|
-- 999 or the STC category code (A1/A2/A3/A4/A6/A7 etc.) for 277CA.
|
|
-- TA1 stores the envelope-level ack code here (A/R/E).
|
|
-- * No FK constraint on ``(ack_kind, ack_id)`` — there are three
|
|
-- separate ack tables (``acks``, ``ta1_acks``, ``two77ca_acks``).
|
|
-- Application code enforces the discriminator.
|
|
|
|
CREATE TABLE claim_acks (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
claim_id TEXT REFERENCES claims(id) ON DELETE CASCADE,
|
|
batch_id TEXT REFERENCES batches(id) ON DELETE CASCADE,
|
|
ack_id INTEGER NOT NULL,
|
|
ack_kind TEXT NOT NULL CHECK (ack_kind IN ('999', '277ca', 'ta1')),
|
|
ak2_index INTEGER,
|
|
set_control_number TEXT,
|
|
set_accept_reject_code TEXT,
|
|
linked_at DATETIME NOT NULL,
|
|
linked_by TEXT NOT NULL CHECK (linked_by IN ('auto', 'manual')),
|
|
CHECK ((claim_id IS NOT NULL) OR (batch_id IS NOT NULL))
|
|
);
|
|
|
|
CREATE INDEX ix_claim_acks_claim_id ON claim_acks(claim_id);
|
|
CREATE INDEX ix_claim_acks_batch_id ON claim_acks(batch_id);
|
|
CREATE INDEX ix_claim_acks_ack ON claim_acks(ack_kind, ack_id);
|
|
|
|
-- Dedup: an auto-link of (claim, 999, ak2_index=3) is idempotent on re-ingest.
|
|
CREATE UNIQUE INDEX ux_claim_acks_dedup
|
|
ON claim_acks(claim_id, ack_kind, ack_id, ak2_index)
|
|
WHERE claim_id IS NOT NULL AND ak2_index IS NOT NULL;
|