<?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%2FOrganization</id>
	<title>References/Organization - 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%2FOrganization"/>
	<link rel="alternate" type="text/html" href="https://ohcnwiki.tellmey.fyi/index.php?title=References/Organization&amp;action=history"/>
	<updated>2026-07-06T07:09:52Z</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/Organization&amp;diff=427&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/Organization&amp;diff=427&amp;oldid=prev"/>
		<updated>2026-07-06T04:06:40Z</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:36, 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 326:&lt;/td&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 326:&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;metadata&amp;lt;/code&amp;gt; is the supported place for deployment-specific key-value data without schema migrations; the specs pass it through verbatim as &amp;lt;code&amp;gt;dict&amp;lt;/code&amp;gt;.&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;metadata&amp;lt;/code&amp;gt; is the supported place for deployment-specific key-value data without schema migrations; the specs pass it through verbatim as &amp;lt;code&amp;gt;dict&amp;lt;/code&amp;gt;.&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;* Soft-delete applies (via &amp;lt;code&amp;gt;EMRBaseModel&amp;lt;/code&amp;gt;); an organization can&#039;t be deleted while it still has children, and system-generated orgs can&#039;t be deleted.&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;* Soft-delete applies (via &amp;lt;code&amp;gt;EMRBaseModel&amp;lt;/code&amp;gt;); an organization can&#039;t be deleted while it still has children, and system-generated orgs can&#039;t be deleted.&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 access governance}}&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/Organization&amp;diff=128&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/Organization&amp;diff=128&amp;oldid=prev"/>
		<updated>2026-07-04T22:43:48Z</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=access-governance&lt;br /&gt;
