Data Ownership Model
Patient = User Identity
Core principle: Every Patient is a User.
PatientID = UserID. There is no separate OrganizationID on the User or Patient record — these entities are global across the entire platform.
A person exists once in the system. Organizations see the patient through org-scoped relationships (encounters, appointments, claims) but never "own" the patient record itself.
User AMI Schema
| Field | Type | Notes |
|---|---|---|
| UserID | ShortGUID (PK) | Primary key, Base62 22-char |
| Unique, verified | ||
| Phone | Phone | E.164 format |
| FirstName | String | |
| LastName | String | |
| DateOfBirth | Date | |
| IsActive | Bool | Soft-delete flag |
| CreatedDateTimeUTC | DateTime | Audit |
| ModifiedDateTimeUTC | DateTime | Audit |
| ModifiedByUserID | ShortGUID | Audit — FK to User |
Patient AMI Schema
| Field | Type | Notes |
|---|---|---|
| PatientID | ShortGUID (PK) | FK → User.UserID (same value) |
| PreferredName | String | Display name / nickname |
| Sex | String | Administrative sex (M/F/O/U) |
| GenderIdentity | String | USCDI v4 value set |
| PreferredLanguage | String | BCP-47 code |
| Race | String | OMB categories |
| Ethnicity | String | OMB categories |
| IsDeceased | Bool | |
| CreatedDateTimeUTC | DateTime | Audit |
| ModifiedDateTimeUTC | DateTime | Audit |
| ModifiedByUserID | ShortGUID | Audit — FK to User |
Short GUID Convention
All primary keys use a Base62-encoded Short GUID: 22 characters, URL-safe, case-sensitive.
| Property | Value |
|---|---|
| Encoding | Base62 (0-9A-Za-z) |
| Length | 22 characters (fixed, zero-padded) |
| Source | Standard UUID v4 (128-bit) |
| Algorithm | UUID → strip hyphens → parse as 128-bit integer → repeatedly divide by 62 → map remainders to Base62 alphabet → pad to 22 chars |
Worked Example
UUID:
Short GUID:
fb1e9c50-3f1c-4b8e-9a31-2b7c0e2d4a18Short GUID:
7nKxC2Lh3vQrX8P4MsB1aF
JavaScript Reference Implementation
const BASE62 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
function uuidToShortGuid(uuid) {
const hex = uuid.replace(/-/g, '');
let num = BigInt('0x' + hex);
let result = '';
while (num > 0n) {
result = BASE62[Number(num % 62n)] + result;
num = num / 62n;
}
return result.padStart(22, '0');
}
function shortGuidToUuid(short) {
let num = 0n;
for (const ch of short) {
num = num * 62n + BigInt(BASE62.indexOf(ch));
}
const hex = num.toString(16).padStart(32, '0');
return [hex.slice(0,8), hex.slice(8,12), hex.slice(12,16),
hex.slice(16,20), hex.slice(20)].join('-');
}
Data Ownership Classification
Every entity is classified as Global (patient-centric, no org owner) or Org-scoped (belongs to a specific organization).
Global Entities (Patient-Owned)
| Entity | Scope | OrganizationID? | PatientID Partition? | SourceOrganizationID? |
|---|---|---|---|---|
| User | Global | No | N/A | No |
| Patient | Global | No | Yes (PK) | No |
| Allergy | Global | No | Yes | Yes |
| Medication | Global | No | Yes | Yes |
| Condition | Global | No | Yes | Yes |
| Vital | Global | No | Yes | Yes |
| LabResult | Global | No | Yes | Yes |
| Imaging | Global | No | Yes | Yes |
| Immunization | Global | No | Yes | Yes |
| CarePlan | Global | No | Yes | Yes |
| FamilyHistory | Global | No | Yes | No |
| Surgery | Global | No | Yes | Yes |
| Problem | Global | No | Yes | Yes |
| ProblemList | Global | No | Yes | No |
| Diagnosis | Global | No | Yes | Yes |
| Procedure | Global | No | Yes | Yes |
| Prescription | Global | No | Yes | Yes |
| PatientDocument | Global | No | Yes | Yes |
| SensitiveClassGating | Global | No | Yes | No |
Org-Scoped Entities
| Entity | Scope | OrganizationID? | PatientID Partition? | SourceOrganizationID? |
|---|---|---|---|---|
| Encounter | Org | Yes | Yes | No |
| CareRelationship | Org | Yes | Yes | No |
| PatientOrgMembership | Org | Yes | Yes | No |
| Appointment | Org | Yes | Yes | No |
| Claim | Org | Yes | Yes | No |
| ClaimLine | Org | Yes | Yes | No |
| Remittance | Org | Yes | Yes | No |
| Denial | Org | Yes | Yes | No |
| PatientStatement | Org | Yes | Yes | No |
| Coverage | Org | Yes | Yes | No |
| Task | Org | Yes | Optional | No |
| Referral | Org | Yes | Yes | No |
| ReferralResponse | Org | Yes | Yes | No |
| Schedule | Org | Yes | No | No |
| Slot | Org | Yes | No | No |
| Resource | Org | Yes | No | No |
| VisitType | Org | Yes | No | No |
| VisitStage | Org | Yes | No | No |
| WaitlistEntry | Org | Yes | Yes | No |
| InsurancePlan | Org | Yes | No | No |
| EligibilityCheck | Org | Yes | Yes | No |
| BenefitDetail | Org | Yes | Yes | No |
| PriorAuth | Org | Yes | Yes | No |
| ControlledSubstanceAuth | Org | Yes | Yes | No |
| PdmpQuery | Org | Yes | Yes | No |
| FormularyCheck | Org | Yes | Yes | No |
| OrderSet | Org | Yes | No | No |
| CdsRule | Org | Yes | No | No |
| CdsHookEvent | Org | Yes | Yes | No |
| PortalMessage | Org | Yes | Yes | No |
| Payment | Org | Yes | Yes | No |
| WorkTask | Org | Yes | Optional | No |
| PayerRule | Org | Yes | No | No |
Billing Nuance
CPT codes and procedure definitions are shareable clinical facts — they travel with the patient.
Payments, claims, and remittances are private to the organization that generated them. Org B cannot see Org A's claim details even for the same patient.
Read-Access Audit Trail
Every read of clinical data generates an audit entry recording who, what, when, how, and why.
Authorization Chain Types
| Chain Type | Description |
|---|---|
CareOrgMember | Staff at the patient's care organization (active CareRelationship) |
FamilyProxy | Family member with patient-granted proxy access |
ExternalSpecialist | Provider at a referred-to organization (active Referral) |
TEFCA | Cross-network query via eHealth Exchange / TEFCA QHIN |
BreakTheGlass | Emergency override — requires justification, triggers alert |
Researcher | IRB-approved de-identified or limited data set access |
AuditLog AMI Schema
| Field | Type | Notes |
|---|---|---|
| PatientID | ShortGUID | Partition key — FK to Patient |
| ActorUserID | ShortGUID | Who performed the action |
| AuditLogID | ShortGUID (PK) | Primary key |
| ActionType | String | Read, Write, Delete, Export, BreakTheGlass |
| ResourceType | String | Entity name (e.g., Medication, Encounter) |
| ResourceID | ShortGUID | ID of the accessed record |
| AccessChannel | String | Web, Mobile, API, FHIR, Bulk |
| AuthorizationChainType | String | See chain types above |
| AuthorizationChainDetail | JSON | Full chain: org, role, relationship IDs |
| Justification | String | Required for BreakTheGlass; optional otherwise |
| SourceIP | String | Client IP address |
| EventDateTimeUTC | DateTime | When the event occurred |
| CreatedDateTimeUTC | DateTime | Audit |
| ModifiedDateTimeUTC | DateTime | Audit |
| ModifiedByUserID | ShortGUID | Audit |
| PreviousHash | String | Hash-chain integrity — SHA-256 of prior entry |
Classification Flow
graph TD
A["New Entity"] --> B{"Has OrganizationID?"}
B -- No --> C["Global Entity"]
B -- Yes --> D["Org-Scoped Entity"]
C --> E{"Clinical fact?"}
E -- Yes --> F["Add SourceOrganizationID
for provenance"]
E -- No --> G["Pure global
(User, Patient, ProblemList)"]
D --> H{"Patient-related?"}
H -- Yes --> I["PatientID partition key"]
H -- No --> J["Org-only partition
(Schedule, Slot, Resource)"]
Authorization Evaluation Flow
graph TD REQ["Data Access Request"] --> AUTH["Identify Actor & Role"] AUTH --> RBAC["RBAC Check:
Role has permission?"] RBAC -- No --> DENY["Deny"] RBAC -- Yes --> ABAC["ABAC Check:
Context attributes match?"] ABAC -- No --> BTG{"Break-the-Glass
available?"} BTG -- No --> DENY BTG -- Yes --> JUSTIFY["Require Justification"] JUSTIFY --> ALERT["Trigger Alert + Audit"] ALERT --> GRANT ABAC -- Yes --> SCOPE["Scope Check:
CareRelationship or
valid AuthorizationChain?"] SCOPE -- No --> DENY SCOPE -- Yes --> GRANT["Grant + Audit Entry"]
Provenance Model & Trust Tiers
Full provenance taxonomy lives in the PMR Deep Exemplar. The complete model —
(a) internal canonical provenance, (b) external inbound provenance, (c) external outbound provenance,
(d) trust-tier definitions, and (e) conflict-handling rules — is documented with worked examples in
PMR Deep Exemplar → Provenance Model
(see also Trust tier definitions).