HL7 v2 → FHIR (ISiK) mapping & conformance validator. FHIRgate ingests legacy HL7 v2 ADT hospital messages, maps them to ISiK‑profiled FHIR R4, validates conformance against the official gematik ISiK Basismodul using the official HL7 validator, and returns a pass/fail readiness gate with AI‑explained defects.
⚕️ Non‑diagnostic demonstrator · synthetic data only · not certified software. See
docs/intended-use.md.
German hospitals run internally on HL7 v2, but regulation now requires that data to be exposed as ISiK‑conformant FHIR so it can flow into national systems — the ePA (ePA für alle; hospital sanctions from April 2026), the Telematik Infrastructure, and eventually the European Health Data Space (EHDS). The catch: a resource can be valid FHIR yet fail ISiK (missing mandatory fields, wrong code systems like ICD‑10 vs ICD‑10‑GM). FHIRgate is the missing checkpoint: it translates v2 → FHIR and proves conformance — stamping GO / NO‑GO — before the data leaves the building. Same "readiness‑gate" pattern as its sibling project Heltig (for DICOM/PACS).
flowchart LR
H["HL7 v2 ADT<br/>A01 / A04 / A08"] --> P[Parser]
P --> M["Mapper<br/>ISiK FHIR R4"]
M --> V["Official HL7 validator<br/>+ gematik ISiK package"]
V --> G{Readiness gate}
G -->|errors| NOGO["⛔ BLOCKED · NO-GO"]
G -->|clean / warnings| GO["✅ GO"]
G --> DB[("PostgreSQL")]
DB --> API["REST API + Streamlit dashboard"]
V -. defects .-> EX["Claude explainer"]
EX -. explanations + fixes .-> API
The verdict is gematik's — produced by the official validator running
de.gematik.isik-basismodul#4.0.3, not hand‑rolled. The LLM only explains defects; it never
changes the verdict.
One command (Docker):
docker compose up --build # api :8000 · dashboard :8501 · validator · postgres
# → http://localhost:8000/docs and http://localhost:8501Local dev:
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements-dev.txt
docker build -t fhirgate-validator ./validator # once
uvicorn app.main:app --reload
pytestcurl -s -X POST localhost:8000/api/v1/ingest -H "Content-Type: text/plain" \
--data-binary @data/samples/adt_a01_blocked.hl7 | jq '{verdict, counts}'{ "verdict": "BLOCKED", "counts": { "blocking": 3, "warnings": 2, "information": 3 } }…with errors like ISiK-enc-5: 'In-Durchführung befindliche Kontakte sollten einen Start-Zeitpunkt angeben' — a real ISiK invariant. Try adt_a01_ready.hl7 for a GO. Full path:
docs/demo-walkthrough.md.
| Method & path | Purpose |
|---|---|
POST /api/v1/ingest |
Ingest one HL7 v2 ADT message → ISiK readiness verdict (persisted) |
GET /api/v1/runs |
List recent validation runs |
GET /api/v1/runs/{id} |
One run with mapped bundle + defects |
POST /api/v1/runs/{id}/explain |
AI explanation + suggested fix per defect |
GET /health |
Liveness |
Interactive docs at /docs; Postman collection at
docs/FHIRgate.postman_collection.json.
HL7 v2 parsing · FHIR R4 + ISiK profiling & conformance · ICD‑10‑GM terminology · FastAPI · PostgreSQL / SQLAlchemy · Docker / docker‑compose · GenAI (Claude) · pytest + GitHub Actions CI.
In: ADT A01/A04/A08 → Patient/Encounter/Condition, ISiK validation, readiness gate, REST API, dashboard, synthetic data. Out: real patient data, diagnostic logic, live TI/PACS/RIS integration, gematik certification, production auth.
Extend the same gate to ePA MIOs (KBV medication plan / vaccination record) and the EHDS Patient Summary (EEHRxF).
- Field‑level mapping:
docs/MAPPING.md - Execution plan:
docs/EXECUTION_PLAN.md - Demo walkthrough:
docs/demo-walkthrough.md - Intended use:
docs/intended-use.md
MIT — see LICENSE.