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.mddocs/specs/deferred/ehr-builder-service-spec.mddocs/specs/deferred/match-progress-sse-spec.md