Release notes

Note

openFHIR Sandbox is usually on latest version of openFHIR. To see the exact version of the sandbox, go to https://sandbox.open-fhir.com

Release 3.0.2 (2026-10-03)

Added

  • queue support: the engine can subscribe to Kafka topics carrying FHIR payloads and/or openEHR compositions (mixed in one topic or one topic per kind), translate each message and publish the result to another topic (OPENFHIR_MESSAGING_ENABLED, see Queue support)

    • needs the new messaging license option; enabling it without one fails startup. Existing licenses do not carry it and must be re-issued

    • the tenant is fixed per subscription; the result is the bare Bundle / composition, with status, issues (OperationOutcome) and the source position in openfhir-* headers

    • delivery is at-least-once: caller errors are dead-lettered straight away, transient failures are retried with backoff and then dead-lettered, and the subscription keeps consuming

    • GET /status reports messaging.enabled and, per subscription, its state and processed / partial / dead-lettered counters

  • operational templates can now be resolved directly from an integrated openEHR CDR instead of being uploaded into the engine (OPENFHIR_CDR_ENABLED, see Integrations), making the CDR the single source of truth

    • supports no authentication, HTTP Basic and OAuth2 client credentials; only ADL 1.4 templates are fetched, and the engine never writes to the CDR

    • when enabled, the local template store is not consulted for mappings: POST/PUT/DELETE /opt return 409, GET /opt returns an empty array, and *.opt files are skipped by the bootstrap scan

    • a CDR outage fails the mapping request with a clear error instead of falling back to a stale local template

    • configurable globally or per tenant through the cdr_opt_source tenant property

    • POST /opt/$refresh?templateId=... evicts a cached template cluster-wide so it is re-fetched; GET /status reports cdr.enabled, cdr.baseUrl and cdr.reachable

Note

