Flag Profile¶
| Canonical | ../StructureDefinition/nexus-emr-core-flag |
|---|---|
| Status | draft · 1.26.0 |
| Base | Flag (constraint) |
| Source | FSH · JSON |
Nexus EMR profile for Flag, carrying a singleton administrative free-text field about a patient (booking alert or patient note). The patient-flag-type coding discriminates the field; the free text rides on Flag.code.text. Backs the Patient Profile Notes section.
FSH
The authored source of truth: resources/StructureDefinition-nexus-emr-core-flag.fsh (edit on GitHub). One FSH file may define several related artifacts.
// NexusEmrCoreFlag.fsh
// Defines the Nexus EMR Flag profile — an administrative "sticky note" on the
// patient's chart. The Patient Profile "Notes" section stores its two
// singleton free-text fields (booking alert, patient note) as one active Flag
// each, discriminated by the patient-flag-type coding, with the free text on
// Flag.code.text. Flags are never edited in place or deleted: a text change
// retires the current Flag to inactive and creates a replacement, and a
// cleared field retires without one — a field's history is the chain of its
// retired flags. Flag is FHIR's official home for patient notes; no
// extensions are needed.
Alias: $NexusEmrCoreFlag = ../StructureDefinition/nexus-emr-core-flag
// Profile Definition
Profile: NexusEmrCoreFlag
Parent: Flag
Id: nexus-emr-core-flag
Title: "Flag Profile"
Description: "Nexus EMR profile for Flag, carrying a singleton administrative free-text field about a patient (booking alert or patient note). The patient-flag-type coding discriminates the field; the free text rides on Flag.code.text. Backs the Patient Profile Notes section."
* ^url = $NexusEmrCoreFlag // Canonical URL from alias
* ^status = #draft
* . ^short = "Nexus EMR Flag Core"
* . ^definition = """
An administrative "sticky note" about a patient: the booking alert (intended for booking
and banner surfaces) or the general patient note. At most one active Flag per patient-flag
type exists per patient; a field with no text stores no Flag at all.
"""
// THE effective date for this profile (see the EffectiveDate / NoEffectiveDate
// RuleSets): none. This model never populates `period` -- a field's history is the chain
// of its retired flags, ordered by resource history, not by a date on the Flag. Naming
// `period.start` here would declare an element nothing writes.
* insert NoEffectiveDate
// SMART on FHIR exposure -- this resource is reachable by an app, and these are the
// permissions each operation costs (see SmartExposed + the SmartExposed RuleSet).
* insert SmartExposed(flag)
* obeys nexus-flag-admin-is-a-field
* 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 // Narrative element with human-readable summary
* text ^short = "Narrative"
* text ^definition = "A human-readable narrative summary of the NexusEmrCoreFlag resource for human interpretation."
// -----------------------------------------
// Status — the soft-delete axis: active flags back the profile fields
// -----------------------------------------
* status MS
* status ^short = "active | inactive | entered-in-error"
* status ^comment = "Flags are never edited in place or deleted. The frontend writes active flags; a text change retires the current Flag to inactive (text kept) and creates a replacement, and clearing a field retires it without one — a field's history is the chain of its retired flags, and what was removed or superseded (and by whom, via resource history) stays queryable. Readers filter to active flags — a retired flag no longer backs its field. entered-in-error is reserved for retracting a flag recorded in error."
// -----------------------------------------
// Category — which kind of flag this is
// -----------------------------------------
//
// NOT PINNED TO `admin`, AND THAT CHANGED IN 1.26.0. This profile began as the carrier for the
// Patient Profile's two singleton administrative fields, and pinned `admin` because those were the
// only flags it modelled. A Flag is also FHIR's home for a clinical or safety alert -- high falls
// risk, difficult airway, aggressive in the waiting room -- and with `admin` pinned there was no
// conformant way to record one. A producer's only options were to assert `admin` about a suicide
// risk, which is false, or to leave the flag uncoded.
//
// ONE PROFILE, TWO KINDS, PARTITIONED BY AN INVARIANT. The administrative contract is unchanged and
// still enforced: an `admin` flag still carries a patient-flag-type coding and still carries its
// text, and `nexus-flag-admin-is-a-field` below is what holds that now the shape no longer can. A
// binding cannot be conditional on a sibling element, which is why this needs both halves -- the
// binding opens the vocabulary, the invariant partitions it. The same construction carries
// `Task.businessStatus`, for the same reason.
* category 1..* MS
* category ^short = "What kind of flag this is: clinical, safety, behavioral, contact or admin"
* category from http://hl7.org/fhir/ValueSet/flag-category (extensible)
* category ^comment = "R4's own category set. `admin` identifies the singleton Patient Profile fields this guide has always modelled and holds them to the rule below; every other category is an ordinary alert. Extensible rather than required: the set is R4's and a deployment may meet a kind it does not name."
// -----------------------------------------
// Code — what the flag says
// -----------------------------------------
//
// `coding` IS NO LONGER REQUIRED, and that is the point of the widening rather than a side effect.
// A clinical alert is very often free text a clinician typed, with no code behind it at all, and R4
// models exactly that: `Flag.code` is `1..1` CodeableConcept and its `coding` is `0..*`, so a
// concept carried as text alone is conformant. Requiring a coding here would have moved the problem
// rather than solved it -- a producer with no code would still have had to invent one.
* code 1..1 MS
* code ^short = "What the flag says: a coding, its text, or both"
* code.coding 0..* MS
* code.coding ^short = "A coding for the flag, where one exists. For an `admin` flag this is the patient-flag type"
* code.text 0..1 MS
* code.text ^short = "The flag in words. Required on an `admin` flag, where it carries the field's value"
// -----------------------------------------
// Subject — the patient the flag is about
// -----------------------------------------
* subject 1..1 MS
* subject ^short = "The patient the flag is about"
* subject only Reference(Patient)
Invariant: nexus-flag-admin-is-a-field
Description: "An administrative flag carries a patient-flag type and the field's text -- it is a singleton Patient Profile field, not a free alert"
Severity: #error
Expression: "category.coding.where(system = 'http://terminology.hl7.org/CodeSystem/flag-category' and code = 'admin').exists() implies (code.coding.where(system = '../CodeSystem/nexus-emr-patient-flag-type').exists() and code.text.exists())"