From 39b02232b7fac32391cbfc68a0e54cc13b3d3bb4 Mon Sep 17 00:00:00 2001 From: oliverduenielsen Date: Wed, 19 Nov 2025 14:24:22 +0100 Subject: [PATCH 1/7] first draft of ehealth-carecommunication --- input/fsh/ehealth-carecommunication.fsh | 176 ++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 input/fsh/ehealth-carecommunication.fsh diff --git a/input/fsh/ehealth-carecommunication.fsh b/input/fsh/ehealth-carecommunication.fsh new file mode 100644 index 00000000..59316a12 --- /dev/null +++ b/input/fsh/ehealth-carecommunication.fsh @@ -0,0 +1,176 @@ +// comment for later: +// The note "should also exist in the MedcomCareCommunicationMessage bundle" is a packaging rule—consider documenting +// this in your IG narrative, as you can't force presence in a different Bundle with profile alone. + + +Profile: ehealth-carecommunication +Id: ehealth-carecommunication +Parent: Communication + +* identifier 1..1 MS +* identifier.use 0..1 +* identifier.use from http://hl7.org/fhir/ValueSet/identifier-use (required) +* identifier.value 1..1 MS +* identifier ^short = "The communication identifier" + +* status 1..1 MS + +// we do not want medcom categories in our IG +* category 1..1 MS +* category.coding 1..1 MS +* category.coding.system = "http://medcomfhir.dk/ig/terminology/CodeSystem/medcom-careCommunication-categoryCodes" MS +* category.coding.code from http://medcomfhir.dk/ig/terminology/CodeSystem/medcom-careCommunication-categoryCodes (required) MS + +* subject 1..1 MS +* subject only Reference(Patient) + +* encounter MS + +* topic 0..1 MS +* topic.text 1..1 MS +* topic.text ^short = "Plain text representation of the concept." +* topic.text ^definition = "The topic must be present." + +* priority MS +* priority ^short = "The priority of the communication." +* priority only code +* priority from http://ehealth.sundhed.dk/vs/priority (required) + +* extension contains ehealth-practitionerrole-extension named practitionerRole 0..1 + +* extension contains ehealth-practitioner-extension named author 0..1 MS + +* extension contains ehealth-destination-extension named destination 1..1 MS + +* recipient only Reference(CareTeam) MS + +* extension contains ehealth-administrative-status named administrativeStatus 1..1 + +* extension contains ehealth-Carecommunication-bundle-extension named careCommunicationBundle 1..1 MS + +* payload 1..* +* payload ^slicing.discriminator.type = #value +* payload ^slicing.discriminator.path = "content[x]" +* payload ^slicing.rules = #open + +* payload contains string 1..* +* payload[string].contentString 1..1 MS +* payload[string].contentString ^short = "Message payload." +* payload[string].extension contains + ehealth-datetime-extension named date 1..1 MS and + ehealth-practitioner-extension named author 1..1 MS and + ehealth-contact-extension named authorContact 1..1 MS and + ehealth-sending-organization-extension named sendingOrganization 1..1 MS + +* payload contains Attachment 0..* +* payload[Attachment].contentAttachment 1..1 MS +* payload[Attachment].contentAttachment ^short = "The payload with an attachment shall contain a link or content attached to the message." +* payload[attachment].extension contains + ehealth-datetime-extension named date 1..1 MS and + ehealth-practitioner-extension named author 0..1 MS and + ehealth-contact-extension named authorContact 0..1 MS and + ehealth-sending-organization-extension named sendingOrganization 1..1 MS + +Extension: ehealth-practitionerrole-extension +Title: "PractitionerRole Extension" +Description: "Reference to the sending PractitionerRole for this communication." +* . ^short = "sending practitioner role" +* value[x] only Reference(PractitionerRole) + +Extension: ehealth-practitioner-extension +Title: "Practitioner Extension" +Description: "Reference to the sending Practitioner for this communication." +* . ^short = "sending practitioner" +* value[x] only Reference(Practitioner) + +Extension: ehealth-destination-extension +Title: "Destination Extension" +Description: "Reference to the destination Organization for this communication." +* . ^short = "destination organization" +* value[x] only Reference(Organization) + +Extension: ehealth-Carecommunication-bundle-extension +Title: "Destination Extension" +Description: "Reference to the careCommunication Bundle received." +* . ^short = "carecommunication bundle" +* value[x] only Reference(Bundle) + +Extension: ehealth-administrative-status +Title: "Administrative status" +Description: "The administrative status of how a message recipient has handled a message" +* . ^short = "The administrative status of how a message recipient has handled a message" +* value[x] only Coding +* valueCoding from http://ehealth.sundhed.dk/vs/administrative-status +* valueCoding 1..1 + +Extension: ehealth-datetime-extension +Title: "DateTime Extension" +Description: "Date and time of the payload segment." +* . ^short = "Payload dateTime" +* value[x] only dateTime + +Extension: ehealth-practitioner-extension +Title: "Practitioner Extension" +Description: "Reference to the author (practitioner role) of this payload segment." +* . ^short = "Payload author" +* value[x] only Reference(MedComCorePractitionerRole) + +Extension: ehealth-contact-extension +Title: "Contact Extension" +Description: "Contact point for the author of this payload segment." +* . ^short = "Payload author contact" +* value[x] only ContactPoint + +Extension: ehealth-sending-organization-extension +Title: "sender Organization" +Description: "Reference to the sending organization for this payload segment." +* . ^short = "Reference to the sending organization" +* value[x] only Reference(Organization) + +// invariants + +Invariant: stopped-status-statusReason +Description: "If status is 'stopped', statusReason must be either 'system-error' or 'recipient-unavailable'." +Expression: "status != 'stopped' or statusReason.coding.where(code = 'system-error' or code = 'recipient-unavailable').exists()" +Severity: #error + +Invariant: only-asap-or-routine +Description: "priority must be either 'asap' or 'routine'" +Expression: "priority = 'asap' or priority = 'routine'" +Severity: #error + +Invariant: topic-required-when-category-other +Description: "topic must be present when category is 'other'." +Expression: "iif(category.coding.code != 'other', true, category.coding.code = 'other' and topic.exists())" +Severity: #error + +Invariant: practitionerrole-author-coding-xor-text +Description: "If a PractitionerRole is used as an author (via the Practitioner extension), then either code.coding.code or code.text must exist—but not both." +Expression: "payload.extension('http://ehealth.sundhed.dk/fhir/StructureDefinition/ehealth-practitioner').value.resolve().all(code.coding.code.exists() xor code.text.exists())" +Severity: #error + +Invariant: practitioner-author-must-have-name +Description: "If a Practitioner is used as author in a message segment, the referenced Practitioner must have a name." +Expression: "payload.where(extension('http://ehealth.sundhed.dk/fhir/StructureDefinition/ehealth-practitioner').exists()).extension.value.reference.resolve().practitioner.resolve().name.exists()" +Severity: #error + +Invariant: priority-category-invariant +Description: "Priority must not be present when category is not 'regarding-referral'." +Expression: "where(category.coding.code != 'regarding-referral').priority.empty()" +Severity: #error + +Invariant: uuidv4 +Description: "The identifier.value SHALL be a valid UUID v4" +Expression: "identifier.value.matches('^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$')" +Severity: #error + +Invariant: atLeastOnePayloadString +Description: "At least one payload segment shall have a message text (payload.contentString)" +Expression: "payload.contentString.exists()" +Severity: #error + +Invariant: payloadAttachment-contentType-required +Description: "contentType SHALL be present if data or url is present in Attachment" +Expression: "payload.contentAttachment.data.exists() or payload.contentAttachment.url.exists() implies payload.contentAttachment.contentType.exists()" +Severity: #error + From 962684d9bd01b305b412283b4cc7959bcd6079c6 Mon Sep 17 00:00:00 2001 From: oliverduenielsen Date: Wed, 19 Nov 2025 14:37:58 +0100 Subject: [PATCH 2/7] MS fix --- input/fsh/ehealth-carecommunication.fsh | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/input/fsh/ehealth-carecommunication.fsh b/input/fsh/ehealth-carecommunication.fsh index 59316a12..c612a4ad 100644 --- a/input/fsh/ehealth-carecommunication.fsh +++ b/input/fsh/ehealth-carecommunication.fsh @@ -18,8 +18,10 @@ Parent: Communication // we do not want medcom categories in our IG * category 1..1 MS * category.coding 1..1 MS -* category.coding.system = "http://medcomfhir.dk/ig/terminology/CodeSystem/medcom-careCommunication-categoryCodes" MS -* category.coding.code from http://medcomfhir.dk/ig/terminology/CodeSystem/medcom-careCommunication-categoryCodes (required) MS +* category.coding.system = "http://medcomfhir.dk/ig/terminology/CodeSystem/medcom-careCommunication-categoryCodes" +* category.coding.system MS +* category.coding.code from http://medcomfhir.dk/ig/terminology/CodeSystem/medcom-careCommunication-categoryCodes (required) +* category.coding.code MS * subject 1..1 MS * subject only Reference(Patient) @@ -109,12 +111,6 @@ Description: "Date and time of the payload segment." * . ^short = "Payload dateTime" * value[x] only dateTime -Extension: ehealth-practitioner-extension -Title: "Practitioner Extension" -Description: "Reference to the author (practitioner role) of this payload segment." -* . ^short = "Payload author" -* value[x] only Reference(MedComCorePractitionerRole) - Extension: ehealth-contact-extension Title: "Contact Extension" Description: "Contact point for the author of this payload segment." From 53c93583cf84c01e0fc715552c3375ccb20c4bba Mon Sep 17 00:00:00 2001 From: oliverduenielsen Date: Wed, 19 Nov 2025 14:45:43 +0100 Subject: [PATCH 3/7] MS fix --- input/fsh/ehealth-carecommunication.fsh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/input/fsh/ehealth-carecommunication.fsh b/input/fsh/ehealth-carecommunication.fsh index c612a4ad..c1a0f4a9 100644 --- a/input/fsh/ehealth-carecommunication.fsh +++ b/input/fsh/ehealth-carecommunication.fsh @@ -44,7 +44,8 @@ Parent: Communication * extension contains ehealth-destination-extension named destination 1..1 MS -* recipient only Reference(CareTeam) MS +* recipient only Reference(CareTeam) +* recipient MS * extension contains ehealth-administrative-status named administrativeStatus 1..1 From e43d8d05b85edf24aad2ebf843d6092e6c0bfeeb Mon Sep 17 00:00:00 2001 From: oliverduenielsen Date: Fri, 21 Nov 2025 13:16:02 +0100 Subject: [PATCH 4/7] building for carecommunication works --- input/fsh/ehealth-carecommunication.fsh | 46 ++++++++++++------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/input/fsh/ehealth-carecommunication.fsh b/input/fsh/ehealth-carecommunication.fsh index c1a0f4a9..3a905729 100644 --- a/input/fsh/ehealth-carecommunication.fsh +++ b/input/fsh/ehealth-carecommunication.fsh @@ -7,6 +7,17 @@ Profile: ehealth-carecommunication Id: ehealth-carecommunication Parent: Communication +* obeys + stopped-status-statusReason + and only-asap-or-routine + and topic-required-when-category-other + and practitionerrole-author-coding-xor-text + and practitioner-author-must-have-name + and priority-category-invariant + and uuidv4 + and atLeastOnePayloadString + and payloadAttachment-contentType-required + * identifier 1..1 MS * identifier.use 0..1 * identifier.use from http://hl7.org/fhir/ValueSet/identifier-use (required) @@ -17,10 +28,9 @@ Parent: Communication // we do not want medcom categories in our IG * category 1..1 MS +* category from http://medcomfhir.dk/ig/terminology/CodeSystem/medcom-careCommunication-categoryCodes (required) * category.coding 1..1 MS -* category.coding.system = "http://medcomfhir.dk/ig/terminology/CodeSystem/medcom-careCommunication-categoryCodes" * category.coding.system MS -* category.coding.code from http://medcomfhir.dk/ig/terminology/CodeSystem/medcom-careCommunication-categoryCodes (required) * category.coding.code MS * subject 1..1 MS @@ -34,16 +44,17 @@ Parent: Communication * topic.text ^definition = "The topic must be present." * priority MS -* priority ^short = "The priority of the communication." +* priority ^short = "Shall be present if the message priority is known to be ASAP, but is only allowed when the category is 'regarding referral', see priority-category-invariant" * priority only code * priority from http://ehealth.sundhed.dk/vs/priority (required) * extension contains ehealth-practitionerrole-extension named practitionerRole 0..1 -* extension contains ehealth-practitioner-extension named author 0..1 MS +* extension contains ehealth-practitioner-extension named practitioner 0..1 MS * extension contains ehealth-destination-extension named destination 1..1 MS +* recipient 0..1 * recipient only Reference(CareTeam) * recipient MS @@ -52,22 +63,19 @@ Parent: Communication * extension contains ehealth-Carecommunication-bundle-extension named careCommunicationBundle 1..1 MS * payload 1..* -* payload ^slicing.discriminator.type = #value +* payload ^slicing.discriminator.type = #type * payload ^slicing.discriminator.path = "content[x]" * payload ^slicing.rules = #open +* payload contains string 1..* and attachment 0..* -* payload contains string 1..* * payload[string].contentString 1..1 MS -* payload[string].contentString ^short = "Message payload." * payload[string].extension contains - ehealth-datetime-extension named date 1..1 MS and - ehealth-practitioner-extension named author 1..1 MS and - ehealth-contact-extension named authorContact 1..1 MS and - ehealth-sending-organization-extension named sendingOrganization 1..1 MS - -* payload contains Attachment 0..* -* payload[Attachment].contentAttachment 1..1 MS -* payload[Attachment].contentAttachment ^short = "The payload with an attachment shall contain a link or content attached to the message." + ehealth-datetime-extension named date 1..1 MS and + ehealth-practitioner-extension named author 1..1 MS and + ehealth-contact-extension named authorContact 1..1 MS and + ehealth-sending-organization-extension named sendingOrganization 1..1 MS + +* payload[attachment].contentAttachment 1..1 MS * payload[attachment].extension contains ehealth-datetime-extension named date 1..1 MS and ehealth-practitioner-extension named author 0..1 MS and @@ -98,14 +106,6 @@ Description: "Reference to the careCommunication Bundle received." * . ^short = "carecommunication bundle" * value[x] only Reference(Bundle) -Extension: ehealth-administrative-status -Title: "Administrative status" -Description: "The administrative status of how a message recipient has handled a message" -* . ^short = "The administrative status of how a message recipient has handled a message" -* value[x] only Coding -* valueCoding from http://ehealth.sundhed.dk/vs/administrative-status -* valueCoding 1..1 - Extension: ehealth-datetime-extension Title: "DateTime Extension" Description: "Date and time of the payload segment." From 10db7d2ff9c42788732ad2ff90efc6bf96ab50ee Mon Sep 17 00:00:00 2001 From: oliverduenielsen Date: Fri, 5 Dec 2025 08:37:44 +0100 Subject: [PATCH 5/7] Added valueset with conceptmap to priority and category elements, changed card. for inReferenceTo and sender --- input/fsh/ehealth-carecommunication.fsh | 148 +++++++++++-- ...ConceptMap-CareCommunication-Priority.json | 36 ++++ ...ConceptMap-CareCommunucation-Category.json | 196 ++++++++++++++++++ 3 files changed, 361 insertions(+), 19 deletions(-) create mode 100644 input/resources/ConceptMap-CareCommunication-Priority.json create mode 100644 input/resources/ConceptMap-CareCommunucation-Category.json diff --git a/input/fsh/ehealth-carecommunication.fsh b/input/fsh/ehealth-carecommunication.fsh index 3a905729..bee3e5cb 100644 --- a/input/fsh/ehealth-carecommunication.fsh +++ b/input/fsh/ehealth-carecommunication.fsh @@ -17,6 +17,8 @@ Parent: Communication and uuidv4 and atLeastOnePayloadString and payloadAttachment-contentType-required + and no-standard-sender + and category-not-required-if-dest-TBD * identifier 1..1 MS * identifier.use 0..1 @@ -26,12 +28,11 @@ Parent: Communication * status 1..1 MS -// we do not want medcom categories in our IG -* category 1..1 MS -* category from http://medcomfhir.dk/ig/terminology/CodeSystem/medcom-careCommunication-categoryCodes (required) +* category 0..1 MS +* category from http://ehealth.sundhed.dk/vs/ehealth-carecommunication-category (required) * category.coding 1..1 MS -* category.coding.system MS -* category.coding.code MS +* category.coding.system 1..1 MS +* category.coding.code 1..1 MS * subject 1..1 MS * subject only Reference(Patient) @@ -46,7 +47,7 @@ Parent: Communication * priority MS * priority ^short = "Shall be present if the message priority is known to be ASAP, but is only allowed when the category is 'regarding referral', see priority-category-invariant" * priority only code -* priority from http://ehealth.sundhed.dk/vs/priority (required) +* priority from http://ehealth.sundhed.dk/vs/ehealth-carecommunication-priority (required) * extension contains ehealth-practitionerrole-extension named practitionerRole 0..1 @@ -54,13 +55,28 @@ Parent: Communication * extension contains ehealth-destination-extension named destination 1..1 MS +* extension contains ehealth-origin-organization-extension named origin 1..1 MS + +* extension contains ehealth-sending-actor-extension named sender 0..1 MS + +* extension contains ehealth-message-Type-extension named messageType 1..1 MS + * recipient 0..1 -* recipient only Reference(CareTeam) +* recipient only Reference(CareTeam or PractitionerRole) * recipient MS +* recipient ^short = "The recieving actor of the message" + +* inResponseTo 0..1 MS + +* sender 0..0 + +* basedOn 0..0 + +* partOf 0..0 * extension contains ehealth-administrative-status named administrativeStatus 1..1 -* extension contains ehealth-Carecommunication-bundle-extension named careCommunicationBundle 1..1 MS +* extension contains ehealth-Carecommunication-bundle-extension named medComCareCommunicationBundle 0..1 MS * payload 1..* * payload ^slicing.discriminator.type = #type @@ -71,16 +87,12 @@ Parent: Communication * payload[string].contentString 1..1 MS * payload[string].extension contains ehealth-datetime-extension named date 1..1 MS and - ehealth-practitioner-extension named author 1..1 MS and - ehealth-contact-extension named authorContact 1..1 MS and - ehealth-sending-organization-extension named sendingOrganization 1..1 MS + ehealth-contact-extension named authorContact 1..1 MS * payload[attachment].contentAttachment 1..1 MS * payload[attachment].extension contains ehealth-datetime-extension named date 1..1 MS and - ehealth-practitioner-extension named author 0..1 MS and - ehealth-contact-extension named authorContact 0..1 MS and - ehealth-sending-organization-extension named sendingOrganization 1..1 MS + ehealth-contact-extension named authorContact 0..1 MS Extension: ehealth-practitionerrole-extension Title: "PractitionerRole Extension" @@ -97,7 +109,7 @@ Description: "Reference to the sending Practitioner for this communication." Extension: ehealth-destination-extension Title: "Destination Extension" Description: "Reference to the destination Organization for this communication." -* . ^short = "destination organization" +* . ^short = "Organization receiving the message" * value[x] only Reference(Organization) Extension: ehealth-Carecommunication-bundle-extension @@ -118,13 +130,102 @@ Description: "Contact point for the author of this payload segment." * . ^short = "Payload author contact" * value[x] only ContactPoint -Extension: ehealth-sending-organization-extension -Title: "sender Organization" +Extension: ehealth-origin-organization-extension +Title: "sender organization" Description: "Reference to the sending organization for this payload segment." -* . ^short = "Reference to the sending organization" +* . ^short = "Reference to the sending organization of the message" * value[x] only Reference(Organization) -// invariants +Extension: ehealth-message-Type-extension +Title: "Message type" +Description: "The type of the message. If inResponseTo is present, the type can not be new-message." +* value[x] only code +* valueCode from MessageTypeVS (required) +* . ^short = "Message type" + +Extension: ehealth-sending-actor-extension +Title: "Sending Actor Extension" +Description: "Reference to the sending actor (e.g., CareTeam or PractitionerRole) for this communication." +* . ^short = "Sending actor" +* value[x] only Reference(CareTeam or PractitionerRole) + + +// Valuesets + +ValueSet: MessageTypeVS +Title: "Message Type ValueSet" +Description: "Allowed message types: new, reply, forward." +* ^compose.include.system = "http://ehealth.sundhed.dk/cs/message-type" +* ^compose.include.concept[+].code = #new +* ^compose.include.concept[=].display = "New Message" +* ^compose.include.concept[+].code = #reply +* ^compose.include.concept[=].display = "Reply" +* ^compose.include.concept[+].code = #forward +* ^compose.include.concept[=].display = "Forward" + +ValueSet: EhealthCareCommunicationCategoryVS +Id: ehealth-carecommunication-category +Title: "eHealth CareCommunication Categories" +* ^url = "http://ehealth.sundhed.dk/vs/ehealth-carecommunication-category" +* ^status = #active +* ^description = "Categories used for CareCommunciation messages." +* ^compose.include.system = "http://ehealth.sundhed.dk/cs/ehealth-carecommunication-category" + +ValueSet: EhealthCareCommunicationPriorityVS +Id: ehealth-carecommunication-priority +Title: "eHealth CareCommunication Priorities" +* ^url = "http://ehealth.sundhed.dk/vs/ehealth-carecommunication-priority" +* ^status = #active +* ^description = "Priorities used for CareCommunication messages." +* ^compose.include.system = "http://ehealth.sundhed.dk/cs/ehealth-carecommunication-priority" + + +// CodeSystems + +CodeSystem: MessageTypeCS +Title: "Message Type CodeSystem" +Description: "Allowed codes for message type." +* ^url = "http://ehealth.sundhed.dk/cs/message-type" +* #new "New Message" +* #reply "Reply" +* #forward "Forward" + +CodeSystem: EhealthCareCommunicationCategoryCS +Id: ehealth-carecommunication-category +Title: "eHealth CareCommunication Category codes" +Description: "The set of CareCommunication category code." +* ^url = "http://ehealth.sundhed.dk/cs/ehealth-carecommunication-category" +* #alcohol-and-drug-treatment "Alcohol and drug treatment" +* #assistive-devices "Assistive technology" +* #carecoordination "Care Coordination" +* #decease "Decease" +* #discharge "Discharge" +* #examination-results "Examination Results" +* #healthcare "Healthcare" +* #home-care-assessment "Home care assessment" +* #medicine "Medicine" +* #nursing "Nursing" +* #outpatient "Outpatient" +* #psychiatry-social-disability "Psychiatry, Social, Disability" +* #regarding-referral "Regarding Referral" +* #telemedicine "Telemedicine" +* #training "Training" +* #acute-ambulant "Acute ambulant" +* #extended-care-responsibility "Extended care responsibility" +* #other "Other" + +CodeSystem: EhealthCareCommunicationPriorityCS +Id: ehealth-carecommunication-priority +Title: "eHealth CareCommunication Priority codes" +Description: "The set of CareCommunication priority code." +* ^url = "http://ehealth.sundhed.dk/cs/ehealth-carecommunication-priority" +* #routine "Routine" +* #asap "ASAP" + + + + +// Invariants Invariant: stopped-status-statusReason Description: "If status is 'stopped', statusReason must be either 'system-error' or 'recipient-unavailable'." @@ -171,3 +272,12 @@ Description: "contentType SHALL be present if data or url is present in Attachme Expression: "payload.contentAttachment.data.exists() or payload.contentAttachment.url.exists() implies payload.contentAttachment.contentType.exists()" Severity: #error +Invariant: no-standard-sender +Description: "The standard Communication.sender element SHALL NOT be used. Use the ehealth-sending-actor extension instead." +Expression: "sender.empty()" +Severity: #error + +Invariant: category-not-required-if-dest-TBD +Description: "category may be omitted if extension 'destination' is the reference FUTORGANIZATIONREFERENCETBD, otherwise category must be present" +Expression: "extension('http://ehealth.sundhed.dk/fhir/StructureDefinition/ehealth-destination-extension').value.as(Reference).reference = 'FUTORGANIZATIONREFERENCETBD' or category.exists()" +Severity: #error \ No newline at end of file diff --git a/input/resources/ConceptMap-CareCommunication-Priority.json b/input/resources/ConceptMap-CareCommunication-Priority.json new file mode 100644 index 00000000..31d46f98 --- /dev/null +++ b/input/resources/ConceptMap-CareCommunication-Priority.json @@ -0,0 +1,36 @@ +{ + "resourceType": "ConceptMap", + "id": "ehealth-to-medcom-carecommunication-priority", + "url": "http://ehealth.sundhed.dk/cm/ehealth-to-medcom-carecommunication-priority", + "version": "1.0.0", + "status": "active", + "title": "eHealth to MedCom CareCommunication Priority Map", + "group": [ + { + "source": "http://ehealth.sundhed.dk/cs/ehealth-carecommunication-priority", + "target": "http://medcomfhir.dk/ig/terminology/ValueSet/medcom-careCommunication-requestPriority", + "element": [ + { + "code": "routine", + "target": [ + { + "code": "routine", + "display": "Routine", + "relationship": "equivalent" + } + ] + }, + { + "code": "asap", + "target": [ + { + "code": "asap", + "display": "ASAP", + "relationship": "equivalent" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/input/resources/ConceptMap-CareCommunucation-Category.json b/input/resources/ConceptMap-CareCommunucation-Category.json new file mode 100644 index 00000000..a71865a7 --- /dev/null +++ b/input/resources/ConceptMap-CareCommunucation-Category.json @@ -0,0 +1,196 @@ +{ + "resourceType": "ConceptMap", + "id": "ehealth-to-medcom-carecommunication-category", + "url": "http://ehealth.sundhed.dk/cm/ehealth-to-medcom-carecommunication-category", + "version": "1.0.0", + "status": "active", + "title": "eHealth to MedCom CareCommunication Category Map", + "group": [ + { + "source": "http://ehealth.sundhed.dk/cs/ehealth-carecommunication-category", + "target": "http://medcomfhir.dk/ig/terminology/ValueSet/medcom-careCommunication-categories", + "element": [ + { + "code": "alcohol-and-drug-treatment", + "target": [ + { + "code": "alcohol-and-drug-treatment", + "display": "Alcohol and drug treatment", + "relationship": "equivalent" + } + ] + }, + { + "code": "assistive-devices", + "target": [ + { + "code": "assistive-devices", + "display": "Assistive technology", + "relationship": "equivalent" + } + ] + }, + { + "code": "carecoordination", + "target": [ + { + "code": "carecoordination", + "display": "Care Coordination", + "relationship": "equivalent" + } + ] + }, + { + "code": "decease", + "target": [ + { + "code": "decease", + "display": "Decease", + "relationship": "equivalent" + } + ] + }, + { + "code": "discharge", + "target": [ + { + "code": "discharge", + "display": "Discharge", + "relationship": "equivalent" + } + ] + }, + { + "code": "examination-results", + "target": [ + { + "code": "examination-results", + "display": "Examination Results", + "relationship": "equivalent" + } + ] + }, + { + "code": "healthcare", + "target": [ + { + "code": "healthcare", + "display": "Healthcare", + "relationship": "equivalent" + } + ] + }, + { + "code": "home-care-assessment", + "target": [ + { + "code": "home-care-assessment", + "display": "Home care assessment", + "relationship": "equivalent" + } + ] + }, + { + "code": "medicine", + "target": [ + { + "code": "medicine", + "display": "Medicine", + "relationship": "equivalent" + } + ] + }, + { + "code": "nursing", + "target": [ + { + "code": "nursing", + "display": "Nursing", + "relationship": "equivalent" + } + ] + }, + { + "code": "outpatient", + "target": [ + { + "code": "outpatient", + "display": "Outpatient", + "relationship": "equivalent" + } + ] + }, + { + "code": "psychiatry-social-disability", + "target": [ + { + "code": "psychiatry-social-disability", + "display": "Psychiatry, Social, Disability", + "relationship": "equivalent" + } + ] + }, + { + "code": "regarding-referral", + "target": [ + { + "code": "regarding-referral", + "display": "Regarding Referral", + "relationship": "equivalent" + } + ] + }, + { + "code": "telemedicine", + "target": [ + { + "code": "telemedicine", + "display": "Telemedicine", + "relationship": "equivalent" + } + ] + }, + { + "code": "training", + "target": [ + { + "code": "training", + "display": "Training", + "relationship": "equivalent" + } + ] + }, + { + "code": "acute-ambulant", + "target": [ + { + "code": "acute-ambulant", + "display": "Acute ambulant", + "relationship": "equivalent" + } + ] + }, + { + "code": "extended-care-responsibility", + "target": [ + { + "code": "extended-care-responsibility", + "display": "Extended care responsibility", + "relationship": "equivalent" + } + ] + }, + { + "code": "other", + "target": [ + { + "code": "other", + "display": "Other", + "relationship": "equivalent" + } + ] + } + ] + } + ] +} \ No newline at end of file From 1d767baee83cc25cbf32e187d1ac52ee995d2cae Mon Sep 17 00:00:00 2001 From: oliverduenielsen Date: Wed, 17 Dec 2025 09:55:03 +0100 Subject: [PATCH 6/7] refactor of sender extension - now holds PractitionerRole, Practitioner and CareTeam --- input/fsh/ehealth-carecommunication.fsh | 119 ++++++++++++------------ input/pagecontent/changelog.md | 9 ++ 2 files changed, 67 insertions(+), 61 deletions(-) diff --git a/input/fsh/ehealth-carecommunication.fsh b/input/fsh/ehealth-carecommunication.fsh index bee3e5cb..3e82eef7 100644 --- a/input/fsh/ehealth-carecommunication.fsh +++ b/input/fsh/ehealth-carecommunication.fsh @@ -11,14 +11,12 @@ Parent: Communication stopped-status-statusReason and only-asap-or-routine and topic-required-when-category-other - and practitionerrole-author-coding-xor-text - and practitioner-author-must-have-name and priority-category-invariant and uuidv4 and atLeastOnePayloadString and payloadAttachment-contentType-required and no-standard-sender - and category-not-required-if-dest-TBD + and sender-required-based-on-messagetype * identifier 1..1 MS * identifier.use 0..1 @@ -28,38 +26,37 @@ Parent: Communication * status 1..1 MS -* category 0..1 MS +* category 1..1 MS * category from http://ehealth.sundhed.dk/vs/ehealth-carecommunication-category (required) * category.coding 1..1 MS * category.coding.system 1..1 MS +* category.coding.system = "http://ehealth.sundhed.dk/cs/ehealth-carecommunication-category" * category.coding.code 1..1 MS * subject 1..1 MS * subject only Reference(Patient) * encounter MS +* encounter ^short = "Shall contain a reference to an Encounter resource with a episodeOfCare-identifier, if the identifier is included in a previous message." * topic 0..1 MS +* topic ^short = "Must be added when category is "other". Topic must be added in the text-element." * topic.text 1..1 MS * topic.text ^short = "Plain text representation of the concept." * topic.text ^definition = "The topic must be present." * priority MS -* priority ^short = "Shall be present if the message priority is known to be ASAP, but is only allowed when the category is 'regarding referral', see priority-category-invariant" +* priority ^short = "Only used when the category is 'regarding referral', see priority-category-invariant." * priority only code * priority from http://ehealth.sundhed.dk/vs/ehealth-carecommunication-priority (required) -* extension contains ehealth-practitionerrole-extension named practitionerRole 0..1 +* extension contains ehealth-carecommunication-sender named sender 0..1 MS -* extension contains ehealth-practitioner-extension named practitioner 0..1 MS +* extension contains ehealth-carecommunication-destination named destination 1..1 MS -* extension contains ehealth-destination-extension named destination 1..1 MS +* extension contains ehealth-carecommunication-origin named origin 1..1 MS -* extension contains ehealth-origin-organization-extension named origin 1..1 MS - -* extension contains ehealth-sending-actor-extension named sender 0..1 MS - -* extension contains ehealth-message-Type-extension named messageType 1..1 MS +* extension contains ehealth-carecommunication-message-Type named messageType 1..1 MS * recipient 0..1 * recipient only Reference(CareTeam or PractitionerRole) @@ -76,7 +73,7 @@ Parent: Communication * extension contains ehealth-administrative-status named administrativeStatus 1..1 -* extension contains ehealth-Carecommunication-bundle-extension named medComCareCommunicationBundle 0..1 MS +* extension contains ehealth-carecommunication-bundle named CorrespondingMedComCareCommunicationBundle 0..1 MS * payload 1..* * payload ^slicing.discriminator.type = #type @@ -86,75 +83,82 @@ Parent: Communication * payload[string].contentString 1..1 MS * payload[string].extension contains - ehealth-datetime-extension named date 1..1 MS and - ehealth-contact-extension named authorContact 1..1 MS + ehealth-carecommunication-datetime named date 1..1 MS and + ehealth-carecommunication-contact-point named authorContact 1..1 MS and + ehealth-carecommunication-payload-identifier named identifier 0..1 MS * payload[attachment].contentAttachment 1..1 MS * payload[attachment].extension contains - ehealth-datetime-extension named date 1..1 MS and - ehealth-contact-extension named authorContact 0..1 MS - -Extension: ehealth-practitionerrole-extension -Title: "PractitionerRole Extension" -Description: "Reference to the sending PractitionerRole for this communication." -* . ^short = "sending practitioner role" -* value[x] only Reference(PractitionerRole) - -Extension: ehealth-practitioner-extension -Title: "Practitioner Extension" -Description: "Reference to the sending Practitioner for this communication." -* . ^short = "sending practitioner" -* value[x] only Reference(Practitioner) - -Extension: ehealth-destination-extension + ehealth-carecommunication-datetime named date 1..1 MS and + ehealth-carecommunication-contact-point named authorContact 0..1 MS and + ehealth-carecommunication-payload-identifier named identifier 0..1 MS + + +// Extensions + +Extension: ehealth-carecommunication-sender +Id: ehealth-carecommunication-sender +Title: "Sender Extension, contains the sending PractitionerRole, Practitioner and CareTeam." +Description: "References the sending PractitionerRole (Actor), the Practitioner, and optionally a CareTeam." +* extension contains + actor 1..1 MS and + practitioner 1..1 MS and + careteam 0..1 MS +* extension[actor] ^short = "Sending PractitionerRole" +* extension[actor].value[x] only Reference(PractitionerRole) +* extension[practitioner] ^short = "The underlying Practitioner for this sender" +* extension[practitioner].value[x] only Reference(Practitioner) +* extension[careteam] ^short = "Optionally, the involved CareTeam" +* extension[careteam].value[x] only Reference(CareTeam) + +Extension: ehealth-carecommunication-destination Title: "Destination Extension" Description: "Reference to the destination Organization for this communication." * . ^short = "Organization receiving the message" * value[x] only Reference(Organization) -Extension: ehealth-Carecommunication-bundle-extension +Extension: ehealth-carecommunication-bundle Title: "Destination Extension" Description: "Reference to the careCommunication Bundle received." * . ^short = "carecommunication bundle" * value[x] only Reference(Bundle) -Extension: ehealth-datetime-extension +Extension: ehealth-carecommunication-datetime Title: "DateTime Extension" Description: "Date and time of the payload segment." * . ^short = "Payload dateTime" * value[x] only dateTime -Extension: ehealth-contact-extension +Extension: ehealth-carecommunication-contact-point Title: "Contact Extension" Description: "Contact point for the author of this payload segment." * . ^short = "Payload author contact" * value[x] only ContactPoint -Extension: ehealth-origin-organization-extension +Extension: ehealth-carecommunication-payload-identifier +Title: "Identifier Extension" +Description: "Extension to hold an Identifier for a payload. Value shall be a UUID identifier version 4." +* value[x] only Identifier + +Extension: ehealth-carecommunication-origin Title: "sender organization" Description: "Reference to the sending organization for this payload segment." * . ^short = "Reference to the sending organization of the message" * value[x] only Reference(Organization) -Extension: ehealth-message-Type-extension +Extension: ehealth-carecommunication-message-Type Title: "Message type" Description: "The type of the message. If inResponseTo is present, the type can not be new-message." -* value[x] only code -* valueCode from MessageTypeVS (required) +* value[x] only Coding +* valueCoding from MessageType (required) * . ^short = "Message type" -Extension: ehealth-sending-actor-extension -Title: "Sending Actor Extension" -Description: "Reference to the sending actor (e.g., CareTeam or PractitionerRole) for this communication." -* . ^short = "Sending actor" -* value[x] only Reference(CareTeam or PractitionerRole) - - // Valuesets -ValueSet: MessageTypeVS +ValueSet: MessageType Title: "Message Type ValueSet" Description: "Allowed message types: new, reply, forward." +* ^url = "http://ehealth.sundhed.dk/cm/ehealth-to-medcom-carecommunication-category" * ^compose.include.system = "http://ehealth.sundhed.dk/cs/message-type" * ^compose.include.concept[+].code = #new * ^compose.include.concept[=].display = "New Message" @@ -242,16 +246,6 @@ Description: "topic must be present when category is 'other'." Expression: "iif(category.coding.code != 'other', true, category.coding.code = 'other' and topic.exists())" Severity: #error -Invariant: practitionerrole-author-coding-xor-text -Description: "If a PractitionerRole is used as an author (via the Practitioner extension), then either code.coding.code or code.text must exist—but not both." -Expression: "payload.extension('http://ehealth.sundhed.dk/fhir/StructureDefinition/ehealth-practitioner').value.resolve().all(code.coding.code.exists() xor code.text.exists())" -Severity: #error - -Invariant: practitioner-author-must-have-name -Description: "If a Practitioner is used as author in a message segment, the referenced Practitioner must have a name." -Expression: "payload.where(extension('http://ehealth.sundhed.dk/fhir/StructureDefinition/ehealth-practitioner').exists()).extension.value.reference.resolve().practitioner.resolve().name.exists()" -Severity: #error - Invariant: priority-category-invariant Description: "Priority must not be present when category is not 'regarding-referral'." Expression: "where(category.coding.code != 'regarding-referral').priority.empty()" @@ -273,11 +267,14 @@ Expression: "payload.contentAttachment.data.exists() or payload.contentAttachmen Severity: #error Invariant: no-standard-sender -Description: "The standard Communication.sender element SHALL NOT be used. Use the ehealth-sending-actor extension instead." +Description: "The standard Communication.sender element SHALL NOT be used. Use the ehealth-carecommunication-sender extension instead." Expression: "sender.empty()" Severity: #error -Invariant: category-not-required-if-dest-TBD -Description: "category may be omitted if extension 'destination' is the reference FUTORGANIZATIONREFERENCETBD, otherwise category must be present" -Expression: "extension('http://ehealth.sundhed.dk/fhir/StructureDefinition/ehealth-destination-extension').value.as(Reference).reference = 'FUTORGANIZATIONREFERENCETBD' or category.exists()" +Invariant: sender-required-based-on-messagetype +Description: """ +If messagetype is 'new' or 'reply', the sender extension must be present. +If 'forward', sender may be absent. +""" +Expression: "extension('http://ehealth.sundhed.dk/fhir/StructureDefinition/ehealth-carecommunication-message-Type').value.coding.where(code = 'new' or code = 'reply').exists() implies extension('http://ehealth.sundhed.dk/fhir/StructureDefinition/ehealth-carecommunication-sender').exists()" Severity: #error \ No newline at end of file diff --git a/input/pagecontent/changelog.md b/input/pagecontent/changelog.md index 0a29629e..47e991cc 100644 --- a/input/pagecontent/changelog.md +++ b/input/pagecontent/changelog.md @@ -1,5 +1,14 @@ This is the log of changes made to the eHealth Implementation Guide. +# Next Release + +### Model +- Added http://ehealth.sundhed.dk/fhir/StructureDefinition/ehealth-carecommunication + +### Conceptmaps +- Added http://ehealth.sundhed.dk/cm/ehealth-to-medcom-carecommunication-priority +- Added http://ehealth.sundhed.dk/cm/ehealth-to-medcom-carecommunication-category + ## 7.0.0 ### CodeSystems - Added 'http://ehealth.sundhed.dk/policy/dk/aeldreloven' to http://ehealth.sundhed.dk/cs/ehealth-provenance-policies From 04662c762300350cb2f5aa2d2f435f6a52641f25 Mon Sep 17 00:00:00 2001 From: oliverduenielsen Date: Wed, 11 Mar 2026 10:42:13 +0100 Subject: [PATCH 7/7] Consolidate contact-point into sender, rename message type codes, make identifier required - Removed ehealth-carecommunication-bundle and ehealth-carecommunication-contact-point extensions - Consolidated contactPoint (0..1) into sender extension; renamed careteam -> careTeam - Made payload identifier required (1..1) for both string and attachment payloads - Renamed message type codes to full hyphenated names (new-message, reply-message, forward-message) - Updated sender-required invariant expression to match new code names Co-Authored-By: Claude Sonnet 4.6 --- input/fsh/ehealth-carecommunication.fsh | 53 ++++++++++--------------- 1 file changed, 20 insertions(+), 33 deletions(-) diff --git a/input/fsh/ehealth-carecommunication.fsh b/input/fsh/ehealth-carecommunication.fsh index 3e82eef7..7a7822a9 100644 --- a/input/fsh/ehealth-carecommunication.fsh +++ b/input/fsh/ehealth-carecommunication.fsh @@ -40,7 +40,7 @@ Parent: Communication * encounter ^short = "Shall contain a reference to an Encounter resource with a episodeOfCare-identifier, if the identifier is included in a previous message." * topic 0..1 MS -* topic ^short = "Must be added when category is "other". Topic must be added in the text-element." +* topic ^short = "Must be added when category is \"other\". Topic must be added in the text-element." * topic.text 1..1 MS * topic.text ^short = "Plain text representation of the concept." * topic.text ^definition = "The topic must be present." @@ -73,8 +73,6 @@ Parent: Communication * extension contains ehealth-administrative-status named administrativeStatus 1..1 -* extension contains ehealth-carecommunication-bundle named CorrespondingMedComCareCommunicationBundle 0..1 MS - * payload 1..* * payload ^slicing.discriminator.type = #type * payload ^slicing.discriminator.path = "content[x]" @@ -84,14 +82,12 @@ Parent: Communication * payload[string].contentString 1..1 MS * payload[string].extension contains ehealth-carecommunication-datetime named date 1..1 MS and - ehealth-carecommunication-contact-point named authorContact 1..1 MS and - ehealth-carecommunication-payload-identifier named identifier 0..1 MS + ehealth-carecommunication-payload-identifier named identifier 1..1 MS * payload[attachment].contentAttachment 1..1 MS * payload[attachment].extension contains ehealth-carecommunication-datetime named date 1..1 MS and - ehealth-carecommunication-contact-point named authorContact 0..1 MS and - ehealth-carecommunication-payload-identifier named identifier 0..1 MS + ehealth-carecommunication-payload-identifier named identifier 1..1 MS // Extensions @@ -103,13 +99,16 @@ Description: "References the sending PractitionerRole (Actor), the Practitioner, * extension contains actor 1..1 MS and practitioner 1..1 MS and - careteam 0..1 MS + contactPoint 0..1 MS and + careTeam 0..1 MS * extension[actor] ^short = "Sending PractitionerRole" * extension[actor].value[x] only Reference(PractitionerRole) * extension[practitioner] ^short = "The underlying Practitioner for this sender" * extension[practitioner].value[x] only Reference(Practitioner) -* extension[careteam] ^short = "Optionally, the involved CareTeam" -* extension[careteam].value[x] only Reference(CareTeam) +* extension[careTeam] ^short = "Optionally, the involved CareTeam" +* extension[careTeam].value[x] only Reference(CareTeam) +* extension[contactPoint] ^short = "Optional contactpoint for the sender" +* extension[contactPoint].value[x] only ContactPoint Extension: ehealth-carecommunication-destination Title: "Destination Extension" @@ -117,28 +116,16 @@ Description: "Reference to the destination Organization for this communication." * . ^short = "Organization receiving the message" * value[x] only Reference(Organization) -Extension: ehealth-carecommunication-bundle -Title: "Destination Extension" -Description: "Reference to the careCommunication Bundle received." -* . ^short = "carecommunication bundle" -* value[x] only Reference(Bundle) - Extension: ehealth-carecommunication-datetime Title: "DateTime Extension" Description: "Date and time of the payload segment." * . ^short = "Payload dateTime" * value[x] only dateTime -Extension: ehealth-carecommunication-contact-point -Title: "Contact Extension" -Description: "Contact point for the author of this payload segment." -* . ^short = "Payload author contact" -* value[x] only ContactPoint - Extension: ehealth-carecommunication-payload-identifier Title: "Identifier Extension" Description: "Extension to hold an Identifier for a payload. Value shall be a UUID identifier version 4." -* value[x] only Identifier +* value[x] Extension: ehealth-carecommunication-origin Title: "sender organization" @@ -157,15 +144,15 @@ Description: "The type of the message. If inResponseTo is present, the type can ValueSet: MessageType Title: "Message Type ValueSet" -Description: "Allowed message types: new, reply, forward." +Description: "Allowed message types: new-message, reply-message, forward-message." * ^url = "http://ehealth.sundhed.dk/cm/ehealth-to-medcom-carecommunication-category" * ^compose.include.system = "http://ehealth.sundhed.dk/cs/message-type" -* ^compose.include.concept[+].code = #new +* ^compose.include.concept[+].code = #new-message * ^compose.include.concept[=].display = "New Message" -* ^compose.include.concept[+].code = #reply -* ^compose.include.concept[=].display = "Reply" -* ^compose.include.concept[+].code = #forward -* ^compose.include.concept[=].display = "Forward" +* ^compose.include.concept[+].code = #reply-message +* ^compose.include.concept[=].display = "Reply Message" +* ^compose.include.concept[+].code = #forward-message +* ^compose.include.concept[=].display = "Forward Message" ValueSet: EhealthCareCommunicationCategoryVS Id: ehealth-carecommunication-category @@ -190,9 +177,9 @@ CodeSystem: MessageTypeCS Title: "Message Type CodeSystem" Description: "Allowed codes for message type." * ^url = "http://ehealth.sundhed.dk/cs/message-type" -* #new "New Message" -* #reply "Reply" -* #forward "Forward" +* #new-message "New Message" +* #reply-message "Reply" +* #forward-message "Forward" CodeSystem: EhealthCareCommunicationCategoryCS Id: ehealth-carecommunication-category @@ -276,5 +263,5 @@ Description: """ If messagetype is 'new' or 'reply', the sender extension must be present. If 'forward', sender may be absent. """ -Expression: "extension('http://ehealth.sundhed.dk/fhir/StructureDefinition/ehealth-carecommunication-message-Type').value.coding.where(code = 'new' or code = 'reply').exists() implies extension('http://ehealth.sundhed.dk/fhir/StructureDefinition/ehealth-carecommunication-sender').exists()" +Expression: "extension('http://ehealth.sundhed.dk/fhir/StructureDefinition/ehealth-carecommunication-message-Type').value.coding.where(code = 'new-message' or code = 'reply-message').exists() implies extension('http://ehealth.sundhed.dk/fhir/StructureDefinition/ehealth-carecommunication-sender').exists()" Severity: #error \ No newline at end of file