Skip to main content

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

ActionPermission
Read institutional context, codes, per-diem summary, referenceclaims.read
Save institutional contextclaims.update
Replace institutional codesclaims.update

No new RBAC migration — claims.update was already granted to billing operators.

Operator walkthrough — 30-day ICF stay

  1. Open the institutional claim's detail page from /claims.

  2. Click Institutional in the tab strip (only renders for 837I).

  3. 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 from rcm_reference.ub04_code (kind=BILL_TYPE / etc.). Cached for 1h client-side.
  4. 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/74 in claim_institutional_code. Out-of-window dates are flagged inline but not blocked at save time (the scrubber owns the hard rejection).
  5. DRG section: free-text DRG Code + numeric DRG Weight. Both are emitted as HI*DR segments by the 837I generator.

  6. Condition / Occurrence / Value codes: pickers backed by the same ub04_code listing endpoint. Adds and removes flush together on save (transactional REPLACE).

  7. Save Institutional Context — issues a parallel POST /institutional-context + PUT /institutional-codes pair, 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_date inclusively, 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 passing condition_codes, occurrence_codes, or value_codes on the body silently get those fields dropped — switch to PUT /institutional-codes.
  • LOA dates are not on the context row. They live as OCCURRENCE/74 rows. The UI surfaces them through the codes endpoint and writes them through the same endpoint; there is no on-disk loa_dates column.
  • Reference data lives in the master DB (rcm_reference.code_set_revenue, rcm_reference.ub04_code). Tenant pickers all hit them via masterDb (cached for the lifetime of the route layer's InstitutionalReference).
  • Knex returns DATE columns as JS Date objects by default; the repo + service helpers normalize to YYYY-MM-DD strings on the way out so JSON payloads stay calendar-date-shaped (no timezone drift on midnight UTC).

Validation

CheckExpected
Save returns 200Yes
Per-diem panelDay-level rows match input
LOA OCC-74 rowsCreated in claim_institutional_code
837I HI*DR segmentsDRG code + weight emitted

Cross-references

Next

6.4 — Batch eligibility sweeps