Skip to content

2026-04-13 — Case Record Porting, DICOM Spec, Live Monitoring

Author: Srikanth Donthi (CPO/CTO) + Claude Code session Theme: Case record porting feature (full implementation), DICOM support spec, live conversation monitoring with 20 issue fixes, full subagent health audit.

Shipped to Production

Backend (PRs #145–#155)

PR What it does
#145 fix(critical): intake_answer_count never incremented + OCR failure handling for JPG/PNG uploads
#146 fix(p2): FHIR provenance from inline attachments + no-medical-interpretation prompt rule
#149 docs: DICOM support Phase 1 feature spec (586 lines, 17 tasks)
#151 docs: case record porting spec v2 — 12 audit findings fixed
#152 feat(porting): full backend — migration (document_references.case_id), case_porting_service.py, orchestrator integration, EHR rebuild case-scoped queries, 14 tests
#155 fix: P0+P1 from subagent audit — GDPR ConsentRecord for porting, LLM voice routing, tenant_id guard, bare except logging

Frontend (PRs #30–#35)

PR What it does
#30 feat(ui): clickable file attachments in chat open DocumentViewer
#31 feat(ui): document viewer from EHR drawer + all source links (z-60 modal overlay)
#35 feat(porting): PortRecordsConsentCard (12 tests), EHR drawer ported badges, rich content registration

Live Conversation Monitoring (CRW-2026-00193)

20 issues identified from monitoring a real patient conversation: - P0: Chat extractor not populating extra_metadata (intake_answer_count stuck at None) - P1: No follow-up after OCR failure, JPG images fail silently, agent re-asked laterality, medical interpretation in responses - Root cause: records_first routing path returned before _handle_intake — answer count never incremented

Code Review + Subagent Audit

Full 7-subagent audit run twice. Key findings addressed: - GDPR ConsentRecord for porting (compliance) - Hardcoded prose routed through LLM (voice) - doc_name_map tenant_id filter (platform integrity) - llm_gateway bare excepts logged (code quality)

New Feature: Case Record Porting

Patients creating a new case see a consent card listing portable records from prior closed cases. Per-document checkboxes, expiry warnings, uncertain-match badges. Behind case_record_porting_v1 Flagsmith flag.

New Spec: DICOM Support (Phase 1)

586-line spec for DICOM file support: metadata extraction, DICOM-SR parsing, Safe Harbor de-identification, procedure requirement auto-matching. Issue #147.


Session 40 Additions (Gap Report Sweep + Intake Testing Fixes)

Gap Report: 21/31 Gaps Closed (68%)

Priority Closed Total
P0 3/3 100%
P1 5/8 63%
P2 7/10 70%
P3 6/10 60%

ADR-0019: GDPR Article 17 Erasure Cascade

6 missing tables added to cascade delete: messages, conversations, cases, match_results, feedback_records, device_registrations. Redis cache flush. 31 unit + 10 integration tests.

Backend — Intake Testing Fixes (PRs #187–#189)

Fix What PR
Fix 1 Case creation reliability: registration race condition (IntegrityError catch), INTAKE_CASE_NOT_FOUND_001 error code, orchestrator error re-raise, SELECT FOR UPDATE on status transitions, auto-grant consent #187
Fix 2 Context retention: conversation window 20→50, LLM window 10→30, enriched patient context (labs, docs, risk factors, collected fields) #187
Fix 3 Matching trigger: 15-turn max before force-match, gates_v2 defaults ON when Flagsmith unreachable #188
Fix 4 Document extraction: min file size 5KB→1KB for small lab PDFs #188
Fix 5 Identity/caregiver: case_role field + migration, name mismatch detection, intake prompt role classification (v1+v2) #189

34 new backend tests across 3 test files.

Frontend — UI Stability (PR #41)

Fix What
SSE timeout 30-second max on chat stream, falls back to POST response
Blank screen Loading skeleton while PatientContext resolves, error state with retry

Security Hardening

  • Security headers middleware (CSP, HSTS, X-Frame-Options, X-Content-Type-Options)
  • Consent gate middleware (clinical_data_processing enforcement)
  • QStash HMAC signature verification with key rotation
  • Rate limiting extended to authenticated endpoints (300 req/min/tenant)
  • Event Type Registry with 35 known event types

New Error Codes

Code HTTP Description
INTAKE_CASE_NOT_FOUND_001 404 Case not found for patient/tenant
INTAKE_CONVERSATION_CREATION_FAILED_001 500 Auto-conversation creation failed
CONSENT_REQUIRED 403 clinical_data_processing consent required

Migrations Run on Production

Revision Column Table
b3c4d5e6f7g8 confidence (FLOAT) fhir_resources
c4d5e6f7g8h9 agent_name (VARCHAR 50) messages
e5f6g7h8i9j0 case_role (VARCHAR 30) cases

Deferred Specs Written

  • docs/specs/deferred/postgresql-rls-spec.md
  • docs/specs/deferred/ehr-builder-service-spec.md
  • docs/specs/deferred/match-progress-sse-spec.md