feat(frontend): add listUnmatched, matchRemit, unmatchClaim to api
This commit is contained in:
@@ -17,6 +17,8 @@
|
||||
* - `health()` GETs `/api/health` and returns `{ status, version }`.
|
||||
* - `listBatches / getBatch / listClaims / listRemittances / listProviders
|
||||
* / listActivity` are plain JSON GETs against the persistence surface.
|
||||
* - `listUnmatched / matchRemit / unmatchClaim` hit the reconciliation
|
||||
* surface. POSTs throw `ApiError` so callers can branch on `.status`.
|
||||
*/
|
||||
|
||||
import type {
|
||||
@@ -24,6 +26,7 @@ import type {
|
||||
ClaimPayment,
|
||||
Envelope,
|
||||
FinancialInfo,
|
||||
MatchResponse,
|
||||
NdjsonEvent,
|
||||
ParseResult837,
|
||||
ParseResult835,
|
||||
@@ -31,6 +34,8 @@ import type {
|
||||
Payer835,
|
||||
Payee835,
|
||||
ReassociationTrace,
|
||||
UnmatchedClaim,
|
||||
UnmatchedResponse,
|
||||
BatchSummary as ParserBatchSummary,
|
||||
} from "@/types";
|
||||
|
||||
@@ -147,6 +152,16 @@ function notConfiguredError(): Error {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Error thrown for non-2xx responses. Carries the HTTP `status` so callers can
|
||||
* branch on it (e.g. 404 vs 500) without parsing the message string.
|
||||
*/
|
||||
export class ApiError extends Error {
|
||||
constructor(public status: number, message: string) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
function joinUrl(path: string): string {
|
||||
return `${BASE_URL.replace(/\/$/, "")}${path}`;
|
||||
}
|
||||
@@ -436,6 +451,61 @@ async function listActivity<T = unknown>(
|
||||
return (await res.json()) as PaginatedResponse<T>;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Public surface — reconciliation endpoints (sub-project 2)
|
||||
// POSTs throw `ApiError` so callers can inspect `.status`; the GET is shaped
|
||||
// like the other list endpoints above.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
async function listUnmatched(): Promise<UnmatchedResponse> {
|
||||
if (!isConfigured) throw notConfiguredError();
|
||||
const res = await fetch(joinUrl(`/api/reconciliation/unmatched`), {
|
||||
headers: { Accept: "application/json" },
|
||||
});
|
||||
if (!res.ok) {
|
||||
const detail = await readErrorBody(res);
|
||||
throw new ApiError(res.status, detail || res.statusText);
|
||||
}
|
||||
return (await res.json()) as UnmatchedResponse;
|
||||
}
|
||||
|
||||
async function matchRemit(
|
||||
claimId: string,
|
||||
remitId: string
|
||||
): Promise<MatchResponse> {
|
||||
if (!isConfigured) throw notConfiguredError();
|
||||
const res = await fetch(joinUrl(`/api/reconciliation/match`), {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Accept: "application/json",
|
||||
},
|
||||
body: JSON.stringify({ claim_id: claimId, remit_id: remitId }),
|
||||
});
|
||||
if (!res.ok) {
|
||||
const detail = await readErrorBody(res);
|
||||
throw new ApiError(res.status, detail || res.statusText);
|
||||
}
|
||||
return (await res.json()) as MatchResponse;
|
||||
}
|
||||
|
||||
async function unmatchClaim(claimId: string): Promise<{ claim: UnmatchedClaim }> {
|
||||
if (!isConfigured) throw notConfiguredError();
|
||||
const res = await fetch(joinUrl(`/api/reconciliation/unmatch`), {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Accept: "application/json",
|
||||
},
|
||||
body: JSON.stringify({ claim_id: claimId }),
|
||||
});
|
||||
if (!res.ok) {
|
||||
const detail = await readErrorBody(res);
|
||||
throw new ApiError(res.status, detail || res.statusText);
|
||||
}
|
||||
return (await res.json()) as { claim: UnmatchedClaim };
|
||||
}
|
||||
|
||||
export const api = {
|
||||
isConfigured,
|
||||
baseUrl: BASE_URL,
|
||||
@@ -448,4 +518,7 @@ export const api = {
|
||||
listRemittances,
|
||||
listProviders,
|
||||
listActivity,
|
||||
listUnmatched,
|
||||
matchRemit,
|
||||
unmatchClaim,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user