FHIR:V1.0 FHIR Profiling Guidelines R4: verschil tussen versies

Uit informatiestandaarden
Ga naar: navigatie, zoeken
(Clone of STU3 guidelines for FHIR R4)
 
k (Beveiligde "FHIR:V1.0 FHIR Profiling Guidelines R4": Protect production page from accidental edits ([Bewerken=Alleen beheerders toestaan] (vervalt niet) [Hernoemen=Alleen beheerders toestaan] (vervalt niet)))
 
(139 tussenliggende versies door 4 gebruikers niet weergegeven)
Regel 1: Regel 1:
{{DISPLAYTITLE:FHIR Profiling Guidelines}}
+
{{DISPLAYTITLE:FHIR Profiling Guidelines for FHIR R4}}
==Introduction==
+
__NUMBEREDHEADINGS__
 +
=Introduction=
  
[http://hl7.org/fhir FHIR] requires [http://hl7.org/fhir/profiling.html profiling]. To do profiling in a comparable way we need conventions. This page lays out these conventions.  
+
This page lays out the conventions for creating FHIR profiles and associated conformance resources within Nictiz. These guidelines are specifically aimed at FHIR R4; for the STU3 profiling work, [[FHIR:V1.0_FHIR_Profiling_Guidelines_STU3|a separate document exists]].
  
The created profiles are generally based on the [https://zibs.nl/wiki/HCIM_Mainpage| Health and Care Information models (HCIM)] defined by the program ‘Registratie aan de bron’ (Data capture at the point of Care) for the Netherlands. In the Netherlands, these models are more commonly known by the name zorginformatiebouwstenen or ZIB's. In this text, we make use of the HCIM abbreviation. The section [https://informatiestandaarden.nictiz.nl/wiki/FHIR_Profiling_Guidelines#Associating_functional_definition_to_StructureDefinition Associating functional definition to StructureDefinition] provides more information regarding these information models.
+
This page is titled "profiling guidelines", but actually addresses all conformance resources (profiles, extensions, value sets, code systems, CapabilityStatements) and associated examples. We use these terms somewhat interchangeable throughout this document; 'profile' can usually be read as 'the whole set of conformance resources'.
  
==Canonical URL==
+
==Language==
 +
Unless stated otherwise, the FHIR conformance materials will be created in English in order to encourage adoption and re-use.
  
Any conformance resource needs a canonical URL. This preferably leads somewhere but does not have to be processable. Canonical URL's are about the ''identity'' of artifacts, not necessarily about retrieval location. URIs for the latter (for artifacts living in ART-DECOR) are described in [https://www.art-decor.org/mediawiki/index.php?title=FHIR_URIs ART-DECOR FHIR_URIs]. 
+
=Open vs. closed world modeling=
  
For Nictiz profiles we SHALL use the following structure:
+
When profiling, an "open world" or a "closed world" model can be chosen. The former means that the profile only allows the elements to be used specified by the functional model, with all the restrictions from the functional model. The latter means that the profile can accommodate the elements specified by the functional model, but doesn't impose further restrictions.
  
*For profiles:
+
We adopt the "open world" modeling approach to aid re-usability beyond the known use cases. When restrictions are deemed necessary for a specific use case, it will be added to the information standard specific profiles.
**that are [http://zibs.nl HCIM] related (this should be the majority of profiles):<br/><code>http://[domain]/fhir/StructureDefinition/zib-[English HCIM name]</code>
 
**standard specific:<br/><code>http://[domain]/fhir/StructureDefinition/[project]-[name]</code>
 
*For extensions:
 
**pertaining to 1 HCIM:<br/><code>http://[domain]/fhir/StructureDefinition/zib-[English HCIM name]-[English HCIM concept name]</code>
 
**not pertaining to HCIMs, and standard specific:<br/><code>http://[domain]/fhir/StructureDefinition/[project]-[name]</code>
 
**pertaining to multiple HCIMs, or not pertaining to HCIMs and generally applicable:
 
***if the use context is a single resource:<br/><code>http://[domain]/fhir/StructureDefinition/[resource]-[purpose]</code>
 
***otherwise:<br/><code>http://[domain]/fhir/StructureDefinition/[purpose]</code>
 
*For value sets related to HCIMs:<br/><code><nowiki>http://decor.nictiz.nl/fhir/ValueSet/[value set OID]--[effective date as yyyymmddhhmmss]</nowiki></code>
 
  
Where:
+
{| class="wikitable"
* <nowiki>[domain]</nowiki> is "nictiz.nl"
+
|-
* <nowiki>[project]</nowiki> is preferably the same as its matching [http://decor.nictiz.nl/art-decor/ ART-DECOR] project prefix
+
! ×
* <nowiki>[purpose]</nowiki> is generally a camelCased name starting with a lowercase letter
+
! 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 by 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 straightforward
 +
* 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 straightforward 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 currently not in scope.
 +
|}
 +
 
 +
==General guidelines for open world modeling==
 +
We only profile elements, cardinalities and bindings that require profiling. We leave other elements, cardinalities and bindings as-is.
 +
 
 +
==Cardinality==
 +
The functional description will specify the cardinality for each concept as a minimum required and maximum allowed number of times it may occur, which is the same mechanism as in FHIR. However, one needs to be careful as the cardinality can only be restricted in derived profiles, and never widened. Being too strict could thus hinder the re-use of these profiles. This is especially true for cardinalities in zibs, which [https://zibs.nl/wiki/Zib_kardinaliteiten should be interpreted as 'purely conceptual']; a use case might allow for data that conceptually always should be there to be absent in practice.
 +
 
 +
For zib profiles:
 +
** A minimum of 0 or 1 will be profiled as 0.
 +
** A maximum (1, ''n'', *) will be profiled as-is.
  
This convention aligns with international initiatives such as DAF and QiCore and has been confirmed/advised by Grahame Grieve.
+
For nl-core profiles:
 +
* No further restrictions are added, as these profiles only cover the currently ''known'' use cases. Adding restrictions here would hinder as yet unknown of undefined use cases.
  
==Versioning intro==
+
For information standard specific profiles:
 +
* If the corresponding zib has a minimum of 1 and the use case doesn't contradict this, the minimum will be profiled here as 1.
 +
* Cardinalities may be further restricted if the use case defines this.
  
The HL7® FHIR® specification specifies a lot of things related to versions. This text aims to stay aligned with the latest insights. Readers should first get acquainted with the core FHIR specification before reading here: http://hl7.org/fhir/versions.html
+
=={{fhir|mustSupport}}==
 +
The basic notion for any element or extension in a profile, most specifically when it has a mapping to a functional definition, is: provide what you have, and support what you can. At the generic profiling levels - zib and nl-core - we can not know what the exact context of use will be. We can therefore never be sure that a formal FHIR [http://hl7.org/fhir/r4/elementdefinition-definitions.html#ElementDefinition.mustSupport {{fhir|mustSupport}}] flag by any definition would hold in every imaginable use case.
  
===Versions of the profiles===
+
For zib and nl-core profiles:
 +
* Do '''not''' use {{fhir|mustSupport}}. Implementers should understand the presence of a mapping as a hint that a semantic understanding exists and should interpret this as a generic encouragement to support this element.
  
Versions of the profiles may occur for any of the following reasons:
+
For information standard specific profiles:
 +
* Both constrain cardinality and apply {{fhir|mustSupport}} as applicable for the information standard. Implementers have generally pushed back on ''too many'' profiles for ''the same'' building blocks so we generally do not go into that level of profiling.
  
*New releases of the underlying HCIMs are normally followed by an update to the representing profiles
+
The way to know the exact requirements for the use case at hand is thus not immediately clear from just looking at the generic profiles, but from reading the transaction that should be part of any information standard. A transaction is the dataset constrained with cardinalities and conformance applied, comparable to what FHIR calls a ''logical model''.
*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 <code>version</code> 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.
+
==Constraining references==
 +
Concepts in a functional description oftentimes refer to each other; e.g. most clinical concepts will refer to the concept of a Patient. In FHIR these connections are realized using the reference datatype, which allow to specify the target (base resource of profile) as well. For example, a profile representing the zib Problem could set the target of the {{fhir|.subject}} element to the profile representing the zib Patient.
  
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.
+
However, setting the target explicitly means a restriction of the allowed targets, which runs counter to the principles of open world modeling. On the other hand, specifying a dedicated profile provides useful guidance on how to handle this profile. To address both concerns, the target profile will be added next to the base resource. For example, the Condition resource allows Patient and Group as target in the {{fhir|.subject}} element. When profiling the zib Problem, the profile representing the zib Patient will be added as a third option.
  
[[Bestand:Profiles-versioned-or-packaged.png|800px|Profiles with versioned references vs Packaged versions of profiles]]
+
=Functional model as base=
  
===Versions in instances===
+
Most, if not all, conformance resources are based on an underlying functional model. The functional model is the specification to which the conformance resources should adhere.
  
To understand how instances of resources are interpreted by a receiving server we should look at two things:
+
The basis for most other functional models is formed by the [https://zibs.nl/wiki/HCIM_Mainpage 'zibs' ('Zorginformatiebouwstenen')], in English also known as are Clinical Information Models (CIMs), Health and Care Information Models (HCIMs) or Clinical Building Blocks (CBB) – we will use the Dutch term 'zib' for all profiling work as it has become a recognizable term over the past years. The zibs are defined by the program ‘Registratie aan de bron’ (Data capture at the point of care) and provide a foundation of use case neutral building blocks from which use cases can be built. The formal definition of the zibs can be found on the [https://zibs.nl zibs wiki].
  
*The indicator for the profile that the sender added to the instance (if any). This indicator would be in the <code>Resource.meta.profile</code> element and may include a version, e.g.<br/><nowiki><profile value="http://fhir.nl/fhir/StructureDefinition/nl-core-patient"/></nowiki>
+
Use cases or information standards use and refine those zibs that are relevant to the situation. The formal specification for these information standards can usually be found in [https://decor.nictiz.nl/art-decor/ Nictiz' instance of ART-DECOR].
*The profile (versions) that the server defaults to in the absence of a profile indicator in the instance
 
  
If the server does not support the profile (version) as indicated in the instance it may do any of the following things. See also the [http://hl7.org/fhir/versions.html#f-compat relevant section] in the FHIR specification.
+
==Layering: zibs, nl-core profiles and information standard specific profiles==
 +
The profiles and other conformance resources align to this layering of information standards. We recognize three levels of profiles:
 +
; zib profiles: profiles that represent the zibs as faithfully as possible
 +
; nl-core profiles: profiles derived from the zib profiles that that might be enriched by concepts from the different use cases that need the zib. See [[#The nl-core layer]] for more information.
 +
; information standard specific profiles: optional derived profiles from the nl-core profiles that further restrict or enhance these profiles for a specific use case.
  
#Try to support the instance based on what it can support. This may lead to ignoring any element it doesn't know, except for modifierElements. If modifier elements are encountered, the instance should be rejected
+
==The nl-core layer==
#Reject the instance
 
  
Note: as specified in the core FHIR specification, the server SHALL use its CapabilityStatement to indicate its behavior around unsupported elements (ignore or reject)
+
The goal of the nl-core layer is to ensure that similar concepts defined at the use case level are implemented in a uniform way at the FHIR level. Whether the concept is used by a single or multiple use cases is irrelevant – adopting it at the intermediate nl-core level provides clear guidance to future use.
  
==Associating functional definition to StructureDefinition==
+
On the other hand, concepts defined at the intermediate level are only of value if they can be reused across situations. Therefore, it should be investigated how the concept can be created in a reusable way before it is implemented at the nl-core level. If there is a vanishingly small opportunity for reuse, then it is best to define it at the use case level to avoid clutter at the nl-core level.
 +
In practice, this means:
 +
* Extensions from use cases should usually be generalized and added to the nl-core layer.
 +
* Adding reference types to specific profiles (see [[#Constraining references]]) should usually be done at the nl-core layer.
 +
* Cardinalities are usually determined by the zibs and further restricted by the use cases, so it makes little sense to implement them at the nl-core layer. These should normally be implemented at the use case layer. Also see [[#Cardinality]].
 +
* Mappings to the functional specifications for use cases (see [[#Associating the functional definition to StructureDefinitions]]) are by definition use case specific and should be added at the use case layer.
 +
* Bindings to ValueSets (see [[#ValueSet binding]]) are usually use case specific, but might be added at the nl-core layer.
 +
* SearchParameters should usually be generalized and added to the nl-core layer.
  
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 and Care Information Models or in Dutch ''Zorginformatiebouwstenen'' or zibs. Profiles SHALL have a traceable relationship with their functional counterpart(s).
+
==Associating the functional definition to StructureDefinitions==
  
The FHIR specification contains several solutions for this problem, [http://hl7.org/fhir/conceptmap.html ConceptMap] (>=STU1), [http://hl7-fhir.github.io/structuredefinition.html StructureMap] (>=STU3), [http://hl7.org/fhir/elementdefinition-definitions.html ElementDefinition.mapping]. Neither of these solutions are mature and cover our use case.
+
Any StructureDefinition that profiles a Resource does so because there is some kind of logical definition ''dictating'' how. Profiles SHALL have a traceable relationship with their functional counterpart(s).
 +
 
 +
The FHIR specification contains several solutions for this problem, [http://hl7.org/fhir/conceptmap.html ConceptMap] (>=STU1), [http://hl7-fhir.github.io/structuredefinition.html StructureMap] (>=STU3), [http://hl7.org/fhir/elementdefinition-definitions.html {{fhir|ElementDefinition.mapping}}]. Neither of these solutions are mature and cover our use case.
  
 
* 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 without updating their resource.
+
* {{fhir|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.
  
 
===Current implementation===
 
===Current implementation===
  
We use the mapping elements in profiles to map functional elements to resource elements. When slicing, the mapping is made on the ''content'' of the slice, not the slice itself (see also [[#Placing-Info]]).
+
We use the {{fhir|StructureDefinition.mapping}} and {{fhir|ElementDefinition.mapping}} elements in profiles to map functional concepts to resource elements. The following rules apply:
 +
* The mapping {{fhir|.mapping.uri}} SHALL resolve to a description of the functional model:
 +
** For zibs, this SHOULD be the English page on zibs.nl.
 +
** For functional models in ART-DECOR, this SHOULD be the link to the dataset on ART-DECOR v3 in the format of <q>[host]/ad/#/[prefix]/datasets/dataset/[dataset id]/[dataset effectiveDate]</q>
 +
* The {{fhir|.mapping.identity}} should be a constructed in the following way:
 +
** For zibs, this SHOULD be the <q>zib-[English zib name, lowercased]-v[version]-[publication]EN</q>
 +
** For functional models in ART-DECOR, this SHOULD be, all in lowercase, <q>[project prefix][dataset name]-[dataset effectiveDate as 'yyyymmdd']</q>. The dataset name SHOULD be the English name if available, otherwise it SHOULD be the Dutch name. All spaces are replaced by dashes. If the project prefix and dataset name are similar, it's better to not repeat it and simply use 'dataset'.
 +
* The {{fhir|.mapping.name}} should be constructed in the following way:
 +
** For zibs, this SHOULD be <q>zib [English zib name]-v[version]([publication]EN)</q>
 +
** For functional models in ART-DECOR, this SHOULD be <q>ART-DECOR Dataset [dataset name] [dataset effectiveDate]</q>. The dataset name SHOULD be the English name if available, otherwise it SHOULD be the Dutch name. If the dataset name contains the word 'dataset', it SHOULD not be repeated.
 +
* Functional concepts are referenced based on their id in the functional model, which should be used to populate {{fhir|.mapping.map}}.
 +
* The description of the functional concept is ''normally'' placed in {{fhir|.mapping.comment}}, unless other rules apply (see [[#References that are reversed in FHIR]]).
 +
* When slicing, the mapping is made on the ''content'' of the slice, not the slice itself (see also [[#Placing-Info]]).
  
Functional elements are referenced based on their mnemonic id in the HCIM, e.g. NL-CM:9.6.19936. The mapping shall resolve to the English page on zibs.nl:
+
So on the root of the StructureDefinition, the mapping for a zib should be defined as:
 +
<syntaxhighlight lang="xml">
 +
<mapping>
 +
    <identity value="zib-medicationagreement-v1.2-2020EN" />
 +
    <uri value="https://zibs.nl/wiki/MedicationAgreement-v1.2(2020EN)" />
 +
    <name value="zib MedicationAgreement-v1.2(2020EN)" />
 +
</mapping>
 +
</syntaxhighlight>
  
 +
A specific element can then be mapped using:
 +
<syntaxhighlight lang="xml">
 +
<element id="MedicationRequest.extension:usageDuration">
 +
    <path value="MedicationRequest.extension" />
 
     <mapping>
 
     <mapping>
         <identity value="hcim-medicationagreement-v1.0-2017EN" />
+
         <identity value="zib-medicationagreement-v1.2-2020EN" />
         <uri value="https://zibs.nl/wiki/MedicationAgreement-v1.0(2017EN)" />
+
         <map value="NL-CM:9.6.19936" />
         <name value="HCIM MedicationAgreement-v1.0(2017EN)" />
+
         <comment value="PeriodOfUse" />
 
     </mapping>
 
     </mapping>
 +
</element>
 +
</syntaxhighlight>
 +
 +
Note that [[#Mandatory FHIR elements without a functional counterpart|implicitly mapped elements]] and [[#References that are reversed in FHIR|reversed references]] use a slightly different {{fhir|comment}}.
 +
 +
==Handling errors, proposed changes and omissions in the functional model==
 +
 +
Conformance resources which are based on a functional model SHOULD faithfully represent the functional model. This implies that errors in the functional model ''cannot'' be fixed in the FHIR implementation unless it's really trivial; doing so would lead to a difference between the FHIR implementation and the functional model, resulting in unclear and hard to use specifications.
 +
 +
Practically, this results in the following guidelines:
 +
<ul>
 +
  <li>If the error is fixed on the functional level, it is adopted in the conformance resources.</li>
 +
  <li>If an error is trivial AND recognized as something that will be fixed on the functional level, it can be adopted (e.g. spelling mistakes).</li>
 +
  <li>In any other case, the error will be implemented as-is in the conformance resources. This includes the following cases:<ul>
 +
    <li>The error is not recognized as something that needs to be fixed.</li>
 +
    <li>The error is recognized as something that needs to be fixed, but the fix has to wait until the next version.</li>
 +
  </ul><p>The error is documented using a hyperlink to the ticket in the suitable element, usually the {{fhir|.comment}} field of the relevant profile element.</p>
 +
  <p>Note: if the error prevents the creation of the conformance resources, then the functional model is deemed unimplementable and no conformance resources are created.</p>
 +
</ul>
 +
 +
Omissions in the functional model are handled like any other error, with one important exception: if extra information is needed ''in order to'' create an implementation (like a code for a functional concept), and this information will be added to a future version of the functional model, it makes sense to already adopt it for the current implementation. This addition is documented with a reference to the relevant ticket.
 +
 +
===For zibs specifically===
 +
For zibs specifically, these guidelines are practically fulfilled in the following way.
 +
 +
* For any error found in the functional model, a BITS ticket is created in the ZIB project.
 +
** If the ticket results in an erratum, the fix is adopted without notice.
 +
** If the error is not recognized, or won't be fixed until the next (pre-)release:
 +
*** If the conformance resources can be made, the error is documented with a hyperlink to the BITS ticket in the suitable element, usually the {{fhir|.comment}} field of the relevant profile element.
 +
*** If the conformance resources cannot be made, this is documented in the release notes using a hyperlink to the BITS ticket.
 +
*** (Only) if the error pertains something trivial like a spelling mistake AND will be fixed in a future release, it is adopted without any notice.
 +
* For missing definition codes, a BITS ticket is created in the ZIB project.
 +
** If the tickets results in a definition code, it is implemented in the conformance resource. The {{fhir|.comment}} field of the element containing the code will document the code using the following remark: <q>The code to identify this concept ([code]) aligns with the next version of the zib, since the current version doesn't provide a code. See [BITS ticket] for more information.</q>
 +
*** [code] should be either <q>SNOMED xxx</q> when using the code system name, or <q>xxx in code system yyy</q> when using the URI.
 +
*** [BITS ticket] should be a Markdown formatted hyperlink to the relevant ticket with the ticket key as title text.
 +
 +
=Versioning=
 +
{{NoteBox|Discussions regarding this topic are ongoing. This section might change in the future.}}
 +
In general terms, FHIR conformance resources could be affected at several different layers:
 +
# The version of the package that the conformance resources reside in: versioned according to [https://semver.org/ SemVer 2.0].
 +
# The version of the conformance resource themselves ({{fhir|StructureDefinition.version}}): used to indicate the business version to the user, without strict specifications.
 +
# The FHIR version ({{fhir|StructureDefinition.fhirVersion}}): this document is specifically aimed at FHIR R4, meaning this element will be fixed on 4.x.
 +
# The version of the underlying data model.
 +
 +
Regarding point 1 and 2: Nictiz uses the package level as the main versioning mechanism. As a result, the conformance resources within the package are not individually versioned; they should be regarded as a consistent set. To identify the package version a conformance resource, its version number will be set to the package version.
 +
 +
Regarding point 4: the life cycle of the underlying data model is not reflected directly in the version number of the conformance resources, but a change in de the underlying data could result in a change in one or more of the conformance resources. In this case, the normal SemVer rules will determine what happens; if some of the conformance resources need to be changed in a backwards compatible way, a new patch release of the package should be made, if major functionality is added, a new minor version of the package should be released, etc. When a new version of the underlying data model reflects a fundamental change, the choice can be made to create a new package under a different name rather than a new version (eg. each zib releases will have their own package).
 +
 +
Version updates of conformance resources normally do not affect their canonical URI. Any resource that references another resource normally does so without a version indicator ({{fhir|uri<nowiki>|</nowiki>version}}). Instead, this is handled at the package level; reference targets either reside within the same package or in a versioned package that has been added as a dependency.
 +
 +
=Mapping semantic codes to profiles=
 +
 +
Oftentimes a functional concept has an equivalent FHIR element, e.g. a 'comment' in the functional description maps in FHIR to the {{fhir|Resource.comment}} element. When this is not the case, a code (usually SNOMED or LOINC) is needed to add the proper definition to the FHIR resource, usually using the {{fhir|Resource.code}} or {{fhir|Resource.category}} element. For example, the root concept of an Observation is unknown unless it is defined by the {{fhir|.code}} element, and when components are used in an Observation, each {{fhir|Observation.component}} needs to be defined using an individual {{fhir|.code}} element. These codes should be provided by the functional description (for zibs this is the DefinitionCode).
 +
 +
These codes are profiled as required elements using a {{fhir|ElementDefinition.pattern}} as described in [[#Values that should be present verbatim]]. If the maximum cardinality of the element is 1, this pattern is defined on the element itself; if the maximum cardinality is larger than 1, a separate [[#Slicing|slice]] is used instead (see [[#Slice names|this section]] for the naming convention of such slices).
 +
 +
=Slicing=
 +
Elements are sliced for three reasons:
 +
# To specify different requirements for repetitions of an element.
 +
# To [[#Associating the functional definition to StructureDefinitions|add the mapping to the functional specification]] to a specific instance of the element (even if all requirements are the same as the default slice).
 +
# To allow other uses of a base element than what is required by the functional specification, e.g. the reuse of an {{fhir|.identifier}} next to the profiled {{fhir|.identifier}}.
 +
 +
Slicing can often occur on different levels within an element, e.g. when the element is of type {{datatype|CodeableConcept}}, a slice can be made on the element itself or on the child element of type {{datatype|Coding}} ({{fhir|.''element''.coding}}). In general, slicing will occur on the highest level possible, thus on the element itself in the example above. Note that this is only possible for repeating elements (max cardinality > 1). When an element of type {{datatype|CodeableConcept}} does not repeat, the {{datatype|Coding}} element ''can'' be sliced, but this is discouraged as this is often not what is meant; when {{fhir|.coding}} repeats within a single element of type {{datatype|CodeableConcept}}, it must have the same semantic meaning although some granularity difference is accepted (e.g. when communicating the same concept in different code systems).
 +
 +
In general, the slice discriminator is set to {{fhir|discriminator.type}} = {{term|value}} and {{fhir|discriminator.path}} to the path where the discriminator value is located (if it is the root element, it should be noted as <code>$this</code>). The sliced element gets a {{fhir|pattern}} or a {{term|required}} ValueSet binding on the location of the path. No further cardinality constraints are added in the sliced element that correspond with the {{fhir|pattern[x]}} as they are made mandatory by the pattern.
 +
These general slicing guidelines apply to the following situations (see [[FHIR:V1.0_FHIR_Profiling_Guidelines_R4_examples|this page for examples in XML]]):
 +
 +
* [[#Mapping_semantic_codes_to_profiles|Mapping semantic codes to profiles]] requires the presence of the semantic code while leaving the option to use the element for other concepts, e.g the zib LaboratoryTestResult profile uses {{fhir|Observation.category}} for a semantic code that represents the zib ''and'' to map the zib concept ResultType. Even if there are no other concepts present in the zib that would be mapped on the same element as the semantic code, the latter code is defined on a separate slice to allow for derivation of the profile. E.g. the zib Stoma profile uses the <q>stomaCode</q> slice on {{fhir|Condition.category}} for a semantic code that represents the zib, and no other slices are present.
 +
* Identifier systems are always defined on a sliced {{fhir|.identifier}}, even if there is only one defined.
 +
 
 +
Other forms of slicing that are common (Forge sets these slicing details by default):
 +
* A concept is mapped to one or multiple types of a polymorphic element, e.g. {{fhir|Observation.value[x]}}. The mapping and functional description are placed on the slice with the matching data type(s).
 +
* Adding an extension slices the {{fhir|.extension}} element that is discriminated by the value on {{fhir|extension.url}}.
 +
==Slice names==
 +
The slice name should describe the concept it represents. It should align with the name from the functional description where possible, but a more suitable name may be chosen if deemed more applicable:
 +
* For [[#Mapping_semantic_codes_to_profiles|slices representing a semantic code]] (i.e. for zibs this is the DefinitionCode) the slice name will be equal to the name of the (root) concept (starting in lower case) suffixed with <q>Code</q>. For instance the semantic code representing the zib NursingIntervention is put on the <q>nursingInterventionCode</q> slice on {{fhir|CarePlan.category}}, while the slice on {{fhir|Condition.category}} representing the LegalStatus concept of the zib LegalSituation is called <q>legalStatusCode</q>.
 +
* E.g. the zib concept <q>PatientIdentificationNumber</q> defines a patient id for Dutch patients in the form of a bsn, hence the slice name <q>bsn</q> for a slice on {{fhir|Patient.identifier}} is more informative than the zib concept name.
 +
* For CodeSpecification extension slices, [[#Handling_conflicts_with_base_bindings|a custom rule applies]].
 +
* When slicing by {{fhir|.targetProfile}}, a [[#Slicing by .targetProfile|workaround may be needed]] resulting in extra additions to the slice names.
 +
 +
Slices follow the convention of FHIR elements in general, using a camelCased name starting with a lowercase letter. If the slice name represents or starts with an abbreviation, the entire abbreviation should be lowercased (e.g. <q>bsn</q> instead of <q>BSN</q>).
 +
 +
==Slicing by {{fhir|.targetProfile}}==
 +
A common pattern is to slice elements of datatype {{datatype|Reference}} by the {{fhir|.targetProfile}} that the reference acts on, using {{fhir|discriminator.type}} = {{term|profile}} and {{fhir|discriminator.path}} = {{fhir|resolve()}} (this is predominantly done to define the mapping to the functional model). There is a limitation in different FHIR tool stacks that prevent the correct handling of multiple {{fhir|.targetProfiles}} on the same slice. As a workaround, slices with multiple {{fhir|.targetProfile}}s should be split up. If this happens and the slice names would be the same according to the normal naming rules, the slice names will be appended with an appropriate suffix like the {{fhir|.id}} (thus [[#Identity of artifacts|the leaf part of the canonical URL]]) of the target profile.
 +
 +
=Restricting the range of allowed values=
 +
==ValueSet binding==
 +
===General approach===
 +
As a general guideline, the ValueSet defined by the functional model should get a binding on the FHIR element representing the functional concept. This means:
 +
* The binding is placed on the same element as the mapping to the functional description. For complex datatypes {{datatype|CodeableConcept}} and {{datatype|Coding}}, this generally means that the binding is placed on the element representing the datatype, not one of its children.
 +
* For the binding strength, see [[#Binding strength]] below.
 +
* For the binding metadata, see [[#Metadata for elements]].
 +
* For special cases, see [[#Binding multiple ValueSets]] and [[#Handling conflicts with base bindings]].
 +
 +
===Binding strength===
 +
The FHIR profiles should faithfully reproduce the binding strength from the functional description. It may not always be possible to adopt the binding strength verbatim. For example, when creating slices for ValueSets, the binding strength must be set to {{term|required}} in order to make the discriminator work, even though the binding strength in the functional description is {{term|extensible}}. However, by making the slicing {{term|open}}, conceptually the same result is achieved.
 +
 +
Also see the [[FHIR:V1.0 FHIR Profiling Guidelines R4 examples|examples]].
 +
===Binding multiple ValueSets===
 +
The functional model might require multiple ValueSets to be used for some data element, e.g. when offering the choice between multiple code systems. However, FHIR allows to bind just one ValueSet to an element. There are two strategies to handle this situation:
 +
# Create and bind a combined ValueSet that encompasses all the ValueSets defined in the functional model.
 +
# Create slices for each ValueSet binding.
 +
 +
The use of combined ValueSets is the preferred approach. Although the use of slices would make the different concepts visible in the profiles, this strategy doesn’t allow for overlapping ValueSets (which often doesn’t make much sense semantically but happens for example when the different ValueSets include the same NullFlavor codes). It is also less straightforward for derived profiles to expand or restrict the base ValueSet when using slices. Using the first approach, a new ValueSet can be created and bound (if the binding strength permits it and it makes sense semantically).
 +
 +
However, option 2 should be used if there are different requirements for the ValueSet bindings.
 +
 +
Also see the [[FHIR:V1.0 FHIR Profiling Guidelines R4 examples|examples]].
 +
 +
===Handling conflicts with base bindings===
 +
FHIR base resource might specify a {{term|required}} binding for some of its elements, whereas the corresponding concept in the functional specification uses alternative or more specialized codes. To conform both to FHIR and to the functional description, a ConceptMap will be created to map the codes from the functional specification to the codes from the FHIR ValueSet. This ConceptMap will be linked to the existing ValueSet using the extension [https://www.hl7.org/fhir/extension-11179-permitted-value-conceptmap.html permitted-value-conceptmap extension].
  
....
+
If all mappings in the ConceptMap are {{term|equal}} or {{term|equivalent}}, no further action is needed.
 +
====Datatype {{datatype|code}}====
 +
When not all codes from the functional specification map cleanly to a {{term|required}} ValueSet from a FHIR base resource with datatype {{datatype|code}}:
 +
* The ValueSet from the functional description will be bound with the binding strength of the functional concept using the {{Simplifier|http://nictiz.nl/fhir/StructureDefinition/ext-CodeSpecification|title=CodeSpecification}} extension. The extension slice is named after the full English name of the value set according to the functional description, in camelCased notation.
 +
* Mapping to the concepts of the functional description is applied both to the FHIR element and the extension.
 +
* The ConceptMap will be added using the extension [https://www.hl7.org/fhir/extension-11179-permitted-value-conceptmap.html permitted-value-conceptmap extension] on the FHIR ValueSet.
 +
====Datatype {{datatype|CodeableConcept}}====
 +
When not all codes from the functional specification map cleanly to a {{term|required}} ValueSet from a FHIR base resource with datatype {{datatype|CodeableConcept}}:
 +
* {{fhir|CodeableConcept.coding}} will be sliced with a discriminator of <code>value</code>/<code>$this</code>, based on a {{term|required}} binding on the {{fhir|CodeableConcept.coding}} level.
 +
* A slice will be created that binds the ValueSet of the functional description:
 +
** The slice is named after the full English name of the value set according to the functional description, in camelCased notation.
 +
** The binding strength is set to {{term|required}}. This is needed in order to make a valid slice definition.
 +
** The minimum cardinality of the slice is set to 1; if the concept is included, both the FHIR and function model codes are required.
 +
** The ConceptMap is documented using the permitted-value-conceptmap extension on the ValueSet bound in this slice.
 +
** {{fhir|binding.description}} is set to: <q>In addition to a coding from this ValueSet, the corresponding coding from the FHIR base ValueSet SHALL be communicated. The ConceptMap <[canonical of ConceptMap]> can be used to relate these two ValueSets.</q>
 +
* Mapping to the concepts of the functional description is applied only to the FHIR element, not to the slice.
  
     <element id="MedicationRequest.extension:usageDuration">
+
==Values that should be present verbatim==
        <path value="MedicationRequest.extension" />
+
On occasion the profile needs to ensure that an element in the resource being profiled has an exactly defined value. Common use cases for this:
         <mapping>
+
* A particular code must be present at the element (mostly to [[#Mapping semantic codes to profiles|map a semantic code to a profile]]).
            <identity value="hcim-medicationagreement-v1.0-2017EN" />
+
* Only codes from a particular code system are allowed, so its {{fhir|.system}} can only have one value.
            <map value="NL-CM:9.6.19936" />
+
* Only Quantity units in UCUM are allowed, so {{fhir|Quantity.system}} must be set to <code><nowiki>http://unitsofmeasure.org</nowiki></code>.
         </mapping>
+
* A boolean, string or other primitive type must have a particular value.
 +
 
 +
FHIR offers two competing ways to do this: fixed values ({{fhir|ElementDefinition.fixed}}) and patterns ({{fhir|ElementDefinition.pattern}}) (there are also less obvious ways to achieve this, like constraints or ValueSet bindings, which could be used when the solution calls for it). Fixed values have the advantage that they are more readable and are better at communicating to the implementer what the expectations are. However, it is a rather rigid mechanism as it states that the element must be exactly that value and nothing else. Oftentimes, the profiled value is a minimum expectation and other '''additional''' values are still allowed – for example, the datatype {{datatype|CodeableConcept}} allows for more than one {{fhir|.coding}}, as long as they are semantically compatible.
 +
 
 +
Therefore, in FHIR R4, the guidance is to use fixed values for primitive types and patterns for complex types. However, from FHIR R5 onward, the guidance is to always use patterns over fixed values, as even on primitive datatypes a fixed value would prevent the use of extensions or element ids.
 +
 
 +
Therefore, when there is a need for fixing values in the profile, the following guidance applies:
 +
* Use a pattern on the element representing the datatype (thus not on one of the elements within the datatype).
 +
* For coded elements where a fixed {{fhir|.system}} is required, including elements of datatype {{datatype|CodeableConcept}}/{{datatype|Coding}} and {{datatype|Quantity}} or one of its derived datatypes:
 +
** If the functional model specifies the fixed value as a value set (e.g. "all codes from SNOMED"), use a [[#ValueSet binding]].
 +
** Otherwise, use a pattern with {{fhir|.system}} set to the required value.
 +
* Fixing values should only be done for data that needs to be present verbatim in the resource being profiled. Concepts like {{fhir|Coding.display}} and {{fhir|Quantity.unit}} should never be fixed, as these are descriptions which might change depending on the context.
 +
 
 +
=Extensions=
 +
Sometimes a concept from the functional model cannot be implemented using the building blocks FHIR offers by default. In this case, an extension might be used to implement such concept. Keep in mind that extensions are often seen as a burden for implementers:
 +
# If it possible to model the concept (cleanly) without an extension, this is usually the preferred way.
 +
# If that's not possible, check if HL7 provides an extension to implements the concept.
 +
# If that's not possible, try to create an extension in a reusable way (or reuse a previously defined extension).
 +
# If that's not possible, create an extension specific for the profile.
 +
 
 +
Usually the mappings to the functional model, bindings to specific ValueSets and any functional descriptions will be added when the extension is used within a profile. When the extension pertains to a particular profile, this information SHALL be added to the StructureDefinition of the ValueSet.
 +
 
 +
==Extensions containing a reference to a zib profile==
 +
Extensions on the zib level that contain a reference to a zib profile, have that zib profile placed as {{fhir|type.targetProfile}} on {{fhir|value[x]}} ({{fhir|valueReference}}). Since it is problematic to make derived extensions, no nl-core counterpart of the extension is created, but the extension is made generic for both the zib and nl-core layer (see also [[#Profiles, extensions and datatypes]]). The nl-core profile that uses this extension should treat the zib profile reference in the extension like any other zib profile references and restrict the {{fhir|targetProfile}} to the nl-core counterpart.
 +
 
 +
=Common patterns=
 +
Sometimes different profiles use a common pattern, for example when references to a particular zib requires special guidance. Special care should be taken to ensure that this pattern is implemented in a consistent way. There are several approaches for this:
 +
* When all these profiles share a common base, a base profile can be defined that includes this pattern.
 +
* When the pattern is part of an extension, then it is applied in a common way by definition.
 +
* A datatype profile may be created that can be re-used across resource profiles (using {{fhir|type.profile}}). This datatype profile may include special guidance aimed at profilers. An example of this approach is described in [[#Referencing zib HealthProfessional]].
 +
 
 +
=Mandatory FHIR elements=
 +
==Without a functional counterpart==
 +
On occasion, FHIR requires an element to be populated while the functional model doesn't specify it. For example, the Procedure resource has the required element {{fhir|Procedure.status}}, but the zib Procedure, which is mapped to this FHIR resource, doesn't specify such a field.
 +
 
 +
In these circumstances, an effort should be made to map the zib concepts implicitly to these elements. For example, FHIR {{fhir|Procedure.status}} can be inferred from the zib concept ProcedureEndDate; if it is in the past, then the status should be assumed to be completed. If it is not possible to make such an implicit mapping, the FHIR element is left as-is; the implementation guide should describe how the implementer should deal with it, probably using the data-absent-reason extension.
 +
 
 +
Implicit mappings are documented in the following way:
 +
* The comment of the implicitly mapped element should provide guidance on how to map the functional concept.
 +
* The {{fhir|mapping}} element is populated with the mapped concept, but the description is altered to: <q>[concept name] (implicit, main mapping is on [element name])</q>.
 +
* Other metadata ({{fhir|.definition}}, {{fhir|.short}}, {{fhir|.alias}}) isn't populated according to the normal guidelines.
 +
 
 +
==With a functional counterpart with a minimal cardinality of 0==
 +
On occasion, a functional concept with a minimal (conceptual) cardinality of 0 is mapped to a mandatory FHIR element. An effort should be made to provide guidance on how to populate the element if no meaningful value can be derived from the zib. For example, the concept TextResultStatus of zib TextResult is mapped to {{fhir|DiagnosticReport.status}}, where value {{term|unknown}} can be used if the value of zib concept TextResultStatus is not present.
 +
 
 +
If no guidance can be provided in the profile, it is up to sending systems to populate the element with a meaningful value from the context of their data and the implementation guide should describe how the implementer should deal with this situation.
 +
 
 +
=References that are reversed in FHIR=
 +
Functional building blocks often refer each other, but on occasion, the logical direction for the reference in FHIR is in the other direction. For example, zib TextResult defines a reference to zib Procedure, but the association between FHIR resources DiagnosticReport (for zib TextResult) and Procedure (for zib Procedure) is defined on {{fhir|Procedure.report}}.
 +
 
 +
In these situations, the FHIR approach is followed rather than some custom extension or other mechanism. Although this approach cannot enforce the cardinality from the functional model, the use of the default implementation requires the least effort from implementers and gives the best results for interoperability.
 +
 
 +
These reversed mappings are profiled in the following way:
 +
* In the profile that contains the reference:
 +
** If the element that represents the association between the two resources is a repeating element, it is sliced with a discriminator of {{fhir|profile}}/{{fhir|resolve()}} and a slice is added with the target(s) set to the target profile(s). Otherwise, the target profile is just added to the list of targets.
 +
** The {{fhir|.mapping}} element is populated with the mapped concept, but the description is altered to: <q>Reversed reference for [functional building block name].[concept name]"</q>
 +
** The {{fhir|.short}} and slice name, if used, use the English name of the target rather than the concept name.
 +
** An {{fhir|.alias}} containing the Dutch name of the target is added.
 +
** The {{fhir|.comment}} contains an (additional) note in the following form: <q>Please note that on a functional level, [functional building block A] references [functional building block B], but in FHIR this direction is reversed."
 +
** {{fhir|.definition}} can be populated with the (modified) definition from the functional building block, but only if it provides useful information to the implementer.
 +
** The cardinality of the element is unaffected.
 +
* In the target profile (where the reference would normally be made if the functional definition is followed):
 +
** The {{fhir|.comment}} on the root contains an (additional) note in the following form: <q>Please note that on a functional level, [functional building block A] references [functional building block B], but in FHIR this direction is reversed. Therefore, the concept [concept name ]([concept identifier]) is mapped on [path to reference] in profile [profile B] instead of in this profile.</q>
 +
 
 +
Example from profile zib-Procedure-event:
 +
<syntaxhighlight lang="xml">
 +
     <element id="Procedure.report">
 +
      <path value="Procedure.report" />
 +
      <slicing>
 +
         <discriminator>
 +
          <type value="profile" />
 +
          <path value="resolve()" />
 +
         </discriminator>
 +
        <rules value="open" />
 +
      </slicing>
 
     </element>
 
     </element>
 +
    <element id="Procedure.report:textResult">
 +
      <path value="Procedure.report" />
 +
      <sliceName value="textResult" />
 +
      <short value="TextResult" />
 +
      <comment value="Please note that on a functional level, zib TextResult references zib Procedure, but in FHIR this direction is reversed." />
 +
      <alias value="TekstUitslag" />
 +
      <type>
 +
        <code value="Reference" />
 +
        <targetProfile value="http://nictiz.nl/fhir/StructureDefinition/zib-TextResult" />
 +
      </type>
 +
      <mapping>
 +
        <identity value="zib-textresult-v4.4-2020EN" />
 +
        <map value="NL-CM:13.2.5" />
 +
        <comment value="Reversed reference for zib TextResult.Procedure" />
 +
      </mapping>
 +
    </element>
 +
</syntaxhighlight>
  
===Proposed way forward===
+
And in zib-TextResult:
 +
<syntaxhighlight lang="xml">
 +
    <element id="DiagnosticReport">
 +
      <path value="DiagnosticReport" />
 +
      ...
 +
      <comment value="Please note that on a functional level, zib TextResult references zib Procedure, but in FHIR this direction is reversed. Therefore the concept Procedure (NL-CM:13.2.5) is mapped on `Procedure.report:textResult` in profile zib-Procedure-event instead of in this profile." />
 +
      ...
 +
</syntaxhighlight>
  
# The functional definitions ''live'' in ART-DECOR and every concept in this functional definition has a versioned id.
+
=Practical guidelines=
# The technical FHIR profile elements we want to map to have an optional @id attribute, but according to [http://gforge.hl7.org/gf/project/fhir/tracker/?action=TrackerItemEdit&tracker_item_id=9843 Tracker#9843] it is a required item for profiles (StructureDefinition)
+
==Identity of artifacts==
# 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.
+
===Canonical URL, id, name and title===
#* Example: <element id="Patient:DAF-Patient.extension:race">...</element>
+
Conformance resources can have multiple types of identifying information, which are related at some level:
#* Example: <element id="2.16.840.1.113883.3.1937.99.62.3.2.3--20110128000000">
+
; {{fhir|.url}}: The canonical URL, which is ''the'' external identifier for conformance resources. All conformance resources SHALL have a canonical URL. This URL is preferably resolvable but does not have to be processable. Canonical URL's are about the ''identity'' of artifacts, not necessarily about retrieval location. Canonical URLs aren't meant to be human recognizable.
# In profiles we reference from third parties that do not have this Element/@id populated we need a less precise method. We will deal with that when we need to.
+
; {{fhir|.id}}: This should align with the latter part of the canonical URL.
 +
; {{fhir|.name}}: A recognizable name that is still computer processable.
 +
; {{fhir|.title}}: A recognizable title purely for human consumption.
  
==Practical guidelines==
+
URIs for the latter (for artifacts living in ART-DECOR) are described in [https://www.art-decor.org/mediawiki/index.php?title=FHIR_URIs ART-DECOR FHIR_URIs]. 
  
===File names===
+
====Profiles, extensions and datatypes====
* For profiles: ''<<the final part of the canonical URI>>''.xml
+
*The {{fhir|.id}} will be constructed in the following way:
* For valuesets: ''<<Valueset.name>>''-''<<Valueset.id>>''.xml
+
**For profiles, the {{fhir|.id}} consists of a prefix, the name of the building block, optionally followed by a specification of the concept ''within'' the building block, optionally followed by a suffix:<br/><code>[prefix]-[building block name]{.[concept name]}{-[suffix]}</code>
 +
***Where <code>[prefix]</code> is:
 +
****for the zib layer: <q>zib</q>.
 +
****for the nl-core layer: <q>nl-core</q>.
 +
****for standard specific layers: <code>[project prefix]</code>.
 +
***Where <code>[building block name]</code> is:
 +
****when representing a zib (irrespective of the layer): the English zib name, PascalCased in the same way as the zib name.
 +
****when representing another functional building block: the English building block name, PascalCased.
 +
****when representing multiple building blocks: the overarching concept name. The overarching concept name is plural and camelCased, to indicate that the profile applies to multiple building blocks and to avoid any possible confusion with actual building blocks, respectively. An example is 'wounds' as the overarching concept of the zibs Burnwound, PressureUlcer and Wound.
 +
***Where the optional <code>[concept name]</code> is used when the profile is not the focal resource for a functional building block, but rather a direct representation of a part of it. In this case, the English concept name is used, capitalized according to the functional description. Underscores are ignored. For example, while zib LaboratoryTestResult is profiled onto the Observation resource, the 'Specimen' container is profiled on the Specimen resource, resulting in a name of 'zib-LaboratoryTestResult.Specimen'.
 +
***Where the optional <code>[suffix]</code> is used in the following situations:
 +
****If the functional building block is spread out over multiple resources, the resource type is appended, PascalCased. For example, zib HealthProfessional is represented using both a Practitioner and a PractitionerRole resource, resulting in 'zib-HealthProfessional-Practitioner' and 'zib-HealthProfessional-PractitionerRole'. This suffix may be absent from the focal resource, if there's one (e.g. 'zib-HealthcareProvider').
 +
****If there are multiple implementations of the same building block for different uses, a use specific suffix is appended. A common pattern for this is when zibs are used both for registered and planned events, resulting in an event and request resource from the [https://hl7.org/FHIR/R4/workflow.html FHIR workflow] perspective (e.g. zib Procedure which is mapped to both a Procedure and ServiceRequest resource). The following suffixes may be used:
 +
*****past use: <q>event</q>
 +
*****future use: <q>request</q>
 +
**For extensions:
 +
***directly representing a specific concept in a single profile:<code>ext-[English root concept name].[English concept name]</code>. Underscores are ignored.
 +
***pertaining to multiple profiles, or not pertaining to specific profiles and generally applicable:
 +
****if the use context is a single resource:<code>ext-[resource]-[purpose]</code>
 +
****otherwise:<code>ext-[purpose]</code>
 +
**For datatype profiles:
 +
***representing a functional building block: this is regarded a normal profile as described above
 +
***representing a pattern: <code>pattern-[purpose]</code>
 +
*The canonical URL will then be created as: <code><nowiki>http://nictiz.nl/fhir/StructureDefinition/[id]</nowiki></code>
 +
*The name will be the {{fhir|.id}} capitalized, with hyphens and periods (.) removed.
 +
*The title will ''generally'' be the {{fhir|.id}} with hyphens replaced by spaces.
  
===Profile meta data===
+
Where:
* URL: see above
+
* <code>[project prefix]</code> is preferably the same as its matching ART-DECOR project prefix
* Resource ID: final part of the canonical URI
+
* <code>[purpose]</code> and <code>[English concept name]</code> are generally a PascalCased name joining words together, with the first letter of every word capitalized.
* Name: final part of the canonical URI (without hyphens, capitalized)
 
* Description:
 
** A(n) ''<<enter resource type>>'' resource as defined by the Dutch Health and Care Information models (Dutch: Zorginformatiebouwsteen or ZIB) ''<<Zorginformatiebouwsteen name>>'' ''<<version>>'' ''<<release>>''
 
** Followed by the 'Concept' section from the HCIM
 
* Version: ''as applicable to the profile, not the HCIM it refers to''
 
* Date: n/a
 
* Lifecycle status: ''as applicable'' (normally draft or active)
 
* Experimental: normally '''false''' or null
 
* Title: final part of the canonical URI (without hyphens, with 'zib' replaced by 'HCIM')
 
* Purpose:
 
** 'Purpose' section from HCIM
 
** If needed: a discussion of where this profile fits in the workflow and why this resource was chosen (separated using a header in Markdown)
 
* Copyright: CC0
 
* Publisher: ''Nictiz''
 
* Contact information: n/a
 
* Use context: n/a
 
* Keywords: n/a
 
* Mappings: ''uri to the version of the HCIM specification'' (see [[#Associating_functional_definition_to_StructureDefinition]])<br/>&lt;mapping><br/>&#160;&#160;&#160;&#160;&lt;identity value="hcim-contactperson-v3.1-2017EN"/><br/>&#160;&#160;&#160;&#160;&lt;uri value="https://zibs.nl/wiki/ContactPerson-v3.1(2017EN)"/><br/>&#160;&#160;&#160;&#160;&lt;name value="HCIM ContactPerson-v3.1(2017EN)"/><br/>&lt;/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 HCIMs)
 
* Kind: n/a (auto handled by Forge)
 
* Type: n/a (auto handled by Forge based on selection at creation time)
 
* Abstract: '''false'''
 
* Base definition: 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 3.0.1 STU3
 
  
===Mapping DefinitionCodes===
+
====ValueSets====
 +
*For value sets as specified on ART-DECOR, the id will be:<code>[value set OID]--[effective date as yyyymmddhhmmss]</code>
 +
*The canonical URL will then be created as: <code><nowiki>http://decor.nictiz.nl/fhir/ValueSet/[id]</nowiki></code>
 +
*Both the name and title will be the name of the value set (usually in Dutch).
 +
====CodeSystems====
 +
*For code systems as specified on ART-DECOR, the id will be:
 +
** If a canonical URL is available, then the latter part of the canonical URL.
 +
** Otherwise the code system OID.
 +
*The canonical URL will then be created as:
 +
** When a URI is explicitly stated, then this is used.
 +
** If the code system can be resolved with a URI in the OID register, then this is used.
 +
** Otherwise: <code><nowiki>urn:oid:[code system OID]</nowiki></code>
 +
*Both the name and title will be name of the code system (usually in Dutch). If the code system can be resolved in the OID register it will get that name as registered.
 +
====NamingSystems====
 +
NamingSystems are rarely needed. No strict guidance is given, but in general, the following conventions apply:
 +
*The id will be <code>namingsystem-[identifier]</code>, where identifier is usually the latter part of the canonical URI this NamingSystem defines. However, a more informative identifier may be chosen if deemed more appropriate.
 +
*The name will be <code>[identifier]</code> capitalized and with dashes and such removed, unless a better scheme is deemed more appropriate.
 +
*NamingSystems don't have a title or canonical URI.
  
Sometimes a FHIR element is equivalent to the HCIM concept (like a comment and a ''Resource.comment'' element), but if not, a code (usually SNOMED or LOINC) needs to be added to the FHIR profile to provide the proper definition. This is for example the case in Observation, where the root concept of the observation is unknown unless it is defined by the ''.code'' element, and where every ''.component'' needs to be defined by an individual ''.code'' element. Usually, the concepts for these elements are provided by the HCIMs (as DefinitionCode).
+
====ConceptMaps====
 +
*The id will be constructed as: <code>[source ValueSet.name]-to-[target ValueSet.name]</code>
 +
*The canonical URL will then be: <code><nowiki>http://nictiz.nl/fhir/ConceptMap/[id]</nowiki></code>
 +
*The name will be constructed as: <code>[source ValueSet.name]_to_[target ValueSet.name]</code>
 +
*The title will be constructed as: <code>[source ValueSet.name] to [target ValueSet.name]</code>
  
We map these DefinitionCodes from the HCIM onto the profile in an extendable way. If possible, we use a required slice for the DefinitionCode. In practice this will look like:
+
====SearchParameters====
{| class="wikitable"
+
SearchParameters are generally added from the nl-core layer onwards because the zib layer is without an use case definition.
|-
+
*The code should consist of one or multiple words in lowercase ASCII characters, with multiple words separated using a dash ("-"):
! COLSPAN="4"| FHIR path                                !! Remark !! Cardinality
+
** If the search parameter doesn't pertain to a specific functional model or use case, the FHIR element that the search parameter acts on should be used.
|-
+
** If the search parameter does pertain to a specific functional model or use case, the English name of the functional concept should be used.
| .code ||        ||                      ||          || || 1..1
+
** If these guidelines aren't feasible, another descriptive name may be used at the profilers discretion.
|-
+
*The id will be: <code>[target]-[code]</code>, where <code>[target]</code> is PascalCased and should be:
|      || .coding ||                      ||          || sliced on ''value/code'' || 1..*
+
** The resource name if the search parameter applies to a single resource type.
|-
+
** A descriptive name for the target if the search parameter applies to more than one resource type, e.g. "Medication" if the search parameter applies to medication related resources.
|      ||        || ''slice for concept'' ||          || named after the concept name || 1..1
+
*The canonical URL will then be: <code><nowiki>http://nictiz.nl/fhir/SearchParameter/[id]</nowiki></code>
|-
+
*The name will be: <code>[target]_[code]</code> with dashes and such removed in <code>[target]</code> and <code>[code]</code>, unless a better scheme is deemed more appropriate.
|      ||        ||                      || .system  || code system from HCIM as ''fixedValue'' || 1..1
+
*The description will describe the working of the search parameter.
|-
+
*The purpose will be populated to indicate why the SearchParameter is created.
|      ||        ||                      || .code   || code from HCIM as ''fixedValue'' || 1..1
+
*The search parameter is expressed using {{fhir|.expression}}.
|-
 
|      ||        ||                      || .display || display value defined in the code system as ''defaultValue'' || 0..1
 
|}
 
===Slicing definitions===
 
====Choosing the discriminator====
 
Defining the discriminator should be based on the most specific slice definition as possible while keeping a close eye on performance cost. Use patterns instead of a combination of fixed values to keep the discriminator logic simple. For example when slicing the Coding/CodeableCocept datatype: use a pattern slice if the code and system of a slice are fixed. If the slices are discriminated by different CodeSystems then a discriminator based on a fixed system is preferred over a ValueSet binding. Use the latter if multiple CodeSystems can be used within a slice definition. Try to avoid the discriminator type 'profile' as this is a very costly operation for a validator.
 
  
====Don't use nested slicing====
+
====Examples and fixtures====
In some cases, slicing in this way would mean to add slices within slices (e.a. Observation.component). This doesn't work too well in FHIR - for example, neither the Java nor the .Net validator can't handle this (at the moment) - so we don't use this mechanism. As an alternative, we can use a slicing discriminator based on pattern/code, and on each slice.code we can add a ''patternCodeableConcept'' with the required system and value. This has the same effect; at least that coding is required, but others may be added.
+
Examples and fixtures (example instances used for test/qualification purposes) are not conformance resources and lack the {{fhir|.url}}, {{fhir|.name}} and {{fhir|.title}} elements. However, to ensure consistency, the {{fhir|.id}} is standardized in the following way:
 +
* For fixtures: <code>[profile id]-[3 character project prefix]-[unique string]</code>, capped to 64 characters. The <code>[project prefix]</code> is necessary to prevent the same id from being used by different projects in the same test environment. It is preferably the same as its matching ART-DECOR project prefix.
 +
* For examples: <code>[profile id]-{[3 character project prefix]-}[unique string]</code>, capped to 64 characters (the <code>[3 character project prefix]</code> is not needed for examples, but may be included to facilitate re-use of tools for both fixtures and examples).
  
===Binding HCIM defined ValueSets===
+
===Folder structure and file name===
* the ValueSet can be obtained in FHIR 3.0 format from ART-DECOR (see [[#File_names]] for file naming conventions)
+
Most FHIR publishing tools adopt the convention to prefix the file name with the resource type. However, there's no rule or tool dependency to do so. These guidelines only partially adopt this convention. In most cases, the file names are based on the {{fhir|.id}}, which has a defined meaning in these guidelines, and it is often deemed more clear to omit the resource type.
* the reference URL can be obtained from the ''<<ValueSet.url>>'' element in this file
 
* we use binding strength "''[http://build.fhir.org/valueset-binding-strength.html extensible]''".
 
* the ''<<binding.description>>'' value is set to ''<<ValueSet.name>>''
 
  
===Binding of HCIM BasicElements to profiles===
+
; profiles and extensions: <code>StructureDefinitions/[id].xml</code>
The [https://zibs.nl/wiki/BasicElements-v1.0(2017EN) BasicElements] were made explicit in HCIM Release 2017 and have been declared applicable to [https://zibs.nl/wiki/BasicElements-v1.0(2015EN) 2015] and [https://zibs.nl/wiki/BasicElements-v1.0(2016EN) 2016] in the zibs.nl wiki.  
+
; ValueSets: <code>vocabulary/ValueSet-[Dutch name]-[id].xml</code>
 +
; other terminology resources (ConceptMaps, CodeSystems, NamingSystems): <code>vocabulary/[resource type]-[id].xml</code>
 +
; other definitional resources (SearchParameters, CapabilityStatements, etc.): <code>[plural of resource type]/[resource type]-[id].xml</code>
 +
; example resources: <code>examples/[profile id]-[serial number, two digits].xml</code>
  
Initially, the profiles did not dedicate much attention to the BsasicElements as there was no clarity around how to interpret them. That clarity has [https://zibs.nl/wiki/BasicElements-v1.0(2017EN)#Concept since been added] but there is still room for interpretation:
+
Sub folders may be used if necessary.
  
{{NoteBox|All HCIM's implicitly contain a number of basic elements. These are usually not included in the information models of the individual building blocks but are supposed to be present.
+
==Metadata==
These are concepts that are of a more technical nature, often have little or no clinical relevance, but are necessary for the sake of clarity and readability of the information. In those cases where these elements are of clinical significance, they will usually be explicit in the information models. An example of this is an AGB number as an identification number for a health professional.}}
+
===StructureDefinitions===
 +
====Metadata on the StructureDefinition root====
 +
* version: see [[#Versioning]]
 +
* status: as applicable (normally ''draft'' or ''active'')
 +
* publisher: <q>Nictiz</q>
 +
* contact:
 +
** name: <q>Nictiz</q>
 +
** telecom:
 +
*** system: <q>url</q>
 +
*** value: <q><nowiki>https://www.nictiz.nl</nowiki></q>
 +
*** use: <q>work</q>
 +
* description:
 +
** For profiles:
 +
*** For zib profiles: the 'Concept' section from the zib.
 +
*** For nl-core profiles: copy the description from the zib profile.
 +
*** For profiles representing a specific concept of a data model: the definition text of the concept. If the definition is not suitable as a description (e.g. a zib container), an applicable description should be created.
 +
*** For standard specific profiles: as applicable.
 +
** For extensions:
 +
*** A description of what the extension is for. If the extension represents a single concept, it could be of the form <q>An extension to provide [(adapted) concept definition].</q>
 +
* purpose:
 +
** For profiles:
 +
*** For zib profiles: <q>This ''[resource type]'' resource represents the Dutch [zib ('Zorginformatiebouwsteen', i.e. Health and Care Information Model) ''[English zib name]'' ''[version]''(''[release]'')](''[link to the English zib page on zibs.nl]'').</q><br/>Note 1: This template includes a markdown link: ''[text](url)''. A complete example would be: <q>This Patient resource represents the Dutch [zib ('Zorginformatiebouwsteen', i.e. Health and Care Information Model) Patient v3.2 (2020)](<nowiki>https://zibs.nl/wiki/Patient-v3.2(2020EN)</nowiki>).</q><br/>Note 2: If the profile represents (a concept of) multiple zibs, they are listed in the form of (Markdown formatting omitted): <q>... the Dutch zib ('Zorginformatiebouwsteen', i.e. Health and Care Information Model) ''[zib info]'', the Dutch zib ''[zib info]'' and the Dutch zib ''[zib info]''.</q>
 +
*** For profiles directly representing a particular concept of a zib: <q>This ''[resource type]'' resource represents the ''[concept name]'' concept ''([zib concept id])'' of the Dutch [zib ('Zorginformatiebouwsteen', i.e. Health and Care Information Model) ''[English zib name]'' ''[version]'' (''[release]'')](''[link to the English zib page on zibs.nl]'').</q>
 +
*** For nl-core profiles: <q>A derived profile from [''[id of zib profile]''](''[canonical of zib profile]'') to provide a version better suited for implementation purposes. This profile augments the base profile with elements found in the various use cases that have adopted the zib.</q>
 +
*** For standard specific profiles: a description with a reference to the base profile, with an explanation of why it has been added.
 +
** For extensions:
 +
*** For extension representing a specific concept: <q>This extension represents the ''[concept name]'' concept of ''[name of the building block]''</q>, followed by a link to the functional description. If the extension represents a zib concept this becomes: <q>This extension represents the ''[concept name]'' concept of the Dutch [zib ('Zorginformatiebouwsteen', i.e. Health and Care Information Model) ''[English zib name]'' ''[version]'' (''[release]'')](''[link to the English zib page on zibs.nl]'').</q>
 +
*** For other extensions this will usually be absent.
 +
** Note: for extensions and datatype profiles, guidance for profilers may be placed here as well.
 +
* copyright: <q>Copyright and related rights waived via CC0, <nowiki>https://creativecommons.org/publicdomain/zero/1.0/</nowiki>. This does not apply to information from third parties, for example a medical terminology system. The implementer alone is responsible for identifying and obtaining any necessary licenses or authorizations to utilize third party IP in connection with the specification or otherwise.</q>
 +
* mapping: see [[#Associating_the_functional_definition_to_StructureDefinitions]]
 +
* abstract: usually ''false'', but may be set to ''true'' when this profile is to be used ''only'' as a base profile from which other profiles should be derived.
 +
* comment: when special guidance on the use of this profile is needed, it will be placed here. For example: when this profile has a (non-trivial) relationship to other profiles, when a concept of the functional description is mapped over multiple elements, etc.<br />Note: this should be guidance aimed at ''implementers''. When the guidance is aimed at ''profilers'', for example in extensions or datatype profiles, it should be added to {{fhir|StructureDefinition.purpose}}.
 +
* alias:
 +
** for zib profiles: the zib concept name as dictated by [[#Associating the functional definition to StructureDefinitions]].
 +
** for nl-core profiles: the id of the profile (this is actually just a placeholder for when there is no actual difference with the base profile, as FHIR requires {{fhir|StructureDefinition.differential}} or {{fhir|StructureDefinition.snapshot}} to be populated).
  
For some elements it's clear, e.g. the IdentificationNumber will always go to .identifier, and for other elements it is not, e.g. InformationSource. What would be the InformationSource for the resource Patient? When would a ContactPerson be a Subject in the current profiles, instance had of a Patient?)
+
====Metadata for elements====
 +
* For elements that map directly (not [[#Mandatory FHIR elements without a functional counterpart|implicitly]]) to zib concepts:
 +
** The English name from the zib concept is placed on {{fhir|element.short}} (in elements that refer to other zibs, the name is built up like <q>ElementName::ReferenceZibName</q>, but we only use the part before the double colons). If there are multiple zib elements mapped to a single FHIR element, it will be formatted like <q>ZibConcept1 / ZibConcept2</q> (unless the names are the same).
 +
** The zib concept description is placed on {{fhir|element.definition}}, unless it's the root concept of the zib (because this will always be <q>Root concept of the [...] information model ...</q>, which doesn't provide much information). If there are multiple zib elements mapped to a single FHIR element, the descriptions will be placed in a bullet list.
 +
** The Dutch zib concept names are placed on {{fhir|element.alias}}
 +
* For elements that bind ValueSets:
 +
** If there is a ConceptMap, {{fhir|.binding.description}} will be: <q>Use ConceptMap [ConceptMap.name] to translate terminology from the functional model to profile terminology in ValueSet [ValueSet.name]</q>
 +
** Otherwise, {{fhir|.binding.description}} is not populated.
 +
* For elements that are (directly or indirectly) included in a custom constraint defined elsewhere:
 +
** The keys of all related constraints are added to {{fhir|.condition}} (note: this is thus not necessary when the constraint is defined on the element itself). Because {{fhir|.condition}} is added to notify the implementer that a constraint applies to the usage of this element, this rule applies to both the element directly mentioned in the constraint as well as its child element(s) that contain the mapping to the functional model.
  
The table outlines which mappings are clear and which are yet to be determined. As of the Spring release 2019 of MedMij, all BasicElement mappings have applied for as far as possible:
+
===ConceptMaps===
 +
====Metadata on the ConceptMap root====
 +
* status: as applicable (normally ''draft'' or ''active'')
 +
* publisher: <q>Nictiz</q>
 +
* contact:
 +
** name: <q>Nictiz</q>
 +
** telecom:
 +
*** system: <q>url</q>
 +
*** value: <q><nowiki>https://www.nictiz.nl</nowiki></q>
 +
*** use: <q>work</q>
 +
* description: <q>Maps [functional ValueSet] codes as found in [linked description to the functional model] to [FHIR ValueSet] codes as found in FHIR R4.</q><p>For zibs, the linked description will be <q>the Dutch [zib ('Zorginformatiebouwsteen', i.e. Health and Care Information Model) ''[English zib name]'' ''[version]''(''[release]'')](''[link to the English zib page on zibs.nl]'').</q>
 +
* copyright: <q>Copyright and related rights waived via CC0, <nowiki>https://creativecommons.org/publicdomain/zero/1.0/</nowiki>. This does not apply to information from third parties, for example a medical terminology system. The implementer alone is responsible for identifying and obtaining any necessary licenses or authorizations to utilize third party IP in connection with the specification or otherwise.</q>
 +
* In addition, the [bidirectional extension (http://hl7.org/fhir/StructureDefinition/concept-bidirectional)](http://hl7.org/fhir/StructureDefinition/concept-bidirectional) is added with a value to indicate whether this ConceptMap can be used in both ways.
  
{| class="wikitable"
+
==Narratives==
!BasicElement!![http://hl7.org/fhir/STU3/w5.html Profiel element]!!Remark
+
The FHIR spec states that resources SHOULD have a narrative, in order <q>to support human-consumption as a fallback</q>. This works out in the following way:
|-
+
* For example instances: a narrative is added that ''at least covers'' all the profiled elements, with {{fhir|Narrative.status}} = {{term|generated}} or {{term|extensions}}.
|NL-CM:0.0.1 HCIMRoot||-||not possible
+
* For definitional resources (profiles, extensions, ConceptMaps, SearchParameters, etc.), a narrative is added with {{fhir|Narrative.status}} = {{term|empty}}, and the following content for {{fhir|Narrative.div}}: <q>No narrative is provided for definitional resources. A human-readable rendering can be found in the implementation guide(s) where this resource is used.</q>
|-
 
|NL-CM:0.0.6 IdentificationNumber ||.identifier||Overlaps sometimes with existing mapping such as HealthProfessionalIdentificationNumber or PatientIdentificationNumber. Unclear what to do with sub parts of an HCIM such as LabroatoryTest and Specimen. Presumably best to map to Observation.identifier and Specimen.identifier
 
|-
 
|NL-CM:0.0.2 InformationSource||.asserter||Mapped only when clinically relevant, e.g. AllergyIntolerance.asserter, Condition.asserter. What HCIM is this really applicable to?
 
|-
 
|NL-CM:0.0.3 PatientAsInformationSource::Patient||Patient||
 
|-
 
|NL-CM:0.0.4 HealthProfessional||Practitioner <nowiki>|</nowiki> PractitionerRole||
 
|-
 
|NL-CM:0.0.5 RelatedPersonAsInformationSource::ContactPerson||RelatedPerson||
 
|-
 
|NL-CM:0.0.7 Author||.author <nowiki>|</nowiki> .performer||FHIR resources do not all have RelatedPerson in its choice list, or even Patient. Example is [http://hl7.org/fhir/STU3/diagnosticreport.html DiagnosticReport]. Is it clinically relevant and/or reasonable to assume a Patient and/or RelatedPerson as possible author?|
 
|-
 
|NL-CM:0.0.8 PatientAsAuthor::Patient||Patient||
 
|-
 
|NL-CM:0.0.9 HealthProfessionalAsAuthor::HealthProfessional||Practitioner <nowiki>|</nowiki> PractitionerRole||
 
|-
 
|NL-CM:0.0.10 RelatedPersonAsAuthor::ContactPerson||RelatedPerson||
 
|-
 
|NL-CM:0.0.11 Subject||.subject <nowiki>|</nowiki> .patient||A RelatedPerson is never a Subject of care except possibly for a family anamnesis. Is it clinically relevant and/or reasonable to assume RelatedPerson as possible subject regardless?
 
|-
 
|NL-CM:0.0.12 Patient||Patient||
 
|-
 
|NL-CM:0.0.13 RelatedPersonAsSubject::ContactPerson||RelatedPerson ||
 
|-
 
|NL-CM:0.0.14 DateTime||.effective <nowiki>|</nowiki> .onset||Is this clinically relevant time to be assumed only on clinical HCIMs? So not on e.g. Patient, Practitioner, Organization?
 
|}
 
  
===Miscellaneous===
+
The reason for using an {{term|empty}} narrative in definitional resources is that it is not trivial and at the same time redundant to satisfy the requirement that the narrative must <q>reflect all content needed for a human to understand the essential clinical and business information for the resource</q>. It is redundant because a useful representation is already published as part of the implementation guide(s) where this resource is used; it is not trivial because all content is relevant in these kind of resources, and representing this in a useful way would amount to replicating the view from the implementation guide(s) in the narrative.
* We only profile elements, cardinalities and bindings that require profiling. We leave other elements, cardinalities and bindings as-is (see [[#Open_vs._Closed_Modeling]])
 
* For elements that map to Health and Care Information Models (HCIM):
 
** We copy the name from the HCIM element into the profile element.short (in elements that refer to other zibs, the name is built up like ''<<ElementName::ReferenceZibName>>'', but we only use the part before the double colons)
 
** The HCIM concept description is placed in the profile element.definition
 
** The HCIM Dutch concept name is placed in the profile element.alias
 
** {{anchor|Placing-Info}}''Note: as a rule of thumb, we place this info 'as close as possible' to the elements that actually represent the data. For example: when slicing, the texts are placed on the slice content, not the slice itself. Similarly, in concept containers like Observation.component, this info is placed on the .valueXXX elements. This is also true for [[#Associating_functional_definition_to_StructureDefinition | the HCIM mappings]].''
 
** Implementation guidance, such as mapping clarification and usage, of HCIM concepts that are mapped to multiple elements is given on the root of the resource. The [http://simplifier.net/resolve?fhirVersion=STU3&scope=nictiz.fhir.nl.stu3.zib2017@2.0.0&canonical=http://fhir.nl/fhir/StructureDefinition/nl-core-address nl-core-address profile] provides a good example.
 
* Slices get an UpperCamelCased name based on the HCIM element name.
 
* New elements defined through extensions get a lowerCamelCased name based on the HCIM element name.
 
* When adding invariants we use "hcim-[hcim-name]-[number]"  as a key. Example: hcim-alert-1
 
* [https://docs.google.com/document/d/1ClF3XpIrE2FiIDG7K7VD3pPjOPx3T950Sfi1Ip8ORcU/edit#heading=h.641auhfi9fvs FHIR URI Strategy] (draft document with potentially good info)
 
* For FHIR base resource elements with datatype ''code'' and binding ''required'' it may be that the HCIM has other/additional codes to specialize the FHIR codes. To conform to FHIR and the HCIM:
 
** We will document the mapping in a ConceptMap, which will be linked from the element .mapping comment.
 
** We will use the extension [https://simplifier.net/resolve?canonical=http://nictiz.nl/fhir/StructureDefinition/code-specification http://nictiz.nl/fhir/StructureDefinition/code-specification]:
 
*** The extension is of datatype CodeableConcept, which also supports text as a fallback. It is bound with strength "extensible" on the HCIM derived ValueSet in the profile where it is applied.
 
*** The extension slice is named after the full English name of the code list according to the HCIM.
 
*** Mapping from the HCIM concepts is applied to the .valueCodeableConcept.mapping in the extension (in addition to the .mapping in the FHIR element).
 
  
==Open vs. Closed Modeling==
+
==Miscellaneous==
 +
* {{anchor|Placing-Info}}As a rule of thumb, info is placed 'as close as possible' to the elements that actually represent the data. For example: when slicing, the texts are placed on the slice content, not the slice itself. Similarly, in concept containers like {{fhir|Observation.component}}, this info is placed on the .valueXXX elements. This is also true for [[#Associating_functional_definition_to_StructureDefinition | the zib mappings]].''
 +
* Slices get a lowerCamelCased name based on the functional concept name.
 +
* New elements defined through extensions get a lowerCamelCased name based on the functional concept name.
 +
* The key for invariants should be:
 +
** for zibs: <q>zib-[English zib name]-[number]</q>, eg. zib-Alert-1.
 +
** for nl-core: <q>nl-core-[English zib name]-[number]</q>.
 +
** for use case specific profiles: <q>[dataset id]-[number]</q>, where [dataset id] is preferably the same as its matching ART-DECOR project prefix.
 +
* Inline examples in profiles are added (only) when the usage of an element in the profile is not trivial.
  
{| class="wikitable"
+
=Special cases=
|-
+
==Special use of FHIR resources==
! ×
+
===Using {{fhir|Observation.hasMember}} vs {{fhir|Observation.component}}===
! Open
+
The Observation resource has two competing mechanisms for defining observations consisting of multiple distinct parts: using {{fhir|Observation.component}}, all parts are inlined into a single Observation resources, while {{fhir|Observation.hasMember}} allows one to group the parts modeled as distinct Observation resources. According to the FHIR spec, the latter approach should be used unless the part cannot be interpreted on its own (i.e. if there ''could'' be a use case to query the part separately, it should be a distinct Observation, otherwise it should be a {{fhir|.component}}). This sometimes is a somewhat arbitrary choice, but the following guidelines can help:
! Closed
+
* If the definition code indicates that the part is an "Observable entity" (child of SNOMED/{{term|363787002}}) or an "Evaluation procedure" (child of SNOMED/{{term|386053000}}), it is a good indication that the part should be a distinct Observation. These are the [https://www.hl7.org/fhir/r4/observation-mappings.html#sct-concept SNOMED domain bindings] of {{fhir|Observation.code}}.
|-
+
* Scale or score models are modeled as a single Observation with {{fhir|.components}}. Although it could be argued that the various elements that are part of the total score are at least based on separate Observations, the scores themselves are an integral part of a set of scores and should not be interpreted outside of this context.
! Pros
 
| - Forward compatibility
 
  
- Modelers don't have to think about what you shouldn't support, only what must be supported 
+
To profile a model as a set of grouped Observations:
 +
* A focal profile should be created representing the "group" or "panel" concept, with an appropriate definition code on {{fhir|Observation.code}}.
 +
* For each part, a distinct profile is created (following the [[#Identity of artifacts|normal naming conventions]]).
 +
** Concepts from the main model that are relevant to the partial Observations will be mapped to the partial profiles as well. There is no general rule for determining which concepts are relevant, a careful analysis needs to be performed on all concepts. Typically, concepts like the date/time and the method of the measurement are relevant to the partial Observations as well.
 +
** The normal mapping rules apply, so if a single concept is being profiled, the mapping will be on the {{fhir|Observation.value''DataType''}} element and not on the root of that profile.
 +
* In the focal profile, {{fhir|Observation.hasMember}} is sliced by profile, and a slice is added for each concept profile.
 +
* The relationship between the profiles is documented in the following way:
 +
** As described in [[#Metadata on the StructureDefinition root]], a comment is placed on the StructureDefinition root in both the focal profile and in the profiles representing the parts to describe the relationship between the profiles.
 +
*** For the profiles representing the parts, this will usually be: <q>This Observation resource represents the ''[English concept name]'' concept (''[concept id]'') of ''[English model name]''. It can be used together with the [''[focal profile id]''](''[focal profile canonical]'') profile on the Observation resource, which groups references to the current and other resources on `Observation.hasMember`.</q>
 +
*** If there's just one part, for the focal profile this comment will usually be: <q>The [English concept name] concept ([concept id]) is represented using distinct Observation resources, using profile [''[profile id]''](''[profile canonical]''). It is referenced from this resource using `Observation.hasMember`.</q>.
 +
*** If there are multiple parts, for the focal profile this comment will usually be: <q>Several concepts of ''[English model name]'' are represented using distinct Observation resources. These are grouped using the current resource and are referenced on `Observation.hasMember`:</q>, followed by a bullet list of all profiled concepts in het form of: <q>* ''[English concept name]'' (''[concept id]''): [''[profile id]''](''[profile canonical]'')</q>.
 +
** On each {{fhir|Observation.hasMember}} slice in the focal profile, the following definition text is set: <q>The ''[English concept name]'' concept (''[concept id]'') of ''[English model name]'', represented as a distinct Observation resource.
  
- Implementers can fit more data, even if it's not in specified explicitly bu the profile
+
===Measurement qualifiers in {{fhir|Observation.component}}===
|| - Implementers, don't have to support all elements that maybe, someday could be used, according to the model
+
Functional models for measurements will usually be mapped onto the FHIR Observation resource. The type of measurement is conveyed using {{fhir|Observation.code}} and the result of the measurement is conveyed using {{fhir|Observation.value[x]}}, or {{fhir|Observation.component.value[x]}} if the measurement consists of multiple components.
- Model becomes more specific
 
  
- Model becomes smaller and more straightforward
+
However, sometimes the functional model requires that the type of measurement needs to be further specified using a qualifier. For this purpose, the {{fhir|Observation.method}} and {{fhir|Observation.bodySite}} elements can be used. If it is not possible to map these concepts to these elements or to a core extension of Observation, they may be mapped to {{fhir|Observation.component}}, according to a remark in the specification ([https://www.hl7.org/fhir/r4/observation.html#gr-comp "or may provide qualifying information to {{fhir|Observation.code}}"]) and [https://chat.fhir.org/#narrow/stream/179166-implementers/topic/Pathology.20Lab.20Reports.20.E2.80.93.20Dynamic.20Function.20Tests.20.2F.20Timed.20Tests/near/227279594 a discussion on Zulip], which concludes that the use of {{fhir|Observation.component}} for qualifiers is appropriate and preferred above (custom) extensions.
  
- More implementer feedback, about elements they want to support, but currently can't
+
===HL7 Vital Signs===
 +
The FHIR R4 specification for the Observation resource defines [https://www.hl7.org/fhir/vitalsigns.html a profile for vital signs measurements]. Furthermore, it states that:
 +
<blockquote>If implementations use this Resource when expressing the profile-specific concepts as structured data, they SHALL conform to the following profiles</blockquote>
 +
This means that the following zib profiles would need to be based on the HL7 Vital Signs profile:
 +
* BloodPressure
 +
* BodyHeight
 +
* BodyWeight
 +
* BodyTemperature
 +
* HeadCircumference
 +
* HeartRate
 +
* O2Saturation
  
|-
+
The FHIR spec defines derived profiles for each of these vital signs, plus [https://www.hl7.org/fhir/observation-vitalsigns.html an IG] with further recommendations.
! 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 straightforward about what should actually be supported, and what can optionally be supported
+
However, the HL7 Vital Signs profile imposes two issues that make it impossible to implement zib profiles for the relevant vital signs measurements directly onto it:
 +
* The {{term|required}} terminology binding on {{fhir|Observation.component}} to the [http://hl7.org/fhir/ValueSet/ucum-vitals-common Vital Signs Units] dataset makes it impossible to use {{fhir|.component}}'s for representing anything else than a Quantity (like a {{datatype|CodeableConcept}} or a {{datatype|boolean}}), which is required by some of these zibs.
 +
* The {{fhir|mustSupport}} = {{term|true}} flag found on numerous elements isn't further specified in the HL7 Vital Signs IG, as is required by FHIR.
  
- Less implementer feedback: elements they want to send can be easier 'hacked' in a not yet explicitly specified element. Model won't be improved.
+
To circumvent this problem, it has been chosen ''not'' to directly base the zib profiles onto the HL7 Vital Signs profiles, but instead create profiles that aim to be (as) functional equivalent (as possible). This means that constraints, terminology bindings, etc. are adopted (except for the terminology binding mentioned above) and that the zib profiles are not in conflict with the equivalent HL7 profiles, ''except'' for the requirement that {{fhir|Observation.hasMember}} and {{fhir|Observation.derivedFrom}} should have a HL7 Vital Signs target – this requirement cannot be satisfied when cloning a profile. Where possible, the current profiling guidelines are followed rather than the approach by HL7 (e.g. where the HL7 profiles use slices with a fixed code and system to enforce the inclusion of a coding, the zib profiles use a pattern).
  
||  
+
On occasion, the zib takes another approach to communicate a certain concept than HL7 Vital Signs. For example, zib BodyHeight specifies a ValueSet for the body position during measurement (lying or standing), while the HL7 Vital Signs suggests to include an additional {{fhir|Observation.code.coding}} for "body height measurement while lying down" (only). When the zib approach is not incompatible with the HL7 approach, the zib approach will be followed and the difference will be documented in the {{fhir|.comment}} of the relevant element.
  
- More versions of models, after more elements have to be supported
+
To enforce a consistent approach for creating the vital signs zib profiles, a {{Simplifier|http://nictiz.nl/fhir/StructureDefinition/pattern-VitalSigns|title=pattern profile}} has been created. Please note that this should not be interpreted as an equivalent to the base HL7 Vital Signs profile; the zib profiles deliberately skip the common base profile and are directly matched directly to their equivalent HL7 profiles like BloodPressure, BodyHeight, etc. This base profile is not needed for the current use case and omitting it prevents a layer of complexity; for example, the HL7 Vital Signs base profile binds certain ValueSets which are then restricted again in the derived profiles.
  
- No forward compatibility, only backwards
+
===Person characteristics: extension or Observation?===
 +
Some type of information can be described as a characteristic or property of a person, like life stance, marital status, language proficiency, nationality, etc. There is a tendency in FHIR to inline this kind of data in the Patient resource, either using a core element or a core extension (and to a lesser degree to the RelatedPerson and Practitioner resources).
  
- Implementers have to wait for a new version of the model, if they want to support elements, that are currently not in scope.
+
However, this choice seems somewhat arbitrary. Oftentimes this kind of information could equally well be regarded as an Observation. For example: whereas the name can be seen as something that is truly part of the patient, and a heart rate truly as a measurement made at some point in time, one could argue that both religion and body height fall somewhere in between – both of them usually apply to longer periods of time, neither of them require additional data apart from the main characteristic, and both of them can have an independent existence. So when modeling these kind of characteristics, the question is whether an Observation should be used or an extension.
|}
 
  
We have chosen for "open" modeling for the HCIMs, since they are very general and not meant for one specific use case. Excluding unspecified elements here is not an option, since we expect derived profiles for more specific use cases that may need those elements.
+
Given that:
 +
* In international IGs, there doesn't seem to be a strong preference for one of the two approaches;
 +
* FHIR core should be used where possible; and
 +
* custom extensions are discouraged,
  
==Cardinality/conformance mapping table==
+
the following guidance applies:
 +
# If possible, use a core element to model the characteristic.
 +
# If this is not possible, use a core extension to model the characteristic.
 +
# If this is not possible, create a profile on Observation.
  
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.  
+
==Zib 2020 specific considerations==
 +
===Implicit subject reference===
 +
Starting from release 2020, zibs oftentimes do not explicitly define their subject, i.e. who or what the information is about. However, the general guideline for zibs is that they capture healthcare information about a patient. So implicitly there ''is'' a subject, and this subject is usually a patient – although in some cases it might be inferred that the subject is something or someone else, or can be more than just a patient.
  
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.  
+
The following guidelines apply for profiling a zib without an explicit subject:
 +
* In the zib profiles, the subject will ''not'' be modeled explicitly.
 +
* In the nl-core profiles, the subject ''will'' be modeled as a reference to the relevant nl-core profile.
  
Reference: [http://hl7.org/fhir/elementdefinition-definitions.html#ElementDefinition.mustSupport ElementDefinition.mustSupport]
+
The reason for this is that even though the subject is assumed, when it is not explicitly defined, no formal mapping can be made to a profile. On the other hand, it can be assumed that the subject will be modeled explicitly once the zib is used in a use case scenario,
  
This poses a need for a mapping table from cardinality/conformance in HCIMs versus that in profiles.
+
===Referencing zib HealthProfessional===
 +
[https://zibs.nl/wiki/HealthProfessional-v3.5(2020EN) Zib HealthProfessional] is mapped onto two profiles: one on FHIR resource PractitionerRole (zib-HealthProfessional-PractitionerRole) and one on FHIR resource Practitioner (zib-HealthProfessional-Practitioner). The PractitionerRole resource covers the recording of the location and types of services that HealthProfessionals are able to provide for a HealthcareProvider, whereas the Practitioner resource captures the personal information, including the identifiers of the health professional.
  
{| class="wikitable"
+
In FHIR, it is usually possible to define a reference to either resource. However, the reference to this zib from other zibs will be modelled in the following way:
|-
+
* Only zib-HealthProfessional-PractitionerRole is added to the list of target resources.
! Generic (HCIM) !! FHIR !! --- !! Specific application !! FHIR
+
* As described in [[#Constraining references]], no restrictions on the base Practitioner or PractitionerRole are made.
|-
 
| 0..1 || 0..1 || || 0..1 || 0..1
 
|-
 
| 0..1 C || 0..1 || || 0..1 C || 0..1
 
|-
 
| 0..1 R || 0..1 || || 0..1 R || 0..1 - consider mustSupport='true'
 
|-
 
| 0..* || 0..* || || 0..* || 0..*
 
|-
 
| 0..* C || 0..* || || 0..* C || 0..*
 
|-
 
| 0..* R || 0..* || || 0..* R || 0..* - consider mustSupport='true'
 
|-
 
| 1..1 || <span style="color: red;">'''0'''</span>..1 || || 1..1 || <span style="color: red;">'''0'''</span>..1
 
|-
 
| 1..1 C || <span style="color: red;">'''0'''</span>..1 || || 1..1 C || <span style="color: red;">'''0'''</span>..1
 
|-
 
| 1..1 R || <span style="color: red;">'''0'''</span>..1 || || 1..1 R || <span style="color: red;">'''0'''</span>..1 - consider mustSupport='true'
 
|-
 
| 1..1 M || 1..1 || || 1..1 M || 1..1 - consider mustSupport='true'
 
|-
 
| 1..* || <span style="color: red;">'''0'''</span>..* || || 1..* || <span style="color: red;">'''0'''</span>..*
 
|-
 
| 1..* C || <span style="color: red;">'''0'''</span>..* || || 1..* C || <span style="color: red;">'''0'''</span>..*
 
|-
 
| 1..* R || <span style="color: red;">'''0'''</span>..* || || 1..* R || <span style="color: red;">'''0'''</span>..* - consider mustSupport='true'
 
|-
 
| 1..* M || 1..* || || 1..* M || 1..* - consider mustSupport='true'
 
|}
 
  
mustSupport="true" has the consequence that any conformant instances based on this profile SHALL support this part of the profile in the way that is defined by the implementation guide that governs the profile. This is not possible to state for a generic profile that aims to support many more use cases/contexts than is possible to know from the perspective of the profile. If a specific context requires use of a certain part of the profile it MAY choose to specify a constraining profile on top of the generic profile to do just that.
+
This approach has been adopted for two reasons. First, the relation between these two resources points from PractitionerRole to Practitioner; having a PractitionerRole instance, the Practitioner instance can be resolved, but not the other way around. Second, information about a health professional will rarely be communicated without the details captured using PractitionerRole.
  
==Constraining references==
+
This mechanism guides implementers to the use of the zib-HealthProfessional-PractitionerRole profile as the main entry point for zib HealthProfessional. Meanwhile, when there is a need to communicate the zib-HealthProfessional-Practitioner profile instead, this is still possible as the base resource Practitioner is still available.
HCIMs might have have connections to other HCIMs. Example: a MedicationAgreement might have a [https://decor.nictiz.nl/art-decor/decor-datasets--mp-?id=2.16.840.1.113883.2.4.3.11.60.20.77.1.3&effectiveDate=2016-06-01T00%3A00%3A00&conceptId=2.16.840.1.113883.2.4.3.11.60.20.77.2.3.19835&conceptEffectiveDate=2015-11-24T08%3A40%3A47&language=nl-NL Prescriber] relationship defined using a HealthProfessional which is mapped to a FHIR MedicationRequest.requester as Reference(Practitioner). The [http://hl7.org/fhir/STU3/medicationrequest.html FHIR MedicationRequest] however, defines more types: Reference(Practitioner | PractitionerRole | Organization | Patient | RelatedPerson | Device). The closed world model would mandate that the profile only marks Practitioner for use. The open world model would mandate that the profile describes that for a HealthProfessional you need the Practitioner without omitting the other choices.
 
  
For general purpose profiles, suitable for further constraining we use open world profiling meaning that we do not constrain the choices of references into just the types that the HCIM requires. We only constrain the generic resource reference to the generic profile(s) for that resource. For Practitioner this would be the nl-core-practitioner. If deemed relevant a second layer of derived profile(s) could be created to tailor the generic profile for a specific use case using closed world modeling.
+
To ensure consistent documentation of this mechanism, the profile {{Simplifier|http://nictiz.nl/fhir/StructureDefinition/pattern-ZibHealthProfessionalReference}} has been created. The {{fhir|.title}} of this profile is simply 'Reference' instead of 'zib HealthProfessional Reference', as is expected following the profiling guidelines. This deviation from the guidelines is the result of the {{fhir|.title}} being used to render the profile in various tooling (mainly Simplifier), and the latter title would result in a rendering that is deemed confusing in some cases (see [https://bits.nictiz.nl/browse/MM-3854 MM-3854]).
  
==Data type mapping table==
+
=Data type mapping=
  
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. The table below shows a mapping for datatypes in HCIMs versus those in profiles.
+
In most cases, the mapping between ART-DECOR, zib and FHIR datatypes is straightforward, though there are a number of cases which are not as clear-cut. The table below shows how datatypes from the functional models should be mapped to FHIR.
  
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! HCIM
 
 
! ART-DECOR
 
! ART-DECOR
 +
! zib
 
! FHIR  
 
! FHIR  
 
! Remarks
 
! Remarks
 
|-
 
|-
| INT || count || [https://www.hl7.org/fhir/STU3/datatypes.html#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 system="http://unitsofmeasure.org" and code="1" (for units). If this is not appropriate, use integer.
+
| {{datatype|count}} || {{datatype|INT}} || [https://www.hl7.org/fhir/STU3/datatypes.html#Count {{datatype|Count}}] or {{datatype|integer}} || {{datatype|Count}} in FHIR is derived from {{datatype|Quantity}}. This is appropriate for observations, such as a count of red blood cells in a specimen. {{datatype|Count}} in FHIR is a {{datatype|Quantity}} with {{fhir|system}} set to <code><nowiki>http://unitsofmeasure.org</nowiki></code> and {{fhir|code}} set to {{term|1}} (for units). If this is not appropriate, use {{datatype|integer}}.
 
|-
 
|-
| BL || boolean || boolean ||  
+
| {{datatype|boolean}} || {{datatype|BL}} || {{datatype|boolean}} ||  
 
|-
 
|-
| ED || blob || base64Binary ||  
+
| {{datatype|blob}} || {{datatype|ED}} || {{datatype|base64Binary}} or {{datatype|Attachment}} ||  
 
|-
 
|-
| CD || code || CodeableConcept or coding or code || In general, CodeableConcept will be the right choice. See [http://hl7.org/fhir/terminologies.html Using Codes in Resources] for details.  
+
| {{datatype|code}} || {{datatype|CD}} || {{datatype|CodeableConcept}} or {{datatype|coding}} or {{datatype|code}} || In general, {{datatype|CodeableConcept}} will be the right choice. See [http://hl7.org/fhir/terminologies.html Using Codes in Resources] for details.  
 
|-
 
|-
| ANY || complex || BackboneElement || 'complex' is data which is not further defined in DECOR, and thus cannot be translated.  
+
| {{datatype|complex}} || {{datatype|ANY}} || {{datatype|BackboneElement}} || {{datatype|complex}} is data which is not further defined in DECOR, and thus cannot be translated.  
 
|-  
 
|-  
| - || currency || Money || Does not have a HCIM counterpart currenty. Theoretically this could be MO
+
| {{datatype|currency}} || - || {{datatype|Money}}|| Does not have a zib counterpart currently. Theoretically this could be {{datatype|MO}}.
 
|-  
 
|-  
| - || date || date || Does not have a HCIM counterpart currently. Closest counterpart could be TS
+
| {{datatype|date}} || - || {{datatype|date}} || Does not have a zib counterpart currently. Closest counterpart could be {{datatype|TS}}.
 
|-  
 
|-  
| TS || datetime || dateTime ||  
+
| {{datatype|datetime}} || {{datatype|TS}} || {{datatype|dateTime}} ||  
 
|-
 
|-
| - || decimal || decimal || Does not have a HCIM counterpart currently. Theoeratically this could be REAL
+
| {{datatype|decimal}} || - || {{datatype|decimal}} || Does not have a zib counterpart currently. Theoretically this could be {{datatype|REAL}}.
 
|-  
 
|-  
| - || duration || Duration || Does not have a HCIM counterpart currently. Closest counterpart could be PQ
+
| {{datatype|duration}} || - || {{datatype|Duration}} || Does not have a zib counterpart currently. Closest counterpart could be {{datatype|PQ}}.
 
|-
 
|-
| II || identifier || Identifier ||  
+
| {{datatype|identifier}} || {{datatype|II}} || {{datatype|Identifier}} ||  
 
|-
 
|-
| CO || ordinal || CodeableConcept or coding or code || See [http://hl7.org/fhir/terminologies.html Using Codes in Resources] for details.
+
| {{datatype|ordinal}} || {{datatype|CO}} || {{datatype|CodeableConcept}} or {{datatype|coding}} or {{datatype|code}} || See [http://hl7.org/fhir/terminologies.html Using Codes in Resources] for details.
 
|-
 
|-
| ST || string || string ||  
+
| {{datatype|string}} || {{datatype|ST}} || {{datatype|string}} or {{datatype|markdown}}||  
 
|-
 
|-
| - || ratio || Ratio || Does not have a HCIM counterpart currently. Closest counterpart could be RTO
+
| {{datatype|ratio}} || - || {{datatype|Ratio}} || Does not have a zib counterpart currently. Closest counterpart could be {{datatype|RTO}}.
 
|-
 
|-
| - || text || string || Does not have a HCIM counterpart currently.
+
| {{datatype|text}} || - || {{datatype|string}} || Does not have a zib counterpart currently.
 
|-
 
|-
| PQ || quantity || Quantity ||  
+
| {{datatype|quantity}} || {{datatype|PQ}} || {{datatype|Quantity}} ||  
 
|}
 
|}
 +
==Notes on binary data ({{datatype|ED}} or {{datatype|blob}})==
 +
Binary data requires special considerations when profiling. One aspect of binary data is that it tends to represent large multimedia files. Healthcare systems might want to have explicit control over the exchange of such files, rather than being confronted with unexpected large data transfers when performing a search or read operation. In addition, these files could have a need for additional metadata next to the structured content present in the clinical data model.
  
==Translating DECOR to FHIR==
+
In FHIR R4, the exchange of binary data is mediated using a combination of resources and data types:
Status: proposal
+
* Data type {{datatype|[http://hl7.org/fhir/r4/datatypes.html#attachment Attachment]}}; this data type provides the means to transfer the actual bytes and annotate it with the proper content type, so that the receiver knows how it is interpreted. This data type offers two ways of transporting the binary content:
 
+
** inline ({{fhir|Attachment.data}}).
Quite often we will populate FHIR artifacts from DECOR artifacts. In such cases, FHIR identification must be derived from DECOR identification.
+
** as reference to an external URL ({{fhir|Attachment.url}}).
 
+
* Resource type DocumentReference; this resource type provides a way to specify metadata about a multimedia file specified using the {{datatype|Attachment}} data type.
DECOR uses the attributes id and effectiveDate to identify concepts, datasets, transactions, valueSets and templates. The artifacts with the same id but different effectiveDates are subsequent versions of the same artifact (though artifacts can also get a new id for a new version, such as when a new dataset is derived from an older one).
+
* Resource type Media; this resource type is similar and has been deprecated in FHIR R5 in favor of DocumentReference.
 
+
* Resource type Binary; this resource type is only meant to wrap binary data in a FHIR resource. It could be the target of {{fhir|Attachment.url}} if there's a strict need to keep all exchanges within the FHIR RESTful framework.
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 artifacts map to FHIR artifacts:
 
 
 
{| class="wikitable"
 
|-
 
! DECOR artifact !! FHIR artifact || 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.
 
|-
 
| dataset<br/>transaction || 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.
 
|-
 
| valueSet || ValueSet || http://art-decor.org/ns/oids/vs ||
 
|}
 
 
 
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.
 
 
 
{| class="wikitable"
 
|-
 
! FHIR artifact !! derivation from DECOR
 
|-
 
| FHIR id || @id + '--' + @effectiveDate
 
|-
 
| FHIR identifier system || See above
 
|-
 
| FHIR identifier value ||  @id
 
|-
 
| FHIR version || @effectiveDate
 
|-
 
| FHIR status || See below
 
|}
 
 
 
Status is translated from DECOR to FHIR:
 
 
 
{| class="wikitable"
 
|-
 
! DECOR status !! FHIR status
 
|-
 
| new || draft
 
|-
 
| draft || draft
 
|-
 
| pending || draft
 
|-
 
| active || active
 
|-
 
| review || draft
 
|-
 
| cancelled || retired
 
|-
 
| rejected || retired
 
|-
 
| deprecated || retired
 
|+ default is 'draft'
 
|}
 
  
 +
It should be noted that the Observation resource does not offer {{datatype|Attachment}} as a valid data type for {{fhir|.value[x]}} (or {{fhir|.component.value[x]}}), although FHIR R5 does support this.
  
[[Category:FHIR]]
+
This translates to the following guidelines:
 +
* Binary data should be mapped onto data type {{datatype|Attachment}}.
 +
** For the generic zib and nl-core layers, no restrictions should be imposed on the question of inlining ({{fhir|Attachment.data}}) versus referring ({{fhir|Attachment.url}}) the actual binary data.
 +
** For use case specific profiles, it should be carefully considered which of these options should be supported to prevent unexpected transfers of large amounts of data.
 +
* If the resource type supports an element of {{datatype|Attachment}} natively that matches the intent of the functional model, it should be used, unless additional metadata needs to be provided which cannot be accommodated by the resource type.
 +
* If the resource type does not support an element of {{datatype|Attachment}} natively or if there's a need to provide additional metadata, a profile on DocumentReference resource should be defined. The Media resource should not be used as it has been deprecated in FHIR R5.
 +
** If there's no obvious way to refer between this DocumentReference and the focal resource of the data model, {{fhir|DocumentReference.context.related}} can be used.
 +
* The use of the Binary resource is dependent on the use case. Normally, it should not be needed to explicitly specify the use of this resource.

Huidige versie van 3 okt 2024 om 10:24


Inhoud

1 Introduction

This page lays out the conventions for creating FHIR profiles and associated conformance resources within Nictiz. These guidelines are specifically aimed at FHIR R4; for the STU3 profiling work, a separate document exists.

This page is titled "profiling guidelines", but actually addresses all conformance resources (profiles, extensions, value sets, code systems, CapabilityStatements) and associated examples. We use these terms somewhat interchangeable throughout this document; 'profile' can usually be read as 'the whole set of conformance resources'.

1.1 Language

Unless stated otherwise, the FHIR conformance materials will be created in English in order to encourage adoption and re-use.

2 Open vs. closed world modeling

When profiling, an "open world" or a "closed world" model can be chosen. The former means that the profile only allows the elements to be used specified by the functional model, with all the restrictions from the functional model. The latter means that the profile can accommodate the elements specified by the functional model, but doesn't impose further restrictions.

We adopt the "open world" modeling approach to aid re-usability beyond the known use cases. When restrictions are deemed necessary for a specific use case, it will be added to the information standard specific profiles.

× 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 by 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 straightforward
  • 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 straightforward 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 currently not in scope.

2.1 General guidelines for open world modeling

We only profile elements, cardinalities and bindings that require profiling. We leave other elements, cardinalities and bindings as-is.

2.2 Cardinality

The functional description will specify the cardinality for each concept as a minimum required and maximum allowed number of times it may occur, which is the same mechanism as in FHIR. However, one needs to be careful as the cardinality can only be restricted in derived profiles, and never widened. Being too strict could thus hinder the re-use of these profiles. This is especially true for cardinalities in zibs, which should be interpreted as 'purely conceptual'; a use case might allow for data that conceptually always should be there to be absent in practice.

For zib profiles:

    • A minimum of 0 or 1 will be profiled as 0.
    • A maximum (1, n, *) will be profiled as-is.

For nl-core profiles:

  • No further restrictions are added, as these profiles only cover the currently known use cases. Adding restrictions here would hinder as yet unknown of undefined use cases.

For information standard specific profiles:

  • If the corresponding zib has a minimum of 1 and the use case doesn't contradict this, the minimum will be profiled here as 1.
  • Cardinalities may be further restricted if the use case defines this.

2.3 mustSupport

The basic notion for any element or extension in a profile, most specifically when it has a mapping to a functional definition, is: provide what you have, and support what you can. At the generic profiling levels - zib and nl-core - we can not know what the exact context of use will be. We can therefore never be sure that a formal FHIR mustSupport flag by any definition would hold in every imaginable use case.

For zib and nl-core profiles:

  • Do not use mustSupport. Implementers should understand the presence of a mapping as a hint that a semantic understanding exists and should interpret this as a generic encouragement to support this element.

For information standard specific profiles:

  • Both constrain cardinality and apply mustSupport as applicable for the information standard. Implementers have generally pushed back on too many profiles for the same building blocks so we generally do not go into that level of profiling.

The way to know the exact requirements for the use case at hand is thus not immediately clear from just looking at the generic profiles, but from reading the transaction that should be part of any information standard. A transaction is the dataset constrained with cardinalities and conformance applied, comparable to what FHIR calls a logical model.

2.4 Constraining references

Concepts in a functional description oftentimes refer to each other; e.g. most clinical concepts will refer to the concept of a Patient. In FHIR these connections are realized using the reference datatype, which allow to specify the target (base resource of profile) as well. For example, a profile representing the zib Problem could set the target of the .subject element to the profile representing the zib Patient.

However, setting the target explicitly means a restriction of the allowed targets, which runs counter to the principles of open world modeling. On the other hand, specifying a dedicated profile provides useful guidance on how to handle this profile. To address both concerns, the target profile will be added next to the base resource. For example, the Condition resource allows Patient and Group as target in the .subject element. When profiling the zib Problem, the profile representing the zib Patient will be added as a third option.

3 Functional model as base

Most, if not all, conformance resources are based on an underlying functional model. The functional model is the specification to which the conformance resources should adhere.

The basis for most other functional models is formed by the 'zibs' ('Zorginformatiebouwstenen'), in English also known as are Clinical Information Models (CIMs), Health and Care Information Models (HCIMs) or Clinical Building Blocks (CBB) – we will use the Dutch term 'zib' for all profiling work as it has become a recognizable term over the past years. The zibs are defined by the program ‘Registratie aan de bron’ (Data capture at the point of care) and provide a foundation of use case neutral building blocks from which use cases can be built. The formal definition of the zibs can be found on the zibs wiki.

Use cases or information standards use and refine those zibs that are relevant to the situation. The formal specification for these information standards can usually be found in Nictiz' instance of ART-DECOR.

3.1 Layering: zibs, nl-core profiles and information standard specific profiles

The profiles and other conformance resources align to this layering of information standards. We recognize three levels of profiles:

zib profiles
profiles that represent the zibs as faithfully as possible
nl-core profiles
profiles derived from the zib profiles that that might be enriched by concepts from the different use cases that need the zib. See #The nl-core layer for more information.
information standard specific profiles
optional derived profiles from the nl-core profiles that further restrict or enhance these profiles for a specific use case.

3.2 The nl-core layer

The goal of the nl-core layer is to ensure that similar concepts defined at the use case level are implemented in a uniform way at the FHIR level. Whether the concept is used by a single or multiple use cases is irrelevant – adopting it at the intermediate nl-core level provides clear guidance to future use.

On the other hand, concepts defined at the intermediate level are only of value if they can be reused across situations. Therefore, it should be investigated how the concept can be created in a reusable way before it is implemented at the nl-core level. If there is a vanishingly small opportunity for reuse, then it is best to define it at the use case level to avoid clutter at the nl-core level. In practice, this means:

  • Extensions from use cases should usually be generalized and added to the nl-core layer.
  • Adding reference types to specific profiles (see #Constraining references) should usually be done at the nl-core layer.
  • Cardinalities are usually determined by the zibs and further restricted by the use cases, so it makes little sense to implement them at the nl-core layer. These should normally be implemented at the use case layer. Also see #Cardinality.
  • Mappings to the functional specifications for use cases (see #Associating the functional definition to StructureDefinitions) are by definition use case specific and should be added at the use case layer.
  • Bindings to ValueSets (see #ValueSet binding) are usually use case specific, but might be added at the nl-core layer.
  • SearchParameters should usually be generalized and added to the nl-core layer.

3.3 Associating the functional definition to StructureDefinitions

Any StructureDefinition that profiles a Resource does so because there is some kind of logical definition dictating how. 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.

3.3.1 Current implementation

We use the StructureDefinition.mapping and ElementDefinition.mapping elements in profiles to map functional concepts to resource elements. The following rules apply:

  • The mapping .mapping.uri SHALL resolve to a description of the functional model:
    • For zibs, this SHOULD be the English page on zibs.nl.
    • For functional models in ART-DECOR, this SHOULD be the link to the dataset on ART-DECOR v3 in the format of [host]/ad/#/[prefix]/datasets/dataset/[dataset id]/[dataset effectiveDate]
  • The .mapping.identity should be a constructed in the following way:
    • For zibs, this SHOULD be the zib-[English zib name, lowercased]-v[version]-[publication]EN
    • For functional models in ART-DECOR, this SHOULD be, all in lowercase, [project prefix][dataset name]-[dataset effectiveDate as 'yyyymmdd']. The dataset name SHOULD be the English name if available, otherwise it SHOULD be the Dutch name. All spaces are replaced by dashes. If the project prefix and dataset name are similar, it's better to not repeat it and simply use 'dataset'.
  • The .mapping.name should be constructed in the following way:
    • For zibs, this SHOULD be zib [English zib name]-v[version]([publication]EN)
    • For functional models in ART-DECOR, this SHOULD be ART-DECOR Dataset [dataset name] [dataset effectiveDate]. The dataset name SHOULD be the English name if available, otherwise it SHOULD be the Dutch name. If the dataset name contains the word 'dataset', it SHOULD not be repeated.
  • Functional concepts are referenced based on their id in the functional model, which should be used to populate .mapping.map.
  • The description of the functional concept is normally placed in .mapping.comment, unless other rules apply (see #References that are reversed in FHIR).
  • When slicing, the mapping is made on the content of the slice, not the slice itself (see also #Placing-Info).

So on the root of the StructureDefinition, the mapping for a zib should be defined as:

<mapping>
    <identity value="zib-medicationagreement-v1.2-2020EN" />
    <uri value="https://zibs.nl/wiki/MedicationAgreement-v1.2(2020EN)" />
    <name value="zib MedicationAgreement-v1.2(2020EN)" />
</mapping>

A specific element can then be mapped using:

<element id="MedicationRequest.extension:usageDuration">
    <path value="MedicationRequest.extension" />
    <mapping>
        <identity value="zib-medicationagreement-v1.2-2020EN" />
        <map value="NL-CM:9.6.19936" />
        <comment value="PeriodOfUse" />
    </mapping>
</element>

Note that implicitly mapped elements and reversed references use a slightly different comment.

3.4 Handling errors, proposed changes and omissions in the functional model

Conformance resources which are based on a functional model SHOULD faithfully represent the functional model. This implies that errors in the functional model cannot be fixed in the FHIR implementation unless it's really trivial; doing so would lead to a difference between the FHIR implementation and the functional model, resulting in unclear and hard to use specifications.

Practically, this results in the following guidelines:

  • If the error is fixed on the functional level, it is adopted in the conformance resources.
  • If an error is trivial AND recognized as something that will be fixed on the functional level, it can be adopted (e.g. spelling mistakes).
  • In any other case, the error will be implemented as-is in the conformance resources. This includes the following cases:
    • The error is not recognized as something that needs to be fixed.
    • The error is recognized as something that needs to be fixed, but the fix has to wait until the next version.

    The error is documented using a hyperlink to the ticket in the suitable element, usually the .comment field of the relevant profile element.

    Note: if the error prevents the creation of the conformance resources, then the functional model is deemed unimplementable and no conformance resources are created.

Omissions in the functional model are handled like any other error, with one important exception: if extra information is needed in order to create an implementation (like a code for a functional concept), and this information will be added to a future version of the functional model, it makes sense to already adopt it for the current implementation. This addition is documented with a reference to the relevant ticket.

3.4.1 For zibs specifically

For zibs specifically, these guidelines are practically fulfilled in the following way.

  • For any error found in the functional model, a BITS ticket is created in the ZIB project.
    • If the ticket results in an erratum, the fix is adopted without notice.
    • If the error is not recognized, or won't be fixed until the next (pre-)release:
      • If the conformance resources can be made, the error is documented with a hyperlink to the BITS ticket in the suitable element, usually the .comment field of the relevant profile element.
      • If the conformance resources cannot be made, this is documented in the release notes using a hyperlink to the BITS ticket.
      • (Only) if the error pertains something trivial like a spelling mistake AND will be fixed in a future release, it is adopted without any notice.
  • For missing definition codes, a BITS ticket is created in the ZIB project.
    • If the tickets results in a definition code, it is implemented in the conformance resource. The .comment field of the element containing the code will document the code using the following remark: The code to identify this concept ([code]) aligns with the next version of the zib, since the current version doesn't provide a code. See [BITS ticket] for more information.
      • [code] should be either SNOMED xxx when using the code system name, or xxx in code system yyy when using the URI.
      • [BITS ticket] should be a Markdown formatted hyperlink to the relevant ticket with the ticket key as title text.

4 Versioning

In general terms, FHIR conformance resources could be affected at several different layers:

  1. The version of the package that the conformance resources reside in: versioned according to SemVer 2.0.
  2. The version of the conformance resource themselves (StructureDefinition.version): used to indicate the business version to the user, without strict specifications.
  3. The FHIR version (StructureDefinition.fhirVersion): this document is specifically aimed at FHIR R4, meaning this element will be fixed on 4.x.
  4. The version of the underlying data model.

Regarding point 1 and 2: Nictiz uses the package level as the main versioning mechanism. As a result, the conformance resources within the package are not individually versioned; they should be regarded as a consistent set. To identify the package version a conformance resource, its version number will be set to the package version.

Regarding point 4: the life cycle of the underlying data model is not reflected directly in the version number of the conformance resources, but a change in de the underlying data could result in a change in one or more of the conformance resources. In this case, the normal SemVer rules will determine what happens; if some of the conformance resources need to be changed in a backwards compatible way, a new patch release of the package should be made, if major functionality is added, a new minor version of the package should be released, etc. When a new version of the underlying data model reflects a fundamental change, the choice can be made to create a new package under a different name rather than a new version (eg. each zib releases will have their own package).

Version updates of conformance resources normally do not affect their canonical URI. Any resource that references another resource normally does so without a version indicator (uri|version). Instead, this is handled at the package level; reference targets either reside within the same package or in a versioned package that has been added as a dependency.

5 Mapping semantic codes to profiles

Oftentimes a functional concept has an equivalent FHIR element, e.g. a 'comment' in the functional description maps in FHIR to the Resource.comment element. When this is not the case, a code (usually SNOMED or LOINC) is needed to add the proper definition to the FHIR resource, usually using the Resource.code or Resource.category element. For example, the root concept of an Observation is unknown unless it is defined by the .code element, and when components are used in an Observation, each Observation.component needs to be defined using an individual .code element. These codes should be provided by the functional description (for zibs this is the DefinitionCode).

These codes are profiled as required elements using a ElementDefinition.pattern as described in #Values that should be present verbatim. If the maximum cardinality of the element is 1, this pattern is defined on the element itself; if the maximum cardinality is larger than 1, a separate slice is used instead (see this section for the naming convention of such slices).

6 Slicing

Elements are sliced for three reasons:

  1. To specify different requirements for repetitions of an element.
  2. To add the mapping to the functional specification to a specific instance of the element (even if all requirements are the same as the default slice).
  3. To allow other uses of a base element than what is required by the functional specification, e.g. the reuse of an .identifier next to the profiled .identifier.

Slicing can often occur on different levels within an element, e.g. when the element is of type CodeableConcept, a slice can be made on the element itself or on the child element of type Coding (.element.coding). In general, slicing will occur on the highest level possible, thus on the element itself in the example above. Note that this is only possible for repeating elements (max cardinality > 1). When an element of type CodeableConcept does not repeat, the Coding element can be sliced, but this is discouraged as this is often not what is meant; when .coding repeats within a single element of type CodeableConcept, it must have the same semantic meaning although some granularity difference is accepted (e.g. when communicating the same concept in different code systems).

In general, the slice discriminator is set to discriminator.type = value and discriminator.path to the path where the discriminator value is located (if it is the root element, it should be noted as $this). The sliced element gets a pattern or a required ValueSet binding on the location of the path. No further cardinality constraints are added in the sliced element that correspond with the pattern[x] as they are made mandatory by the pattern. These general slicing guidelines apply to the following situations (see this page for examples in XML):

  • Mapping semantic codes to profiles requires the presence of the semantic code while leaving the option to use the element for other concepts, e.g the zib LaboratoryTestResult profile uses Observation.category for a semantic code that represents the zib and to map the zib concept ResultType. Even if there are no other concepts present in the zib that would be mapped on the same element as the semantic code, the latter code is defined on a separate slice to allow for derivation of the profile. E.g. the zib Stoma profile uses the stomaCode slice on Condition.category for a semantic code that represents the zib, and no other slices are present.
  • Identifier systems are always defined on a sliced .identifier, even if there is only one defined.

Other forms of slicing that are common (Forge sets these slicing details by default):

  • A concept is mapped to one or multiple types of a polymorphic element, e.g. Observation.value[x]. The mapping and functional description are placed on the slice with the matching data type(s).
  • Adding an extension slices the .extension element that is discriminated by the value on extension.url.

6.1 Slice names

The slice name should describe the concept it represents. It should align with the name from the functional description where possible, but a more suitable name may be chosen if deemed more applicable:

  • For slices representing a semantic code (i.e. for zibs this is the DefinitionCode) the slice name will be equal to the name of the (root) concept (starting in lower case) suffixed with Code. For instance the semantic code representing the zib NursingIntervention is put on the nursingInterventionCode slice on CarePlan.category, while the slice on Condition.category representing the LegalStatus concept of the zib LegalSituation is called legalStatusCode.
  • E.g. the zib concept PatientIdentificationNumber defines a patient id for Dutch patients in the form of a bsn, hence the slice name bsn for a slice on Patient.identifier is more informative than the zib concept name.
  • For CodeSpecification extension slices, a custom rule applies.
  • When slicing by .targetProfile, a workaround may be needed resulting in extra additions to the slice names.

Slices follow the convention of FHIR elements in general, using a camelCased name starting with a lowercase letter. If the slice name represents or starts with an abbreviation, the entire abbreviation should be lowercased (e.g. bsn instead of BSN).

6.2 Slicing by .targetProfile

A common pattern is to slice elements of datatype Reference by the .targetProfile that the reference acts on, using discriminator.type = profile and discriminator.path = resolve() (this is predominantly done to define the mapping to the functional model). There is a limitation in different FHIR tool stacks that prevent the correct handling of multiple .targetProfiles on the same slice. As a workaround, slices with multiple .targetProfiles should be split up. If this happens and the slice names would be the same according to the normal naming rules, the slice names will be appended with an appropriate suffix like the .id (thus the leaf part of the canonical URL) of the target profile.

7 Restricting the range of allowed values

7.1 ValueSet binding

7.1.1 General approach

As a general guideline, the ValueSet defined by the functional model should get a binding on the FHIR element representing the functional concept. This means:

7.1.2 Binding strength

The FHIR profiles should faithfully reproduce the binding strength from the functional description. It may not always be possible to adopt the binding strength verbatim. For example, when creating slices for ValueSets, the binding strength must be set to required in order to make the discriminator work, even though the binding strength in the functional description is extensible. However, by making the slicing open, conceptually the same result is achieved.

Also see the examples.

7.1.3 Binding multiple ValueSets

The functional model might require multiple ValueSets to be used for some data element, e.g. when offering the choice between multiple code systems. However, FHIR allows to bind just one ValueSet to an element. There are two strategies to handle this situation:

  1. Create and bind a combined ValueSet that encompasses all the ValueSets defined in the functional model.
  2. Create slices for each ValueSet binding.

The use of combined ValueSets is the preferred approach. Although the use of slices would make the different concepts visible in the profiles, this strategy doesn’t allow for overlapping ValueSets (which often doesn’t make much sense semantically but happens for example when the different ValueSets include the same NullFlavor codes). It is also less straightforward for derived profiles to expand or restrict the base ValueSet when using slices. Using the first approach, a new ValueSet can be created and bound (if the binding strength permits it and it makes sense semantically).

However, option 2 should be used if there are different requirements for the ValueSet bindings.

Also see the examples.

7.1.4 Handling conflicts with base bindings

FHIR base resource might specify a required binding for some of its elements, whereas the corresponding concept in the functional specification uses alternative or more specialized codes. To conform both to FHIR and to the functional description, a ConceptMap will be created to map the codes from the functional specification to the codes from the FHIR ValueSet. This ConceptMap will be linked to the existing ValueSet using the extension permitted-value-conceptmap extension.

If all mappings in the ConceptMap are equal or equivalent, no further action is needed.

7.1.4.1 Datatype code

When not all codes from the functional specification map cleanly to a required ValueSet from a FHIR base resource with datatype code:

  • The ValueSet from the functional description will be bound with the binding strength of the functional concept using the CodeSpecification extension. The extension slice is named after the full English name of the value set according to the functional description, in camelCased notation.
  • Mapping to the concepts of the functional description is applied both to the FHIR element and the extension.
  • The ConceptMap will be added using the extension permitted-value-conceptmap extension on the FHIR ValueSet.

7.1.4.2 Datatype CodeableConcept

When not all codes from the functional specification map cleanly to a required ValueSet from a FHIR base resource with datatype CodeableConcept:

  • CodeableConcept.coding will be sliced with a discriminator of value/$this, based on a required binding on the CodeableConcept.coding level.
  • A slice will be created that binds the ValueSet of the functional description:
    • The slice is named after the full English name of the value set according to the functional description, in camelCased notation.
    • The binding strength is set to required. This is needed in order to make a valid slice definition.
    • The minimum cardinality of the slice is set to 1; if the concept is included, both the FHIR and function model codes are required.
    • The ConceptMap is documented using the permitted-value-conceptmap extension on the ValueSet bound in this slice.
    • binding.description is set to: In addition to a coding from this ValueSet, the corresponding coding from the FHIR base ValueSet SHALL be communicated. The ConceptMap <[canonical of ConceptMap]> can be used to relate these two ValueSets.
  • Mapping to the concepts of the functional description is applied only to the FHIR element, not to the slice.

7.2 Values that should be present verbatim

On occasion the profile needs to ensure that an element in the resource being profiled has an exactly defined value. Common use cases for this:

  • A particular code must be present at the element (mostly to map a semantic code to a profile).
  • Only codes from a particular code system are allowed, so its .system can only have one value.
  • Only Quantity units in UCUM are allowed, so Quantity.system must be set to http://unitsofmeasure.org.
  • A boolean, string or other primitive type must have a particular value.

FHIR offers two competing ways to do this: fixed values (ElementDefinition.fixed) and patterns (ElementDefinition.pattern) (there are also less obvious ways to achieve this, like constraints or ValueSet bindings, which could be used when the solution calls for it). Fixed values have the advantage that they are more readable and are better at communicating to the implementer what the expectations are. However, it is a rather rigid mechanism as it states that the element must be exactly that value and nothing else. Oftentimes, the profiled value is a minimum expectation and other additional values are still allowed – for example, the datatype CodeableConcept allows for more than one .coding, as long as they are semantically compatible.

Therefore, in FHIR R4, the guidance is to use fixed values for primitive types and patterns for complex types. However, from FHIR R5 onward, the guidance is to always use patterns over fixed values, as even on primitive datatypes a fixed value would prevent the use of extensions or element ids.

Therefore, when there is a need for fixing values in the profile, the following guidance applies:

  • Use a pattern on the element representing the datatype (thus not on one of the elements within the datatype).
  • For coded elements where a fixed .system is required, including elements of datatype CodeableConcept/Coding and Quantity or one of its derived datatypes:
    • If the functional model specifies the fixed value as a value set (e.g. "all codes from SNOMED"), use a #ValueSet binding.
    • Otherwise, use a pattern with .system set to the required value.
  • Fixing values should only be done for data that needs to be present verbatim in the resource being profiled. Concepts like Coding.display and Quantity.unit should never be fixed, as these are descriptions which might change depending on the context.

8 Extensions

Sometimes a concept from the functional model cannot be implemented using the building blocks FHIR offers by default. In this case, an extension might be used to implement such concept. Keep in mind that extensions are often seen as a burden for implementers:

  1. If it possible to model the concept (cleanly) without an extension, this is usually the preferred way.
  2. If that's not possible, check if HL7 provides an extension to implements the concept.
  3. If that's not possible, try to create an extension in a reusable way (or reuse a previously defined extension).
  4. If that's not possible, create an extension specific for the profile.

Usually the mappings to the functional model, bindings to specific ValueSets and any functional descriptions will be added when the extension is used within a profile. When the extension pertains to a particular profile, this information SHALL be added to the StructureDefinition of the ValueSet.

8.1 Extensions containing a reference to a zib profile

Extensions on the zib level that contain a reference to a zib profile, have that zib profile placed as type.targetProfile on value[x] (valueReference). Since it is problematic to make derived extensions, no nl-core counterpart of the extension is created, but the extension is made generic for both the zib and nl-core layer (see also #Profiles, extensions and datatypes). The nl-core profile that uses this extension should treat the zib profile reference in the extension like any other zib profile references and restrict the targetProfile to the nl-core counterpart.

9 Common patterns

Sometimes different profiles use a common pattern, for example when references to a particular zib requires special guidance. Special care should be taken to ensure that this pattern is implemented in a consistent way. There are several approaches for this:

  • When all these profiles share a common base, a base profile can be defined that includes this pattern.
  • When the pattern is part of an extension, then it is applied in a common way by definition.
  • A datatype profile may be created that can be re-used across resource profiles (using type.profile). This datatype profile may include special guidance aimed at profilers. An example of this approach is described in #Referencing zib HealthProfessional.

10 Mandatory FHIR elements

10.1 Without a functional counterpart

On occasion, FHIR requires an element to be populated while the functional model doesn't specify it. For example, the Procedure resource has the required element Procedure.status, but the zib Procedure, which is mapped to this FHIR resource, doesn't specify such a field.

In these circumstances, an effort should be made to map the zib concepts implicitly to these elements. For example, FHIR Procedure.status can be inferred from the zib concept ProcedureEndDate; if it is in the past, then the status should be assumed to be completed. If it is not possible to make such an implicit mapping, the FHIR element is left as-is; the implementation guide should describe how the implementer should deal with it, probably using the data-absent-reason extension.

Implicit mappings are documented in the following way:

  • The comment of the implicitly mapped element should provide guidance on how to map the functional concept.
  • The mapping element is populated with the mapped concept, but the description is altered to: [concept name] (implicit, main mapping is on [element name]).
  • Other metadata (.definition, .short, .alias) isn't populated according to the normal guidelines.

10.2 With a functional counterpart with a minimal cardinality of 0

On occasion, a functional concept with a minimal (conceptual) cardinality of 0 is mapped to a mandatory FHIR element. An effort should be made to provide guidance on how to populate the element if no meaningful value can be derived from the zib. For example, the concept TextResultStatus of zib TextResult is mapped to DiagnosticReport.status, where value unknown can be used if the value of zib concept TextResultStatus is not present.

If no guidance can be provided in the profile, it is up to sending systems to populate the element with a meaningful value from the context of their data and the implementation guide should describe how the implementer should deal with this situation.

11 References that are reversed in FHIR

Functional building blocks often refer each other, but on occasion, the logical direction for the reference in FHIR is in the other direction. For example, zib TextResult defines a reference to zib Procedure, but the association between FHIR resources DiagnosticReport (for zib TextResult) and Procedure (for zib Procedure) is defined on Procedure.report.

In these situations, the FHIR approach is followed rather than some custom extension or other mechanism. Although this approach cannot enforce the cardinality from the functional model, the use of the default implementation requires the least effort from implementers and gives the best results for interoperability.

These reversed mappings are profiled in the following way:

  • In the profile that contains the reference:
    • If the element that represents the association between the two resources is a repeating element, it is sliced with a discriminator of profile/resolve() and a slice is added with the target(s) set to the target profile(s). Otherwise, the target profile is just added to the list of targets.
    • The .mapping element is populated with the mapped concept, but the description is altered to: Reversed reference for [functional building block name].[concept name]"
    • The .short and slice name, if used, use the English name of the target rather than the concept name.
    • An .alias containing the Dutch name of the target is added.
    • The .comment contains an (additional) note in the following form: Please note that on a functional level, [functional building block A] references [functional building block B], but in FHIR this direction is reversed."
    • .definition can be populated with the (modified) definition from the functional building block, but only if it provides useful information to the implementer.
    • The cardinality of the element is unaffected.
  • In the target profile (where the reference would normally be made if the functional definition is followed):
    • The .comment on the root contains an (additional) note in the following form: Please note that on a functional level, [functional building block A] references [functional building block B], but in FHIR this direction is reversed. Therefore, the concept [concept name ]([concept identifier]) is mapped on [path to reference] in profile [profile B] instead of in this profile.

Example from profile zib-Procedure-event:

    <element id="Procedure.report">
      <path value="Procedure.report" />
      <slicing>
        <discriminator>
          <type value="profile" />
          <path value="resolve()" />
        </discriminator>
        <rules value="open" />
      </slicing>
    </element>
    <element id="Procedure.report:textResult">
      <path value="Procedure.report" />
      <sliceName value="textResult" />
      <short value="TextResult" />
      <comment value="Please note that on a functional level, zib TextResult references zib Procedure, but in FHIR this direction is reversed." />
      <alias value="TekstUitslag" />
      <type>
        <code value="Reference" />
        <targetProfile value="http://nictiz.nl/fhir/StructureDefinition/zib-TextResult" />
      </type>
      <mapping>
        <identity value="zib-textresult-v4.4-2020EN" />
        <map value="NL-CM:13.2.5" />
        <comment value="Reversed reference for zib TextResult.Procedure" />
      </mapping>
    </element>

And in zib-TextResult:

    <element id="DiagnosticReport">
      <path value="DiagnosticReport" />
      ...
      <comment value="Please note that on a functional level, zib TextResult references zib Procedure, but in FHIR this direction is reversed. Therefore the concept Procedure (NL-CM:13.2.5) is mapped on `Procedure.report:textResult` in profile zib-Procedure-event instead of in this profile." />
      ...

12 Practical guidelines

12.1 Identity of artifacts

12.1.1 Canonical URL, id, name and title

Conformance resources can have multiple types of identifying information, which are related at some level:

.url
The canonical URL, which is the external identifier for conformance resources. All conformance resources SHALL have a canonical URL. This URL is preferably resolvable but does not have to be processable. Canonical URL's are about the identity of artifacts, not necessarily about retrieval location. Canonical URLs aren't meant to be human recognizable.
.id
This should align with the latter part of the canonical URL.
.name
A recognizable name that is still computer processable.
.title
A recognizable title purely for human consumption.

URIs for the latter (for artifacts living in ART-DECOR) are described in ART-DECOR FHIR_URIs.

12.1.1.1 Profiles, extensions and datatypes

  • The .id will be constructed in the following way:
    • For profiles, the .id consists of a prefix, the name of the building block, optionally followed by a specification of the concept within the building block, optionally followed by a suffix:
      [prefix]-[building block name]{.[concept name]}{-[suffix]}
      • Where [prefix] is:
        • for the zib layer: zib.
        • for the nl-core layer: nl-core.
        • for standard specific layers: [project prefix].
      • Where [building block name] is:
        • when representing a zib (irrespective of the layer): the English zib name, PascalCased in the same way as the zib name.
        • when representing another functional building block: the English building block name, PascalCased.
        • when representing multiple building blocks: the overarching concept name. The overarching concept name is plural and camelCased, to indicate that the profile applies to multiple building blocks and to avoid any possible confusion with actual building blocks, respectively. An example is 'wounds' as the overarching concept of the zibs Burnwound, PressureUlcer and Wound.
      • Where the optional [concept name] is used when the profile is not the focal resource for a functional building block, but rather a direct representation of a part of it. In this case, the English concept name is used, capitalized according to the functional description. Underscores are ignored. For example, while zib LaboratoryTestResult is profiled onto the Observation resource, the 'Specimen' container is profiled on the Specimen resource, resulting in a name of 'zib-LaboratoryTestResult.Specimen'.
      • Where the optional [suffix] is used in the following situations:
        • If the functional building block is spread out over multiple resources, the resource type is appended, PascalCased. For example, zib HealthProfessional is represented using both a Practitioner and a PractitionerRole resource, resulting in 'zib-HealthProfessional-Practitioner' and 'zib-HealthProfessional-PractitionerRole'. This suffix may be absent from the focal resource, if there's one (e.g. 'zib-HealthcareProvider').
        • If there are multiple implementations of the same building block for different uses, a use specific suffix is appended. A common pattern for this is when zibs are used both for registered and planned events, resulting in an event and request resource from the FHIR workflow perspective (e.g. zib Procedure which is mapped to both a Procedure and ServiceRequest resource). The following suffixes may be used:
          • past use: event
          • future use: request
    • For extensions:
      • directly representing a specific concept in a single profile:ext-[English root concept name].[English concept name]. Underscores are ignored.
      • pertaining to multiple profiles, or not pertaining to specific profiles and generally applicable:
        • if the use context is a single resource:ext-[resource]-[purpose]
        • otherwise:ext-[purpose]
    • For datatype profiles:
      • representing a functional building block: this is regarded a normal profile as described above
      • representing a pattern: pattern-[purpose]
  • The canonical URL will then be created as: http://nictiz.nl/fhir/StructureDefinition/[id]
  • The name will be the .id capitalized, with hyphens and periods (.) removed.
  • The title will generally be the .id with hyphens replaced by spaces.

Where:

  • [project prefix] is preferably the same as its matching ART-DECOR project prefix
  • [purpose] and [English concept name] are generally a PascalCased name joining words together, with the first letter of every word capitalized.

12.1.1.2 ValueSets

  • For value sets as specified on ART-DECOR, the id will be:[value set OID]--[effective date as yyyymmddhhmmss]
  • The canonical URL will then be created as: http://decor.nictiz.nl/fhir/ValueSet/[id]
  • Both the name and title will be the name of the value set (usually in Dutch).

12.1.1.3 CodeSystems

  • For code systems as specified on ART-DECOR, the id will be:
    • If a canonical URL is available, then the latter part of the canonical URL.
    • Otherwise the code system OID.
  • The canonical URL will then be created as:
    • When a URI is explicitly stated, then this is used.
    • If the code system can be resolved with a URI in the OID register, then this is used.
    • Otherwise: urn:oid:[code system OID]
  • Both the name and title will be name of the code system (usually in Dutch). If the code system can be resolved in the OID register it will get that name as registered.

12.1.1.4 NamingSystems

NamingSystems are rarely needed. No strict guidance is given, but in general, the following conventions apply:

  • The id will be namingsystem-[identifier], where identifier is usually the latter part of the canonical URI this NamingSystem defines. However, a more informative identifier may be chosen if deemed more appropriate.
  • The name will be [identifier] capitalized and with dashes and such removed, unless a better scheme is deemed more appropriate.
  • NamingSystems don't have a title or canonical URI.

12.1.1.5 ConceptMaps

  • The id will be constructed as: [source ValueSet.name]-to-[target ValueSet.name]
  • The canonical URL will then be: http://nictiz.nl/fhir/ConceptMap/[id]
  • The name will be constructed as: [source ValueSet.name]_to_[target ValueSet.name]
  • The title will be constructed as: [source ValueSet.name] to [target ValueSet.name]

12.1.1.6 SearchParameters

SearchParameters are generally added from the nl-core layer onwards because the zib layer is without an use case definition.

  • The code should consist of one or multiple words in lowercase ASCII characters, with multiple words separated using a dash ("-"):
    • If the search parameter doesn't pertain to a specific functional model or use case, the FHIR element that the search parameter acts on should be used.
    • If the search parameter does pertain to a specific functional model or use case, the English name of the functional concept should be used.
    • If these guidelines aren't feasible, another descriptive name may be used at the profilers discretion.
  • The id will be: [target]-[code], where [target] is PascalCased and should be:
    • The resource name if the search parameter applies to a single resource type.
    • A descriptive name for the target if the search parameter applies to more than one resource type, e.g. "Medication" if the search parameter applies to medication related resources.
  • The canonical URL will then be: http://nictiz.nl/fhir/SearchParameter/[id]
  • The name will be: [target]_[code] with dashes and such removed in [target] and [code], unless a better scheme is deemed more appropriate.
  • The description will describe the working of the search parameter.
  • The purpose will be populated to indicate why the SearchParameter is created.
  • The search parameter is expressed using .expression.

12.1.1.7 Examples and fixtures

Examples and fixtures (example instances used for test/qualification purposes) are not conformance resources and lack the .url, .name and .title elements. However, to ensure consistency, the .id is standardized in the following way:

  • For fixtures: [profile id]-[3 character project prefix]-[unique string], capped to 64 characters. The [project prefix] is necessary to prevent the same id from being used by different projects in the same test environment. It is preferably the same as its matching ART-DECOR project prefix.
  • For examples: [profile id]-{[3 character project prefix]-}[unique string], capped to 64 characters (the [3 character project prefix] is not needed for examples, but may be included to facilitate re-use of tools for both fixtures and examples).

12.1.2 Folder structure and file name

Most FHIR publishing tools adopt the convention to prefix the file name with the resource type. However, there's no rule or tool dependency to do so. These guidelines only partially adopt this convention. In most cases, the file names are based on the .id, which has a defined meaning in these guidelines, and it is often deemed more clear to omit the resource type.

profiles and extensions
StructureDefinitions/[id].xml
ValueSets
vocabulary/ValueSet-[Dutch name]-[id].xml
other terminology resources (ConceptMaps, CodeSystems, NamingSystems)
vocabulary/[resource type]-[id].xml
other definitional resources (SearchParameters, CapabilityStatements, etc.)
[plural of resource type]/[resource type]-[id].xml
example resources
examples/[profile id]-[serial number, two digits].xml

Sub folders may be used if necessary.

12.2 Metadata

12.2.1 StructureDefinitions

12.2.1.1 Metadata on the StructureDefinition root

  • version: see #Versioning
  • status: as applicable (normally draft or active)
  • publisher: Nictiz
  • contact:
    • name: Nictiz
    • telecom:
      • system: url
      • value: https://www.nictiz.nl
      • use: work
  • description:
    • For profiles:
      • For zib profiles: the 'Concept' section from the zib.
      • For nl-core profiles: copy the description from the zib profile.
      • For profiles representing a specific concept of a data model: the definition text of the concept. If the definition is not suitable as a description (e.g. a zib container), an applicable description should be created.
      • For standard specific profiles: as applicable.
    • For extensions:
      • A description of what the extension is for. If the extension represents a single concept, it could be of the form An extension to provide [(adapted) concept definition].
  • purpose:
    • For profiles:
      • For zib profiles: This [resource type] resource represents the Dutch [zib ('Zorginformatiebouwsteen', i.e. Health and Care Information Model) [English zib name] [version]([release])]([link to the English zib page on zibs.nl]).
        Note 1: This template includes a markdown link: [text](url). A complete example would be: This Patient resource represents the Dutch [zib ('Zorginformatiebouwsteen', i.e. Health and Care Information Model) Patient v3.2 (2020)](https://zibs.nl/wiki/Patient-v3.2(2020EN)).
        Note 2: If the profile represents (a concept of) multiple zibs, they are listed in the form of (Markdown formatting omitted): ... the Dutch zib ('Zorginformatiebouwsteen', i.e. Health and Care Information Model) [zib info], the Dutch zib [zib info] and the Dutch zib [zib info].
      • For profiles directly representing a particular concept of a zib: This [resource type] resource represents the [concept name] concept ([zib concept id]) of the Dutch [zib ('Zorginformatiebouwsteen', i.e. Health and Care Information Model) [English zib name] [version] ([release])]([link to the English zib page on zibs.nl]).
      • For nl-core profiles: A derived profile from [[id of zib profile]]([canonical of zib profile]) to provide a version better suited for implementation purposes. This profile augments the base profile with elements found in the various use cases that have adopted the zib.
      • For standard specific profiles: a description with a reference to the base profile, with an explanation of why it has been added.
    • For extensions:
      • For extension representing a specific concept: This extension represents the [concept name] concept of [name of the building block], followed by a link to the functional description. If the extension represents a zib concept this becomes: This extension represents the [concept name] concept of the Dutch [zib ('Zorginformatiebouwsteen', i.e. Health and Care Information Model) [English zib name] [version] ([release])]([link to the English zib page on zibs.nl]).
      • For other extensions this will usually be absent.
    • Note: for extensions and datatype profiles, guidance for profilers may be placed here as well.
  • copyright: Copyright and related rights waived via CC0, https://creativecommons.org/publicdomain/zero/1.0/. This does not apply to information from third parties, for example a medical terminology system. The implementer alone is responsible for identifying and obtaining any necessary licenses or authorizations to utilize third party IP in connection with the specification or otherwise.
  • mapping: see #Associating_the_functional_definition_to_StructureDefinitions
  • abstract: usually false, but may be set to true when this profile is to be used only as a base profile from which other profiles should be derived.
  • comment: when special guidance on the use of this profile is needed, it will be placed here. For example: when this profile has a (non-trivial) relationship to other profiles, when a concept of the functional description is mapped over multiple elements, etc.
    Note: this should be guidance aimed at implementers. When the guidance is aimed at profilers, for example in extensions or datatype profiles, it should be added to StructureDefinition.purpose.
  • alias:
    • for zib profiles: the zib concept name as dictated by #Associating the functional definition to StructureDefinitions.
    • for nl-core profiles: the id of the profile (this is actually just a placeholder for when there is no actual difference with the base profile, as FHIR requires StructureDefinition.differential or StructureDefinition.snapshot to be populated).

12.2.1.2 Metadata for elements

  • For elements that map directly (not implicitly) to zib concepts:
    • The English name from the zib concept is placed on element.short (in elements that refer to other zibs, the name is built up like ElementName::ReferenceZibName, but we only use the part before the double colons). If there are multiple zib elements mapped to a single FHIR element, it will be formatted like ZibConcept1 / ZibConcept2 (unless the names are the same).
    • The zib concept description is placed on element.definition, unless it's the root concept of the zib (because this will always be Root concept of the [...] information model ..., which doesn't provide much information). If there are multiple zib elements mapped to a single FHIR element, the descriptions will be placed in a bullet list.
    • The Dutch zib concept names are placed on element.alias
  • For elements that bind ValueSets:
    • If there is a ConceptMap, .binding.description will be: Use ConceptMap [ConceptMap.name] to translate terminology from the functional model to profile terminology in ValueSet [ValueSet.name]
    • Otherwise, .binding.description is not populated.
  • For elements that are (directly or indirectly) included in a custom constraint defined elsewhere:
    • The keys of all related constraints are added to .condition (note: this is thus not necessary when the constraint is defined on the element itself). Because .condition is added to notify the implementer that a constraint applies to the usage of this element, this rule applies to both the element directly mentioned in the constraint as well as its child element(s) that contain the mapping to the functional model.

12.2.2 ConceptMaps

12.2.2.1 Metadata on the ConceptMap root

  • status: as applicable (normally draft or active)
  • publisher: Nictiz
  • contact:
    • name: Nictiz
    • telecom:
      • system: url
      • value: https://www.nictiz.nl
      • use: work
  • description: Maps [functional ValueSet] codes as found in [linked description to the functional model] to [FHIR ValueSet] codes as found in FHIR R4.

    For zibs, the linked description will be the Dutch [zib ('Zorginformatiebouwsteen', i.e. Health and Care Information Model) [English zib name] [version]([release])]([link to the English zib page on zibs.nl]).

  • copyright: Copyright and related rights waived via CC0, https://creativecommons.org/publicdomain/zero/1.0/. This does not apply to information from third parties, for example a medical terminology system. The implementer alone is responsible for identifying and obtaining any necessary licenses or authorizations to utilize third party IP in connection with the specification or otherwise.
  • In addition, the [bidirectional extension (http://hl7.org/fhir/StructureDefinition/concept-bidirectional)](http://hl7.org/fhir/StructureDefinition/concept-bidirectional) is added with a value to indicate whether this ConceptMap can be used in both ways.

12.3 Narratives

The FHIR spec states that resources SHOULD have a narrative, in order to support human-consumption as a fallback. This works out in the following way:

  • For example instances: a narrative is added that at least covers all the profiled elements, with Narrative.status = generated or extensions.
  • For definitional resources (profiles, extensions, ConceptMaps, SearchParameters, etc.), a narrative is added with Narrative.status = empty, and the following content for Narrative.div: No narrative is provided for definitional resources. A human-readable rendering can be found in the implementation guide(s) where this resource is used.

The reason for using an empty narrative in definitional resources is that it is not trivial and at the same time redundant to satisfy the requirement that the narrative must reflect all content needed for a human to understand the essential clinical and business information for the resource. It is redundant because a useful representation is already published as part of the implementation guide(s) where this resource is used; it is not trivial because all content is relevant in these kind of resources, and representing this in a useful way would amount to replicating the view from the implementation guide(s) in the narrative.

12.4 Miscellaneous

  • As a rule of thumb, info is placed 'as close as possible' to the elements that actually represent the data. For example: when slicing, the texts are placed on the slice content, not the slice itself. Similarly, in concept containers like Observation.component, this info is placed on the .valueXXX elements. This is also true for the zib mappings.
  • Slices get a lowerCamelCased name based on the functional concept name.
  • New elements defined through extensions get a lowerCamelCased name based on the functional concept name.
  • The key for invariants should be:
    • for zibs: zib-[English zib name]-[number], eg. zib-Alert-1.
    • for nl-core: nl-core-[English zib name]-[number].
    • for use case specific profiles: [dataset id]-[number], where [dataset id] is preferably the same as its matching ART-DECOR project prefix.
  • Inline examples in profiles are added (only) when the usage of an element in the profile is not trivial.

13 Special cases

13.1 Special use of FHIR resources

13.1.1 Using Observation.hasMember vs Observation.component

The Observation resource has two competing mechanisms for defining observations consisting of multiple distinct parts: using Observation.component, all parts are inlined into a single Observation resources, while Observation.hasMember allows one to group the parts modeled as distinct Observation resources. According to the FHIR spec, the latter approach should be used unless the part cannot be interpreted on its own (i.e. if there could be a use case to query the part separately, it should be a distinct Observation, otherwise it should be a .component). This sometimes is a somewhat arbitrary choice, but the following guidelines can help:

  • If the definition code indicates that the part is an "Observable entity" (child of SNOMED/363787002) or an "Evaluation procedure" (child of SNOMED/386053000), it is a good indication that the part should be a distinct Observation. These are the SNOMED domain bindings of Observation.code.
  • Scale or score models are modeled as a single Observation with .components. Although it could be argued that the various elements that are part of the total score are at least based on separate Observations, the scores themselves are an integral part of a set of scores and should not be interpreted outside of this context.

To profile a model as a set of grouped Observations:

  • A focal profile should be created representing the "group" or "panel" concept, with an appropriate definition code on Observation.code.
  • For each part, a distinct profile is created (following the normal naming conventions).
    • Concepts from the main model that are relevant to the partial Observations will be mapped to the partial profiles as well. There is no general rule for determining which concepts are relevant, a careful analysis needs to be performed on all concepts. Typically, concepts like the date/time and the method of the measurement are relevant to the partial Observations as well.
    • The normal mapping rules apply, so if a single concept is being profiled, the mapping will be on the Observation.valueDataType element and not on the root of that profile.
  • In the focal profile, Observation.hasMember is sliced by profile, and a slice is added for each concept profile.
  • The relationship between the profiles is documented in the following way:
    • As described in #Metadata on the StructureDefinition root, a comment is placed on the StructureDefinition root in both the focal profile and in the profiles representing the parts to describe the relationship between the profiles.
      • For the profiles representing the parts, this will usually be: This Observation resource represents the [English concept name] concept ([concept id]) of [English model name]. It can be used together with the [[focal profile id]]([focal profile canonical]) profile on the Observation resource, which groups references to the current and other resources on `Observation.hasMember`.
      • If there's just one part, for the focal profile this comment will usually be: The [English concept name] concept ([concept id]) is represented using distinct Observation resources, using profile [[profile id]]([profile canonical]). It is referenced from this resource using `Observation.hasMember`..
      • If there are multiple parts, for the focal profile this comment will usually be: Several concepts of [English model name] are represented using distinct Observation resources. These are grouped using the current resource and are referenced on `Observation.hasMember`:, followed by a bullet list of all profiled concepts in het form of: * [English concept name] ([concept id]): [[profile id]]([profile canonical]).
    • On each Observation.hasMember slice in the focal profile, the following definition text is set: The [English concept name] concept ([concept id]) of [English model name], represented as a distinct Observation resource.

13.1.2 Measurement qualifiers in Observation.component

Functional models for measurements will usually be mapped onto the FHIR Observation resource. The type of measurement is conveyed using Observation.code and the result of the measurement is conveyed using Observation.value[x], or Observation.component.value[x] if the measurement consists of multiple components.

However, sometimes the functional model requires that the type of measurement needs to be further specified using a qualifier. For this purpose, the Observation.method and Observation.bodySite elements can be used. If it is not possible to map these concepts to these elements or to a core extension of Observation, they may be mapped to Observation.component, according to a remark in the specification ("or may provide qualifying information to Observation.code") and a discussion on Zulip, which concludes that the use of Observation.component for qualifiers is appropriate and preferred above (custom) extensions.

13.1.3 HL7 Vital Signs

The FHIR R4 specification for the Observation resource defines a profile for vital signs measurements. Furthermore, it states that:

If implementations use this Resource when expressing the profile-specific concepts as structured data, they SHALL conform to the following profiles

This means that the following zib profiles would need to be based on the HL7 Vital Signs profile:

  • BloodPressure
  • BodyHeight
  • BodyWeight
  • BodyTemperature
  • HeadCircumference
  • HeartRate
  • O2Saturation

The FHIR spec defines derived profiles for each of these vital signs, plus an IG with further recommendations.

However, the HL7 Vital Signs profile imposes two issues that make it impossible to implement zib profiles for the relevant vital signs measurements directly onto it:

  • The required terminology binding on Observation.component to the Vital Signs Units dataset makes it impossible to use .component's for representing anything else than a Quantity (like a CodeableConcept or a boolean), which is required by some of these zibs.
  • The mustSupport = true flag found on numerous elements isn't further specified in the HL7 Vital Signs IG, as is required by FHIR.

To circumvent this problem, it has been chosen not to directly base the zib profiles onto the HL7 Vital Signs profiles, but instead create profiles that aim to be (as) functional equivalent (as possible). This means that constraints, terminology bindings, etc. are adopted (except for the terminology binding mentioned above) and that the zib profiles are not in conflict with the equivalent HL7 profiles, except for the requirement that Observation.hasMember and Observation.derivedFrom should have a HL7 Vital Signs target – this requirement cannot be satisfied when cloning a profile. Where possible, the current profiling guidelines are followed rather than the approach by HL7 (e.g. where the HL7 profiles use slices with a fixed code and system to enforce the inclusion of a coding, the zib profiles use a pattern).

On occasion, the zib takes another approach to communicate a certain concept than HL7 Vital Signs. For example, zib BodyHeight specifies a ValueSet for the body position during measurement (lying or standing), while the HL7 Vital Signs suggests to include an additional Observation.code.coding for "body height measurement while lying down" (only). When the zib approach is not incompatible with the HL7 approach, the zib approach will be followed and the difference will be documented in the .comment of the relevant element.

To enforce a consistent approach for creating the vital signs zib profiles, a pattern profile has been created. Please note that this should not be interpreted as an equivalent to the base HL7 Vital Signs profile; the zib profiles deliberately skip the common base profile and are directly matched directly to their equivalent HL7 profiles like BloodPressure, BodyHeight, etc. This base profile is not needed for the current use case and omitting it prevents a layer of complexity; for example, the HL7 Vital Signs base profile binds certain ValueSets which are then restricted again in the derived profiles.

13.1.4 Person characteristics: extension or Observation?

Some type of information can be described as a characteristic or property of a person, like life stance, marital status, language proficiency, nationality, etc. There is a tendency in FHIR to inline this kind of data in the Patient resource, either using a core element or a core extension (and to a lesser degree to the RelatedPerson and Practitioner resources).

However, this choice seems somewhat arbitrary. Oftentimes this kind of information could equally well be regarded as an Observation. For example: whereas the name can be seen as something that is truly part of the patient, and a heart rate truly as a measurement made at some point in time, one could argue that both religion and body height fall somewhere in between – both of them usually apply to longer periods of time, neither of them require additional data apart from the main characteristic, and both of them can have an independent existence. So when modeling these kind of characteristics, the question is whether an Observation should be used or an extension.

Given that:

  • In international IGs, there doesn't seem to be a strong preference for one of the two approaches;
  • FHIR core should be used where possible; and
  • custom extensions are discouraged,

the following guidance applies:

  1. If possible, use a core element to model the characteristic.
  2. If this is not possible, use a core extension to model the characteristic.
  3. If this is not possible, create a profile on Observation.

13.2 Zib 2020 specific considerations

13.2.1 Implicit subject reference

Starting from release 2020, zibs oftentimes do not explicitly define their subject, i.e. who or what the information is about. However, the general guideline for zibs is that they capture healthcare information about a patient. So implicitly there is a subject, and this subject is usually a patient – although in some cases it might be inferred that the subject is something or someone else, or can be more than just a patient.

The following guidelines apply for profiling a zib without an explicit subject:

  • In the zib profiles, the subject will not be modeled explicitly.
  • In the nl-core profiles, the subject will be modeled as a reference to the relevant nl-core profile.

The reason for this is that even though the subject is assumed, when it is not explicitly defined, no formal mapping can be made to a profile. On the other hand, it can be assumed that the subject will be modeled explicitly once the zib is used in a use case scenario,

13.2.2 Referencing zib HealthProfessional

Zib HealthProfessional is mapped onto two profiles: one on FHIR resource PractitionerRole (zib-HealthProfessional-PractitionerRole) and one on FHIR resource Practitioner (zib-HealthProfessional-Practitioner). The PractitionerRole resource covers the recording of the location and types of services that HealthProfessionals are able to provide for a HealthcareProvider, whereas the Practitioner resource captures the personal information, including the identifiers of the health professional.

In FHIR, it is usually possible to define a reference to either resource. However, the reference to this zib from other zibs will be modelled in the following way:

  • Only zib-HealthProfessional-PractitionerRole is added to the list of target resources.
  • As described in #Constraining references, no restrictions on the base Practitioner or PractitionerRole are made.

This approach has been adopted for two reasons. First, the relation between these two resources points from PractitionerRole to Practitioner; having a PractitionerRole instance, the Practitioner instance can be resolved, but not the other way around. Second, information about a health professional will rarely be communicated without the details captured using PractitionerRole.

This mechanism guides implementers to the use of the zib-HealthProfessional-PractitionerRole profile as the main entry point for zib HealthProfessional. Meanwhile, when there is a need to communicate the zib-HealthProfessional-Practitioner profile instead, this is still possible as the base resource Practitioner is still available.

To ensure consistent documentation of this mechanism, the profile http://nictiz.nl/fhir/StructureDefinition/pattern-ZibHealthProfessionalReference has been created. The .title of this profile is simply 'Reference' instead of 'zib HealthProfessional Reference', as is expected following the profiling guidelines. This deviation from the guidelines is the result of the .title being used to render the profile in various tooling (mainly Simplifier), and the latter title would result in a rendering that is deemed confusing in some cases (see MM-3854).

14 Data type mapping

In most cases, the mapping between ART-DECOR, zib and FHIR datatypes is straightforward, though there are a number of cases which are not as clear-cut. The table below shows how datatypes from the functional models should be mapped to FHIR.

ART-DECOR zib FHIR Remarks
count INT Count or integer Count in FHIR is derived from Quantity. This is appropriate for observations, such as a count of red blood cells in a specimen. Count in FHIR is a Quantity with system set to http://unitsofmeasure.org and code set to 1 (for units). If this is not appropriate, use integer.
boolean BL boolean
blob ED base64Binary or Attachment
code CD CodeableConcept or coding or code In general, CodeableConcept will be the right choice. See Using Codes in Resources for details.
complex ANY BackboneElement complex is data which is not further defined in DECOR, and thus cannot be translated.
currency - Money Does not have a zib counterpart currently. Theoretically this could be MO.
date - date Does not have a zib counterpart currently. Closest counterpart could be TS.
datetime TS dateTime
decimal - decimal Does not have a zib counterpart currently. Theoretically this could be REAL.
duration - Duration Does not have a zib counterpart currently. Closest counterpart could be PQ.
identifier II Identifier
ordinal CO CodeableConcept or coding or code See Using Codes in Resources for details.
string ST string or markdown
ratio - Ratio Does not have a zib counterpart currently. Closest counterpart could be RTO.
text - string Does not have a zib counterpart currently.
quantity PQ Quantity

14.1 Notes on binary data (ED or blob)

Binary data requires special considerations when profiling. One aspect of binary data is that it tends to represent large multimedia files. Healthcare systems might want to have explicit control over the exchange of such files, rather than being confronted with unexpected large data transfers when performing a search or read operation. In addition, these files could have a need for additional metadata next to the structured content present in the clinical data model.

In FHIR R4, the exchange of binary data is mediated using a combination of resources and data types:

  • Data type Attachment; this data type provides the means to transfer the actual bytes and annotate it with the proper content type, so that the receiver knows how it is interpreted. This data type offers two ways of transporting the binary content:
    • inline (Attachment.data).
    • as reference to an external URL (Attachment.url).
  • Resource type DocumentReference; this resource type provides a way to specify metadata about a multimedia file specified using the Attachment data type.
  • Resource type Media; this resource type is similar and has been deprecated in FHIR R5 in favor of DocumentReference.
  • Resource type Binary; this resource type is only meant to wrap binary data in a FHIR resource. It could be the target of Attachment.url if there's a strict need to keep all exchanges within the FHIR RESTful framework.

It should be noted that the Observation resource does not offer Attachment as a valid data type for .value[x] (or .component.value[x]), although FHIR R5 does support this.

This translates to the following guidelines:

  • Binary data should be mapped onto data type Attachment.
    • For the generic zib and nl-core layers, no restrictions should be imposed on the question of inlining (Attachment.data) versus referring (Attachment.url) the actual binary data.
    • For use case specific profiles, it should be carefully considered which of these options should be supported to prevent unexpected transfers of large amounts of data.
  • If the resource type supports an element of Attachment natively that matches the intent of the functional model, it should be used, unless additional metadata needs to be provided which cannot be accommodated by the resource type.
  • If the resource type does not support an element of Attachment natively or if there's a need to provide additional metadata, a profile on DocumentReference resource should be defined. The Media resource should not be used as it has been deprecated in FHIR R5.
    • If there's no obvious way to refer between this DocumentReference and the focal resource of the data model, DocumentReference.context.related can be used.
  • The use of the Binary resource is dependent on the use case. Normally, it should not be needed to explicitly specify the use of this resource.