Skip to content

openEHR to BFF

openEHR to BFF - Experimental

This mapping is still experimental. It currently documents the implemented openEHR -> BFF behavior for EHRbase-style canonical JSON/YAML compositions and may change as more openEHR payloads are tested. Starting with v0.31, we used LLM assistance for part of the mapping work.

The current mapper groups openEHR input by patient identity before mapping. Patient identity must be resolvable from the payload or envelope, and multiple compositions for the same patient are aggregated into one Beacon individual. For raw composition arrays, automatic splitting uses only embedded patient-scoped identifiers such as ehr_status.subject.external_ref.id.value or PARTY_SELF.external_ref.id.value; composition-level ids are not used as patient keys.

Terms with an external defining_code keep their source CURIE. Uncoded DV_TEXT terms are emitted with synthetic openEHR: ids so Beacon ontology terms still have both id and label.

Schemas and source profile

Version 0.31

Starting with v0.31, this mapping table may be drafted or refined with LLM assistance to carry part of the heavy schema-mapping load. When the openEHR source material is especially dense or ambiguous, the documented default is gpt-5.4 with high reasoning, followed by human review.

Target model: BFF

Entity: individuals

Terms

id

Source field Target field Notes
patient.id id Preferred patient envelope id
id id Accepted top-level envelope id
ehr_status.subject.external_ref.id.value id Accepted patient identifier from ehr_status
ehr_id.value / ehr_id id Accepted openEHR envelope identifier after ehr_status.subject.external_ref.id.value
PARTY_SELF.external_ref.id.value id Accepted when present inside a canonical composition
multiple input documents with the same resolved patient id one individual.id Compositions are grouped before mapping
raw composition arrays with multiple embedded patient ids multiple individual.id values Split only by embedded patient-scoped identifiers; composition-level ids are ignored
missing resolvable patient id none Conversion fails

sex

Source field Target field Notes
administrative gender code male sex Mapped to NCIT:C20197 / Male
administrative gender code female sex Mapped to NCIT:C16576 / Female
missing administrative gender none Conversion fails

info

Source field Target field Notes
compositions[] info.openehr.compositions Full canonical source compositions are preserved
multiple documents for the same patient info.openehr.compositions Concatenated into one patient-scoped list
generated conversion metadata info.convertPheno Added unless --test is used

diseases

Source field Target field Notes
openEHR-EHR-EVALUATION.problem_diagnosis.v1 / ELEMENT["Problem/Diagnosis name"] diseases.diseaseCode DV_CODED_TEXT keeps its external CURIE; DV_TEXT gets a synthetic openEHR: id
source evaluation node diseases._info.openEHR Exact source node is preserved for provenance

measures

Source field Target field Notes
openEHR-EHR-OBSERVATION.lab_test-result.v1 or openEHR-EHR-OBSERVATION.laboratory_test_result.v1 / ELEMENT["Test result name"|"Test name"|"Analyte name"] measures.assayCode DV_CODED_TEXT keeps its external CURIE; DV_TEXT gets a synthetic openEHR: id
same laboratory observation / ELEMENT["Result value"] measures.measurementValue.quantity Quantity value and unit are preserved
same laboratory observation / first available datetime measures.timeObserved.timestamp Timestamp is preserved when found
openEHR-EHR-OBSERVATION.body_temperature.v2 / ELEMENT["Temperatur"] measures.measurementValue.quantity Mapped as a first-class measurement
openEHR-EHR-OBSERVATION.body_temperature.v2 / node name measures.assayCode Uncoded node names become synthetic openEHR: ids
measurement source node measures._info.openEHR Exact source node is preserved for provenance
observation without a usable quantity none Skipped

phenotypicFeatures

Source field Target field Notes
openEHR-EHR-OBSERVATION.symptom_sign_screening.v0 / ELEMENT["Bezeichnung des Symptoms oder Anzeichens."] phenotypicFeatures.featureType Falls back to the node name when the explicit symptom label is absent
same observation / ELEMENT["Vorhanden?"] phenotypicFeatures.excluded Present symptoms map to false, absent symptoms map to true
phenotypic feature source node phenotypicFeatures._info.openEHR Exact source node is preserved for provenance

interventionsOrProcedures

Source field Target field Notes
openEHR-EHR-ACTION.procedure.v1 / ELEMENT["Procedure name"] interventionsOrProcedures.procedureCode DV_TEXT becomes a synthetic openEHR: id
same procedure action / ELEMENT["Body site"] interventionsOrProcedures.bodySite Preserved when present
same procedure action / time.value interventionsOrProcedures.dateOfProcedure Date only
procedure source node interventionsOrProcedures._info.openEHR Exact source node is preserved for provenance

treatments

Source field Target field Notes
openEHR-EHR-ACTION.medication.v1 / ELEMENT["Name"|"Medication item"|"Immunisation item"] treatments.treatmentCode DV_TEXT becomes a synthetic openEHR: id
same medication action / ELEMENT["Route"] treatments.routeOfAdministration Preserved when present
treatment source node treatments._info.openEHR Exact source node is preserved for provenance

Current omissions

The current experimental mapper does not yet emit first-class Beacon fields such as:

  • ethnicity
  • exposures
  • geographicOrigin
  • karyotypicSex
  • biosamples

Those source details remain only in the preserved info.openehr.compositions payload unless and until explicit mappings are added.