References/Patient: Difference between revisions
From OHC Network Wiki
More languages
More actions
Content deleted Content added
OHC identity seed Tag: Reverted |
OHC identity seed Tag: Manual revert |
||
| Line 2: | Line 2: | ||
|type=reference |
|type=reference |
||
|domain=clinical |
|domain=clinical |
||
|title=Patient |
|title=Patient (reference) |
||
|summary=Technical reference for the Patient module in Care EMR — models, fields, relationships, and save behaviour. |
|||
|order=1 |
|order=1 |
||
|introduced=3.0 |
|introduced=3.0 |
||
|fhir=Patient |
|fhir=Patient |
||
|model=Patient |
|model=Patient |
||
|source=care/emr/models/patient.py |
|||
|concept=Concepts/Patient |
|concept=Concepts/Patient |
||
|flow=Flows/Create a patient |
|flow=Flows/Create a patient |
||
| Line 12: | Line 14: | ||
Technical reference for the <code>Patient</code> module in Care EMR. For a product-oriented overview, see the [[Concepts/Patient|Patient concept]]. |
Technical reference for the <code>Patient</code> module in Care EMR. For a product-oriented overview, see the [[Concepts/Patient|Patient concept]]. |
||
'''Source:''' [<nowiki/>https://github.com/ohcnetwork/care/blob/develop/care/emr/models/patient.py <code>care/emr/models/patient.py</code>] |
|||
== Models == |
== Models == |
||
{| class="wikitable" |
{| class="wikitable" |
||
| ⚫ | |||
|- |
|- |
||
| ⚫ | |||
! Model |
|||
| ⚫ | |||
|- |
|- |
||
| ⚫ | |||
| ⚫ | |||
| Core patient record |
|||
|- |
|- |
||
| ⚫ | |||
| <code>PatientOrganization</code> |
|||
| ⚫ | |||
|- |
|- |
||
| ⚫ | |||
| <code>PatientUser</code> |
|||
| ⚫ | |||
|- |
|- |
||
| ⚫ | |||
| <code>PatientIdentifierConfig</code> |
|||
| ⚫ | |||
|- |
|||
| <code>PatientIdentifier</code> |
|||
| ⚫ | |||
|} |
|} |
||
| Line 45: | Line 38: | ||
{| class="wikitable" |
{| class="wikitable" |
||
! Field !! Type !! Notes |
|||
|- |
|||
! Field |
|||
! Type |
|||
! Notes |
|||
{{Field|model=Patient|section=Demographics|name=name|type=CharField(200)|notes=Display name}} |
{{Field|model=Patient|section=Demographics|name=name|type=CharField(200)|notes=Display name}} |
||
{{Field|model=Patient|section=Demographics|name=gender|type=CharField(35)|notes=Administrative gender}} |
{{Field|model=Patient|section=Demographics|name=gender|type=CharField(35)|notes=Administrative gender}} |
||
| Line 57: | Line 47: | ||
|} |
|} |
||
=== Contact & |
=== Contact & address === |
||
{| class="wikitable" |
{| class="wikitable" |
||
! Field !! Type !! Notes |
|||
|- |
|||
| ⚫ | |||
! Field |
|||
| ⚫ | |||
! Type |
|||
| ⚫ | |||
! Notes |
|||
{{Field|model=Patient|section=Contact & |
{{Field|model=Patient|section=Contact & address|name=permanent_address|type=TextField|notes=}} |
||
{{Field|model=Patient|section=Contact & |
{{Field|model=Patient|section=Contact & address|name=pincode|type=IntegerField|notes=Nullable}} |
||
| ⚫ | |||
| ⚫ | |||
| ⚫ | |||
|} |
|} |
||
=== Organization & |
=== Organization & access caches === |
||
These are '''denormalized caches''' rebuilt on every <code>Patient.save()</code> for fast filtering without deep joins. |
These are '''denormalized caches''' rebuilt on every <code>Patient.save()</code> for fast filtering without deep joins. |
||
{| class="wikitable" |
{| class="wikitable" |
||
! Field !! Type !! Notes |
|||
|- |
|||
{{Field|model=Patient|section=Organization & access caches|name=geo_organization|type=FK → Organization|notes=Geographic/administrative org assignment}} |
|||
! Field |
|||
| ⚫ | |||
! Type |
|||
| ⚫ | |||
! Rebuilt by |
|||
|- |
|||
| <code>geo_organization</code> |
|||
| <code>FK → Organization</code> |
|||
| Geographic/administrative org assignment |
|||
|- |
|||
| <code>organization_cache</code> |
|||
| <code>ArrayField[int]</code> |
|||
| ⚫ | |||
|- |
|||
| <code>users_cache</code> |
|||
| <code>ArrayField[int]</code> |
|||
| ⚫ | |||
|} |
|} |
||
=== Identifiers & |
=== Identifiers & tags === |
||
{| class="wikitable" |
{| class="wikitable" |
||
! Field !! Type !! Notes |
|||
|- |
|||
{{Field|model=Patient|section=Identifiers & tags|name=instance_identifiers|type=JSONField|notes=List of <code>{config, value}</code> built from <code>PatientIdentifier</code> rows (instance-scoped configs)}} |
|||
! Field |
|||
| ⚫ | |||
! Type |
|||
| ⚫ | |||
! Notes |
|||
{{Field|model=Patient|section=Identifiers & |
{{Field|model=Patient|section=Identifiers & tags|name=facility_tags|type=JSONField|notes=Dict keyed by facility → tag IDs}} |
||
{{Field|model=Patient|section=Identifiers & |
{{Field|model=Patient|section=Identifiers & tags|name=extensions|type=JSONField|notes=Open extension bag for deployment-specific metadata}} |
||
| ⚫ | |||
| ⚫ | |||
{{Field|model=Patient|section=Identifiers & tags|name=extensions|type=JSONField|notes=Open extension bag for deployment-specific metadata}} |
|||
|} |
|} |
||
| Line 114: | Line 86: | ||
=== <code>PatientOrganization</code> === |
=== <code>PatientOrganization</code> === |
||
<syntaxhighlight lang="text"> |
<syntaxhighlight lang="text"> |
||
patient → FK Patient |
|||
organization → FK Organization |
organization → FK Organization |
||
</syntaxhighlight> |
|||
Saving a <code>PatientOrganization</code> triggers <code>patient.save()</code>, which rebuilds <code>organization_cache</code>. |
Saving a <code>PatientOrganization</code> triggers <code>patient.save()</code>, which rebuilds <code>organization_cache</code>. |
||
| Line 122: | Line 97: | ||
Grants a Care user access to a patient record. |
Grants a Care user access to a patient record. |
||
<syntaxhighlight lang="text"> |
<syntaxhighlight lang="text"> |
||
user → FK User |
|||
patient → FK Patient |
patient → FK Patient |
||
role → FK RoleModel (PROTECT) |
role → FK RoleModel (PROTECT) |
||
</syntaxhighlight> |
|||
Saving a <code>PatientUser</code> triggers <code>patient.save()</code>, which rebuilds <code>users_cache</code>. |
Saving a <code>PatientUser</code> triggers <code>patient.save()</code>, which rebuilds <code>users_cache</code>. |
||
| Line 131: | Line 109: | ||
<code>PatientIdentifierConfig</code> defines what identifiers exist (status, optional facility scope, JSON config). <code>PatientIdentifier</code> stores the actual value: |
<code>PatientIdentifierConfig</code> defines what identifiers exist (status, optional facility scope, JSON config). <code>PatientIdentifier</code> stores the actual value: |
||
<syntaxhighlight lang="text"> |
<syntaxhighlight lang="text"> |
||
patient → FK Patient |
|||
config → FK PatientIdentifierConfig |
config → FK PatientIdentifierConfig |
||
facility → FK Facility (nullable) |
facility → FK Facility (nullable) |
||
value → CharField(1024), indexed |
value → CharField(1024), indexed |
||
</syntaxhighlight> |
|||
<code>PatientIdentifierConfigCache</code> provides in-process caching for configs (<code>get_instance_config()</code>, <code>get_facility_config(facility_id)</code>). |
<code>PatientIdentifierConfigCache</code> provides in-process caching for configs (<code>get_instance_config()</code>, <code>get_facility_config(facility_id)</code>). |
||
== Methods & |
== Methods & save behaviour == |
||
=== Age === |
=== Age === |
||
| Line 153: | Line 134: | ||
# <code>rebuild_organization_cache()</code> runs |
# <code>rebuild_organization_cache()</code> runs |
||
# <code>rebuild_users_cache()</code> runs |
# <code>rebuild_users_cache()</code> runs |
||
# A second <code>save(update_fields=[ |
# A second <code>save(update_fields=["organization_cache", "users_cache"])</code> persists the caches |
||
Integrators should expect '''two write passes''' when creating or updating patients through the ORM. |
Integrators should expect '''two write passes''' when creating or updating patients through the ORM. |
||