Files
cyclone/src/components/ClaimDrawer/DiagnosesList.tsx
T
Tyler 9bca4b608a feat(release): v0.2.0 — batch 837 export, ClaimCard, theme tokens
Backend:

- New POST /api/batches/{id}/export-837: regenerate X12 837 files
  for a list of claim_ids into a ZIP using HCPF file naming standards,
  with a unique interchange/group control number per export. Wire
  the clearhouse Loop 1000A (NM1*41 + PER) and per-payer receiver
  (NM1*40) blocks so the serializer no longer falls back to
  CYCLONE / RECEIVER placeholders.
- /api/parse-837 and /api/parse-835 now surface the server-side
  batch_id in both JSON and NDJSON response shapes so the frontend
  can hit batch-scoped endpoints without an extra listBatches
  round-trip.
- Filename helpers and the 837 serializer updated to match the new
  HCPF envelope; tests cover batch export, parse batch_id, and the
  serializer's control-number uniqueness guarantee.

Frontend:
- New shared components: ClaimCard, ClaimCard837, DominantKpiCard,
  EditorialNote, ExportBar, TickerTape, and a charts/ set
  (BarChart, HBarChart, SegmentedBar, AgingBars).
- New useBatchExport hook driving ExportBar's download flow against
  the new endpoint.
- ClaimDrawer, Lane, and Layout migrated from raw CSS-variable
  colors to Tailwind theme tokens (bg-card, text-foreground,
  border/60, etc.) for consistency with the rest of the instrument
  chrome; the active tab indicator gains a subtle accent glow.
- Upload, Inbox, Batches, BatchDiff, Reconciliation, and Acks pages
  reworked to compose the new shared components and consume the new
  batch-scoped API surface (notably ExportBar wired into Batches).

Tooling / Docs:
- Add audit-uiux.mjs and a docs/goodclaim.x12 sample fixture.
- Update ClaimDrawer testids and add coverage for the new
  components and the useBatchExport hook.

Rolls up into the v0.2.0 release tag.
2026-06-22 11:01:58 -06:00

83 lines
2.6 KiB
TypeScript

import type { ClaimDetail } from "@/types";
type DiagnosesListProps = {
diagnoses: ClaimDetail["diagnoses"];
};
// Minimal ICD-10 description lookup. Covers the most common codes
// likely to appear in the test fixtures; the full ICD-10 catalog is
// ~95k entries and out of scope. Codes not in this map render without
// a description (the code + qualifier still display).
const ICD10_DESCRIPTION: Record<string, string> = {
"E11.9": "Type 2 diabetes mellitus without complications",
"E11.65": "Type 2 diabetes mellitus with hyperglycemia",
"I10": "Essential (primary) hypertension",
"J45.909": "Unspecified asthma, uncomplicated",
"M54.5": "Low back pain",
"R51": "Headache",
"Z00.00": "General adult medical examination",
};
function describe(code: string): string | null {
return ICD10_DESCRIPTION[code] ?? null;
}
/**
* Diagnoses list for the claim detail drawer (SP4).
*
* Inline list of mono codes + (when present) qualifier + (when the
* code is in our small ICD-10 dictionary) a short human description.
* The dictionary is intentionally tiny — the drawer's purpose is to
* show what the claim says, not to be an ICD-10 reference.
*/
export function DiagnosesList({ diagnoses }: DiagnosesListProps) {
return (
<section className="flex flex-col gap-3 px-6 py-4">
<h3
data-testid="section-label"
className="eyebrow text-muted-foreground"
>
Diagnoses ({diagnoses.length})
</h3>
{diagnoses.length === 0 ? (
<p
data-testid="diagnoses-empty"
className="text-sm text-muted-foreground"
>
No diagnoses
</p>
) : (
<ul className="flex flex-col gap-2" data-testid="diagnoses-list">
{diagnoses.map((d, i) => {
const desc = describe(d.code);
return (
<li
key={`${d.code}-${i}`}
data-testid="diagnosis-item"
className="flex items-baseline gap-3 text-sm"
>
<span
className="mono text-foreground font-medium"
>
{d.qualifier ? `${d.qualifier} ${d.code}` : d.code}
</span>
{desc ? (
<>
<span
className="h-px w-3 bg-border/60"
aria-hidden
/>
<span className="text-muted-foreground italic">
{desc}
</span>
</>
) : null}
</li>
);
})}
</ul>
)}
</section>
);
}