feat(sp7): migration 0006 — service_line_payments + line_reconciliations + FKs
Migration renumbered from 0005 to 0006 because 0005_create_ta1_acks.sql (another agent's WIP, unmerged) already claims version 5. Bumping our migration to version 6 avoids stepping on it; user_version will land at 6 once both migrations run.
This commit is contained in:
@@ -260,6 +260,9 @@ class Remittance(Base):
|
|||||||
total_paid: Mapped[Decimal] = mapped_column(Numeric(12, 2), nullable=False, default=Decimal("0"))
|
total_paid: Mapped[Decimal] = mapped_column(Numeric(12, 2), nullable=False, default=Decimal("0"))
|
||||||
patient_responsibility: Mapped[Optional[Decimal]] = mapped_column(Numeric(12, 2), nullable=True)
|
patient_responsibility: Mapped[Optional[Decimal]] = mapped_column(Numeric(12, 2), nullable=True)
|
||||||
adjustment_amount: Mapped[Decimal] = mapped_column(Numeric(12, 2), nullable=False, default=Decimal("0"))
|
adjustment_amount: Mapped[Decimal] = mapped_column(Numeric(12, 2), nullable=False, default=Decimal("0"))
|
||||||
|
claim_level_adjustment_amount: Mapped[Decimal] = mapped_column(
|
||||||
|
Numeric(12, 2), nullable=False, default=Decimal("0"), server_default=text("0")
|
||||||
|
)
|
||||||
received_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
|
received_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
|
||||||
service_date: Mapped[Optional[date]] = mapped_column(Date, nullable=True)
|
service_date: Mapped[Optional[date]] = mapped_column(Date, nullable=True)
|
||||||
is_reversal: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
|
is_reversal: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
|
||||||
@@ -292,11 +295,17 @@ class CasAdjustment(Base):
|
|||||||
reason_code: Mapped[str] = mapped_column(String(8), nullable=False)
|
reason_code: Mapped[str] = mapped_column(String(8), nullable=False)
|
||||||
amount: Mapped[Decimal] = mapped_column(Numeric(12, 2), nullable=False)
|
amount: Mapped[Decimal] = mapped_column(Numeric(12, 2), nullable=False)
|
||||||
quantity: Mapped[Optional[Decimal]] = mapped_column(Numeric(10, 2), nullable=True)
|
quantity: Mapped[Optional[Decimal]] = mapped_column(Numeric(10, 2), nullable=True)
|
||||||
|
service_line_payment_id: Mapped[Optional[int]] = mapped_column(
|
||||||
|
Integer,
|
||||||
|
ForeignKey("service_line_payments.id", ondelete="SET NULL"),
|
||||||
|
nullable=True,
|
||||||
|
)
|
||||||
|
|
||||||
remittance: Mapped["Remittance"] = relationship(back_populates="cas_adjustments")
|
remittance: Mapped["Remittance"] = relationship(back_populates="cas_adjustments")
|
||||||
|
|
||||||
__table_args__ = (
|
__table_args__ = (
|
||||||
Index("ix_cas_adjustments_remittance_id", "remittance_id"),
|
Index("ix_cas_adjustments_remittance_id", "remittance_id"),
|
||||||
|
Index("ix_cas_adjustments_service_line_payment_id", "service_line_payment_id"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -346,10 +355,15 @@ class LineReconciliation(Base):
|
|||||||
"""One row per matched (or explicitly unmatched) 837 service line within a claim.
|
"""One row per matched (or explicitly unmatched) 837 service line within a claim.
|
||||||
|
|
||||||
SP7. Created during ``reconcile.run()`` after the claim↔remit match.
|
SP7. Created during ``reconcile.run()`` after the claim↔remit match.
|
||||||
At least one of ``claim_service_line_id`` / ``service_line_payment_id``
|
At least one of ``claim_service_line_number`` / ``service_line_payment_id``
|
||||||
must be non-null; the application enforces this.
|
must be non-null; the application enforces this.
|
||||||
|
|
||||||
See spec §3.2.
|
Implementation note: 837 service lines live in ``Claim.raw_json.service_lines[]``
|
||||||
|
keyed by ``line_number`` (1-based). They are NOT a separate ORM table, so the
|
||||||
|
claim-side FK is the line number itself; lookups join via the parent ``claim_id``
|
||||||
|
+ this column to read the line from the JSON blob.
|
||||||
|
|
||||||
|
See spec §3.2 (with this implementation note appended during T3).
|
||||||
"""
|
"""
|
||||||
__tablename__ = "line_reconciliations"
|
__tablename__ = "line_reconciliations"
|
||||||
|
|
||||||
@@ -357,10 +371,8 @@ class LineReconciliation(Base):
|
|||||||
claim_id: Mapped[str] = mapped_column(
|
claim_id: Mapped[str] = mapped_column(
|
||||||
String(64), ForeignKey("claims.id", ondelete="CASCADE"), nullable=False
|
String(64), ForeignKey("claims.id", ondelete="CASCADE"), nullable=False
|
||||||
)
|
)
|
||||||
claim_service_line_id: Mapped[Optional[int]] = mapped_column(
|
claim_service_line_number: Mapped[Optional[int]] = mapped_column(
|
||||||
Integer,
|
Integer, nullable=True
|
||||||
ForeignKey("service_lines.id", ondelete="SET NULL"),
|
|
||||||
nullable=True,
|
|
||||||
)
|
)
|
||||||
service_line_payment_id: Mapped[Optional[int]] = mapped_column(
|
service_line_payment_id: Mapped[Optional[int]] = mapped_column(
|
||||||
Integer,
|
Integer,
|
||||||
@@ -376,7 +388,8 @@ class LineReconciliation(Base):
|
|||||||
__table_args__ = (
|
__table_args__ = (
|
||||||
Index("ix_line_reconciliations_claim_id", "claim_id"),
|
Index("ix_line_reconciliations_claim_id", "claim_id"),
|
||||||
Index(
|
Index(
|
||||||
"ix_line_reconciliations_claim_service_line_id", "claim_service_line_id"
|
"ix_line_reconciliations_claim_service_line_number",
|
||||||
|
"claim_service_line_number",
|
||||||
),
|
),
|
||||||
Index(
|
Index(
|
||||||
"ix_line_reconciliations_service_line_payment_id",
|
"ix_line_reconciliations_service_line_payment_id",
|
||||||
|
|||||||
+3
-3
@@ -1,4 +1,4 @@
|
|||||||
-- version: 5
|
-- version: 6
|
||||||
-- SP7: per-service-line adjustment audit
|
-- SP7: per-service-line adjustment audit
|
||||||
-- See spec: docs/superpowers/specs/2026-06-20-cyclone-line-reconciliation-design.md
|
-- See spec: docs/superpowers/specs/2026-06-20-cyclone-line-reconciliation-design.md
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ CREATE INDEX ix_service_line_payments_procedure_code_date ON service_line_paymen
|
|||||||
CREATE TABLE line_reconciliations (
|
CREATE TABLE line_reconciliations (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
claim_id VARCHAR(64) NOT NULL REFERENCES claims(id) ON DELETE CASCADE,
|
claim_id VARCHAR(64) NOT NULL REFERENCES claims(id) ON DELETE CASCADE,
|
||||||
claim_service_line_id INTEGER REFERENCES service_lines(id) ON DELETE SET NULL,
|
claim_service_line_number INTEGER,
|
||||||
service_line_payment_id INTEGER REFERENCES service_line_payments(id) ON DELETE SET NULL,
|
service_line_payment_id INTEGER REFERENCES service_line_payments(id) ON DELETE SET NULL,
|
||||||
status VARCHAR(16) NOT NULL,
|
status VARCHAR(16) NOT NULL,
|
||||||
match_score INTEGER,
|
match_score INTEGER,
|
||||||
@@ -32,7 +32,7 @@ CREATE TABLE line_reconciliations (
|
|||||||
);
|
);
|
||||||
|
|
||||||
CREATE INDEX ix_line_reconciliations_claim_id ON line_reconciliations(claim_id);
|
CREATE INDEX ix_line_reconciliations_claim_id ON line_reconciliations(claim_id);
|
||||||
CREATE INDEX ix_line_reconciliations_claim_service_line_id ON line_reconciliations(claim_service_line_id);
|
CREATE INDEX ix_line_reconciliations_claim_service_line_number ON line_reconciliations(claim_service_line_number);
|
||||||
CREATE INDEX ix_line_reconciliations_service_line_payment_id ON line_reconciliations(service_line_payment_id);
|
CREATE INDEX ix_line_reconciliations_service_line_payment_id ON line_reconciliations(service_line_payment_id);
|
||||||
|
|
||||||
ALTER TABLE cas_adjustments ADD COLUMN service_line_payment_id INTEGER REFERENCES service_line_payments(id) ON DELETE SET NULL;
|
ALTER TABLE cas_adjustments ADD COLUMN service_line_payment_id INTEGER REFERENCES service_line_payments(id) ON DELETE SET NULL;
|
||||||
Reference in New Issue
Block a user