Referral Profile¶
| Canonical | ../StructureDefinition/nexus-core-referral |
|---|---|
| Status | draft · 1.26.0 |
| Base | ServiceRequest (constraint) |
| Source | FSH · JSON |
Defines the Nexus EMR FHIR profile for referrals: a request that another clinician or service accept the patient, for consultation, second opinion, or ongoing management. Aligned to the pan-Canadian CA-eReC / Ontario eReferral contract, which is the shape Nexus already exchanges with Ocean. Distinct from NexusEmrCoreServiceRequest, which governs laboratory, imaging and procedure ORDERS and fixes intent to order.
FSH
The authored source of truth: resources/StructureDefinition-nexus-core-referral.fsh (edit on GitHub). One FSH file may define several related artifacts.
// NexusCoreReferral.fsh
//
// A referral: a request that another clinician or service take the patient on.
//
// WHY A SEPARATE PROFILE, not a change to NexusEmrCoreServiceRequest. That profile is
// order-shaped -- `intent` fixed to `order`, `category` required-bound to the five-concept
// base value set, `code` 1..1 -- and a referral satisfies none of the three. It also
// cannot be a CHILD of it: a derived profile may tighten but never loosen, so a fixed
// `#order` and a required binding are not recoverable downstream. This is a SIBLING,
// derived from base R4 ServiceRequest, and the order profile is untouched: laboratory and
// imaging keep their guarantees, and no published canonical changes meaning.
//
// The id takes the bare `nexus-*` form rather than `nexus-emr-*`: new artifacts do not
// take the `-emr-` infix, which is on its way out.
//
// See the handbook (guide/features/referrals/overview.md) for the relationship to the
// Ontario eReferral / CA-eReC contract and to what Ocean actually sends.
//
// OCEAN IDENTIFIER SYSTEMS ARE NOT GOVERNED HERE, AND THE EXAMPLE USES A SANDBOX ONE. A referral
// arriving from Ocean carries identifiers under Ocean's own NamingSystems, on the host of the Ocean
// environment the tenant is provisioned against. This specification neither publishes nor resolves
// those addresses. The published example names `test.cognisantmd.com`, which is a SANDBOX host
// shown for shape -- it is the only Ocean host anywhere in this guide, so there is nothing here for
// a reader to infer a production address from, and it must not be copied into one. Take the address
// from the Ocean environment, not from this guide.
Alias: $NexusCoreReferral = ../StructureDefinition/nexus-core-referral
// A referral is legible even when nothing recognises its coded values, the same floor the
// order profile holds with `code.text 1..1`. It cannot be stated the same way here,
// because the referrals Nexus receives carry no `code` element at all -- so the rule is
// conditional rather than absent.
Invariant: referral-code-has-text
Description: "When code is present it SHALL carry text, so the requested service stays legible when no coded value is recognised"
Severity: #error
Expression: "code.exists() implies code.text.exists()"
// The routing information. A referral whose destination is only free text cannot be routed,
// counted, or matched to a reply, so this is worth saying -- but it is a WARNING, on the same
// reasoning that made the `category` binding extensible rather than required: a rule that makes
// the referrals we actually receive non-conformant is enforcing our preferences, not the spec.
// Destinations arrive that have no usable code, and the right answer for one of those is to carry
// the text rather than map it to an approximate neighbour, because an approximate destination
// routes the patient approximately. At error severity this rule and that answer could not both be
// followed, and the handbook's Referrals page was telling implementers to do the thing the
// invariant rejected.
Invariant: referral-category-coded
Description: "At least one category SHOULD carry a SNOMED CT coding identifying the receiving service or specialty (recommended, not enforced: a destination with no usable code carries text instead)"
Severity: #warning
Expression: "category.coding.where(system = 'http://snomed.info/sct').exists()"
// Profile Definition
Profile: NexusCoreReferral
Parent: ServiceRequest
Id: nexus-core-referral
Title: "Referral Profile"
Description: "Defines the Nexus EMR FHIR profile for referrals: a request that another clinician or service accept the patient, for consultation, second opinion, or ongoing management. Aligned to the pan-Canadian CA-eReC / Ontario eReferral contract, which is the shape Nexus already exchanges with Ocean. Distinct from NexusEmrCoreServiceRequest, which governs laboratory, imaging and procedure ORDERS and fixes intent to `order`."
// THE effective date for this profile (see the EffectiveDate / NoEffectiveDate
// RuleSets): one date concept per resource, declared here rather than guessed.
* insert EffectiveDate([[authoredOn]])
// Same resource type as the order profile, so the same SMART permission surface.
* insert SmartExposed(servicerequest)
* ^url = $NexusCoreReferral // Canonical URL from alias
* ^status = #draft
* insert NoResourceNoteExtension
* obeys referral-code-has-text
* obeys referral-category-coded
// --- Element Constraints ---
* . ^short = "Nexus EMR Referral"
* . ^definition = """
A referral: a request that another clinician or service accept the patient, for
consultation, second opinion, or short- or longer-term management.
The referrer does not control whether the receiving service accepts. That is why
`intent` is `proposal` and not `order`, and it is the substantive difference between
this profile and NexusEmrCoreServiceRequest.
"""
* meta.source 0..1 MS
* meta.source ^short = "Identifies EMR instance & pipeline version the resource came from"
* meta.source ^definition = "A URI that identifies the EMR pipeline and version from which this resource originated. This tells you which EMR instance (recommend using the instance identifier), and the version of the pipeline code/transformations."
* text 0..1 MS
* text ^short = "Narrative"
* text ^definition = "A human-readable narrative summary of the referral for human interpretation."
* identifier 0..* MS
* identifier.system 1..1
* identifier.value 1..1
* identifier ^short = "Business identifier(s) for the referral"
* identifier ^definition = """
Unique identifiers for the referral.
A business identifier is recommended but not required (identifier is 0..*). Where
available, carry the source-system identifier using the most appropriate system URI. For
a referral received over Ontario eReferral this is the sending network's referral
reference, and preserving it is what lets a later status update or a returning consult
letter be matched to the referral it answers.
A source system's own identifier SHOULD be carried alongside this one, flagged `use = secondary`. See [Carrying the raw code](../guide/patterns/raw-codes.md).
"""
// --- Status ---
* status 1..1 MS
* status ^short = "draft | active | on-hold | revoked | completed | entered-in-error"
* status ^definition = "The state of the referral. `draft` written but not sent, `active` sent and awaiting the consult, `on-hold` waiting on something (imaging, bloodwork, patient contact), `revoked` declined or withdrawn, `completed` the consult happened."
* status ^comment = "This is a modifier element. A worklist showing what has been sent and not yet answered reads this element."
* status from http://hl7.org/fhir/ValueSet/request-status (required)
// --- Intent ---
// Fixed to `proposal`. This follows the interoperability contract Nexus is on; it is NOT a
// claim that FHIR requires it. Base R4 places no such rule on referrals, and HL7's own
// BSeR referral profile fixes `order` instead. What settles it here is that CA-eReC fixes
// `intent = proposal`, the Ontario eReferral profile derives from CA-eReC, and every
// referral Nexus receives from Ocean arrives as `proposal`.
//
// If Nexus ever takes on a non-Canadian referral contract, this is the element that gives
// first. The answer then is a looser parent with jurisdictional children, NOT a relaxation
// here -- relaxing a published fixed value silently changes what every existing instance
// claims.
* intent 1..1 MS
* intent ^short = "proposal"
* intent ^definition = "Fixed to `proposal`: a referral asks a receiving service to accept the patient and carries no authorization to act. Matches CA-eReC and the Ontario eReferral profile."
* intent ^comment = "A request the requester DOES have authority to have carried out is an order, not a referral, and belongs on NexusEmrCoreServiceRequest."
* intent = #proposal (exactly)
* intent from http://hl7.org/fhir/ValueSet/request-intent (required)
// --- Category: the receiving service or specialty ---
// 1..* rather than 1..1 so an inbound coding and a Nexus coding can both be carried
// without either being dropped. See the binding note below.
* category 1..* MS
* category ^short = "Receiving service or specialty"
* category ^definition = """
The healthcare service or clinical specialty the referral is directed to. This is the
routing information: it is what decides which service receives the referral, so a wrong
value here sends the patient to the wrong place.
The binding is EXTENSIBLE, not required, and that is deliberate. Live Ontario traffic
includes concepts outside this value set -- Ocean sends 17561000 |Cardiologist|, an
OCCUPATION concept, where the value set carries services and specialties -- and a required
binding would make the referrals we actually receive non-conformant.
Preserve the raw coding exactly as received and add the Nexus coding alongside it in
the same element. Do not rewrite or drop the original: it is the evidence of what the
sending system meant, and normalising it away loses the only record of that.
"""
* category from ../ValueSet/nexus-referral-service-type (extensible)
// --- Code: OPTIONAL, unlike the order profile ---
// The order profile requires `code` 1..1 with `code.text` 1..1. A referral cannot: the
// Ontario eReferral contract does not send `code` at all, and every referral Nexus
// receives from Ocean omits it. Requiring it would make live inbound traffic
// non-conformant. The legibility floor is preserved conditionally by
// referral-code-has-text instead.
//
// Deliberately left with the base R4 binding. CA-eReC binds `code` to Infoway's
// InterventionCodeSubsetCare, which Infoway RETIRED in April 2026 along with the Primary
// Health Care EMR Minimum Data Set, marking it "not recommended for continued use". We do
// not adopt a retired binding; when Infoway publishes its replacement this is the element
// to revisit.
* code 0..1 MS
* code ^short = "Specific requested service, when more precise than category"
* code ^definition = """
The particular service, procedure or question being requested, when it is known and more
specific than `category`.
Optional: the Ontario eReferral contract carries the routing information in `category` and
sends no `code`. Where Nexus authors a referral itself, populate this from the reason for
referral so the receiving clinician can see what is being asked without opening the letter.
Where this code was mapped from a source system's own vocabulary, carry the raw coding alongside the mapped one, flagged `userSelected = true`. See [Carrying the raw code](../guide/patterns/raw-codes.md).
"""
* subject 1..1 MS
* subject ^short = "The patient being referred"
* subject ^definition = "The patient for whom the referral is being made. Must reference using Nexus EMR patient identifier."
* subject only Reference(NexusEmrCorePatient)
// CA-eReC requires `requester`. A referral with no referrer cannot be replied to, and the
// consult letter that comes back has nothing to be addressed to.
* requester 1..1 MS
* requester ^short = "Who is making the referral"
* requester ^definition = "The clinician or organization making the referral. Required: a referral with no referrer cannot be answered, and loop closure has nothing to close against."
// DIVERGENCE FROM CA-eReC, recorded deliberately: CA-eReC makes `performer` 1..*. That
// profile governs electronic referral MESSAGING, where a destination is definitionally
// known. This profile also covers referrals recorded in the chart that were never sent
// electronically -- a dictated letter to a named consultant, or a referral whose target is
// still being chosen. Requiring `performer` would make those unrecordable.
* performer 0..* MS
* performer ^short = "The service or clinician the referral is directed to"
* performer ^definition = "The receiving service, clinician or organization. Optional rather than CA-eReC's 1..*, because Nexus also records referrals that were never sent electronically and referrals whose destination is not yet chosen. Populate it whenever the destination is known."
* encounter 0..1 MS
* encounter ^short = "Encounter in which the referral was created"
* encounter ^definition = "The encounter during which this referral was created. Optional but provides important clinical context."
* encounter only Reference(NexusEmrCoreEncounter)
* occurrence[x] 0..1 MS
* occurrence[x] ^short = "When the referred service should occur"
* occurrence[x] ^definition = "The date/time or period when the referred service should occur, where a timeframe has been specified."
* priority 0..1 MS
* priority ^short = "routine | urgent | asap | stat"
* priority ^definition = "How quickly the referral should be actioned. A referral worklist sorts on this: a suspected-cancer referral and a routine dermatology one do not wait in the same queue."
* reasonCode 0..* MS
* reasonCode ^short = "Why the referral is being made"
* reasonCode ^definition = "The clinical reason for the referral -- the question being asked of the receiving service. Where this code was mapped from a source system's own vocabulary, carry the raw coding alongside the mapped one, flagged `userSelected = true`. See [Carrying the raw code](../guide/patterns/raw-codes.md)."
* supportingInfo 0..* MS
* supportingInfo ^short = "Prior results, notes and documents sent with the referral"
* supportingInfo ^definition = "Resources sent alongside the referral to support it: prior investigations, relevant notes, the referral letter itself."
* note 0..* MS
* note ^short = "Free-text notes on the referral"
* authoredOn 1..1 MS
* authoredOn ^short = "Date the referral was authored"
* authoredOn ^definition = "When the referral was originally authored/created in the system."
* authoredOn ^comment = "This is the creation date, not when the referred service should be performed."