← Knowledge library

Clinical care

Consent

A Consent records a patient's permit-or-deny decision for a category of activity, scoped to an encounter. You write one when capturing a patient's agreement to treatment, research, privacy disclosure, or an advance directive. The Django model…

3.1 · versioned documentation · 7 min read

A Consent records a patient's permit-or-deny decision for a category of activity, scoped to an encounter. You write one when capturing a patient's agreement (or refusal) to treatment, research, privacy disclosure, or an advance directive.

The Django model only stores data: status, category, and decision are bare CharFields, and period / verification_details are opaque JSONFields. Allowed enum values, the nested JSON shapes, validation, and the read/write schema split all live in the Pydantic resource specs at care/emr/resources/consent/spec.py, built on EMRResource.

Source:

Models

Model Purpose
Consent Records a patient's consent decision (permit/deny) for a category of activity, scoped to an encounter

Consent extends EMRBaseModel, the shared MANSOQ EMR base that provides external_id, created_date/modified_date, soft-delete via deleted, created_by/updated_by, and history/meta JSON.

Consent fields

Storage type is the Django column; Spec type is the shape the API enforces.

Field Storage type Spec type Notes
status CharField(50) ConsentStatusChoices (enum) Required. Lifecycle state. See enum
category CharField(50) CategoryChoice (enum) Required. What the consent is for. See enum
date DateTimeField datetime Required. When the consent was recorded
period JSONField (default dict) PeriodSpec { start, end } Validity window. Both ends must be tz-aware; start ≤ end; and on create, start ≥ date. See PeriodSpec
encounter FK → Encounter (CASCADE, related_name="consents") UUID4 (external_id) Required. The encounter this consent applies to; deleting the encounter deletes its consents. Listed in __exclude__, so it skips the generic DB mapping and is resolved by hand — see Methods
decision CharField(10) DecisionType (enum) Required. permit / deny. See enum
verification_details JSONField (default list) list[ConsentVerificationSpec] Read-only on the API; one entry per verification record. See ConsentVerificationSpec
note TextField (null, blank) str | None Optional free-text note

Note: source_attachments is not a model field. It is derived at serialize time from FileUpload rows (see Resource specs).

Enums

ConsentStatusChoices values

Value Meaning
draft Consent is being drafted, not yet in force
active Consent is in force
inactive Consent is no longer in force
not_done Consent activity did not occur
entered_in_error Consent was recorded in error

CategoryChoice values

Value Meaning
research Consent for research participation
patient_privacy Patient privacy / information disclosure consent
treatment Consent to treatment
dnr Do-not-resuscitate directive
comfort_care Comfort / palliative care directive
acd Advance care directive
adr Advance directive (other)

A consent_document category (LOINC 59284-0) exists in migrations only and is not an accepted API value.

DecisionType values

Value Meaning
permit Consent is granted
deny Consent is refused

VerificationType values

Used inside ConsentVerificationSpec.verification_type.

Value Meaning
family Verified by a family member
validation Verified through validation

Nested JSON shapes

PeriodSpec nested shape

The period field deserializes to PeriodSpec (from care/emr/resources/base.py). The model default is dict, so an absent period stores {}.

Field Type Notes
start datetime | None Default None. Must be timezone-aware if set
end datetime | None Default None. Must be timezone-aware if set

PeriodSpec.validate_period (mode after) enforces:

ConsentVerificationSpec nested shape

This is the shape each verification_details entry takes on write. On read, verified_by is expanded — see below.

Field Type Notes
verified bool Required. Whether the consent was verified
verified_by UUID4 | None Default None. On write, the verifying user's external_id. On read, replaced by a full UserSpec object
verification_date datetime | None Default None
verification_type VerificationType Required. family / validation
note str | None Default None

Resource specs (API schema)

Every spec subclasses EMRResource through ConsentBaseSpec. serialize builds the read schema from the model; de_serialize writes a model from the payload, skipping id/external_id and any __exclude__ field. ConsentBaseSpec sets __exclude__ = ["encounter"], so the encounter FK never round-trips through the generic mapping — the deserialization hooks resolve it instead.

Spec class Role Exposes / behaviour
ConsentBaseSpec shared base id, status, category, date, period, encounter (UUID4), decision, note. __model__ = Consent, __exclude__ = ["encounter"]
ConsentCreateSpec write · create Same fields as base (all required except id, note). Validates period.start ≥ date; resolves encounter from external_id → Encounter instance
ConsentUpdateSpec write · update All fields optional (status, category, date, period, encounter, decision, note → None). Keeps the existing encounter and ignores any supplied value
ConsentListSpec read · list Base fields plus derived source_attachments: list and expanded verification_details: list
ConsentRetrieveSpec read · detail Identical to ConsentListSpec (pass)

The schema nests PeriodSpec for the period field and ConsentVerificationSpec for entries of verification_details.

Validation

Server-maintained behaviour

Related models

Consent points at one Encounter, and an encounter carries many consents through the consents reverse relation:

encounter → FK Encounter (CASCADE, related_name="consents")

The owning patient is reached through encounter. Coded values (status, category, decision) and structured JSON (period, verification_details) are validated by the Pydantic specs at the API layer, not by database constraints.

Read schemas also reach into FileUpload (consent attachments) and User (verifiers) at serialize time.

Methods & save behaviour

API integration notes

Related

Source evidence

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