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_typeJSONFieldCodingHolds 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_metadataJSONFielddictNullable 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_typeCoding

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)
locationslist[UUID4] (write)list[dict] (embedded)
managing_organizationUUID4 | 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.