Cumuluz Translate Implementation Guide
0.1.0 - ci-build

Cumuluz Translate Implementation Guide - Local Development build (v0.1.0) built by the FHIR (HL7® FHIR® Standard) Build Tools. See the Directory of published versions

Implementation Notes

Implementation Notes

Translation Shape

The runtime follows one consistent route:

STU3 source profile -> logical model -> R4 target profile

The service is profile-aware on both sides.

It does not flatten the problem into a generic resource-to-resource conversion where every Patient, Condition, or Procedure is treated as equivalent regardless of profile semantics.

That keeps the translation explicit when multiple ZIB or target-profile versions overlap in the same ecosystem.

Why The Logical Layer Exists

The logical layer is the semantic handoff between source and target.

It exists to:

  • normalize shared meaning across source and target families
  • keep STU3 source concerns out of the R4 target maps
  • keep Dutch profile-specific deltas visible
  • support nl-core, eu-base, and EPS targets without pushing profile-specific resource mapping into the HTTP layer

Mapping Assets

The main mapping assets live under:

  • src/main/resources/mappings/structuremaps/zib2017-to-logical
  • src/main/resources/mappings/structuremaps/nlcore2017-to-logical
  • src/main/resources/mappings/structuremaps/bgz2017-to-logical
  • src/main/resources/mappings/structuremaps/pzp2017-to-logical
  • src/main/resources/mappings/structuremaps/eafspraak2017-to-logical
  • src/main/resources/mappings/structuremaps/pzp-questionnaire
  • src/main/resources/mappings/structuremaps/logical-to-eubase
  • src/main/resources/mappings/structuremaps/logical-to-eps
  • src/main/resources/mappings/structuremaps/logical-to-nlcore
  • src/main/resources/mappings/structuremaps/logical-to-pzp
  • src/main/resources/mappings/structuremaps/logical-to-r4
  • src/main/resources/mappings/structuremaps/shared

The logical model definitions live under:

  • logical-models/input/fsh

The published IG also includes the generated logical StructureDefinition artifacts so readers can inspect the actual intermediate model pages.

For the concrete map inventory, see Structure Maps. For the intermediate semantic layer, see Logical Models.

The .map files use FHIR StructureMap syntax and are parsed by HAPI, but the service executes them with its local deterministic StructureMap executor. They should be read as visible mapping assets for this translator, not as a guarantee that every map will run unchanged on another StructureMap engine. Porting the maps elsewhere would require equivalent support for the local logical models, local ConceptMaps, STU3-shaped source context, and the target-write behavior used by the local executor.

Runtime Boundaries

The HTTP layer is intentionally thin.

It is responsible for:

  • route handling
  • parsing requests
  • serializing FHIR responses
  • turning failures into OperationOutcome

The translation layer is responsible for:

  • finding the exact source and target profile route
  • executing the source-to-logical and logical-to-target maps
  • optionally invoking validation

It should not silently substitute a different profile family when the requested route is missing.

The validator is responsible for:

  • checking the translated R4 result against the requested target profile
  • returning a useful OperationOutcome

Runtime Steps

For a single-resource $transform request, the runtime takes these steps:

  1. Parse the HTTP body as a FHIR Parameters resource.
  2. Extract the nested source resource and parse it with the STU3 parser.
  3. Resolve the exact source-profile and target-profile pair in the translation registry.
  4. Parse the registered source-to-logical StructureMaps and execute them against the STU3-shaped source context.
  5. Create the configured logical model and populate it with mapped source semantics.
  6. Execute the registered logical-to-target StructureMap for the requested R4 target profile.
  7. Materialize the typed HAPI R4 target resource and apply the requested target meta.profile.
  8. Apply validationMode: enforce, report, or none.
  9. Return a FHIR Parameters response containing the translated result, the resolved targetProfile, optional logical output, and optional validation outcome.

For a Bundle $transform request, the same route resolution and mapping chain is applied per entry. Each entry supplies its source profile through entry.resource.meta.profile. The target can come from the entry-level translation-target-profile extension, the top-level targetProfile, or PZP profile-pair inference for PZP entries.

