FHIR Data Model
ChartChat uses FHIR R4 as its data model, stored in the Medplum FHIR server. All patient data — conditions, medications, lab results, visits, etc. — is stored as standard FHIR resources. ChartChat extends the base spec with a small set of custom resource types for platform-specific data.
Standard FHIR Resources Used
| Resource | Used for |
|---|---|
Patient | Patient demographics, identity |
Condition | Diagnoses, problem list |
AllergyIntolerance | Allergy records |
MedicationRequest | Medication orders |
Observation | Lab results, vitals, survey responses |
DiagnosticReport | Lab reports grouping Observations |
Encounter | Clinic visits |
Immunization | Vaccination records |
Procedure | Surgical and procedural history |
DocumentReference | Clinical notes, uploaded documents |
CarePlan | Care plans |
Appointment | Scheduled appointments |
Practitioner | Treating physicians |
Organization | Healthcare organizations |
Coverage | Insurance coverage |
Binary | Raw file attachments (PDFs, images) |
Custom FHIR Resources
ChartChat adds custom resource types on top of the standard spec. These are defined in packages/definitions/ and built into @medplum/definitions. The npm-published version does not include them — the local build must be used at runtime (see Deployment).
PatientEHRConnection
Tracks a patient's active OAuth connection to an external EHR system.
| Field | Type | Description |
|---|---|---|
patient | Reference(Patient) | The ChartChat patient |
ehrProvider | string | EHR key (epic, healow, meditech) or HospitalIntegration UUID |
externalPatientId | string | Patient's ID in the external EHR |
fhirBaseUrl | string | The EHR's FHIR R4 base URL |
accessToken | string | Encrypted OAuth access token |
refreshToken | string | Encrypted OAuth refresh token (if provided) |
tokenExpiresAt | dateTime | When the access token expires |
connectedAt | dateTime | When the connection was established |
status | code | active | revoked | token_expired |
connectionType | code | Always SMART |
HospitalIntegration
Represents a hospital or health system configured in the Admin Portal for EHR connections.
| Field | Type | Description |
|---|---|---|
name | string | Display name |
ehrVendor | code | EHR vendor (epic, healow, meditech) |
fhirBaseUrl | string | The hospital's FHIR R4 base URL |
redirectUri | string | OAuth redirect URI override |
scope | string | OAuth scope override |
enabled | boolean | Whether this integration is active |
SSOIntegration
Stores an SSO provider configuration for a specific identity provider (Microsoft, Google, custom OIDC).
| Field | Type | Description |
|---|---|---|
name | string | Display name |
authorizeUrl | string | OAuth2 authorization endpoint |
tokenUrl | string | OAuth2 token endpoint |
clientId | string | OAuth2 client ID |
clientSecret | string | OAuth2 client secret |
useSubject | boolean | Use sub claim as user identifier |
ChatMessage
Stores a single AI chat message in the Member Portal.
| Field | Type | Description |
|---|---|---|
patient | Reference(Patient) | Owner of the message |
sessionId | string | Groups messages into a conversation |
role | code | user or assistant |
content | string | Message text |
intent | code | Detected intent: lab, medications, condition, visits, allergies, general |
timestamp | dateTime | When the message was sent |
SupportTicket
A support request submitted by a patient via the Member Portal.
| Field | Type | Description |
|---|---|---|
patient | Reference(Patient) | Patient who submitted the ticket (optional — anonymous if absent) |
name | string | Submitter display name |
email | string | Submitter email |
phone | string | Submitter phone (optional) |
category | code | technical-issue | health-details | general-inquiry | feedback |
description | string | Full description of the request |
status | code | unresolved | pending | resolved |
priority | code | low | medium | high |
internalNotes | string | Admin-only notes (not shown to patient) |
createdAt | dateTime | When the ticket was submitted |
SupportTicketMessage
A single message in a support ticket thread (admin replies only).
| Field | Type | Description |
|---|---|---|
ticket | Reference(SupportTicket) | The parent ticket |
body | string | Message content |
sender | code | Always admin |
senderName | string | Display name of the admin who replied |
createdAt | dateTime | When the message was sent |
PatientNotification
An in-app notification for a Member Portal patient. Created by the server (support events) or the client (EHR sync results). See Notifications for the full architecture.
| Field | Type | Description |
|---|---|---|
patient | Reference(Patient) | Notification recipient |
type | code | ehr_expired | sync_complete | sync_partial | sync_failed | support_reply | support_status_changed |
title | string | Short heading shown in the bell drawer |
message | string | Body text |
read | boolean | false until patient reads or dismisses |
sent | dateTime | Creation timestamp |
actionLabel | string | Optional CTA button label |
actionPath | string | Optional client-side route for the CTA |
FHIR Search Parameters
ChartChat adds custom search parameters for its custom resource types. They are defined in packages/definitions/src/fhir/r4/search-parameters-medplum.json and must be rebuilt via Admin → Super Admin → Rebuild SearchParameters after updates.
Key custom search parameters:
| Parameter | Resource | Type | Description |
|---|---|---|---|
patient | PatientEHRConnection | reference | Search by patient |
ehr-provider | PatientEHRConnection | token | Search by EHR key or hospital ID |
external-patient-id | PatientEHRConnection | token | Search by EHR-side patient ID |
status | PatientEHRConnection | token | Filter by connection status |
patient | ChatMessage | reference | Search by patient |
session-id | ChatMessage | token | Search by session |
patient | SupportTicket | reference | Search by patient |
status | SupportTicket | token | Filter by ticket status |
category | SupportTicket | token | Filter by category |
priority | SupportTicket | token | Filter by priority |
created-at | SupportTicket | date | Filter by creation date |
ticket | SupportTicketMessage | reference | Search messages by parent ticket |
patient | PatientNotification | reference | Search by patient |
read | PatientNotification | token | Filter by read status |
type | PatientNotification | token | Filter by notification type |
sent | PatientNotification | date | Filter by creation timestamp |
Access Policies
Access to FHIR resources is controlled by AccessPolicy resources attached to each ProjectMembership.
| Role | Policy |
|---|---|
| Patient | defaultPatientAccessPolicy — read their own FHIR resources, write to ChatMessage |
| Admin | Full access to all resources in the project |
| System (server) | Uses systemRepo — bypasses all access policies for internal operations |
See Auth → defaultPatientAccessPolicy for setup details.
PHI Audit Middleware
All FHIR reads are tracked by the PHI audit middleware (fhir/phi-audit-middleware.ts). Each read generates an AuditEvent resource. The breach detection system monitors these events for unusual access patterns.