Skip to main content

Introduction

Overview

This section documents custom FHIR resources developed specifically for the Mona ICU project. These resources extend the standard FHIR specification to address domain-specific requirements that cannot be adequately modeled using core FHIR resources alone.

Custom resources are defined using FHIR Shorthand (FSH), compiled to FHIR JSON via SUSHI, and automatically deployed to Aidbox through a GitLab CI/CD pipeline.


Why Custom Resources?

While FHIR provides a comprehensive set of resources for healthcare data exchange, certain clinical workflows require specialized data structures. Custom resources enable:

  • Domain-specific modeling: Capture concepts unique to intensive care workflows
  • Simplified data access: Avoid complex workarounds with extensions and contained resources
  • Type safety: Define strict validation rules via FHIR constraints
  • Searchability: Custom SearchParameters for efficient querying

Example Use Cases

Custom ResourcePurpose
SubEncounterTemporal subdivision of hospital encounters for phase-specific reporting
SubEncounterLinkVersionable associations between SubEncounters and clinical resources

Development Workflow

The following diagram illustrates the end-to-end workflow for defining, compiling, and deploying custom FHIR resources:

Step-by-Step Process

  1. Write FSH Definitions in fsh/input/fsh/ directory
  2. Configure SUSHI settings in sushi-config.yaml
  3. Compile locally using npm run build to validate syntax
  4. Commit and push to the Git repository
  5. Automated deployment via GitLab CI/CD to Aidbox

FHIR Shorthand (FSH)

What is FSH?

FHIR Shorthand (FSH) is a domain-specific language designed for authoring FHIR artifacts. It provides a compact, human-readable syntax that simplifies the creation of:

  • StructureDefinitions (profiles, extensions, logical models)
  • ValueSets and CodeSystems
  • SearchParameters
  • Examples

Advantages Over JSON/XML

AspectFSHFHIR JSON/XML
ReadabilityHigh - concise, declarative syntaxLow - verbose nested structures
MaintainabilityEasy to diff and review in GitDifficult to track changes
Type safetyBuilt-in validation rulesManual constraint validation
Learning curveModerate - requires FSH knowledgeLow for JSON, but complex FHIR knowledge needed

Example Comparison

FHIR JSON (verbose):

{
"resourceType": "StructureDefinition",
"id": "SubEncounter",
"url": "http://mona.icu/StructureDefinition/SubEncounter",
"name": "SubEncounter",
"status": "active",
"kind": "resource",
"abstract": false,
"type": "SubEncounter",
"baseDefinition": "http://hl7.org/fhir/StructureDefinition/DomainResource",
"differential": {
"element": [
{
"id": "SubEncounter.encounter",
"path": "SubEncounter.encounter",
"min": 1,
"max": "1",
"type": [{"code": "Reference", "targetProfile": ["http://hl7.org/fhir/StructureDefinition/Encounter"]}]
}
]
}
}

FSH (concise):

Logical: SubEncounter
Id: SubEncounter
* ^url = "http://mona.icu/StructureDefinition/SubEncounter"
* ^status = #active
* encounter 1..1 Reference(Encounter) "Parent Encounter"

SUSHI Compiler

What is SUSHI?

SUSHI ("SUSHI Unshortens SHorthand Inputs") is the reference implementation compiler for FSH. It converts FSH definitions into standard FHIR JSON resources.

Key Features

  • Automatic generation of StructureDefinitions, SearchParameters, ValueSets
  • Validation of FSH syntax and FHIR conformance
  • Dependency management for FHIR packages
  • Snapshot generation for profiles

Configuration

SUSHI is configured via sushi-config.yaml:

canonical: http://mona.icu
status: active
version: 1.0.0
fhirVersion: 4.0.1

FSHOnly: true
applyExtensionMetadataToRoot: false
SettingPurpose
canonicalBase URL for all generated resources
fhirVersionTarget FHIR specification version
FSHOnlySkip IG publication (we only need JSON output)

Running SUSHI

# Install dependencies
npm install

# Compile FSH to FHIR JSON
npm run build

# Output appears in: fsh/fsh-generated/resources/

GitLab CI/CD Pipeline

Pipeline Overview

The GitLab CI/CD pipeline automatically deploys FHIR resources to Aidbox whenever changes are pushed to the repository. The pipeline:

  1. Installs dependencies (Node.js, SUSHI, HURL)
  2. Compiles FSH definitions to FHIR JSON
  3. Uploads all generated resources to the configured Aidbox instance
Pipeline Configuration

For the current pipeline implementation, refer to .gitlab-ci.yml in the mona3-fhir-definitions repository. The pipeline configuration may evolve over time.

Pipeline Flow

Upload Mechanism

The pipeline iterates through all generated FHIR JSON files and uploads them to Aidbox using PUT requests (upsert operation). This ensures that resources are created if they don't exist, or updated if they do.

Implementation Details

For the current implementation, see the upload-resources.sh script and .gitlab-ci.yml in the mona3-fhir-definitions repository.

PUT vs POST

The pipeline uses PUT requests to upload resources. This performs an upsert operation (create or update), ensuring idempotency. Resources are never deleted automatically—only created or modified.


Aidbox Deployment

Resource Lifecycle

Important Deployment Rules

