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

References/Specimen Definition: Difference between revisions

From OHC Network Wiki
Content deleted Content added
OHC identity seed
 
Automated edit (via update-page on MediaWiki MCP Server)
 
Line 277: Line 277:
* '''Read payload''' (<code>SpecimenDefinitionReadSpec</code>): adds <code>id</code> (= <code>external_id</code>), <code>version</code>, the qualified <code>slug</code>, and <code>slug_config</code>.
* '''Read payload''' (<code>SpecimenDefinitionReadSpec</code>): adds <code>id</code> (= <code>external_id</code>), <code>version</code>, the qualified <code>slug</code>, and <code>slug_config</code>.
* The model maps to the FHIR <code>SpecimenDefinition</code> resource. Care's spec is intentionally minimal: one container per definition, and behaviour changes bump <code>version</code> rather than mutate published records.
* The model maps to the FHIR <code>SpecimenDefinition</code> resource. Care's spec is intentionally minimal: one container per definition, and behaviour changes bump <code>version</code> rather than mutate published records.

{{Navbox definitions}}


{{Related}}
{{Related}}

Latest revision as of 09:33, 6 July 2026

referencedefinitionsCARE 3.0+

A SpecimenDefinition is a reusable, facility-scoped template for a kind of specimen: what material to collect, how to prepare the patient, how to collect it, and how it's held in a container for testing. A lab maintains a repository of these, and an References/Activity Definition or References/Service Request references one so the same container and handling rules apply every time. When a concrete References/Specimen is instantiated from a definition, the link is kept and the specimen copies the definition's data for history and integrity.

The Django model is only the storage layer: type_collected, patient_preparation, collection, and type_tested are opaque JSONFields. Their real structure — the enums, value-set bindings, and read/write API schemas — lives in the Pydantic resource specs documented below.

Source:

Models

Model Purpose
SpecimenDefinition Reusable definition of a kind of specimen: what to collect, how to prepare the patient, how to collect it, and how it is contained and tested

SpecimenDefinition extends SlugBaseModel: the Care EMR base with FACILITY_SCOPED = True, a facility-scoped slug, external_id, history/meta JSON, audit fields, and soft-delete semantics.

SpecimenDefinition fields

Identity & status

Field Type Required Notes
facility FK → facility.Facility (PROTECT) model: optional
version IntegerField default 1
slug CharField(255) yes (server-built)
title CharField(1024) yes
derived_from_uri TextField optional
status CharField(255) yes
description TextField yes

Collection & testing detail (JSON fields)

The model stores these as raw JSON; the spec defines their true shape and value-set bindings.

