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

References/Observation

From OHC Network Wiki
referenceclinicalFHIR: ObservationCARE 3.0+

An Observation is one named, coded data point about a subject — almost always a patient: a blood pressure reading, a temperature, a coded answer captured through a questionnaire. main_code records what was observed (usually bound to LOINC) and value holds the result. You rarely create one by hand; most observations are materialized when a questionnaire is submitted.


The model is just storage; several fields are opaque JSONFields. Their real structure lives in the Pydantic resource specs under care/emr/resources/observation/, which own the enums, nested JSON shapes, validation, and the read/write schema split. Each field row below gives the storage column first, then the shape the spec enforces on top of it.


Models

Model Purpose
Observation A single coded measurement or finding about a patient, captured within an encounter

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

Observation fields

Classification & coding

Field Storage type Spec shape / notes
status CharField(255) Enum ObservationStatusfinal, amended, entered_in_error. Required in specs. Questionnaire-sourced observations land as final
is_group BooleanField Default False. True marks a grouping/panel observation that holds component/child observations instead of a single value. Not exposed in the resource specs
category JSONField (default {}) Spec: optional Coding { system?, version?, code, display? }. FHIR observation category, derived from the questionnaire
main_code JSONField (default {}) Spec: optional Coding. What is being observed, typically LOINC (CARE_OBSERVATION_VALUSET, system http://loinc.org)
alternate_coding JSONField (default []) Spec: optional CodeableConcept { id?, coding?: Coding[], text }. Same concept expressed in other code systems

Subject & context

Field Storage type Spec shape / notes
subject_type CharField(255) Enum SubjectTypepatient, encounter. Spec defaults to encounter
subject_id UUIDField The subject entity's id. Set server-side; not in the spec body
patient FK → Patient CASCADE. Set server-side, not in the spec body
encounter FK → Encounter None. Where the observation was recorded
effective_datetime DateTimeField When the observation was effective. Nullable in storage, but the spec requires a tz-aware datetime on create; optional on update

Author & performer

Field Storage type Spec shape / notes
data_entered_by FK → users.User CASCADE, nullable. related_name="observations_entered". Write specs accept data_entered_by_id: int; read specs serialize a nested UserSpec
performer JSONField (default {}) user), id: str }. Use it when the performer differs from the data-entry user

Value

Field Storage type Spec shape / notes
value_type CharField(255) Enum QuestionType (from the questionnaire module). Tells the client how to read value — see the table below. Required in specs
value JSONField Spec: QuestionnaireSubmitResultValue { value?: str, unit?: Coding, coding?: Coding }. Required on create, optional on update. value holds the raw/string result, unit the quantity unit, coding the coded answer
note TextField None. Free-text note

Clinical qualifiers

Field Storage type Spec shape / notes
body_site JSONField (default {}) Spec: optional Coding bound to CARE_BODY_SITE_VALUESET (slug system-body-site-observation, SNOMED CT). FHIR Observation.bodySite
method JSONField (default {}) Spec: optional Coding bound to CARE_OBSERVATION_COLLECTION_METHOD (slug system-collection-method, SNOMED CT). FHIR Observation.method
reference_range JSONField (default []) Spec: ReferenceRange[] (shape below), default []. Reference ranges for the value, usually carried over from the observation definition
interpretation JSONField (default {}) Spec: free dict, default {}. Coded interpretation against the reference range (high/low/normal). Normal/abnormal/critical value sets exist (below) but are not enforced on this dict
interpretation_old CharField(255) Nullable. Legacy free-text interpretation, kept for backward compatibility. Not in the specs

Structure & relationships

Field Storage type Spec shape / notes
parent UUIDField None — the external_id of a parent observation, for nesting related observations
component JSONField (default []) Spec: Component[] (shape below), default []. Sub-observations sharing this context but carrying their own codes and values (FHIR Observation.component)
questionnaire_response FK → QuestionnaireResponse None. The submission that produced this observation
diagnostic_report FK → DiagnosticReport CASCADE, nullable. The report this observation belongs to, if any. Not in the write specs
observation_definition FK → ObservationDefinition CASCADE, nullable. The definition this observation templates from. Serialized as BaseObservationDefinitionSpec only in ObservationRetrieveSpec

Enum & value-set reference

ObservationStatus values

Value Meaning
final Recorded, complete and verified. The default for questionnaire-sourced observations
amended Was final, then corrected
entered_in_error Recorded in error; disregard it

PerformerType values (performer.type)

Value
related_person
user

SubjectType values (subject_type)

Value
patient
encounter (spec default)

QuestionType values (value_type)

From the questionnaire module. The value tells the client which key of value to read.

Value Value sourced from QuestionnaireSubmitResultValue
group grouping node (no direct value)
boolean value ("true"/"false")
decimal value
integer value
string value
text value
display display-only
date value
dateTime value
time value
choice coding
url value
quantity value + unit
structured structured payload

Bound value sets

Coded fields validate against registered Care value sets. A body_site or method coding outside its value set is rejected during deserialization.

Field Value set Slug System(s)
main_code CARE_OBSERVATION_VALUSET system-observation http://loinc.org
body_site CARE_BODY_SITE_VALUESET system-body-site-observation http://snomed.info/sct (curated concept list + descendants of 442083009)
method CARE_OBSERVATION_COLLECTION_METHOD system-collection-method http://snomed.info/sct (descendants of 272394005, 129264002, 386053000)