RuleExplanation
Resources are never deletedRemoving a .fsh file does NOT delete the resource from Aidbox
Updates are idempotentRe-deploying the same definition is safe
IDs must be stableChanging a resource's id creates a new resource (orphaning the old one)
Manual cleanup requiredTo remove obsolete resources, use Aidbox UI or API

Deployment Environments

The pipeline supports deployment to different Aidbox instances via environment variables:

VariablePurposeExample
AIDBOX_URLTarget Aidbox server URLhttps://dev.aidbox.app
AIDBOX_AUTHBasic auth credentials (base64)client:secret

Override during manual pipeline runs:

  • Navigate to GitLab → CI/CD → Pipelines → Run Pipeline
  • Provide aidbox_url and aidbox_auth as input parameters

Adding New Custom Resources

Step-by-Step Guide

  1. Create FSH file in fsh/input/fsh/:
# Example: Creating a new resource
cd /path/to/mona3-fhir-definitions
touch fsh/input/fsh/MyCustomResource.fsh
  1. Define the resource using FSH syntax:
Logical: MyCustomResource
Id: MyCustomResource
Title: "My Custom Resource"
Description: "Description of what this resource represents"
* ^url = "http://mona.icu/StructureDefinition/MyCustomResource"
* ^status = #active
* ^kind = #resource
* ^type = "MyCustomResource"

* identifier 0..* Identifier "Business identifier"
* status 1..1 code "active | inactive | entered-in-error"
* subject 1..1 Reference(Patient) "Patient reference"
  1. Add SearchParameters (if needed):
Instance: mycustomresource-status
InstanceOf: SearchParameter
Usage: #definition
* url = "http://mona.icu/SearchParameter/mycustomresource-status"
* name = "MyCustomResourceStatus"
* status = #active
* description = "Search by status"
* code = #status
* base = #MyCustomResource
* type = #token
* expression = "MyCustomResource.status"
  1. Compile locally to validate:
npm run build

Check for errors in the terminal output. Generated files appear in fsh/fsh-generated/resources/.

  1. Review generated JSON:
cat fsh/fsh-generated/resources/StructureDefinition-MyCustomResource.json
  1. Commit and push:
git add fsh/input/fsh/MyCustomResource.fsh
git commit -m "Add MyCustomResource custom resource"
git push
  1. Monitor pipeline:

Navigate to GitLab → CI/CD → Pipelines to verify successful deployment.


Local Development Workflow

Prerequisites

Setup

# Clone repository
git clone <repository-url>
cd mona3-fhir-definitions

# Install dependencies
npm install

Development Loop

Testing Changes Locally

You can upload resources manually without triggering the pipeline:

# Set environment variables
export AIDBOX_URL="https://dev.aidbox.app"
export AIDBOX_AUTH="client:secret"

# Upload all resources
npm run upload

# Or upload a single resource manually
curl -X PUT \
-H "Authorization: Basic $(echo -n 'client:secret' | base64)" \
-H "Content-Type: application/json" \
-d @fsh/fsh-generated/resources/StructureDefinition-MyResource.json \
https://dev.aidbox.app/StructureDefinition/MyResource

Best Practices

FSH Authoring

Do:

  • Use descriptive resource and element names
  • Add comprehensive descriptions to all elements
  • Define invariants for business rules
  • Group related resources in the same file

Don't:

  • Hardcode version numbers in individual resources (use sushi-config.yaml)
  • Create overly complex nested structures (consider separate resources instead)
  • Forget to define SearchParameters for queryable fields

Version Control

Do:

  • Commit FSH source files, not generated JSON
  • Write clear commit messages explaining changes
  • Use feature branches for major changes

Don't:

  • Commit fsh/fsh-generated/ directory (it's in .gitignore)
  • Make breaking changes to production resources without versioning

Deployment

Do:

  • Test FSH compilation locally before pushing
  • Monitor pipeline logs for upload errors
  • Document custom resources in this documentation site

Don't:

  • Push directly to main without review (use merge requests)
  • Deploy to production Aidbox without testing in dev/staging first
  • Assume deleted FSH files are removed from Aidbox automatically

Troubleshooting

Common Compilation Errors

Error MessageCauseSolution
Unrecognized keywordInvalid FSH syntaxCheck FSH specification
Cardinality mismatchElement cardinality violates base definitionAdjust min..max values
Unknown typeReferenced resource type doesn't existVerify resource name spelling

Pipeline Failures

Error: AIDBOX_URL environment variable is not set

Solution: Configure AIDBOX_URL and AIDBOX_AUTH in GitLab CI/CD settings (Settings → CI/CD → Variables)

Error: 401 Unauthorized during upload

Solution: Verify AIDBOX_AUTH credentials are correct and have write permissions

Error: 422 Unprocessable Entity from Aidbox

Solution: The FHIR resource is invalid. Check Aidbox logs for detailed validation errors.

Viewing Uploaded Resources

Access Aidbox UI:

  1. Navigate to Aidbox instance URL
  2. Go to REST Console or Database tab
  3. Query resources:
GET /StructureDefinition?url=http://mona.icu/StructureDefinition/SubEncounter

Resources and References

External Documentation

Repository

Support

For questions about custom resources or the FSH workflow, contact the FHIR implementation team or open an issue in the repository.