References/Specimen: Difference between revisions
More languages
More actions
OHC identity seed |
Automated edit (via update-page on MediaWiki MCP Server) |
||
| Line 373: | Line 373: | ||
specimen_definition → FK SpecimenDefinition (CASCADE, nullable)</syntaxhighlight> |
specimen_definition → FK SpecimenDefinition (CASCADE, nullable)</syntaxhighlight> |
||
A <code>Specimen</code> is created to fulfill a [[References/Service Request|<code>ServiceRequest</code>]] (a lab order) and may be shaped by a [[References/Specimen Definition|<code>SpecimenDefinition</code>]] describing the expected sample. Results derived from a specimen surface through a [[References/Diagnostic Report|<code>DiagnosticReport</code>]]. |
A <code>Specimen</code> is created to fulfill a [[References/Service Request|<code>ServiceRequest</code>]] (a lab order) and may be shaped by a [[References/Specimen Definition|<code>SpecimenDefinition</code>]] describing the expected sample. Results derived from a specimen surface through a [[References/Diagnostic Report|<code>DiagnosticReport</code>]]. |
||
{{Navbox clinical}} |
|||
{{Related}} |
{{Related}} |
||
Wiki: ohcnwiki.tellmey.fyi |
|||
Latest revision as of 09:35, 6 July 2026
A Specimen is a physical sample — blood, tissue, swab — collected from a patient for laboratory analysis. You create one to fulfill a lab order, then update it as the specimen moves through collection, receipt, and processing.
Several of the model's fields (care/emr/models/specimen.py) are opaque JSONFields whose structure lives only in the Pydantic resource specs (care/emr/resources/specimen/). The specs define the enums, nested JSON shapes, value-set bindings, validation, and the read/write schemas, so you need both layers to work with this resource.
Source:
- Model: [https://github.com/ohcnetwork/care/blob/develop/care/emr/models/specimen.py
care/emr/models/specimen.py] - Resource specs: [https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/specimen/spec.py
care/emr/resources/specimen/spec.py], [https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/specimen/valueset.pyvalueset.py] - Viewset: [https://github.com/ohcnetwork/care/blob/develop/care/emr/api/viewsets/specimen.py
care/emr/api/viewsets/specimen.py]
Models
Specimen extends EMRBaseModel, the shared Care EMR base providing external_id, audit fields, soft-delete via deleted, and history/meta JSON.
Specimen fields
Identity & status
| Field | Model type | Spec shape / values | Notes |
|---|---|---|---|
accession_identifier
|
CharField(255), db_index=True
|
str, default ""
|
Lab accession/barcode identifier; indexed for lookup. Defaults to "", so it's optional on write.
|
status
|
CharField(20)
|
SpecimenStatusOptions enum
|
Required on base/create, optional on update. See [[#specimenstatusoptions-values |
specimen_type
|
JSONField
|
Coding bound to value set system-specimen_type-code
|
Kind of material collected, as a single coding. Required on base/create, optional on update. |
Clinical links
| Field | Model type | Notes |
|---|---|---|
facility
|
FK → Facility
|
PROTECT, nullable; the facility the specimen belongs to. Excluded from all specs (__exclude__).
|
patient
|
FK → Patient
|
CASCADE; the patient the specimen was collected from. Set on create via subject_patient (UUID).
|
encounter
|
FK → Encounter
|
CASCADE, nullable; the encounter during which collection occurred. Set on create via subject_encounter (UUID).
|
service_request
|
FK → ServiceRequest
|
CASCADE, nullable; the order this specimen fulfills. Set on create via request (UUID); excluded from base/read field copy.
|
specimen_definition
|
FK → SpecimenDefinition
|
CASCADE, nullable; the definition/template this specimen was derived from.
|
Collection & processing
| Field | Model type | Spec shape | Notes |
|---|---|---|---|
collection
|
JSONField default=dict
|
None, default None
|
A single collection event: collector, method, body site, quantity, fasting. See [[#collectionspec |
received_time
|
DateTimeField, nullable
|
None, default None
|
When the lab received the specimen; ISO 8601 string in the spec. |
condition
|
JSONField default=list
|
list[Coding] bound to system-specimen-condition-code, default []
|
Coded conditions/state of the specimen on receipt. |
processing
|
JSONField default=list
|
list[ProcessingSpec], default []
|
Processing steps applied. See [[#processingspec |
note
|
TextField, nullable
|
None, default None
|
Free-text annotation. |
Enums
SpecimenStatusOptions values
The status enum (str). Two things to watch: entered_in_error uses an underscore rather than the FHIR hyphen, and draft is a Care addition with no FHIR equivalent.
| Value | Meaning |
|---|---|
draft
|
Care-specific; not from FHIR |
available
|
Specimen available for testing |
unavailable
|
Specimen no longer available |
unsatisfactory
|
Specimen unsuitable for testing |
entered_in_error
|
Recorded in error |
Nested JSON specs
These define the real structure behind the model's JSONFields.
CollectionSpec
Shape of the collection JSON field — a single collection event.
| Field | Type | Required | Notes |
|---|---|---|---|
collector |
UUID4 |
optional | |
collected_date_time |
datetime |
optional | |
quantity |
QuantitySpec |
optional | |
method |
Coding |
optional | |
procedure |
UUID4 |
optional | |
body_site |
Coding |
optional | |
fasting_status_codeable_concept |
Coding |
optional | |
fasting_status_duration |
DurationSpec |
optional |
ProcessingSpec
One element of the processing list.
| Field | Type | Required | Notes |
|---|---|---|---|
description |
str |
required | |
method |
Coding |
optional | |
performer |
UUID4 |
optional | |
time_date_time |
str |
required |
QuantitySpec
| Field | Type | Notes |
|---|---|---|
value |
Decimal |
max_digits=20, decimal_places=0, so integer-valued.
|
unit |
Coding |
Required unit coding. |
This is a specimen-local quantity spec, distinct from the shared [https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/common/quantity.py Quantity] common type — which allows decimal_places=6, optional value/unit, plus code/meta.
DurationSpec
| Field | Type | Notes |
|---|---|---|
value |
int |
Duration magnitude. |
unit |
Coding |
Required unit coding. |
Coding (shared common type)
Every coded field above uses [https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/common/coding.py Coding] (extra="forbid"):
| Field | Type | Required |
|---|---|---|
system
|
None | optional |
version
|
None | optional |
code
|
str
|
required |
display
|
None | optional |
Bound value sets
Coded fields bind to Care value sets via ValueSetBoundCoding[<slug>], which validates the submitted code against the value set at write time.
| Field | Value set | Slug | Source system |
|---|---|---|---|
specimen_type
|
Specimen Type Code | system-specimen_type-code
|
HL7 v2-0487 |
condition[]
|
Specimen Condition | system-specimen-condition-code
|
HL7 v2-0493 (v2.0.0) |
collection.method
|
Collection Method | system-collection-method-code
|
SNOMED CT (enumerated, see below) |
collection.body_site
|
Body Site | system-body-site-observation
|
(observation body-site value set) |
collection.fasting_status_codeable_concept
|
Fasting Status | system-fasting-status-code
|
HL7 v2-0916 (v2.0.0) |
processing[].method
|
Specimen Processing Method | system-specimen-processing-method-code
|
SNOMED CT (< 9265001)
|
Collection Method value set
The system-collection-method-code value set enumerates these SNOMED CT codes:
| Code | Display |
|---|---|
129316008
|
Aspiration - action |
129314006
|
Biopsy - action |
129300006
|
Puncture - action |
129304002
|
Excision - action |
129323009
|
Scraping - action |
73416001
|
Urine specimen collection, clean catch |
225113003
|
Timed urine collection |
70777001
|
Urine specimen collection, catheterized |
386089008
|
Collection of coughed sputum |
278450005
|
Finger-prick sampling |
The other coded fields aren't enumerated. Fasting Status (http://terminology.hl7.org/CodeSystem/v2-0916), Specimen Condition (v2-0493), Specimen Type (v2-0487), Body Site, and Specimen Processing Method (SNOMED < 9265001) are pulled in by code-system reference or filter rather than a fixed concept list.
Resource specs (API schema)
Every spec extends EMRResource (care/emr/resources/base.py), which provides serialize (DB object → pydantic, via get_database_mapping) and de_serialize (pydantic → DB object), plus the perform_extra_serialization / perform_extra_deserialization hooks. __exclude__ = ["facility", "request"] on the base keeps those fields from being copied field-for-field.
| Spec class | Role | Key fields / behaviour |
|---|---|---|
BaseSpecimenSpec
|
shared base | id, accession_identifier, status (required), specimen_type (required), received_time, collection, processing, condition, note. __model__ = Specimen, __exclude__ = ["facility", "request"].
|
SpecimenCreateSpec
|
write · create | None. Wires up the FK links on creation. |
SpecimenUpdateSpec
|
write · update | None) for partial updates. |
SpecimenReadSpec
|
read · list | None. perform_extra_serialization sets id = external_id and, when present, embeds the linked specimen definition via SpecimenDefinitionReadSpec.serialize(...).to_json().
|
SpecimenRetrieveSpec
|
read · detail | None; serialization additionally embeds the linked service request via ServiceRequestReadSpec.serialize(...).to_json().
|
Nested specs (defined in the same module): CollectionSpec, ProcessingSpec, QuantitySpec, DurationSpec — see Nested JSON specs.
Validation & server behaviour
collection.collectorandprocessing[].performermust reference existing users byexternal_id; serialization then injects the resolvedcollector_object/performer_object(cachedUserSpec).- Coded fields are validated against their value sets on write (
ValueSetBoundCoding); an unbound or invalidcodeis rejected. - Read specs embed related resources — specimen definition on list and detail, service request on detail — as nested JSON rather than bare IDs.
- The base spec doesn't override
perform_extra_deserialization, so nostatus_history-style server-side history is appended on write, unlike some other clinical resources.
API integration notes
- Aligned with the FHIR
Specimenresource, though some Care field names differ. On create,subject_patient/subject_encounter/requestmap to thepatient/encounter/service_requestFKs. - The viewset (
SpecimenViewSet) mixes in retrieve and update only (EMRRetrieveMixin,EMRUpdateMixin) — so you get read/detail/list and update, withpydantic_model = BaseSpecimenSpec,pydantic_update_model = SpecimenUpdateSpec,pydantic_read_model = SpecimenReadSpec,pydantic_retrieve_model = SpecimenRetrieveSpec. - Filtering:
accession_identifier(icontains); ordering oncreated_date/modified_date. - The custom action
POST retrieve_by_accession_identifierlooks up a specimen byaccession_identifier(must be ≥ 5 chars), returning aSpecimenRetrieveSpec. It raises a validation error on no match or multiple matches. - Authorization keys off the linked
service_request: read viacan_read_specimen, write viacan_write_specimen. One service request may own multiple specimens.
Related models
facility → FK Facility (PROTECT, nullable) [excluded from specs]
patient → FK Patient (CASCADE) [set via subject_patient]
encounter → FK Encounter (CASCADE, nullable) [set via subject_encounter]
service_request → FK ServiceRequest (CASCADE, nullable) [set via request]
specimen_definition → FK SpecimenDefinition (CASCADE, nullable)
A Specimen is created to fulfill a ServiceRequest (a lab order) and may be shaped by a SpecimenDefinition describing the expected sample. Results derived from a specimen surface through a DiagnosticReport.
Related
Pages that link here:
- Reference: References/Base models & conventions
Wiki: ohcnwiki.tellmey.fyi