<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://ohcnwiki.tellmey.fyi/index.php?action=history&amp;feed=atom&amp;title=References%2FConsent</id>
	<title>References/Consent - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://ohcnwiki.tellmey.fyi/index.php?action=history&amp;feed=atom&amp;title=References%2FConsent"/>
	<link rel="alternate" type="text/html" href="https://ohcnwiki.tellmey.fyi/index.php?title=References/Consent&amp;action=history"/>
	<updated>2026-07-06T05:20:12Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.45.4</generator>
	<entry>
		<id>https://ohcnwiki.tellmey.fyi/index.php?title=References/Consent&amp;diff=412&amp;oldid=prev</id>
		<title>Admin: Automated edit (via update-page on MediaWiki MCP Server)</title>
		<link rel="alternate" type="text/html" href="https://ohcnwiki.tellmey.fyi/index.php?title=References/Consent&amp;diff=412&amp;oldid=prev"/>
		<updated>2026-07-06T04:03:58Z</updated>

		<summary type="html">&lt;p&gt;Automated edit (via update-page on MediaWiki MCP Server)&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 09:33, 6 July 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 279:&lt;/td&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 279:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* &amp;lt;code&amp;gt;verification_details&amp;lt;/code&amp;gt; is read-only on write and comes back with &amp;lt;code&amp;gt;verified_by&amp;lt;/code&amp;gt; expanded to full user objects.&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* &amp;lt;code&amp;gt;verification_details&amp;lt;/code&amp;gt; is read-only on write and comes back with &amp;lt;code&amp;gt;verified_by&amp;lt;/code&amp;gt; expanded to full user objects.&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* The Pydantic enums, not the database columns, enforce the allowed &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;category&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;decision&amp;lt;/code&amp;gt; values.&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* The Pydantic enums, not the database columns, enforce the allowed &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;category&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;decision&amp;lt;/code&amp;gt; values.&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-empty diff-side-deleted&quot;&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-empty diff-side-deleted&quot;&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;{{Navbox clinical}}&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;{{Related}}&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;{{Related}}&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-empty diff-side-deleted&quot;&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Wiki: ohcnwiki.tellmey.fyi&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://ohcnwiki.tellmey.fyi/index.php?title=References/Consent&amp;diff=139&amp;oldid=prev</id>
		<title>Admin: OHC identity seed</title>
		<link rel="alternate" type="text/html" href="https://ohcnwiki.tellmey.fyi/index.php?title=References/Consent&amp;diff=139&amp;oldid=prev"/>
		<updated>2026-07-04T22:44:19Z</updated>

		<summary type="html">&lt;p&gt;OHC identity seed&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Doc header&lt;br /&gt;
