Steer-04: Clinical Context Autochain — Document → Parse → Extract → FHIR → Graph → Embedding¶
Read first:
specs/sdd-mvp/04-agent-pipeline.md,specs/sdd-mvp/07-document-pipeline.md,specs/sdd-mvp/05-ehr-builder.md
Context & Goal¶
Wire the complete auto-chain: when a document is uploaded and parsed, the Clinical Context Agent automatically triggers, extracts entities, creates FHIR resources, updates the Neo4j graph, indexes in Qdrant, and updates the EHR — all async, non-blocking, with SSE status updates at each step.
Backend (curaway-ai/curaway-backend)¶
Step 1: Verify Document Upload Pipeline¶
Ensure the existing upload pipeline emits correct events:
- POST /uploads/confirm → creates document_reference (status: uploaded) → emits document_uploaded
- QStash handler receives callback → runs PyMuPDF → updates status to parsed → emits document_parsed
- If PyMuPDF fails → try Unstructured.io → try Claude Vision → status failed if all fail
Step 2: Auto-Chain Trigger¶
In QStash document parse handler (or as a new QStash callback):
- On document_parsed event, check if extracted_text has clinical content (> 100 chars, not just headers)
- If clinical content: dispatch Clinical Context Agent via QStash (non-blocking)
- Update document analysis_status to analyzing
- Emit document_analyzing event (SSE: status update)
Step 3: Clinical Context Agent Integration¶
Ensure Clinical Context Agent:
1. Receives document_id + patient_id + tenant_id + extracted_text
2. Runs LangGraph: extract_clinical_entities → map_to_medical_codes → generate_fhir_resources → store_resources
3. Each FHIR resource stored → emits fhir_resource_created event
4. Updates document analysis_status to completed
5. Emits clinical_entities_extracted event with summary
Step 4: Post-FHIR Graph + Embedding Updates¶
Create event handler for fhir_resource_created:
- Neo4j: Add/update nodes and relationships
- New Condition → (Patient)-[:DIAGNOSED_WITH]->(Condition) + (Condition)-[:INDICATED_FOR]->(Procedure) if procedure can be inferred
- New Procedure → link to patient
- New AllergyIntolerance → (Patient)-[:HAS_ALLERGY]->(Allergy)
- Qdrant: Re-generate patient clinical embedding (concatenate all conditions + procedures + meds as text → Voyage AI embed → upsert)
- EHR Builder: Call merge_clinical_entities() to update patient record
Step 5: End-to-End Chain Test¶
Create integration test that: 1. Uploads a sample radiology report (mock PyMuPDF extraction) 2. Verifies document status transitions: uploaded → parsing → parsed → analyzing → analyzed 3. Verifies FHIR Condition created with correct ICD code 4. Verifies Neo4j has new patient→condition relationship 5. Verifies intake_progress increased 6. Verifies SSE events emitted at each step
Backend Verification¶
python -m pytest tests/test_clinical_autochain.py -v
# Manual: upload a PDF, watch events table for the full chain
Frontend (curaway-ai/curaway-frontend)¶
Step 1: Document Status Cards in Conversation¶
Update src/components/chat/DocumentCard.tsx:
- Show real-time status transitions via SSE document_update events
- States: uploading (progress bar) → parsing (spinner) → analyzing (pulsing) → complete (green check + extracted entities)
- On complete: show extracted findings summary (conditions found, labs extracted)
- "View Details" link opens document detail in left panel
Step 2: Upload Flow in Chat Input¶
Update src/components/chat/ChatInput.tsx:
- File attachment button (📎) triggers native file picker
- On file select: show file name + upload progress in conversation
- Execute presign → upload → confirm flow
- Insert DocumentCard into conversation thread
- SSE takes over for status updates after confirm
Step 3: Analysis Results Rendering¶
When document analysis completes, render results inline: - Condition badges with ICD codes - Lab value table (if observations extracted) - Medication list (if medications found) - Anomaly flags (expired, out of range) with warning styling
Frontend Verification¶
npm run build
npx tsc --noEmit
# Manual: upload a PDF in chat, watch status transitions, verify findings display
Checklist¶
- [ ] No new migrations (document_references table exists)
- [ ] Seed data: sample radiology report for testing
- [ ] Error codes: CHAIN_PARSE_001, CHAIN_EXTRACT_001, CHAIN_GRAPH_001
- [ ] Feature flag:
clinical_autochain— disable to decouple document parsing from agent extraction - [ ] Env vars: verify VOYAGE_AI_API_KEY, QDRANT_URL, NEO4J_URI all set
- [ ] Swagger: no new endpoints, but document status field values documented
- [ ] Unit tests: full chain integration test
- [ ] PostHog:
document_uploaded_in_chat,analysis_completed,findings_viewed - [ ] Loading states: each status transition has distinct visual
- [ ] Mobile: document cards responsive, upload works from mobile camera roll
- [ ] CLAUDE.md: update with autochain flow description
- [ ] Rollback: disable
clinical_autochainflag → documents parsed but not auto-analyzed