-
-
Notifications
You must be signed in to change notification settings - Fork 0
FHIR R5 Interoperability Layer
The interoperability layer is centered on two collaborating components: FHIRBundleBuilder and related functions in fhir/builders.py, which construct well-formed FHIR JSON resources and a CapabilityStatement; and FHIRStore in fhir/repository.py, which owns the in-memory persistence, versioning, and search behavior. The API layer never manipulates raw resource dictionaries directly — every request passes through the store's typed interface, which is what allows the resource-type/URL consistency check, version increment, and audit emission to be enforced in one place regardless of which route triggered them.
Figure 3 traces a create-then-update sequence end to end. On creation, FHIRStore validates that the URL's resource type matches the payload's resourceType field, assigns a server-generated identifier, sets meta.versionId to 1, and appends a corresponding entry to the audit chain before returning a 201 response with a weak ETag. On update, the client is expected to supply an If-Match header carrying the version it last observed; the store compares this against the currently stored versionId and raises a VersionConflict, mapped by the API layer to an HTTP 409 response with a FHIR OperationOutcome body, whenever the two disagree. This is the standard optimistic-concurrency pattern FHIR servers use to prevent silent lost updates when two clients race to modify the same resource, implemented here without a database transaction because the store itself is single-process and lock-protected.
sequenceDiagram
participant C as Client
participant Auth as APIKeyAuthenticator
participant R as FHIR Route
participant S as FHIRStore
participant A as AuditChain
C->>Auth: POST /fhir/R5/Patient (X-API-Key)
Auth-->>R: key verified (constant-time compare)
R->>S: create(resourceType, payload)
S->>S: validate resourceType == payload.resourceType
S->>S: assign server id, meta.versionId = 1
S->>A: append(action=create, resource=Patient/id)
S-->>R: resource, ETag W/"1"
R-->>C: 201 Created, ETag: W/"1"
C->>Auth: PUT /fhir/R5/Patient/id (If-Match: W/"1")
Auth-->>R: key verified
R->>S: update(id, payload, if_match="1")
alt version matches
S->>S: versionId += 1
S->>A: append(action=update, resource=Patient/id)
S-->>R: resource, ETag W/"2"
R-->>C: 200 OK, ETag: W/"2"
else version stale
S-->>R: raise VersionConflict
R-->>C: 409 Conflict, OperationOutcome
end
Figure 3. Sequence diagram of a FHIR create-then-update lifecycle, showing the authentication check, resource-type validation, version-conflict handling, and audit emission.
Because FHIRStore holds resources purely in process memory, its deep-copy discipline is what prevents a caller from mutating a resource through an aliased reference after it has been "persisted." The architecture documentation is explicit that this store is intentionally replaceable with a real FHIR repository, and that the project's data rules — synthetic data only, no PHI in contract state or events, opaque identifiers when integrating externally — apply to the repository and its CI as a whole, not merely to this one module.
MedIntelOS implements a narrow, exact-match search subset rather than the full FHIR search grammar (chained parameters, modifiers, _include/_revinclude, and so on). The /fhir/R5/metadata endpoint returns a CapabilityStatement generated from the same code that implements the behavior it describes, which is a meaningful correctness property: a CapabilityStatement is only useful to an integrating client if it does not overstate what the server can do, and generating it programmatically from the implemented route set is one concrete way to keep the two in sync.
Creating a synthetic FHIR Patient resource against the reference API illustrates the full request shape:
POST /fhir/R5/Patient HTTP/1.1
Content-Type: application/fhir+json
X-API-Key: <development key>
{"resourceType": "Patient", "name": [{"family": "Doe"}], "gender": "unknown"}HTTP/1.1 201 Created
ETag: W/"1"
Location: /fhir/R5/Patient/<generated-id>Table 2. FHIR capability status
| Capability | Status |
|---|---|
| Resource CRUD with server-assigned IDs | Implemented |
| Optimistic concurrency via If-Match / ETag | Implemented |
| CapabilityStatement generation | Implemented |
| Exact-match search subset | Implemented |
| Profile / StructureDefinition validation | Not implemented |
| Terminology binding and validation | Not implemented |
| Durable persistence across process restarts | Not implemented |
| Bulk Data / subscriptions / SMART App Launch | Not implemented |
The pattern that emerges — a correct, well-tested implementation of a deliberately narrow slice, paired with an accurate statement of what lies outside that slice — recurs in every subsequent pillar examined in this wiki.
Previous: ← System Architecture Overview · Next: The Clinical Decision Support Subsystem →
MedIntelOS · A Reference Architecture for Interoperable, Explainable, and Federated Clinical Software Systems
Introduction · Architecture · Security · Getting Started · Glossary · FAQ
Status: Alpha · Educational Reference Implementation — not a production EHR, not a certified FHIR server, not a medical device, and not evidence of regulatory compliance.
Licensed under the MIT License · github.com/Ciprian-LocalPulse/MedIntelOS
© 2026 MedIntelOS Contributors. This documentation is provided "as is," without warranty of any kind.