Skip to main content
Version: 3.1

Healthcare Service

A HealthcareService is a service a facility offers — cardiology, lab, radiology, pharmacy — scoped to one or more locations and to the facility organization that manages it. You touch it when modeling what a facility provides and where.

The Django model is thin storage: service_type and styling_metadata are opaque JSONFields. Their real structure lives in the Pydantic resource specs, which also define the bound value set, the internal_type enum, and the separate read and write API schemas.

Source:

Models​

ModelPurpose
HealthcareServiceA service a facility offers (e.g. cardiology, lab, radiology), scoped to locations and a managing organization

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

HealthcareService fields​

Identity & classification​

FieldTypeNotes
nameCharField(1024)Display name. Required on write; no default
service_typeJSONField → CodingHolds one FHIR-style Coding object, not a string. Defaults to {}. In the API it is a ValueSetBoundCoding bound to the Healthcare Service Type Code value set (below). Optional (None)
internal_typeCharField(255)Nullable, default None. The API constrains it to the HealthcareServiceInternalType enum (pharmacy / lab / scheduling / store); the column does not
extra_detailsTextFieldFree text. Not nullable and no DB default, so write specs require a value — an empty string counts

Scope & placement​

FieldTypeNotes
facilityFK → facility.FacilityPROTECT; nullable (default=None, blank=True). Excluded from every spec (__exclude__ = ["facility"]) and set server-side from the URL context — never from the request body
locationsArrayField[int]Defaults to []. Holds FacilityLocation primary-key integers, not FK rows. Write specs take location external_ids (UUIDs); retrieve specs return serialized location objects
managing_organizationFK → emr.FacilityOrganizationPROTECT; nullable. The facility-scoped org (department/team) responsible for the service. Write specs take its external_id (UUID), resolved server-side

Presentation​

FieldTypeNotes
styling_metadataJSONField → dictNullable in the DB; defaults to {} in the specs. An open JSON bag of UI hints (colors, icons) with no backend semantics

Coded field shapes (JSON fields)​

service_type → Coding​

service_type stores a single Coding object. In the API it is a ValueSetBoundCoding whose code is checked against the Healthcare Service Type Code value set during de-serialization. Optional (None).

Coding {
system: str | None # e.g. "http://terminology.hl7.org/CodeSystem/service-type"
version: str | None
code: str # required; validated against the bound value set
display: str | None
}
# extra="forbid" — unknown keys rejected

Bound value set — Healthcare Service Type Code​

PropertyValue
NameHealthcare Service Type Code
Slughealthcare-service-type-code
Statusactive
Compose / include systemhttp://terminology.hl7.org/CodeSystem/service-type
System version2.0.0

Registered via register_valueset(...) and register_as_system(). The service_type.code on create or update must resolve within this value set.

Enums​

HealthcareServiceInternalType values​

Constrains internal_type in the specs (str enum). The model column is a plain CharField, so legacy or other values may already exist in storage.

Value
pharmacy
lab
scheduling
store

facility.Facility​

facility → FK Facility (PROTECT, nullable)

The facility offering the service. PROTECT blocks deleting a facility that still has healthcare services. Excluded from specs and set from the request context. See Facility.

emr.FacilityOrganization​

managing_organization → FK FacilityOrganization (PROTECT, nullable)

The facility-scoped organization (department/team) that owns the service. Write specs take its external_id (UUID); the retrieve spec embeds it, serialized via FacilityOrganizationReadSpec. See Organization.

Locations​

locations is an ArrayField of integer PKs, not a relational join — each entry references a FacilityLocation row by primary key, with resolution and validation handled in application code rather than by a database foreign key. Write specs take location external_ids (UUIDs); the retrieve spec embeds each location, serialized via FacilityLocationListSpec. See Location.

Resource specs (API schema)​

Every spec extends EMRResource (care/emr/resources/base.py), which provides serialize (DB object → spec) and de_serialize (spec → DB object), plus the perform_extra_serialization / perform_extra_deserialization hooks. __exclude__ = ["facility"] keeps facility out of every payload.

Spec classRoleNotes
BaseHealthcareServiceSpecshared baseFields: id, service_type, internal_type, name, styling_metadata, extra_details. __model__ = HealthcareService, __exclude__ = ["facility"]
HealthcareServiceWriteSpecwrite · create & updateBase fields plus locations: list[UUID4] (default []) and managing_organization: UUID4 | None. Resolves managing_organization from its external_id in perform_extra_deserialization
HealthcareServiceReadSpecread · listBase fields. perform_extra_serialization sets id to obj.external_id
HealthcareServiceRetrieveSpecread · detailExtends ReadSpec; overrides locations: list[dict] (each location serialized via FacilityLocationListSpec) and managing_organization: dict | None (serialized via FacilityOrganizationReadSpec)

Field exposure by spec​

FieldBaseWriteRead (list)Retrieve (detail)
id (UUID4)✓ (read-only)✓✓ (= external_id)✓ (= external_id)
name (str, required)✓✓✓✓
service_type (bound Coding, optional)✓✓✓✓
internal_type (enum, optional)✓✓✓✓
styling_metadata (dict, default {})✓✓✓✓
extra_details (str, required)✓✓✓✓
locations—list[UUID4] (write)—list[dict] (embedded)
managing_organization—UUID4 | None (write)—dict | None (embedded)

Validation & server-side behaviour​

  • service_type — a ValueSetBoundCoding. De-serialization runs validate_valueset on code against the healthcare-service-type-code value set, and extra="forbid" on the underlying Coding rejects unknown keys.
  • managing_organization (write) — perform_extra_deserialization resolves the UUID via get_object_or_404(FacilityOrganization, external_id=...) and assigns the FK; a falsy value sets managing_organization = None.
  • locations (write) — submitted as UUIDs. The retrieve spec resolves each PK back to a FacilityLocation and serializes it, silently skipping any that fail to load (try/except … pass).
  • id / external_id — never written from the body. de_serialize skips both; serialize / perform_extra_serialization populate id from obj.external_id.
  • facility — excluded from all specs and assigned server-side, so it can't be set or changed through the API body.
  • No status field, and therefore no server-maintained status_history.

Methods & save behaviour​

  • Inherits save(), soft-delete (deleted), audit fields (created_by/updated_by), history/meta, and external_id from EMRBaseModel.
  • EMRResource.serialize / de_serialize drive read/write conversion; the extra (de)serialization hooks above handle FK resolution and embedded serialization.
  • facility and managing_organization use on_delete=PROTECT, so deleting either while a service references it is blocked at the DB level.

API integration notes​

The API surface is built from the spec classes, not the raw model. Three things commonly trip up integrators:

  • service_type takes a Coding object whose code is in the bound value set, not a bare string.
  • On write, locations and managing_organization are external_ids (UUIDs); detail responses embed the full objects. Nothing at the DB level confirms the referenced locations belong to the same facility.
  • facility is never accepted in the request body — it's set from the URL context.