|title=Organization&lt;br /&gt;
|order=1&lt;br /&gt;
|introduced=3.0&lt;br /&gt;
|model=Organization&lt;br /&gt;
|reference=References/Permission&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Organizations are Care&amp;#039;s FHIR-aligned grouping primitive: a nested tree that groups permissions and resources. A node might represent all doctors, a &amp;lt;code&amp;gt;Cardiology&amp;lt;/code&amp;gt; sub-team, or a governance unit, and permissions attached to a parent flow implicitly to every descendant. You touch them whenever you model who can do what, and where.&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/organization.py &amp;lt;code&amp;gt;care/emr/models/organization.py&amp;lt;/code&amp;gt;] · [&amp;lt;nowiki/&amp;gt;https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/organization/spec.py &amp;lt;code&amp;gt;resources/organization/spec.py&amp;lt;/code&amp;gt;] · [&amp;lt;nowiki/&amp;gt;https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/organization/organization_user_spec.py &amp;lt;code&amp;gt;resources/organization/organization_user_spec.py&amp;lt;/code&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
The Django model is only the storage layer. Its opaque columns — &amp;lt;code&amp;gt;JSONField&amp;lt;/code&amp;gt;s (&amp;lt;code&amp;gt;metadata&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;cached_parent_json&amp;lt;/code&amp;gt;) and arrays (&amp;lt;code&amp;gt;parent_cache&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;managing_organizations&amp;lt;/code&amp;gt;) — get their structure from the resource specs under &amp;lt;code&amp;gt;care/emr/resources/organization/&amp;lt;/code&amp;gt;, which also define the &amp;lt;code&amp;gt;org_type&amp;lt;/code&amp;gt; enum, validation, the nested JSON returned for &amp;lt;code&amp;gt;parent&amp;lt;/code&amp;gt;, and the read/write API schemas. See [[#resource-specs-api-schema|Resource specs (API schema)]].&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;OrganizationCommonBase&amp;lt;/code&amp;gt;&lt;br /&gt;
| Abstract base holding the tree structure, caching, and uniqueness logic shared by both organization types&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Organization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Instance-wide organization (permission/governance tree, not tied to a facility)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;FacilityOrganization&amp;lt;/code&amp;gt;&lt;br /&gt;
| Facility-scoped organization (departments/teams within one &amp;lt;code&amp;gt;Facility&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;OrganizationUser&amp;lt;/code&amp;gt;&lt;br /&gt;
| Membership row linking a &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; to an &amp;lt;code&amp;gt;Organization&amp;lt;/code&amp;gt; with a &amp;lt;code&amp;gt;RoleModel&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;FacilityOrganizationUser&amp;lt;/code&amp;gt;&lt;br /&gt;
| Membership row linking a &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; to a &amp;lt;code&amp;gt;FacilityOrganization&amp;lt;/code&amp;gt; with a &amp;lt;code&amp;gt;RoleModel&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Organization&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;FacilityOrganization&amp;lt;/code&amp;gt; extend &amp;lt;code&amp;gt;OrganizationCommonBase&amp;lt;/code&amp;gt;, which extends [[References/Base models &amp;amp;amp; conventions|&amp;lt;code&amp;gt;EMRBaseModel&amp;lt;/code&amp;gt;]] — the shared Care EMR base providing &amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt;, audit fields, soft-delete, and &amp;lt;code&amp;gt;history&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;meta&amp;lt;/code&amp;gt; JSON. &amp;lt;code&amp;gt;OrganizationUser&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;FacilityOrganizationUser&amp;lt;/code&amp;gt; extend &amp;lt;code&amp;gt;EMRBaseModel&amp;lt;/code&amp;gt; directly. &amp;lt;code&amp;gt;OrganizationCommonBase&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;abstract = True&amp;lt;/code&amp;gt; and has no table of its own.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;code&amp;gt;OrganizationCommonBase&amp;lt;/code&amp;gt; fields ==&lt;br /&gt;
&lt;br /&gt;
These columns land on both the &amp;lt;code&amp;gt;Organization&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;FacilityOrganization&amp;lt;/code&amp;gt; tables.&lt;br /&gt;
&lt;br /&gt;
=== Identity &amp;amp;amp; classification ===&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=Organization|section=Identity &amp;amp;amp; classification|name=name|type=CharField(255)|notes=yes}}&lt;br /&gt;
{{Field|model=Organization|section=Identity &amp;amp;amp; classification|name=org_type|type=CharField(255)|notes=yes}}&lt;br /&gt;
{{Field|model=Organization|section=Identity &amp;amp;amp; classification|name=description|type=TextField|notes=no}}&lt;br /&gt;
{{Field|model=Organization|section=Identity &amp;amp;amp; classification|name=active|type=BooleanField|notes=no}}&lt;br /&gt;
{{Field|model=Organization|section=Identity &amp;amp;amp; classification|name=system_generated|type=BooleanField|notes=no}}&lt;br /&gt;
{{Field|model=Organization|section=Identity &amp;amp;amp; classification|name=metadata|type=JSONField|notes=no}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Tree structure ===&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=Organization|section=Tree structure|name=parent|type=FK → self|notes=no}}&lt;br /&gt;
{{Field|model=Organization|section=Tree structure|name=root_org|type=FK → self|notes=no}}&lt;br /&gt;
{{Field|model=Organization|section=Tree structure|name=has_children|type=BooleanField|notes=no}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Denormalized caches ===&lt;br /&gt;
&lt;br /&gt;
Care rebuilds these on insert so reading the tree doesn&amp;#039;t need recursive joins. Do not set them from clients.&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;
! Default&lt;br /&gt;
! Rebuilt by&lt;br /&gt;
! Shape&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;level_cache&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;IntegerField&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;set_organization_cache()&amp;lt;/code&amp;gt;&lt;br /&gt;
| Depth in the tree (&amp;lt;code&amp;gt;parent.level_cache + 1&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;parent_cache&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;ArrayField[int]&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;[]&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;list&amp;lt;/code&amp;gt;)&lt;br /&gt;
| &amp;lt;code&amp;gt;set_organization_cache()&amp;lt;/code&amp;gt;&lt;br /&gt;
| Full ancestor &amp;#039;&amp;#039;&amp;#039;internal id&amp;#039;&amp;#039;&amp;#039; chain (&amp;lt;code&amp;gt;parent.parent_cache + [parent.id]&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;cached_parent_json&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;JSONField&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;dict&amp;lt;/code&amp;gt;)&lt;br /&gt;
| &amp;lt;code&amp;gt;get_parent_json()&amp;lt;/code&amp;gt;&lt;br /&gt;
| Materialized parent record (shape below). Rebuilt after &amp;lt;code&amp;gt;cache_expiry_days&amp;lt;/code&amp;gt; (15)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cached_parent_json&amp;lt;/code&amp;gt; is built in &amp;lt;code&amp;gt;get_parent_json()&amp;lt;/code&amp;gt; and is &amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt; for root orgs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;{&lt;br /&gt;
  id:           str   (parent.external_id, UUID as string)&lt;br /&gt;
  name:         str&lt;br /&gt;
  description:  str | null&lt;br /&gt;
  org_type:     str   (OrganizationTypeChoices value)&lt;br /&gt;
  metadata:     dict&lt;br /&gt;
  parent:       dict  (recursively, the parent&amp;#039;s own cached_parent_json)&lt;br /&gt;
  level_cache:  int&lt;br /&gt;
  cache_expiry: str   (ISO datetime; cache is reused while now &amp;lt; cache_expiry)&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This is the same structure &amp;lt;code&amp;gt;OrganizationReadSpec.parent&amp;lt;/code&amp;gt; returns on read (see [[#parent-read-shape|&amp;lt;code&amp;gt;parent&amp;lt;/code&amp;gt; read shape]]).&lt;br /&gt;
&lt;br /&gt;
== Related models ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;Organization&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Instance-wide organization. Adds one field on top of &amp;lt;code&amp;gt;OrganizationCommonBase&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;
! Default&lt;br /&gt;
! Notes&lt;br /&gt;
{{Field|model=Organization|section=Organization|name=managing_organizations|type=ArrayField[int]|notes=&amp;lt;code&amp;gt;[]&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;list&amp;lt;/code&amp;gt;)}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;FacilityOrganization&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Facility-scoped organization — departments, teams, and groups within one facility. Adds one field on top of &amp;lt;code&amp;gt;OrganizationCommonBase&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;facility → FK facility.Facility  (CASCADE)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Its &amp;lt;code&amp;gt;org_type&amp;lt;/code&amp;gt; binds to &amp;lt;code&amp;gt;FacilityOrganizationTypeChoices&amp;lt;/code&amp;gt; rather than &amp;lt;code&amp;gt;OrganizationTypeChoices&amp;lt;/code&amp;gt; (see [[#facility-organization-type-values|Facility organization type values]]), and its specs live in &amp;lt;code&amp;gt;resources/facility_organization/&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;FacilityOrganizationWriteSpec&amp;lt;/code&amp;gt; requires &amp;lt;code&amp;gt;facility&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;org_type&amp;lt;/code&amp;gt; + optional &amp;lt;code&amp;gt;parent&amp;lt;/code&amp;gt; (validated to be in the same facility); &amp;lt;code&amp;gt;FacilityOrganizationReadSpec&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;FacilityOrganizationRetrieveSpec&amp;lt;/code&amp;gt; mirror the instance read specs, resolving the caller&amp;#039;s &amp;lt;code&amp;gt;permissions&amp;lt;/code&amp;gt; through &amp;lt;code&amp;gt;get_permission_on_facility_organization&amp;lt;/code&amp;gt;. See [[References/Facility]].&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;OrganizationUser&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Grants a user access to an organization&amp;#039;s resources through a role — only the resources assigned to the org, not everything it owns.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;organization → FK Organization (CASCADE)&lt;br /&gt;
user         → FK users.User   (CASCADE)&lt;br /&gt;
role         → FK security.RoleModel (CASCADE)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== &amp;lt;code&amp;gt;FacilityOrganizationUser&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The facility-scoped equivalent of &amp;lt;code&amp;gt;OrganizationUser&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;organization → FK FacilityOrganization (CASCADE)&lt;br /&gt;
user         → FK users.User           (CASCADE)&lt;br /&gt;
role         → FK security.RoleModel    (CASCADE)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Enum &amp;amp;amp; coded values ==&lt;br /&gt;
&lt;br /&gt;
=== Organization type values ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Organization.org_type&amp;lt;/code&amp;gt; is a &amp;lt;code&amp;gt;CharField&amp;lt;/code&amp;gt; in the DB, but every write binds to &amp;lt;code&amp;gt;OrganizationTypeChoices&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;resources/organization/spec.py&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;team&amp;lt;/code&amp;gt;&lt;br /&gt;
| A working / department-style grouping of people (the default)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;govt&amp;lt;/code&amp;gt;&lt;br /&gt;
| A governance unit mirroring a real administrative hierarchy (&amp;lt;code&amp;gt;State → District → …&amp;lt;/code&amp;gt;). Any user can view these to support cross-governance coordination; create/edit is superadmin-only; facilities and patients reference these nodes geographically&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;role&amp;lt;/code&amp;gt;&lt;br /&gt;
| A &amp;#039;&amp;#039;&amp;#039;user group&amp;#039;&amp;#039;&amp;#039; — a flat set of users, e.g. &amp;#039;&amp;#039;Volunteer&amp;#039;&amp;#039;, &amp;#039;&amp;#039;ASHA Worker&amp;#039;&amp;#039;. Adding an &amp;lt;code&amp;gt;OrganizationUser&amp;lt;/code&amp;gt; to a &amp;lt;code&amp;gt;role&amp;lt;/code&amp;gt;-typed org invalidates that user&amp;#039;s &amp;lt;code&amp;gt;cached_role_orgs&amp;lt;/code&amp;gt; (see [[#organizationusersave&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;product_supplier&amp;lt;/code&amp;gt;&lt;br /&gt;
| Supplier organization (links to the supply chain)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Facility organization type values ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;FacilityOrganization.org_type&amp;lt;/code&amp;gt; binds to a &amp;#039;&amp;#039;&amp;#039;separate&amp;#039;&amp;#039;&amp;#039; enum — &amp;lt;code&amp;gt;FacilityOrganizationTypeChoices&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;resources/facility_organization/spec.py&amp;lt;/code&amp;gt;), &amp;#039;&amp;#039;&amp;#039;not&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;OrganizationTypeChoices&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;root&amp;lt;/code&amp;gt;&lt;br /&gt;
| System-generated top node, one per facility (cannot be edited or deleted)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dept&amp;lt;/code&amp;gt;&lt;br /&gt;
| A department within the facility&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt;&lt;br /&gt;
| A team, often nested under a department&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;role&amp;lt;/code&amp;gt;&lt;br /&gt;
| A facility-scoped user group&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;other&amp;lt;/code&amp;gt;&lt;br /&gt;
| Any grouping outside the categories above&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Root, &amp;lt;code&amp;gt;govt&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;role&amp;lt;/code&amp;gt; (instance) organizations, plus any system-generated organization, are restricted to superadmin management.&lt;br /&gt;
&lt;br /&gt;
== Resource specs (API schema) ==&lt;br /&gt;
&lt;br /&gt;
Resource specs (&amp;lt;code&amp;gt;EMRResource&amp;lt;/code&amp;gt; subclasses) are the API layer. &amp;lt;code&amp;gt;serialize&amp;lt;/code&amp;gt; builds a read object from a DB row, running the &amp;lt;code&amp;gt;perform_extra_serialization&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;perform_extra_user_serialization&amp;lt;/code&amp;gt; hooks; &amp;lt;code&amp;gt;de_serialize&amp;lt;/code&amp;gt; builds a DB row from a write payload, running &amp;lt;code&amp;gt;perform_extra_deserialization&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;__exclude__&amp;lt;/code&amp;gt; lists the model fields the base serializer skips so a hook can handle them instead.&lt;br /&gt;
&lt;br /&gt;
=== Organization specs (&amp;lt;code&amp;gt;resources/organization/spec.py&amp;lt;/code&amp;gt;) ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Spec&lt;br /&gt;
! Role&lt;br /&gt;
! Fields exposed&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;OrganizationBaseSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| shared&lt;br /&gt;
| &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;active&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;org_type&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;metadata&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;__model__ = Organization&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;__exclude__ = [&amp;amp;quot;parent&amp;amp;quot;]&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;org_type&amp;lt;/code&amp;gt; bound to &amp;lt;code&amp;gt;OrganizationTypeChoices&amp;lt;/code&amp;gt;; &amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt; defaults &amp;lt;code&amp;gt;&amp;amp;quot;&amp;amp;quot;&amp;lt;/code&amp;gt;; &amp;lt;code&amp;gt;metadata&amp;lt;/code&amp;gt; defaults &amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;OrganizationUpdateSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| write · update&lt;br /&gt;
| (inherits &amp;lt;code&amp;gt;OrganizationBaseSpec&amp;lt;/code&amp;gt;)&lt;br /&gt;
| No extra fields — &amp;lt;code&amp;gt;parent&amp;lt;/code&amp;gt; can&amp;#039;t change on update&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;OrganizationWriteSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| write · create&lt;br /&gt;
| base + &amp;lt;code&amp;gt;parent: UUID4 | null&amp;lt;/code&amp;gt;&lt;br /&gt;
| Validates &amp;lt;code&amp;gt;parent&amp;lt;/code&amp;gt; exists (&amp;lt;code&amp;gt;validate_parent_organization&amp;lt;/code&amp;gt;); on create, &amp;lt;code&amp;gt;perform_extra_deserialization&amp;lt;/code&amp;gt; resolves &amp;lt;code&amp;gt;parent&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt; (or sets &amp;lt;code&amp;gt;None&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;OrganizationReadSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| read · list&lt;br /&gt;
| base + &amp;lt;code&amp;gt;level_cache&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;system_generated&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;has_children&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;parent: dict&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;perform_extra_serialization&amp;lt;/code&amp;gt; sets &amp;lt;code&amp;gt;id = external_id&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;parent = obj.get_parent_json()&amp;lt;/code&amp;gt; — see [[#parent-read-shape&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;OrganizationRetrieveSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| read · detail&lt;br /&gt;
| &amp;lt;code&amp;gt;OrganizationReadSpec&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;permissions: list[str]&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;managing_organizations: list[dict]&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;perform_extra_user_serialization&amp;lt;/code&amp;gt; fills &amp;lt;code&amp;gt;permissions&amp;lt;/code&amp;gt; (via &amp;lt;code&amp;gt;AuthorizationController.get_permission_on_organization&amp;lt;/code&amp;gt; for the requesting user), expands &amp;lt;code&amp;gt;managing_organizations&amp;lt;/code&amp;gt; to nested &amp;lt;code&amp;gt;OrganizationReadSpec&amp;lt;/code&amp;gt; JSON, and adds audit users (&amp;lt;code&amp;gt;serialize_audit_users&amp;lt;/code&amp;gt;)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;parent&amp;lt;/code&amp;gt; read shape ====&lt;br /&gt;
&lt;br /&gt;
On read, &amp;lt;code&amp;gt;OrganizationReadSpec.parent&amp;lt;/code&amp;gt; (and &amp;lt;code&amp;gt;OrganizationRetrieveSpec.parent&amp;lt;/code&amp;gt;) is &amp;#039;&amp;#039;&amp;#039;not&amp;#039;&amp;#039;&amp;#039; a UUID — it&amp;#039;s the nested object from &amp;lt;code&amp;gt;get_parent_json()&amp;lt;/code&amp;gt;, sharing the shape of [[#denormalized-caches|&amp;lt;code&amp;gt;cached_parent_json&amp;lt;/code&amp;gt;]]: &amp;lt;code&amp;gt;{ id, name, description, org_type, metadata, parent (recursive), level_cache, cache_expiry }&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt; for root orgs. On write, &amp;lt;code&amp;gt;parent&amp;lt;/code&amp;gt; is instead a plain &amp;lt;code&amp;gt;UUID4&amp;lt;/code&amp;gt; (the parent&amp;#039;s &amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Membership specs (&amp;lt;code&amp;gt;resources/organization/organization_user_spec.py&amp;lt;/code&amp;gt;) ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Spec&lt;br /&gt;
! Role&lt;br /&gt;
! Fields exposed&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;OrganizationUserBaseSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| shared&lt;br /&gt;
| (none)&lt;br /&gt;
| &amp;lt;code&amp;gt;__model__ = OrganizationUser&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;__exclude__ = [&amp;amp;quot;user&amp;amp;quot;, &amp;amp;quot;role&amp;amp;quot;]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;OrganizationUserUpdateSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| write · update&lt;br /&gt;
| &amp;lt;code&amp;gt;role: UUID4&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;validate_role&amp;lt;/code&amp;gt; requires the &amp;lt;code&amp;gt;RoleModel&amp;lt;/code&amp;gt; to exist; &amp;lt;code&amp;gt;perform_extra_deserialization&amp;lt;/code&amp;gt; resolves &amp;lt;code&amp;gt;role&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt;. Only the role can change on update&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;OrganizationUserWriteSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| write · create&lt;br /&gt;
| &amp;lt;code&amp;gt;role: UUID4&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;user: UUID4&amp;lt;/code&amp;gt;&lt;br /&gt;
| Extends the update spec; &amp;lt;code&amp;gt;validate_user&amp;lt;/code&amp;gt; requires the &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; to exist. On create, resolves both &amp;lt;code&amp;gt;user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;role&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;OrganizationUserReadSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| read&lt;br /&gt;
| &amp;lt;code&amp;gt;id: UUID4&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;user: dict&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;role: dict&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;user&amp;lt;/code&amp;gt; = cached &amp;lt;code&amp;gt;UserSpec&amp;lt;/code&amp;gt; JSON (&amp;lt;code&amp;gt;model_from_cache&amp;lt;/code&amp;gt;); &amp;lt;code&amp;gt;role&amp;lt;/code&amp;gt; = &amp;lt;code&amp;gt;RoleReadSpec&amp;lt;/code&amp;gt; JSON (full permissions)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;OrganizationUserExtendedReadSpec&amp;lt;/code&amp;gt;&lt;br /&gt;
| read&lt;br /&gt;
| &amp;lt;code&amp;gt;id: UUID4&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;role: dict&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;organization: dict&amp;lt;/code&amp;gt;&lt;br /&gt;
| Used by &amp;lt;code&amp;gt;OrganizationUser.get_cached_role_orgs()&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;organization&amp;lt;/code&amp;gt; = &amp;lt;code&amp;gt;OrganizationReadSpec&amp;lt;/code&amp;gt; JSON; &amp;lt;code&amp;gt;role&amp;lt;/code&amp;gt; = &amp;lt;code&amp;gt;RoleReadMinimalSpec&amp;lt;/code&amp;gt; JSON (no permission list)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Nested membership JSON shapes (from &amp;lt;code&amp;gt;resources/role/spec.py&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;resources/user/spec.py&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;role  (RoleReadSpec):        { id: UUID, name, description, is_system: bool,&lt;br /&gt;
                               is_archived: bool, contexts: [RoleContext],&lt;br /&gt;
                               permissions: [{ name, description, slug, context }] }&lt;br /&gt;
role  (RoleReadMinimalSpec): same as above without `permissions`&lt;br /&gt;
user  (UserSpec):            cached user summary JSON&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Methods &amp;amp;amp; save behaviour ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;OrganizationCommonBase.save()&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
On insert (no &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt; yet), the base saves the row, then calls &amp;lt;code&amp;gt;set_organization_cache()&amp;lt;/code&amp;gt; to populate the tree caches. Updates save normally and don&amp;#039;t recompute caches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;set_organization_cache()&amp;lt;/code&amp;gt; side effects when a &amp;lt;code&amp;gt;parent&amp;lt;/code&amp;gt; is set:&lt;br /&gt;
&lt;br /&gt;
# Computes &amp;lt;code&amp;gt;parent_cache&amp;lt;/code&amp;gt; = &amp;lt;code&amp;gt;parent.parent_cache + [parent.id]&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;level_cache&amp;lt;/code&amp;gt; = &amp;lt;code&amp;gt;parent.level_cache + 1&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Derives &amp;lt;code&amp;gt;root_org&amp;lt;/code&amp;gt; from the parent (&amp;lt;code&amp;gt;parent.root_org&amp;lt;/code&amp;gt;, or the parent itself if the parent is a root).&lt;br /&gt;
# If the parent had no children before, flips &amp;lt;code&amp;gt;parent.has_children = True&amp;lt;/code&amp;gt; and persists only that field.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;get_parent_json()&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Returns the cached parent JSON while &amp;lt;code&amp;gt;cached_parent_json&amp;lt;/code&amp;gt; is present and &amp;lt;code&amp;gt;cache_expiry&amp;lt;/code&amp;gt; is still in the future. Otherwise it recursively rebuilds the nested parent record, stamps a new expiry (&amp;lt;code&amp;gt;cache_expiry_days = 15&amp;lt;/code&amp;gt;), and persists &amp;lt;code&amp;gt;cached_parent_json&amp;lt;/code&amp;gt;. Returns &amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt; for root orgs. This is what &amp;lt;code&amp;gt;OrganizationReadSpec.parent&amp;lt;/code&amp;gt; exposes on every read.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;validate_uniqueness(queryset, pydantic_instance, model_instance)&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Classmethod enforcing &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; uniqueness among &amp;#039;&amp;#039;&amp;#039;siblings&amp;#039;&amp;#039;&amp;#039; — those sharing the same &amp;lt;code&amp;gt;root_org&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;level_cache&amp;lt;/code&amp;gt;. For a new org it derives &amp;lt;code&amp;gt;level_cache&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;root_org&amp;lt;/code&amp;gt; from the supplied &amp;lt;code&amp;gt;parent&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt;); a null parent means &amp;lt;code&amp;gt;level_cache = 0&amp;lt;/code&amp;gt; and a null &amp;lt;code&amp;gt;root_org&amp;lt;/code&amp;gt;. The resource layer calls it before create/update.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;OrganizationUser.save()&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
After saving, if the linked organization&amp;#039;s &amp;lt;code&amp;gt;org_type&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;role&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;OrganizationTypeChoices.role&amp;lt;/code&amp;gt;), it clears &amp;lt;code&amp;gt;user.cached_role_orgs&amp;lt;/code&amp;gt; (sets it to &amp;lt;code&amp;gt;None&amp;lt;/code&amp;gt; and persists that field) so the user&amp;#039;s role-org cache rebuilds on the next read.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;OrganizationUser.get_cached_role_orgs(user_id)&amp;lt;/code&amp;gt; is a classmethod that serializes all of a user&amp;#039;s &amp;lt;code&amp;gt;role&amp;lt;/code&amp;gt;-typed org memberships via &amp;lt;code&amp;gt;OrganizationUserExtendedReadSpec&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== API integration notes ==&lt;br /&gt;
&lt;br /&gt;
* Organizations are exposed through Care&amp;#039;s REST API and align with the FHIR &amp;lt;code&amp;gt;Organization&amp;lt;/code&amp;gt; resource. Tree position (&amp;lt;code&amp;gt;level_cache&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;parent_cache&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;root_org&amp;lt;/code&amp;gt;), &amp;lt;code&amp;gt;has_children&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;cached_parent_json&amp;lt;/code&amp;gt; are platform-maintained — don&amp;#039;t set them from clients.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Write path:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;OrganizationWriteSpec&amp;lt;/code&amp;gt; (create) / &amp;lt;code&amp;gt;OrganizationUpdateSpec&amp;lt;/code&amp;gt; (update). &amp;lt;code&amp;gt;org_type&amp;lt;/code&amp;gt; is constrained to &amp;lt;code&amp;gt;OrganizationTypeChoices&amp;lt;/code&amp;gt;; &amp;lt;code&amp;gt;parent&amp;lt;/code&amp;gt; is supplied as the parent&amp;#039;s &amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt; (UUID) and validated to exist; &amp;lt;code&amp;gt;validate_uniqueness&amp;lt;/code&amp;gt; enforces sibling-name uniqueness. &amp;lt;code&amp;gt;parent&amp;lt;/code&amp;gt; is immutable after create (the update spec omits it).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Read path:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;OrganizationReadSpec&amp;lt;/code&amp;gt; (list) returns &amp;lt;code&amp;gt;parent&amp;lt;/code&amp;gt; as nested JSON (&amp;lt;code&amp;gt;get_parent_json()&amp;lt;/code&amp;gt;) plus &amp;lt;code&amp;gt;level_cache&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;system_generated&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;has_children&amp;lt;/code&amp;gt;; &amp;lt;code&amp;gt;OrganizationRetrieveSpec&amp;lt;/code&amp;gt; (detail) adds the caller&amp;#039;s &amp;lt;code&amp;gt;permissions&amp;lt;/code&amp;gt;, expanded &amp;lt;code&amp;gt;managing_organizations&amp;lt;/code&amp;gt;, and audit users.&lt;br /&gt;
* Membership is managed through &amp;lt;code&amp;gt;OrganizationUser&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;FacilityOrganizationUser&amp;lt;/code&amp;gt; (specs above); &amp;lt;code&amp;gt;role&amp;lt;/code&amp;gt; is required and bounded by the assigning user&amp;#039;s own role in that org. Adding a member to a &amp;lt;code&amp;gt;role&amp;lt;/code&amp;gt;-typed org invalidates that user&amp;#039;s &amp;lt;code&amp;gt;cached_role_orgs&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;metadata&amp;lt;/code&amp;gt; is the supported place for deployment-specific key-value data without schema migrations; the specs pass it through verbatim as &amp;lt;code&amp;gt;dict&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Soft-delete applies (via &amp;lt;code&amp;gt;EMRBaseModel&amp;lt;/code&amp;gt;); an organization can&amp;#039;t be deleted while it still has children, and system-generated orgs can&amp;#039;t be deleted.&lt;br /&gt;
&lt;br /&gt;
{{Related}}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
</feed>