Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
39b0223
first draft of ehealth-carecommunication
OliverDueNielsen Nov 19, 2025
962684d
MS fix
OliverDueNielsen Nov 19, 2025
53c9358
MS fix
OliverDueNielsen Nov 19, 2025
e43d8d0
building for carecommunication works
OliverDueNielsen Nov 21, 2025
10db7d2
Added valueset with conceptmap to priority and category elements, cha…
OliverDueNielsen Dec 5, 2025
1d767ba
refactor of sender extension - now holds PractitionerRole, Practition…
OliverDueNielsen Dec 17, 2025
2899934
[(CCR0224-changes-for-media)] Updated ehealth-media profile to allow …
mkl-systematic Jan 27, 2026
4a510ff
[(CCR0224-changes-for-media)] Merge remote-tracking branch 'origin/re…
mkl-systematic Jan 27, 2026
5ed1b9c
[(CCR0224-changes-for-media)] updated changelog
mkl-systematic Jan 27, 2026
9970ddc
[(CCR0224-changes-for-media)] updated changelog
mkl-systematic Jan 27, 2026
612a2c5
Merge pull request #227 from fut-infrastructure/CCR0224-changes-for-m…
mkl-systematic Jan 27, 2026
04662c7
Consolidate contact-point into sender, rename message type codes, mak…
OliverDueNielsen Mar 11, 2026
763419d
Merge branch 'master' into ehealth-carecommunication
OliverDueNielsen Mar 11, 2026
0e650f3
Add messageHeaderId as identifier
OliverDueNielsen Apr 20, 2026
e2013d9
docs(event-messages): document tightened EHealthApplicationEvent sche…
jhntrifork Apr 20, 2026
f732bca
Merge branch 'release_2026.3' into ehealth-carecommunication
OliverDueNielsen Apr 27, 2026
1182b55
Add system to carecommunication identifier
OliverDueNielsen Apr 27, 2026
2873e65
Merge remote-tracking branch 'origin/master' into release_2026.3
BastianTrifork Apr 28, 2026
476df18
set version to SNAPSHOT on snapshot branch
BastianTrifork Apr 28, 2026
4b9a184
docs(event-messages): refine EHealthApplicationEvent schema constrain…
jhntrifork Apr 29, 2026
d35a382
Merge branch 'release_2026.3' into fix/CCR0303-ig-schema-constraints
jhntrifork Apr 29, 2026
9619623
Merge pull request #270 from fut-infrastructure/fix/CCR0303-ig-schema…
jhntrifork Apr 29, 2026
0b7d070
Merge remote-tracking branch 'origin/release_2026.3' into release_202…
BastianTrifork Apr 29, 2026
4895cc8
re-add poa privilege
BastianTrifork Apr 29, 2026
d734025
updated changelog.md
BastianTrifork Apr 29, 2026
eeddc76
Merge pull request #274 from fut-infrastructure/poa-privilege
BastianTrifork Apr 29, 2026
847cbed
make relationship.coding extensible
BastianTrifork Apr 30, 2026
2b40201
add intro to ehealth-carecommunication
OliverDueNielsen May 4, 2026
286f44d
Merge branch 'release_2026.3' into ehealth-carecommunication
OliverDueNielsen May 4, 2026
2625f3e
version 9.0.2-snapshot
OliverDueNielsen May 4, 2026
f2b8224
added change to changelog
OliverDueNielsen May 4, 2026
c4ba4e2
Merge pull request #242 from fut-infrastructure/ehealth-carecommunica…
OliverDueNielsen May 4, 2026
f29a095
added ehealth-carecommunication to supported profiles for Communicati…
OliverDueNielsen May 4, 2026
5087b91
Merge pull request #275 from fut-infrastructure/update-capability-sta…
OliverDueNielsen May 4, 2026
a354b6a
fix carecommunication profile
OliverDueNielsen May 11, 2026
8e53bd2
Merge pull request #277 from fut-infrastructure/fix-carecommunication…
OliverDueNielsen May 11, 2026
30ee735
fix carecommunication profile
OliverDueNielsen May 11, 2026
9fb71aa
Merge pull request #279 from fut-infrastructure/various-fixes-for-car…
OliverDueNielsen May 11, 2026
66c07cb
invariant for urn:uuid: only for carecommunication identifier
OliverDueNielsen May 12, 2026
d6b5b25
Merge pull request #281 from fut-infrastructure/invariant-only-for-co…
OliverDueNielsen May 12, 2026
7c4ae8f
bump SNAPSHOT version after merging snapshot version into 2026.3
BastianTrifork May 12, 2026
43d16e5
exclude inherited eCPR identifier slices from ehealth-patient
BastianTrifork May 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ The CI/CD pipeline uses the HL7 CI/CD infrastructure and Github webhooks which i

