fi-fhir: Profile-Driven Healthcare Integration
How fi-fhir separates feed-specific variance from parsing, semantic events, durable delivery, and workflow policy—and where the pre-1.0 platform still has work to do.
- Published
- Materially updated
- Reading time
- 6 min read
- Context
- Internal platform
- Delivery window
- Active development
Related system: fi-fhirthe healthcare integration toolkit, its docs and playground
Evidence at a glance
Context markers for the implementation. Measurement windows, caveats, and remaining gaps are documented in the study.
- Input Families
- 4
- HL7v2, CSV/flat files, EDI X12, and CDA/CCDA in the current CLI surface
- Ingress Paths
- 3
- authenticated HTTP, MLLP, and S3/SFTP batch implementations
- Release State
- Pre-1.0
- parsing and delivery are implemented; release and operational checks remain
Implementation stack
Backend
- Go
- CEL
Database
- PostgreSQL
Infrastructure
- YAML
- FHIR R4
- HL7v2
- EDI X12
Frontend
- SvelteKit
Monitoring
- Prometheus
Healthcare interface engines tend to accumulate exceptions until the exceptions become the architecture. A feed says HL7v2 2.5.1, sends older data types, adds local Z-segments, and assigns business meaning that exists nowhere in the base standard.
fi-fhir is my attempt to put that variance in an explicit place. A Source Profile describes what one feed means and what it is allowed to get wrong. Parsers turn supported formats into canonical events. Workflows decide where those events go. The production path adds durable acceptance, idempotency, delivery attempts, and replay.
I have implemented the parsing and durable-delivery foundations, session-based authoring, workflow simulation, and reviewable publication. Full release journeys and deployment-specific validation remain prerequisites for 1.0.
TL;DR
- Each feed profile records source-specific meaning, tolerance, and mapping rules.
- Parsing, semantic extraction, routing, and delivery are separate contracts. That makes tolerance and failure policy reviewable.
- Recoverable anomalies become structured warnings only when policy permits. Unrecoverable or unauthorized input still fails closed.
- The current backend implements authenticated HTTP, MLLP, and S3/SFTP batch paths around a shared durable processor.
- The evidence here covers implemented behavior and repository tests. It does not establish parser coverage across all vendor feeds or a reduction in onboarding time.
Context and evidence
This study reflects the following internal workspace sources as of August 30, 2026:
libs/fi-fhir/README.mdfor the supported format, workflow, and runtime surface;libs/fi-fhir/ROADMAP.mdfor the current maturity statement and remaining release gates;libs/fi-fhir/internal/parser/,pkg/events/, andpkg/fhir/for parsing and canonical-event behavior;libs/fi-fhir/internal/integration/andcmd/fi-fhir/for durable ingestion and delivery; and- the fi-fhir deployment in
platform/gitops/for what is actually activated in the cluster.
The source repository contains tests for parsers, contracts, PostgreSQL-backed durability, transport behavior, and failure recovery. This study does not claim customer throughput, onboarding time, clinical accuracy, or a production SLO.
Delivery update — September 20, 2026
The merged implementation adds Kafka, Redis Streams, and Google Cloud Pub/Sub
backends with shared handlers, acknowledgment-aware consumers, and an outbox
adapter. workflow consume processes canonical events from a broker through
configured workflow routes. Source Profiles can select the event families
emitted by CDA/CCDA parsing.
FHIR delivery now supports conditions, procedures, immunizations, vital signs, medication requests, and allergies in addition to admission and lab events. Workflow transactions resolve Patient/Encounter references, while durable clinical writes use the persisted canonical event ID to keep retries stable and sibling records separate. A new event ID still creates a new clinical resource; correction merging needs a separate identity policy.
The final feature CI run passed 53 automatic jobs. Live HAPI acceptance ran fourteen top-level tests, including nine FHIR subtests, with no skips; broker, PostgreSQL/MinIO, and two-replica tests also passed. This evidence supports the implemented delivery contract. It does not establish official US Core conformance or production capacity.
See the roadmap, event backend guide, and FHIR output guide. The underlying merge and CI records are linked there and require internal GitLab access. This update does not revalidate the August deployment observations below.
The challenge
Standards reduce variation; they do not remove it. A practical integration still has to answer questions the wire format cannot:
- Which repeated identifier is authoritative for this feed?
- Is a missing segment fatal, tolerable, or grounds for quarantine?
- Does an ADT A01 mean inpatient admission or outpatient registration here?
- How should local codes map to LOINC, SNOMED CT, or ICD-10?
- What acknowledgment is safe before a message is durably recorded?
- Which exact profile and workflow revision handled a message?
If those answers live in parser branches, each feed needs a code change. If they live only in an operator’s memory, the next person cannot review or reproduce them.
Constraints
| Constraint | Design consequence |
|---|---|
| Feeds drift from declared standards | Tolerance belongs in versioned, source-specific policy. |
| Protected health information (PHI) is sensitive | Logs, browser flows, errors, and traces need explicit redaction boundaries. |
| Upstreams retry and duplicate | Acceptance needs deterministic identity and idempotency. |
| Downstreams fail independently | Delivery needs durable attempts, bounded retry, circuit breaking, and replay. |
| Mappings change over time | The exact profile and workflow revision must remain reconstructable. |
| Operators need to inspect failures | Diagnostics need provenance without casually copying raw PHI across systems. |
Decisions and implementation
Put feed variance in Source Profiles
A Source Profile owns expectations and tolerated drift for one source. It can describe delimiter handling, missing segments, Z-segment extraction, identifier normalization, terminology mappings, and event classification rules.
The parser receives that profile; it does not guess a universal tolerance level. A permissive development feed and a strict production feed can use the same parsing code with different policy.
Separate bytes, syntax, and meaning
The parsing model has three conceptual phases:
- Normalize bytes: line endings, encoding, and preservation of the original payload where policy allows.
- Parse syntax: format delimiters, repetitions, components, escapes, and extensions.
- Extract semantics: identifiers, encounters, observations, claims, and other canonical event data.
This separation helps locate a failure. “The payload could not be decoded,” “the segment is malformed,” and “the source lacks a usable patient identifier” are different problems and should not collapse into one parse error.
Make warnings structured and bounded
The HL7v2 parser records ParseWarning values with a phase, code, message, and path. Warnings travel with event metadata so they can drive quality review.
“Warnings over errors” is not a blanket rule. A profile may tolerate a recoverable anomaly. Authentication failures, exceeded bounds, missing required identity, or an inability to produce a valid event still stop processing.
Admit once, then deliver durably
The production processor resolves an exact immutable revision, parses the message, records a receipt and canonical event, and admits delivery work through PostgreSQL. Retries and circuit state live on the delivery side. Dead-letter queue (DLQ) operations support investigation and controlled replay.
HTTP, Minimal Lower Layer Protocol (MLLP), and batch sources share that processor. This avoids three transports quietly implementing three meanings of “accepted.”
Separate authoring from the clinical data plane
The SvelteKit Mapping Studio supports inspection, diagnostics, lineage, and authoring flows. The current roadmap deliberately limits what is considered production-complete. Durable sessions, streaming diagnostics, workflow simulation, reviewable publication, and deployment controls are implemented. The full set of supported release journeys still needs acceptance evidence.
Optional large-language-model features assist with explanation or suggestions. They are not the source of truth for deterministic parsing or clinical routing.
Outcomes and measurement context
A shared semantic boundary
The current CLI parses four input families: HL7v2, CSV/flat files, EDI X12, and CDA/CCDA. The canonical event model lets workflow policy refer to business events instead of format-specific coordinates. FHIR R4 mapping is an output capability, not evidence that every source is natively FHIR.
One durable path across transports
Repository integration tests exercise exact revision resolution, duplicate handling, restart behavior, durable PostgreSQL admission, MLLP framing and acknowledgments, and S3/SFTP checkpoint recovery. The result is implementation evidence for those invariants, not a claim about production message volume.
Honest deployment scope
The August 30 deployment review proved a narrower preview and containment boundary than the full repository could express. In particular, the roadmap says production activation for some runtime paths remains intentionally pending. Shipped code and activated operations are tracked separately.
Limits and open work
- fi-fhir has not passed its full 1.0 security, accessibility, latency, throughput, disaster-recovery, and upgrade gates.
- Profile authoring and terminology governance still require domain expertise and review.
- Authorization, PHI retention, recovery, and multi-replica controls have repository proofs; supported-deployment certification and the remaining release budgets still need evidence.
- The Mapping Studio does not yet complete every author-test-publish-deploy journey in the roadmap.
- Format support is not conformance for every transaction, implementation guide, or vendor variation. Supported journeys need explicit fixtures and acceptance criteria.
Takeaways
- Model the feed, not just the format. Local meaning and tolerated drift need a versioned owner.
- Keep failure layers distinct. Byte, syntax, semantic, policy, and delivery failures require different responses.
- Acknowledge only durable work. Transport success is not the same as accepted, replayable processing.
- Preserve exact revisions. An operator should be able to reconstruct which rules handled a message.
- State maturity plainly. Describe the implemented paths and the release checks that remain.
The current documentation is available under fi-fhir docs, with browser-based examples in the fi-fhir playground.
Working through a similar constraint?
I am happy to compare implementation notes, tradeoffs, and the evidence you would want before shipping.