Field Model type Spec type Notes
type_collected JSONField (null=True) Coding bound to Specimen Type Code value set Required on write. The kind of material collected. See [[#bound-value-sets
patient_preparation JSONField (default=list) list[Coding] bound to Prepare Patient Prior Specimen Code value set Defaults to []. Steps the patient follows before collection
collection JSONField (null=True) Coding bound to Specimen Collection Code value set, optional The specimen collection procedure
type_tested JSONField (default=dict) TypeTestedSpec (nested), optional Container, handling, and testing detail. See [[#typetestedspec

Each bound coded field accepts a Coding object ({ system, version?, code, display? }); ValueSetBoundCoding validates the code against the bound value set at de-serialization time.

Type Where Shape
Coding [https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/common/coding.py resources/common/coding.py] { system: str?, version: str?, code: str (required), display: str? }, extra="forbid"
QuantitySpec spec.py { value: Decimal (max_digits=20, decimal_places=0), unit: Coding }decimal_places=0, so integer-valued
MinimumVolumeSpec spec.py { quantity: QuantitySpec?, string: str? }; a validator forbids supplying both
ContainerSpec spec.py { description: str?, capacity: QuantitySpec?, minimum_volume: MinimumVolumeSpec?, cap: Coding? (bound to Container Cap), preparation: str? }
DurationSpec spec.py { value: Decimal (max_digits=20, decimal_places=0), unit: Coding }unit not yet restricted to datetime units
RangeSpec spec.py { low: QuantitySpec?, high: QuantitySpec? }
HandlingSpec spec.py { temperature_qualifier: HandlingConditionOptions?, temperature_range: RangeSpec?, max_duration: DurationSpec?, instruction: str? }
TypeTestedSpec spec.py see [[#typetestedspec

TypeTestedSpec

The structured shape of the type_tested JSON field. A definition holds a single container; for multiple containers per test, repeat the definition in the References/Activity Definition spec.

Field Type Required Notes
is_derived bool yes
preference PreferenceOptions yes
container ContainerSpec optional
requirement str optional
retention_time DurationSpec optional
single_use bool optional
handling HandlingSpec optional

Enums

SpecimenDefinitionStatusOptions values

Value Meaning
draft Being authored, not yet in use
active In use
retired Withdrawn from use

PreferenceOptions values

Value Meaning
preferred Preferred specimen for the test
alternate Acceptable alternative specimen

HandlingConditionOptions values

Value Meaning
room Room temperature
refrigerated Refrigerated
frozen Frozen

Resource specs (API schema)

All specs build on EMRResource (serialize/de_serialize, perform_extra_serialization/perform_extra_deserialization). __exclude__ = ["facility"] keeps facility out of both directions. The ViewSet wires pydantic_model = SpecimenDefinitionWriteSpec for create/update and pydantic_read_model = SpecimenDefinitionReadSpec for list/retrieve.

Spec class Role Fields / behaviour
BaseSpecimenDefinitionSpec shared base id, title, derived_from_uri, status, description, type_collected, patient_preparation, collection, type_tested. Holds the coded-field value-set bindings and the nested type_tested shape
SpecimenDefinitionWriteSpec write · create & update Base fields plus slug_value: SlugType. perform_extra_deserialization copies slug_valueobj.slug (the ViewSet then fully-qualifies it). facility, version, and the stored slug are never client-supplied
SpecimenDefinitionReadSpec read · list & detail Base fields plus version: int?, slug: str, slug_config: dict. perform_extra_serialization sets id = obj.external_id and slug_config = obj.parse_slug(obj.slug), decomposing the qualified slug into { facility, slug_value }

Nested specs used by the schemas: TypeTestedSpec, ContainerSpec, MinimumVolumeSpec, QuantitySpec, DurationSpec, RangeSpec, HandlingSpec (see Related models).

Validation rules

  • slug_value (SlugType): string, length 5–50, matching ^[a-zA-Z0-9][a-zA-Z0-9_-]*[a-zA-Z0-9]$ (URL-safe; starts and ends alphanumeric).
  • Coded fields type_collected, patient_preparation[*], collection, and container.cap: ValueSetBoundCoding validates each Coding.code against its bound value set during de-serialization and rejects unknown codes.
  • MinimumVolumeSpec: quantity and string are mutually exclusive — supplying both raises "Only one of quantity or string should be provided".
  • QuantitySpec / DurationSpec value: Decimal, max_digits=20, decimal_places=0 (integer-valued).
  • Slug uniqueness (ViewSet validate_data): the fully-qualified f-<facility>-<slug_value> must be unique within the facility (case-insensitive), else "Specimen Definition with this slug already exists." On update, the current record is excluded from the check.

Bound value sets

Field Value set Slug Source system(s)
type_collected Specimen Type Code system-specimen_type-code HL7 v2-0487 (unbounded include)
patient_preparation[*] Prepare Patient Prior Specimen Code system-prepare_patient_prior_specimen_code SNOMED CT, is-a 703763000
collection Specimen Collection Code system-specimen_collection_code SNOMED CT (curated list: aspiration, biopsy, puncture, excision, scraping, clean-catch/timed/catheterized urine, coughed sputum, finger-prick)
container.cap Container Cap system-container_cap-code HL7 container-cap code system

Methods & save behaviour

SpecimenDefinition overrides no save()/delete() and defines no custom methods. Slug helpers, audit fields, and soft-delete come from SlugBaseModel. The side effects below live in the resource spec and the ViewSet, not the model:

  • Slug qualification (write). Clients send a bare slug_value. SpecimenDefinitionWriteSpec.perform_extra_deserialization sets obj.slug = slug_value; then the ViewSet's perform_create/perform_update rewrites it via SpecimenDefinition.calculate_slug_from_facility(facility.external_id, slug)f-<facility_external_id>-<slug_value>.
  • Facility binding (create). perform_create sets instance.facility from the facility_external_id URL kwarg before saving.
  • Slug decomposition (read). SpecimenDefinitionReadSpec.perform_extra_serialization exposes slug_config = obj.parse_slug(obj.slug), splitting the stored slug back into { facility, slug_value }.
  • Specimen instantiation. convert_sd_to_specimen ([https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/specimen_definition/specimen.py specimen.py]) builds a Specimen from a definition with status="available", specimen_type = definition.type_collected, and specimen_definition = <definition>, preserving the link and a copy of the type.

API integration notes

  • Endpoints are facility-scoped. The ViewSet supports create, retrieve, update, list, and upsert with lookup_field = "slug". Every operation requires facility_external_id in the URL.
  • Authorization. Writes require can_write_facility_specimen_definition; list/retrieve require can_list_facility_specimen_definition on the facility — otherwise 403 PermissionDenied. The queryset is filtered to the URL facility.
  • Filtering / ordering. status (iexact) and title (icontains) filters; ordering by created_date / modified_date.
  • Write payload (SpecimenDefinitionWriteSpec): send slug_value, title, status, description, the coded fields (type_collected, patient_preparation, collection) as Coding objects, and type_tested. Don't send facility, version, or the qualified slug — they're server-managed.
  • Read payload (SpecimenDefinitionReadSpec): adds id (= external_id), version, the qualified slug, and slug_config.
  • The model maps to the FHIR SpecimenDefinition resource. Care's spec is intentionally minimal: one container per definition, and behaviour changes bump version rather than mutate published records.

Pages that link here: