Stream: tooling
Topic: Differences in validation in Forge vs ClinFHIR
Diego Bosca (Dec 04 2019 at 12:28):
I'm curious about the differences in profile validation criteria in Forge vs ClinFHIR. I can generate profiles that give no errors in Forge but return lots of errors in clinFHIR
Most of errors are multiple occurrences of these errors, repeating for each element in the profile. E.g.
StructureDefinition.differential.element[0]
Constraints must be unique by key () constraint.select(key).isDistinct()
Types must be unique by code () type.select(code).isDistinct()
Must have a modifier reason if isModifier = true () isModifier implies isModifierReason.exists()
Last one is puzzling because there is no modifier defined.
This is the profile I'm testing things with (it is autogenerated, the idea is to improve the generation process to make it valid for every tool)
<?xml version="1.0" encoding="UTF-8"?> <StructureDefinition xmlns="http://hl7.org/fhir"> <id value="observation-Observation1"/> <extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm"> <valueInteger value="0"/> </extension> <url value="http://linkehr.com/fhir/observation-observation1"/> <version value="0"/> <name value="Observation1"/> <status value="draft"/> <date value="2019-11-12"/> <publisher value="openEHR"/> <contact> <telecom> <system value="url"/> <value value="http://www.veratech.es"/> </telecom> </contact> <description value="was empty"/> <fhirVersion value="4.0.0"/> <mapping> <identity value="openEHR"/> <uri value="http://openehr.org"/> <name value="openEHR Mapping"/> </mapping> <mapping> <identity value="openEHR-natural"/> <uri value="http://openehr.org"/> <name value="openEHR natural path"/> </mapping> <kind value="complex-type"/> <abstract value="false"/> <type value="Observation"/> <baseDefinition value="http://hl7.org/fhir/StructureDefinition/Observation"/> <derivation value="constraint"/> <differential> <element id="Observation"> <path value="Observation"/> <short value="OBSERVATION1"/> <definition value=""/> <min value="0"/> </element> <element id="Observation.component"> <path value="Observation.component"/> <slicing> <discriminator> <type value="value"/> <path value="code.coding.code"/> </discriminator> <discriminator> <type value="value"/> <path value="code.coding.system"/> </discriminator> <ordered value="false"/> <rules value="open"/> </slicing> </element> <element id="Observation.component:Element1_1"> <path value="Observation.component"/> <sliceName value="Element1_1"/> <short value="ELEMENT1.1"/> <min value="0"/> </element> <element id="Observation.component:Element1_1.value[x]"> <path value="Observation.component.value[x]"/> <type> <code value="CodeableConcept"/> </type> <mapping> <identity value="openEHR"/> <map value="/content[at0001]/items[at0004]/data[at0012]/events[at0014]/data[at0005]/items[at0006]"/> </mapping> <mapping> <identity value="openEHR-natural"/> <map value="/content[SECTION1]/items[OBSERVATION1]/data[at0012]/events[INTERVAL_EVENT]/data[ITEM_TREE]/items[ELEMENT1.1]"/> </mapping> </element> <element id="Observation.component:Element1_2"> <path value="Observation.component"/> <sliceName value="Element1_2"/> <short value="ELEMENT1.2"/> <min value="0"/> </element> <element id="Observation.component:Element1_2.value[x]"> <path value="Observation.component.value[x]"/> <type> <code value="Quantity"/> </type> </element> <element id="Observation.component:Element1_2.value[x].value"> <path value="Observation.component.value[x].value"/> <min value="1"/> <max value="1"/> <type> <code value="string"/> </type> </element> <element id="Observation.component:Element1_2.value[x].system"> <path value="Observation.component.value[x].system"/> <min value="1"/> <max value="1"/> <type> <code value="uri"/> </type> <fixedUri value="http://unitsofmeasure.org"/> </element> <element id="Observation.component:Element1_2.value[x].code"> <path value="Observation.component.value[x].code"/> <min value="1"/> <max value="1"/> <type> <code value="code"/> </type> </element> </differential> </StructureDefinition>
Lloyd McKenzie (Dec 04 2019 at 13:08):
@David Hay
David Hay (Dec 04 2019 at 17:27):
Well, clinFHIR itself doesn't do any validation - it just calls the $validate operation on the servers you select, so that's where to look for differences. Which servers are the ones that generate errors? BTW - intending to remove the requirement to have to declare the profile in the instance when I get a chance - a work in progress ATM...
Diego Bosca (Dec 05 2019 at 09:24):
I just pasted the profile and pressed the validation button :)
David Hay (Dec 05 2019 at 14:15):
Ah. Assuming you're using the CF validator (https://fhirblog.com/2019/11/12/validating-a-resource/) then it's intended to validate conformance of a resource instance to a profile - not the profile itself.
The idea is that you save the profile on a server (like hapi or grahames server) - along with any dependant artifacts like extension definitions or terminology, then create an instance that is supposed to be conformant to that profile and paste that into the validator and select the server.
Right now, you need to indicate the profile in the resource meta element - working on that
All the app does is to call the $validate operation on the indicatedserver/s and show the results...
Last updated: Apr 12 2022 at 19:14 UTC