# FHIR resource and interaction coverage

OPRP `0.1.0-dev.11` adds six clinical resource types to the existing Patient/laboratory slice. A requester can create, read, search, update, delete and retrieve versions/history under separate type-specific Host permissions. Accepted writes retain operation receipts, immutable versions and actor attribution, and participate in the same synchronization, notification, archive and migration workflows.

These are FHIR R4 resource structures carried inside OPRP encrypted operations. The reference implementation is not a general RESTful FHIR server or a US Core conformant service. It implements a declared, bounded subset, with selected structural, ownership, temporal and clinical invariant checks described in [clinical validation](clinical-validation.md). Exhaustive terminology/cardinality/profile validation remains open. [FHIR R4 interactions](https://hl7.org/fhir/R4/http.html) provide the design reference for read/vread, search, update, delete and history. Full FHIR conformance remains a release requirement.

## Supported clinical profiles

| Resource | Supported reference slice | Ownership field |
| --- | --- | --- |
| [Condition](https://hl7.org/fhir/R4/condition.html) | Patient-owned condition with a code/text concept. | `subject.reference` |
| [AllergyIntolerance](https://hl7.org/fhir/R4/allergyintolerance.html) | Patient-owned allergy/intolerance with a code/text concept and the admitted R4 clinical/verification status invariant. | `patient.reference` |
| [MedicationStatement](https://hl7.org/fhir/R4/medicationstatement.html) | Medication statement with R4 status and `medicationCodeableConcept`; referenced Medication resources are not admitted yet. | `subject.reference` |
| [Encounter](https://hl7.org/fhir/R4/encounter.html) | Encounter with R4 status and coded class. | `subject.reference` |
| [Procedure](https://hl7.org/fhir/R4/procedure.html) | Procedure with R4 status and code/text concept. | `subject.reference` |
| [Immunization](https://hl7.org/fhir/R4/immunization.html) | Immunization with R4 status, vaccine concept and exactly one occurrence date/string representation. | `patient.reference` |

Ownership must be the exact relative `Patient/<authorized record ID>` reference. Nested explicit Patient references must belong to the same record. The narrow profile rejects attachments, photos, contained resources, `derivedFrom` and unrecognized modifier extensions rather than silently dropping them. Ordinary unknown fields/extensions are preserved. Referenced non-patient resources are not fetched or clinically validated. Resource narratives must still be safely rendered by consuming applications.

Resource IDs use FHIR's bounded letter/digit/hyphen/period shape. The Host assigns IDs on create. `meta.versionId` and `meta.lastUpdated` are Host-owned; other admitted metadata/unknown fields are preserved. Existing Patient name updates and laboratory Observation creation/search retain their previous wire operations. Generic interactions in this increment apply to the six new types; broad Patient/Observation updates/deletes remain future work.

## Permissions and operations

Each new type has independent `patient/<Type>.rs`, `.c`, `.u` and `.d` permissions. Read/search permission also admits historical read/history in this experimental profile; requesters and Hosts must treat that as access to prior clinical content. A standing or conditional grant still follows [Host policy](authorization-model.md); no new patient login is required just because an access JWT expires.

| Protected operation | Required fields after common patient/access-token/type | Result |
| --- | --- | --- |
| `read_resource` | `resource_id`, `version` (null for current, positive integer for vread) | Authorized resource and version, or deleted/not-found error. |
| `search_resources` | Optional `limit`, `page_cursor` | Immutable patient/type searchset Bundle pages. |
| `resource_history` | `resource_id`; optional `limit`, `page_cursor` | Ordered immutable version pages with deletion flags and attribution. |
| `create_resource` | `resource`, stable `operation_id` | Metadata-only assigned ID, version and deletion flag. |
| `update_resource` | `resource_id`, complete replacement `resource`, `base_version`, stable `operation_id` | Metadata-only result; stale base version conflicts. |
| `delete_resource` | `resource_id`, `base_version`, stable `operation_id` | Metadata-only deletion marker with a new version. |

`resource_type` is required for every operation. A created resource has no supplied `id`; an update resource carries the exact existing ID and matching resource type/record owner. Updates replace the resource instead of merging arbitrary fields. Read-modify-write callers therefore preserve fields they intend to keep; there is no generic patch or transaction Bundle API in this increment.

Mutation replies include only `status`, `resource_type`, `resource_id`, `version` and `deleted`, including retries. This prevents write-only applications from recovering unrelated clinical fields through receipts. Reads require the corresponding read grant. The logical receipt key remains application/record/operation ID, so changing the request under a reused ID fails instead of corrupting the record.

## Version history and deletion

Clinical mutations atomically commit the current resource, immutable version, actor/application attribution, operation receipt, audit entry and change event. The history attribution contains `app`, optional `actor`, `accepted_at` and `operation_id`. It records protocol acceptance, not clinical authorship or verification of a practitioner's identity, and does not claim to be a complete FHIR Provenance resource.

Delete creates a new version and makes the resource absent from current search/snapshot results. The change feed emits `{resourceType, id}` with `kind: "deleted"` and a version; no clinical values appear in that marker. Current reads report `resource_deleted`. Earlier non-deleted versions remain available to authorized historical reads. History reports deletion versions without their retained clinical body. A deleted ID cannot be resurrected by an update in this profile.

Deletion is logical record state, not a physical erasure or a medical-record retention policy. The Host retains prior content for authorized history, export and retry recovery. Legal retention, erasure and country-specific policy remain Host/operator responsibilities. An expired or withdrawn grant cannot use history or recover a write receipt through a stale token.

## Synchronization, subscriptions and portability

Snapshot and change visibility include only the resource types admitted by current read scopes. New topics can be registered through [subscriptions](subscriptions.md), and their accepted updates/deletes schedule the same minimal encrypted hint. Read scope for one type grants no visibility into another type's events.

Archives containing the new types use `oprp-reference-r4-expanded`; legacy Patient/lab archives remain supported. The expanded manifest carries current entries, including retained deleted entries with `deleted: true`, and `clinical_history` with immutable versions/attribution. Per-entry digests, history continuity/current consistency, receipt binding and patient membership are validated by the Host importer. The overall `complete_history` flag remains false because legacy Patient/Observation and imported external histories are not complete.

Restore and live Host migration preserve these entries, versions, history, tombstones and operation receipts. A deletion accepted after baseline staging appears in the fenced final archive; activation restores its deleted state. A late unchanged create/update/delete retry recovers its original metadata result under new destination authorization. Source grants, keys, subscriptions and cursors are not transferred. See [portability](portability.md) and [Host migration](host-migration.md).

Stable paged search/history and scoped baseline enumeration are defined in [pagination and mirrors](pagination-mirrors.md). All three SDKs now include a durable reading mirror.

## SDK example

```ts
const created = await client.createResource(patient, {
  resourceType: 'Condition',
  subject: { reference: `Patient/${patient}` },
  code: { text: 'Synthetic condition' },
}, 'stable-create-id');
const current = await client.readResource(patient, 'Condition', created.resource_id);
await client.updateResource(patient, {
  ...current.resource,
  note: [{ text: 'Synthetic correction' }],
}, current.version, 'stable-update-id');
await client.deleteResource(patient, 'Condition', created.resource_id, 2, 'stable-delete-id');
```

Persist operation intent/ID before transmission. The TypeScript durable queue admits the same generic create/update/delete operations, stops on conflicts and preserves order. Python and .NET provide the equivalent interfaces and durable adapters/hooks; see [SDKs](sdks.md).

## Verification and remaining work

Nine focused [FHIR cases](../tests/fhir-resources.test.ts) cover all six types, extensions/version/history, scope/patient isolation, stale writes, unsupported content, tombstones, write-only replies, archive restoration, queue restart, new notification topics and actual live migration after baseline deletion. Seven focused [validation/paging/mirror tests](../tests/clinical-paging-mirror.test.ts) extend that coverage; the suite now contains 104 tests. Independent SDK conformance exercises the new Condition flow across compiled TypeScript, installed Python and installed .NET packages.

Remaining work includes complete R4/profile validation, US Core selection/conformance, FHIR Provenance/AuditEvent mapping, terminology validation, broader label policies/handling obligations, generic Patient/Observation mutations, streaming large reads/archives, attachments and atomic transaction/dependency semantics. The Host now applies field and exact-label visibility in addition to scopes; [visibility](visibility.md) explains partial views, protected writes and generations.

**Next:** deployable Host/storage operations, broader licensed terminology and attachments.

## External clinical validation update

The [external clinical validation guide](external-clinical-validation.md) supplies six versioned R4 profiles and selected US Core 9.0.0 targets. The [durable validation guide](durable-clinical-validation.md) adds full offline dependency locking, finite local terminology and restartable intake/migration jobs. Setup requires Java and a verified dependency-cache copy. Structural-only mode advertises disabled terminology; local mode rejects unavailable systems and does not include broad licensed clinical vocabularies. Host authorization and conditional patient approval remain separate.