EPS document Bundle output is a special Bundle-level target. A STU3 source Bundle targeting http://hl7.eu/fhir/eps/StructureDefinition/bundle-eu-eps is translated entry by entry through the EPS resource maps, then assembled into a document Bundle with a Composition, section references, and stable fullUrls.

QuestionnaireResponse extraction is not part of $transform. It has its own operation because one completed form can produce multiple clinical resources.

Supported Route Semantics

The registry is the source of truth for supported profile pairs. It contains:

  • BgZ 2017 and dependent Dutch STU3 source profiles to nl-core, eu-base, EPS, or base R4 targets where implemented
  • PZP 2017 ACP resource profiles to matching PZP 2020 ACP profiles
  • additional explicit PZP ACP routes to supported generic parent targets, including ACP-Patient routes to nl-core-Patient, patient-eu-core, and patient-eu-eps

The service deliberately reports unsupported route pairs instead of changing the target family behind the client's back. Current examples:

  • generic BgZ resources do not target PZP ACP profiles
  • PZP ACP-Procedure targets nl-core-Procedure-event, but not EU Base or EPS Procedure because those target profiles require performed timing that the PZP source profile does not require

These are contract decisions, not missing controller conditionals.

Validation And Error Semantics

Transform-time validation is controlled only by validationMode.

  • enforce validates the translated R4 result and blocks error or fatal issues.
  • report validates and returns diagnostics without blocking the translated result.
  • none skips transform-time validation.

The $transform operation does not accept a validate parameter. That parameter belongs to QuestionnaireResponse extraction, while standalone validation uses POST /fhir/r4/$validate.

Validation is target-side R4 validation. Structural errors, max-cardinality errors, unknown profiles, and missing mapped target requirements remain blocking in enforce mode. The runtime only relaxes a narrow set of known offline terminology/package expansion issues where the mapped code is covered by local terminology fragments or installed examples; those relaxations are logged and counted in the validation summary.

The IG examples are kept profile-valid for publication. The nl-core Patient target map normalizes known STU3 BCP-47 communication-language codings to the ISO 639-1 coding shape expected by nl-core Patient, for example urn:ietf:bcp:47#nl-NL to urn:oid:1.0.639.1#nl.

Discovery Model

Clients can discover the service in several ways:

  1. CapabilityStatement at /fhir/stu3-r4/metadata
  2. OperationDefinition at /fhir/stu3-r4/OperationDefinition/bgz-transform
  3. translation-index Bundle at /fhir/stu3-r4/translation-index
  4. QuestionnaireResponse extraction OperationDefinition at /fhir/OperationDefinition/extract-questionnaire-response

The translation-index endpoint is especially useful when a client needs a machine-readable inventory of supported pairs instead of a narrative guide.

Keeping This Guide Aligned

When route coverage changes, update these pages in the same change:

  • Translation Matrix, because it lists exact profile pairs
  • Target Profiles, because target-family semantics can change
  • EHDS / EPS Coverage, because package availability, source candidates, and registered routes are separate concerns
  • Transform, when request routing, bundle behavior, validation modes, or response shape changes
  • QuestionnaireResponse, when form extraction behavior changes
  • this page, when runtime ownership or execution steps change

The runtime discovery endpoint /fhir/stu3-r4/translation-index should match the narrative matrix. If they differ, the registry and docs should be reconciled before publishing the IG.

Current Practical Limits

This guide documents what the service actually supports now.

That includes:

  • a stable core around Patient, Problem, and Procedure
  • additional Dutch STU3 dependent profile routes where BgZ exchange depends on them
  • explicit PZP 2017 ACP to PZP 2020 ACP profile-pair routes through shared logical models
  • QuestionnaireResponse extraction for the currently registered ACP-zib2017 STU3 and ACP-zib2020 R4 forms
  • base R4 targets where no installed nl-core or eu-base profile is available for that route
  • EPS targets layered on the EU Base maps, plus document Bundle assembly for supported patient-summary source bundles

This keeps the IG honest. It should describe the current contract first, then leave room for future expansion.

One practical consequence is that the examples can be richer than a minimal field list when that helps readers see which fields really survive translation and which ones are intentionally left behind.