Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
318 changes: 318 additions & 0 deletions input/fsh/ehealth-carecommunication.fsh
Original file line number Diff line number Diff line change
@@ -0,0 +1,318 @@
// 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 uuidv4
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].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] ^short = "The communication identifier"

* identifier[messageHeaderId].system 1..1 MS
* identifier[messageHeaderId].system = "http://ehealth.sundhed.dk/id/ehealth-carecommunication-messageHeaderId"
* 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 = "content[x]"
* 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
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. Value shall be a UUID identifier version 4."
* value[x] only string
* valueString 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/cm/ehealth-to-medcom-carecommunication-category"
* ^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 = '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: "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

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.coding.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.coding.where(code = 'new-message' or code = 'reply-message').exists() implies extension('http://ehealth.sundhed.dk/fhir/StructureDefinition/ehealth-carecommunication-sender').exists()"
Severity: #error
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Introduction

An Ehealth-CareCommunication is an FUT abstraction of a MedCom CareCommunication.
This is needed to support communication through the VANS network with parties outside the FUT infrastructure, as well as inside FUT.
The Ehealth-CareCommunication's primary feature is to enable communication in relation to several images of different file types.

# Remarks about status and administrative-status

- __status__:
- A message is considered "not yet sent" when it has one of the following status and can freely transition from one to another: 'preparation', 'on-hold', 'not-done', 'entered-in-error'
- A message is considered "being sent" when created or patched into status 'in-progress' and cannot be patched further or deleted by the sender
- The server will automatically transition a message from 'in-progress' to 'completed' when it has been sent successfully (happens when the Vans-Relay has received a positive acknowledgement on the send message)
- The server will automatically transition a message from 'in-progress' to 'stopped' if it could not be sent (happens when the Vans-Relay has received a negative acknowledgement on the send message, or at 3 failed attempts at sending)
- The client can never create or patch a message into status 'completed' or 'stopped'
- The sender cannot patch, only delete messages with status 'stopped'
- The sender cannot patch or delete messages with status 'completed'
- The recipient can patch /received and administrative-status on messages with status 'completed'

- __administrative-status__ (extension): Makes it possible for the message __recipient__ to indicate the state of a message. A message may hold an administrative status that defines the last action the recipient took on the message in question. At first, the message has administrative-status "activate". The recipient may mark the message as read by setting administrative-status "read". If the recipient considers the message a sort of "task", the message may also be updated with
administrative-status "complete" when the task is done, or "reactivate" if the task was not complete anyway.

# Scope and Usage

In the eHealth Infrastructure the ehealth-CareCommunication resource is used in conjunction with the
following resources:

- Patient
- As a subject of a message

- PractitionerRole
- As specific sender/recipient of a message

- Practitioner
- the Practitioner of the PractitionerRole

- CareTeam
- as specific sender/recipient of a message

- Organization
- as sender/recipient of a message

__note on sender__: The sender of a message is structured as a complex extension,
holding a reference to the sending PractitionerRole, the linked Practitioner and optional
CareTeam. If a CareTeam is present, that CareTeam is considered the specific sender,
not the PractitionerRole. PractitionerRole is still required, since every message has to
have a PractitionerRole representing that message.

# General rules

- The sender/receiver Organizations have to have both a SOR and GLN (EAN) identifier to be eligible for VANS communication.
- If the message type is Forward, you as a sender have to pick which payloads should be included in the message.
- If the message type is Reply, the message will be populated automatically with all prior payloads of the given conversation.
- The Communication identifier is the same for all Ehealth-CareCommunications of the same conversation. A new Communication Id is needed for a Forward message type, even though bundles from a prior conversation are included.
- The MessageHeader identifier is set for received messages, as client-side assignment of id's is not possible. For messages sent from the FUT infrastructure, it is not needed.
The reasoning for the use of this identifier is that the correlating MedCom model for Ehealth-CareCommunications identifies specific messages based on the MessageHeader identifier.
- inResponseTo has to be included for Reply messages. It points to the previous MessageHeader identifier in the conversation if present, otherwise Ehealth-CareCommunication.id.
- If category is other, the topic.text element has to be populated.
- recipient can be excluded, which means the message is considered sent to the destination organization.
Loading