Health Tech Companies · healthtech-interoperability
Interoperability requirements — the round trip, live
Each step below ran just now against the sandbox. Links open the real resources.
-
done Form, response and patient in the exchange layer in hapi-fhir
A blood-pressure Questionnaire (as the Form Builder would publish it) and a completed QuestionnaireResponse (as LForms would submit it), for a synthetic patient.
-
done Observation extracted from the response in hapi-fhir
SDC extraction: the two answers become one Observation with systolic and diastolic components (LOINC 8480-6 / 8462-4). Done server-side here; LForms can do it in the browser.
Show payload
{ "resourceType": "Observation", "id": "ehds-uc08-bp", "status": "final", "code": { "coding": [ { "system": "http://loinc.org", "code": "85354-9", "display": "Blood pressure panel" } ] }, "subject": { "reference": "Patient/ehds-uc08-patient" }, "effectiveDateTime": "2026-09-18T09:00:00Z", "derivedFrom": [ { "reference": "QuestionnaireResponse/ehds-uc08-bp-response" } ], "component": [ { "code": { "coding": [ { "system": "http://loinc.org", "code": "8480-6", "display": "Systolic blood pressure" } ] }, "valueQuantity": { "value": 128, "unit": "mm[Hg]", "system": "http://unitsofmeasure.org", "code": "mm[Hg]" } }, { "code": { "coding": [ { "system": "http://loinc.org", "code": "8462-4", "display": "Diastolic blood pressure" } ] }, "valueQuantity": { "value": 82, "unit": "mm[Hg]", "system": "http://unitsofmeasure.org", "code": "mm[Hg]" } } ] } -
done Mapping definition loaded in openfhir
The openEHR template plus a declarative FHIR Connect model and context mapping (shown in full below). Nothing is hand-coded per field.
-
done FHIR → openEHR in openfhir
The Observation mapped into a FLAT openEHR composition of the Blood Pressure template.
Show payload
{ "blood_pressure/blood_pressure/any_event:0/systolic|magnitude": 128.0, "blood_pressure/blood_pressure/any_event:0/systolic|unit": "mm[Hg]", "blood_pressure/blood_pressure/any_event:0/diastolic|magnitude": 82.0, "blood_pressure/blood_pressure/any_event:0/diastolic|unit": "mm[Hg]", "blood_pressure/blood_pressure/a24_hour_average/position|code": "at1000", "blood_pressure/blood_pressure/a24_hour_average/confounding_factors": "confounding factor", "ctx/language": "en", "ctx/territory": "DE", "ctx/composer_name": "EHDS Sandbox seeder", "ctx/time": "2026-09-18T09:00:00Z", "blood_pressure/blood_pressure/any_event:0/time": "2026-09-18T09:00:00Z" } -
failed Stored in the openEHR CDR in ehrbase
422 Client Error: Unprocessable Entity for url: https://cdr.sandbox.ehds.technicise.eu/ehrbase/rest/openehr/v1/ehr/3240c9d5-ce9b-414e-aa06-ec0c8ffbe96b/composition?templateId=Blood+Pressure
The mapping definition
FHIR Connect — declarative and reviewable. This is the whole bridge between the two standards for this template.
context + model mapping (YAML)
engine: FHIRConnect/v0.0.1
type: context
metadata:
name: "Blood Pressure"
version: 0.0.1a # version of this particular mapping
spec: # schema specific to the FHIRConnect v0.0.1 engine
system: FHIR
version: R4
context:
profileUrl: "Observation"
templateId: "Blood Pressure"
archetypes:
- "openEHR-EHR-OBSERVATION.blood_pressure.v2"
start: "openEHR-EHR-OBSERVATION.blood_pressure.v2"
# ---- model mapping ----
# Copyright 2022 Better Ltd (www.better.care)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
engine: FHIRConnect/v0.0.1
type: model
metadata:
name: openEHR-EHR-OBSERVATION.blood_pressure.v2
version: 0.0.1a # version of this particular mapping
spec: # schema specific to the FHIRConnect v0.0.1 engine
system: FHIR
version: R4
openEhrConfig:
archetype: openEHR-EHR-OBSERVATION.blood_pressure.v2
fhirConfig:
structureDefinition: http://hl7.org/fhir/StructureDefinition/Observation
# Actual mapping points:
mappings:
# Each mapping has a unique (self documenting) name.
- name: "patient"
# A simple mapping, which maps one attribute to another.
with:
# Access the FHIR resource, either in input or output direction.
fhir: "$resource.subject.reference"
# Some context variable are necessary to be accessible from the mapping.
openehr: "$archetype.$ehr"
# Another mapping which maps on a met condition. This condition is used to identify
# the correct "component" in the FHIR resource (array).
- name: "systolic"
with:
fhir: "$resource.component.value"
openehr: "$archetype/data[at0001]/events[at0006]/data[at0003]/items[at0004]"
type: "QUANTITY"
fhirCondition:
# One of the codings has to be the matching LOINC or SNOMED code.
# incl. implicit handling of arrays, as ".coding" is a set of codings.
# -> Here the backwards direction is ambiguous. The program will interpret "one of"
# as "put those in the target resource" if the direction is openEHR->FHIR.
targetRoot: "$resource.component" # Scope of object for 'condition'
targetAttribute: "code.coding.code" # Actual attribute to check for 'condition'
operator: "one of"
criteria: "[$loinc.8480-6, $snomed.271649006]"
identifying: true # The *one* condition able to identify FHIR input to match this mapping
# The next step allows a mapping to have a list of succeeding mappings, which
# are executed in the same scope of the parent mapping.
- name: "diastolic"
with:
fhir: "$resource.component.value"
openehr: "$archetype/data[at0001]/events[at0006]/data[at0003]/items[at0005]"
type: "QUANTITY"
fhirCondition:
targetRoot: "$resource.component" # Scope of object for 'condition'
targetAttribute: "code.coding.code" # Actual attribute to check for 'condition'
operator: "one of"
criteria: "[$loinc.8462-4]"
- name: "clinical interpretation"
with:
fhir: "$resource.component.interpretation.text"
openehr: "$archetype/data[at0001]/events[at0006]/data[at0003]/items[at1059]"
type: "STRING"
- name: "description"
with:
fhir: "$resource.code.text"
openehr: "$archetype/data[at0001]/events[at0006]/data[at0003]/items[at0033]"
type: "STRING"
- name: "position hardcoded to openehr"
with:
openehr: "$archetype/data[at0001]/events[at1042]/state[at0007]/items[at0008]|code"
value: "at1000"
type: "STRING"
- name: "confounding_factors hardcoded to openehr"
with:
openehr: "$archetype/data[at0001]/events[at1042]/state[at0007]/items[at1052]"
value: "confounding factor"
type: "STRING"
- name: "performer hardcoded in fhir"
with:
fhir: "$resource.performer.as(Reference).display"
value: "John Doe"
type: "STRING"
- name: "location"
with:
fhir: "$resource.bodySite.coding"
openehr: "$archetype/protocol[at0011]/items[at0014]"
type: "CODING"
fhirCondition:
targetRoot: "$resource.bodySite"
targetAttribute: "text"
operator: "one of"
criteria: "[THIS IS LOCATION OF MEASUREMENT]"Staged records: Patient/ehds-uc08-patient, Questionnaire/ehds-uc08-bp, QuestionnaireResponse/ehds-uc08-bp-response, Observation/ehds-uc08-bp, openFHIR mapping openEHR-EHR-OBSERVATION.blood_pressure.v2