Skip to main content

Registration Service — Domain Model

Status: populated Owner: TBD Last updated: 2026-04-17 Companion: Service Template · 03 platform-services · 02 DDD

1. Aggregates​

1.1 PatientAggregate​

Root aggregate for person identity and demographics in a tenant.

Invariants

#Invariant
I-PAT-01Identifiers are unique per (tenantId, system, value) — no two patients share the same identifier in the same assigning authority.
I-PAT-02A merged patient (mergedIntoPatientId ≠ null) is inactive and cannot be updated.
I-PAT-03deceasedDateTime may only be set when deceased = true.
I-PAT-04isProvisional and isUnidentified are mutually exclusive.
I-PAT-05isNewborn = true requires newbornLinkedPatientId or a MOTHER/GUARDIAN NOK row.
I-PAT-06preferredLang must be in the allowed language set.
I-PAT-07MPI score ≥ 85 blocks normal create (409) unless isUnidentified = true.
I-PAT-08Optimistic lock version must match on every mutation.

State Machine

1.2 EncounterAggregate​

Single visit registration linked to a Patient.

Invariants

#Invariant
I-ENC-01Status transitions follow allowed graph only.
I-ENC-02admittedAt is set once on first in-progress transition.
I-ENC-03dischargedAt is set once on finished transition.
I-ENC-04patientId references an active, non-merged patient in the same tenant.

Encounter Status Machine

2. Entities​

EntityAggregateKey attributes
PatientNamePatientuse, family, given[], script, textDirection, patronymic, middle
PatientIdentifierPatientsystem, value, typeCode, issuer, verificationStatus, confidence
PatientTelecomPatientsystem, value, use, rank
PatientAddressPatientcountry, stateProvince, district, city, line[], postalCode, use
NextOfKinEntryPatientrelationship (coded), name, phone, relatedPatientId?, priority
ConsentFlagPatienttype, granted, channel
PatientPortraitPatientcontentType, consentGiven, clinicalDisplayAllowed, retentionUntil, supersededPortraitId?
PatientExtensionInstancePatientbundleKey, schemaId, payload (JSONB), effectiveFrom, effectiveTo?
VitalStatusCorrectionPatientpriorDeceased, priorDeceasedDateTime, newDeceased, correctedBy, correctedAt

3. Value Objects​

Value ObjectType / Format
PatientIdBranded<string, 'PatientId'> — UUID
EncounterIdBranded<string, 'EncounterId'> — UUID
MRNPAT-{tenantCode}-{timestamp}
TemporaryEnterpriseKeyUNK-{tenantCode}-{timestamp}-{random8}
NationalIdentifierValueValidated 8–20 digit string
MPIScoreInteger 0–100; ≥85 → probable duplicate; 71–84 → weak match
KinRelationshipCodeEnum from kin_relationship_types catalog
LanguageCodeen | ps | ps-af | fa | fa-af | ar | ar-ae | ar-af | ar-sa
ScriptCodelatn | arab | arab-af | fa-af | ps
EncounterStatusplanned | arrived | in-progress | finished | cancelled
AlternateIdentifierEvidence{system, value, typeCode, issuer, verificationStatus, confidence}

4. Domain Events​

NATS subjectCloudEvents typeTriggerVersion
REGISTRATION.patient.createdghasi.registration.patient.createdPatient creation succeedsv1
REGISTRATION.patient.updatedghasi.registration.patient.updatedDemographics/identifiers updatedv1
REGISTRATION.patient.vital-status-changedghasi.registration.patient.vital-status-changedDeceased recorded or correctedv1
REGISTRATION.patient.duplicate-detectedghasi.registration.patient.duplicate-detectedMPI ≥ 85 aborts createv1
REGISTRATION.patient.unidentified-duplicate-reviewghasi.registration.patient.unidentified-duplicate-reviewUnidentified create + weak matchv1
REGISTRATION.patient.mergedghasi.registration.patient.mergedMerge executes (source deactivated)v1
REGISTRATION.patient.unmergedghasi.registration.patient.unmergedSource reactivated via unmergev1
REGISTRATION.encounter.registeredghasi.registration.encounter.registeredEncounter createdv1
REGISTRATION.encounter.status-changedghasi.registration.encounter.status-changedEncounter status transitionsv1

5. Ubiquitous Language​

TermDefinition
PatientRegistered person in the platform identity system
MRNMedical Record Number — tenant-scoped, system-generated
MPIMaster Patient Index — probabilistic matching engine
MergeDeactivating a duplicate (source) patient and transferring identifiers to the survivor
SurvivorThe patient identity that remains active post-merge
SourceThe duplicate deactivated during merge
Provisional patientMinimal identity for emergency intake pending full confirmation
Unidentified patientUnknown-person record (no name/DOB); must be reconciled
ReconciliationLinking or merging provisional/unidentified chart to identified patient
Vital statusLiving or deceased state, with optional time of death
Next-of-kin (NOK)Related person (family/guardian/emergency contact) linked to patient
NID / TazkiraAfghanistan national identity document types
Alternate identity evidenceNon-NID credentials for populations without national IDs
stablePatientIdPlatform-wide stable UUID duplicated in all events
EncounterSingle visit registration (check-in through discharge)
Break-glassEmergency access beyond normal role scope with mandatory justification
Relationship graphNetwork of patient–NOK and patient–patient links