Set a finite OPENFHIR_CACHE_OPT_TTL when enabling this — the default -1 never expires and there is no local upsert to evict on.

  • updated dependency on open-fhir-core

    • a runtime failure inside a single mapping no longer fails the whole $tofhir / $toopenehr request as an opaque 500: it is reported as an OperationOutcome issue of severity error naming the model mapper, archetype, mapping and the openEHR/FHIR paths being processed; the remaining mappings still run and the partial result is returned (see RESTful APIs). The issue code is processing / structure when the cause is yours to correct (the message is echoed), and exception for an engine fault, where diagnostics carry a reference id and the detail stays in the engine log

    • OPENFHIR_OPERATIONS_OUTCOME_VERBOSITY controls what the $tofhir / $toopenehr OperationOutcome carries: all (default), errors (failed mappings only) or none (no OperationOutcome), so the response stays small for inputs that skip many elements; the engine log is unaffected

    • $tofhir: a fhirCondition whose targetRoot is the mapped CodeableConcept’s coding (or the mapped Coding itself) now selects which of a DV_CODED_TEXT’s codings — its own code and its TERM_MAPPING targets (_mapping:N/target) — are written, with the same one of / not of condition that already filters codings in the $toopenehr direction; it used to be a no-op outbound. Matched after terminology translation, so the criteria are FHIR systems (http://snomed.info/sct after a "*" passthrough ConceptMap). A selection, not a gate: when no coding satisfies the condition the codings are written unchanged. See FHIR Connect, “Selecting a coding with fhirCondition”

Changed

  • GET /status masks the values of secret-looking properties (password, secret, jaas, token, key, …) and the password of credentials embedded in a URI as ******; the endpoint is unauthenticated and used to print them in clear (see RESTful APIs)

  • POST /terminology/fhir/ConceptMap now returns the stored ConceptMap (with its assigned id) as application/fhir+json in the 201 response, the same way PUT and GET serve it; the Location header is unchanged

  • updated dependency on open-fhir-core

    • the legacy /openfhir/* endpoints fail fast on the first failed mapping and return the same descriptive message as their 400 text body

    • $toopenehr failures inside custom mapping code are no longer swallowed and only logged; they are reported like any other mapping failure, and a mapping code that is not registered or declines to map is reported as a warning

    • $tofhir nested mappings (followedBy / reference / slotArchetype) now report their warnings; they used to be lost

    • a FHIRPath expression in a model mapping that cannot be evaluated in the $toopenehr direction (unknown function, malformed condition path, unresolvable resolve()) is reported as a warning / incomplete issue naming the mapping, the expression and the FHIRPath engine’s message, instead of only a log line

    • the $toopenehr “matched the mapping criteria but nothing could be mapped” warning is now raised only when a mapping found no data at its FHIR path or its data produced no openEHR value; it names those mappings with their FHIR paths, the model mapper and archetype, and quotes the FHIR JSON of the element they were evaluated on (truncated at 2000 characters). Elements a mapping was never meant to match (a slot rejected by its mapper’s preprocessor condition, a reference of another resource type, a filtering condition that matched nothing, a manual FHIR-value mapping) no longer produce a warning, so a Bundle fanned out over several slot mappings is no longer reported once per slot per entry

Fixed

  • terminology service: a ConceptMap translation now picks the group by the coding’s system alone. Groups whose source matches the system (and target the requested target system) are used exclusively; the lookup by code across all groups only runs when no group matches by system. Previously both were OR’d together, so a code that is identical on both sides of a bidirectional map (the same SNOMED CT id under two terminology ids) matched the forward and the reverse group at once, logged More than one mapped entry found, and resolved to whichever group came first in the document — one direction was always wrong. See Terminology, “How a ConceptMap is resolved”

    • a "*" (system-only) translation keeps the source coding’s display instead of returning none: $tofhir keeps coding.display and the openEHR return leg keeps |value, so an open code set (ATC, ICD-10) whose terminology_id differs from the FHIR system can be mapped with a two-group "*" ConceptMap instead of a manual system rewrite (needs the open-fhir-core change below)

    • $translate with a sourceCodeableConcept returns the translated codings; it used to return the input codings unchanged, and read the wrong request parameter

    • on PostgreSQL a ConceptMap larger than 4096 characters could not be stored — POST /terminology/fhir/ConceptMap failed with 500 value too long for type character varying(4096). The column is now text (Flyway migration V10, applied automatically on start-up)

  • every entry of a produced Bundle now carries a fullUrl and a legal resource id, regardless of the contained_to_separate_bundle_entry tenant property. With the property set to false — required when a profile’s Bundle slicing is closed — entries used to come out with no entry.fullUrl at all, and a resource created behind a resolve() kept the internal #<uuid> id it is instantiated with, which the HL7 validator rejects as Invalid Resource id and bdl-*. The leading # is now stripped and a missing fullUrl is set to urn:uuid:<uuid>; an id that is already absolute is used as the fullUrl as is, and resources nested behind a reference keep their local # reference so they stay contained. transaction and batch Bundles are left alone, since their entries are addressed by entry.request.url; every other type is normalised, including a Bundle whose type a root mapper writes through a manual — that value reaches the output but not the instance the post-processor inspects

  • updated dependency on open-fhir-core

    • the populators hand the source coding’s display to the terminology translator, so a system-only translation no longer loses it (TerminologyTranslatorInterface gained default display-carrying overloads; existing translators keep working unchanged)

    • $tofhir: a TERM_MAPPING target whose target|terminology carries a version (http://snomed.info/sct@20240101) now yields a coding with that version, as the element’s own code already did

    • $toopenehr: the additional codings of a CodeableConcept are written as TERM_MAPPINGs under the flat key _mapping:N|match; the engine wrote _mapping:N/match, which the flat format does not know, so the TERM_MAPPINGs came out with match: "?" (unknown). They now carry match: "=" (equivalent) — check any consumer that keyed on ?

    • $toopenehr of a FHIR enumeration (MedicationAdministration.status and the like) into a DV_CODED_TEXT / CODE_PHRASE now takes |value from the display of the mapping or ConceptMap target, so an ISM state mapped completed -> 532 comes out as |code: 532, |value: completed. Where the translation names no display, |value falls back to the translated code, and only to the enumeration’s own value when nothing was translated — a mapping of permit -> at0035 with no term still yields |value: at0035, never the untranslated FHIR token

    • a bare resource posted to $toopenehr (not wrapped in a Bundle) is now mapped as documented when its type matches the one the mapping starts from, instead of returning an empty Composition; previously this only worked for model mappers without a preprocessor FHIR condition

    • a mapping request naming an operational template that was never uploaded now returns 400 with an OperationOutcome naming the template, instead of 500 with a NullPointerException

    • input that contains none of the resource type a template starts from (for example a lab report mapping given an Observation but no DiagnosticReport) is now reported as a warning with an empty result, instead of failing with Index 0 out of bounds for length 0

    • a non-repeating hierarchy node in a model mapping no longer fails with Range [0, -1) out of bounds

    • an operational template that is stored but no longer parses is reported as 500 naming the template, separately from the missing-template case

    • unexpected errors on the $tofhir / $toopenehr operations no longer echo internal exception text back to the caller; the response carries a reference id and the detail stays in the engine log

    • an openehrCondition can now narrow on an attribute of an RM data value (DV_*) that the flat format represents as a pipe attribute, written as the RM path the same way a DV_CODED_TEXT is narrowed on defining_code/code_string: DV_IDENTIFIER (targetAttribute: "type", "issuer", "id", "assigner"), DV_QUANTITY and the other quantified types ("magnitude", "units", "precision", "numerator", "denominator"), CODE_PHRASE ("code_string", "terminology_id"), DV_TEXT ("formatting", "language", "encoding"), DV_ORDINAL ("ordinal", "symbol") and the encapsulated types ("formalism", "media_type", "size", "charset", "uri"); each may also be spelled out through the element’s value ("value/type"). Such a condition used to exclude every occurrence of the targeted element, so a cluster holding several identifiers could not be narrowed down to one of them — for example selecting only the HSA id out of a care unit that also carries an organisation number. Where the flat name differs from the RM one the mapping is applied (units → |unit, code_string → |code, terminology_id → |terminology, media_type → |mediatype)

    • $tofhir: a mapping whose FHIR path walks through a single-valued element that an earlier walk already built — a sibling mapping, or an earlier occurrence of the same one — now continues into that element instead of replacing it, so what was there is kept. A repeating openEHR element mapped to $resource.code.coding yields one code carrying all its codings rather than only the last, and a manual on $resource.identifier.system no longer discards the identifier a sibling mapping filled, so a type: NONE parent is no longer required to merge them (it remains the order-independent way). Lists still append on every walk, and a Reference is still replaced when walked through (a $reference mapping, or a path continuing with resolve()), so an identifier-only Reference is still superseded by the resolved one. Check existing mappings for a writer that was redundant with an earlier one — it was masked by the replacement and now adds a second entry, e.g. a manual adding the KVZ10 type coding to an identifier whose DV_IDENTIFIER already carries that type; guard such fallbacks with an openehrCondition (targetAttribute: "type", operator: "empty")

Release 3.0.1 (2026-09-09)

Changed

Release 3.0.0 (2026-09-04)

Changed

  • terminology concept maps are now bootstrapped by the same scan as model mappers, context mappers and operational templates, instead of by a separate runner that applied each file only once, ever

    • editing a bootstrapped concept map and re-scanning now updates it in place under the same id, and an unchanged one is skipped — the create / update / skip semantics the other three file types already had

    • POST /$bootstrap now picks up *.json files, and concept maps appear in its summary counts and per-file breakdown; previously they were skipped silently

    • GET /health readiness now covers the concept-map part of the startup scan as well

    • concept maps are only bootstrapped when the license includes the terminology option; without it *.json files are skipped and the rest of the scan is unaffected

    • a concept map and a mapping file that share a name in different sub-folders no longer adopt each other’s ledger entries

  • migration (Postgres V9 / Mongock V7) tags the ledger entries written by the previous terminology runner, so concept maps bootstrapped before this release are recognised and updated in place on the first scan after the upgrade rather than being re-created

  • updated dependency on open-fhir-core to 3.0.0

    • bootstrap extension points widened so a distribution can add its own bootstrapped file types; no behaviour change in core

Release 2.2.3 (2026-08-17)

Added

  • POST /$bootstrap endpoint for re-running the bootstrap directory scan without restarting the engine; returns a summary of created, updated, unchanged and failed files, and 409 Conflict if a scan is already in progress

  • GET /bootstrap endpoint returning the bootstrap ledger of the logged-in user: which files have been bootstrapped, from which path, and which entity each one created

Changed

  • updated dependency on open-fhir-core to 2.2.5

    • bootstrapped files are now tracked by content hash and re-applied in place under the same entity id when their content changes, instead of being bootstrapped only once; unchanged files are skipped and new files are created

    • bootstrap ledger entries are keyed by the file path relative to the bootstrap directory, so identically named files in different sub-folders no longer collide

    • GET /health now returns 503 STARTING until the startup bootstrap scan completes and 200 UP afterwards, making it usable as a “safe to send traffic” gate

    • unidirectional can now be declared in the header (spec) of a mapping file, applying to the whole file; a unidirectional on an individual mapping still takes precedence

    • added support for mapping openEHR PARTY_PROXY data types, to and from a FHIR Reference and Identifier

    • dose and rate Ranges (DV_INTERVAL<DV_QUANTITY>) are no longer dropped from dosage.doseAndRate

    • values no longer leak between FHIR list entries when repeated slot archetypes feed the same list

    • corrected administration duration for minute-denominated infusion rates

    • non-daily and weekly dosage schedules are now reconstructed as timing.repeat instead of appearing only as text in dosage.text

    • openEHR null_flavour on an ELEMENT is now reconstructed as a FHIR data-absent-reason extension on the primitive it maps to

    • resolved a NullPointerException on conditions that had not been amended against a web template

    • sub-directories whose name ended in .yaml, .yml or .opt are no longer processed as mapping files themselves

    • KDS v1.0 mappings added to the test suite, covering the composition mappings against the FhirConnect v1.0 release

  • the bootstrap ledger is now tenant-scoped, so GET /$purge clears the bootstrap entries of the logged-in user’s tenant as well, meaning that tenant’s bootstrapped files are created again on the next startup

Release 2.2.2 (2026-06-16)

Changed

  • updated dependency on open-fhir-core to 2.2.4

    • added support for hardcoded AQLs via the _query option in context mappings, allowing predefined AQLs to be returned directly when an incoming toAql request matches a defined rule (rules support matching on operations such as $summary, on resources with query parameters such as Observation?category=height, and on resource-only matches). See AQL Generation & Configurable Queries

    • added support for mapping openEHR DV_ORDINAL data types

    • corrected AQL path generation for CodedText and CodePhrase coded data points

    • deprecated fields (such as fhirCondition and criteria) are now excluded from model mapping serialization

Added

  • certain RESTful endpoints required by the Atlas 2.0.0

Release 2.2.1 (2026-05-19)

Changed

  • updated dependency on open-fhir-core to 2.2.2

    • resolved issue with ad-hoc Composition generation when sections had names resulting in empty AQL paths

    • fhirCondition operators one of and not of now evaluate correctly even with matching subpaths

    • fhirCondition operator type now functions as a filter in mappings rather than only conditioning entire operations

    • spec.fhirConfig.structureDefinition now implicitly validates incoming resource types during FHIR→openEHR conversions

    • added coded_text_value leaf type support when multiple type options exist

    • improved RM type propagation when mappings contain only manualMappings as children

    • corrected population of coded text manual mappings when field type is TEXT

    • implemented post-processing logic ensuring Bundles conform to document type with required profiles and identifiers (IPS)

    • added narrative generation templates for medical devices and procedures

    • initial implementation for openEHR DV_PARSABLE data type (assumes text/html formalism)

    • docker image now supports nonarm cpus

Release 2.2.0 (2026-05-04)

Warning

Breaking change: all openFHIR-specific configuration properties are now required to be nested under the openfhir. key. The following properties must be updated in your application.yaml or environment variable configuration:

Old key

New key

db.type

openfhir.db.type

bootstrap.dir

openfhir.bootstrap.dir

bootstrap.recursively-open-directories

openfhir.bootstrap.recursively-open-directories

protected

openfhir.protected

license

openfhir.license

terminology.*

openfhir.terminology.*

app.cluster.*

openfhir.cluster.*

Added

  • GET /status now returns additional diagnostic information:

    • properties — all configuration properties the engine is currently running on, allowing operators to verify that properties were properly picked up

    • cache — per-cache entry counts and configured TTL for fhirConnect, opt, and tenant caches

  • database indexes for both MongoDB and PostgreSQL, significantly improving query performance

  • DELETE /opt/{id} endpoint for deleting Operational Templates

  • DELETE /fc/model/{id} endpoint for deleting FHIR Connect model mappers

  • DELETE /fc/context/{id} endpoint for deleting FHIR Connect context mappers

  • Cross-version FHIR support: openFHIR now supports mapping to and from STU3, R4, R4B, and R5 within a single deployment. The target FHIR version is declared once in the FHIRConnect context mapping (spec.version) as per the FHIRConnect spec. No changes are required for existing R4 mappings. New mappings targeting other versions simply declare spec.version: STU3 (or R4B / R5) in their context file.

  • narrative generation as a programmed mapping (mappingCode: "generateNarrative(entry, profile)"), allowing HTML narratives to be produced for FHIR resources during openEHR → FHIR mapping

Fixed

  • GET /opt/{id}, GET /fc/model/{id}, and GET /fc/context/{id} now return 404 Not Found when the requested resource does not exist, instead of 200 with an empty body

  • GET /opt?templateId= now properly filters by a templateId (before it returned all operational templates)

  • IParser (HAPI FHIR) instances are no longer shared across threads; a new parser is created per call via FhirContext.newJsonParser(), resolving a thread-safety issue under concurrent load

Changed

  • updated dependency on open-fhir-core to 2.2.1

  • all openFHIR-specific configuration properties are now nested under the openfhir. key (see breaking change above)

  • caching now defaults to infinite TTL (-1) instead of 300 seconds; entries are evicted explicitly on upsert

Performance

  • performance benchmarks conducted across 6 hardware configurations show improvements compared to 2.1.0:

    • throughput improved by 11.6% – 36.7% across all configurations

    • mean response time improved by 5% – 72% across all configurations

    • error rates improved in 5 of 6 configurations (up to 50% reduction)

    • most notable gains on PostgreSQL with 4 CPUs / 8 GB memory: mean response time reduced by 72%, max response time from 30s to 6s

Release 2.1.0 (2026-04-07)

Warning

Breaking change: a preprocessor.fhirCondition that previously caused a mapping to be applied in the openEHR → FHIR direction will no longer do so (#35). If your mappings relied on this behaviour, an explicit manual mapping must be added to reproduce the previous result.

Added

  • ability to collect execution metrics

  • performance benchmarks were conducted on this release across 8 hardware configurations. Results show more than 20× improvement in mapping throughput and latency compared to previous versions. See Performance for the full analysis.

  • ability to set up openFHIR Enterprise in a HA mode. See High Availability

Fixed

  • performance optimizations, increasing performance results by approximately 20x compared to previous version

  • criteria are properly evaluated when multiple (previously only 0th criteria was evaluated)

  • preprocessor fhircondition no longer results in a mapping going openehr->fhir [#35](https://github.com/openFHIR/openfhir/issues/35)

Changed

  • updated dependency on open-fhir-core to 2.1.0

  • bootstrap.recursively-open-directories now defaults to true, meaning openfhir engine will go through all directories and subdirectories of the bootstrap location to find mappings and contexts

Release 2.0.4 (2026-03-23)

Changed

Added

  • CodedText <> Enumeration mapping

  • terminology is properly handled when terminology is added in extension model mapping (do note that merging of terminology doesn’t work yet, meaning it can’t be present both on core and on extension model mapping and the one set in extension will be applied)

  • IPS postprocessor for IPS composition mappings

  • DV_TEXT can implicitly be mapped to/from DV_CODED_TEXT

Fixed

  • when mapping to FHIR Enumeration that’s a List (like AllergyIntolerance.category), this is now properly mapped and serialized (previously HAPI serialization was throwing errors)

  • criterias are properly evaluated when multiple (previously only 0th criteria was evaluated)

  • some terminology bugs when the right system wasn’t found when mapping from FHIR bound codes (without a system)

Release 2.0.3 (2026-03-21)

Changed

Added

  • DV_TEXT now maps to CodeableConcept.text

  • ability to transform discrete ContentItems on the fly

  • EHR ID is now replaced with the EHR ID coming in the request during toAql translation

  • IPS tests

Fixed

  • manual mappings may produce duplicate results due to incorrect manual mapping construction

  • FHIRPath with FHIR conditions was in some cases wrongly constructed, resulting in missing mappings

  • $reference can now be suffixed with further AQL path when necessary

  • AQL generation now falls back to archetype-only AQL when no param matches

  • logging when something goes wrong in toAql now works correctly (previously stacktrace was not logged)

Release 2.0.2 (2026-03-15)

Changed

Added

  • tests for toAql translation

  • ability to translate separate ContentItems not necessarily the whole Composition

Fixed

  • toAql now properly exposed via RESTful API (/openfhir/toaql), but still a BETA feature

Release 2.0.1 (2026-03-14)

Changed

Added

Fixed

  • when a duplicate OPT is trying to be created, server now responds with 400 not 500

  • fixed DV_TEXT (String) to CodeableConcept mapping (now maps to CodeableConcept.text, before it didn’t map at all)

  • when there is more than 1 possible rmType, engine now correctly finds the right one (when openEHR -> FHIR, this is done by deducing rmType based on the data; when going FHIR -> openEHR it is based on FHIR type)

Release 2.0.0 (2026-03-06)

Important

with this version of openFHIR, docker images changed from openfhir/openfhir to openfhir/openfhir-enterprise. Old image name now reflects the open sourced version of openFHIR.

Added

  • documented overview of enterprise vs open source features (enterprise)

Changed

  • improvements throughout the codebase, reflecting in a new open source version (https://github.com/openFHIR/openfhir) as well as this one now tightly related to the open sourced one

  • image name changed on dockerhub from openfhir/openfhir to openfhir/openfhir-enterprise

Fixed

  • trying to persist a duplicate operational template now responds with 400 instead of 500

Release 1.2.9

Fixed

  • fixed bug where openEHR to FHIR mappings produced too many resources when mappings were referenced both from slotArchetype as well as from the content of a start archetype

  • fixed PUT /terminology/fhir/ConceptMap/{id} returning 201 Created instead of 200 OK on update

Release 1.2.8

Added

  • enhanced Terminology API with additional endpoints for ConceptMap management:

    • GET /terminology/fhir/ConceptMap now supports searching all ConceptMaps without a URL parameter, returning a properly structured FHIR Bundle with type searchset

    • support for searching ConceptMaps by canonical URL using ?url= query parameter

  • proper support for context.start field in context mappers (see #160)

    • the start field now correctly identifies which archetype within the composition content should be used as the starting point for mapping

    • previously, the engine would ignore the context.start and map directly from the root or from the content

Fixed

  • fixed bug in Terminology API where GET /terminology/fhir/ConceptMap without parameters would fail to return all available ConceptMaps

  • fixed openEhrCondition not being applied correctly in manual mappings (see #168)

Warning

Breaking Change: The proper enforcement of context.start may cause existing mapping files to fail if they specify an incorrect or non-existent start archetype.

If your mappings break after upgrading, look for the following log entry:

context.start archetype '<archetype-id>' not found within composition content. Available starts are: <list-of-available-archetypes>

To fix this, update your context mapper’s context.start field to match one of the available archetypes listed in the error message.

Release 1.2.7

Added

  • support for mapping XhtmlNode elements

Fixed

  • root archetypes within a template are now part of mapping as well and not skipped

Release 1.2.6

Added

Fixed

  • fixed behavior when a mapping of type reference was a followedBy mapping with a different openehr path than the parent, which in some cases caused data points to be overwritten

Release 1.2.5

Fixed

Release 1.2.4

Added

  • tenant entity in the database for tenant-specific configuration; this comes together with a CRUD on /tenant endpoint, protected by users that have tenant.crud scopes

  • configurable behavior per-tenant whether Resources created as part of $reference mapping (https://sevkohler.github.io/FHIRconnect-spec/build/site/FHIRconnect/v1.0.0/types-of-mappings/concept-type/Reference.html) are included as contained Resources or separate bundle entries. Default behavior (and that of sandbox) is that Resources are now included as separate Bundle entries, which is different than how engine behaved up until now

Fixed

  • when OPT is updated through a RESTful API, cache is cleared up, fixing an issue of stale OPT being used for mapping (restart of an engine is still required is OPT is updated directly in the database)

Release 1.2.3

Added

  • ability to use FhirPath concatenation when going openEHR -> FHIR, for example suffixing fhir: "$resource.context.related.reference & '^^^^urn:ihe:iti:xds:2016:studyInstanceUID'" or prefixing fhir: "'prefixOfInstitution'&$resource.custodian.as(Reference).display"

  • /openfhir/tofhir can now handle array of Compositions in a canonical format, rather than just a single one. When an array is provided, openFHIR expects payload to be an array of Compositions in a canonical format (not flat) and of the same template (if they’re not, they will all attempted to be mapped base on a templateId on the 0th Composition in the array). Results of mappings from those multiple compositions will be added to the returned Bundle.entries.

  • support Identifier to String, see: https://github.com/medblocks/openFHIR/pull/140 (thanks @subigre)

Fixed

  • when Insights fail, they fail gracefully now and dont impact successfulness of a mapping

Release 1.2.2

Added

  • ability to map DV_ORDINAL to/from Coding/CodeableConcept and with that, |ordinal values to inline terminology

Fixed

  • Bundle type now defaults to collection when returned in openEHR —> FHIR

Release 1.2.1

Added

  • insights now include mapper name as well

Fixed

  • if fhirCondition as a preprocessor includes multiple ‘one of’ criteria, these now properly result in ‘or’ statements

Release 1.2.0

Added

  • compliance to FHIR Connect spec version 1.0.0 with implicit typing (‘type’ in model mapper is no longer required, types are implied based on RMType and data type on data values being mapped). At the moment, explicit typing is still supported, but will be removed in future versions.

Fixed

  • proper serialization to YAML when requesting YAML representation of model/context mappers (with Accept: application/x-yaml)

Changed

  • snake-yaml de/serialization replaced with jackson yaml

Release 1.1.2

Fixed

  • prevent overriding of recurring elements when they reference a different parent openehr path within a followed by

Release 1.1.1

Added

  • hierarchy to the model schema, although not yet implemented/supported by the engine

  • created and updated (timestamp) added to all database entities

Changed

  • if constructed FHIRPath during runtime of the engine is invalid, mapping now gracefully fails and logs a warning/error instead of failing altogether

Fixed

  • manual mappings, if present in followedBy statements, are now applied on all parent occurrences instead of only the last one

  • proper handling of $openehrRoot and $archetype

  • fixed behavior of the engine when parent path had multiple fhir where clauses

Release 1.1.0

Added

  • Introduced the preprocessor : The spec.fhirConfig.conditions have been relocated to preprocessor.fhirConditions in accordance with the FHIR Connect v1.0.0 specification. All existing mappings have been automatically migrated to comply with this update. No further action required on users.

Before
    spec:
    ...
      fhirConfig:
          structureDefinition: http://hl7.org/fhir/StructureDefinition/Observation
          condition:
              - targetRoot: "$resource"
                targetAttribute: "code.coding.code"
                operator: "one of"
                criteria: "[$snomed.364075005,$snomed.78564009,$loinc.8867-4]"
        

Now
    spec:
    ...
      fhirConfig:
          structureDefinition: http://hl7.org/fhir/StructureDefinition/Observation
    preprocessor:
      fhirConditions:
          - targetRoot: "$resource"
            targetAttribute: "code.coding.code"
            operator: "one of"
            criteria: "[$snomed.364075005,$snomed.78564009,$loinc.8867-4]"
        

Changed

  • The RESTful API endpoints (/fc/model, /fc/context) now return and accept model/context mappers directly, without any additional wrapper.

    Example: When retrieving a model mapper (GET /fc/model/{id}) for an update, you can now use the entire response payload as the PUT body.

Before (context example)
      {
        "id": "67e8351186096400101ba5ae",
        "fhirConnectContext": {
          "grammar": "FHIRConnect/v1.0.0",
          "type": "CONTEXT",
          "metadata": {
            "name": "Growth chart",
            "version": "1.0.0"
          },
          "spec": {
            "system": "FHIR",
            "version": "R4"
          },
          "context": {
            "profile": {
              "url": ""
            },
            "template": {
              "id": "Growth chart"
            },
            "archetypes": [
              "openEHR-EHR-OBSERVATION.body_weight.v2",
              "openEHR-EHR-OBSERVATION.height.v2",
              "openEHR-EHR-OBSERVATION.body_mass_index.v2",
              "openEHR-EHR-OBSERVATION.head_circumference.v1"
            ],
            "start": "openEHR-EHR-OBSERVATION.body_weight.v2"
          }
        },
        "user": "123",
        "organisation": "123"
      }

  

Now (context example)
    {
        "id": "67e8351186096400101ba5ae",
        "grammar": "FHIRConnect/v1.0.0",
        "type": "context",
        "metadata": {
            "name": "Growth chart",
            "version": "1.0.0"
        },
        "spec": {
            "system": "FHIR",
            "version": "R4"
        },
        "context": {
            "profile": {
                "url": ""
            },
            "template": {
                "id": "Growth chart"
            },
            "archetypes": [
                "openEHR-EHR-OBSERVATION.body_weight.v2",
                "openEHR-EHR-OBSERVATION.height.v2",
                "openEHR-EHR-OBSERVATION.body_mass_index.v2",
                "openEHR-EHR-OBSERVATION.head_circumference.v1"
            ],
            "start": "openEHR-EHR-OBSERVATION.body_weight.v2"
        }
    }
  

Fixed

  • $fhirRoot is now correctly processed if set in a mapper fhirCondition.targetRoot