<?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%2FBase_models_%26_conventions</id>
	<title>References/Base models &amp; conventions - 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%2FBase_models_%26_conventions"/>
	<link rel="alternate" type="text/html" href="https://ohcnwiki.tellmey.fyi/index.php?title=References/Base_models_%26_conventions&amp;action=history"/>
	<updated>2026-07-06T05:19: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/Base_models_%26_conventions&amp;diff=162&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/Base_models_%26_conventions&amp;diff=162&amp;oldid=prev"/>
		<updated>2026-07-04T22:45:12Z</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=foundation&lt;br /&gt;
|title=Base models &amp;amp; conventions&lt;br /&gt;
|order=1&lt;br /&gt;
|introduced=3.0&lt;br /&gt;
|model=BaseModels&amp;amp;Conventions&lt;br /&gt;
|reference=References/Charge Item Definition&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Every Care EMR resource inherits a shared base that supplies opaque IDs, audit fields, soft-delete, history, slugs, and feature flags. A resource author writes domain fields and validation; the base handles the rest. It spans two layers:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Storage layer&amp;#039;&amp;#039;&amp;#039; — abstract Django models in &amp;lt;code&amp;gt;care/emr/models&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;care/utils/models&amp;lt;/code&amp;gt;. Several of their columns are opaque &amp;lt;code&amp;gt;JSONField&amp;lt;/code&amp;gt;s whose structure lives elsewhere; the model alone won&amp;#039;t tell you what goes inside them.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;API layer&amp;#039;&amp;#039;&amp;#039; — Pydantic resource specs built on &amp;lt;code&amp;gt;EMRResource&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;care/emr/resources/base.py&amp;lt;/code&amp;gt;). These define enums, field validation, the read/write schemas, and the structured shapes that fill those JSON columns via nested specs. The structured types in &amp;lt;code&amp;gt;care/emr/resources/common/&amp;lt;/code&amp;gt; are reused across nearly every resource.&lt;br /&gt;
&lt;br /&gt;
Come here for the rules a resource gets for free: the soft-delete contract, what &amp;lt;code&amp;gt;serialize&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;de_serialize&amp;lt;/code&amp;gt; do, how write and read schemas diverge, and the common spec types behind the JSON fields. Concrete resources such as [[References/Patient]] inherit a storage base and define their own specs on top of &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; [&amp;lt;nowiki/&amp;gt;https://github.com/ohcnetwork/care/blob/develop/care/emr/models/base.py &amp;lt;code&amp;gt;care/emr/models/base.py&amp;lt;/code&amp;gt;], [&amp;lt;nowiki/&amp;gt;https://github.com/ohcnetwork/care/blob/develop/care/utils/models/base.py &amp;lt;code&amp;gt;care/utils/models/base.py&amp;lt;/code&amp;gt;], [&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;], [&amp;lt;nowiki/&amp;gt;https://github.com/ohcnetwork/care/tree/develop/care/emr/resources/common &amp;lt;code&amp;gt;care/emr/resources/common/&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;
! Layer&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;BaseModel&amp;lt;/code&amp;gt;&lt;br /&gt;
| storage&lt;br /&gt;
| Lowest-level abstract base — opaque &amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt;, timestamps, and soft-delete&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;BaseManager&amp;lt;/code&amp;gt;&lt;br /&gt;
| storage&lt;br /&gt;
| Default manager that hides soft-deleted rows&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;BaseFlag&amp;lt;/code&amp;gt;&lt;br /&gt;
| storage&lt;br /&gt;
| Abstract base for feature-flag tables with cache-backed lookups&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;EMRBaseModel&amp;lt;/code&amp;gt;&lt;br /&gt;
| storage&lt;br /&gt;
| Standard base for EMR resources — adds audit &amp;lt;code&amp;gt;created_by&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;updated_by&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;history&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;meta&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;SlugBaseModel&amp;lt;/code&amp;gt;&lt;br /&gt;
| storage&lt;br /&gt;
| EMR base that adds facility-scoped or instance-scoped slug helpers&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;EMRResource&amp;lt;/code&amp;gt;&lt;br /&gt;
| API&lt;br /&gt;
| Pydantic base for all resource specs — &amp;lt;code&amp;gt;serialize&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;de_serialize&amp;lt;/code&amp;gt; between DB objects and API schemas&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
All five storage models are &amp;lt;code&amp;gt;abstract = True&amp;lt;/code&amp;gt; — none owns a database table. A concrete resource model inherits one and contributes its own columns.&lt;br /&gt;
&lt;br /&gt;
The storage models inherit in one chain:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;models.Model&lt;br /&gt;
  └─ BaseModel            (care/utils/models/base.py)&lt;br /&gt;
       ├─ BaseFlag        (care/utils/models/base.py)&lt;br /&gt;
       └─ EMRBaseModel    (care/emr/models/base.py)&lt;br /&gt;
            └─ SlugBaseModel&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The API specs form a parallel hierarchy under &amp;lt;code&amp;gt;pydantic.BaseModel&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;pydantic.BaseModel&lt;br /&gt;
  └─ EMRResource          (care/emr/resources/base.py)&lt;br /&gt;
       └─ &amp;lt;Resource&amp;gt;SpecBase / &amp;lt;Resource&amp;gt;CreateSpec / ...ReadSpec / ...RetrieveSpec&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
-----&lt;br /&gt;
&lt;br /&gt;
== Storage layer ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;BaseModel&amp;lt;/code&amp;gt; fields ===&lt;br /&gt;
&lt;br /&gt;
The root abstract model. Every other base — and so every persisted Care resource — carries these four columns.&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;
! Required&lt;br /&gt;
! Default&lt;br /&gt;
! Notes&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=BaseModel fields|name=external_id|type=UUIDField|notes=yes}}&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=BaseModel fields|name=created_date|type=DateTimeField|notes=no}}&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=BaseModel fields|name=modified_date|type=DateTimeField|notes=no}}&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=BaseModel fields|name=deleted|type=BooleanField|notes=yes}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;objects&amp;lt;/code&amp;gt; is overridden to a [[#basemanager|&amp;lt;code&amp;gt;BaseManager&amp;lt;/code&amp;gt;]], so the default queryset returns only live rows.&lt;br /&gt;
&lt;br /&gt;
==== Soft delete ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;BaseModel.delete()&amp;lt;/code&amp;gt; issues no SQL &amp;lt;code&amp;gt;DELETE&amp;lt;/code&amp;gt;. It flips the flag and persists only that column:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;def delete(self, *args):&lt;br /&gt;
    self.deleted = True&lt;br /&gt;
    self.save(update_fields=[&amp;quot;deleted&amp;quot;])&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Rows stay put for audit and referential integrity. To reach deleted rows, bypass the default manager — for example via &amp;lt;code&amp;gt;Model._base_manager&amp;lt;/code&amp;gt; or an unfiltered queryset.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;EMRBaseModel&amp;lt;/code&amp;gt; fields ===&lt;br /&gt;
&lt;br /&gt;
The standard base for EMR resource models. On top of the &amp;lt;code&amp;gt;BaseModel&amp;lt;/code&amp;gt; columns it adds audit, history, and metadata:&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;
! Required&lt;br /&gt;
! Default&lt;br /&gt;
! Notes&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=EMRBaseModel fields|name=history|type=JSONField|notes=no}}&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=EMRBaseModel fields|name=meta|type=JSONField|notes=no}}&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=EMRBaseModel fields|name=created_by|type=FK → users.User|notes=no}}&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=EMRBaseModel fields|name=updated_by|type=FK → users.User|notes=no}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;%(app_label)s_%(class)s_…&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;related_name&amp;lt;/code&amp;gt; template lets every concrete subclass reuse the same FK definitions without reverse-accessor collisions.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;SlugBaseModel&amp;lt;/code&amp;gt; helpers ===&lt;br /&gt;
&lt;br /&gt;
Extends &amp;lt;code&amp;gt;EMRBaseModel&amp;lt;/code&amp;gt; for resources that expose a human-readable, scoped slug — value sets and definitions, for instance. It adds no columns of its own; concrete subclasses supply their own &amp;lt;code&amp;gt;slug&amp;lt;/code&amp;gt; and, when facility-scoped, &amp;lt;code&amp;gt;facility&amp;lt;/code&amp;gt; fields. It sets the class flag &amp;lt;code&amp;gt;FACILITY_SCOPED = True&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Method&lt;br /&gt;
! Behaviour&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;calculate_slug_from_facility(facility_external_id, slug)&amp;lt;/code&amp;gt;&lt;br /&gt;
| Class helper → &amp;lt;code&amp;gt;f-&amp;amp;lt;facility_external_id&amp;amp;gt;-&amp;amp;lt;slug&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;calculate_slug_from_instance(slug)&amp;lt;/code&amp;gt;&lt;br /&gt;
| Class helper → &amp;lt;code&amp;gt;i-&amp;amp;lt;slug&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;calculate_slug()&amp;lt;/code&amp;gt;&lt;br /&gt;
| Instance helper — facility-scoped form when &amp;lt;code&amp;gt;FACILITY_SCOPED&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;facility&amp;lt;/code&amp;gt; are set, otherwise instance-scoped&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;parse_slug(slug)&amp;lt;/code&amp;gt;&lt;br /&gt;
| Reverses the encoding; returns &amp;lt;code&amp;gt;{facility, slug_value}&amp;lt;/code&amp;gt; for &amp;lt;code&amp;gt;f-&amp;lt;/code&amp;gt; slugs or &amp;lt;code&amp;gt;{slug_value}&amp;lt;/code&amp;gt; for &amp;lt;code&amp;gt;i-&amp;lt;/code&amp;gt; slugs; raises &amp;lt;code&amp;gt;ValueError&amp;lt;/code&amp;gt; on invalid input&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Slug encoding:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;facility-scoped:  f-&amp;lt;facility external_id (36-char UUID)&amp;gt;-&amp;lt;slug&amp;gt;&lt;br /&gt;
instance-scoped:  i-&amp;lt;slug&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;parse_slug&amp;lt;/code&amp;gt; reads the facility segment as &amp;lt;code&amp;gt;slug[2:38]&amp;lt;/code&amp;gt; (36 chars), validates it as a UUID, takes &amp;lt;code&amp;gt;slug[39:]&amp;lt;/code&amp;gt; as the slug value, and rejects any slug of length ≤ 2.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-----&lt;br /&gt;
&lt;br /&gt;
== Related models ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;BaseManager&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The default manager set as &amp;lt;code&amp;gt;objects&amp;lt;/code&amp;gt; on &amp;lt;code&amp;gt;BaseModel&amp;lt;/code&amp;gt;. Every query through &amp;lt;code&amp;gt;Model.objects&amp;lt;/code&amp;gt; is implicitly scoped to &amp;lt;code&amp;gt;deleted=False&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;def get_queryset(self):&lt;br /&gt;
    return super().get_queryset().filter(deleted=False)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== &amp;lt;code&amp;gt;BaseFlag&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Abstract base for per-entity feature-flag tables (facility or organization flags, for example). It extends &amp;lt;code&amp;gt;BaseModel&amp;lt;/code&amp;gt;, stores one validated flag name, and serves all lookups from cache.&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=BaseModels&amp;amp;Conventions|section=BaseFlag|name=flag|type=CharField(max_length=1024)|notes=Flag name, validated against &amp;lt;code&amp;gt;FlagRegistry&amp;lt;/code&amp;gt; for the subclass&amp;#039;s &amp;lt;code&amp;gt;flag_type&amp;lt;/code&amp;gt;}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Subclasses configure these class attributes:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Attribute&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;cache_key_template&amp;lt;/code&amp;gt;&lt;br /&gt;
