ADR-0020: HAPI FHIR Adoption — Deferred with Trigger-Based Evaluation¶
Status: Accepted Date: 2026-04-17 Session: 42 Context window: Clinical data interoperability strategy
Context¶
Curaway stores clinical data as FHIR R4 resources in PostgreSQL (fhir_resources table, ~904 resources in production for tenant-apollo-001). The storage uses validated fhir.resources Pydantic models, with document provenance (document_id, case_id) and versioning support. This is FHIR-compliant storage, not a FHIR-compliant REST API.
HAPI FHIR (the open-source Java reference implementation of HL7 FHIR) would provide:
- Standards-compliant FHIR REST API (search parameters, _include, _revinclude, batch/transaction bundles)
- FHIR Subscriptions (webhooks on resource changes)
- SMART on FHIR (standardized auth for healthcare apps)
- Terminology services (ValueSet, CodeSystem expansion)
- CDA/CCDA document support
- External provider interoperability — any HL7-compliant system can integrate
The question is when — not if — Curaway needs this infrastructure.
Decision¶
Defer HAPI FHIR adoption until specific triggers fire. Continue with custom FHIR storage + custom REST API through Wave 7. Add FHIR Bundle export as an intermediate option in Wave 7+.
Rationale¶
Curaway is a coordination platform, not an EHR. FHIR resources are used internally for matching, risk assessment, and explanations. External parties (hospitals, MSOs, coordinators) currently don't query patient FHIR data directly — they receive packaged documents via the forwarding service.
HAPI FHIR is a heavy addition: full Java Spring stack, standalone server, separate database. For Curaway's Python monolith on Railway, this is significant infrastructure that would not serve near-term product needs.
What works today (without HAPI)¶
| Use case | Current solution |
|---|---|
| Store clinical data | fhir_resources table with JSONB + Pydantic validation |
| Version clinical records | Existing version column, supercede logic |
| Track provenance | document_id + case_id on every resource |
| Patient chat uses clinical data | Clinical Context Agent reads from fhir_resources |
| Matching uses clinical data | Matching engine reads from fhir_resources |
| Forward records to providers | forwarding_service packages records as PDFs/documents |
Triggers for re-evaluation¶
| Trigger | Action | Stage |
|---|---|---|
| First hospital partner requests FHIR REST API access | Evaluate HAPI vs. expanding custom FHIR REST | Post Wave 3 (provider portal live) |
| Regulatory requirement (US 21st Century Cures, EU EHDS) | Adopt HAPI or equivalent | If expanding to US clinical care |
| SMART on FHIR app ecosystem need | Adopt HAPI (de facto standard for SMART) | Post-Series A |
| Provider quote workflow requires FHIR resources | Custom FHIR REST or HAPI migration | ADR-0018 Phase 1 evolution |
| 3+ countries with clinical integrations | Adopt HAPI for standardization | Series B |
Intermediate option: FHIR Bundle export¶
Before committing to HAPI, add a FHIR-compliant export endpoint:
- Patient downloads full record as a FHIR Bundle (JSON)
- One-way export, no query API
- Uses existing
fhir_resourcesdata - ~2-3 days implementation
- Satisfies most "FHIR support" requests without HAPI's complexity
This becomes part of Wave 7 scope.
Alternatives Considered¶
Alternative 1: Adopt HAPI FHIR now¶
Rejected. Adds substantial infrastructure (Java Spring, separate DB, ops burden) before product needs justify it. No external parties currently consume Curaway's FHIR data via REST.
Alternative 2: Build full FHIR REST on top of existing storage¶
Rejected for now. Medium effort (~2 weeks for baseline search + _include), but the same concerns as HAPI: no current consumers. Becomes a maintenance burden without serving real needs.
Alternative 3: Adopt HAPI but only for new clinical integrations¶
Considered, deferred. Would create dual-stack complexity (Python + Java) for limited benefit. Revisit if first provider integration requires it.
Consequences¶
Positive¶
- Focus engineering effort on Wave 1-6 product value (intake restructuring, coordinator tooling, provider portal, mobile)
- Avoid premature infrastructure complexity
- Keep deployment simple (one Python service on Railway)
- Preserve optionality — FHIR storage is already standards-compliant, migration to HAPI is a REST-layer change not a data-layer change
Negative¶
- No FHIR interop today — if a hospital asks for FHIR API access, we have to say "export only" or build it
- Custom REST API is not a standard that external developers recognize
- May need to reprioritize if an early provider integration requires FHIR
Mitigation¶
- Keep
fhir_resourcesdata FHIR-compliant (current practice, viafhir.resourcesvalidation) - Document the FHIR schema publicly in
docs/reference/fhir-resources.md - Add FHIR Bundle export in Wave 7 as bridge option
- Revisit this ADR when any trigger fires
Related ADRs¶
- ADR-0018 Multi-Tenancy Platform Architecture (Phase 1 provider flow — may surface FHIR need)
- FHIR Provenance Feature (docs/specs/fhir-provenance-feature.md) — current implementation
Review Cadence¶
Re-evaluate this decision when: - Any trigger from the table above fires - At the start of Phase 3 of ADR-0018 (facilitators + coordinators live) - Post-Series A when clinical integrations become a core revenue surface