feat(sp27): pin Claim↔Remit matched-pair invariant + startup drift audit
Add check_matched_pair_drift() at module level in store.py — read-only audit of the Claim.matched_remittance_id ↔ Remittance.claim_id FK pair. Logs WARNING on drift with up to 5 examples of each of two cases (claim-side and remit-side), returns the count of drifted rows. Wired into api.py::lifespan right after db.init_db() and ensure_clearhouse_seeded(), wrapped in try/except so a query failure logs but doesn't crash boot. The symmetric-write + symmetric-clear invariants on manual_match / manual_unmatch were already correct; this commit pins them with focused regression tests in test_store_match_invariant.py (8 tests covering both directions, both happy-path, rollback pin, and drift-check unit behavior). PCN asymmetry in the fixture prevents the auto-match inside CycloneStore.add (Task 10) from pre-pairing, so manual_match is the only writer. Migration 0016 adds the missing ix_claims_matched_remittance_id index — the drift check scans WHERE matched_remittance_id IS NOT NULL on every boot and would become a full-table scan past ~10k claims. Symmetric with ix_remittances_claim_id (added in 0007). Migration tests bumped from head=15 to head=16.
This commit is contained in:
@@ -51,21 +51,22 @@ def test_migration_0002_creates_acks_table():
|
||||
|
||||
def test_migration_latest_idempotent_on_fresh_db():
|
||||
"""Re-running the migration on the same DB must be a no-op (PRAGMA
|
||||
user_version already at the latest version — currently 15 after
|
||||
user_version already at the latest version — currently 16 after
|
||||
0004-0006 line_reconciliation, 0005 ta1_acks, SP9's 0007
|
||||
providers/payers/clearhouse, SP10's 0008 payer_rejected,
|
||||
SP11's 0009 audit_log, SP14's 0010 payer_rejected_acknowledged,
|
||||
SP16's 0011 processed_inbound_files, SP17's 0012 db_backups,
|
||||
SP-auth's 0013 users + sessions, SP-audit's 0014 audit_log.user_id,
|
||||
SP22's 0015 drop_claims_unique_constraint)."""
|
||||
SP22's 0015 drop_claims_unique_constraint, SP27-Task 11's 0016
|
||||
claims.matched_remittance_id index)."""
|
||||
with db.engine().begin() as c:
|
||||
v1 = c.exec_driver_sql("PRAGMA user_version").scalar() or 0
|
||||
assert v1 == 15
|
||||
assert v1 == 16
|
||||
# A second run should not raise and should not bump the version.
|
||||
db_migrate.run(db.engine())
|
||||
with db.engine().begin() as c:
|
||||
v2 = c.exec_driver_sql("PRAGMA user_version").scalar() or 0
|
||||
assert v2 == 15
|
||||
assert v2 == 16
|
||||
|
||||
|
||||
def test_add_ack_persists_row():
|
||||
|
||||
Reference in New Issue
Block a user