FHIR Profiling Guidelines
Any conformance resource needs a canonical URL. This preferably leads somewhere but does not have to be processable. For Nictiz profiles we SHALL use the following structure:
- For HCIM/zib related profiles (this should be the majority of profiles):
http://[domain]/fhir/StructureDefinition/zib-[English hcim/zib name]
- For extensions pertaining to 1 HCIM/zib:
http://[domain]/fhir/StructureDefinition/zib-[English hcim/zib name]-[English hcim/zib concept name]
- For extensions pertaining to multiple HCIM/zib:
- For other profiles:
- For value sets related to HCIMs/zibs:
http://decor.nictiz.nl/fhir/ValueSet/[value set OID]--[effective date as yyyymmddhhmmss]
- [domain] is "nictiz.nl"
- [project] is preferably the same as its matching ART-DECOR project prefix
This convention aligns with international initiatives such as DAF and QiCore and has been confirmed/advised by Grahame Grieve.
Canonical URL's are about the identity of artefacts, not necessarily about retrieval location. URIs for the latter (for artefacts living in ART-DECOR) are described in ART-DECOR FHIR_URIs.
Versions of the specification may occur for any of the following reasons:
- New releases of the underlying HCIMs/zibs are normally followed by an update to the representing profiles
- Identified issues in existing profiles may require an update
- HL7® FHIR® updates may lead to an update of the profiles. We do not automatically follow every FHIR version as it is released
Version updates first and foremost affects the
version element found in all conformance resources (profiles, value sets, extensions, search parameter, operation definition etc.). The update normally does not affect the canonical uri of the conformance resource. Conformance resources create a web of interrelated artifacts. Any resource that references another resource, e.g. Patient referencing Practitioner for the general practitioner, normally does so without a version indicator (uri|version). This means that any reference points dynamically to 'the latest version' of the artifact. If you were to build a consistent set of versions you would need to add the version to any reference in the set of conformance resources, and update the full set after any updating any particular part.
Around the advent of FHIR R4, the follow up of STU3, there will be a new versioning layer that allows packaging of profiles into a consistent set without affecting the profiles itself. The packaging mechanism will be tested in May 2018, and should greatly simplify specification and implementation of versions.
Associating functional definition to StructureDefinition
Any StructureDefinition that profiles a Resource does so because there is some kind of logical definition dictating how. These functional definitions are known as Clinical Building Blocks, Health Information models or in Dutch Zorginformatiebouwstenen or ZIB's. Profiles SHALL have a traceable relationship with their functional counterpart(s).
The FHIR specification contains several solutions for this problem, ConceptMap (>=STU1), StructureMap (>=STU3), ElementDefinition.mapping. Neither of these solutions are mature and cover our use case.
- ConceptMap: works best for value sets and codes
- StructureMap: overcomplicated and unclear how to apply and whether or not this has a future
- ElementDefinition.mapping: is a free text mapping inside the profile. This means we cannot add mappings to profiles from third parties without updating their resource
Proposed way forward:
- The functional definitions live in ART-DECOR and every concept in this functional definition has a versioned id
- The technical FHIR profile elements we want to map to have an optional @id attribute, but according to Tracker#9843 it is a required item for profiles (StructureDefinition)
- In our own profiles we can make sure we populate this Element/@id and associate the functional concept on id / id basis. We found that DAF Profiles populate these ids as well.
- Example: <element id="Patient:DAF-Patient.extension:race">...</element>
- Example: <element id="2.16.840.1.113883.3.1918.104.22.168.2.3--20110128000000">
- In profiles we reference from third parties that do not have this Element/@id populated we need less precise method. We will deal with that when we need to
Translating DECOR to FHIR
Quite often we will populate FHIR artefacts from DECOR artefacts. In such cases, FHIR identification must be derived from DECOR identification.
DECOR uses the attributes id and effectiveDate to identify concepts, datasets, transactions, valueSets and templates. The artefacts with the same id but different effectiveDates are subsequent versions of the same artefact (though artefacts can also get a new id for a new version, such as when a new dataset is derived from an older one).
In FHIR. every resource can have an id, which is the "logical id" of the resource. This id never changes once assigned, like DECOR id and effectiveDate. Resources usually have an url too, which also identifies the resource, but should be resolvable. The URL can contain the id.
The following ART-DECOR artefacts map to FHIR artefacts:
|DECOR artefact||FHIR artefact||FHIR identifier system||Notes|
|concept||DataElement||http://art-decor.org/ns/oids/de||DataElement is a wrapper around a FHIR element (based on ElementDefinition). A FHIR element is not serializable independently, but is wrapped in a StructureDefinition or DataElement.|
|Logical Model||http://art-decor.org/ns/oids/sd||A Logical Model is a StructureDefinition without base resource. FHIR uses this to capture user requirements.|
The following FHIR attributes are constructed in the following way, when generated from ART-DECOR. Non-digits are stripped from the timestamp in @effectiveDate because they violate the FHIR rules for id.
|FHIR artefact||derivation from DECOR|
|FHIR id||@id + '--' + @effectiveDate|
|FHIR identifier system||See above|
|FHIR identifier value||@id|
|FHIR status||See below|
Status is translated from DECOR to FHIR:
|DECOR status||FHIR status|
Profile meta data
- URL: see above
- Resource ID: n/a
- Name: see above
- Description: An enter resource type resource as defined by the Dutch Clinical Building Building Block Zorginformatiebouwsteen naam version
- Version: as applicable to the profile, not the CBB it refers to
- Publishing: publishing date (should find way to align across all CBB profiles)
- Lifecycle status: as applicable (normally draft or active)
- Experimental: normally false or null
- Display label: null
- Requirements: null (is already evident by the description)
- Copyright: CC0
- Publisher: Nictiz
- Contact information: n/a
- Use context: n/a
- Terminology codes: n/a
- Mappings: uri to the version of the CBB specification
<name value="Zorginformatiebouwsteen Contactpersoon"/>
- Identifiers: n/a
- Meta data: tbd
- Implicit rules (URI): n/a
- Language: n/a (most content is en-US from the core, some is nl-NL from the CBBs)
- Kind: n/a (auto handled by Forge)
- Constrained Type: n/a (auto handled by Forge based on selection at creation time)
- Abstract: false
- Base: n/a (auto handled by Forge based on selection at creation time)
- FHIR version: n/a (auto handled by Forge based on selection at creation time) - initially 1.0.2 DSTU2
- We only profile elements, cardinalities and bindings that require profiling. We leave other elements, cardinalities and bindings as-is
- For elements that map to Clinical Building Blocks (CBB) we copy the name from the CBB element into the profile element.name.
- For now we do not copy the description of the CBB elements into the profile. This is to avoid maintenance/synching problems. The CBB descriptions however shall be available at publication.
- FHIR URI Strategy (draft document with potentially good info)
- When adding invariants we use "cbb-[cbb-name]-[number]" as a key. Example: cbb-alert-1
- For vocabulary bindings to CBB ValueSets we use binding strength "extensible".
- For FHIR base resource elements with datatype code and binding required it may be that the CBB has other/additional codes to specialize the FHIR codes. To conform to FHIR and the CBB we will use the FHIR required element and binding and specify the mapping. We will use 1 extension to cover this use case.
- Extension URI http://nictiz.nl/fhir/StructureDefinition/code-specification
- The extension is of datatype CodeableConcept which also support text as fallback
- The extension receives its ValueSet binding in the context of the profile element and does not have a binding internally
- The extension is only required to be present when the extension actually holds a specialization, e.g. CRITH + fatal. It is optional when the mapping is equal
- The mapping shall be documented in a ConceptMap
- Example AllergyIntolerance.criticality
Open vs. Closed Modeling
|Pros||- Forward compatibility
- Modelers don't have to think about what you shouldn't support, only what must be supported
- Implementers can fit more data, even if it's not in specified explicitly bu the profile
|- Implementers, don't have to support all elements that maybe, someday could be used, according to the model
- Model becomes more specific
- Model becomes smaller and more straight forward
- More implementer feedback, about elements they want to support, but currently can't
- Implementers, have to support all optional elements that maybe, someday could be used, according to the model - Model becomes more vague,
- Model becomes larger and less straight forward about what should actually be supported, and what can optionally be supported
- Less implementer feedback: elements they want to send can be easier 'hacked' in a not yet explicitly specified element. Model won't be improved.
- More versions of models, after more elements have to be supported
- No forward compatibility, only backwards
- Implementers have to wait for a new version of the model, if they want to support elements, that are currenyly not in scope.
We have chosen for "open" modeling for the ZIBs, since they are very general en not meant for one specific sue case. Excluding unspecified elements here is not an option, since we expect derived profiles for more specific use cases that may need those elements.
Cardinality/conformance mapping table
Cardinality applies to the number of occurrences that an element MAY/SHOULD/SHALL have. Minimum cardinality is integer 0. Maximum cardinality is "n" or "*" (exact character depends on tooling). If the minimum cardinality is higher than 0, then an element has to be present.
Conformance applies to what a system MAY/SHOULD/SHALL support. When data for an element is missing, e.g. because it is not applicable, then the element may be absent, but when conformance MustSupport is active, then a conformant application SHALL support it. Contrary to V3, there is no concept of NullFlavor in FHIR, so whenever an element is 1..1 in FHIR, there is no escape through NullFlavor: a value SHALL be present.
This poses a need for a mapping table from cardinality/conformance in CBBs (ZIBs) versus that in profiles.
|ART-DECOR / CBB||FHIR|
|0..1 R||0..1 mustSupport='true'|
|0..* R||0..* mustSupport='true'|
|1..1 R||0..1 mustSupport='true'|
|1..1 M||1..1 mustSupport='true'|
|1..* R||0..* mustSupport='true'|
|1..* M||1..* mustSupport='true'|
Data type mapping table
DECOR defines a set of data types. In most cases the mapping to FHIR is straightforward, though there are a number of cases which are not as clear-cut. When defining extensions, or specifying the datatype of an Observation or Questionnaire.item in FHIR, a mapping to the relevant FHIR datatype needs to be done. There we need for a mapping table for datatypes in CBBs (ZIBs) versus those in profiles.
|INT||count||Count or integer||Count in FHIR is derived from Quantity, this is appropriate for observations, such a a count of red blood cells in a specimen. Count in FHIR is a Quantity with code="1" (for units). If this is not appropriate, use integer.|
|CD||code||CodeableConcept or coding or code||In general, CodeableConcept will be the right choice. See Using Codes in Resources for details.|
|ANY||complex||BackboneElement||'complex' is data which is not further defined in DECOR, and thus cannot be translated.|
|-||currency||Money||Does not have a CBB counterpart currenty. Theoretically this could be MO|
|-||date||date||Does not have a CBB counterpart currently. Closest counterpart could be TS|
|-||decimal||decimal||Does not have a CBB counterpart currently. Theoeratically this could be REAL|
|-||duration||Duration||Does not have a CBB counterpart currently. Closest counterpart could be PQ|
|CO||ordinal||CodeableConcept or coding or code||See Using Codes in Resources for details.|
|-||ratio||Ratio||Does not have a CBB counterpart currently. Closest counterpart could be RTO|
|-||text||string||Does not have a CBB counterpart currently.|