Secondary Use FHIR Server Implementation Guide
0.1.0 - ci-build

Publish Box goes here

Implementation Notes

Implementation Notes

This page is non-normative. It explains how the current service implements the public behavior described in this guide.

Runtime Components

The application starts two Ktor/Netty servers:

  • MockFhirServer
  • BulkAdapterServer

Both use Jackson for HTTP JSON handling. FHIR resource parsing and serialization are handled through HAPI FHIR R4.

Mock FHIR Server

The mock server:

  1. loads or generates a named dataset through DatasetStore
  2. exposes health and metadata endpoints
  3. serves resource reads at /fhir/{resourceType}/{id}
  4. serves resource searches at /fhir/{resourceType}
  5. creates Bulk jobs at /fhir/$export
  6. serves status and NDJSON files through /fhir/bulk-status/{jobId} and /fhir/bulk-files/{jobId}/{file}
  7. deletes completed prototype jobs through DELETE /fhir/bulk-status/{jobId}

Search matching is implemented in code against the generated in-memory resources.

Bulk Privacy Adapter

The adapter:

  1. parses front query parameters into BulkCriteria
  2. rejects unsupported mode values
  3. returns count preview when _summary=count is present
  4. resolves the cohort through FhirSearchBackend
  5. fetches requested resources for the cohort
  6. applies PrivacyTransformer
  7. creates a Bulk job with transformed resources
  8. optionally posts a completion notification when notification-url is present
  9. exposes status and NDJSON output

This keeps the front API Bulk-shaped even when the backend only supports ordinary FHIR searches.

Query Translation

FhirSearchBackend owns the translation from front cohort criteria to backend FHIR searches.

It deliberately fans out multi-code filters into one search per code and merges results. This avoids relying on repeated-parameter semantics in a simple backend.

When several filter families are present, patient sets are intersected. That means a broad code family can be combined with a demographic or date filter without changing the output API.

Bulk Job Store

BulkStore groups resources by resourceType, assigns a random job ID, and can write job payloads to disk.

The status response contains one output entry per resource type with a download URL and stable bulk:// storage location. NDJSON output is generated by serializing each stored resource on its own line.

Named dataset runs persist mock and adapter Bulk jobs below:

<data-dir>/bulk-jobs/

The jobs still complete synchronously. Persistence and delete support exist for local repeatability, restart inspection, and cleanup, not production scheduling.

Privacy Transformer

PrivacyTransformer works on typed HAPI R4 resources.

The pseudonymized mode:

  • builds a patient ID map from exported Patient resources
  • rewrites patient IDs and references
  • removes direct Patient fields
  • shifts date fields by a deterministic offset

The minimized mode:

  • runs pseudonymization first
  • creates new compact resources containing only selected fields

Keeping This Guide Aligned

When runtime behavior changes, update these pages together: