FHIR:V1.0 FHIR Profiling Guidelines STU3: verschil tussen versies
Regel 34: | Regel 34: | ||
* ConceptMap: works best for value sets and codes | * ConceptMap: works best for value sets and codes | ||
* StructureMap: overcomplicated and unclear how to apply and whether or not this has a future | * 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 | + | * 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: | Proposed way forward: | ||
Regel 43: | Regel 43: | ||
#* Example: <element id="Patient:DAF-Patient.extension:race">...</element> | #* Example: <element id="Patient:DAF-Patient.extension:race">...</element> | ||
# 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 | # 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 | ||
− | |||
==Profile meta data== | ==Profile meta data== |
Versie van 5 dec 2016 13:43
Introduction
FHIR requires profiling. To do profiling in a comparable way we need conventions. This page lays out these conventions.
Canonical URL
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:
http://[domain]/fhir/[ConformanceResource]/[project]-[name]-[semver.major]
Where:
- [domain] is "nictiz.nl"
- [ConformanceResource] is usually "StructureDefinition" or "ValueSet"
- [project] is preferably the same as its matching ART-DECOR project prefix
- [name] is the name that best depicts the purpose of the Conformance Resource
- [semver.major] is the version of the Conformance Resources. Of the 3 parts in a semantical version a.k.a. semver can contain we SHALL only use the major version
This convention aligns with international initiatives such as DAF and QiCore and has been confirmed/advised by Grahame Grieve
Versioning
Breaking changes constitute a new conformance resource with a new canonical URL. A breaking change is any change that breaks conformance of instances by adding new required contents, removing previously required contents, making previously required contents optional, changing the terminology bindings contents in a incompatible way like removing codes or changing code systems.
Minor changes like adding additional textual guidance, extending value sets without changing semantics are reflected in the StructureDefinition.version, ValueSet.version, OperationDefinition.version etc. The *.version therefor SHALL consist of major.minor version where major matches that of the canonical URL.
Patches are most difficult of all. Patches are most of time also a breaking change. As per the rule of breaking changes this would constitute a new conformance resources and canonical URL. If context allows it, and that really depends on whether there is known group of stakeholders and their implementation status, you might agree on implementing the patch as a (well documented) minor version.
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 definition 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>
- 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
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
<mapping>
<identity value="zib-patient"/>
<uri value="https://zibs.nl/wiki/Contactpersoon(NL)"/>
<name value="Zorginformatiebouwsteen Contactpersoon"/>
</mapping> - 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
Miscellaneous
- 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.
- 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
FHIR | CBB |
---|---|
CRITL | low |
CRITL | medium |
CRITH | high |
CRITH | fatal |
CRITU | - |
Open vs. Closed Modeling
× | Open | Closed |
---|---|---|
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 |
Cons |
- 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. |
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.
Reference: ElementDefinition.mustSupport
This poses a need for a mapping table from cardinality/conformance in CBBs (ZIBs) versus that in profiles.
ART-DECOR / CBB | FHIR |
---|---|
0..1 | 0..1 |
0..1 C | 0..1 |
0..1 R | 0..1 mustSupport='true' |
0..* | 0..* |
0..* C | 0..* |
0..* R | 0..* mustSupport='true' |
1..1 | 0..1 |
1..1 C | 0..1 |
1..1 R | 0..1 mustSupport='true' |
1..1 M | 1..1 mustSupport='true' |
1..* | 0..* |
1..* C | 0..* |
1..* R | 0..* mustSupport='true' |
1..* M | 1..* mustSupport='true' |