## Local development

### Running SUSHI
Use `./sushi.sh` instead of `npx sushi` to suppress known-safe naming warnings (ehealth-* names that don't follow PascalCase) while keeping all other output intact.

### Running locally
Do `rm -rf output && rm -rf temp/ && ./_genonce.sh`

Expand Down
321 changes: 321 additions & 0 deletions input/fsh/ehealth-carecommunication.fsh
Original file line number Diff line number Diff line change
@@ -0,0 +1,321 @@
// 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

* obeys
stopped-status-statusReason
and only-asap-or-routine
and topic-required-when-category-other
and priority-category-invariant
and atLeastOnePayloadString
and payloadAttachment-contentType-required
and no-standard-sender
and sender-required-based-on-messagetype
and reply-requires-inResponseTo

* identifier 1..2 MS
* identifier ^slicing.discriminator.type = #value
* identifier ^slicing.discriminator.path = "system"
* identifier ^slicing.rules = #open
* identifier contains communicationId 1..1 MS and messageHeaderId 0..1 MS

* identifier[communicationId] obeys uuidv4
* identifier[communicationId].system 1..1 MS
* identifier[communicationId].system = "http://ehealth.sundhed.dk/id/ehealth-carecommunication-identifier"
* identifier[communicationId].use 0..1
* identifier[communicationId].use from http://hl7.org/fhir/ValueSet/identifier-use (required)
* identifier[communicationId].value 1..1 MS
* identifier[communicationId].value ^short = "UUID v4 in URN form (urn:uuid:<uuid>)"
* identifier[communicationId].value ^definition = "The communication identifier as a UUID v4 in URN form. The URN form (urn:uuid:<uuid>) is used so the same UUID is byte-identical to Bundle.entry.fullUrl and references in the MedCom careCommunication Bundle this profile is aligned with."
* identifier[communicationId] ^short = "The communication identifier"

* identifier[messageHeaderId].system 1..1 MS
* identifier[messageHeaderId].system = "http://ehealth.sundhed.dk/fhir/system/medcom-message-header-id"
* identifier[messageHeaderId].value 1..1 MS
* identifier[messageHeaderId] ^short = "The ID of the originating MessageHeader resource"

* status 1..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 = "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-carecommunication-sender named sender 0..1 MS

* extension contains ehealth-carecommunication-destination named destination 1..1 MS

* extension contains ehealth-carecommunication-origin named origin 1..1 MS

* extension contains ehealth-carecommunication-message-Type named messageType 1..1 MS

* recipient 0..1
* recipient only Reference(CareTeam or PractitionerRole)
* recipient MS
* recipient ^short = "The recieving actor of the message"

* inResponseTo 0..1 MS
* inResponseTo ^short = "references the Ehealth-CareCommunication Communication.id, which this message is a response to."

* sender 0..0

* basedOn 0..0

* partOf 0..0

* extension contains ehealth-administrative-status named administrativeStatus 1..1

* payload 1..*
* payload ^slicing.discriminator.type = #type
* payload ^slicing.discriminator.path = "$this.content"
* payload ^slicing.rules = #open
* payload contains string 1..* and attachment 0..*

* payload[string].contentString 1..1 MS
* payload[string].extension contains
ehealth-carecommunication-datetime named date 1..1 MS and
ehealth-carecommunication-payload-identifier named identifier 1..1 MS

* payload[attachment].content[x] only Attachment
* payload[attachment].contentAttachment 1..1 MS
* payload[attachment].extension contains
ehealth-carecommunication-datetime named date 1..1 MS and
ehealth-carecommunication-payload-identifier named identifier 1..1 MS
* payload[attachment].contentAttachment.contentType MS
* payload[attachment].contentAttachment.contentType ^short = "The content type shall be present when the content is an attachment included in the data element."
* payload[attachment].contentAttachment.contentType from http://ehealth.sundhed.dk/vs/ehealth-carecommunication-mimetypes (required)
* payload[attachment].contentAttachment.data MS
* payload[attachment].contentAttachment.data ^short = "Shall be present and contain the base64 encoded content of the attachment."
* payload[attachment].contentAttachment.url MS
* payload[attachment].contentAttachment.url ^short = "Shall be present if the attachment is a link to a web page."
* payload[attachment].contentAttachment.title 1.. MS
* payload[attachment].contentAttachment.title ^short = "Note: it is not allowed for the system to automatically include '.filetype' in the title."
* payload[attachment].contentAttachment.creation MS
* payload[attachment].contentAttachment.creation ^short = "The time the attachment was created"

// 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
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[contactPoint] ^short = "Optional contactpoint for the sender"
* extension[contactPoint].value[x] only ContactPoint

Extension: ehealth-carecommunication-destination
Id: 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-datetime
Title: "DateTime Extension"
Description: "Date and time of the payload segment."
* . ^short = "Payload dateTime"
* value[x] only dateTime

Extension: ehealth-carecommunication-payload-identifier
Title: "Identifier Extension"
Description: "Extension to hold an Identifier for a payload. Identifier.value shall be a UUID v4 in URN form (urn:uuid:<uuid>)."
* value[x] only Identifier
* valueIdentifier 1..1

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-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 Coding
* valueCoding from MessageType (required)
* . ^short = "Message type"

// Valuesets

ValueSet: MessageType
Title: "Message Type ValueSet"
Description: "Allowed message types: new-message, reply-message, forward-message."
* ^url = "http://ehealth.sundhed.dk/vs/ehealth-carecommunication-message-type"
* ^compose.include.system = "http://ehealth.sundhed.dk/cs/message-type"
* ^compose.include.concept[+].code = #new-message
* ^compose.include.concept[=].display = "New Message"
* ^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
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: EhealthCareCommunicationMimeTypesVS
Id: ehealth-carecommunication-mimetypes
Title: "eHealth CareCommunication Attachment MIME Types"
Description: "Allowed MIME types for attachments in eHealth CareCommunication messages. Mirrors MedCom's medcom-core-attachmentMimeTypes ValueSet."
* ^url = "http://ehealth.sundhed.dk/vs/ehealth-carecommunication-mimetypes"
* ^status = #active
* ^compose.include.system = "urn:ietf:bcp:13"
* ^compose.include.concept[+].code = #application/pdf
* ^compose.include.concept[=].display = "application/pdf"
* ^compose.include.concept[+].code = #image/gif
* ^compose.include.concept[=].display = "image/gif"
* ^compose.include.concept[+].code = #image/jpeg
* ^compose.include.concept[=].display = "image/jpeg"
* ^compose.include.concept[+].code = #image/png
* ^compose.include.concept[=].display = "image/png"
* ^compose.include.concept[+].code = #image/tiff
* ^compose.include.concept[=].display = "image/tiff"
* ^compose.include.concept[+].code = #image/bmp
* ^compose.include.concept[=].display = "image/bmp"

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-message "New Message"
* #reply-message "Reply"
* #forward-message "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'."
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.empty() or 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: priority-category-invariant
Description: "Priority must not be present when category is not 'regarding-referral'."
Expression: "category.coding.code = 'regarding-referral' or priority.empty()"
Severity: #error

Invariant: uuidv4
Description: "identifier.value SHALL be a valid UUID v4 in URN form (urn:uuid:<uuid>)"
Expression: "value.matches('^urn:uuid:[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

Invariant: no-standard-sender
Description: "The standard Communication.sender element SHALL NOT be used. Use the ehealth-carecommunication-sender extension instead."
Expression: "sender.empty()"
Severity: #error

Invariant: reply-requires-inResponseTo
Description: "If messageType is 'reply-message', inResponseTo SHALL be populated."
Expression: "extension('http://ehealth.sundhed.dk/fhir/StructureDefinition/ehealth-carecommunication-message-Type').value.where(code = 'reply-message').exists() implies inResponseTo.exists()"
Severity: #error

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.where(code = 'new-message' or code = 'reply-message').exists() implies extension('http://ehealth.sundhed.dk/fhir/StructureDefinition/ehealth-carecommunication-sender').exists()"
Severity: #error
2 changes: 1 addition & 1 deletion input/fsh/ehealth-media.fsh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Parent: Media
* subject ^type.aggregation = #referenced
* subject.reference 1..1
* created[x] 1..1
* operator only Reference(ehealth-practitioner)
* operator only Reference(ehealth-practitioner or ehealth-patient or ehealth-relatedperson)
* operator ^type.aggregation = #referenced
* device only Reference(ehealth-device or ehealth-devicemetric)
* device ^type.aggregation = #referenced
Expand Down
2 changes: 2 additions & 0 deletions input/fsh/ehealth-patient.fsh
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ Parent: DkCorePatient
* telecom[eBoks].rank 0..0

* identifier[cpr] 1..1
* identifier[x-ecpr] 0..0
* identifier[d-ecpr] 0..0

* gender 1..1
* contact.extension contains ehealth-patient-contactnote named patientContactnote 0..*
Expand Down
2 changes: 1 addition & 1 deletion input/fsh/ehealth-relatedperson.fsh
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Parent: RelatedPerson

* patient only Reference(ehealth-patient)
* patient ^type.aggregation = #referenced
* relationship.coding from http://ehealth.sundhed.dk/vs/relatedperson-relationshiptype
* relationship.coding from http://ehealth.sundhed.dk/vs/relatedperson-relationshiptype (extensible)
* name 1..*

Instance: relatedperson01
Expand Down
Loading
Loading