From 0b753713b032c7763c3ca39c09f248ef600929ec Mon Sep 17 00:00:00 2001 From: MariekeMassa Date: Mon, 27 Apr 2026 16:15:56 +0200 Subject: [PATCH 01/23] Add specialty valueset --- input/fsh/ValueSet.fsh | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/input/fsh/ValueSet.fsh b/input/fsh/ValueSet.fsh index 3faba5d..5a7ccea 100644 --- a/input/fsh/ValueSet.fsh +++ b/input/fsh/ValueSet.fsh @@ -217,4 +217,14 @@ Description: "ValueSet representing 'Yes, No, Unknown' answers." * $snomed#373067005 ^designation[=].value = "ontkenning" * $snomed#373067005 ^designation[+].language = #nl-NL * $snomed#373067005 ^designation[=].use = $snomed#900000000000013009 "Synonym" -* $snomed#373067005 ^designation[=].value = "neen" \ No newline at end of file +* $snomed#373067005 ^designation[=].value = "neen" + + +ValueSet: ACPHealthProfessionalSpecialtyVS +Id: ACP-HealthProfessionalSpecialty +Title: "ACP Health Professional Specialty" +Description: "ValueSet for specialty of the health professional, to be used in the questionnaire. This ValueSet allows codes from both the UZI role coding and the AGB specialty list. The ValueSet is derived from the zib Healthcare Professional (zib2020) Specialty, representing the specialty of the healthcare professional using UZI and AGB codes." +* insert MetaRules +* compose.include[0].system = "http://fhir.nl/fhir/NamingSystem/uzi-rolcode" +* compose.include[1].system = "urn:oid:2.16.840.1.113883.2.4.6.7" + From 286a8efd9905712d5ae7b085fad25a1452a0017b Mon Sep 17 00:00:00 2001 From: MariekeMassa Date: Mon, 27 Apr 2026 16:32:58 +0200 Subject: [PATCH 02/23] Use specialty valueset in questionnaire and change type to codeableconcept in responses --- .../resources/Questionnaire-ACP-zib2020.json | 45 +------------------ ...naireResponse-HendrikHartman-20201001.json | 12 +++-- ...naireResponse-HendrikHartman-20221108.json | 12 +++-- ...eResponse-SamiraVanDerSluijs-20251117.json | 12 +++-- 4 files changed, 25 insertions(+), 56 deletions(-) diff --git a/input/resources/Questionnaire-ACP-zib2020.json b/input/resources/Questionnaire-ACP-zib2020.json index 17be0c7..3c7dd96 100644 --- a/input/resources/Questionnaire-ACP-zib2020.json +++ b/input/resources/Questionnaire-ACP-zib2020.json @@ -96,50 +96,7 @@ "type": "choice", "required": false, "repeats": false, - "answerOption": [ - { - "valueCoding": { - "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", - "code": "01.000", - "display": "Arts" - } - }, - { - "valueCoding": { - "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", - "code": "01.015", - "display": "Huisarts" - } - }, - { - "valueCoding": { - "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", - "code": "01.047", - "display": "Specialist ouderengeneeskunde" - } - }, - { - "valueCoding": { - "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", - "code": "30.000", - "display": "Verpleegkundige" - } - }, - { - "valueCoding": { - "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", - "code": "81.000", - "display": "Physician assistant" - } - }, - { - "valueCoding": { - "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", - "code": "99.000", - "display": "Zorgverlener andere zorg" - } - } - ] + "answerValueSet": "https://api.iknl.nl/docs/pzp/r4/ValueSet/ACP-HealthProfessionalSpecialty" } ] }, diff --git a/input/resources/QuestionnaireResponse-HendrikHartman-20201001.json b/input/resources/QuestionnaireResponse-HendrikHartman-20201001.json index 43e5192..0dd2820 100644 --- a/input/resources/QuestionnaireResponse-HendrikHartman-20201001.json +++ b/input/resources/QuestionnaireResponse-HendrikHartman-20201001.json @@ -99,10 +99,14 @@ { "answer": [ { - "valueCoding": { - "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", - "code": "01.015", - "display": "Huisarts" + "valueCodeableConcept": { + "coding": [ + { + "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", + "code": "01.015", + "display": "Huisarts" + } + ] } } ], diff --git a/input/resources/QuestionnaireResponse-HendrikHartman-20221108.json b/input/resources/QuestionnaireResponse-HendrikHartman-20221108.json index b9269ab..ed29426 100644 --- a/input/resources/QuestionnaireResponse-HendrikHartman-20221108.json +++ b/input/resources/QuestionnaireResponse-HendrikHartman-20221108.json @@ -99,10 +99,14 @@ { "answer": [ { - "valueCoding": { - "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", - "code": "01.015", - "display": "Huisarts" + "valueCodeableConcept": { + "coding": [ + { + "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", + "code": "01.015", + "display": "Huisarts" + } + ] } } ], diff --git a/input/resources/QuestionnaireResponse-SamiraVanDerSluijs-20251117.json b/input/resources/QuestionnaireResponse-SamiraVanDerSluijs-20251117.json index 00a34f5..e6417a0 100644 --- a/input/resources/QuestionnaireResponse-SamiraVanDerSluijs-20251117.json +++ b/input/resources/QuestionnaireResponse-SamiraVanDerSluijs-20251117.json @@ -106,10 +106,14 @@ { "answer": [ { - "valueCoding": { - "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", - "code": "01.015", - "display": "Huisarts" + "valueCodeableConcept": { + "coding": [ + { + "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", + "code": "01.015", + "display": "Huisarts" + } + ] } } ], From 83fe2be60fbe30ab6fb2b3557e874086e618ae42 Mon Sep 17 00:00:00 2001 From: MariekeMassa Date: Mon, 27 Apr 2026 17:58:35 +0200 Subject: [PATCH 03/23] Replace 'compose.include' by 'include codes from' Previous approach gave error which could not be fixed (Assignment rules must include at least one space both before and after the '=' sign voor: * compose.include[0].system = "http://fhir.nl/fhir/NamingSystem/uzi-rolcode") --- input/fsh/ValueSet.fsh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/input/fsh/ValueSet.fsh b/input/fsh/ValueSet.fsh index 5a7ccea..5ad3f8d 100644 --- a/input/fsh/ValueSet.fsh +++ b/input/fsh/ValueSet.fsh @@ -225,6 +225,7 @@ Id: ACP-HealthProfessionalSpecialty Title: "ACP Health Professional Specialty" Description: "ValueSet for specialty of the health professional, to be used in the questionnaire. This ValueSet allows codes from both the UZI role coding and the AGB specialty list. The ValueSet is derived from the zib Healthcare Professional (zib2020) Specialty, representing the specialty of the healthcare professional using UZI and AGB codes." * insert MetaRules -* compose.include[0].system = "http://fhir.nl/fhir/NamingSystem/uzi-rolcode" -* compose.include[1].system = "urn:oid:2.16.840.1.113883.2.4.6.7" +* include codes from system http://fhir.nl/fhir/NamingSystem/uzi-rolcode +* include codes from system urn:oid:2.16.840.1.113883.2.4.6.7 + From 9b6b39eaf9cc7920d1ccbf6353daaff813c1a6f9 Mon Sep 17 00:00:00 2001 From: MariekeMassa Date: Tue, 28 Apr 2026 16:39:25 +0200 Subject: [PATCH 04/23] Change codeableconcept to coding again CodeableConcept resulted in 'null!' --- ...tionnaireResponse-HendrikHartman-20201001.json | 15 ++++++--------- ...tionnaireResponse-HendrikHartman-20221108.json | 15 ++++++--------- ...naireResponse-SamiraVanDerSluijs-20251117.json | 15 ++++++--------- 3 files changed, 18 insertions(+), 27 deletions(-) diff --git a/input/resources/QuestionnaireResponse-HendrikHartman-20201001.json b/input/resources/QuestionnaireResponse-HendrikHartman-20201001.json index 0dd2820..76eb0fd 100644 --- a/input/resources/QuestionnaireResponse-HendrikHartman-20201001.json +++ b/input/resources/QuestionnaireResponse-HendrikHartman-20201001.json @@ -99,15 +99,12 @@ { "answer": [ { - "valueCodeableConcept": { - "coding": [ - { - "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", - "code": "01.015", - "display": "Huisarts" - } - ] - } + + "valueCoding": { + "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", + "code": "01.015", + "display": "Huisarts" + } } ], "linkId": "1405", diff --git a/input/resources/QuestionnaireResponse-HendrikHartman-20221108.json b/input/resources/QuestionnaireResponse-HendrikHartman-20221108.json index ed29426..92a2167 100644 --- a/input/resources/QuestionnaireResponse-HendrikHartman-20221108.json +++ b/input/resources/QuestionnaireResponse-HendrikHartman-20221108.json @@ -99,15 +99,12 @@ { "answer": [ { - "valueCodeableConcept": { - "coding": [ - { - "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", - "code": "01.015", - "display": "Huisarts" - } - ] - } + + "valueCoding": { + "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", + "code": "01.015", + "display": "Huisarts" + } } ], "linkId": "1405", diff --git a/input/resources/QuestionnaireResponse-SamiraVanDerSluijs-20251117.json b/input/resources/QuestionnaireResponse-SamiraVanDerSluijs-20251117.json index e6417a0..3118b6e 100644 --- a/input/resources/QuestionnaireResponse-SamiraVanDerSluijs-20251117.json +++ b/input/resources/QuestionnaireResponse-SamiraVanDerSluijs-20251117.json @@ -106,15 +106,12 @@ { "answer": [ { - "valueCodeableConcept": { - "coding": [ - { - "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", - "code": "01.015", - "display": "Huisarts" - } - ] - } + + "valueCoding": { + "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", + "code": "01.015", + "display": "Huisarts" + } } ], "linkId": "1405", From d83112d272fdf7d7f30d47967e5c9a2ba0881de7 Mon Sep 17 00:00:00 2001 From: MariekeMassa Date: Wed, 29 Apr 2026 09:39:25 +0200 Subject: [PATCH 05/23] Add comment in valueset stating that oid is for AGB specialty list --- input/fsh/ValueSet.fsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/input/fsh/ValueSet.fsh b/input/fsh/ValueSet.fsh index 5ad3f8d..e40ba23 100644 --- a/input/fsh/ValueSet.fsh +++ b/input/fsh/ValueSet.fsh @@ -226,6 +226,6 @@ Title: "ACP Health Professional Specialty" Description: "ValueSet for specialty of the health professional, to be used in the questionnaire. This ValueSet allows codes from both the UZI role coding and the AGB specialty list. The ValueSet is derived from the zib Healthcare Professional (zib2020) Specialty, representing the specialty of the healthcare professional using UZI and AGB codes." * insert MetaRules * include codes from system http://fhir.nl/fhir/NamingSystem/uzi-rolcode -* include codes from system urn:oid:2.16.840.1.113883.2.4.6.7 +* include codes from system urn:oid:2.16.840.1.113883.2.4.6.7 //OID for AGB specialty list From 1fa5330032ec53a4e4058b4bcea55e3a6335779b Mon Sep 17 00:00:00 2001 From: Ardon Toonstra Date: Wed, 13 May 2026 10:01:14 +0200 Subject: [PATCH 06/23] Replaced ValueSet with Nictiz ValueSet #131 --- input/fsh/ValueSet.fsh | 10 ---------- input/resources/Questionnaire-ACP-zib2020.json | 2 +- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/input/fsh/ValueSet.fsh b/input/fsh/ValueSet.fsh index e40ba23..3f52afc 100644 --- a/input/fsh/ValueSet.fsh +++ b/input/fsh/ValueSet.fsh @@ -219,13 +219,3 @@ Description: "ValueSet representing 'Yes, No, Unknown' answers." * $snomed#373067005 ^designation[=].use = $snomed#900000000000013009 "Synonym" * $snomed#373067005 ^designation[=].value = "neen" - -ValueSet: ACPHealthProfessionalSpecialtyVS -Id: ACP-HealthProfessionalSpecialty -Title: "ACP Health Professional Specialty" -Description: "ValueSet for specialty of the health professional, to be used in the questionnaire. This ValueSet allows codes from both the UZI role coding and the AGB specialty list. The ValueSet is derived from the zib Healthcare Professional (zib2020) Specialty, representing the specialty of the healthcare professional using UZI and AGB codes." -* insert MetaRules -* include codes from system http://fhir.nl/fhir/NamingSystem/uzi-rolcode -* include codes from system urn:oid:2.16.840.1.113883.2.4.6.7 //OID for AGB specialty list - - diff --git a/input/resources/Questionnaire-ACP-zib2020.json b/input/resources/Questionnaire-ACP-zib2020.json index 3c7dd96..0857243 100644 --- a/input/resources/Questionnaire-ACP-zib2020.json +++ b/input/resources/Questionnaire-ACP-zib2020.json @@ -96,7 +96,7 @@ "type": "choice", "required": false, "repeats": false, - "answerValueSet": "https://api.iknl.nl/docs/pzp/r4/ValueSet/ACP-HealthProfessionalSpecialty" + "answerValueSet": "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.121.11.22--20200901000000" } ] }, From 58c8eeb8d1579de5a870589bb6fe6c6021a45a77 Mon Sep 17 00:00:00 2001 From: Ardon Toonstra Date: Fri, 29 May 2026 14:13:29 +0200 Subject: [PATCH 07/23] #126 updated questionnaire with latest changes --- .../resources/Questionnaire-ACP-zib2020.json | 212 +++++++++++++++--- 1 file changed, 183 insertions(+), 29 deletions(-) diff --git a/input/resources/Questionnaire-ACP-zib2020.json b/input/resources/Questionnaire-ACP-zib2020.json index f5619e1..eb55ca0 100644 --- a/input/resources/Questionnaire-ACP-zib2020.json +++ b/input/resources/Questionnaire-ACP-zib2020.json @@ -2,15 +2,15 @@ "resourceType": "Questionnaire", "id": "ACP-zib2020", "url": "https://api.iknl.nl/docs/pzp/r4/Questionnaire/ACP-zib2020", - "version": "1.0.0-rc2", + "version": "1.0.0-rc3", "name": "ACPzib2020", - "title": "Uniform vastleggen proactieve zorgpanning (PZP) o.b.v. zibs2020 - ReleaseCandidate2 03-03-2026", + "title": "Uniform vastleggen proactieve zorgpanning (PZP) o.b.v. zibs2020 - ReleaseCandidate3 02-06-2026", "status": "draft", - "experimental": false, - "publisher": "Published by PZNL & executed by IKNL", - "copyright": "This form is subject to copyright, user rights and a disclaimer, as specified for all IKNL information standards. For details, see the paragraph on Gebruikersrechten en disclaimer at https://iknl.nl/onderzoek/eenheid-van-taal.", - "purpose": "This form was developed to clearly document agreements resulting from the advance care planning (ACP) process.", - "description": "This form was developed to clearly document agreements resulting from the advance care planning (ACP) process. It is NOT a checklist. It can only be completed by a healthcare provider after a professional and nuanced conversation. For advice on conducting these conversations, please refer to the guideline for advance care planning in the palliative phase and Palliaweb, see https://palliaweb.nl/zorgpraktijk/proactieve-zorgplanning. \nEnter 'unknown' if a topic is not discussed or if the patient does not (yet) have an opinion.When transferring to a long-term care setting, consider adding conversation records about advance care planning (ACP) to the transfer documents.", + "experimental": true, + "publisher": "Gepubliceerd door PZNL & uitgevoerd door IKNL | Published by PZNL & executed by IKNL", + "description": "Dit formulier is ontwikkeld om afspraken voortkomend uit het proces van proactieve zorgplanning (PZP) eenduidig vast te leggen. Het is GEEN afvinklijst. Het kan alleen na deskundig en genuanceerd gesprek door een zorgverlener worden ingevuld. Voor adviezen over het voeren van deze gesprekken word verwezen naar de richtlijn proactieve zorgplanning in de palliatieve fase en Palliaweb, zie https://palliaweb.nl/zorgpraktijk/proactieve-zorgplanning. \nVul 'nog onbekend' in als een onderwerp niet is besproken of als de patiënt (nog) geen mening heeft. Overweeg bij overplaatsing naar een langdurige zorgsetting gespreksverslagen over proactieve zorgplanning aan de overdracht toe te voegen. | \nThis form was developed to clearly document agreements resulting from the advance care planning (ACP) process. It is NOT a checklist. It can only be completed by a healthcare provider after a professional and nuanced conversation. For advice on conducting these conversations, please refer to the guideline for proactive care planning in the palliative phase and Palliaweb, see https://palliaweb.nl/zorgpraktijk/proactieve-zorgplanning. \nEnter 'unknown' if a topic is not discussed or if the patient does not (yet) have an opinion.When transferring to a long-term care setting, consider adding conversation records about advance care planning (ACP) to the transfer documents.", + "purpose": "Dit formulier is ontwikkeld om afspraken voortkomend uit het proces van proactieve zorgplanning (PZP) eenduidig vast te leggen. | \nThis form was developed to clearly document agreements resulting from the advance care planning (ACP) process.", + "copyright": "Op dit formulier is copyright, gebruikersrechten en een disclaimer van toepassing, zoals die gespecificeerd zijn voor alle informatiestandaarden van IKNL, zie voor de details het onderdeel Gebruikersrechten en disclaimer op https://iknl.nl/onderzoek/eenheid-van-taal. | \nThis form is subject to copyright, user rights and a disclaimer, as specified for all IKNL information standards. For details, see the paragraph on Gebruikersrechten en disclaimer at https://iknl.nl/onderzoek/eenheid-van-taal.", "item": [ { "linkId": "963", @@ -51,7 +51,7 @@ { "linkId": "967", "text": "Geboortedatum patiënt", - "type": "date", + "type": "dateTime", "required": false, "repeats": false }, @@ -96,23 +96,80 @@ "type": "choice", "required": false, "repeats": false, - "answerValueSet": "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.121.11.22--20200901000000" + "answerOption": [ + { + "valueCoding": { + "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", + "code": "01.000", + "display": "Arts" + } + }, + { + "valueCoding": { + "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", + "code": "01.015", + "display": "Huisarts" + } + }, + { + "valueCoding": { + "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", + "code": "01.047", + "display": "Specialist ouderengeneeskunde" + } + }, + { + "valueCoding": { + "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", + "code": "30.000", + "display": "Verpleegkundige" + } + }, + { + "valueCoding": { + "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", + "code": "81.000", + "display": "Physician assistant" + } + }, + { + "valueCoding": { + "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", + "code": "99.000", + "display": "Zorgverlener andere zorg" + } + } + ] } ] }, { "linkId": "26", - "prefix": "1", + "prefix": "1.", "text": "Wilsbekwaamheid & Wettelijke vertegenwoordiging", "type": "group", "repeats": false, "item": [ { - "linkId": "1406", + "linkId": "1651", "text": "Is de patiënt op dit moment wilsbekwaam m.b.t. medische behandelbeslissingen?", - "type": "boolean", + "type": "choice", "required": false, "repeats": false, + "answerOption": [ + { + "valueCoding": { + "code": "1", + "display": "Ja" + } + }, + { + "valueCoding": { + "code": "0", + "display": "Nee" + } + } + ], "item": [ { "linkId": "1407", @@ -474,9 +531,23 @@ "linkId": "984", "prefix": "d)", "text": "Is de wettelijk vertegenwoordiger ook de eerste contactpersoon?", - "type": "boolean", + "type": "choice", "required": false, - "repeats": false + "repeats": false, + "answerOption": [ + { + "valueCoding": { + "code": "1", + "display": "Ja" + } + }, + { + "valueCoding": { + "code": "0", + "display": "Nee" + } + } + ] }, { "linkId": "53", @@ -487,7 +558,10 @@ { "question": "984", "operator": "=", - "answerBoolean": false + "answerCoding": { + "code": "0", + "display": "Nee" + } } ], "enableBehavior": "any", @@ -525,7 +599,10 @@ { "question": "984", "operator": "=", - "answerBoolean": false + "answerCoding": { + "code": "0", + "display": "Nee" + } } ], "enableBehavior": "any", @@ -668,7 +745,10 @@ { "question": "984", "operator": "=", - "answerBoolean": false + "answerCoding": { + "code": "0", + "display": "Nee" + } } ], "enableBehavior": "any", @@ -695,7 +775,10 @@ { "question": "984", "operator": "=", - "answerBoolean": false + "answerCoding": { + "code": "0", + "display": "Nee" + } } ], "enableBehavior": "any", @@ -971,7 +1054,7 @@ }, { "linkId": "586", - "prefix": "3", + "prefix": "3.", "text": "Belangrijkste overeengekomen doel van medisch beleid", "type": "group", "repeats": false, @@ -1035,7 +1118,7 @@ }, { "linkId": "83", - "prefix": "4", + "prefix": "4.", "text": "Behandelgrenzen", "type": "group", "repeats": false, @@ -1611,10 +1694,31 @@ "valueCoding": { "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", "code": "OTH", - "display": "Other" + "display": "Anders" }, "initialSelected": true } + ], + "item": [ + { + "linkId": "1645", + "text": "Anders, namelijk:", + "type": "string", + "enableWhen": [ + { + "question": "1422", + "operator": "=", + "answerCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", + "code": "OTH", + "display": "Anders" + } + } + ], + "enableBehavior": "any", + "required": false, + "repeats": false + } ] }, { @@ -1867,7 +1971,7 @@ }, { "linkId": "107", - "prefix": "5", + "prefix": "5.", "text": "Behandelwensen", "type": "group", "repeats": false, @@ -1903,6 +2007,24 @@ "type": "string", "required": false, "repeats": false + }, + { + "linkId": "1648", + "text": "Vaststellen wens en verwachting patiënt ([MeetMethode])", + "type": "choice", + "required": false, + "repeats": false, + "readOnly": true, + "answerOption": [ + { + "valueCoding": { + "system": "http://snomed.info/sct", + "code": "370819000", + "display": "Vaststellen van persoonlijke waarden en wensen met betrekking tot zorg" + }, + "initialSelected": true + } + ] } ] }, @@ -1914,7 +2036,7 @@ "repeats": false, "item": [ { - "linkId": "1430", + "linkId": "1649", "text": "Gewenste plek van overlijden ([MetingNaam])", "type": "choice", "required": false, @@ -1925,7 +2047,7 @@ "valueCoding": { "system": "http://snomed.info/sct", "code": "395091006", - "display": "Gewenste plek van overlijden" + "display": "Voorkeur voor plaats van overlijden (waarneembare entiteit)" }, "initialSelected": true } @@ -2120,6 +2242,24 @@ } } ] + }, + { + "linkId": "1650", + "text": "Keuze orgaandonatie vastgelegd in donorregister? ([MeetMethode])", + "type": "choice", + "required": false, + "repeats": false, + "readOnly": true, + "answerOption": [ + { + "valueCoding": { + "system": "http://snomed.info/sct", + "code": "1156040003", + "display": "Self reported (qualifier value)" + }, + "initialSelected": true + } + ] } ] } @@ -2127,7 +2267,7 @@ }, { "linkId": "598", - "prefix": "6", + "prefix": "6.", "text": "Wat verder nog belangrijk is", "type": "group", "repeats": false, @@ -2161,7 +2301,7 @@ }, { "linkId": "115", - "prefix": "7", + "prefix": "7.", "text": "Eerder vastgelegde behandelwensen", "type": "group", "repeats": false, @@ -2253,7 +2393,7 @@ }, { "linkId": "119", - "prefix": "8", + "prefix": "8.", "text": "Informatie delen", "type": "group", "repeats": false, @@ -2262,9 +2402,23 @@ "linkId": "1200", "prefix": "a)", "text": "Heeft u patient geïnformeerd over eigen verantwoordelijkheid om deze behandelafspraken met naasten te bespreken?", - "type": "boolean", + "type": "choice", "required": false, - "repeats": false + "repeats": false, + "answerOption": [ + { + "valueCoding": { + "code": "1", + "display": "Ja" + } + }, + { + "valueCoding": { + "code": "0", + "display": "Nee" + } + } + ] }, { "linkId": "1201", From c38a5f891d492c107cd1471a0002b81b66e275f6 Mon Sep 17 00:00:00 2001 From: Ardon Toonstra Date: Fri, 29 May 2026 14:28:00 +0200 Subject: [PATCH 08/23] Revert change --- .../resources/Questionnaire-ACP-zib2020.json | 45 +------------------ 1 file changed, 1 insertion(+), 44 deletions(-) diff --git a/input/resources/Questionnaire-ACP-zib2020.json b/input/resources/Questionnaire-ACP-zib2020.json index eb55ca0..c803872 100644 --- a/input/resources/Questionnaire-ACP-zib2020.json +++ b/input/resources/Questionnaire-ACP-zib2020.json @@ -96,50 +96,7 @@ "type": "choice", "required": false, "repeats": false, - "answerOption": [ - { - "valueCoding": { - "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", - "code": "01.000", - "display": "Arts" - } - }, - { - "valueCoding": { - "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", - "code": "01.015", - "display": "Huisarts" - } - }, - { - "valueCoding": { - "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", - "code": "01.047", - "display": "Specialist ouderengeneeskunde" - } - }, - { - "valueCoding": { - "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", - "code": "30.000", - "display": "Verpleegkundige" - } - }, - { - "valueCoding": { - "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", - "code": "81.000", - "display": "Physician assistant" - } - }, - { - "valueCoding": { - "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", - "code": "99.000", - "display": "Zorgverlener andere zorg" - } - } - ] + "answerValueSet": "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.121.11.22--20200901000000" } ] }, From f39f3606c588c36ba9589f3c603cca9f73ef3cb9 Mon Sep 17 00:00:00 2001 From: Ardon Toonstra Date: Fri, 29 May 2026 15:52:13 +0200 Subject: [PATCH 09/23] Replace inline answerOption with answerValueSet Remove large inline answerOption arrays from Questionnaire-ACP-zib2020.json and replace them with answerValueSet references to canonical ValueSets. Add util/questionnaire_item_anwserOption_expander.py: a resolver/expander tool that materialises answerValueSet references back into answerOption lists (writes -expanded copies) for tooling (e.g. NLM LHC-Forms) that cannot resolve ValueSet URLs. The script resolves ValueSets from local fsh-generated resources and the FHIR package cache, fills missing displays (preferring nl-NL), supports pre-computed expansions and compose/include logic, and contains a small hardcoded map for unavailable code systems. --- .../resources/Questionnaire-ACP-zib2020.json | 612 +----------------- ...uestionnaire_item_anwserOption_expander.py | 516 +++++++++++++++ 2 files changed, 531 insertions(+), 597 deletions(-) create mode 100644 util/questionnaire_item_anwserOption_expander.py diff --git a/input/resources/Questionnaire-ACP-zib2020.json b/input/resources/Questionnaire-ACP-zib2020.json index c803872..5173576 100644 --- a/input/resources/Questionnaire-ACP-zib2020.json +++ b/input/resources/Questionnaire-ACP-zib2020.json @@ -390,78 +390,7 @@ "type": "choice", "required": false, "repeats": false, - "answerOption": [ - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "DOMPART", - "display": "Partner" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "HUSB", - "display": "Echtgenoot" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "WIFE", - "display": "Echtgenote" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "FTH", - "display": "Vader" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "MTH", - "display": "Moeder" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "SONC", - "display": "Zoon" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "DAUC", - "display": "Dochter" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "BRO", - "display": "Broer" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "SIS", - "display": "Zuster" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", - "code": "OTH", - "display": "Anders" - } - } - ], + "answerValueSet": "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.40.2.3.1.1--20200901000000", "item": [ { "linkId": "408", @@ -584,36 +513,7 @@ "type": "choice", "required": false, "repeats": false, - "answerOption": [ - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.22.1", - "code": "LL", - "display": "Land Line" - } - }, - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.22.1", - "code": "FAX", - "display": "Fax" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", - "code": "MC", - "display": "Mobiel telefoonnummer" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", - "code": "PG", - "display": "Pieper" - } - } - ] + "answerValueSet": "http://nictiz.nl/fhir/ValueSet/ContactInformation-TelephoneNumbersSystem" }, { "linkId": "990", @@ -741,78 +641,7 @@ "enableBehavior": "any", "required": false, "repeats": false, - "answerOption": [ - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "DOMPART", - "display": "Partner" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "HUSB", - "display": "Echtgenoot" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "WIFE", - "display": "Echtgenote" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "FTH", - "display": "Vader" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "MTH", - "display": "Moeder" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "SONC", - "display": "Zoon" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "DAUC", - "display": "Dochter" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "BRO", - "display": "Broer" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "SIS", - "display": "Zuster" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", - "code": "OTH", - "display": "Anders" - } - } - ], + "answerValueSet": "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.40.2.3.1.1--20200901000000", "item": [ { "linkId": "412", @@ -913,78 +742,7 @@ "type": "choice", "required": false, "repeats": true, - "answerOption": [ - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "DOMPART", - "display": "Partner" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "HUSB", - "display": "Echtgenoot" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "WIFE", - "display": "Echtgenote" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "FTH", - "display": "Vader" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "MTH", - "display": "Moeder" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "SONC", - "display": "Zoon" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "DAUC", - "display": "Dochter" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "BRO", - "display": "Broer" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "SIS", - "display": "Zuster" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", - "code": "OTH", - "display": "Anders" - } - } - ], + "answerValueSet": "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.40.2.3.1.1--20200901000000", "item": [ { "linkId": "413", @@ -1040,36 +798,7 @@ "type": "choice", "required": false, "repeats": false, - "answerOption": [ - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "385987000", - "display": "Curatief / actief ziektebeleid" - } - }, - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "1351964001", - "display": "Palliatief met als doel levensverlenging én symptoomverlichting" - } - }, - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "225353007", - "display": "Palliatief met als doel symptoomverlichting, waarbij levensverlenging niet gewenst is" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", - "code": "UNK", - "display": "Nog onbekend" - } - } - ] + "answerValueSet": "https://api.iknl.nl/docs/pzp/r4/ValueSet/ACP-MedicalPolicyGoal" } ] }, @@ -1111,36 +840,7 @@ "type": "choice", "required": false, "repeats": false, - "answerOption": [ - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", - "code": "0", - "display": "Wel uitvoeren" - } - }, - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", - "code": "1", - "display": "Anders" - } - }, - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", - "code": "2", - "display": "Niet uitvoeren" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", - "code": "UNK", - "display": "Onbekend" - } - } - ], + "answerValueSet": "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.40.2.2.2.2--20200901000000", "item": [ { "linkId": "1001", @@ -1203,36 +903,7 @@ "type": "choice", "required": false, "repeats": false, - "answerOption": [ - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", - "code": "0", - "display": "Wel uitvoeren" - } - }, - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", - "code": "1", - "display": "Anders" - } - }, - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", - "code": "2", - "display": "Niet uitvoeren" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", - "code": "UNK", - "display": "Onbekend" - } - } - ], + "answerValueSet": "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.40.2.2.2.2--20200901000000", "item": [ { "linkId": "1388", @@ -1295,36 +966,7 @@ "type": "choice", "required": false, "repeats": false, - "answerOption": [ - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", - "code": "0", - "display": "Wel uitvoeren" - } - }, - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", - "code": "1", - "display": "Anders" - } - }, - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", - "code": "2", - "display": "Niet uitvoeren" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", - "code": "UNK", - "display": "Onbekend" - } - } - ], + "answerValueSet": "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.40.2.2.2.2--20200901000000", "item": [ { "linkId": "1391", @@ -1387,36 +1029,7 @@ "type": "choice", "required": false, "repeats": false, - "answerOption": [ - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", - "code": "0", - "display": "Wel uitvoeren" - } - }, - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", - "code": "1", - "display": "Anders" - } - }, - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", - "code": "2", - "display": "Niet uitvoeren" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", - "code": "UNK", - "display": "Onbekend" - } - } - ], + "answerValueSet": "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.40.2.2.2.2--20200901000000", "item": [ { "linkId": "1394", @@ -1479,36 +1092,7 @@ "type": "choice", "required": false, "repeats": false, - "answerOption": [ - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", - "code": "0", - "display": "Wel uitvoeren" - } - }, - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", - "code": "1", - "display": "Anders" - } - }, - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", - "code": "2", - "display": "Niet uitvoeren" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", - "code": "UNK", - "display": "Onbekend" - } - } - ], + "answerValueSet": "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.40.2.2.2.2--20200901000000", "item": [ { "linkId": "1397", @@ -1571,36 +1155,7 @@ "type": "choice", "required": false, "repeats": false, - "answerOption": [ - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", - "code": "0", - "display": "Wel uitvoeren" - } - }, - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", - "code": "1", - "display": "Anders" - } - }, - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", - "code": "2", - "display": "Niet uitvoeren" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", - "code": "UNK", - "display": "Onbekend" - } - } - ], + "answerValueSet": "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.40.2.2.2.2--20200901000000", "item": [ { "linkId": "1400", @@ -1684,29 +1239,7 @@ "type": "choice", "required": false, "repeats": false, - "answerOption": [ - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", - "code": "0", - "display": "Wel uitvoeren" - } - }, - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", - "code": "2", - "display": "Niet uitvoeren" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", - "code": "UNK", - "display": "Onbekend" - } - } - ], + "answerValueSet": "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.40.2.2.2.2--20200901000000", "item": [ { "linkId": "1404", @@ -1768,50 +1301,7 @@ "enableBehavior": "any", "required": false, "repeats": false, - "answerOption": [ - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "72506001", - "display": "implanteerbare cardioverter-defibrillator" - } - }, - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "465460004", - "display": "univentriculaire implanteerbare cardioverter-defibrillator" - } - }, - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "468542000", - "display": "implanteerbare tweekamercardioverter-defibrillator" - } - }, - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "704707009", - "display": "implanteerbare biventriculaire cardioverter-defibrillator" - } - }, - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "1263462004", - "display": "pulsgenerator van defibrillator voor cardiale resynchronisatietherapie" - } - }, - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "1236894001", - "display": "subcutane implanteerbare cardioverter-defibrillator" - } - } - ] + "answerValueSet": "https://api.iknl.nl/docs/pzp/r4/ValueSet/ACP-MedicalDeviceProductType-ICD" }, { "linkId": "1009", @@ -2016,50 +1506,7 @@ "type": "choice", "required": false, "repeats": false, - "answerOption": [ - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "264362003", - "display": "Thuis" - } - }, - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "22232009", - "display": "Ziekenhuis" - } - }, - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "108344006", - "display": "Verpleeghuis" - } - }, - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "284546000", - "display": "Hospice" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", - "code": "OTH", - "display": "Anders" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", - "code": "UNK", - "display": "Nog onbekend" - } - } - ], + "answerValueSet": "https://api.iknl.nl/docs/pzp/r4/ValueSet/ACP-PreferredPlaceOfDeath", "item": [ { "linkId": "1192", @@ -2103,36 +1550,7 @@ "type": "choice", "required": false, "repeats": false, - "answerOption": [ - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "340181000146102", - "display": "Heeft euthanasieverklaring" - } - }, - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "340201000146103", - "display": "Wenst geen euthanasie" - } - }, - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "340191000146100", - "display": "Geen euthanasieverklaring, zou wel verzoek kunnen doen in bepaalde situaties" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", - "code": "UNK", - "display": "Nog onbekend" - } - } - ], + "answerValueSet": "https://api.iknl.nl/docs/pzp/r4/ValueSet/ACP-PositionRegardingEuthanasia", "item": [ { "linkId": "1194", diff --git a/util/questionnaire_item_anwserOption_expander.py b/util/questionnaire_item_anwserOption_expander.py new file mode 100644 index 0000000..ca6c481 --- /dev/null +++ b/util/questionnaire_item_anwserOption_expander.py @@ -0,0 +1,516 @@ +#!/usr/bin/env python3 +"""Expand Questionnaire ``answerValueSet`` references into inline ``answerOption`` lists. + +Why this exists +--------------- +The NLM LHC-Forms tool (https://lhcforms.nlm.nih.gov/) cannot resolve ``answerValueSet`` +references against a terminology server. To preview/use the ACP Questionnaire there, every +question that points at a ValueSet needs the matching codes materialised as ``answerOption``. + +What the script does +-------------------- +For every ``Questionnaire`` resource found in ``input/resources`` it walks the item tree and, +for each item that has an ``answerValueSet``, it: + + 1. Resolves the ValueSet, looking first in the local ``fsh-generated/resources`` folder and + then in the FHIR package cache (``~/.fhir/packages``). The packages to scan are taken + from the ``dependencies:`` block of ``sushi-config.yaml``; if that is missing, the + resolved dependency list in ``fhirpkg.lock.json`` is used instead. As a last resort the + whole package cache is searched. + 2. Expands it: + * a pre-computed ``expansion.contains`` is used as-is when present; + * otherwise ``compose.include`` is processed - explicit ``concept`` lists are used + directly, ``valueSet`` imports are resolved recursively, and a bare ``system`` + (whole code system) is enumerated from the resolved CodeSystem; + * ``compose.exclude`` entries are removed; + * the CodeSystem is consulted to fill in a missing ``display``. + 3. Replaces the item's ``answerValueSet`` with the resulting ``answerOption`` array. + +Because the form is Dutch, the Dutch (``nl-NL``) designation is preferred for the display, +falling back to the concept's base ``display`` and finally the code. + +Some ValueSets reference a CodeSystem we have no access to (e.g. the UZI based +``SpecialismeCodelijst``). For those a fixed answer list is supplied via ``HARDCODED_ANSWER_OPTIONS``. + +The original files are left untouched; a copy suffixed with ``-expanded`` is written next to +each source Questionnaire. + +Usage +----- + python util/questionnaire_item_anwserOption_expander.py + python util/questionnaire_item_anwserOption_expander.py --input-dir input/resources +""" + +from __future__ import annotations + +import argparse +import json +import re +import sys +from pathlib import Path + +# -------------------------------------------------------------------------------------- +# Configuration +# -------------------------------------------------------------------------------------- + +# Repository root (this file lives in /util/). +ROOT = Path(__file__).resolve().parent.parent + +# Where the source Questionnaires live and where expanded copies are written. +DEFAULT_INPUT_DIR = ROOT / "input" / "resources" + +# Locally generated conformance resources (ValueSets / CodeSystems produced by SUSHI). +FSH_GENERATED_DIR = ROOT / "fsh-generated" / "resources" + +# Resolved dependency list (authoritative); fall back to sushi-config.yaml if absent. +LOCK_FILE = ROOT / "fhirpkg.lock.json" +SUSHI_CONFIG = ROOT / "sushi-config.yaml" + +# FHIR package cache. Honour the standard override, otherwise ~/.fhir/packages. +import os + +FHIR_PACKAGE_CACHE = Path( + os.environ.get("FHIR_PACKAGE_CACHE", Path.home() / ".fhir" / "packages") +) + +# Suffix added to the expanded copy (before the .json extension). +OUTPUT_SUFFIX = "-expanded" + +# Preferred display language (the form is Dutch). +PREFERRED_LANGUAGE = "nl-NL" + +# ValueSets that cannot be resolved from the packages (their CodeSystem is not available). +# Map the ValueSet canonical URL to a fixed list of FHIR answerOption entries. +HARDCODED_ANSWER_OPTIONS = { + # Functie (Specialisme) - SpecialismeCodelijst. Imports UZI based code lists that are + # not distributed in the package cache, so a representative subset is hardcoded. + "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.121.11.22--20200901000000": [ + {"valueCoding": {"system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", "code": "01.000", "display": "Arts"}}, + {"valueCoding": {"system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", "code": "01.015", "display": "Huisarts"}}, + {"valueCoding": {"system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", "code": "01.047", "display": "Specialist ouderengeneeskunde"}}, + {"valueCoding": {"system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", "code": "30.000", "display": "Verpleegkundige"}}, + {"valueCoding": {"system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", "code": "81.000", "display": "Physician assistant"}}, + {"valueCoding": {"system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", "code": "99.000", "display": "Zorgverlener andere zorg"}}, + ], +} + + +# -------------------------------------------------------------------------------------- +# Resource resolver: maps canonical URL -> file path for ValueSets and CodeSystems. +# -------------------------------------------------------------------------------------- + + +class ResourceResolver: + """Locate ValueSet / CodeSystem resources locally and in the FHIR package cache.""" + + def __init__(self) -> None: + # url -> Path. Local (fsh-generated) entries take precedence over package entries. + self._valuesets: dict[str, Path] = {} + self._codesystems: dict[str, Path] = {} + # Cache of loaded JSON resources keyed by path. + self._loaded: dict[Path, dict] = {} + self._scanned_full_cache = False + + self._index_local() + self._index_declared_packages() + + # -- index building ----------------------------------------------------------------- + + def _register(self, url: str | None, resource_type: str | None, path: Path) -> None: + if not url or not resource_type: + return + target = self._valuesets if resource_type == "ValueSet" else ( + self._codesystems if resource_type == "CodeSystem" else None + ) + if target is None: + return + # First registration wins (local before packages, declared deps before fallback). + target.setdefault(url, path) + + def _index_local(self) -> None: + """Index ValueSets / CodeSystems generated locally by SUSHI.""" + if not FSH_GENERATED_DIR.is_dir(): + return + for path in FSH_GENERATED_DIR.glob("*.json"): + try: + data = json.loads(path.read_text(encoding="utf-8")) + except (json.JSONDecodeError, OSError): + continue + if isinstance(data, dict): + self._register(data.get("url"), data.get("resourceType"), path) + # Cache it - we already paid the read cost. + self._loaded[path] = data + + def _package_dirs_from_dependencies(self) -> list[Path]: + """Determine which package directories to index from the project dependencies.""" + deps: dict[str, str] = {} + + # Primary source: the dependencies declared in sushi-config.yaml. + if SUSHI_CONFIG.is_file(): + deps.update(_parse_sushi_dependencies(SUSHI_CONFIG)) + + # Fallback: the resolved dependency list in fhirpkg.lock.json. + if not deps and LOCK_FILE.is_file(): + try: + lock = json.loads(LOCK_FILE.read_text(encoding="utf-8")) + deps.update(lock.get("dependencies", {})) + except (json.JSONDecodeError, OSError): + pass + + # hl7.fhir.r4.core is always needed for base FHIR code systems. + deps.setdefault("hl7.fhir.r4.core", "4.0.1") + + dirs: list[Path] = [] + for pkg_id, version in deps.items(): + candidate = FHIR_PACKAGE_CACHE / f"{pkg_id}#{version}" + if candidate.is_dir(): + dirs.append(candidate) + else: + print(f" ! dependency package not found in cache: {pkg_id}#{version}", + file=sys.stderr) + return dirs + + def _index_package_dir(self, pkg_dir: Path) -> None: + index_file = pkg_dir / "package" / ".index.json" + if not index_file.is_file(): + return + try: + index = json.loads(index_file.read_text(encoding="utf-8")) + except (json.JSONDecodeError, OSError): + return + for entry in index.get("files", []): + rtype = entry.get("resourceType") + if rtype not in ("ValueSet", "CodeSystem"): + continue + filename = entry.get("filename") + if not filename: + continue + self._register(entry.get("url"), rtype, pkg_dir / "package" / filename) + + def _index_declared_packages(self) -> None: + for pkg_dir in self._package_dirs_from_dependencies(): + self._index_package_dir(pkg_dir) + + def _index_full_cache(self) -> None: + """Fallback: index every package in the cache (used only when a URL is missing).""" + if self._scanned_full_cache or not FHIR_PACKAGE_CACHE.is_dir(): + return + self._scanned_full_cache = True + for pkg_dir in FHIR_PACKAGE_CACHE.iterdir(): + if pkg_dir.is_dir(): + self._index_package_dir(pkg_dir) + + # -- loading ------------------------------------------------------------------------ + + def _load(self, path: Path) -> dict | None: + if path in self._loaded: + return self._loaded[path] + try: + data = json.loads(path.read_text(encoding="utf-8")) + except (json.JSONDecodeError, OSError): + return None + self._loaded[path] = data + return data + + def get_valueset(self, url: str) -> dict | None: + url = _strip_version(url) + if url not in self._valuesets: + self._index_full_cache() + path = self._valuesets.get(url) + return self._load(path) if path else None + + def get_codesystem(self, url: str) -> dict | None: + url = _strip_version(url) + if url not in self._codesystems: + self._index_full_cache() + path = self._codesystems.get(url) + return self._load(path) if path else None + + +def _strip_version(url: str) -> str: + """Drop a trailing ``|version`` from a canonical reference.""" + return url.split("|", 1)[0] if url else url + + +def _parse_sushi_dependencies(config_path: Path) -> dict[str, str]: + """Minimal parser for the ``dependencies:`` block of sushi-config.yaml. + + Avoids a hard dependency on PyYAML. Only handles the simple ``id: version`` form, + which is what this project uses. + """ + deps: dict[str, str] = {} + try: + lines = config_path.read_text(encoding="utf-8").splitlines() + except OSError: + return deps + + in_block = False + dep_re = re.compile(r"^(\s*)([A-Za-z0-9._-]+)\s*:\s*([^\s#]+)") + for line in lines: + stripped = line.strip() + if not in_block: + if stripped.startswith("dependencies:"): + in_block = True + continue + # Stop when a new top-level (non-indented, non-comment) key starts. + if stripped and not line[0].isspace() and not stripped.startswith("#"): + break + if not stripped or stripped.startswith("#"): + continue + m = dep_re.match(line) + if m: + deps[m.group(2)] = m.group(3) + return deps + + +# -------------------------------------------------------------------------------------- +# ValueSet expansion +# -------------------------------------------------------------------------------------- + + +def _dutch_display(concept: dict) -> str | None: + """Return the preferred display for a concept, favouring the Dutch designation.""" + for designation in concept.get("designation", []): + if designation.get("language") == PREFERRED_LANGUAGE and designation.get("value"): + return designation["value"] + return concept.get("display") + + +def _codesystem_display_map(codesystem: dict) -> dict[str, str]: + """Flatten a (possibly hierarchical) CodeSystem into code -> display.""" + result: dict[str, str] = {} + + def walk(concepts: list) -> None: + for concept in concepts: + code = concept.get("code") + if code is not None: + result[code] = _dutch_display(concept) or concept.get("display") or code + if concept.get("concept"): + walk(concept["concept"]) + + walk(codesystem.get("concept", [])) + return result + + +class ValueSetExpander: + def __init__(self, resolver: ResourceResolver) -> None: + self.resolver = resolver + + def expand(self, url: str) -> list[dict]: + """Expand a ValueSet URL into a list of FHIR ``answerOption`` entries.""" + if url in HARDCODED_ANSWER_OPTIONS: + return [dict(opt) for opt in HARDCODED_ANSWER_OPTIONS[url]] + + codings = self._expand_to_codings(url, seen=set()) + return [{"valueCoding": coding} for coding in codings] + + def _expand_to_codings(self, url: str, seen: set[str]) -> list[dict]: + url = _strip_version(url) + if url in seen: + return [] # guard against circular imports + seen.add(url) + + valueset = self.resolver.get_valueset(url) + if valueset is None: + raise LookupError(f"ValueSet not found: {url}") + + codings: list[dict] = [] + + # 1. Pre-computed expansion wins. + expansion = valueset.get("expansion", {}) + for contains in expansion.get("contains", []): + self._collect_contains(contains, codings) + if codings: + return _dedupe(codings) + + compose = valueset.get("compose", {}) + + # 2. Includes. + for include in compose.get("include", []): + codings.extend(self._expand_include(include, seen)) + + # 3. Excludes - drop matching (system, code) pairs. + excluded = set() + for exclude in compose.get("exclude", []): + for coding in self._expand_include(exclude, seen): + excluded.add((coding.get("system"), coding.get("code"))) + if excluded: + codings = [c for c in codings if (c.get("system"), c.get("code")) not in excluded] + + return _dedupe(codings) + + def _collect_contains(self, contains: dict, out: list[dict]) -> None: + if not contains.get("abstract") and contains.get("code") is not None: + coding = {} + if contains.get("system"): + coding["system"] = contains["system"] + coding["code"] = contains["code"] + display = _dutch_display(contains) + if display: + coding["display"] = display + out.append(coding) + for child in contains.get("contains", []): + self._collect_contains(child, out) + + def _expand_include(self, include: dict, seen: set[str]) -> list[dict]: + codings: list[dict] = [] + + # Imported ValueSets. + for imported_url in include.get("valueSet", []): + try: + codings.extend(self._expand_to_codings(imported_url, seen)) + except LookupError as exc: + print(f" ! could not resolve imported ValueSet: {exc}", file=sys.stderr) + + system = include.get("system") + + if "concept" in include and system: + # Explicit concept list; fill in missing displays from the CodeSystem. + cs_map: dict[str, str] | None = None + for concept in include["concept"]: + display = _dutch_display(concept) + if not display: + if cs_map is None: + codesystem = self.resolver.get_codesystem(system) + cs_map = _codesystem_display_map(codesystem) if codesystem else {} + display = cs_map.get(concept.get("code")) + coding = {"system": system, "code": concept.get("code")} + if display: + coding["display"] = display + codings.append(coding) + elif system and "filter" not in include: + # Whole code system - enumerate it from the resolved CodeSystem. + codesystem = self.resolver.get_codesystem(system) + if codesystem is None: + print(f" ! cannot enumerate system (CodeSystem not found): {system}", + file=sys.stderr) + else: + for code, display in _codesystem_display_map(codesystem).items(): + coding = {"system": system, "code": code} + if display: + coding["display"] = display + codings.append(coding) + elif system and "filter" in include: + print(f" ! filter-based include not supported for system: {system}", + file=sys.stderr) + + return codings + + +def _dedupe(codings: list[dict]) -> list[dict]: + """Remove duplicate (system, code) codings, preserving order.""" + seen: set[tuple] = set() + result: list[dict] = [] + for coding in codings: + key = (coding.get("system"), coding.get("code")) + if key not in seen: + seen.add(key) + result.append(coding) + return result + + +# -------------------------------------------------------------------------------------- +# Questionnaire processing +# -------------------------------------------------------------------------------------- + + +def process_items(items: list[dict], expander: ValueSetExpander, stats: dict) -> None: + """Recursively expand answerValueSet references on a list of Questionnaire items.""" + for item in items: + value_set_url = item.get("answerValueSet") + if value_set_url: + stats["found"] += 1 + try: + options = expander.expand(value_set_url) + except LookupError as exc: + stats["failed"] += 1 + print(f" ! {exc} (linkId={item.get('linkId')})", file=sys.stderr) + options = None + if options: + # Merge with any existing answerOption, then drop the reference so LHC + # uses the inline options instead of trying to resolve the ValueSet. + existing = item.get("answerOption", []) + item["answerOption"] = _merge_options(existing, options) + del item["answerValueSet"] + stats["expanded"] += 1 + print(f" + linkId={item.get('linkId')}: {len(options)} options " + f"from {value_set_url}") + elif options is not None: + print(f" ! linkId={item.get('linkId')}: 0 options from {value_set_url}", + file=sys.stderr) + + if item.get("item"): + process_items(item["item"], expander, stats) + + +def _merge_options(existing: list[dict], expanded: list[dict]) -> list[dict]: + """Append expanded options to any pre-existing ones, de-duplicating by coding.""" + seen: set[tuple] = set() + merged: list[dict] = [] + for opt in list(existing) + list(expanded): + coding = opt.get("valueCoding", {}) + key = (coding.get("system"), coding.get("code")) + if key not in seen: + seen.add(key) + merged.append(opt) + return merged + + +def process_questionnaire(path: Path, expander: ValueSetExpander) -> bool: + """Expand one Questionnaire file. Returns True if an expanded copy was written.""" + try: + data = json.loads(path.read_text(encoding="utf-8")) + except (json.JSONDecodeError, OSError) as exc: + print(f"! skipping {path.name}: {exc}", file=sys.stderr) + return False + + if not isinstance(data, dict) or data.get("resourceType") != "Questionnaire": + return False + + print(f"\nProcessing {path.name} ...") + stats = {"found": 0, "expanded": 0, "failed": 0} + process_items(data.get("item", []), expander, stats) + + if stats["found"] == 0: + print(" (no answerValueSet references found)") + return False + + out_path = path.with_name(f"{path.stem}{OUTPUT_SUFFIX}{path.suffix}") + out_path.write_text( + json.dumps(data, ensure_ascii=False, indent=2) + "\n", encoding="utf-8" + ) + print(f" -> wrote {out_path.relative_to(ROOT)} " + f"(found {stats['found']}, expanded {stats['expanded']}, failed {stats['failed']})") + return True + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument("--input-dir", type=Path, default=DEFAULT_INPUT_DIR, + help=f"directory to scan for Questionnaires (default: {DEFAULT_INPUT_DIR})") + args = parser.parse_args() + + input_dir: Path = args.input_dir + if not input_dir.is_dir(): + print(f"Input directory does not exist: {input_dir}", file=sys.stderr) + return 1 + + print(f"FHIR package cache: {FHIR_PACKAGE_CACHE}") + resolver = ResourceResolver() + expander = ValueSetExpander(resolver) + + written = 0 + for path in sorted(input_dir.glob("*.json")): + # Skip the expanded copies themselves. + if path.stem.endswith(OUTPUT_SUFFIX): + continue + if process_questionnaire(path, expander): + written += 1 + + print(f"\nDone. Expanded copies written: {written}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) From c5a6eb8beee0475098ac9056a096dff0cb6fd747 Mon Sep 17 00:00:00 2001 From: Ardon Toonstra Date: Fri, 29 May 2026 15:53:04 +0200 Subject: [PATCH 10/23] Questionable replace of anwserValueSet because of moving from zib values to FHIR values --- .../resources/Questionnaire-ACP-zib2020.json | 114 +----------------- 1 file changed, 6 insertions(+), 108 deletions(-) diff --git a/input/resources/Questionnaire-ACP-zib2020.json b/input/resources/Questionnaire-ACP-zib2020.json index 5173576..30a9eea 100644 --- a/input/resources/Questionnaire-ACP-zib2020.json +++ b/input/resources/Questionnaire-ACP-zib2020.json @@ -199,36 +199,8 @@ "type": "choice", "required": false, "repeats": false, - "answerOption": [ - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.22.1", - "code": "LL", - "display": "Land Line" - } - }, - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.22.1", - "code": "FAX", - "display": "Fax" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", - "code": "PG", - "display": "Pieper" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", - "code": "MC", - "display": "Mobiel telefoonnummer" - } - } - ] + "answerValueSet": "http://nictiz.nl/fhir/ValueSet/ContactInformation-TelephoneNumbersSystem" + }, { "linkId": "978", @@ -236,29 +208,7 @@ "type": "choice", "required": false, "repeats": false, - "answerOption": [ - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", - "code": "HP", - "display": "Telefoonnummer thuis" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", - "code": "TMP", - "display": "Tijdelijk telefoonnummer" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", - "code": "WP", - "display": "Zakelijk telefoonnummer" - } - } - ] + "answerValueSet": "http://nictiz.nl/fhir/ValueSet/ContactInformation-TelephoneNumbersUse" }, { "linkId": "979", @@ -288,22 +238,7 @@ "type": "choice", "required": false, "repeats": false, - "answerOption": [ - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", - "code": "HP", - "display": "Privé e-mailadres" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", - "code": "WP", - "display": "Zakelijk e-mailadres" - } - } - ] + "answerValueSet": "http://nictiz.nl/fhir/ValueSet/ContactInformation-EmailAddressesUse" } ] } @@ -521,29 +456,7 @@ "type": "choice", "required": false, "repeats": false, - "answerOption": [ - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", - "code": "HP", - "display": "Telefoonnummer thuis" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", - "code": "TMP", - "display": "Tijdelijk telefoonnummer" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", - "code": "WP", - "display": "Zakelijk telefoonnummer" - } - } - ] + "answerValueSet": "http://nictiz.nl/fhir/ValueSet/ContactInformation-TelephoneNumbersUse" }, { "linkId": "991", @@ -573,22 +486,7 @@ "type": "choice", "required": false, "repeats": false, - "answerOption": [ - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", - "code": "HP", - "display": "Privé e-mailadres" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", - "code": "WP", - "display": "Zakelijk e-mailadres" - } - } - ] + "answerValueSet": "http://nictiz.nl/fhir/ValueSet/ContactInformation-EmailAddressesUse" } ] } From bc5b8a297752b232f779f647d88358c248ae6d05 Mon Sep 17 00:00:00 2001 From: Ardon Toonstra Date: Fri, 29 May 2026 16:16:52 +0200 Subject: [PATCH 11/23] Use ACP-YesNoUnknown ValueSet and normalize labels Replace multiple inline answerOption arrays with a single reference to the shared ACP-YesNoUnknown ValueSet (https://api.iknl.nl/docs/pzp/r4/ValueSet/ACP-YesNoUnknownVS) in the Questionnaire resource to centralize the Yes/No/Unknown options. Also normalize several answerCoding.display values from "Ja" to "ja" for consistency. Affects input/resources/Questionnaire-ACP-zib2020.json. --- .../resources/Questionnaire-ACP-zib2020.json | 106 ++---------------- 1 file changed, 9 insertions(+), 97 deletions(-) diff --git a/input/resources/Questionnaire-ACP-zib2020.json b/input/resources/Questionnaire-ACP-zib2020.json index 30a9eea..8b94a46 100644 --- a/input/resources/Questionnaire-ACP-zib2020.json +++ b/input/resources/Questionnaire-ACP-zib2020.json @@ -1157,29 +1157,7 @@ "type": "choice", "required": false, "repeats": false, - "answerOption": [ - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "373066001", - "display": "Ja" - } - }, - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "373067005", - "display": "Nee" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", - "code": "UNK", - "display": "Nog onbekend" - } - } - ], + "answerValueSet": "https://api.iknl.nl/docs/pzp/r4/ValueSet/ACP-YesNoUnknownVS", "item": [ { "linkId": "1008", @@ -1192,7 +1170,7 @@ "answerCoding": { "system": "http://snomed.info/sct", "code": "373066001", - "display": "Ja" + "display": "ja" } } ], @@ -1212,7 +1190,7 @@ "answerCoding": { "system": "http://snomed.info/sct", "code": "373066001", - "display": "Ja" + "display": "ja" } } ], @@ -1234,7 +1212,7 @@ "answerCoding": { "system": "http://snomed.info/sct", "code": "373066001", - "display": "Ja" + "display": "ja" } } ], @@ -1270,7 +1248,7 @@ "answerCoding": { "system": "http://snomed.info/sct", "code": "373066001", - "display": "Ja" + "display": "ja" } } ], @@ -1492,29 +1470,7 @@ "type": "choice", "required": false, "repeats": false, - "answerOption": [ - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "373066001", - "display": "Ja" - } - }, - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "373067005", - "display": "Nee" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", - "code": "UNK", - "display": "Nog onbekend" - } - } - ] + "answerValueSet": "https://api.iknl.nl/docs/pzp/r4/ValueSet/ACP-YesNoUnknownVS" }, { "linkId": "1650", @@ -1586,29 +1542,7 @@ "type": "choice", "required": false, "repeats": false, - "answerOption": [ - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "373066001", - "display": "Ja" - } - }, - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "373067005", - "display": "Nee" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", - "code": "UNK", - "display": "Nog onbekend" - } - } - ], + "answerValueSet": "https://api.iknl.nl/docs/pzp/r4/ValueSet/ACP-YesNoUnknownVS", "item": [ { "linkId": "1198", @@ -1631,36 +1565,14 @@ "answerCoding": { "system": "http://snomed.info/sct", "code": "373066001", - "display": "Ja" + "display": "ja" } } ], "enableBehavior": "any", "required": false, "repeats": false, - "answerOption": [ - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "373066001", - "display": "Ja" - } - }, - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "373067005", - "display": "Nee" - } - }, - { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", - "code": "UNK", - "display": "Nog onbekend" - } - } - ] + "answerValueSet": "https://api.iknl.nl/docs/pzp/r4/ValueSet/ACP-YesNoUnknownVS" } ] }, From a614f707ac425bc34a61dcfb27fc9a898ef3cd6b Mon Sep 17 00:00:00 2001 From: Ardon Toonstra Date: Fri, 29 May 2026 16:20:03 +0200 Subject: [PATCH 12/23] Strip SNOMED semantic tags from displays Handle SNOMED semantic tags and prefer parenthesis-free Dutch designations when building display labels. Add SNOMED_SYSTEM constant and a regex-based _clean_display to remove trailing semantic tags (e.g. "ja (kwalificatiewaarde)" -> "ja"). Update _dutch_display to prefer Dutch designations without parenthetical parts and to call _clean_display; propagate an optional system parameter through _dutch_display and _codesystem_display_map and update callers so CodeSystem lookups can apply SNOMED-specific cleaning. This yields cleaner answerOption/display values for SNOMED concepts. --- ...uestionnaire_item_anwserOption_expander.py | 51 ++++++++++++++----- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/util/questionnaire_item_anwserOption_expander.py b/util/questionnaire_item_anwserOption_expander.py index ca6c481..f12c90e 100644 --- a/util/questionnaire_item_anwserOption_expander.py +++ b/util/questionnaire_item_anwserOption_expander.py @@ -79,6 +79,10 @@ # Preferred display language (the form is Dutch). PREFERRED_LANGUAGE = "nl-NL" +# SNOMED CT system URL. SNOMED designations often carry a trailing semantic tag in +# parentheses (e.g. "ja (kwalificatiewaarde)"); that tag is stripped from the display. +SNOMED_SYSTEM = "http://snomed.info/sct" + # ValueSets that cannot be resolved from the packages (their CodeSystem is not available). # Map the ValueSet canonical URL to a fixed list of FHIR answerOption entries. HARDCODED_ANSWER_OPTIONS = { @@ -268,15 +272,38 @@ def _parse_sushi_dependencies(config_path: Path) -> dict[str, str]: # -------------------------------------------------------------------------------------- -def _dutch_display(concept: dict) -> str | None: - """Return the preferred display for a concept, favouring the Dutch designation.""" - for designation in concept.get("designation", []): - if designation.get("language") == PREFERRED_LANGUAGE and designation.get("value"): - return designation["value"] - return concept.get("display") +_SNOMED_SEMANTIC_TAG = re.compile(r"\s*\([^()]*\)\s*$") + + +def _clean_display(display: str | None, system: str | None) -> str | None: + """Strip the trailing SNOMED semantic tag (e.g. " (kwalificatiewaarde)") from a display.""" + if display and system == SNOMED_SYSTEM: + stripped = _SNOMED_SEMANTIC_TAG.sub("", display).strip() + if stripped: + return stripped + return display -def _codesystem_display_map(codesystem: dict) -> dict[str, str]: +def _dutch_display(concept: dict, system: str | None = None) -> str | None: + """Return the preferred display for a concept, favouring the Dutch designation. + + For SNOMED concepts a parenthesis-free designation is preferred, and any remaining + trailing semantic tag is stripped (so "ja (kwalificatiewaarde)" becomes "ja"). + """ + nl_values = [ + d["value"] for d in concept.get("designation", []) + if d.get("language") == PREFERRED_LANGUAGE and d.get("value") + ] + display = None + if nl_values: + # Prefer a Dutch designation without a parenthetical part, if one exists. + display = next((v for v in nl_values if "(" not in v), nl_values[0]) + else: + display = concept.get("display") + return _clean_display(display, system) + + +def _codesystem_display_map(codesystem: dict, system: str | None = None) -> dict[str, str]: """Flatten a (possibly hierarchical) CodeSystem into code -> display.""" result: dict[str, str] = {} @@ -284,7 +311,7 @@ def walk(concepts: list) -> None: for concept in concepts: code = concept.get("code") if code is not None: - result[code] = _dutch_display(concept) or concept.get("display") or code + result[code] = _dutch_display(concept, system) or concept.get("display") or code if concept.get("concept"): walk(concept["concept"]) @@ -345,7 +372,7 @@ def _collect_contains(self, contains: dict, out: list[dict]) -> None: if contains.get("system"): coding["system"] = contains["system"] coding["code"] = contains["code"] - display = _dutch_display(contains) + display = _dutch_display(contains, contains.get("system")) if display: coding["display"] = display out.append(coding) @@ -368,11 +395,11 @@ def _expand_include(self, include: dict, seen: set[str]) -> list[dict]: # Explicit concept list; fill in missing displays from the CodeSystem. cs_map: dict[str, str] | None = None for concept in include["concept"]: - display = _dutch_display(concept) + display = _dutch_display(concept, system) if not display: if cs_map is None: codesystem = self.resolver.get_codesystem(system) - cs_map = _codesystem_display_map(codesystem) if codesystem else {} + cs_map = _codesystem_display_map(codesystem, system) if codesystem else {} display = cs_map.get(concept.get("code")) coding = {"system": system, "code": concept.get("code")} if display: @@ -385,7 +412,7 @@ def _expand_include(self, include: dict, seen: set[str]) -> list[dict]: print(f" ! cannot enumerate system (CodeSystem not found): {system}", file=sys.stderr) else: - for code, display in _codesystem_display_map(codesystem).items(): + for code, display in _codesystem_display_map(codesystem, system).items(): coding = {"system": system, "code": code} if display: coding["display"] = display From e1b41142dca4590d0e5e8f2d56e1bf1e5dcb03b3 Mon Sep 17 00:00:00 2001 From: MariekeMassa Date: Thu, 30 Apr 2026 17:14:36 +0200 Subject: [PATCH 13/23] Change type choice to boolean for 1406, 984 and 1200 in questionnaire and responses Includes fixed enableWhen behaviour --- .../resources/Questionnaire-ACP-zib2020.json | 72 +++---------------- 1 file changed, 9 insertions(+), 63 deletions(-) diff --git a/input/resources/Questionnaire-ACP-zib2020.json b/input/resources/Questionnaire-ACP-zib2020.json index 8b94a46..cf11804 100644 --- a/input/resources/Questionnaire-ACP-zib2020.json +++ b/input/resources/Questionnaire-ACP-zib2020.json @@ -110,23 +110,9 @@ { "linkId": "1651", "text": "Is de patiënt op dit moment wilsbekwaam m.b.t. medische behandelbeslissingen?", - "type": "choice", + "type": "boolean", "required": false, "repeats": false, - "answerOption": [ - { - "valueCoding": { - "code": "1", - "display": "Ja" - } - }, - { - "valueCoding": { - "code": "0", - "display": "Nee" - } - } - ], "item": [ { "linkId": "1407", @@ -352,23 +338,9 @@ "linkId": "984", "prefix": "d)", "text": "Is de wettelijk vertegenwoordiger ook de eerste contactpersoon?", - "type": "choice", + "type": "boolean", "required": false, - "repeats": false, - "answerOption": [ - { - "valueCoding": { - "code": "1", - "display": "Ja" - } - }, - { - "valueCoding": { - "code": "0", - "display": "Nee" - } - } - ] + "repeats": false }, { "linkId": "53", @@ -379,10 +351,7 @@ { "question": "984", "operator": "=", - "answerCoding": { - "code": "0", - "display": "Nee" - } + "answerBoolean": false } ], "enableBehavior": "any", @@ -420,10 +389,7 @@ { "question": "984", "operator": "=", - "answerCoding": { - "code": "0", - "display": "Nee" - } + "answerBoolean": false } ], "enableBehavior": "any", @@ -500,10 +466,7 @@ { "question": "984", "operator": "=", - "answerCoding": { - "code": "0", - "display": "Nee" - } + "answerBoolean": false } ], "enableBehavior": "any", @@ -530,10 +493,7 @@ { "question": "984", "operator": "=", - "answerCoding": { - "code": "0", - "display": "Nee" - } + "answerBoolean": false } ], "enableBehavior": "any", @@ -1587,23 +1547,9 @@ "linkId": "1200", "prefix": "a)", "text": "Heeft u patient geïnformeerd over eigen verantwoordelijkheid om deze behandelafspraken met naasten te bespreken?", - "type": "choice", + "type": "boolean", "required": false, - "repeats": false, - "answerOption": [ - { - "valueCoding": { - "code": "1", - "display": "Ja" - } - }, - { - "valueCoding": { - "code": "0", - "display": "Nee" - } - } - ] + "repeats": false }, { "linkId": "1201", From 357ff4c694d6728a716ec2658557888621bfe762 Mon Sep 17 00:00:00 2001 From: Ardon Toonstra Date: Fri, 29 May 2026 16:56:13 +0200 Subject: [PATCH 14/23] added new version of QR --- ...naireResponse-HendrikHartman-20201001.json | 74 +++++++++++----- ...naireResponse-HendrikHartman-20221108.json | 84 ++++++++++++++----- 2 files changed, 113 insertions(+), 45 deletions(-) diff --git a/input/resources/QuestionnaireResponse-HendrikHartman-20201001.json b/input/resources/QuestionnaireResponse-HendrikHartman-20201001.json index be80735..b8cd68e 100644 --- a/input/resources/QuestionnaireResponse-HendrikHartman-20201001.json +++ b/input/resources/QuestionnaireResponse-HendrikHartman-20201001.json @@ -4,13 +4,13 @@ "meta": { "tag": [ { - "code": "lformsVersion: 38.2.0" + "code": "lformsVersion: 42.2.0" } ] }, "status": "completed", "authored": "2025-08-25T19:14:50.150Z", - "questionnaire": "https://api.iknl.nl/docs/pzp/r4/Questionnaire/ACP-zib2020|1.0.0-rc2", + "questionnaire": "https://api.iknl.nl/docs/pzp/r4/Questionnaire/ACP-zib2020|1.0.0-rc3", "subject": { "reference": "Patient/ACP-Patient-HendrikHartman-Pat1", "display": "Patient, Hendrik Hartman" @@ -99,12 +99,11 @@ { "answer": [ { - - "valueCoding": { - "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", - "code": "01.015", - "display": "Huisarts" - } + "valueCoding": { + "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", + "code": "01.015", + "display": "Huisarts" + } } ], "linkId": "1405", @@ -122,7 +121,7 @@ "valueBoolean": true } ], - "linkId": "1406", + "linkId": "1651", "text": "Is de patiënt op dit moment wilsbekwaam m.b.t. medische behandelbeslissingen?" }, { @@ -174,9 +173,9 @@ "answer": [ { "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", - "code": "HP", - "display": "Privé e-mailadres" + "system": "http://hl7.org/fhir/contact-point-use", + "code": "home", + "display": "Home" } } ], @@ -187,6 +186,19 @@ } ] }, + { + "linkId": "982", + "text": "Relatie tot patiënt (1)", + "answer": [ + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.22.472", + "code": "24", + "display": "Wettelijke vertegenwoordiger" + } + } + ] + }, { "answer": [ { @@ -267,7 +279,7 @@ "valueCoding": { "system": "http://snomed.info/sct", "code": "1351964001", - "display": "Palliatief met als doel levensverlenging én symptoomverlichting" + "display": "levensverlengende behandeling" } } ], @@ -482,7 +494,7 @@ "valueCoding": { "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", "code": "OTH", - "display": "Other" + "display": "Anders" } } ], @@ -521,7 +533,7 @@ "valueCoding": { "system": "http://snomed.info/sct", "code": "373066001", - "display": "Ja" + "display": "ja" }, "item": [ { @@ -622,10 +634,15 @@ "answer": [ { "valueString": "Hendrik wil er alles aan doen om zo lang mogelijk in goede gezondheid te kunnen leven. Hij probeert regelmatig te sporten en zou graag willen blijven hardlopen. Broer Michiel woont om de hoek en is erg betrokken bij het proces van Hendrik" + "valueCoding": { + "system": "http://snomed.info/sct", + "code": "370819000", + "display": "Vaststellen van persoonlijke waarden en wensen met betrekking tot zorg" + } } ], - "linkId": "1190", - "text": "Wens en verwachting patient ([MetingWaarde])" + "linkId": "1648", + "text": "Vaststellen wens en verwachting patiënt ([MeetMethode])" } ] }, @@ -639,11 +656,11 @@ "valueCoding": { "system": "http://snomed.info/sct", "code": "395091006", - "display": "Gewenste plek van overlijden" + "display": "Voorkeur voor plaats van overlijden (waarneembare entiteit)" } } ], - "linkId": "1430", + "linkId": "1649", "text": "Gewenste plek van overlijden ([MetingNaam])" }, { @@ -695,7 +712,7 @@ "valueCoding": { "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", "code": "UNK", - "display": "Nog onbekend" + "display": "onbekend" }, "item": [ { @@ -738,12 +755,25 @@ "valueCoding": { "system": "http://snomed.info/sct", "code": "373066001", - "display": "Ja" + "display": "ja" } } ], "linkId": "1435", "text": "Keuze orgaandonatie in donorregister ([MetingWaarde])" + }, + { + "answer": [ + { + "valueCoding": { + "system": "http://snomed.info/sct", + "code": "1156040003", + "display": "Self reported (qualifier value)" + } + } + ], + "linkId": "1650", + "text": "Keuze orgaandonatie vastgelegd in donorregister? ([MeetMethode])" } ] } @@ -787,7 +817,7 @@ "valueCoding": { "system": "http://snomed.info/sct", "code": "373067005", - "display": "Nee" + "display": "nee" } } ], diff --git a/input/resources/QuestionnaireResponse-HendrikHartman-20221108.json b/input/resources/QuestionnaireResponse-HendrikHartman-20221108.json index 2e7e672..713a0f4 100644 --- a/input/resources/QuestionnaireResponse-HendrikHartman-20221108.json +++ b/input/resources/QuestionnaireResponse-HendrikHartman-20221108.json @@ -4,13 +4,13 @@ "meta": { "tag": [ { - "code": "lformsVersion: 38.2.0" + "code": "lformsVersion: 42.2.0" } ] }, "status": "completed", "authored": "2025-08-25T19:18:32.253Z", - "questionnaire": "https://api.iknl.nl/docs/pzp/r4/Questionnaire/ACP-zib2020|1.0.0-rc2", + "questionnaire": "https://api.iknl.nl/docs/pzp/r4/Questionnaire/ACP-zib2020|1.0.0-rc3", "subject": { "reference": "Patient/ACP-Patient-HendrikHartman-Pat1", "display": "Patient, Hendrik Hartman" @@ -99,12 +99,11 @@ { "answer": [ { - - "valueCoding": { - "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", - "code": "01.015", - "display": "Huisarts" - } + "valueCoding": { + "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", + "code": "01.015", + "display": "Huisarts" + } } ], "linkId": "1405", @@ -122,7 +121,7 @@ "valueBoolean": true } ], - "linkId": "1406", + "linkId": "1651", "text": "Is de patiënt op dit moment wilsbekwaam m.b.t. medische behandelbeslissingen?" }, { @@ -174,9 +173,9 @@ "answer": [ { "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", - "code": "HP", - "display": "Privé e-mailadres" + "system": "http://hl7.org/fhir/contact-point-use", + "code": "home", + "display": "Home" } } ], @@ -187,6 +186,19 @@ } ] }, + { + "linkId": "982", + "text": "Relatie tot patiënt (1)", + "answer": [ + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.22.472", + "code": "24", + "display": "Wettelijke vertegenwoordiger" + } + } + ] + }, { "answer": [ { @@ -266,8 +278,8 @@ { "valueCoding": { "system": "http://snomed.info/sct", - "code": "225353007", - "display": "Palliatief met als doel symptoomverlichting, waarbij levensverlenging niet gewenst is" + "code": "713148004", + "display": "voorkomen en behandelen van symptomen" } } ], @@ -515,7 +527,7 @@ "valueCoding": { "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", "code": "OTH", - "display": "Other" + "display": "Anders" } } ], @@ -543,7 +555,7 @@ "valueCoding": { "system": "http://snomed.info/sct", "code": "373066001", - "display": "Ja" + "display": "ja" }, "item": [ { @@ -637,6 +649,19 @@ ], "linkId": "1190", "text": "Wens en verwachting patient ([MetingWaarde])" + }, + { + "answer": [ + { + "valueCoding": { + "system": "http://snomed.info/sct", + "code": "370819000", + "display": "Vaststellen van persoonlijke waarden en wensen met betrekking tot zorg" + } + } + ], + "linkId": "1648", + "text": "Vaststellen wens en verwachting patiënt ([MeetMethode])" } ] }, @@ -650,11 +675,11 @@ "valueCoding": { "system": "http://snomed.info/sct", "code": "395091006", - "display": "Gewenste plek van overlijden" + "display": "Voorkeur voor plaats van overlijden (waarneembare entiteit)" } } ], - "linkId": "1430", + "linkId": "1649", "text": "Gewenste plek van overlijden ([MetingNaam])" }, { @@ -663,7 +688,7 @@ "valueCoding": { "system": "http://snomed.info/sct", "code": "264362003", - "display": "Thuis" + "display": "thuis" }, "item": [ { @@ -706,7 +731,7 @@ "valueCoding": { "system": "http://snomed.info/sct", "code": "340201000146103", - "display": "Wenst geen euthanasie" + "display": "wil geen euthanasie" } } ], @@ -738,12 +763,25 @@ "valueCoding": { "system": "http://snomed.info/sct", "code": "373066001", - "display": "Ja" + "display": "ja" } } ], "linkId": "1435", "text": "Keuze orgaandonatie in donorregister ([MetingWaarde])" + }, + { + "answer": [ + { + "valueCoding": { + "system": "http://snomed.info/sct", + "code": "1156040003", + "display": "Self reported (qualifier value)" + } + } + ], + "linkId": "1650", + "text": "Keuze orgaandonatie vastgelegd in donorregister? ([MeetMethode])" } ] } @@ -787,7 +825,7 @@ "valueCoding": { "system": "http://snomed.info/sct", "code": "373066001", - "display": "Ja" + "display": "ja" }, "item": [ { @@ -811,7 +849,7 @@ "valueCoding": { "system": "http://snomed.info/sct", "code": "373066001", - "display": "Ja" + "display": "ja" } } ], From 51badc47239e75adf2065f111ebbe991849f6778 Mon Sep 17 00:00:00 2001 From: Ardon Toonstra Date: Fri, 29 May 2026 17:03:15 +0200 Subject: [PATCH 15/23] Fixed last QR --- ...eResponse-SamiraVanDerSluijs-20251117.json | 109 +++++++++++------- 1 file changed, 67 insertions(+), 42 deletions(-) diff --git a/input/resources/QuestionnaireResponse-SamiraVanDerSluijs-20251117.json b/input/resources/QuestionnaireResponse-SamiraVanDerSluijs-20251117.json index f000f54..7d34ccd 100644 --- a/input/resources/QuestionnaireResponse-SamiraVanDerSluijs-20251117.json +++ b/input/resources/QuestionnaireResponse-SamiraVanDerSluijs-20251117.json @@ -106,12 +106,11 @@ { "answer": [ { - - "valueCoding": { - "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", - "code": "01.015", - "display": "Huisarts" - } + "valueCoding": { + "system": "http://fhir.nl/fhir/NamingSystem/uzi-rolcode", + "code": "01.015", + "display": "Huisarts" + } } ], "linkId": "1405", @@ -131,7 +130,7 @@ { "answer": [ { - "valueString": "Patiënt is wilsbekwaam. Bij verandering van de situatie wordt haar partner haar wettelijk vertegenwoordiger." + "valueString": "Patiënt is wilsbekwaam. Bij verandering van de situatie wordt haar partner haar wettelijk vertegenwoordiger." } ], "linkId": "1407", @@ -140,7 +139,7 @@ ] } ], - "linkId": "1406", + "linkId": "1651", "text": "Is de patiënt op dit moment wilsbekwaam m.b.t. medische behandelbeslissingen?" }, { @@ -201,9 +200,9 @@ "answer": [ { "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", - "code": "MC", - "display": "Mobiel telefoonnummer" + "system": "http://hl7.org/fhir/contact-point-system", + "code": "phone", + "display": "Phone" } } ], @@ -214,9 +213,9 @@ "answer": [ { "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", - "code": "HP", - "display": "Telefoonnummer thuis" + "system": "http://hl7.org/fhir/contact-point-use", + "code": "home", + "display": "Home" } } ], @@ -242,9 +241,9 @@ "answer": [ { "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", - "code": "HP", - "display": "Privé e-mailadres" + "system": "http://hl7.org/fhir/contact-point-use", + "code": "home", + "display": "Home" } } ], @@ -344,9 +343,9 @@ "answer": [ { "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", - "code": "MC", - "display": "Mobiel telefoonnummer" + "system": "http://hl7.org/fhir/contact-point-system", + "code": "phone", + "display": "Phone" } } ], @@ -357,9 +356,9 @@ "answer": [ { "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", - "code": "HP", - "display": "Telefoonnummer thuis" + "system": "http://hl7.org/fhir/contact-point-use", + "code": "home", + "display": "Home" } } ], @@ -385,9 +384,9 @@ "answer": [ { "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", - "code": "HP", - "display": "Privé e-mailadres" + "system": "http://hl7.org/fhir/contact-point-use", + "code": "home", + "display": "Home" } } ], @@ -451,8 +450,8 @@ { "valueCoding": { "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "SIS", - "display": "Zuster" + "code": "BRO", + "display": "Broer" } } ] @@ -481,8 +480,8 @@ { "valueCoding": { "system": "http://snomed.info/sct", - "code": "225353007", - "display": "Palliatief met als doel symptoomverlichting, waarbij levensverlenging niet gewenst is" + "code": "713148004", + "display": "voorkomen en behandelen van symptomen" } } ], @@ -642,7 +641,7 @@ { "answer": [ { - "valueString": "Alleen als de patiënt een kans heeft om weer uit het ziekenhuis te komen, anders hoeft het niet meer voor mevrouw" + "valueString": "Alleen als de patiënt een kans heeft om weer uit het ziekenhuis te komen, anders hoeft het niet meer voor mevrouw" } ], "linkId": "1394", @@ -730,7 +729,7 @@ "valueCoding": { "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", "code": "OTH", - "display": "Other" + "display": "Anders" } } ], @@ -769,7 +768,7 @@ "valueCoding": { "system": "http://snomed.info/sct", "code": "373066001", - "display": "Ja" + "display": "ja" }, "item": [ { @@ -869,11 +868,24 @@ { "answer": [ { - "valueString": "De kleinzoon van mevrouw van der Sluijs is geboren en mevrouw is dolgelukkig dat ze hem heeft kunnen zien. Ze merkt dat ze fysiek erg achteruit gaat. Mevrouw heeft daar nu vrede mee, in tegenstelling tot eerdere gesprekken." + "valueString": "De kleinzoon van mevrouw van der Sluijs is geboren en mevrouw is dolgelukkig dat ze hem heeft kunnen zien. Ze merkt dat ze fysiek erg achteruit gaat. Mevrouw heeft daar nu vrede mee, in tegenstelling tot eerdere gesprekken." } ], "linkId": "1190", "text": "Wens en verwachting patient ([MetingWaarde])" + }, + { + "answer": [ + { + "valueCoding": { + "system": "http://snomed.info/sct", + "code": "370819000", + "display": "Vaststellen van persoonlijke waarden en wensen met betrekking tot zorg" + } + } + ], + "linkId": "1648", + "text": "Vaststellen wens en verwachting patiënt ([MeetMethode])" } ] }, @@ -887,11 +899,11 @@ "valueCoding": { "system": "http://snomed.info/sct", "code": "395091006", - "display": "Gewenste plek van overlijden" + "display": "Voorkeur voor plaats van overlijden (waarneembare entiteit)" } } ], - "linkId": "1430", + "linkId": "1649", "text": "Gewenste plek van overlijden ([MetingNaam])" }, { @@ -900,7 +912,7 @@ "valueCoding": { "system": "http://snomed.info/sct", "code": "264362003", - "display": "Thuis" + "display": "thuis" }, "item": [ { @@ -943,7 +955,7 @@ "valueCoding": { "system": "http://snomed.info/sct", "code": "340201000146103", - "display": "Wenst geen euthanasie" + "display": "wil geen euthanasie" } } ], @@ -975,12 +987,25 @@ "valueCoding": { "system": "http://snomed.info/sct", "code": "373066001", - "display": "Ja" + "display": "ja" } } ], "linkId": "1435", "text": "Keuze orgaandonatie in donorregister ([MetingWaarde])" + }, + { + "answer": [ + { + "valueCoding": { + "system": "http://snomed.info/sct", + "code": "1156040003", + "display": "Self reported (qualifier value)" + } + } + ], + "linkId": "1650", + "text": "Keuze orgaandonatie vastgelegd in donorregister? ([MeetMethode])" } ] } @@ -1006,7 +1031,7 @@ { "answer": [ { - "valueString": "Mevrouw is gek op haar kleinzoon, dus brengt graag veel tijd met hem door. Verder is ze gek op muziek en luistert ze dat graag als ze alleen is." + "valueString": "Mevrouw is gek op haar kleinzoon, dus brengt graag veel tijd met hem door. Verder is ze gek op muziek en luistert ze dat graag als ze alleen is." } ], "linkId": "1196", @@ -1024,7 +1049,7 @@ "valueCoding": { "system": "http://snomed.info/sct", "code": "373066001", - "display": "Ja" + "display": "ja" }, "item": [ { @@ -1048,7 +1073,7 @@ "valueCoding": { "system": "http://snomed.info/sct", "code": "373066001", - "display": "Ja" + "display": "ja" } } ], From f0a0efd19ce56b10ef77e4a472b6d99062faeddb Mon Sep 17 00:00:00 2001 From: Ardon Toonstra Date: Fri, 29 May 2026 17:05:34 +0200 Subject: [PATCH 16/23] Update questionnaire README steps and scripts Revise input/resources/README.md to reorganize and clarify the questionnaire preparation steps. Replaces the old conditional-expression/FHIRPath instructions with a new Step 4 instructing replacement of answerOption arrays by answerValueSet references; removes the NLM Form Builder fix walkthrough and example JSON. Adds a Step 0 to run util/questionnaire_item_anwserOption_expander.py to expand answer options and a Step 5 to run util/questionnaire_item_prefix_populator.py to populate item prefixes; retains the code-removal script step (renumbered). Updates the export/replace and LHC Forms loading guidance to reference the expanded questionnaire and adjusts step numbering and registration notes for the IG. --- input/resources/README.md | 79 ++++++--------------------------------- 1 file changed, 12 insertions(+), 67 deletions(-) diff --git a/input/resources/README.md b/input/resources/README.md index c680afb..3f4b5aa 100644 --- a/input/resources/README.md +++ b/input/resources/README.md @@ -68,80 +68,22 @@ Transform the exported metadata to follow IG standards. Use English for all meta ### Step 3: Save to Repository Save the adjusted Questionnaire as `Questionnaire-[id].json` in `input/resources/` -### Step 4: Fix Conditional Expressions +### Step 4: Replace all anwserOption with a answerValueSet reference +To ensure better maintainability and consistency, replace all `answerOption` arrays in the questionnaire items with a reference to an `answerValueSet`. Use a diff to identify all `answerValueSet` references and replace the corresponding `answerOption` arrays with the appropriate `ValueSet` reference. -Use [NLM Form Builder](https://formbuilder.nlm.nih.gov/) to correct invalid FHIRPath expressions: - -1. Select **"Start with existing form"** → **"Import from local file"** -2. Import your adjusted Questionnaire JSON -3. Review warnings for invalid FHIRPath conditions -4. Fix conditional displays (especially boolean comparisons) - - **Example fix needed:** - - Item: "Naam eerste contactpersoon" should display when: - - Question `984` ("Is de wettelijk vertegenwoordiger ook de eerste contactpersoon?") = `Nee (0)` - -### Step 5: Set Read-Only Treatment/Measurement Codes - -For sections **4. Behandelgrenzen** and **5. Behandelwensen**, configure treatment codes and measurement names as: -- **Read only**: Yes -- **Value method**: Pick initial value - -This simplifies QuestionnaireResponse creation. Example result: - -```json -"item": [ - { - "type": "choice", - "linkId": "1408", - "text": "Belangrijkste doel van behandeling ([MetingNaam])", - "required": false, - "repeats": false, - "readOnly": true, - "answerOption": [ - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "180771000146100", - "display": "Focus van behandeling (waarneembare entiteit)" - }, - "initialSelected": true - } - ] - }, -] -``` - -### Step 6: Export and Replace +### Step 5: Export and Replace 1. In Form Builder, select top-right menu → **"Export"** → **"Export to file in FHIR R4 format"** 2. Save and replace the file in `input/resources/` -### Step 7: Expand ICD valueset -In the question concerning the 'ProductType van IC' (linkID 1008), replace the ICD code and display by the valueset values, including the system, the code and the display. Illustrated for first two answer options: -```json -"answerOption": [ - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "72506001", - "display": "implanteerbare cardioverter-defibrillator" - } - }, - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "465460004", - "display": "univentriculaire implanteerbare cardioverter-defibrillator" - } - }, -] -``` -### Step 8: Remove 'code' keys from questionnaire items with Python script +### Step 6: Populate item prefix with Python script +Run the Questionnaire Item Prefix Populator script (`/util\questionnaire_item_prefix_populator.py/`) that populates the `prefix` field for all questionnaire items based on their `linkId` values, following the pattern "Q[linkId]". This ensures consistent and clear identification of questionnaire items in the IG. + +### Step 7: Remove 'code' keys from questionnaire items with Python script Run the Questionnaire Item Code Remover script (`/util\questionnaire_item_code_remover.py/`) that removes 'code' keys from all questionnaire items, including incorrect 'code' properties. -### Step 9: Register in Configuration for better presentation in IG +### Step 8: Register in Configuration for better presentation in IG Add the Questionnaire to `sushi-config.yaml`: @@ -166,8 +108,11 @@ groups: ## QuestionnaireResponse Creation Process +### Step 0: Prepare Questionnaire +Run `util\questionnaire_item_anwserOption_expander.py` to expand answer options with proper display values, ensuring that the questionnaire is fully functional for data entry. + ### Step 1: Load Questionnaire -Use [LHC Forms](https://lhcforms.nlm.nih.gov/lhcforms/) to create example responses: +Use [LHC Forms](https://lhcforms.nlm.nih.gov/lhcforms/) to create example responses - use the expanded version of the questionnaire (output step 0): 1. Select **"Load From File"** 2. Choose the adjusted Questionnaire from `input/resources/` From eeed36fd43ae7ae8970e9738a4b7b4ee09a11fea Mon Sep 17 00:00:00 2001 From: Ardon Toonstra Date: Fri, 29 May 2026 17:32:01 +0200 Subject: [PATCH 17/23] Fix incorrect QR --- .../QuestionnaireResponse-HendrikHartman-20201001.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/input/resources/QuestionnaireResponse-HendrikHartman-20201001.json b/input/resources/QuestionnaireResponse-HendrikHartman-20201001.json index b8cd68e..0466ec2 100644 --- a/input/resources/QuestionnaireResponse-HendrikHartman-20201001.json +++ b/input/resources/QuestionnaireResponse-HendrikHartman-20201001.json @@ -634,6 +634,14 @@ "answer": [ { "valueString": "Hendrik wil er alles aan doen om zo lang mogelijk in goede gezondheid te kunnen leven. Hij probeert regelmatig te sporten en zou graag willen blijven hardlopen. Broer Michiel woont om de hoek en is erg betrokken bij het proces van Hendrik" + } + ], + "linkId": "1190", + "text": "Wens en verwachting patient ([MetingWaarde])" + }, + { + "answer": [ + { "valueCoding": { "system": "http://snomed.info/sct", "code": "370819000", From ec71902ba90013b2c2108a03836ad0b94aa22517 Mon Sep 17 00:00:00 2001 From: MariekeMassa Date: Mon, 1 Jun 2026 17:10:12 +0200 Subject: [PATCH 18/23] Added group for contactperson in question 2 Changed in questionnaire and one QR, still needs to be done for remaining two QRs --- .../resources/Questionnaire-ACP-zib2020.json | 145 ++++++++++-------- ...naireResponse-HendrikHartman-20201001.json | 22 ++- 2 files changed, 97 insertions(+), 70 deletions(-) diff --git a/input/resources/Questionnaire-ACP-zib2020.json b/input/resources/Questionnaire-ACP-zib2020.json index cf11804..2f75d4b 100644 --- a/input/resources/Questionnaire-ACP-zib2020.json +++ b/input/resources/Questionnaire-ACP-zib2020.json @@ -549,77 +549,98 @@ ] }, { - "linkId": "997", - "text": "Rol", - "type": "choice", - "required": false, - "repeats": true, - "answerOption": [ - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.22.472", - "code": "03", - "display": "Curator (juridisch)" - } - }, - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.22.472", - "code": "15", - "display": "Mentor" - } - }, - { - "valueCoding": { - "system": "http://snomed.info/sct", - "code": "310141000146103", - "display": "Schriftelijk gemachtigde" - } - }, - { - "valueCoding": { - "system": "urn:oid:2.16.840.1.113883.2.4.3.11.22.472", - "code": "09", - "display": "Anders" - } - } - ], + "linkId": "1652", + "text": "Contactperso(o)n(en)", + "type": "group", + "repeats": false, "item": [ { - "linkId": "414", - "text": "Anders, namelijk:", - "type": "string", + "linkId": "997", + "text": "Rol", + "type": "choice", "required": false, - "repeats": false - } - ] - }, - { - "linkId": "998", - "text": "Relatie tot patiënt", - "type": "choice", - "required": false, - "repeats": true, - "answerValueSet": "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.40.2.3.1.1--20200901000000", - "item": [ - { - "linkId": "413", - "text": "Anders, namelijk:", - "type": "string", - "enableWhen": [ + "repeats": true, + "answerOption": [ { - "question": "998", - "operator": "=", - "answerCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", - "code": "OTH", + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.22.472", + "code": "03", + "display": "Curator (juridisch)" + } + }, + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.22.472", + "code": "15", + "display": "Mentor" + } + }, + { + "valueCoding": { + "system": "http://snomed.info/sct", + "code": "310141000146103", + "display": "Schriftelijk gemachtigde" + } + }, + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.22.472", + "code": "09", "display": "Anders" } } ], - "enableBehavior": "any", + "item": [ + { + "linkId": "414", + "text": "Anders, namelijk:", + "type": "string", + "enableWhen": [ + { + "question": "997", + "operator": "=", + "answerCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.22.472", + "code": "09", + "display": "Anders" + } + } + ], + "enableBehavior": "any", + "required": false, + "repeats": false + + } + ] + }, + { + "linkId": "998", + "text": "Relatie tot patiënt", + "type": "choice", "required": false, - "repeats": false + "repeats": true, + "answerValueSet": "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.40.2.3.1.1--20200901000000", + "item": [ + { + "linkId": "413", + "text": "Anders, namelijk:", + "type": "string", + "enableWhen": [ + { + "question": "998", + "operator": "=", + "answerCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", + "code": "OTH", + "display": "Anders" + } + } + ], + "enableBehavior": "any", + "required": false, + "repeats": false + } + ] } ] } diff --git a/input/resources/QuestionnaireResponse-HendrikHartman-20201001.json b/input/resources/QuestionnaireResponse-HendrikHartman-20201001.json index 0466ec2..f1c39b5 100644 --- a/input/resources/QuestionnaireResponse-HendrikHartman-20201001.json +++ b/input/resources/QuestionnaireResponse-HendrikHartman-20201001.json @@ -242,15 +242,21 @@ "text": "Patiënt" }, { - "linkId": "998", - "text": "Relatie tot patiënt", - "answer": [ + "linkId": "1652", + "text": "Contactperso(o)n(en)", + "item": [ { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "BRO", - "display": "Broer" - } + "linkId": "998", + "text": "Relatie tot patiënt", + "answer": [ + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "BRO", + "display": "Broer" + } + } + ] } ] } From 2cb20d9182d465725249a15f881522649343ac4e Mon Sep 17 00:00:00 2001 From: MariekeMassa Date: Mon, 1 Jun 2026 19:06:11 +0200 Subject: [PATCH 19/23] Added group for contactperson question 2 in QRs The group level was added to the remaining two questionnaire responses for the question 'Gesprek gevoerd in bijzijn van'. Additionally, answer in QR for Samira was changed to SIS. --- ...naireResponse-HendrikHartman-20221108.json | 22 ++++++++++++------- ...eResponse-SamiraVanDerSluijs-20251117.json | 22 ++++++++++++------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/input/resources/QuestionnaireResponse-HendrikHartman-20221108.json b/input/resources/QuestionnaireResponse-HendrikHartman-20221108.json index 713a0f4..3c2e052 100644 --- a/input/resources/QuestionnaireResponse-HendrikHartman-20221108.json +++ b/input/resources/QuestionnaireResponse-HendrikHartman-20221108.json @@ -242,15 +242,21 @@ "text": "Patiënt" }, { - "linkId": "998", - "text": "Relatie tot patiënt", - "answer": [ + "linkId": "1652", + "text": "Contactperso(o)n(en)", + "item": [ { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "BRO", - "display": "Broer" - } + "linkId": "998", + "text": "Relatie tot patiënt", + "answer": [ + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "BRO", + "display": "Broer" + } + } + ] } ] } diff --git a/input/resources/QuestionnaireResponse-SamiraVanDerSluijs-20251117.json b/input/resources/QuestionnaireResponse-SamiraVanDerSluijs-20251117.json index 7d34ccd..d33bbbe 100644 --- a/input/resources/QuestionnaireResponse-SamiraVanDerSluijs-20251117.json +++ b/input/resources/QuestionnaireResponse-SamiraVanDerSluijs-20251117.json @@ -444,15 +444,21 @@ "text": "Patiënt" }, { - "linkId": "998", - "text": "Relatie tot patiënt", - "answer": [ + "linkId": "1652", + "text": "Contactperso(o)n(en)", + "item": [ { - "valueCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", - "code": "BRO", - "display": "Broer" - } + "linkId": "998", + "text": "Relatie tot patiënt", + "answer": [ + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "SIS", + "display": "Zuster" + } + } + ] } ] } From 58ebe9185d794071c9bc2a10089b88aff71aae53 Mon Sep 17 00:00:00 2001 From: Ardon Toonstra Date: Tue, 2 Jun 2026 11:18:06 +0200 Subject: [PATCH 20/23] Process PR Feedback --- .../resources/Questionnaire-ACP-zib2020.json | 375 +++++++++++++++++- 1 file changed, 359 insertions(+), 16 deletions(-) diff --git a/input/resources/Questionnaire-ACP-zib2020.json b/input/resources/Questionnaire-ACP-zib2020.json index 2f75d4b..ddf1077 100644 --- a/input/resources/Questionnaire-ACP-zib2020.json +++ b/input/resources/Questionnaire-ACP-zib2020.json @@ -6,11 +6,11 @@ "name": "ACPzib2020", "title": "Uniform vastleggen proactieve zorgpanning (PZP) o.b.v. zibs2020 - ReleaseCandidate3 02-06-2026", "status": "draft", - "experimental": true, - "publisher": "Gepubliceerd door PZNL & uitgevoerd door IKNL | Published by PZNL & executed by IKNL", - "description": "Dit formulier is ontwikkeld om afspraken voortkomend uit het proces van proactieve zorgplanning (PZP) eenduidig vast te leggen. Het is GEEN afvinklijst. Het kan alleen na deskundig en genuanceerd gesprek door een zorgverlener worden ingevuld. Voor adviezen over het voeren van deze gesprekken word verwezen naar de richtlijn proactieve zorgplanning in de palliatieve fase en Palliaweb, zie https://palliaweb.nl/zorgpraktijk/proactieve-zorgplanning. \nVul 'nog onbekend' in als een onderwerp niet is besproken of als de patiënt (nog) geen mening heeft. Overweeg bij overplaatsing naar een langdurige zorgsetting gespreksverslagen over proactieve zorgplanning aan de overdracht toe te voegen. | \nThis form was developed to clearly document agreements resulting from the advance care planning (ACP) process. It is NOT a checklist. It can only be completed by a healthcare provider after a professional and nuanced conversation. For advice on conducting these conversations, please refer to the guideline for proactive care planning in the palliative phase and Palliaweb, see https://palliaweb.nl/zorgpraktijk/proactieve-zorgplanning. \nEnter 'unknown' if a topic is not discussed or if the patient does not (yet) have an opinion.When transferring to a long-term care setting, consider adding conversation records about advance care planning (ACP) to the transfer documents.", - "purpose": "Dit formulier is ontwikkeld om afspraken voortkomend uit het proces van proactieve zorgplanning (PZP) eenduidig vast te leggen. | \nThis form was developed to clearly document agreements resulting from the advance care planning (ACP) process.", - "copyright": "Op dit formulier is copyright, gebruikersrechten en een disclaimer van toepassing, zoals die gespecificeerd zijn voor alle informatiestandaarden van IKNL, zie voor de details het onderdeel Gebruikersrechten en disclaimer op https://iknl.nl/onderzoek/eenheid-van-taal. | \nThis form is subject to copyright, user rights and a disclaimer, as specified for all IKNL information standards. For details, see the paragraph on Gebruikersrechten en disclaimer at https://iknl.nl/onderzoek/eenheid-van-taal.", + "experimental": false, + "publisher": "Published by PZNL & executed by IKNL", + "description": "This form was developed to clearly document agreements resulting from the advance care planning (ACP) process. It is NOT a checklist. It can only be completed by a healthcare provider after a professional and nuanced conversation. For advice on conducting these conversations, please refer to the guideline for proactive care planning in the palliative phase and Palliaweb, see https://palliaweb.nl/zorgpraktijk/proactieve-zorgplanning. \nEnter 'unknown' if a topic is not discussed or if the patient does not (yet) have an opinion.When transferring to a long-term care setting, consider adding conversation records about advance care planning (ACP) to the transfer documents.", + "purpose": "This form was developed to clearly document agreements resulting from the advance care planning (ACP) process.", + "copyright": "This form is subject to copyright, user rights and a disclaimer, as specified for all IKNL information standards. For details, see the paragraph on Gebruikersrechten en disclaimer at https://iknl.nl/onderzoek/eenheid-van-taal.", "item": [ { "linkId": "963", @@ -185,8 +185,36 @@ "type": "choice", "required": false, "repeats": false, - "answerValueSet": "http://nictiz.nl/fhir/ValueSet/ContactInformation-TelephoneNumbersSystem" - + "answerOption": [ + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.22.1", + "code": "LL", + "display": "Land Line" + } + }, + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.22.1", + "code": "FAX", + "display": "Fax" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", + "code": "PG", + "display": "Pieper" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", + "code": "MC", + "display": "Mobiel telefoonnummer" + } + } + ] }, { "linkId": "978", @@ -194,7 +222,29 @@ "type": "choice", "required": false, "repeats": false, - "answerValueSet": "http://nictiz.nl/fhir/ValueSet/ContactInformation-TelephoneNumbersUse" + "answerOption": [ + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", + "code": "HP", + "display": "Telefoonnummer thuis" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", + "code": "TMP", + "display": "Tijdelijk telefoonnummer" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", + "code": "WP", + "display": "Zakelijk telefoonnummer" + } + } + ] }, { "linkId": "979", @@ -224,7 +274,22 @@ "type": "choice", "required": false, "repeats": false, - "answerValueSet": "http://nictiz.nl/fhir/ValueSet/ContactInformation-EmailAddressesUse" + "answerOption": [ + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", + "code": "HP", + "display": "Privé e-mailadres" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", + "code": "WP", + "display": "Zakelijk e-mailadres" + } + } + ] } ] } @@ -311,7 +376,78 @@ "type": "choice", "required": false, "repeats": false, - "answerValueSet": "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.40.2.3.1.1--20200901000000", + "answerOption": [ + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "DOMPART", + "display": "Partner" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "HUSB", + "display": "Echtgenoot" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "WIFE", + "display": "Echtgenote" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "FTH", + "display": "Vader" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "MTH", + "display": "Moeder" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "SONC", + "display": "Zoon" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "DAUC", + "display": "Dochter" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "BRO", + "display": "Broer" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "SIS", + "display": "Zuster" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", + "code": "OTH", + "display": "Anders" + } + } + ], "item": [ { "linkId": "408", @@ -414,7 +550,36 @@ "type": "choice", "required": false, "repeats": false, - "answerValueSet": "http://nictiz.nl/fhir/ValueSet/ContactInformation-TelephoneNumbersSystem" + "answerOption": [ + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.22.1", + "code": "LL", + "display": "Land Line" + } + }, + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.22.1", + "code": "FAX", + "display": "Fax" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", + "code": "PG", + "display": "Pieper" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", + "code": "MC", + "display": "Mobiel telefoonnummer" + } + } + ] }, { "linkId": "990", @@ -422,7 +587,29 @@ "type": "choice", "required": false, "repeats": false, - "answerValueSet": "http://nictiz.nl/fhir/ValueSet/ContactInformation-TelephoneNumbersUse" + "answerOption": [ + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", + "code": "HP", + "display": "Telefoonnummer thuis" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", + "code": "TMP", + "display": "Tijdelijk telefoonnummer" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", + "code": "WP", + "display": "Zakelijk telefoonnummer" + } + } + ] }, { "linkId": "991", @@ -452,7 +639,22 @@ "type": "choice", "required": false, "repeats": false, - "answerValueSet": "http://nictiz.nl/fhir/ValueSet/ContactInformation-EmailAddressesUse" + "answerOption": [ + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", + "code": "HP", + "display": "Privé e-mailadres" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-AddressUse", + "code": "WP", + "display": "Zakelijk e-mailadres" + } + } + ] } ] } @@ -499,7 +701,78 @@ "enableBehavior": "any", "required": false, "repeats": false, - "answerValueSet": "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.40.2.3.1.1--20200901000000", + "answerOption": [ + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "DOMPART", + "display": "Partner" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "HUSB", + "display": "Echtgenoot" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "WIFE", + "display": "Echtgenote" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "FTH", + "display": "Vader" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "MTH", + "display": "Moeder" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "SONC", + "display": "Zoon" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "DAUC", + "display": "Dochter" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "BRO", + "display": "Broer" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "SIS", + "display": "Zuster" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", + "code": "OTH", + "display": "Anders" + } + } + ], "item": [ { "linkId": "412", @@ -609,7 +882,6 @@ "enableBehavior": "any", "required": false, "repeats": false - } ] }, @@ -619,7 +891,78 @@ "type": "choice", "required": false, "repeats": true, - "answerValueSet": "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.40.2.3.1.1--20200901000000", + "answerOption": [ + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "DOMPART", + "display": "Partner" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "HUSB", + "display": "Echtgenoot" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "WIFE", + "display": "Echtgenote" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "FTH", + "display": "Vader" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "MTH", + "display": "Moeder" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "SONC", + "display": "Zoon" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "DAUC", + "display": "Dochter" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "BRO", + "display": "Broer" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode", + "code": "SIS", + "display": "Zuster" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", + "code": "OTH", + "display": "Anders" + } + } + ], "item": [ { "linkId": "413", From 1eabe48f34a14d5a027c6ad4b673078b9e740fd2 Mon Sep 17 00:00:00 2001 From: Ardon Toonstra Date: Tue, 2 Jun 2026 11:22:32 +0200 Subject: [PATCH 21/23] Process PR feedback --- .../resources/Questionnaire-ACP-zib2020.json | 210 +++++++++++++++++- 1 file changed, 203 insertions(+), 7 deletions(-) diff --git a/input/resources/Questionnaire-ACP-zib2020.json b/input/resources/Questionnaire-ACP-zib2020.json index ddf1077..dbfc161 100644 --- a/input/resources/Questionnaire-ACP-zib2020.json +++ b/input/resources/Questionnaire-ACP-zib2020.json @@ -1062,7 +1062,36 @@ "type": "choice", "required": false, "repeats": false, - "answerValueSet": "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.40.2.2.2.2--20200901000000", + "answerOption": [ + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", + "code": "0", + "display": "Wel uitvoeren" + } + }, + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", + "code": "1", + "display": "Anders" + } + }, + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", + "code": "2", + "display": "Niet uitvoeren" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", + "code": "UNK", + "display": "Onbekend" + } + } + ], "item": [ { "linkId": "1001", @@ -1125,7 +1154,36 @@ "type": "choice", "required": false, "repeats": false, - "answerValueSet": "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.40.2.2.2.2--20200901000000", + "answerOption": [ + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", + "code": "0", + "display": "Wel uitvoeren" + } + }, + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", + "code": "1", + "display": "Anders" + } + }, + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", + "code": "2", + "display": "Niet uitvoeren" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", + "code": "UNK", + "display": "Onbekend" + } + } + ], "item": [ { "linkId": "1388", @@ -1188,7 +1246,36 @@ "type": "choice", "required": false, "repeats": false, - "answerValueSet": "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.40.2.2.2.2--20200901000000", + "answerOption": [ + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", + "code": "0", + "display": "Wel uitvoeren" + } + }, + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", + "code": "1", + "display": "Anders" + } + }, + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", + "code": "2", + "display": "Niet uitvoeren" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", + "code": "UNK", + "display": "Onbekend" + } + } + ], "item": [ { "linkId": "1391", @@ -1251,7 +1338,36 @@ "type": "choice", "required": false, "repeats": false, - "answerValueSet": "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.40.2.2.2.2--20200901000000", + "answerOption": [ + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", + "code": "0", + "display": "Wel uitvoeren" + } + }, + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", + "code": "1", + "display": "Anders" + } + }, + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", + "code": "2", + "display": "Niet uitvoeren" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", + "code": "UNK", + "display": "Onbekend" + } + } + ], "item": [ { "linkId": "1394", @@ -1314,7 +1430,36 @@ "type": "choice", "required": false, "repeats": false, - "answerValueSet": "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.40.2.2.2.2--20200901000000", + "answerOption": [ + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", + "code": "0", + "display": "Wel uitvoeren" + } + }, + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", + "code": "1", + "display": "Anders" + } + }, + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", + "code": "2", + "display": "Niet uitvoeren" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", + "code": "UNK", + "display": "Onbekend" + } + } + ], "item": [ { "linkId": "1397", @@ -1377,7 +1522,36 @@ "type": "choice", "required": false, "repeats": false, - "answerValueSet": "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.40.2.2.2.2--20200901000000", + "answerOption": [ + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", + "code": "0", + "display": "Wel uitvoeren" + } + }, + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", + "code": "1", + "display": "Anders" + } + }, + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", + "code": "2", + "display": "Niet uitvoeren" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", + "code": "UNK", + "display": "Onbekend" + } + } + ], "item": [ { "linkId": "1400", @@ -1461,7 +1635,29 @@ "type": "choice", "required": false, "repeats": false, - "answerValueSet": "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.40.2.2.2.2--20200901000000", + "answerOption": [ + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", + "code": "0", + "display": "Wel uitvoeren" + } + }, + { + "valueCoding": { + "system": "urn:oid:2.16.840.1.113883.2.4.3.11.60.40.4.25.1", + "code": "2", + "display": "Niet uitvoeren" + } + }, + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", + "code": "UNK", + "display": "Onbekend" + } + } + ], "item": [ { "linkId": "1404", From f379c31b94e8fa4093e30f1a3696efe74eb3674a Mon Sep 17 00:00:00 2001 From: Ardon Toonstra Date: Tue, 2 Jun 2026 11:31:21 +0200 Subject: [PATCH 22/23] Remove dots in prefix --- input/resources/Questionnaire-ACP-zib2020.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/input/resources/Questionnaire-ACP-zib2020.json b/input/resources/Questionnaire-ACP-zib2020.json index dbfc161..db769f3 100644 --- a/input/resources/Questionnaire-ACP-zib2020.json +++ b/input/resources/Questionnaire-ACP-zib2020.json @@ -102,7 +102,7 @@ }, { "linkId": "26", - "prefix": "1.", + "prefix": "1", "text": "Wilsbekwaamheid & Wettelijke vertegenwoordiging", "type": "group", "repeats": false, @@ -991,7 +991,7 @@ }, { "linkId": "586", - "prefix": "3.", + "prefix": "3", "text": "Belangrijkste overeengekomen doel van medisch beleid", "type": "group", "repeats": false, @@ -1026,7 +1026,7 @@ }, { "linkId": "83", - "prefix": "4.", + "prefix": "4", "text": "Behandelgrenzen", "type": "group", "repeats": false, @@ -1814,7 +1814,7 @@ }, { "linkId": "107", - "prefix": "5.", + "prefix": "5", "text": "Behandelwensen", "type": "group", "repeats": false, @@ -2016,7 +2016,7 @@ }, { "linkId": "598", - "prefix": "6.", + "prefix": "6", "text": "Wat verder nog belangrijk is", "type": "group", "repeats": false, @@ -2050,7 +2050,7 @@ }, { "linkId": "115", - "prefix": "7.", + "prefix": "7", "text": "Eerder vastgelegde behandelwensen", "type": "group", "repeats": false, @@ -2098,7 +2098,7 @@ }, { "linkId": "119", - "prefix": "8.", + "prefix": "8", "text": "Informatie delen", "type": "group", "repeats": false, @@ -2138,4 +2138,4 @@ ] } ] -} \ No newline at end of file +} From 9975628eaafe4ce2069873a56a315781e3acf300 Mon Sep 17 00:00:00 2001 From: Ardon Toonstra Date: Tue, 2 Jun 2026 11:35:39 +0200 Subject: [PATCH 23/23] Remove unneeded enableWhen --- input/resources/Questionnaire-ACP-zib2020.json | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/input/resources/Questionnaire-ACP-zib2020.json b/input/resources/Questionnaire-ACP-zib2020.json index db769f3..ac50f65 100644 --- a/input/resources/Questionnaire-ACP-zib2020.json +++ b/input/resources/Questionnaire-ACP-zib2020.json @@ -1612,18 +1612,6 @@ "linkId": "1645", "text": "Anders, namelijk:", "type": "string", - "enableWhen": [ - { - "question": "1422", - "operator": "=", - "answerCoding": { - "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", - "code": "OTH", - "display": "Anders" - } - } - ], - "enableBehavior": "any", "required": false, "repeats": false }