← Knowledge library

Laboratory & radiology

Specimen Definition

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,…

3.1 · versioned documentation · 7 min read

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 Activity Definition or Service Request references one so the same container and handling rules apply every time. When a concrete 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 MANSOQ 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 null=True, blank=True, default=None. Never client-supplied — the ViewSet sets it from the facility_external_id URL kwarg, so every API-created definition is facility-scoped. Excluded from both spec schemas (__exclude__ = ["facility"])
version IntegerField default 1 Definition version. Read-only over the API — exposed by SpecimenDefinitionReadSpec, never accepted on write
slug CharField(255) yes (server-built) Stored fully-qualified as f-<facility_external_id>-<slug_value> (see Methods & save behaviour). Clients send the bare slug_value instead
title CharField(1024) yes Human-readable name
derived_from_uri TextField optional null=True, blank=True. URI of the canonical/external definition this was derived from
status CharField(255) yes Lifecycle status, constrained by SpecimenDefinitionStatusOptions — see enum
description TextField yes Natural-language description (markdown)

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 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.

Related models

Type Where Shape
Coding 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 below

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 Activity Definition spec.

Field Type Required Notes
is_derived bool yes false for a primary specimen, true for a secondary/derived one
preference PreferenceOptions yes preferred / alternate — see enum
container ContainerSpec optional The specimen's container — description, capacity, minimum volume, cap, preparation
requirement str optional Delivery requirements / special handling (markdown)
retention_time DurationSpec optional Usual time this kind of specimen is retained
single_use bool optional Specimen for single use only
handling HandlingSpec optional Temperature qualifier/range, max duration, instruction

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_value → obj.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

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:

API integration notes

Related

Source evidence

References are pinned to the private MANSOQ source repository. Repository access is required to open these links.