<?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%2FFacility_Flag</id>
	<title>References/Facility Flag - 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%2FFacility_Flag"/>
	<link rel="alternate" type="text/html" href="https://ohcnwiki.tellmey.fyi/index.php?title=References/Facility_Flag&amp;action=history"/>
	<updated>2026-07-06T07:12:19Z</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/Facility_Flag&amp;diff=401&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/Facility_Flag&amp;diff=401&amp;oldid=prev"/>
		<updated>2026-07-06T04:02:25Z</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:32, 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 217:&lt;/td&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 217:&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;* Flag names are limited to entries registered in the &amp;lt;code&amp;gt;FACILITY&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;FlagRegistry&amp;lt;/code&amp;gt;. An unregistered name fails save validation with &amp;lt;code&amp;gt;FlagNotFoundError&amp;lt;/code&amp;gt;, so clients cannot introduce arbitrary flag strings.&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;* Flag names are limited to entries registered in the &amp;lt;code&amp;gt;FACILITY&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;FlagRegistry&amp;lt;/code&amp;gt;. An unregistered name fails save validation with &amp;lt;code&amp;gt;FlagNotFoundError&amp;lt;/code&amp;gt;, so clients cannot introduce arbitrary flag strings.&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 &amp;lt;code&amp;gt;{facility, flag}&amp;lt;/code&amp;gt; uniqueness holds only over non-deleted rows, so soft-deleted history is preserved and a flag can be removed then re-added.&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 &amp;lt;code&amp;gt;{facility, flag}&amp;lt;/code&amp;gt; uniqueness holds only over non-deleted rows, so soft-deleted history is preserved and a flag can be removed then re-added.&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 facility}}&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;!-- diff cache key mediawiki:diff:1.41:old-158:rev-401:wikidiff2=table:1.14.2:bc2a06be --&gt;
&lt;/table&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://ohcnwiki.tellmey.fyi/index.php?title=References/Facility_Flag&amp;diff=158&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/Facility_Flag&amp;diff=158&amp;oldid=prev"/>
		<updated>2026-07-04T22:45:02Z</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=facility&lt;br /&gt;
