Clinical validation profile
OPRP 0.1.0-dev.9 tightens the reference Host's six clinical profiles under the advertised identifier oprp-r4-clinical-2. Admission now checks selected R4 field shapes, calendar/time values, choice exclusivity, extension structure, status bindings and clinical invariants before committing any resource, history, operation receipt or change event. These checks apply to accepted writes and Host archive import verification.
This is a declared subset validator, not a complete FHIR R4, US Core, terminology or clinical-safety validator. Other Hosts can use stronger validators and advertise their supported profiles. The protocol continues to leave patient approval, standing permissions, representative authority and at-rest custody with the Host. No patient portal session is introduced by these checks.
Admission rules
The existing exact record ownership, server-assigned IDs, optimistic base version and unsupported-content rules remain in force. The reference Host admits only relative ownership Patient/<record ID>; explicit nested Patient references must point to that same record. It rejects attachments, photos, contained resources, derivedFrom and modifier extensions. Ordinary unknown fields and admitted ordinary extensions are retained. Non-patient reference targets are not resolved or comprehensively type-checked.
| Area | Implemented checks |
|---|---|
| Concepts and coding | Concept object, nonempty text or usable coding, nonempty supplied coding arrays, supplied coding field types, URI-shaped supplied systems and boolean userSelected. |
| References | Selected reference fields must be objects with a nonempty literal reference; whitespace/control characters are rejected. Display/type values must be strings. Identifier-only references are outside this slice. |
| Calendar/time | Gregorian calendar validity including leap years; year, month and date precision accepted for dateTime; a supplied time requires hours, minutes, seconds and offset. Hours/minutes/seconds and offsets are bounded. Host meta.lastUpdated requires a full timestamp. Leap-second :60 and fractions longer than nine digits are outside this reference slice. |
| Choice fields | At most one supported representation for onset, abatement, effective, performed, occurrence and note author; Immunization occurrence requires exactly one. Unsupported representations fail explicitly. |
| Period/range/quantity | Selected date endpoints, finite numbers, supported comparators, and ordered full timestamp endpoints; comparable range values are ordered. Mixed/partial temporal precision is shape-checked without assuming an ordering. |
| Metadata and notes | Metadata object, supplied version/time/profile/security/tag shapes; nonempty note arrays with string text and selected author/time fields. |
| Extensions | Nonempty extension arrays; URI-shaped URL; one value or nested extensions; selected primitive/coding/concept/reference/quantity values checked. Unknown complex value types must be objects and remain opaque. |
The source implementation is fhir-validation.ts, called by resource-profile.ts. The structural JSON schema is deliberately supplemental: it does not implement all calendar, extension-choice, terminology-binding or cross-field invariants. The handwritten admission validator remains the executable reference. Schema syntax checks alone are not semantic conformance testing.
Resource rules
| Resource | Additional checks |
|---|---|
| Condition | Supplied clinical/verification status uses one recognized coding from the respective R4 system. Abatement requires inactive, resolved or remission; entered-in-error verification forbids clinicalStatus. A problem-list category requires clinicalStatus unless entered-in-error. Selected onset/abatement forms and category concepts are checked. |
| AllergyIntolerance | Clinical status is required unless verification is entered-in-error; entered-in-error forbids it. Supplied clinical/verification status uses recognized R4 coding. Type, category, criticality and reaction severity enums are checked; every supplied reaction has a nonempty manifestation list. |
| MedicationStatement | Existing R4 status and medication concept requirements remain. Supplied effective time/period is exclusive and checked. MedicationReference is still unsupported. |
| Encounter | Existing R4 status/class requirements remain. Class coding, supplied period/type and status-history periods/enums are checked. |
| Procedure | Existing R4 status/code requirements remain. Supplied performed time/period/string/age/range is exclusive and checked. |
| Immunization | Existing status/vaccine/occurrence requirements remain. Date occurrence is validated, and supplied primarySource/isSubpotent must be booleans. |
Unknown ordinary fields are preserved but do not thereby become validated clinical semantics. Required bindings are checked for the selected status fields only; arbitrary clinical terminology systems are not expanded or clinically evaluated. Narrative HTML is not sanitized here and must be safely handled by consuming applications.
Compatibility and evidence
This evolving draft tightens admission. A resource or archive accepted by an earlier prototype may fail the new profile, especially an AllergyIntolerance without clinicalStatus. Operators must validate and explicitly reconcile existing data before upgrading; no silent data conversion or retroactive clinical status is invented. Resources already present are not rewritten during startup. Validation does not erase earlier histories.
The focused paging/mirror tests reject invalid dates, simultaneous choices, malformed coding, ambiguous extensions, missing Allergy status and Condition abatement/status inconsistencies without committing receipts. They also accept a leap-day timestamp and preserve an ordinary extension. The existing six-type history, archive, queue, subscription and migration tests continue to exercise the shared validator.
The design references FHIR R4 datatypes, Condition, AllergyIntolerance, MedicationStatement, Encounter, Procedure and Immunization. OPRP's narrower admission choices are its own reference profile.
Versioned StructureDefinitions and an optional external R4/US Core admission path are now implemented; see external clinical validation. The bounded validator remains active with or without that optional gate. Visibility adds field/security-label projection and cache generation invalidation.
Next: lock validator dependencies, add local terminology fixtures/services and durable intake scheduling.