These interpretation value sets are registered for the frontend and observation definitions, but are not enforced on the interpretation dict:

Value set Slug Concepts (system http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation)
Normal system-normal-coded-valueset N Normal, ND Not detected, NEG Negative
Abnormal system-abnormal-coded-valueset A Abnormal, AA Critically abnormal, H High, HH Critically high, L Low, LL Critically low, POS Positive, DET Detected
Critical system-critical-coded-valueset C Critical, CC Critical high, CL Critical low, CV Critical value
UCUM units system-ucum-units http://unitsofmeasure.org (all UCUM units)

Nested JSON shapes (from the spec)

The structures behind the model's JSONFields.

Coding

Coding {
  system:  str | null      # e.g. http://loinc.org
  version: str | null
  code:    str             # required
  display: str | null
}                          # extra keys forbidden

CodeableConcept (alternate_coding)

CodeableConcept {
  id:     str | null
  coding: Coding[] | null
  text:   str | null       # field present, required key
}                          # extra keys forbidden

QuestionnaireSubmitResultValue (value)

QuestionnaireSubmitResultValue {
  value:  str | null       # raw/string value
  unit:   Coding | null    # for quantity values
  coding: Coding | null    # for coded values
}

Performer (performer)

Performer {
  type: PerformerType      # related_person | user
  id:   str
}

ReferenceRange (reference_range[])

ReferenceRange {
  min:            float | null
  max:            float | null
  unit:           str | null
  interpretation: str        # required
  value:          str | null
}

Component (component[])

Component {
  value:           QuestionnaireSubmitResultValue   # required
  interpretation:  str | dict     = {}
  reference_range: ReferenceRange[] = []
  code:            Coding | null   = null
  note:            str            = ""
}

Resource specs (API schema)

The Pydantic specs build on [https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/base.py EMRResource], which provides serialize / de_serialize and the perform_extra_serialization / perform_extra_deserialization hooks. Every concrete spec inherits from BaseObservationSpec.

Spec Role Notes
BaseObservationSpec shared base Defines the common fields: id, status, category, main_code, alternate_coding, subject_type, encounter, effective_datetime, performer, value_type, value, note, body_site (bound), method (bound), reference_range, interpretation, parent, questionnaire_response, component
ObservationSpec write · create Adds data_entered_by_id, created_by_id, updated_by_id (all int). Used internally when materializing observations from a questionnaire submission
ObservationUpdateSpec write · update The base, but effective_datetime and value relax to optional (None) for partial updates
ObservationReadSpec read · list Swaps the user IDs for nested created_by / updated_by / data_entered_by UserSpec objects
ObservationRetrieveSpec read · detail Extends ObservationReadSpec and additionally serializes observation_definition via BaseObservationDefinitionSpec when it is set

Server-side behaviour

  • ObservationSpec.perform_extra_deserialization (create/update): sets obj.external_id = self.id, copies data_entered_by_id, created_by_id, updated_by_id onto the model, drops data_entered_by_id from meta, and on create (is_update is false) clears obj.id so a new row is inserted.
  • ObservationReadSpec.perform_extra_serialization: maps id from external_id; deliberately blanks encounter, patient, and questionnaire_response to None in the output to avoid extra DB queries; resolves the audit users (created_by, updated_by) and data_entered_by from cache (model_from_cache).
  • ObservationRetrieveSpec.perform_extra_serialization: calls the parent, then inlines the full observation_definition when the FK is set.
  • body_site / method are ValueSetBoundCoding[...]: the supplied Coding is validated against its bound value set during deserialization and rejected if the code is not a member.
  • de_serialize only writes fields present in the model's column mapping. Non-default values are persisted (model_dump(exclude_defaults=True)), and unknown spec-only fields would land in meta when __store_metadata__ is set — which, by default, it is not for observations.

Observation is self-contained; it expresses relationships through foreign keys rather than secondary tables.

patient                → FK Patient (CASCADE)
encounter              → FK Encounter (CASCADE)
data_entered_by        → FK users.User (CASCADE, nullable)
questionnaire_response → FK QuestionnaireResponse (CASCADE, nullable)
diagnostic_report      → FK DiagnosticReport (CASCADE, nullable)
observation_definition → FK ObservationDefinition (CASCADE, nullable)

parent is the exception: a soft, UUID-based self-reference to another observation's external_id, not a Django FK. It lets observations nest without a database constraint.

API integration notes

  • Observations are exposed through Care's REST API and align with the FHIR Observation resource. FHIR field names (effectiveDateTime, bodySite, and so on) differ from the Django model names; the resource specs above are the authoritative request/response schemas.
  • Most observations are created as a side effect of submitting a questionnaire. value and value_type mirror the submission types (QuestionnaireSubmitResultValue / QuestionType), and questionnaire_response records provenance.
  • effective_datetime must be timezone-aware. Required on create, optional on update.
  • status is one of final / amended / entered_in_error; questionnaire-sourced observations are final.
  • body_site and method are validated against their bound value sets, and main_code is expected to bind to LOINC via CARE_OBSERVATION_VALUSET.
  • On read, the list and detail specs blank out encounter, patient, and questionnaire_response, so don't rely on those being populated in observation payloads.
  • Prefer structured observations. Allergy and medication checks read coded values, not free text, so unstructured data leaves them blind.


Source code

The files below are fetched live from the care repository — any changes pushed to the repo will show here automatically:

Model

Spec

Value set









Pages that link here:

Wiki: ohcnwiki.tellmey.fyi