feat(batch-diff): side-by-side claim diff between two batches

This commit is contained in:
Tyler
2026-06-20 17:17:09 -06:00
parent 4cd52c3084
commit 7b394fff1a
12 changed files with 2556 additions and 0 deletions
+76
View File
@@ -560,3 +560,79 @@ export interface ClaimDetail {
matchedRemittance: ClaimDetailMatchedRemittance | null;
stateHistory: ClaimDetailStateHistoryEvent[];
}
// ---------------------------------------------------------------------------
// Side-by-side batch diff (SP3 P4 / T18)
// Mirrors `GET /api/batch-diff?a=<batch_id>&b=<batch_id>` (see
// `backend/src/cyclone/batch_diff.py` and `backend/src/cyclone/api.py`).
// The contract is deliberately small: no raw segments, no service-line
// details — just the summary fields the operator needs to spot the
// deltas between two parsed files at a glance.
// ---------------------------------------------------------------------------
export type BatchKind = "837p" | "835";
export interface BatchDiffSideMeta {
id: string;
kind: BatchKind;
parsedAt: string; // ISO Z
inputFilename: string;
claimCount: number;
}
/**
* One claim (or remittance) row projected for the diff view. Carries
* just enough context to render side-by-side without the EDI parse
* tree. ``status`` carries the validation-derived label for 837P
* (``submitted`` / ``pending`` / ``draft`` / ``denied``) and the CLP02
* code/label for 835.
*/
export interface BatchClaimDiffSummary {
claim_id: string;
patient_name: string;
total_charge: number;
service_date: string | null;
status: string;
cpt_codes: string[];
}
/**
* One changed field between the two sides of a claim. ``field``
* identifies which column changed (``status`` / ``total_charge`` /
* ``service_date`` / ``cpt_codes``); ``a`` and ``b`` are the values
* from each side, rendered verbatim.
*/
export interface BatchDiffFieldDiff {
field: "status" | "total_charge" | "service_date" | "cpt_codes";
a: string | number | string[] | null;
b: string | number | string[] | null;
}
export interface BatchDiffChangedRow {
a: BatchClaimDiffSummary;
b: BatchClaimDiffSummary;
diff: BatchDiffFieldDiff[];
}
export interface BatchDiffSummary {
addedCount: number;
removedCount: number;
changedCount: number;
unchangedCount: number;
}
/**
* Full response from `GET /api/batch-diff`. The three bucket arrays
* (``added`` / ``removed`` / ``changed``) are always present (never
* absent) so the UI can index unconditionally; ``summary`` is
* precomputed by the backend so the four count cards don't have to
* derive them on the client.
*/
export interface BatchDiff {
a: BatchDiffSideMeta;
b: BatchDiffSideMeta;
added: BatchClaimDiffSummary[];
removed: BatchClaimDiffSummary[];
changed: BatchDiffChangedRow[];
summary: BatchDiffSummary;
}