Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

References/Diagnostic Report

From OHC Network Wiki
referenceclinicalFHIR: DiagnosticReportCARE 3.0+

A DiagnosticReport records the results and interpretation of a diagnostic test, tied to the ServiceRequest that ordered it. You create one to report on an investigation, then read it back with its observations, encounter, and requester embedded.

The Django model (care/emr/models/diagnostic_report.py) imposes no shape: it persists category and code as opaque JSONFields and status as a free CharField. Shape and validation come from the Pydantic resource specs (care/emr/resources/diagnostic_report/) — the status enum, the coded-concept structure, the bound value sets, and the separate read/write API schemas. The specs build on EMRResource and serialize between the API and the model.

Source:

Models

Model Purpose
DiagnosticReport Results and interpretation of a diagnostic test or investigation, tied to a ServiceRequest

DiagnosticReport extends EMRBaseModel, the shared Care EMR base that provides external_id, created_date/modified_date, soft-delete via deleted, created_by/updated_by, and history/meta JSON.

DiagnosticReport fields

Classification

Field Model type Spec shape Notes
status CharField(255) DiagnosticReportStatusChoices (enum, required) Lifecycle status. Stored as free text but constrained to the enum below on write. Optional on update.
category JSONField (null) Coding { system, version?, code, display? }, required Service section the report belongs to. code is validated against the Diagnostic Service Sections value set.
code JSONField (null) Coding { system, version?, code, display? }, optional The test or panel performed. code is validated against the Observation value set (LOINC). Nullable.

The Coding shape (from care/emr/resources/common/coding.py, extra="forbid"):

Field Type Required Notes
system str optional
version str optional
code str required
display str optional

Narrative

Field Model type Spec shape Notes
note TextField (null) None Free-text comments. Not parsed by the platform.
conclusion TextField (null) None Clinical interpretation/summary of the results. Not parsed by the platform.

Relationships

Field Type Notes
facility FK → facility.Facility PROTECT, nullable. Facility the report is scoped to. Set server-side; not a writable spec field.
patient FK → emr.Patient CASCADE. Subject of the report. Set server-side; not a writable spec field.
encounter FK → emr.Encounter CASCADE. Encounter the report was produced under. Set server-side; not a writable spec field.
service_request FK → emr.ServiceRequest CASCADE. The order this report fulfils. Write-only on create (resolved from external_id); excluded from base serialization via __exclude__.

Enum values

DiagnosticReportStatusChoices

From spec.py. (modified is defined in source but commented out and is not an active value.)

Value Meaning
registered Report exists / has been registered
partial Some results available, report incomplete
preliminary Provisional results pending verification
final Verified, complete report

Bound value sets

Coded fields validate their code against a registered Care value set (ValueSetBoundCoding). A code outside the bound set is rejected at deserialization.

Field Value set Slug Included system(s)
category Diagnostic Service Sections system-diagnostic-service-sections-code http://terminology.hl7.org/CodeSystem/v2-0074
code Observation system-observation http://loinc.org

Resource specs (API schema)

Every spec extends EMRResource (care/emr/resources/base.py) through DiagnosticReportSpecBase. serialize builds the read payload from the model (mapping external_idid); de_serialize writes spec fields back to the model. The perform_extra_serialization/perform_extra_deserialization hooks handle server-side behaviour — resolving foreign keys on write, embedding related resources on read.

Spec class Role Fields / behaviour
DiagnosticReportSpecBase shared base id?, status (enum, required), category (bound Coding, required), code? (bound Coding), note?, conclusion?. __model__ = DiagnosticReport, __exclude__ = ["service_request"].
DiagnosticReportCreateSpec write · create Base + service_request: UUID4 (required, the request's external_id). perform_extra_deserialization resolves it via get_object_or_404(ServiceRequest, external_id=...) and sets obj.service_request.
DiagnosticReportUpdateSpec write · update None). service_request is not writable on update.
DiagnosticReportListSpec read · list None. perform_extra_serialization sets id = external_id and embeds the linked request via BaseServiceRequestSpec.serialize(...).
DiagnosticReportRetrieveSpec read · detail Extends ListSpec + observations: list[dict], encounter: dict, created_by?, updated_by?, requester?. See serialization below.

DiagnosticReportRetrieveSpec.perform_extra_serialization (server-side, read)

The detail read enriches the list payload so a viewer gets the report, its observations, and its context in one call:

  • Calls the ListSpec hook (sets id, embeds service_request).
  • serialize_audit_users → populates created_by / updated_by from cache (UserSpec).
  • observations → all Observation rows where diagnostic_report == obj, each via ObservationRetrieveSpec.serialize(...).
  • requester → if service_request.requester_id is set, loaded from cache via UserSpec.
  • encounterEncounterListSpec.serialize(obj.encounter), with encounter["patient"] set to PatientRetrieveSpec.serialize(obj.encounter.patient, facility=obj.facility).

These embedded fields (service_request, observations, encounter, requester, audit users) are read-only and are not accepted on create/update.

DiagnosticReport is the only model defined in this file. It sits downstream of a ServiceRequest and is anchored to a patient and encounter:

diagnostic_report
  facility        → FK facility.Facility (PROTECT, nullable)
  patient         → FK emr.Patient (CASCADE)
  encounter       → FK emr.Encounter (CASCADE)
  service_request → FK emr.ServiceRequest (CASCADE)

Deleting a Patient, Encounter, or ServiceRequest cascades to its diagnostic reports; the facility link is PROTECTed. Routine deletes are soft, via EMRBaseModel. On retrieve, related Observation records are pulled in through the reverse FK (Observation.diagnostic_report).

Methods & save behaviour

  • Create (DiagnosticReportCreateSpec.de_serialize): writes status, category, code, note, conclusion onto the model; perform_extra_deserialization resolves service_request from its external_id (404 if missing). facility, patient, and encounter come from the request context in the view layer, not the payload.
  • Update (DiagnosticReportUpdateSpec): same base fields, but status is optional, so a partial status change is allowed. service_request cannot be reassigned.
  • Read (List/Retrieve): no model writes; all enrichment happens in perform_extra_serialization (see above). User and service-request lookups go through the serializer cache (model_from_cache).
  • Coded fields are validated at deserialization: category.code must be in the Diagnostic Service Sections value set; code.code (when present) must be in the Observation value set. status must be a DiagnosticReportStatusChoices value.

API integration notes

  • Diagnostic reports are exposed through Care's REST API and align with the FHIR DiagnosticReport resource; payload field names follow the spec classes above.
  • category and code are coded concepts (Coding: system/code/display), not free strings. Populate code from the bound value set — anything outside it is rejected, and Coding forbids extra keys.
  • status is stored as a free CharField, but the spec restricts writes to the DiagnosticReportStatusChoices enum (registered, partial, preliminary, final).
  • A report fulfils exactly one service_request. Create the References/Service Request first, then pass its external_id as service_request on create.
  • note and conclusion carry human-readable narrative and are not parsed by the platform.
  • The detail (Retrieve) payload embeds the linked service request, its requester, the encounter (with patient), audit users, and all child observations — none of which are writable.

Pages that link here:

Wiki: ohcnwiki.tellmey.fyi