Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions docs/FHIR_R4_MINIMUM_DATASET.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Synthetic FHIR R4 minimum dataset (review draft)

**Status:** review draft, 2026-10-22. Synthetic data only. This is a proposal for discussion under [issue #7](https://github.com/PubInv/GDP2-project-85/issues/7), not an approved clinical dataset, profile, use case, or architecture.

The repository currently accepts five resource types and checks that an input is a JSON object, has a supported `resourceType`, has a non-empty `id` when supplied, is JSON-serializable, and is no larger than 256 KiB. The request body limit is 512 KiB. Those checks do not validate FHIR R4 element cardinalities, value sets, terminology membership, reference resolution, profiles, or clinical meaning. See `src/domain/fhir.ts` and the README.

These examples use the FHIR R4 (4.0.1) resource shapes and standard terminology identifiers as a review starting point. They are not yet run through a full FHIR validator. Validate the selected code systems and versions, and profile constraints, before treating any example as conformant. A terminology code and display are illustrative; a real implementation must use the selected terminology release and check code/display consistency.

## Files

The five individual JSON fixtures are in `examples/fhir-r4-minimum/`:

- `allergy-intolerance.json`
- `condition.json`
- `immunization.json`
- `medication-statement.json`
- `observation.json`

All use the same fictional references: `Patient/synthetic-patient-001` and `Practitioner/synthetic-clinician-a`. The relative references are syntactically illustrative but intentionally do not bundle Patient or Practitioner resources, since those resource types are outside this POC's supported set. A future conformance test must resolve them against synthetic test resources or a controlled test endpoint. No demographic search or actual patient identity is implied. `meta.source` identifies a fictional source system; it does not identify the author.

## Compact data dictionary

| Element | Proposed meaning / constraint | Example |
|---|---|---|
| `resourceType` | One of the five resource types accepted by this POC | `Observation` |
| `id` | Synthetic FHIR logical id; no real-world identifier | `synthetic-observation-001` |
| `meta.source` | URI for fictional source system; not a facility identity or author assertion | `urn:synthetic:system:clinic-a` |
| `patient` / `subject` | Consistent relative reference to a synthetic Patient | `Patient/synthetic-patient-001` |
| `recorder`, `performer.actor`, `informationSource` | Consistent relative reference to synthetic Practitioner where the resource supports the element | `Practitioner/synthetic-clinician-a` |
| `code.coding.system`, `code`, `display` | Coding from a named standard system; verify membership and display against a pinned release | SNOMED CT, LOINC, CVX, RxNorm |
| `status` and clinical status fields | FHIR R4 codes with resource-specific value sets | `Immunization.status = completed` |
| `effectiveDateTime`, `occurrenceDateTime`, `recordedDate` | Synthetic event or assertion time; do not conflate clinical time with system ingestion time | 2026-10-21 |
| provenance sidecar (proposal below) | Author, source facility, and recording time associated with each fixture; not currently stored as a FHIR Provenance resource by the POC | `Practitioner/synthetic-clinician-a` |

The candidate code systems are SNOMED CT (`http://snomed.info/sct`), LOINC (`http://loinc.org`), CVX (`http://hl7.org/fhir/sid/cvx`), RxNorm (`http://www.nlm.nih.gov/research/umls/rxnorm`), and the relevant HL7 FHIR code systems shown in the examples. Proposed constraints for review: require a system and code for each coded clinical concept in the minimum dataset; reject an unknown code or a mismatched display in a terminology-aware test; do not treat free-text alone as coded interoperability. Pin terminology versions and jurisdictional value sets before adopting these constraints.

## Provenance proposal

FHIR clinical resources do not share one universal author/facility field. These fixtures use `meta.source` only for a fictional source system. [`provenance-proposal.json`](../examples/fhir-r4-minimum/provenance-proposal.json) is a separate R4-shaped candidate: it targets the five resources, uses `recorded` for assertion time, identifies the clinician in `agent.who`, and the fictional facility in `agent.onBehalfOf`. It is not included in the supported fixture set and the POC rejects `resourceType: Provenance`. A future mapping could use `entity` for source material when appropriate.

The prototype separately creates its own signed provenance event with `recordedAt`, `clinicianId`, resource type, content hash, and parent links. It does not currently store a FHIR facility/encounter source or a clinical author reference in that event. A future crosswalk must be reviewed before claiming equivalence between the prototype event and FHIR Provenance.

## Identifier, reference, and version rules to review

1. Keep FHIR `id` values synthetic, stable within a fixture, and free of personal data. Do not put names, birth dates, contact details, or real identifiers in `identifier`.
2. Use only the shared synthetic Patient and Practitioner logical references shown above in this first fixture set. Define whether the eventual validator resolves relative references against a test Bundle, a test server, or a local reference map.
3. Reject malformed reference strings and references to unapproved resource types in the future conformance suite; test unresolved references separately from malformed references.
4. Treat an update as a new version/history event; do not silently overwrite provenance or claim that a FHIR server version identifier is already managed by this POC. The exact versioning and correction workflow needs team approval.
5. Do not add a demographic lookup or expose a real patient identifier to make reference resolution work.

## Validation matrix

“Prototype result” below describes the existing generic validator, not an R4 validator. “R4 test expectation” is a proposed conformance-test result once a versioned R4 validator, terminology support, and reference resolver are selected.

| Case | Input / mutation | Existing prototype | Proposed FHIR R4 test expectation |
|---|---|---|---|
| P1 | Each of the five checked-in fixtures as an individual resource | Accepts if JSON shape and size limits pass | Pass base R4 checks after reference resolution and terminology validation |
| P2 | Supported resource with required element removed (e.g. `Immunization.patient`) | **Accepts**; required R4 cardinality is not checked | Reject |
| P3 | Invalid resource-specific code (e.g. `Immunization.status = "active-ish"`) | **Accepts**; value sets are not checked | Reject |
| P4 | Malformed reference (e.g. `Patient/`) or unresolved `Patient/unknown` | **Accepts**; references are not parsed or resolved | Reject malformed; report unresolved distinctly |
| P5 | Coded concept has unknown system/code or incompatible display | **Accepts**; terminology is not checked | Reject or flag according to approved binding strength and terminology policy |
| P6 | `resourceType: "Provenance"` | Rejects as unsupported | Not submitted to the current POC endpoint; validate as a separate R4 resource if adopted |
| N1 | Unsupported type such as `Patient` | Rejects | Reject at the POC supported-type boundary |
| N2 | Empty `id` | Rejects | Reject |
| N3 | Non-JSON value / `undefined` in a programmatic input | Rejects | Reject before serialization |
| N4 | Serialized resource above 256 KiB | Rejects | Reject at the POC size boundary |
| N5 | Malformed request JSON or body above 512 KiB | Rejected by request parsing/size boundary | Reject before resource validation |

The POC's generic validator currently has a small automated test in `test/fhir.spec.ts` for supported types and unsupported/non-JSON input. Rows P2–P5 are specifically useful regression cases because they demonstrate gaps that must be closed by a separate FHIR validation layer; they are not tests the current validator already passes or rejects.

## Approval and follow-up needed

- Confirm whether the initial clinical scenario and target users are approved. [Issue #5](https://github.com/PubInv/GDP2-project-85/issues/5) still requires clinical stakeholder confirmation and team sign-off. This draft does not select its two-clinic proposal as the finalized workflow.
- Confirm the minimum profile: base FHIR R4 4.0.1 only, or a project-specific implementation guide and required elements.
- Confirm clinical terminology systems, pinned versions, jurisdictions, and binding strengths, especially for medication, allergy, and vaccine data.
- Approve the patient/practitioner/facility reference strategy, identifier policy, correction/version rules, and whether a FHIR Provenance resource is in scope.
- Evaluate validator and OpenMRS-compatible endpoint options as issue #7 requests. No validator or endpoint is selected here.
- Review the existing four use cases in [issue #10](https://github.com/PubInv/GDP2-project-85/issues/10); they are not reproduced here.

## Source notes

- [FHIR R4 AllergyIntolerance](https://hl7.org/fhir/R4/allergyintolerance.html), [Condition](https://hl7.org/fhir/R4/condition.html), [Immunization](https://hl7.org/fhir/R4/immunization.html), [MedicationStatement](https://hl7.org/fhir/R4/medicationstatement.html), and [Observation](https://hl7.org/fhir/R4/observation.html).
- [Project README](https://github.com/PubInv/GDP2-project-85/blob/main/README.md), [issue #7](https://github.com/PubInv/GDP2-project-85/issues/7), [issue #5](https://github.com/PubInv/GDP2-project-85/issues/5), and [issue #10](https://github.com/PubInv/GDP2-project-85/issues/10).
43 changes: 43 additions & 0 deletions examples/fhir-r4-minimum/allergy-intolerance.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"resourceType": "AllergyIntolerance",
"id": "synthetic-allergy-001",
"meta": {
"source": "urn:synthetic:system:clinic-a"
},
"clinicalStatus": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/allergyintolerance-clinical",
"code": "active"
}
]
},
"verificationStatus": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/allergyintolerance-verification",
"code": "confirmed"
}
]
},
"type": "allergy",
"category": ["food"],
"criticality": "low",
"code": {
"coding": [
{
"system": "http://snomed.info/sct",
"code": "227493005",
"display": "Cashew nuts"
}
],
"text": "Cashew nuts"
},
"patient": {
"reference": "Patient/synthetic-patient-001"
},
"recordedDate": "2026-10-21T14:00:00Z",
"recorder": {
"reference": "Practitioner/synthetic-clinician-a"
}
}
48 changes: 48 additions & 0 deletions examples/fhir-r4-minimum/condition.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"resourceType": "Condition",
"id": "synthetic-condition-001",
"meta": {
"source": "urn:synthetic:system:clinic-a"
},
"clinicalStatus": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/condition-clinical",
"code": "active"
}
]
},
"verificationStatus": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/condition-ver-status",
"code": "confirmed"
}
]
},
"category": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/condition-category",
"code": "encounter-diagnosis",
"display": "Encounter Diagnosis"
}
]
}
],
"code": {
"coding": [
{
"system": "http://snomed.info/sct",
"code": "39065001",
"display": "Burn of ear"
}
],
"text": "Small burn on left outer ear (synthetic example)"
},
"subject": {
"reference": "Patient/synthetic-patient-001"
},
"onsetDateTime": "2026-10-21"
}
30 changes: 30 additions & 0 deletions examples/fhir-r4-minimum/immunization.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"resourceType": "Immunization",
"id": "synthetic-immunization-001",
"meta": {
"source": "urn:synthetic:system:clinic-a"
},
"status": "completed",
"vaccineCode": {
"coding": [
{
"system": "http://hl7.org/fhir/sid/cvx",
"code": "104",
"display": "Hep A-Hep B vaccine"
}
],
"text": "Synthetic example vaccine"
},
"patient": {
"reference": "Patient/synthetic-patient-001"
},
"occurrenceDateTime": "2026-10-21",
"primarySource": true,
"performer": [
{
"actor": {
"reference": "Practitioner/synthetic-clinician-a"
}
}
]
}
25 changes: 25 additions & 0 deletions examples/fhir-r4-minimum/medication-statement.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"resourceType": "MedicationStatement",
"id": "synthetic-medication-statement-001",
"meta": {
"source": "urn:synthetic:system:clinic-a"
},
"status": "active",
"medicationCodeableConcept": {
"coding": [
{
"system": "http://www.nlm.nih.gov/research/umls/rxnorm",
"code": "358793",
"display": "Mometasone Furoate 0.05 mg/actuation"
}
]
},
"subject": {
"reference": "Patient/synthetic-patient-001"
},
"effectiveDateTime": "2026-10-21",
"dateAsserted": "2026-10-21T14:00:00Z",
"informationSource": {
"reference": "Practitioner/synthetic-clinician-a"
}
}
38 changes: 38 additions & 0 deletions examples/fhir-r4-minimum/observation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"resourceType": "Observation",
"id": "synthetic-observation-001",
"meta": {
"source": "urn:synthetic:system:clinic-a"
},
"status": "final",
"category": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/observation-category",
"code": "vital-signs",
"display": "Vital Signs"
}
]
}
],
"code": {
"coding": [
{
"system": "http://loinc.org",
"code": "8310-5",
"display": "Body temperature"
}
]
},
"subject": {
"reference": "Patient/synthetic-patient-001"
},
"effectiveDateTime": "2026-10-21T14:00:00Z",
"valueQuantity": {
"value": 36.8,
"unit": "Cel",
"system": "http://unitsofmeasure.org",
"code": "Cel"
}
}
41 changes: 41 additions & 0 deletions examples/fhir-r4-minimum/provenance-proposal.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"resourceType": "Provenance",
"id": "synthetic-provenance-001",
"meta": {
"source": "urn:synthetic:system:clinic-a"
},
"target": [
{
"reference": "AllergyIntolerance/synthetic-allergy-001"
},
{
"reference": "Condition/synthetic-condition-001"
},
{
"reference": "Immunization/synthetic-immunization-001"
},
{
"reference": "MedicationStatement/synthetic-medication-statement-001"
},
{
"reference": "Observation/synthetic-observation-001"
}
],
"recorded": "2026-10-21T14:05:00Z",
"activity": {
"text": "Synthetic record assertion"
},
"agent": [
{
"type": {
"text": "Author"
},
"who": {
"reference": "Practitioner/synthetic-clinician-a"
},
"onBehalfOf": {
"reference": "Organization/synthetic-clinic-a"
}
}
]
}
Loading