|type=reference&lt;br /&gt;
|domain=clinical&lt;br /&gt;
|title=Consent&lt;br /&gt;
|order=8&lt;br /&gt;
|introduced=3.0&lt;br /&gt;
|fhir=Consent&lt;br /&gt;
|model=Consent&lt;br /&gt;
|reference=References/User &amp;amp;amp; Skills&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;Consent&amp;lt;/code&amp;gt; records a patient&amp;#039;s permit-or-deny decision for a category of activity, scoped to an encounter. You write one when capturing a patient&amp;#039;s agreement (or refusal) to treatment, research, privacy disclosure, or an advance directive.&lt;br /&gt;
&lt;br /&gt;
The Django model only stores data: &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;category&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;decision&amp;lt;/code&amp;gt; are bare &amp;lt;code&amp;gt;CharField&amp;lt;/code&amp;gt;s, and &amp;lt;code&amp;gt;period&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;verification_details&amp;lt;/code&amp;gt; are opaque &amp;lt;code&amp;gt;JSONField&amp;lt;/code&amp;gt;s. Allowed enum values, the nested JSON shapes, validation, and the read/write schema split all live in the Pydantic resource specs at &amp;lt;code&amp;gt;care/emr/resources/consent/spec.py&amp;lt;/code&amp;gt;, built on &amp;lt;code&amp;gt;EMRResource&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Source:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
* Model: [&amp;lt;nowiki/&amp;gt;https://github.com/ohcnetwork/care/blob/develop/care/emr/models/consent.py &amp;lt;code&amp;gt;care/emr/models/consent.py&amp;lt;/code&amp;gt;]&lt;br /&gt;
* Resource spec: [&amp;lt;nowiki/&amp;gt;https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/consent/spec.py &amp;lt;code&amp;gt;care/emr/resources/consent/spec.py&amp;lt;/code&amp;gt;]&lt;br /&gt;
* Base resource: [&amp;lt;nowiki/&amp;gt;https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/base.py &amp;lt;code&amp;gt;care/emr/resources/base.py&amp;lt;/code&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
== Models ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Consent&amp;lt;/code&amp;gt;&lt;br /&gt;
| Records a patient&amp;#039;s consent decision (permit/deny) for a category of activity, scoped to an encounter&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Consent&amp;lt;/code&amp;gt; extends [[References/Base models &amp;amp;amp; conventions|&amp;lt;code&amp;gt;EMRBaseModel&amp;lt;/code&amp;gt;]], the shared Care EMR base that provides &amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;created_date&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;modified_date&amp;lt;/code&amp;gt;, soft-delete via &amp;lt;code&amp;gt;deleted&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;created_by&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;updated_by&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;history&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;meta&amp;lt;/code&amp;gt; JSON.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;code&amp;gt;Consent&amp;lt;/code&amp;gt; fields ==&lt;br /&gt;
&lt;br /&gt;
Storage type is the Django column; Spec type is the shape the API enforces.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Storage type&lt;br /&gt;
! Spec type&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;CharField(50)&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;ConsentStatusChoices&amp;lt;/code&amp;gt; (enum)&lt;br /&gt;
| Required. Lifecycle state. See [[#consentstatuschoices-values&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;category&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;CharField(50)&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;CategoryChoice&amp;lt;/code&amp;gt; (enum)&lt;br /&gt;
| Required. What the consent is for. See [[#categorychoice-values&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;date&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;DateTimeField&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;datetime&amp;lt;/code&amp;gt;&lt;br /&gt;
| Required. When the consent was recorded&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;period&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;JSONField&amp;lt;/code&amp;gt; (default &amp;lt;code&amp;gt;dict&amp;lt;/code&amp;gt;)&lt;br /&gt;
| &amp;lt;code&amp;gt;PeriodSpec { start, end }&amp;lt;/code&amp;gt;&lt;br /&gt;
| Validity window. Both ends must be tz-aware; &amp;lt;code&amp;gt;start ≤ end&amp;lt;/code&amp;gt;; and on create, &amp;lt;code&amp;gt;start ≥ date&amp;lt;/code&amp;gt;. See [[#periodspec-nested-shape&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;encounter&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;FK → Encounter&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;CASCADE&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;related_name=&amp;amp;quot;consents&amp;amp;quot;&amp;lt;/code&amp;gt;)&lt;br /&gt;
| &amp;lt;code&amp;gt;UUID4&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt;)&lt;br /&gt;
| Required. The encounter this consent applies to; deleting the encounter deletes its consents. Listed in &amp;lt;code&amp;gt;__exclude__&amp;lt;/code&amp;gt;, so it skips the generic DB mapping and is resolved by hand — see [[#methods--save-behaviour&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;decision&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;CharField(10)&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;DecisionType&amp;lt;/code&amp;gt; (enum)&lt;br /&gt;
| Required. &amp;lt;code&amp;gt;permit&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;deny&amp;lt;/code&amp;gt;. See [[#decisiontype-values&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;verification_details&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;JSONField&amp;lt;/code&amp;gt; (default &amp;lt;code&amp;gt;list&amp;lt;/code&amp;gt;)&lt;br /&gt;
| &amp;lt;code&amp;gt;list[ConsentVerificationSpec]&amp;lt;/code&amp;gt;&lt;br /&gt;
| Read-only on the API; one entry per verification record. See [[#consentverificationspec-nested-shape&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;note&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;TextField&amp;lt;/code&amp;gt; (null, blank)&lt;br /&gt;
| &amp;lt;code&amp;gt;str | None&amp;lt;/code&amp;gt;&lt;br /&gt;
| Optional free-text note&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: &amp;lt;code&amp;gt;source_attachments&amp;lt;/code&amp;gt; is &amp;#039;&amp;#039;&amp;#039;not&amp;#039;&amp;#039;&amp;#039; a model field. It is derived at serialize time from &amp;lt;code&amp;gt;FileUpload&amp;lt;/code&amp;gt; rows (see [[#resource-specs-api-schema|Resource specs]]).&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
== Enums ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;ConsentStatusChoices&amp;lt;/code&amp;gt; values ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Value&lt;br /&gt;
! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;draft&amp;lt;/code&amp;gt;&lt;br /&gt;
| Consent is being drafted, not yet in force&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;active&amp;lt;/code&amp;gt;&lt;br /&gt;
| Consent is in force&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;&lt;br /&gt;
| Consent is no longer in force&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;not_done&amp;lt;/code&amp;gt;&lt;br /&gt;
| Consent activity did not occur&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;entered_in_error&amp;lt;/code&amp;gt;&lt;br /&gt;
| Consent was recorded in error&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;CategoryChoice&amp;lt;/code&amp;gt; values ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Value&lt;br /&gt;
! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;research&amp;lt;/code&amp;gt;&lt;br /&gt;
| Consent for research participation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;patient_privacy&amp;lt;/code&amp;gt;&lt;br /&gt;
| Patient privacy / information disclosure consent&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;treatment&amp;lt;/code&amp;gt;&lt;br /&gt;
| Consent to treatment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dnr&amp;lt;/code&amp;gt;&lt;br /&gt;
| Do-not-resuscitate directive&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;comfort_care&amp;lt;/code&amp;gt;&lt;br /&gt;
| Comfort / palliative care directive&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;acd&amp;lt;/code&amp;gt;&lt;br /&gt;
| Advance care directive&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;adr&amp;lt;/code&amp;gt;&lt;br /&gt;
| Advance directive (other)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;A &amp;lt;code&amp;gt;consent_document&amp;lt;/code&amp;gt; category (LOINC 59284-0) exists in migrations only and is &amp;#039;&amp;#039;&amp;#039;not&amp;#039;&amp;#039;&amp;#039; an accepted API value.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
=== &amp;lt;code&amp;gt;DecisionType&amp;lt;/code&amp;gt; values ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Value&lt;br /&gt;
! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;permit&amp;lt;/code&amp;gt;&lt;br /&gt;
| Consent is granted&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;deny&amp;lt;/code&amp;gt;&lt;br /&gt;
| Consent is refused&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;VerificationType&amp;lt;/code&amp;gt; values ===&lt;br /&gt;
&lt;br /&gt;
Used inside &amp;lt;code&amp;gt;ConsentVerificationSpec.verification_type&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Value&lt;br /&gt;
! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;family&amp;lt;/code&amp;gt;&lt;br /&gt;
| Verified by a family member&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;validation&amp;lt;/code&amp;gt;&lt;br /&gt;
| Verified through validation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Nested JSON shapes ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;PeriodSpec&amp;lt;/code&amp;gt; nested shape ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;period&amp;lt;/code&amp;gt; field deserializes to &amp;lt;code&amp;gt;PeriodSpec&amp;lt;/code&amp;gt; (from &amp;lt;code&amp;gt;care/emr/resources/base.py&amp;lt;/code&amp;gt;). The model default is &amp;lt;code&amp;gt;dict&amp;lt;/code&amp;gt;, so an absent period stores &amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Notes&lt;br /&gt;
{{Field|model=Consent|section=PeriodSpec nested shape|name=start|type=datetime | None|notes=Default &amp;lt;code&amp;gt;None&amp;lt;/code&amp;gt;. Must be &amp;#039;&amp;#039;&amp;#039;timezone-aware&amp;#039;&amp;#039;&amp;#039; if set}}&lt;br /&gt;
{{Field|model=Consent|section=PeriodSpec nested shape|name=end|type=datetime | None|notes=Default &amp;lt;code&amp;gt;None&amp;lt;/code&amp;gt;. Must be &amp;#039;&amp;#039;&amp;#039;timezone-aware&amp;#039;&amp;#039;&amp;#039; if set}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;PeriodSpec.validate_period&amp;lt;/code&amp;gt; (mode &amp;lt;code&amp;gt;after&amp;lt;/code&amp;gt;) enforces:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;start&amp;lt;/code&amp;gt; must be tz-aware (else &amp;lt;code&amp;gt;&amp;amp;quot;Start Date must be timezone aware&amp;amp;quot;&amp;lt;/code&amp;gt;).&lt;br /&gt;
* &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; must be tz-aware (else &amp;lt;code&amp;gt;&amp;amp;quot;End Date must be timezone aware&amp;amp;quot;&amp;lt;/code&amp;gt;).&lt;br /&gt;
* If both are set, &amp;lt;code&amp;gt;start ≤ end&amp;lt;/code&amp;gt; (else &amp;lt;code&amp;gt;&amp;amp;quot;Start Date cannot be greater than End Date&amp;amp;quot;&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;ConsentVerificationSpec&amp;lt;/code&amp;gt; nested shape ===&lt;br /&gt;
&lt;br /&gt;
This is the shape each &amp;lt;code&amp;gt;verification_details&amp;lt;/code&amp;gt; entry takes on write. On read, &amp;lt;code&amp;gt;verified_by&amp;lt;/code&amp;gt; is expanded — see below.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Notes&lt;br /&gt;
{{Field|model=Consent|section=ConsentVerificationSpec nested shape|name=verified|type=bool|notes=Required. Whether the consent was verified}}&lt;br /&gt;
{{Field|model=Consent|section=ConsentVerificationSpec nested shape|name=verified_by|type=UUID4 | None|notes=Default &amp;lt;code&amp;gt;None&amp;lt;/code&amp;gt;. On write, the verifying user&amp;#039;s &amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt;. On read, replaced by a full &amp;lt;code&amp;gt;UserSpec&amp;lt;/code&amp;gt; object}}&lt;br /&gt;
{{Field|model=Consent|section=ConsentVerificationSpec nested shape|name=verification_date|type=datetime | None|notes=Default &amp;lt;code&amp;gt;None&amp;lt;/code&amp;gt;}}&lt;br /&gt;
{{Field|model=Consent|section=ConsentVerificationSpec nested shape|name=verification_type|type=VerificationType|notes=Required. &amp;lt;code&amp;gt;family&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;validation&amp;lt;/code&amp;gt;}}&lt;br /&gt;
{{Field|model=Consent|section=ConsentVerificationSpec nested shape|name=note|type=str | None|notes=Default &amp;lt;code&amp;gt;None&amp;lt;/code&amp;gt;}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Resource specs (API schema) ==&lt;br /&gt;
&lt;br /&gt;
Every spec subclasses &amp;lt;code&amp;gt;EMRResource&amp;lt;/code&amp;gt; through &amp;lt;code&amp;gt;ConsentBaseSpec&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;serialize&amp;lt;/code&amp;gt; builds the read schema from the model; &amp;lt;code&amp;gt;de_serialize&amp;lt;/code&amp;gt; writes a model from the payload, skipping &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt; and any &amp;lt;code&amp;gt;__exclude__&amp;lt;/code&amp;gt; field. &amp;lt;code&amp;gt;ConsentBaseSpec&amp;lt;/code&amp;gt; sets &amp;lt;code&amp;gt;__exclude__ = [&amp;amp;quot;encounter&amp;amp;quot;]&amp;lt;/code&amp;gt;, so the encounter FK never round-trips through the generic mapping — the deserialization hooks resolve it instead.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Spec class&lt;br /&gt;
! Role&lt;br /&gt;
! Exposes / behaviour&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ConsentBaseSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| shared base&lt;br /&gt;
| &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;category&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;date&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;period&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;encounter&amp;lt;/code&amp;gt; (UUID4), &amp;lt;code&amp;gt;decision&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;note&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;__model__ = Consent&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;__exclude__ = [&amp;amp;quot;encounter&amp;amp;quot;]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ConsentCreateSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| write · create&lt;br /&gt;
| Same fields as base (all required except &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;note&amp;lt;/code&amp;gt;). Validates &amp;lt;code&amp;gt;period.start ≥ date&amp;lt;/code&amp;gt;; resolves &amp;lt;code&amp;gt;encounter&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Encounter&amp;lt;/code&amp;gt; instance&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ConsentUpdateSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| write · update&lt;br /&gt;
| All fields optional (&amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;category&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;date&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;period&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;encounter&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;decision&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;note&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;None&amp;lt;/code&amp;gt;). Keeps the existing &amp;lt;code&amp;gt;encounter&amp;lt;/code&amp;gt; and ignores any supplied value&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ConsentListSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| read · list&lt;br /&gt;
| Base fields plus derived &amp;lt;code&amp;gt;source_attachments: list&amp;lt;/code&amp;gt; and expanded &amp;lt;code&amp;gt;verification_details: list&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ConsentRetrieveSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| read · detail&lt;br /&gt;
| Identical to &amp;lt;code&amp;gt;ConsentListSpec&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;pass&amp;lt;/code&amp;gt;)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The schema nests [[#periodspec-nested-shape|&amp;lt;code&amp;gt;PeriodSpec&amp;lt;/code&amp;gt;]] for the &amp;lt;code&amp;gt;period&amp;lt;/code&amp;gt; field and [[#consentverificationspec-nested-shape|&amp;lt;code&amp;gt;ConsentVerificationSpec&amp;lt;/code&amp;gt;]] for entries of &amp;lt;code&amp;gt;verification_details&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Validation ===&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Create only&amp;#039;&amp;#039;&amp;#039; (&amp;lt;code&amp;gt;ConsentCreateSpec.validate_period_and_date&amp;lt;/code&amp;gt;, mode &amp;lt;code&amp;gt;after&amp;lt;/code&amp;gt;): if &amp;lt;code&amp;gt;period.start&amp;lt;/code&amp;gt; is set and &amp;lt;code&amp;gt;period.start &amp;amp;lt; date&amp;lt;/code&amp;gt;, raises &amp;lt;code&amp;gt;&amp;amp;quot;Start of the period cannot be before than the Consent date&amp;amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;All specs&amp;#039;&amp;#039;&amp;#039; (via &amp;lt;code&amp;gt;PeriodSpec&amp;lt;/code&amp;gt;): tz-aware &amp;lt;code&amp;gt;start&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;start ≤ end&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Enum fields (&amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;category&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;decision&amp;lt;/code&amp;gt;) reject any value outside their enum. On &amp;lt;code&amp;gt;ConsentUpdateSpec&amp;lt;/code&amp;gt; they may be omitted (&amp;lt;code&amp;gt;None&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Server-maintained behaviour ===&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Encounter resolution (create):&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;ConsentCreateSpec.perform_extra_deserialization&amp;lt;/code&amp;gt; sets &amp;lt;code&amp;gt;obj.encounter = Encounter.objects.get(external_id=self.encounter)&amp;lt;/code&amp;gt; when not an update.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Encounter immutability (update):&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;ConsentUpdateSpec.perform_extra_deserialization&amp;lt;/code&amp;gt; copies &amp;lt;code&amp;gt;self.encounter = obj.encounter&amp;lt;/code&amp;gt;, so an update can&amp;#039;t reassign the encounter through the API.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Source attachments (read):&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;ConsentListSpec.perform_extra_serialization&amp;lt;/code&amp;gt; sets &amp;lt;code&amp;gt;source_attachments&amp;lt;/code&amp;gt; to the serialized &amp;lt;code&amp;gt;FileUploadListSpec&amp;lt;/code&amp;gt; for every &amp;lt;code&amp;gt;FileUpload&amp;lt;/code&amp;gt; where &amp;lt;code&amp;gt;associating_id == consent.external_id&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;file_category == consent_attachment&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;file_type == consent&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Verifier expansion (read):&amp;#039;&amp;#039;&amp;#039; each &amp;lt;code&amp;gt;verification_details[i].verified_by&amp;lt;/code&amp;gt; is replaced with a full &amp;lt;code&amp;gt;UserSpec&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;User.objects.get(external_id=...)&amp;lt;/code&amp;gt;).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Identifiers (read):&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt; is set to &amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt;; &amp;lt;code&amp;gt;encounter&amp;lt;/code&amp;gt; is serialized as &amp;lt;code&amp;gt;obj.encounter.external_id&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Related models ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Consent&amp;lt;/code&amp;gt; points at one &amp;lt;code&amp;gt;Encounter&amp;lt;/code&amp;gt;, and an encounter carries many consents through the &amp;lt;code&amp;gt;consents&amp;lt;/code&amp;gt; reverse relation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;encounter → FK Encounter (CASCADE, related_name=&amp;quot;consents&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The owning patient is reached through &amp;lt;code&amp;gt;encounter&amp;lt;/code&amp;gt;. Coded values (&amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;category&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;decision&amp;lt;/code&amp;gt;) and structured JSON (&amp;lt;code&amp;gt;period&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;verification_details&amp;lt;/code&amp;gt;) are validated by the Pydantic specs at the API layer, not by database constraints.&lt;br /&gt;
&lt;br /&gt;
Read schemas also reach into &amp;lt;code&amp;gt;FileUpload&amp;lt;/code&amp;gt; (consent attachments) and &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; (verifiers) at serialize time.&lt;br /&gt;
&lt;br /&gt;
== Methods &amp;amp;amp; save behaviour ==&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;EMRResource.serialize(obj)&amp;lt;/code&amp;gt; builds the read object: it copies the non-FK model fields present on the spec, runs &amp;lt;code&amp;gt;perform_extra_serialization&amp;lt;/code&amp;gt; (id, encounter &amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;source_attachments&amp;lt;/code&amp;gt;, expanded &amp;lt;code&amp;gt;verification_details&amp;lt;/code&amp;gt;), and stamps &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;EMRResource.de_serialize(obj=None)&amp;lt;/code&amp;gt; builds or updates the model: it dumps the spec (&amp;lt;code&amp;gt;exclude_defaults=True&amp;lt;/code&amp;gt;), assigns matching DB fields (skipping &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;__exclude__&amp;lt;/code&amp;gt;), then runs &amp;lt;code&amp;gt;perform_extra_deserialization&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Because &amp;lt;code&amp;gt;encounter&amp;lt;/code&amp;gt; is in &amp;lt;code&amp;gt;__exclude__&amp;lt;/code&amp;gt;, the generic loop never touches it — create resolves it from &amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt;, update preserves the existing FK.&lt;br /&gt;
* &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt; is a plain field. Setting it to &amp;lt;code&amp;gt;entered_in_error&amp;lt;/code&amp;gt; (or anything else) is a direct write with no status-history side effect.&lt;br /&gt;
&lt;br /&gt;
== API integration notes ==&lt;br /&gt;
&lt;br /&gt;
* Payload field names match the spec, and &amp;lt;code&amp;gt;encounter&amp;lt;/code&amp;gt; is the UUID &amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt;, not the numeric PK — a common source of 404s on create.&lt;br /&gt;
* The model maps to the FHIR &amp;lt;code&amp;gt;Consent&amp;lt;/code&amp;gt; resource; &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;category&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;decision&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;period&amp;lt;/code&amp;gt; line up with their FHIR counterparts.&lt;br /&gt;
* &amp;lt;code&amp;gt;verification_details&amp;lt;/code&amp;gt; is read-only on write and comes back with &amp;lt;code&amp;gt;verified_by&amp;lt;/code&amp;gt; expanded to full user objects.&lt;br /&gt;
* The Pydantic enums, not the database columns, enforce the allowed &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;category&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;decision&amp;lt;/code&amp;gt; values.&lt;br /&gt;
&lt;br /&gt;
{{Related}}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
</feed>