|title=Facility Flag&lt;br /&gt;
|order=3&lt;br /&gt;
|introduced=3.0&lt;br /&gt;
|model=FacilityFlag&lt;br /&gt;
|reference=References/Base models &amp;amp;amp; conventions&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;FacilityFlag&amp;lt;/code&amp;gt; binds a registered flag name to a single &amp;lt;code&amp;gt;Facility&amp;lt;/code&amp;gt; to gate server-side behaviour. It is not a FHIR resource and has no Pydantic spec — no endpoint, serializer, or &amp;lt;code&amp;gt;...CreateSpec&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;...ReadSpec&amp;lt;/code&amp;gt; — so everything below comes from the Django storage model. Clients never write flags; they read them as a derived array on the Facility resource (see [[#resource-specs-api-schema|Resource specs]]).&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/facility/models/facility_flag.py &amp;lt;code&amp;gt;care/facility/models/facility_flag.py&amp;lt;/code&amp;gt;]&lt;br /&gt;
* Base/flag machinery: [&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;]&lt;br /&gt;
* Flag registry &amp;amp;amp; types: [&amp;lt;nowiki/&amp;gt;https://github.com/ohcnetwork/care/blob/develop/care/utils/registries/feature_flag.py &amp;lt;code&amp;gt;care/utils/registries/feature_flag.py&amp;lt;/code&amp;gt;]&lt;br /&gt;
* Surfaced via Facility spec: [&amp;lt;nowiki/&amp;gt;https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/facility/spec.py &amp;lt;code&amp;gt;care/emr/resources/facility/spec.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;FacilityFlag&amp;lt;/code&amp;gt;&lt;br /&gt;
| Associates a registered feature flag with a single &amp;lt;code&amp;gt;Facility&amp;lt;/code&amp;gt;, gating behaviour per facility&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;FacilityFlag&amp;lt;/code&amp;gt; extends &amp;lt;code&amp;gt;BaseFlag&amp;lt;/code&amp;gt;, which extends &amp;lt;code&amp;gt;BaseModel&amp;lt;/code&amp;gt; — the Care EMR base providing &amp;lt;code&amp;gt;external_id&amp;lt;/code&amp;gt; (UUID), &amp;lt;code&amp;gt;created_date&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;modified_date&amp;lt;/code&amp;gt; audit timestamps, and soft-delete via &amp;lt;code&amp;gt;deleted&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;BaseModel&amp;lt;/code&amp;gt; is leaner than &amp;lt;code&amp;gt;EMRBaseModel&amp;lt;/code&amp;gt; (see [[References/Base models &amp;amp;amp; conventions|Base model]]): no &amp;lt;code&amp;gt;created_by&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;updated_by&amp;lt;/code&amp;gt;, no &amp;lt;code&amp;gt;history&amp;lt;/code&amp;gt;, no &amp;lt;code&amp;gt;meta&amp;lt;/code&amp;gt; JSON. &amp;lt;code&amp;gt;BaseFlag&amp;lt;/code&amp;gt; adds the &amp;lt;code&amp;gt;flag&amp;lt;/code&amp;gt; value and the per-entity machinery: cache invalidation and validation against the flag registry.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;code&amp;gt;FacilityFlag&amp;lt;/code&amp;gt; fields ==&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=FacilityFlag|section=FacilityFlag fields|name=flag|type=CharField(max_length=1024)|notes=yes}}&lt;br /&gt;
{{Field|model=FacilityFlag|section=FacilityFlag fields|name=facility|type=FK → facility.Facility|notes=yes}}&lt;br /&gt;
{{Field|model=FacilityFlag|section=FacilityFlag fields|name=external_id|type=UUIDField|notes=auto}}&lt;br /&gt;
{{Field|model=FacilityFlag|section=FacilityFlag fields|name=created_date|type=DateTimeField|notes=auto}}&lt;br /&gt;
{{Field|model=FacilityFlag|section=FacilityFlag fields|name=modified_date|type=DateTimeField|notes=auto}}&lt;br /&gt;
{{Field|model=FacilityFlag|section=FacilityFlag fields|name=deleted|type=BooleanField|notes=no}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The model has no &amp;lt;code&amp;gt;JSONField&amp;lt;/code&amp;gt;s, so there is no opaque JSON shape to document.&lt;br /&gt;
&lt;br /&gt;
=== Flag type values ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;flag_type&amp;lt;/code&amp;gt; is fixed to &amp;lt;code&amp;gt;FlagType.FACILITY&amp;lt;/code&amp;gt;. The full &amp;lt;code&amp;gt;FlagType&amp;lt;/code&amp;gt; enum (from [&amp;lt;nowiki/&amp;gt;https://github.com/ohcnetwork/care/blob/develop/care/utils/registries/feature_flag.py &amp;lt;code&amp;gt;feature_flag.py&amp;lt;/code&amp;gt;]):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &amp;lt;code&amp;gt;FlagType&amp;lt;/code&amp;gt; member&lt;br /&gt;
! Value&lt;br /&gt;
! Used by&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;USER&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;amp;quot;USER&amp;amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;UserFlag&amp;lt;/code&amp;gt; ([[References/User &amp;amp;amp; Skills&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;FACILITY&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;amp;quot;FACILITY&amp;amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;FacilityFlag&amp;lt;/code&amp;gt; (this model)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;flag&amp;lt;/code&amp;gt; values themselves are not enumerated in source. They are registered at runtime via &amp;lt;code&amp;gt;FlagRegistry.register(FlagType.FACILITY, &amp;amp;quot;&amp;amp;lt;name&amp;amp;gt;&amp;amp;quot;)&amp;lt;/code&amp;gt;, and a name absent from the &amp;lt;code&amp;gt;FACILITY&amp;lt;/code&amp;gt; registry raises &amp;lt;code&amp;gt;FlagNotFoundError&amp;lt;/code&amp;gt; on save.&lt;br /&gt;
&lt;br /&gt;
=== Class-level configuration ===&lt;br /&gt;
&lt;br /&gt;
These class attributes wire &amp;lt;code&amp;gt;FacilityFlag&amp;lt;/code&amp;gt; into the generic &amp;lt;code&amp;gt;BaseFlag&amp;lt;/code&amp;gt; caching and validation logic. They are not database fields.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Attribute&lt;br /&gt;
! Value&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;cache_key_template&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;amp;quot;facility_flag_cache:{entity_id}:{flag_name}&amp;amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
| Per-flag existence cache key&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;all_flags_cache_key_template&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;amp;quot;facility_all_flags_cache:{entity_id}&amp;amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
| Cache key for a facility&amp;#039;s full flag list&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;flag_type&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;FlagType.FACILITY&amp;lt;/code&amp;gt;&lt;br /&gt;
| Registry namespace used for flag-name validation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;entity_field_name&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;amp;quot;facility&amp;amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
| Tells &amp;lt;code&amp;gt;BaseFlag&amp;lt;/code&amp;gt; which FK is the owning entity; backs the &amp;lt;code&amp;gt;entity&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;entity_id&amp;lt;/code&amp;gt; properties&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Module-level constants mirror these templates: &amp;lt;code&amp;gt;FACILITY_FLAG_CACHE_KEY&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;&amp;amp;quot;facility_flag_cache:{facility_id}:{flag_name}&amp;amp;quot;&amp;lt;/code&amp;gt;), &amp;lt;code&amp;gt;FACILITY_ALL_FLAGS_CACHE_KEY&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;&amp;amp;quot;facility_all_flags_cache:{facility_id}&amp;amp;quot;&amp;lt;/code&amp;gt;), and &amp;lt;code&amp;gt;FACILITY_FLAG_CACHE_TTL&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;60 * 60 * 24&amp;lt;/code&amp;gt;, 1 day).&lt;br /&gt;
&lt;br /&gt;
=== Constraints ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;UniqueConstraint(&lt;br /&gt;
    fields=[&amp;quot;facility&amp;quot;, &amp;quot;flag&amp;quot;],&lt;br /&gt;
    condition=Q(deleted=False),&lt;br /&gt;
    name=&amp;quot;unique_facility_flag&amp;quot;,&lt;br /&gt;
)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
A facility holds a given flag at most once among non-deleted rows. The condition excludes soft-deleted rows, so a flag can be removed and re-added. &amp;lt;code&amp;gt;Meta.verbose_name = &amp;amp;quot;Facility Flag&amp;amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Methods &amp;amp;amp; save behaviour ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;save()&amp;lt;/code&amp;gt; (inherited from &amp;lt;code&amp;gt;BaseFlag&amp;lt;/code&amp;gt;) ===&lt;br /&gt;
&lt;br /&gt;
Every save runs four steps in order:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;validate_flag(self.flag)&amp;lt;/code&amp;gt; calls &amp;lt;code&amp;gt;FlagRegistry.validate_flag_name(FlagType.FACILITY, flag)&amp;lt;/code&amp;gt;, which validates the flag type, then checks that the name is registered. An unknown type or unregistered name raises &amp;lt;code&amp;gt;FlagNotFoundError&amp;lt;/code&amp;gt; (a subclass of Django &amp;lt;code&amp;gt;ValidationError&amp;lt;/code&amp;gt;) and the row is not written.&lt;br /&gt;
# The per-flag cache key (&amp;lt;code&amp;gt;facility_flag_cache:{facility_id}:{flag}&amp;lt;/code&amp;gt;) is deleted.&lt;br /&gt;
# The all-flags cache key (&amp;lt;code&amp;gt;facility_all_flags_cache:{facility_id}&amp;lt;/code&amp;gt;) is deleted.&lt;br /&gt;
# The row is persisted via &amp;lt;code&amp;gt;super().save()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Deletes use the &amp;lt;code&amp;gt;BaseModel&amp;lt;/code&amp;gt; soft-delete: &amp;lt;code&amp;gt;delete()&amp;lt;/code&amp;gt; sets &amp;lt;code&amp;gt;deleted = True&amp;lt;/code&amp;gt; and saves &amp;lt;code&amp;gt;update_fields=[&amp;amp;quot;deleted&amp;amp;quot;]&amp;lt;/code&amp;gt;. It does not purge cache entries, so they expire by TTL or are rebuilt on the next miss.&lt;br /&gt;
&lt;br /&gt;
=== Lookups ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Method&lt;br /&gt;
! Returns&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;check_facility_has_flag(facility_id, flag_name)&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;bool&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delegates to &amp;lt;code&amp;gt;BaseFlag.check_entity_has_flag&amp;lt;/code&amp;gt;: validates the flag name, then &amp;lt;code&amp;gt;cache.get_or_set&amp;lt;/code&amp;gt; on the per-flag key with an &amp;lt;code&amp;gt;.exists()&amp;lt;/code&amp;gt; query; cached for &amp;lt;code&amp;gt;FLAGS_CACHE_TTL&amp;lt;/code&amp;gt; (1 day)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;get_all_flags(facility_id)&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;tuple[FlagName]&amp;lt;/code&amp;gt;&lt;br /&gt;
| Delegates to &amp;lt;code&amp;gt;BaseFlag.get_all_flags&amp;lt;/code&amp;gt;: &amp;lt;code&amp;gt;cache.get_or_set&amp;lt;/code&amp;gt; on the all-flags key, materializing &amp;lt;code&amp;gt;values_list(&amp;amp;quot;flag&amp;amp;quot;, flat=True)&amp;lt;/code&amp;gt; for the facility; cached for 1 day&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Both wrap the generic &amp;lt;code&amp;gt;BaseFlag&amp;lt;/code&amp;gt; methods using &amp;lt;code&amp;gt;entity_field_name=&amp;amp;quot;facility&amp;amp;quot;&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;Facility.get_facility_flags()&amp;lt;/code&amp;gt; is a thin wrapper over &amp;lt;code&amp;gt;FacilityFlag.get_all_flags(self.id)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Properties (inherited) ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;entity&amp;lt;/code&amp;gt; → the related &amp;lt;code&amp;gt;Facility&amp;lt;/code&amp;gt; instance (&amp;lt;code&amp;gt;getattr(self, &amp;amp;quot;facility&amp;amp;quot;)&amp;lt;/code&amp;gt;)&lt;br /&gt;
* &amp;lt;code&amp;gt;entity_id&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;facility_id&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;getattr(self, &amp;amp;quot;facility_id&amp;amp;quot;)&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
== Resource specs (API schema) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;FacilityFlag&amp;lt;/code&amp;gt; has no Pydantic resource spec and no REST endpoint of its own. There is no &amp;lt;code&amp;gt;FacilityFlagCreateSpec&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;FacilityFlagUpdateSpec&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;FacilityFlagListSpec&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;FacilityFlagRetrieveSpec&amp;lt;/code&amp;gt;, no serializer, and no viewset — confirmed by their absence from &amp;lt;code&amp;gt;care/emr/resources/&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;care/facility/api/&amp;lt;/code&amp;gt;. Flags are administered through Django admin or registration/management code, not the public API.&lt;br /&gt;
&lt;br /&gt;
Flags reach API clients in exactly one place: the Facility resource exposes them as a derived read-only field.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Spec&lt;br /&gt;
! Field&lt;br /&gt;
! Role&lt;br /&gt;
! Behaviour&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;FacilityRetrieveSpec&amp;lt;/code&amp;gt; ([&amp;lt;nowiki/&amp;gt;https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/facility/spec.py &amp;lt;code&amp;gt;facility/spec.py&amp;lt;/code&amp;gt;])&lt;br /&gt;
| &amp;lt;code&amp;gt;flags: list[str]&amp;lt;/code&amp;gt;&lt;br /&gt;
| read · detail&lt;br /&gt;
| Populated in &amp;lt;code&amp;gt;perform_extra_serialization&amp;lt;/code&amp;gt; via &amp;lt;code&amp;gt;mapping[&amp;amp;quot;flags&amp;amp;quot;] = obj.get_facility_flags()&amp;lt;/code&amp;gt;. Server-maintained and read-only; clients cannot set or mutate flags through the Facility write specs&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;flags&amp;lt;/code&amp;gt; array is the materialized list of registered flag names attached to the facility, from &amp;lt;code&amp;gt;FacilityFlag.get_all_flags&amp;lt;/code&amp;gt; (cache-backed, 1-day TTL). No value set is bound to it — entries are the runtime &amp;lt;code&amp;gt;FACILITY&amp;lt;/code&amp;gt; registry names, not a coded concept. The User resource mirrors this, exposing &amp;lt;code&amp;gt;flags&amp;lt;/code&amp;gt; via &amp;lt;code&amp;gt;obj.get_all_flags()&amp;lt;/code&amp;gt; backed by &amp;lt;code&amp;gt;UserFlag&amp;lt;/code&amp;gt; (see [[References/User &amp;amp;amp; Skills|User]]).&lt;br /&gt;
&lt;br /&gt;
== Related models ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;FacilityFlag&amp;lt;/code&amp;gt; defines no secondary models. Its behaviour comes from two utilities in &amp;lt;code&amp;gt;care/utils&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;BaseFlag&amp;lt;/code&amp;gt; (abstract) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;flag → CharField(max_length=1024)&lt;br /&gt;
(abstract base — no table of its own)&lt;br /&gt;
class attrs: cache_key_template, all_flags_cache_key_template, flag_type, entity_field_name&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Provides save-time validation, cache invalidation, and the &amp;lt;code&amp;gt;check_entity_has_flag&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;get_all_flags&amp;lt;/code&amp;gt; lookups. Subclasses set &amp;lt;code&amp;gt;flag_type&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;entity_field_name&amp;lt;/code&amp;gt;, and the two cache-key templates. See [&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;].&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;FlagRegistry&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
An in-process, class-level registry (&amp;lt;code&amp;gt;_flags: dict[FlagType, dict[FlagName, bool]]&amp;lt;/code&amp;gt;) of valid flag names per &amp;lt;code&amp;gt;FlagType&amp;lt;/code&amp;gt;. Key methods:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Method&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;register(flag_type, flag_name)&amp;lt;/code&amp;gt;&lt;br /&gt;
| Adds a name to a type&amp;#039;s registry, creating the type bucket if needed&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;register_wrapper(flag_type, flag_name)&amp;lt;/code&amp;gt;&lt;br /&gt;
| Class-decorator form of &amp;lt;code&amp;gt;register&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;unregister(flag_type, flag_name)&amp;lt;/code&amp;gt;&lt;br /&gt;
| Removes a name; logs a warning if absent&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;validate_flag_type(flag_type)&amp;lt;/code&amp;gt;&lt;br /&gt;
| Raises &amp;lt;code&amp;gt;FlagNotFoundError&amp;lt;/code&amp;gt; (&amp;amp;quot;Invalid Flag Type&amp;amp;quot;) if the type bucket is missing&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;validate_flag_name(flag_type, flag_name)&amp;lt;/code&amp;gt;&lt;br /&gt;
| Validates type, then raises &amp;lt;code&amp;gt;FlagNotFoundError&amp;lt;/code&amp;gt; (&amp;amp;quot;Flag not registered&amp;amp;quot;) if the name is absent&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;get_all_flags(flag_type)&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;list[FlagName]&amp;lt;/code&amp;gt; of registered names&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;get_all_flags_as_choices(flag_type)&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;(value, value)&amp;lt;/code&amp;gt; tuples for Django choices&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A flag must be registered before a &amp;lt;code&amp;gt;FacilityFlag&amp;lt;/code&amp;gt; referencing it can be saved. See [&amp;lt;nowiki/&amp;gt;https://github.com/ohcnetwork/care/blob/develop/care/utils/registries/feature_flag.py &amp;lt;code&amp;gt;care/utils/registries/feature_flag.py&amp;lt;/code&amp;gt;].&lt;br /&gt;
&lt;br /&gt;
== API integration notes ==&lt;br /&gt;
&lt;br /&gt;
* There is no CRUD endpoint. Manage flags via Django admin or registration/management code; clients only observe them through the read-only &amp;lt;code&amp;gt;flags: list[str]&amp;lt;/code&amp;gt; field on &amp;lt;code&amp;gt;FacilityRetrieveSpec&amp;lt;/code&amp;gt; (see [[#resource-specs-api-schema|Resource specs]]).&lt;br /&gt;
* In application code, read through &amp;lt;code&amp;gt;check_facility_has_flag&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;get_all_flags&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;Facility.get_facility_flags()&amp;lt;/code&amp;gt;), which are cache-backed. Do not query the table directly for hot-path checks.&lt;br /&gt;
* Flag names are limited to entries registered in the &amp;lt;code&amp;gt;FACILITY&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;FlagRegistry&amp;lt;/code&amp;gt;. An unregistered name fails save validation with &amp;lt;code&amp;gt;FlagNotFoundError&amp;lt;/code&amp;gt;, so clients cannot introduce arbitrary flag strings.&lt;br /&gt;
* The &amp;lt;code&amp;gt;{facility, flag}&amp;lt;/code&amp;gt; uniqueness holds only over non-deleted rows, so soft-deleted history is preserved and a flag can be removed then re-added.&lt;br /&gt;
&lt;br /&gt;
{{Related}}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
</feed>