fix(frontend): UnmatchedClaim/UnmatchedRemittance types match store.to_ui_claim_from_orm wire shape
The Reconciliation page crashed with 'c.chargeAmount.toFixed is undefined' because the TS types declared fields the backend never emitted (chargeAmount vs billedAmount, patientControlNumber vs patientName, statusCode vs status, totalPaid vs paidAmount). - UnmatchedClaim: chargeAmount -> billedAmount, patientControlNumber -> patientName, payerId/serviceDate now optional (backend omits them) - UnmatchedRemittance: statusCode -> status, totalPaid -> paidAmount, totalCharge/serviceDate/isReversal now optional - Reconciliation page + test fixtures updated to use the wire shape - Tests: 124/124 pass
This commit is contained in:
@@ -95,10 +95,10 @@ describe("ReconciliationPage", () => {
|
||||
claims: [
|
||||
{
|
||||
id: "CLM-1",
|
||||
patientControlNumber: "PCN-A",
|
||||
serviceDate: "2026-06-01",
|
||||
chargeAmount: 100,
|
||||
patientName: "Patient A",
|
||||
billedAmount: 100,
|
||||
providerNpi: "1234567890",
|
||||
serviceDate: "2026-06-01",
|
||||
payerId: "P1",
|
||||
state: "submitted",
|
||||
},
|
||||
@@ -107,12 +107,13 @@ describe("ReconciliationPage", () => {
|
||||
{
|
||||
id: "CLP-1:b1",
|
||||
payerClaimControlNumber: "PCN-A",
|
||||
statusCode: "1",
|
||||
totalCharge: 100,
|
||||
totalPaid: 100,
|
||||
status: "received",
|
||||
paidAmount: 100,
|
||||
adjustmentAmount: 0,
|
||||
serviceDate: "2026-06-01",
|
||||
receivedDate: "2026-06-01",
|
||||
isReversal: false,
|
||||
totalCharge: 100,
|
||||
serviceDate: "2026-06-01",
|
||||
batchId: "b1",
|
||||
},
|
||||
],
|
||||
|
||||
@@ -163,10 +163,10 @@ export function ReconciliationPage() {
|
||||
>
|
||||
<div className="display num text-sm">{c.id}</div>
|
||||
<div className="font-mono text-xs text-muted-foreground">
|
||||
{c.patientControlNumber}
|
||||
{c.patientName}
|
||||
</div>
|
||||
<div className="text-xs text-muted-foreground mt-0.5">
|
||||
{c.serviceDate ?? "—"} · ${c.chargeAmount.toFixed(2)} · NPI{" "}
|
||||
{c.serviceDate ?? "—"} · ${c.billedAmount.toFixed(2)} · NPI{" "}
|
||||
{c.providerNpi ?? "—"}
|
||||
</div>
|
||||
</button>
|
||||
@@ -205,7 +205,7 @@ export function ReconciliationPage() {
|
||||
) : null}
|
||||
</div>
|
||||
<div className="text-xs text-muted-foreground mt-0.5">
|
||||
Status {r.statusCode} · ${r.totalPaid.toFixed(2)} paid · $
|
||||
Status {r.status} · ${r.paidAmount.toFixed(2)} paid · $
|
||||
{r.adjustmentAmount.toFixed(2)} adj
|
||||
</div>
|
||||
</button>
|
||||
|
||||
+26
-9
@@ -366,26 +366,43 @@ export interface Match {
|
||||
is_reversal: boolean;
|
||||
}
|
||||
|
||||
// Mirrors `cyclone.store.to_ui_claim_from_orm` (backend/src/cyclone/store.py).
|
||||
// Fields the backend does not currently emit are optional so the type
|
||||
// matches the actual wire shape (was previously assumed but never true).
|
||||
export interface UnmatchedClaim {
|
||||
id: string;
|
||||
patientControlNumber: string;
|
||||
serviceDate: string | null;
|
||||
chargeAmount: number;
|
||||
patientName: string;
|
||||
billedAmount: number;
|
||||
providerNpi: string | null;
|
||||
payerId: string | null;
|
||||
payerName?: string;
|
||||
payerId?: string | null;
|
||||
serviceDate?: string | null;
|
||||
cptCode?: string;
|
||||
submissionDate?: string;
|
||||
state: ClaimState;
|
||||
}
|
||||
|
||||
// Mirrors `cyclone.store.list_unmatched` (backend/src/cyclone/store.py) for
|
||||
// the remittances payload. `status` is the 3-state remittance lifecycle
|
||||
// ("received" | "posted" | "reconciled"); the previous `statusCode` field
|
||||
// was a confusion with the 835 claim-status code and never existed on the
|
||||
// wire. Fields the backend omits are optional.
|
||||
export interface UnmatchedRemittance {
|
||||
id: string;
|
||||
payerClaimControlNumber: string;
|
||||
statusCode: string;
|
||||
totalCharge: number;
|
||||
totalPaid: number;
|
||||
payerName?: string;
|
||||
status: string;
|
||||
paidAmount: number;
|
||||
adjustmentAmount: number;
|
||||
serviceDate: string | null;
|
||||
isReversal: boolean;
|
||||
batchId: string;
|
||||
receivedDate?: string;
|
||||
parsedAt?: string;
|
||||
claimId?: string;
|
||||
denialReason?: string | null;
|
||||
validationWarnings?: string[];
|
||||
isReversal?: boolean;
|
||||
totalCharge?: number;
|
||||
serviceDate?: string | null;
|
||||
}
|
||||
|
||||
export interface UnmatchedResponse {
|
||||
|
||||
Reference in New Issue
Block a user