| Cache key for a single &amp;lt;code&amp;gt;(entity_id, flag_name)&amp;lt;/code&amp;gt; pair&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;all_flags_cache_key_template&amp;lt;/code&amp;gt;&lt;br /&gt;
| Cache key for all flags of one entity&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;flag_type&amp;lt;/code&amp;gt;&lt;br /&gt;
| Flag category validated against &amp;lt;code&amp;gt;FlagRegistry&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;entity_field_name&amp;lt;/code&amp;gt;&lt;br /&gt;
| Name of the FK field pointing at the owning entity&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Helper properties and classmethods:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Member&lt;br /&gt;
! Behaviour&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;entity&amp;lt;/code&amp;gt;&lt;br /&gt;
| Resolves the related entity via &amp;lt;code&amp;gt;entity_field_name&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;entity_id&amp;lt;/code&amp;gt;&lt;br /&gt;
| Resolves &amp;lt;code&amp;gt;&amp;amp;lt;entity_field_name&amp;amp;gt;_id&amp;lt;/code&amp;gt; without a join&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;validate_flag(flag_name)&amp;lt;/code&amp;gt;&lt;br /&gt;
| Validates the name against &amp;lt;code&amp;gt;FlagRegistry&amp;lt;/code&amp;gt; for &amp;lt;code&amp;gt;flag_type&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;check_entity_has_flag(entity_id, flag_name)&amp;lt;/code&amp;gt;&lt;br /&gt;
| Cached &amp;lt;code&amp;gt;exists()&amp;lt;/code&amp;gt; lookup (TTL 1 day)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;get_all_flags(entity_id)&amp;lt;/code&amp;gt;&lt;br /&gt;
| Cached tuple of all flag names for an entity (TTL 1 day)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-----&lt;br /&gt;
&lt;br /&gt;
== API layer ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;EMRResource&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The Pydantic base (&amp;lt;code&amp;gt;care/emr/resources/base.py&amp;lt;/code&amp;gt;) that every resource spec extends. It moves data both ways between Django model instances and the API schema, and holds the serialization rules in one place.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Class attribute&lt;br /&gt;
! Default&lt;br /&gt;
! Role&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;__model__&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;None&amp;lt;/code&amp;gt;&lt;br /&gt;
| The Django model the spec serializes to/from&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;__exclude__&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;[]&amp;lt;/code&amp;gt;&lt;br /&gt;
| Field names skipped in both &amp;lt;code&amp;gt;serialize&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;de_serialize&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;__store_metadata__&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;False&amp;lt;/code&amp;gt;&lt;br /&gt;
| When &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt;, spec fields that are not DB columns are read from / written to the model&amp;#039;s &amp;lt;code&amp;gt;meta&amp;lt;/code&amp;gt; JSON bag&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;__version__&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;0.1&amp;lt;/code&amp;gt;&lt;br /&gt;
| Stamped onto every serialized object as &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;meta&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt;&lt;br /&gt;
| Open metadata dict carried on the spec itself&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Method&lt;br /&gt;
! Direction&lt;br /&gt;
! Behaviour&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;serialize(obj, user=None)&amp;lt;/code&amp;gt;&lt;br /&gt;
| DB → API&lt;br /&gt;
| Builds a spec via &amp;lt;code&amp;gt;model_construct&amp;lt;/code&amp;gt; from the DB object&amp;#039;s columns; copies &amp;lt;code&amp;gt;meta&amp;lt;/code&amp;gt; fields back out when &amp;lt;code&amp;gt;__store_metadata__&amp;lt;/code&amp;gt;; calls &amp;lt;code&amp;gt;perform_extra_serialization&amp;lt;/code&amp;gt; (always sets &amp;lt;code&amp;gt;mapping[&amp;amp;quot;id&amp;amp;quot;] = obj.external_id&amp;lt;/code&amp;gt;) and, when a &amp;lt;code&amp;gt;user&amp;lt;/code&amp;gt; is passed, &amp;lt;code&amp;gt;perform_extra_user_serialization&amp;lt;/code&amp;gt;; stamps &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;de_serialize(obj=None, partial=False)&amp;lt;/code&amp;gt;&lt;br /&gt;
| API → DB&lt;br /&gt;
| Dumps the spec (&amp;lt;code&amp;gt;exclude_defaults=True&amp;lt;/code&amp;gt;), writes mapped fields onto a new or existing model instance (skipping &amp;lt;code&amp;gt;__exclude__&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt;), routes non-column fields into &amp;lt;code&amp;gt;meta&amp;lt;/code&amp;gt; when &amp;lt;code&amp;gt;__store_metadata__&amp;lt;/code&amp;gt;, then calls &amp;lt;code&amp;gt;perform_extra_deserialization(is_update, obj)&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;is_update&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; when an existing &amp;lt;code&amp;gt;obj&amp;lt;/code&amp;gt; is supplied&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;perform_extra_serialization(mapping, obj)&amp;lt;/code&amp;gt;&lt;br /&gt;
| DB → API&lt;br /&gt;
| Hook for resolving derived/nested read fields; base sets &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;perform_extra_deserialization(is_update, obj)&amp;lt;/code&amp;gt;&lt;br /&gt;
| API → DB&lt;br /&gt;
| Hook for server-side side effects on write (e.g. appending to &amp;lt;code&amp;gt;status_history&amp;lt;/code&amp;gt;, resolving FKs from &amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt;, validating coded values against a value set)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;serialize_audit_users(mapping, obj)&amp;lt;/code&amp;gt;&lt;br /&gt;
| DB → API&lt;br /&gt;
| Helper that fills &amp;lt;code&amp;gt;created_by&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;updated_by&amp;lt;/code&amp;gt; from a cached &amp;lt;code&amp;gt;UserSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;to_json()&amp;lt;/code&amp;gt;&lt;br /&gt;
| —&lt;br /&gt;
| &amp;lt;code&amp;gt;model_dump(mode=&amp;amp;quot;json&amp;amp;quot;, exclude=[&amp;amp;quot;meta&amp;amp;quot;])&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;get_database_mapping()&amp;lt;/code&amp;gt;&lt;br /&gt;
| —&lt;br /&gt;
| Lists the model&amp;#039;s non-FK column names, used to decide which spec fields map to columns&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Each concrete resource exposes a small set of specs built on &amp;lt;code&amp;gt;EMRResource&amp;lt;/code&amp;gt;, named by convention:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Spec class&lt;br /&gt;
! Kind&lt;br /&gt;
! Role&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;amp;lt;X&amp;amp;gt;SpecBase&amp;lt;/code&amp;gt;&lt;br /&gt;
| shared&lt;br /&gt;
| Common fields shared by the write/read specs&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;amp;lt;X&amp;amp;gt;CreateSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| write · create&lt;br /&gt;
| Request body for POST; &amp;lt;code&amp;gt;de_serialize&amp;lt;/code&amp;gt; builds a new model instance&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;amp;lt;X&amp;amp;gt;UpdateSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| write · update&lt;br /&gt;
| Request body for PUT/PATCH; &amp;lt;code&amp;gt;de_serialize&amp;lt;/code&amp;gt; updates an existing instance (&amp;lt;code&amp;gt;is_update=True&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;amp;lt;X&amp;amp;gt;ListSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| read · list&lt;br /&gt;
| Lightweight response for list endpoints&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;amp;lt;X&amp;amp;gt;ReadSpec&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;&amp;amp;lt;X&amp;amp;gt;RetrieveSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| read · detail&lt;br /&gt;
| Full response for the detail endpoint (often resolving nested/coded fields in &amp;lt;code&amp;gt;perform_extra_serialization&amp;lt;/code&amp;gt;)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Coded fields commonly bind to a &amp;#039;&amp;#039;&amp;#039;value set&amp;#039;&amp;#039;&amp;#039; — a &amp;lt;code&amp;gt;system&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;code&amp;lt;/code&amp;gt; allow-list. The resource spec declares the binding (e.g. via &amp;lt;code&amp;gt;json_schema_extra={&amp;amp;quot;slug&amp;amp;quot;: &amp;amp;quot;&amp;amp;lt;valueset-slug&amp;amp;gt;&amp;amp;quot;}&amp;lt;/code&amp;gt; on the field) and validates the submitted &amp;lt;code&amp;gt;Coding&amp;lt;/code&amp;gt; against it in &amp;lt;code&amp;gt;perform_extra_deserialization&amp;lt;/code&amp;gt;. Status fields commonly maintain a server-side &amp;lt;code&amp;gt;status_history&amp;lt;/code&amp;gt; appended on create/update. Each resource page documents its exact bindings and side effects.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;PeriodSpec&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Defined alongside &amp;lt;code&amp;gt;EMRResource&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;base.py&amp;lt;/code&amp;gt;. The validated period type used by write specs — distinct from the looser [[#period|&amp;lt;code&amp;gt;Period&amp;lt;/code&amp;gt;]] read type in &amp;lt;code&amp;gt;common/&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;
! Required&lt;br /&gt;
! Default&lt;br /&gt;
! Validation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;start&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;datetime&amp;lt;/code&amp;gt;&lt;br /&gt;
| no&lt;br /&gt;
| &amp;lt;code&amp;gt;None&amp;lt;/code&amp;gt;&lt;br /&gt;
| must be timezone-aware&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;datetime&amp;lt;/code&amp;gt;&lt;br /&gt;
| no&lt;br /&gt;
| &amp;lt;code&amp;gt;None&amp;lt;/code&amp;gt;&lt;br /&gt;
| must be timezone-aware&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
When both are set, &amp;lt;code&amp;gt;start&amp;lt;/code&amp;gt; must be ≤ &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;. Naive datetimes are rejected with &amp;lt;code&amp;gt;&amp;amp;quot;Start/End Date must be timezone aware&amp;amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;PhoneNumber&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
An &amp;lt;code&amp;gt;Annotated&amp;lt;/code&amp;gt; type exported from &amp;lt;code&amp;gt;base.py&amp;lt;/code&amp;gt;: a phone string validated by &amp;lt;code&amp;gt;PhoneNumberValidator&amp;lt;/code&amp;gt; with &amp;lt;code&amp;gt;number_format=&amp;amp;quot;E164&amp;amp;quot;&amp;lt;/code&amp;gt;, no default region, and no region restriction. Use it wherever a spec field accepts a phone number.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-----&lt;br /&gt;
&lt;br /&gt;
== Shared common specs ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;care/emr/resources/common/&amp;lt;/code&amp;gt; holds the structured types reused across resources — the actual shapes behind many of the opaque &amp;lt;code&amp;gt;JSONField&amp;lt;/code&amp;gt;s in the storage layer.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;Coding&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
A single code from a code system. &amp;lt;code&amp;gt;model_config = extra=&amp;amp;quot;forbid&amp;amp;quot;&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;
! Required&lt;br /&gt;
! Default&lt;br /&gt;
! Notes&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=Coding|name=system|type=str|notes=no}}&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=Coding|name=version|type=str|notes=no}}&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=Coding|name=code|type=str|notes=&amp;#039;&amp;#039;&amp;#039;yes&amp;#039;&amp;#039;&amp;#039;}}&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=Coding|name=display|type=str|notes=no}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;CodeableConcept&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
A concept expressed as one or more codings plus free text. &amp;lt;code&amp;gt;extra=&amp;amp;quot;forbid&amp;amp;quot;&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;
! Required&lt;br /&gt;
! Default&lt;br /&gt;
! Notes&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=CodeableConcept|name=id|type=str|notes=no}}&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=CodeableConcept|name=coding|type=list[Coding]|notes=no}}&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=CodeableConcept|name=text|type=str | None|notes=&amp;#039;&amp;#039;&amp;#039;yes&amp;#039;&amp;#039;&amp;#039; (field present)}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;Period&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The read/storage period shape — looser than &amp;lt;code&amp;gt;PeriodSpec&amp;lt;/code&amp;gt;, with no timezone or ordering validation. &amp;lt;code&amp;gt;extra=&amp;amp;quot;forbid&amp;amp;quot;&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;
! Required&lt;br /&gt;
! Default&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;str&amp;lt;/code&amp;gt;&lt;br /&gt;
| no&lt;br /&gt;
| &amp;lt;code&amp;gt;None&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;start&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;datetime&amp;lt;/code&amp;gt;&lt;br /&gt;
| no&lt;br /&gt;
| &amp;lt;code&amp;gt;None&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;datetime&amp;lt;/code&amp;gt;&lt;br /&gt;
| no&lt;br /&gt;
| &amp;lt;code&amp;gt;None&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;Quantity&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
A measured amount, optionally with coded units. &amp;lt;code&amp;gt;extra=&amp;amp;quot;forbid&amp;amp;quot;&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;
! Required&lt;br /&gt;
! Default&lt;br /&gt;
! Notes&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=Quantity|name=value|type=Decimal|notes=no}}&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=Quantity|name=unit|type=Coding|notes=no}}&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=Quantity|name=meta|type=dict|notes=no}}&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=Quantity|name=code|type=Coding|notes=no}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Ratio&amp;lt;/code&amp;gt; (same file) wraps two &amp;#039;&amp;#039;&amp;#039;required&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;Quantity&amp;lt;/code&amp;gt; values: &amp;lt;code&amp;gt;numerator&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;denominator&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;ContactPoint&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
A means of contact (phone, email, etc.). All three fields are &amp;#039;&amp;#039;&amp;#039;required&amp;#039;&amp;#039;&amp;#039;.&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;
! Required&lt;br /&gt;
! Notes&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=ContactPoint|name=system|type=ContactPointSystemChoices|notes=yes}}&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=ContactPoint|name=value|type=str|notes=yes}}&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=ContactPoint|name=use|type=ContactPointUseChoices|notes=yes}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;ContactPointSystemChoices&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;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;phone&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fax&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;pager&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;url&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sms&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;other&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;ContactPointUseChoices&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;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;home&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;work&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;temp&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;old&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mobile&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;MonetaryComponent&amp;lt;/code&amp;gt; and pricing types ===&lt;br /&gt;
&lt;br /&gt;
Pricing line components used by billing resources (see [[References/Charge Item Definition]], [[References/Charge Item]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;MonetaryComponent&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;
! Required&lt;br /&gt;
! Default&lt;br /&gt;
! Notes&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=MonetaryComponent and pricing types|name=monetary_component_type|type=MonetaryComponentType|notes=&amp;#039;&amp;#039;&amp;#039;yes&amp;#039;&amp;#039;&amp;#039;}}&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=MonetaryComponent and pricing types|name=code|type=Coding|notes=no}}&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=MonetaryComponent and pricing types|name=factor|type=Decimal|notes=no}}&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=MonetaryComponent and pricing types|name=amount|type=Decimal|notes=no}}&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=MonetaryComponent and pricing types|name=tax_included_amount|type=Decimal|notes=no}}&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=MonetaryComponent and pricing types|name=global_component|type=bool|notes=no}}&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=MonetaryComponent and pricing types|name=conditions|type=list[EvaluatorConditionSpec]|notes=no}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Model validators enforce:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;tax_included_amount&amp;lt;/code&amp;gt; is only allowed when &amp;lt;code&amp;gt;monetary_component_type == base&amp;lt;/code&amp;gt;.&lt;br /&gt;
* A &amp;lt;code&amp;gt;base&amp;lt;/code&amp;gt; component must have no &amp;lt;code&amp;gt;conditions&amp;lt;/code&amp;gt; and must set &amp;lt;code&amp;gt;amount&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;amount&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;factor&amp;lt;/code&amp;gt; are mutually exclusive (not both).&lt;br /&gt;
* Either &amp;lt;code&amp;gt;amount&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;factor&amp;lt;/code&amp;gt; must be present — unless &amp;lt;code&amp;gt;global_component&amp;lt;/code&amp;gt; is set together with a &amp;lt;code&amp;gt;code&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;MonetaryComponentType&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;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;base&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;surcharge&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;discount&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;tax&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;informational&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;MonetaryComponentsWithoutBase&amp;lt;/code&amp;gt; (a &amp;lt;code&amp;gt;RootModel&amp;lt;/code&amp;gt; over &amp;lt;code&amp;gt;list[MonetaryComponent]&amp;lt;/code&amp;gt;) adds two list-level rules: no duplicate &amp;lt;code&amp;gt;code.code&amp;lt;/code&amp;gt; values across the list; and, when a base component declares &amp;lt;code&amp;gt;tax_included_amount&amp;lt;/code&amp;gt;, the sum of tax-component amounts (or &amp;lt;code&amp;gt;base.amount * factor&amp;lt;/code&amp;gt;) plus &amp;lt;code&amp;gt;tax_included_amount&amp;lt;/code&amp;gt; must equal the base amount. &amp;lt;code&amp;gt;MonetaryComponents&amp;lt;/code&amp;gt; extends it with one more: at most &amp;#039;&amp;#039;&amp;#039;one&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;base&amp;lt;/code&amp;gt; component.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;MonetaryComponentDefinition&amp;lt;/code&amp;gt; extends &amp;lt;code&amp;gt;MonetaryComponent&amp;lt;/code&amp;gt; for definition-time use: it adds a &amp;#039;&amp;#039;&amp;#039;required&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;title: str&amp;lt;/code&amp;gt;, disables the duplicate-code / amount-or-factor checks, and forbids a &amp;lt;code&amp;gt;base&amp;lt;/code&amp;gt; component entirely.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;DiscountConfiguration&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=BaseModels&amp;amp;Conventions|section=MonetaryComponentType values|name=max_applicable|type=int|notes=&amp;lt;code&amp;gt;ge=0&amp;lt;/code&amp;gt;}}&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=MonetaryComponentType values|name=applicability_order|type=DiscountApplicability|notes=enum below}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;DiscountApplicability&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;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;total_asc&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;total_desc&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;EvaluatorConditionSpec&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
A single condition evaluated against a registered metric — used inside &amp;lt;code&amp;gt;MonetaryComponent.conditions&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;
! Required&lt;br /&gt;
! Notes&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=EvaluatorConditionSpec|name=metric|type=str|notes=yes}}&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=EvaluatorConditionSpec|name=operation|type=str|notes=yes}}&lt;br /&gt;
{{Field|model=BaseModels&amp;amp;Conventions|section=EvaluatorConditionSpec|name=value|type=dict | str|notes=yes}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ValueSet definition types ===&lt;br /&gt;
&lt;br /&gt;
The shapes used to &amp;#039;&amp;#039;define&amp;#039;&amp;#039; a value set (the FHIR &amp;lt;code&amp;gt;compose&amp;lt;/code&amp;gt; structure), used by [[References/Value Set|ValueSet]].&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;ValueSet&amp;lt;/code&amp;gt; — &amp;lt;code&amp;gt;name: str&amp;lt;/code&amp;gt; (required), &amp;lt;code&amp;gt;status: str | None&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;compose: ValueSetCompose&amp;lt;/code&amp;gt; (required).&lt;br /&gt;
* &amp;lt;code&amp;gt;ValueSetCompose&amp;lt;/code&amp;gt; — &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;include: list[ValueSetInclude]&amp;lt;/code&amp;gt; (required), &amp;lt;code&amp;gt;exclude: list[ValueSetInclude] | None&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;property: list[str] | None&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;ValueSetInclude&amp;lt;/code&amp;gt; — &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;system&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;concept: list[ValueSetConcept] | None&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;filter: list[ValueSetFilter] | None&amp;lt;/code&amp;gt;. &amp;#039;&amp;#039;&amp;#039;&amp;lt;code&amp;gt;concept&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;filter&amp;lt;/code&amp;gt; are mutually exclusive.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* &amp;lt;code&amp;gt;ValueSetConcept&amp;lt;/code&amp;gt; — &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;code&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;display&amp;lt;/code&amp;gt; (all optional).&lt;br /&gt;
* &amp;lt;code&amp;gt;ValueSetFilter&amp;lt;/code&amp;gt; — &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;property&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;op&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;value&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;op&amp;lt;/code&amp;gt; must be one of: &amp;lt;code&amp;gt;=&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;is-a&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;descendent-of&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;is-not-a&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;regex&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;in&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;not-in&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;generalizes&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;child-of&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;descendent-leaf&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;exists&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
All ValueSet types use &amp;lt;code&amp;gt;extra=&amp;amp;quot;forbid&amp;amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;MailTypeChoices&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Defined in &amp;lt;code&amp;gt;common/mail_type.py&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;create&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;create_password&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;reset&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;reset_password&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-----&lt;br /&gt;
&lt;br /&gt;
== Methods &amp;amp;amp; save behaviour ==&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;BaseModel.delete()&amp;lt;/code&amp;gt; soft-deletes: sets &amp;lt;code&amp;gt;deleted=True&amp;lt;/code&amp;gt; and saves only that field, never a hard &amp;lt;code&amp;gt;DELETE&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;BaseFlag.save()&amp;lt;/code&amp;gt; validates &amp;lt;code&amp;gt;flag&amp;lt;/code&amp;gt; against &amp;lt;code&amp;gt;FlagRegistry&amp;lt;/code&amp;gt;, then evicts the single-flag and all-flags cache entries for the entity before persisting, so cached lookups stay consistent.&lt;br /&gt;
* &amp;lt;code&amp;gt;BaseFlag.check_entity_has_flag&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;get_all_flags&amp;lt;/code&amp;gt; populate those caches on read with a 1-day TTL (&amp;lt;code&amp;gt;FLAGS_CACHE_TTL = 60 * 60 * 24&amp;lt;/code&amp;gt;).&lt;br /&gt;
* &amp;lt;code&amp;gt;SlugBaseModel&amp;lt;/code&amp;gt; exposes slug encode/parse helpers but does not override &amp;lt;code&amp;gt;save()&amp;lt;/code&amp;gt;; subclasses decide when to call &amp;lt;code&amp;gt;calculate_slug()&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;EMRResource.de_serialize&amp;lt;/code&amp;gt; is where write-time side effects happen — subclasses override &amp;lt;code&amp;gt;perform_extra_deserialization&amp;lt;/code&amp;gt; to append to status histories, resolve FKs from &amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt;, and validate coded fields against bound value sets.&lt;br /&gt;
* &amp;lt;code&amp;gt;cacheable(...)&amp;lt;/code&amp;gt; (in &amp;lt;code&amp;gt;base.py&amp;lt;/code&amp;gt;) is a decorator that marks a spec cacheable and wires a &amp;lt;code&amp;gt;post_save&amp;lt;/code&amp;gt; signal to invalidate the per-instance serializer cache; &amp;lt;code&amp;gt;model_from_cache&amp;lt;/code&amp;gt; then serves serialized specs from cache by &amp;lt;code&amp;gt;pk&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== API integration notes ==&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt; (UUID) is the identifier used across Care&amp;#039;s REST API and FHIR resources; the integer primary key is internal and never exposed. &amp;lt;code&amp;gt;EMRResource.serialize&amp;lt;/code&amp;gt; surfaces it as &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;de_serialize&amp;lt;/code&amp;gt; refuses to write &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt; from request bodies.&lt;br /&gt;
* Deletes are soft — a resource removed through the API still exists in the database with &amp;lt;code&amp;gt;deleted=True&amp;lt;/code&amp;gt;, hidden by the default manager.&lt;br /&gt;
* &amp;lt;code&amp;gt;history&amp;lt;/code&amp;gt; is not returned by standard endpoints; every version (including migration-time changes) is stored flattened with its performer and served through a separate, on-request audit API.&lt;br /&gt;
* &amp;lt;code&amp;gt;meta&amp;lt;/code&amp;gt; is the supported way to attach system metadata without a schema migration; specs with &amp;lt;code&amp;gt;__store_metadata__ = True&amp;lt;/code&amp;gt; round-trip extra fields through it. &amp;lt;code&amp;gt;created_by&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;updated_by&amp;lt;/code&amp;gt; are platform-maintained audit fields — clients must not set them directly.&lt;br /&gt;
* Periods sent on write (&amp;lt;code&amp;gt;PeriodSpec&amp;lt;/code&amp;gt;) must be timezone-aware and ordered (&amp;lt;code&amp;gt;start ≤ end&amp;lt;/code&amp;gt;); the read-side &amp;lt;code&amp;gt;Period&amp;lt;/code&amp;gt; type does not enforce this.&lt;br /&gt;
* Feature-flag state (&amp;lt;code&amp;gt;BaseFlag&amp;lt;/code&amp;gt; subclasses) is read through the cached classmethods, not queried row-by-row.&lt;br /&gt;
&lt;br /&gt;
{{Related}}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
</feed>