Institutional context UI
Outcome
Institutional claims have correctly entered stay context (admit/discharge, covered/non-covered days, LOA, DRG, condition / occurrence / value codes) and the per-diem accumulation panel matches expectation.
Prerequisites
| Action | Permission |
|---|---|
| Read institutional context, codes, per-diem summary, reference | claims.read |
| Save institutional context | claims.update |
| Replace institutional codes | claims.update |
No new RBAC migration — claims.update was already granted to billing
operators.
Operator walkthrough — 30-day ICF stay
Open the institutional claim's detail page from
/claims.Click Institutional in the tab strip (only renders for 837I).
Fill the Stay section:
Admit Date,Discharge Date— drives the inclusive day count shown in the read-only "Stay Length" field.Bill Type,Admit Type,Admit Source,Patient Discharge Status— picker options come fromrcm_reference.ub04_code(kind=BILL_TYPE / etc.). Cached for 1h client-side.
Coverage section:
Covered Days+Non-Covered Days— must sum to inclusive stay length when both are populated; UI surfaces a validation error otherwise.- LOA Dates — add one date at a time. Each value persists as
OCCURRENCE/74inclaim_institutional_code. Out-of-window dates are flagged inline but not blocked at save time (the scrubber owns the hard rejection).
DRG section: free-text
DRG Code+ numericDRG Weight. Both are emitted asHI*DRsegments by the 837I generator.Condition / Occurrence / Value codes: pickers backed by the same
ub04_codelisting endpoint. Adds and removes flush together on save (transactional REPLACE).Save Institutional Context — issues a parallel
POST /institutional-context+PUT /institutional-codespair, then re-hydrates the form from the refetched claim detail.
Per-diem accumulation panel
Below the editor, the panel renders the day-level breakdown returned by
GET /api/v1/claims/:id/per-diem-summary. For each accommodation claim
line the panel:
- Expands
from_date → to_dateinclusively, one row per day. - Tags the row LOA when the date appears in
claim_institutional_code(OCCURRENCE/74). - Shows per-diem rate =
chargeCents / units(display rounding matches what the 837I emitter put on the line). - Sums covered, non-covered, LOA day counts plus accommodation / ancillary cents in the totals strip.
Ancillary lines render as a single anchored row (no day fanning).
Unknown revenue codes display as the literal code with category
"UNKNOWN" — usually a sign that rcm_reference.code_set_revenue needs
an ingestion update for that state.
Reconciling covered_days vs. inferred days
The summary's coveredDays total prefers an explicit
claim_institutional_context.covered_days value when set; otherwise it
infers (accommodation_days - LOA_days). If the operator-entered split
disagrees with the line data, the UI displays the override and counts
on the scrubber's InstitutionalStayStage to reject the inconsistency
at submission time — this UI is intentionally non-prescriptive about
which side is right.
Pitfalls
- Column allowlist on
setInstitutionalContext. Old callers passingcondition_codes,occurrence_codes, orvalue_codeson the body silently get those fields dropped — switch toPUT /institutional-codes. - LOA dates are not on the context row. They live as
OCCURRENCE/74rows. The UI surfaces them through the codes endpoint and writes them through the same endpoint; there is no on-diskloa_datescolumn. - Reference data lives in the master DB
(
rcm_reference.code_set_revenue,rcm_reference.ub04_code). Tenant pickers all hit them viamasterDb(cached for the lifetime of the route layer'sInstitutionalReference). - Knex returns DATE columns as JS
Dateobjects by default; the repo + service helpers normalize toYYYY-MM-DDstrings on the way out so JSON payloads stay calendar-date-shaped (no timezone drift on midnight UTC).
Validation
| Check | Expected |
|---|---|
| Save returns 200 | Yes |
| Per-diem panel | Day-level rows match input |
| LOA OCC-74 rows | Created in claim_institutional_code |
837I HI*DR segments | DRG code + weight emitted |
Cross-references
- Per-diem & institutional billing for backend semantics.