HL7 FHIR Specification

repository·master·Indexed 20 days ago

https://github.com/hl7/fhir

Documentation for the HL7 FHIR specification, including the FHIR Specification Publisher tool for building the specification from spreadsheet data. It covers the publishing workflow, PR submission requirements, version mapping syntax in fhir.ini, FHIRPath extraction language, and recovery processes for FHIR Subscription notifications.

Tokens
2.9K
Snippets
8
Records
15
Agent score
73%

What's inside hl7-fhir

  1. What is FHIRPath and how is it used?

    master

    FHIRPath is a path-based extraction language optimized for FHIR resources. Unlike XPath, which operates on XML/JSON representations, FHIRPath operates on the logical content of resources. All operations result in a collection of Elements.

    Common use cases include:

    • Search parameter paths: Defining what content a parameter refers to.
    • Slicing discriminators: Indicating elements that define uniqueness.
    • Invariants in ElementDefinition: Applying co-occurrence and other rules.
    • Error message locations: Specifying locations in OperationOutcome.
    • URL templates: Used in Smart on FHIR's cds-hooks.
  2. Understand the FHIR specification publishing workflow

    master

    The publishing process is automated via CI pipelines based on the branch being used:

    1. Pull Requests: Opening a PR triggers a pipeline that uploads the build as a separate branch to build.fhir.org/branches. This allows for reviewing the accuracy of the build before merging.
    2. Master Branch: Once changes are merged to master, the master branch pipeline runs and uploads the successful build to the main build.fhir.org webpage.
    3. R4B Branch: Changes to the R4B branch are automatically detected and published to build.fhir.org/R4B.
  3. Requirements for PR submission (Hard Blocks)

    master

    The following rules are considered 'Hard Blocks' and will result in a CHANGES_REQUEST for every Pull Request (PR) that violates them:

    1. Jira Tracker Reference: Every PR must include a link to a Jira tracker item in the PR body that documents Working Group (WG) approval.
    2. Alignment with Jira: Changes must strictly align with what was authorized in the Jira ticket. Only minor adjustments for wording, grammar, or flow are permitted.
    3. Code Systems and Value Sets: Inline code systems must either be marked experimental=true or be bound to a code element. If these conditions are not met, the code system must be located in the Terminology Home Organization (THO) rather than the extension Implementation Guide (IG).
    4. Reference targetProfile usage: When a Reference type requires multiple targetProfile values, they must be expressed as multiple targetProfile entries on a single type.Reference element. Do not use duplicate type entries.
    5. Markdown Entities: Markdown files must only use XHTML entities (e.g., &, <). HTML entities (e.g., —) are not allowed.
  4. Use test certificates for FHIR implementations

    master

    The implementations/certificates/ directory contains test certificates intended for use during the FHIR build process or by other test FHIR implementations.

    Note that the RSA and DSA certificates are protected by a password.

    Password for RSA and DSA certificates: `fhir`
  5. Checklist for PR Authors

    master

    Before opening a Pull Request, authors should verify the following checklist to avoid rejection:

    • All new extensions have a Jira tracker link in the PR body showing WG approval.
    • Inline code systems are marked experimental, are bound to a 'code' element, or have a THO proposal reference.
    • Reference types use multiple targetProfile entries on a single element (not duplicate elements).
    • No HTML entities (e.g., —) in markdown narrative files.
    • Description text is original and not copied from another extension unchanged.
  6. Publish the FHIR specification locally

    master

    To build and publish the FHIR specification from a local environment, ensure your machine has at least 16 GB of RAM. You can use the Gradle wrapper or provided executable scripts.

    Using Gradle

    Run the following command from the project root:

    ./gradlew publish

    Note that the process typically takes approximately 20 minutes to complete.

    Using Executable Scripts

    If you prefer not to use the terminal directly, use the provided scripts:

    • Windows: publish.bat
    • macOS/Linux/Windows (Bash): publish.sh
  7. Select elements using FHIRPath paths

    master

    You can select elements by traversing their path. When evaluating an expression, there is a collection with one element in focus.

    Basic Selection

    • path.subPath.subPath: Selects all elements on the path.
    • path.value[x].subPath: Selects all kinds of values (polymorphic items).
    • path.valueQuantity.subPath: Selects only values that are of type Quantity.

    Special Paths

    • *: Any child.
    • **: Any descendant.
    • name*: Recursive use of the element.
    • $context: The original context.
    • $resource: The original container resource (useful for skipping contained resources).
    • $parent: The element that contains $context.

    Note: $resource and $parent are only allowed in invariants.

    Contextual Prefixing

    Expressions can be evaluated on a specific resource type by prefixing the path with the resource name:

    • telecom(use = 'phone').value: Evaluated on the current context.
    • Patient.telecom(use = 'phone').value: Only produces results when used on a Patient resource.
    telecom.value
    Patient.telecom(use = 'phone').value
  8. Configure version mapping in fhir.ini

    master

    The fhir.ini file uses specific sections to describe mappings between FHIR versions. The primary sections used for versioning are:

    • r4-r6-changes: Maps changes from R4 to R6 (includes R4B changes).
    • r5-r6-changes: Maps changes from R5 to R6.

    Each entry in these sections maps a single property from a Source (older version) to a Target (newer version).

  9. Recover from missing FHIR Subscription notifications (No Event)

    master

    If a subscriber experiences a heartbeat timeout (a period where no notifications are received), they should verify the subscription state by calling the $status operation on the Subscription resource. If the server returns a SubscriptionStatus with state: error, the subscriber must perform a recovery process:

    1. Query/Retrieve Data: Use standard FHIR REST requests to fetch any data that might have been missed during the silence.
    2. Reset Subscription: Send a request to the server to reset the subscription to an active state to resume normal operations.
    GET [base]/Subscription/[id]/$status
  10. Recover from skipped FHIR Subscription events

    master

    A subscriber can detect missing events by monitoring the eventsSinceSubscriptionStart value in incoming Notification Bundles. If a sequence gap is detected (e.g., receiving event 21 followed by event 23), the subscriber should initiate a recovery process:

    1. Query/Retrieve Data: Use standard FHIR REST requests to fetch the missing data (e.g., event 22).
    2. Reset Subscription: Send a request to the server to reset the subscription to an active state to ensure the sequence is synchronized.
  11. Handle deleted backbones with moving children in fhir.ini

    master

    When a backbone element (a child element) is deleted in a new version, but its children are moved up to the parent level, you must explicitly map the children to their new paths using the @ syntax. This prevents the children from being swallowed by the deletion of the parent.

    Example (Moving Subscription.channel children to the root):

    # The backbone itself is deleted, but children are moved
    Subscription.channel.type=@Subscription.channelType
    Subscription.channel.payload=@Subscription.contentType
  12. Handle merges and conditional splits in fhir.ini

    master

    The fhir.ini syntax does not have dedicated operators for merges (multiple old properties into one) or conditional splits (one old property into several). Instead, use a combination of New property notes on the target and Deletion mapping notes on the sources.

    Note: The diff engine does not support multiple maps to the same property (it treats them as moves). To implement a merge, follow this pattern:

    1. Add a + note to the new target property describing the merge.
    2. Add -> notes to each of the old source properties pointing to the new target.

    Example (Merging reasonCode and reasonReference into reason):

    CareTeam.reason=+ Merged both reasonCode and reasonReference into reason
    CareTeam.reasonCode=-> CareTeam.reason
    CareTeam.reasonReference=-> CareTeam.reason