Skip to content

Subscription Profile

Canonical../StructureDefinition/nexus-emr-core-subscription
Statusdraft (experimental) · 1.26.0
BaseSubscription (constraint)
SourceFSH · JSON

Nexus EMR profile for Subscription (R4 criteria-based) -- server-side push notification registration managed by the subscription manager service. Infrastructure and a data-egress security surface: no effective date, and R4 gives it no identifier element. First pass; note the R5 redesign migration path.

TypedFhir API / Pydantic schema

The typed accessor surface Subscription exposes for Subscription — generated from this IG's compiled profile; each typed accessor has a validating raw-FHIR twin (xRaw) where marked. The three ports are parity-enforced.

The AI-facing shape: from typed_fhir.facade.generated.schemas import SubscriptionSchemamodel_json_schema() is a structured-output / tool definition; instantiating validates an extraction. Generated source.

class SubscriptionSchema(BaseModel):
    """AI-facing shape of the Subscription profile: the facade's typed accessor
    surface (curated + salient fields) as a pydantic model. `model_json_schema()` is a
    structured-output / tool schema; instantiating validates an extraction."""

    model_config = ConfigDict(extra="forbid")

    status: Literal["active", "error", "off", "requested"] | None = Field(
        None,
        description=(
            "requested | active | error | off. The status of the subscription, which marks the "
            "server state for managing the subscription. Note: `error` and `off` both mean "
            "notifications are NOT being delivered, and the server sets them itself (e.g. after "
            "repeated delivery failure). A manager service that created a subscription and "
            "assumes it is still live will miss events silently -- this element must be polled or "
            "watched, not set-and-forgotten. Subscription.status — 1..1"
        ),
    )
    end: FuzzyDate | None = Field(
        None,
        description=(
            "When the subscription expires. The time for the server to turn the subscription off. "
            "Note: An expiry, NOT an effective date -- see the NoEffectiveDate declaration above. "
            "SHOULD be set: an open-ended subscription is a permanent egress path that outlives "
            "the reason it was created. Subscription.end — 0..1"
        ),
    )
    reason: str | None = Field(
        None,
        description=(
            "Why this subscription exists. A description of why this subscription is defined. "
            "Note: Free text, required by R4, and worth taking seriously rather than filling with "
            "a placeholder: it is the only human-readable record of why an egress path was "
            "opened, and the first thing an audit asks. Subscription.reason — 1..1"
        ),
    )
    criteria: str | None = Field(
        None,
        description=(
            "The search expression selecting resources to notify on. An R4 search expression "
            "(e.g. `Observation?patient=123`) selecting the resources whose changes trigger a "
            "notification. ⚠ This is a security boundary, not just a filter. A broad criteria "
            "string (a resource type with no patient or category scoping) subscribes to the whole "
            "population of that type. Note: ⚠ NOT ENFORCED HERE, and not declared by this guide "
            "either. `criteria` remains `1..1` with no type or parameter invariant, so a criteria "
            "posted directly to a server is checked by whatever that server chooses to check. A "
            "criteria naming a parameter the server does not support may match nothing and fire "
            "never -- silently, and indistinguishably from a period in which nothing happened. "
            "That is the failure mode to design against when accepting a subscription from an "
            "untrusted writer: validate the string against the search surface the receiving "
            "server actually declares, rather than assuming it will be rejected. This API does "
            "not offer the Subscription type to applications; see the Subscriptions page in the "
            "guide for the criteria vocabulary a future surface would use and the limits that "
            "would apply to it. Subscription.criteria — 1..1"
        ),
    )
    channel: dict | None = Field(
        None,
        description=(
            "How notifications are delivered. Details where to send notifications when resources "
            "are received that meet the criteria. Subscription.channel — 1..1"
        ),
    )