EHR & Patient Management Integration Specifications

EHR & Patient Management Integration Specifications

Integration Summary

ID Target System Direction Trigger Event Data Exchanged Protocol Frequency Auth
INT-EHR-001 NABIDH (Dubai HIE) Bidirectional Patient registration/update; encounter open/close; clinical note signed ADT A01/A04/A08/A40, patient demographics, encounter notifications, CDA clinical documents HL7 v2.5.1 over MLLP/TLS Real-time mTLS + NABIDH OAuth 2.0
INT-EHR-002 Malaffi (Abu Dhabi HIE) Bidirectional Same as NABIDH, emirate-based routing ADT A01/A04/A08/A40, patient demographics, encounter notifications, CDA clinical documents HL7 v2.5.1 over MLLP/TLS Real-time mTLS (DOH-issued)
INT-EHR-003 Scheduling Bidirectional New registration; demographic update; appointment booking Patient demographics (view/create/update), encounter shell creation, visit status notifications Internal REST API + HL7 ADT (optional) Real-time Internal mTLS / JWT
INT-EHR-004 Billing & Claims Outbound Registration; insurance update; encounter status change Patient demographics, identifiers, insurance info, encounter data for claim creation Internal REST API + HL7 ADT Real-time Internal mTLS / JWT
INT-EHR-005 CPOE Outbound Allergy/problem list update; chart open Patient allergies, problem list, core demographics for order context Internal REST API / DB views Real-time Internal network + RBAC
INT-EHR-006 Patient Portal Bidirectional Patient login; data view; demographic update; document upload; consent change Patient demographics, clinical summaries, consents, documents; patient-initiated updates FHIR R4 REST API On-demand OAuth 2.0 + PKCE
INT-EHR-007 Insurance Eligibility (eClaimLink / DOH) Bidirectional Patient registration; insurance update; pre-encounter eligibility check Member validation, eligibility response, policy coverage details REST API (payer-specific) Real-time mTLS and/or OAuth 2.0 / keys

INT-EHR-001: NABIDH (Dubai HIE)

Business Context

What flows

  • Outbound from HIS to NABIDH:
  • Patient demographics and identifiers (MRN, Emirates ID, passport, mobile, address).
  • Encounter notifications (inpatient/outpatient registration, discharge).
  • Clinical documents (e.g., discharge summaries, outpatient visit summaries) as CDA.
  • Inbound from NABIDH to HIS:
  • External clinical documents for the patient (CDA).
  • Updated demographics if NABIDH is configured as a reference source (optional, usually view-only).

When

  • ADT A01/A04: New registration or admission in Dubai-licensed facilities.
  • ADT A08: Demographic updates (e.g., mobile, address, name corrections).
  • ADT A40: Patient merge / MPI resolution.
  • CDA: When a clinical note of a configured type (e.g., discharge summary) is signed.

Why

  • Meet DHA/NABIDH requirements for HIE participation.
  • Provide longitudinal patient record across Dubai providers.
  • Reduce duplicate testing and improve care coordination.

How often

  • Real-time: messages sent within seconds of the triggering event.

Error impact

  • Outbound failure: NABIDH may not have up-to-date demographics or encounters; could impact downstream providers’ view but does not block local care.
  • Inbound failure: External documents may not be visible; clinicians may miss outside history.
  • All failures must be logged and monitored to maintain NABIDH submission success KPI (≥ 99.5%).

HL7 v2.5.1 Technical Detail (NABIDH)

Primary Message Types

  • ADT^A04 – Outpatient registration.
  • ADT^A01 – Inpatient admission.
  • ADT^A08 – Demographic update.
  • ADT^A40 – Patient merge.
  • CDA documents are typically transported via separate document-sharing mechanisms (XDS.b) referenced from HL7 (if required by NABIDH profile); here we focus on ADT.

Sample: ADT^A04 – Outpatient Registration (Dubai)

HL7 v2
MSH|^~\&|HIS_EHR|DUBAIHOSP|NABIDH|DHA|20260207101530+0400||ADT^A04^ADT_A01|MSG20260207101530001|P|2.5.1|||AL|NE||UTF-8
EVN|A04|20260207101525+0400|||RC001^ALI^HASSAN^^^MR
PID|1||MRN202600987^^^DUBAIHOSP^MR~784-1985-1234567-1^^^AE^EID||AL-MAKTOUM^AHMED^MOHAMMED^^MR||19850315|M|||PO BOX 12345^^DUBAI^^00000^AE||+971501234567^PRN^PH^^^971^50^1234567|+97143211234^WPN^PH^^^971^4^3211234||M|||784-1985-1234567-1^^^AE^EID|||||||||||AE
PD1|||DUBCLINIC^^^DUBAIHOSP^^^^^DHA|PRV001^KHAN^SARA^AHMED^^DR^^^DHA
NK1|1|AL-MAKTOUM^FATIMA^ALI|SPO^Spouse|PO BOX 12345^^DUBAI^^00000^AE|+971505551111^PRN^PH
PV1|1|O|OPD^CARD^01^DUBAIHOSP^^BED01||||PRV001^KHAN^SARA^AHMED^^DR^^^DHA|||||||||ENC20260207000123^^^DUBAIHOSP^VN|||||||||||||||||||||||||20260207101000+0400
ZID|1|EID|784-1985-1234567-1|Verified
ZEM|1|Nationality|AE|United Arab Emirates

Key Segment Notes

  • MSH-3/4: Sending application/facility must match NABIDH registration.
  • PID-3: Multiple identifiers:
  • MRN: MRN202600987^^^DUBAIHOSP^MR
  • Emirates ID: 784-1985-1234567-1^^^AE^EID
  • PID-11: UAE address with PO Box and emirate.
  • PID-13/14: UAE-format phone numbers.
  • PV1-2: O for outpatient, I for inpatient.
  • PV1-19: Visit/encounter number, mapped from encounters.encounter_id.
  • ZID, ZEM: Example custom Z-segments for Emirates ID verification and nationality (exact structure to follow NABIDH profile).

Sample: ADT^A08 – Demographic Update (Dubai)

HL7 v2
MSH|^~\&|HIS_EHR|DUBAIHOSP|NABIDH|DHA|20260207113010+0400||ADT^A08^ADT_A08|MSG20260207113010001|P|2.5.1|||AL|NE||UTF-8
EVN|A08|20260207113005+0400|||RC002^SALEH^OMAR^^^MR
PID|1||MRN202600987^^^DUBAIHOSP^MR~784-1985-1234567-1^^^AE^EID||AL-MAKTOUM^AHMED^MOHAMMED^^MR||19850315|M|||PO BOX 67890^^DUBAI^^00000^AE||+971509998888^PRN^PH^^^971^50^9998888
PV1|1|O|OPD^CARD^01^DUBAIHOSP^^BED01||||PRV001^KHAN^SARA^AHMED^^DR^^^DHA|||||||||ENC20260207000123^^^DUBAIHOSP^VN

Sample: ADT^A40 – Patient Merge (Dubai)

HL7 v2
MSH|^~\&|HIS_EHR|DUBAIHOSP|NABIDH|DHA|20260207120000+0400||ADT^A40^ADT_A39|MSG20260207120000001|P|2.5.1|||AL|NE||UTF-8
EVN|A40|20260207115955+0400|||MRO001^YOUSEF^LAILA^^^MS
PID|1||MRN202600987^^^DUBAIHOSP^MR~784-1985-1234567-1^^^AE^EID||AL-MAKTOUM^AHMED^MOHAMMED^^MR||19850315|M
MRG|MRN202600654^^^DUBAIHOSP^MR~784-1985-1234567-1^^^AE^EID|MRN202600987^^^DUBAIHOSP^MR
  • PID-3: Surviving (primary) identifiers.
  • MRG-1: Prior (merged) identifiers.
  • MRG-2: Surviving identifiers (may repeat).

Field Mapping to EHR Tables

HL7 Field Table/Column
PID-3 (MRN) patients.mrn
PID-3 (EID) patient_identifiers.identifier_value (type = EID)
PID-5 (names) patients.first_name_en, last_name_en, etc.
PID-7 patients.date_of_birth
PID-8 patients.gender
PID-11 patient_demographics.address_line1_en, city, emirate, po_box
PID-13/14 patient_demographics.mobile_phone, home_phone
NK1 patient_demographics.emergency_contacts (JSON or child table)
PV1-19 encounters.encounter_id (FK)
PV1-3 locations (facility/department/bed)
EVN-2 Event timestamp (audit)
MRG-1/2 duplicate_suspects, merge logic in MPI

NABIDH-Specific Requirements

  • Use NABIDH-defined value sets for:
  • Gender, marital status, nationality, encounter type.
  • Emirates ID is mandatory where available and must be validated (format 784-YYYY-NNNNNNN-C).
  • All messages must be sent over MLLP within a TLS tunnel (mTLS).
  • Acknowledgement:
  • Expect ACK^A01/ACK^A08 with MSA-1 = AA (accept), AE (error), or AR (reject).
  • Store MSA-2 (message control ID) and status in integration_message_log.

Error Handling (INT-EHR-001)

Condition Handling Retry / Recovery
TCP/MLLP connection failure Queue message in integration_message_log with status queued; do not block registration UI Exponential backoff: 30s, 1m, 2m, 5m, 10m; after 10 attempts mark as failed and alert IT
No ACK within 30 seconds Treat as timeout; keep message in pending state Retry send up to 3 times; if still no ACK, mark suspect and alert interface team
ACK with AE (application error) Log error text; mark message error; do not auto-resend MRO/HIM correct data (e.g., invalid code) and trigger manual resend via admin UI
ACK with AR (application reject) Log as rejected; store reason; may indicate configuration issue Interface team investigates; resend only after root cause fixed
Invalid Emirates ID format Block outbound message; show validation error to registration clerk User corrects ID; message generated only after valid data
CDA document packaging error Do not send CDA; still send ADT Queue CDA for re-generation; alert HIS technical team
  • Dead-letter queue: messages with status failed or rejected older than 24 hours appear in an “Integration Exceptions” dashboard for HIM/IT.
  • All failures must be auditable for DHA/NABIDH compliance.

Retry and Recovery

Retry Strategy

Attempt Delay Max Elapsed Action on Final Failure
1 30 seconds 30s
2 1 minute 1m 30s
3 2 minutes 3m 30s
4 5 minutes 8m 30s
5 10 minutes 18m 30s
6–10 10 minutes each 68m 30s Mark failed; move to DLQ; alert Integration Admin
  • Trigger: TCP/MLLP connection failure or no ACK within 30 seconds.
  • Non-retryable: ACK with AE (application error) or AR (application reject) — route directly to DLQ for manual investigation.

Dead Letter Queue

  • Storage: integration_message_log rows with status IN ('failed', 'rejected') and endpoint = 'NABIDH'.
  • Visibility: “Integration Exceptions” dashboard filtered by endpoint, status, and age.
  • Retention: DLQ entries retained for 90 days (configurable); older entries archived per facility policy.
  • Resolution workflow: HIM/IT reviews DLQ entry → corrects root cause (data, configuration, or connectivity) → triggers manual resend via admin UI → system updates status to resent and logs new attempt.
  • Alerting: Email + dashboard alert to Integration Admin if DLQ depth > 10 messages or any message aged > 24 hours unresolved.

Idempotency

  • Deduplication key: MSH-10 (Message Control ID), unique per message.
  • NABIDH-side: NABIDH is expected to deduplicate by MSH-10; resending the same message should not create duplicate records.
  • HIS-side: On ACK receipt, system matches MSA-2 (acknowledging message control ID) to integration_message_log.message_control_id to update status; duplicate ACKs are ignored.

Reconciliation

  • Frequency: Daily at 03:00 (configurable).
  • Process: Batch job compares integration_message_log entries (status = sent, acked) for the previous 24 hours against expected events (registrations, updates, merges from audit_log). Any events without corresponding successful messages are flagged for re-transmission.
  • Report: Reconciliation discrepancies appear on the Integration Exceptions dashboard and in the daily integration health report sent to HIM Supervisor.
  • KPI: NABIDH submission success rate target >= 99.5%.

INT-EHR-002: Malaffi (Abu Dhabi HIE)

Business Context

What flows

  • Same categories as NABIDH:
  • Patient demographics and identifiers.
  • Encounter notifications.
  • CDA clinical documents.
  • Emirate-specific routing: only encounters at Abu Dhabi–licensed facilities are sent to Malaffi.

When

  • ADT A01/A04/A08/A40 on events occurring in facilities where facilities.emirate IN ('Abu Dhabi', 'Al Ain', 'Al Dhafra').

Why

  • Meet DOH/Malaffi participation requirements.
  • Support cross-provider care in Abu Dhabi.

How often

  • Real-time.

Error impact

  • Similar to NABIDH: HIE may be out-of-date; local care continues but external providers may lack latest data.

HL7 v2.5.1 Technical Detail (Malaffi)

Malaffi uses DOH-specific profiles; structure is similar to NABIDH but with DOH code sets and ADHICS security requirements.

Sample: ADT^A01 – Inpatient Admission (Abu Dhabi)

HL7 v2
MSH|^~\&|HIS_EHR|ADHOSP|MALAFFI|DOH|20260207104500+0400||ADT^A01^ADT_A01|MSG20260207104500001|P|2.5.1|||AL|NE||UTF-8
EVN|A01|20260207104455+0400|||RC010^OMAR^KHALID^^^MR
PID|1||MRNAD202600321^^^ADHOSP^MR~784-1990-7654321-3^^^AE^EID||AL-NAHYAN^FATIMA^SAEED^^MRS||19900620|F|||PO BOX 54321^^ABU DHABI^^00000^AE||+971502223344^PRN^PH^^^971^50^2223344|||M|||784-1990-7654321-3^^^AE^EID|||||||||||AE
PD1|||ADCLINIC^^^ADHOSP^^^^^DOH|PRV010^HASSAN^ALI^MOHAMMED^^DR^^^DOH
NK1|1|AL-NAHYAN^SAEED^ALI|HUS^Husband|PO BOX 54321^^ABU DHABI^^00000^AE|+971505556666^PRN^PH
PV1|1|I|WARD3^301^02^ADHOSP^^BED05||||PRV010^HASSAN^ALI^MOHAMMED^^DR^^^DOH|||||||||ENCAD2026020700456^^^ADHOSP^VN|||||||||||||||||||||||||20260207104000+0400
  • Same mapping as NABIDH; use DOH facility and provider codes.

Sample: ADT^A08 – Demographic Update (Abu Dhabi)

HL7 v2
MSH|^~\&|HIS_EHR|ADHOSP|MALAFFI|DOH|20260207130000+0400||ADT^A08^ADT_A08|MSG20260207130000001|P|2.5.1|||AL|NE||UTF-8
EVN|A08|20260207125955+0400|||RC011^SALEH^LAILA^^^MR
PID|1||MRNAD202600321^^^ADHOSP^MR~784-1990-7654321-3^^^AE^EID||AL-NAHYAN^FATIMA^SAEED^^MRS||19900620|F|||PO BOX 77777^^ABU DHABI^^00000^AE||+971507778888^PRN^PH^^^971^50^7778888
PV1|1|I|WARD3^301^02^ADHOSP^^BED05||||PRV010^HASSAN^ALI^MOHAMMED^^DR^^^DOH|||||||||ENCAD2026020700456^^^ADHOSP^VN

Field Mapping

Same as INT-EHR-001, but:

  • facilities.licensing_authority = 'DOH'.
  • Provider codes from DOH registry.

Malaffi-Specific Requirements

  • ADHICS-aligned security controls (network segmentation, logging).
  • DOH-specific value sets for:
  • Facility codes, provider identifiers, encounter types.
  • mTLS with DOH-issued certificates.
  • Acknowledgement handling identical to NABIDH (ACK with AA/AE/AR).

Error Handling (INT-EHR-002)

Same pattern as NABIDH, but separate queues and monitoring:

  • Separate integration_endpoint identifier for Malaffi.
  • Alerting rules may differ (e.g., DOH requires notification if downtime > defined threshold).
  • Messages failing due to DOH code-set issues must be flagged for master data correction (facility/provider codes).

Retry and Recovery

Retry Strategy

Attempt Delay Max Elapsed Action on Final Failure
1 30 seconds 30s
2 1 minute 1m 30s
3 2 minutes 3m 30s
4 5 minutes 8m 30s
5 10 minutes 18m 30s
6–10 10 minutes each 68m 30s Mark failed; move to DLQ; alert Integration Admin
  • Trigger: TCP/MLLP connection failure or no ACK within 30 seconds.
  • Non-retryable: ACK with AE or AR — route to DLQ for manual investigation. DOH code-set errors specifically flagged for master data correction.

Dead Letter Queue

  • Storage: integration_message_log rows with status IN ('failed', 'rejected') and endpoint = 'MALAFFI'.
  • Visibility: "Integration Exceptions" dashboard filtered by endpoint; separate from NABIDH queue for independent monitoring.
  • Retention: 90 days; archived per facility policy.
  • Resolution workflow: HIM/IT reviews DLQ entry → corrects root cause (DOH facility/provider codes, data quality, or connectivity) → triggers manual resend → system updates status.
  • Alerting: Email + dashboard alert to Integration Admin if DLQ depth > 10 messages or any message aged > 24 hours unresolved. DOH may require notification if outbound downtime exceeds a defined threshold.

Idempotency

  • Deduplication key: MSH-10 (Message Control ID), unique per message.
  • Malaffi-side: Malaffi deduplicates by MSH-10.
  • HIS-side: ACK matching via MSA-2 to integration_message_log.message_control_id.

Reconciliation

  • Frequency: Daily at 03:00 (configurable), separate from NABIDH reconciliation.
  • Process: Batch job compares integration_message_log entries for Malaffi endpoint against expected events for Abu Dhabi–licensed facilities (facilities.emirate IN ('Abu Dhabi', 'Al Ain', 'Al Dhafra')). Missing messages flagged for re-transmission.
  • Report: Discrepancies on Integration Exceptions dashboard and daily health report.
  • KPI: Malaffi submission success rate target >= 99.5%.

INT-EHR-003: Scheduling

Business Context

What flows

  • EHR → Scheduling:
  • New patient demographics for appointment booking.
  • Demographic updates (phone, address, insurance).
  • Scheduling → EHR:
  • Creation of encounter shell when appointment is confirmed/checked-in.
  • Updates to encounter status (scheduled, arrived, in-progress, completed, no-show).

When

  • On patient registration or demographic update (EHR pushes to Scheduling).
  • On appointment creation/check-in (Scheduling calls EHR to create/update encounter).

Why

  • Ensure a single source of truth for patient data.
  • Avoid duplicate patient creation in Scheduling.
  • Link appointments to encounters for clinical and billing workflows.

How often

  • Real-time, synchronous for APIs; optional HL7 ADT feed for legacy scheduling engines.

Error impact

  • If EHR → Scheduling fails: appointment staff may not see the latest demographics; manual re-entry risk.
  • If Scheduling → EHR fails: encounters may not be created; downstream modules (CPOE, billing) may lack encounter context.

HL7 v2.5.1 Technical Detail (Optional ADT Feed)

Some deployments may use HL7 ADT from EHR to a legacy scheduling system.

Sample: ADT^A04 – New Registration to Scheduling

HL7 v2
MSH|^~\&|HIS_EHR|MAINHOSP|SCHEDSYS|MAINHOSP|20260207111000+0400||ADT^A04^ADT_A01|MSG20260207111000001|P|2.5.1|||AL|NE||UTF-8
EVN|A04|20260207110955+0400|||RC020^AHMED^NOUR^^^MR
PID|1||MRN202601111^^^MAINHOSP^MR~784-1988-2223334-5^^^AE^EID||AL-SUWAIDI^OMAR^KHALID^^MR||19881201|M|||PO BOX 22222^^DUBAI^^00000^AE||+971501112233^PRN^PH
PV1|1|O|OPD^GEN^01^MAINHOSP^^BED01||||PRV020^ALI^HANA^MOHAMMED^^DR
  • Scheduling system uses PID/PV1 to create or update its own patient and visit records.

REST API Technical Detail (Primary)

1. EHR → Scheduling: Push/Sync Patient

Endpoint (Scheduling)
POST /api/v1/patients/sync

Request (from EHR)

JSON
{
  "externalId": "MRN202601111",
  "emiratesId": "784-1988-2223334-5",
  "firstNameEn": "Omar",
  "lastNameEn": "Al-Suwaidi",
  "firstNameAr": "عمر",
  "lastNameAr": "السويدي",
  "dateOfBirth": "1988-12-01",
  "gender": "M",
  "mobile": "+971501112233",
  "email": "[email protected]",
  "address": {
    "line1": "PO BOX 22222",
    "city": "Dubai",
    "emirate": "Dubai",
    "country": "AE"
  },
  "insurance": {
    "payerCode": "DAMAN",
    "memberId": "DAM123456789",
    "planId": "PLN-DAMAN-ENHANCED"
  }
}

Key Mappings

JSON Field Table/Column
externalId patients.mrn
emiratesId patient_identifiers (type = EID)
firstNameEn/Ar patients.first_name_en/ar
lastNameEn/Ar patients.last_name_en/ar
dateOfBirth patients.date_of_birth
gender patients.gender
mobile patient_demographics.mobile_phone
insurance.* insurance_plans, patient_identifiers (member ID)

2. Scheduling → EHR: Create Encounter Shell

Endpoint (EHR)
POST /api/v1/encounters

Request

JSON
{
  "patientMrn": "MRN202601111",
  "appointmentId": "APT-20260207-0001",
  "visitType": "OPD",
  "departmentCode": "CARD",
  "providerId": "PRV020",
  "scheduledStart": "2026-02-07T11:30:00+04:00",
  "facilityId": "MAINHOSP"
}

Response

JSON
{
  "encounterId": "ENC2026020700789",
  "status": "planned"
}

Error Handling (INT-EHR-003)

Condition Handling Retry / Recovery
Scheduling API unreachable Log failure; queue message in integration_message_log with target scheduling Exponential backoff: 15s, 30s, 1m, 2m, 5m; after 10 attempts mark as failed
4xx from Scheduling (validation) Do not retry; mark as rejected; store response body Registration supervisor corrects data and triggers manual re-sync
5xx from Scheduling Treat as transient; retry as above If > 30 minutes cumulative, alert IT
Encounter creation failure Appointment remains without encounter; Scheduling shows warning Staff can manually create encounter via EHR UI and re-link appointment
Duplicate patient detected in Sched. Scheduling returns conflict with existing externalId/emiratesId EHR logs and flags for MPI review; no auto-merge
  • Dead-letter queue: integration_message_log entries with status in ('failed','rejected') older than 24h.

Retry and Recovery

Retry Strategy

Attempt Delay Max Elapsed Action on Final Failure
1 15 seconds 15s
2 30 seconds 45s
3 1 minute 1m 45s
4 2 minutes 3m 45s
5 5 minutes 8m 45s
6–10 5 minutes each 33m 45s Mark failed; move to DLQ; alert IT
  • Trigger: 5xx server errors or network timeouts from Scheduling API.
  • Non-retryable: 4xx validation errors — route directly to DLQ for data correction by Registration Supervisor.
  • Timeout: 10 seconds per request; requests exceeding timeout are treated as failures.

Circuit Breaker

  • Threshold: 5 consecutive failures within 2 minutes → circuit opens.
  • Open state: All requests to Scheduling are queued locally (not sent) for 60 seconds.
  • Half-open: After 60 seconds, one probe request is sent; if successful, circuit closes and queued messages are drained. If probe fails, circuit remains open for another 60 seconds.
  • Alert: Dashboard + email alert to IT when circuit opens; auto-close notification when circuit recovers.

Dead Letter Queue

  • Storage: integration_message_log rows with status IN ('failed', 'rejected') and endpoint = 'SCHEDULING'.
  • Visibility: "Integration Exceptions" dashboard.
  • Retention: 30 days; older entries archived.
  • Resolution workflow: IT/Registration Supervisor reviews → corrects data or resolves connectivity → triggers manual re-sync via admin UI.

Idempotency

  • Deduplication key: patient_id + message_type + timestamp (truncated to second).
  • Scheduling-side: Patient sync endpoint uses externalId (MRN) as natural key; duplicate syncs perform upsert rather than insert, preventing duplicate patient records.
  • Encounter creation: appointmentId serves as idempotency key; duplicate encounter creation requests return existing encounter rather than creating a new one.

Reconciliation

  • Frequency: Nightly at 02:00.
  • Process: Batch job compares patients records (created/updated in last 24 hours) with Scheduling's patient table via reconciliation API (GET /api/v1/patients/reconcile?since={timestamp}). Mismatches (missing or stale records) are queued for re-sync.
  • Report: Reconciliation results logged in integration_message_log and visible on dashboard.

INT-EHR-004: Billing & Claims

Business Context

What flows

  • EHR → Billing:
  • Patient demographics and identifiers.
  • Insurance coverage details.
  • Encounter data (type, dates, attending provider, location) to support claim generation.

When

  • On registration (new patient or new encounter).
  • On insurance update.
  • On encounter status change (e.g., discharge, visit completion).

Why

  • Ensure billing has accurate data for claim submission to payers (eClaimLink, DOH eClaims).
  • Avoid claim rejections due to demographic/insurance mismatches.

How often

  • Real-time.

Error impact

  • If integration fails, claims may be delayed or rejected; manual re-entry may be required.

HL7 v2.5.1 Technical Detail (ADT to Billing)

Sample: ADT^A04 – Outpatient Registration to Billing

HL7 v2
MSH|^~\&|HIS_EHR|MAINHOSP|BILLING|MAINHOSP|20260207114500+0400||ADT^A04^ADT_A01|MSG20260207114500001|P|2.5.1|||AL|NE||UTF-8
EVN|A04|20260207114455+0400|||RC030^ALI^HASSAN^^^MR
PID|1||MRN202601222^^^MAINHOSP^MR~784-1982-5556667-9^^^AE^EID||AL-MAZROUI^HIND^AHMED^^MRS||19820510|F|||PO BOX 99999^^DUBAI^^00000^AE||+971501234890^PRN^PH
PV1|1|O|OPD^DERM^02^MAINHOSP^^BED03||||PRV030^YOUSEF^LAILA^OMAR^^DR|||||||||ENC2026020700999^^^MAINHOSP^VN
IN1|1|DAMAN|DAMAN^^^DHA|Daman Insurance||PO BOX 128888^^ABU DHABI^^00000^AE|+97126000000^WPN^PH||||AL-MAZROUI^HIND^AHMED||19820510|F|||||THIQA123456789|PLN-DAMAN-ENHANCED
IN2|1|784-1982-5556667-9^^^AE^EID

Key Segment Notes

  • IN1-3: Payer code (aligned with DHA/DOH payer registry).
  • IN1-36: Policy number / member ID.
  • IN2: Additional info (e.g., Emirates ID).

REST API Technical Detail

Endpoint (Billing)
POST /api/v1/patients-and-encounters

Request

JSON
{
  "patient": {
    "mrn": "MRN202601222",
    "emiratesId": "784-1982-5556667-9",
    "firstNameEn": "Hind",
    "lastNameEn": "Al-Mazroui",
    "firstNameAr": "هند",
    "lastNameAr": "المزروعي",
    "dateOfBirth": "1982-05-10",
    "gender": "F",
    "mobile": "+971501234890",
    "address": {
      "line1": "PO BOX 99999",
      "city": "Dubai",
      "emirate": "Dubai",
      "country": "AE"
    }
  },
  "encounter": {
    "encounterId": "ENC2026020700999",
    "visitType": "OPD",
    "departmentCode": "DERM",
    "facilityId": "MAINHOSP",
    "attendingProviderId": "PRV030",
    "start": "2026-02-07T11:30:00+04:00",
    "status": "in-progress"
  },
  "insurance": {
    "payerCode": "DAMAN",
    "planCode": "PLN-DAMAN-ENHANCED",
    "memberId": "THIQA123456789",
    "validFrom": "2026-01-01",
    "validTo": "2026-12-31"
  }
}

Error Handling (INT-EHR-004)

Condition Handling Retry / Recovery
Billing API unreachable Queue payload; do not block registration Exponential backoff: 30s, 1m, 2m, 5m, 10m; after 10 attempts mark failed
4xx validation error Mark as rejected; show notification to Registration Supervisor Correct data in EHR (e.g., missing payer code) and trigger manual re-send
5xx server error Treat as transient; retry If > 1 hour cumulative, alert RCM and IT
Insurance segment rejected Billing returns specific error code (e.g., invalid plan) Registration clerk prompted to correct insurance; new message sent on update

Retry and Recovery

Retry Strategy

Attempt Delay Max Elapsed Action on Final Failure
1 30 seconds 30s
2 1 minute 1m 30s
3 2 minutes 3m 30s
4 5 minutes 8m 30s
5 10 minutes 18m 30s
6–10 10 minutes each 68m 30s Mark failed; move to DLQ; alert RCM + IT
  • Trigger: 5xx server errors or network timeouts from Billing API.
  • Non-retryable: 4xx validation errors (e.g., invalid payer code, missing insurance) — route to DLQ for data correction.
  • Timeout: 15 seconds per request.

Circuit Breaker

  • Threshold: 5 consecutive failures within 2 minutes → circuit opens.
  • Open state: All outbound billing messages queued locally for 60 seconds.
  • Half-open: Probe request after 60 seconds; success closes circuit and drains queue.
  • Alert: Dashboard + email to RCM and IT when circuit opens.

Dead Letter Queue

  • Storage: integration_message_log rows with status IN ('failed', 'rejected') and endpoint = 'BILLING'.
  • Visibility: "Integration Exceptions" dashboard with RCM-specific filter view.
  • Retention: 60 days (billing data has longer audit requirements).
  • Resolution workflow: RCM reviews rejected messages → coordinates with Registration to correct data (insurance, payer codes) → triggers manual resend → billing module processes corrected payload.
  • Alerting: Email + dashboard alert if DLQ depth > 5 messages or cumulative failure > 1 hour.

Idempotency

  • Deduplication key: encounter_id + message_type (registration, insurance_update, status_change).
  • Billing-side: Billing uses encounter_id as natural key for encounter-related data; duplicate pushes perform upsert. Insurance updates are versioned by effective_date.

Reconciliation

  • Frequency: Nightly at 01:00.
  • Process: Batch job compares encounters with status changes in the last 24 hours (audit_log events for encounter registration, insurance update, discharge) against Billing's encounter records via reconciliation API. Missing or stale records are queued for re-push.
  • Report: Discrepancies flagged on dashboard and included in daily RCM operations report.
  • KPI: Billing data sync success rate target >= 99.9% (to minimize claim rejections).

INT-EHR-005: CPOE

Business Context

What flows

  • EHR → CPOE:
  • Patient demographics (read-only).
  • Allergy list.
  • Problem list.
  • CPOE uses this context for:
  • Clinical decision support (drug-allergy, drug-diagnosis checks).
  • Displaying patient context in order entry.

When

  • On chart open in CPOE.
  • On allergy or problem list update in EHR.

Why

  • Maintain a single source of truth for allergies and problems.
  • Avoid duplicate maintenance of clinical lists.

How often

  • Real-time, internal.

Error impact

  • If unavailable, CPOE may operate with stale or missing allergy/problem data; risk to patient safety.
  • CPOE must clearly indicate when allergy/problem data is unavailable.

Technical Detail (Internal API / DB Views)

Preferred approach is read-only DB views or internal REST.

Option A: Shared Database Views

  • vw_patient_allergies (in CPOE DB, view over EHR schema):
SQL
CREATE VIEW cpoe.vw_patient_allergies AS
SELECT
  pa.allergy_id,
  pa.patient_id,
  pa.allergen_code,
  pa.allergen_system,
  pa.allergen_display,
  pa.reaction_type,
  pa.severity,
  pa.manifestation_code,
  pa.manifestation_display,
  pa.onset_date,
  pa.status,
  pa.verified_by,
  pa.verified_date
FROM ehr.patient_allergies pa
WHERE pa.status IN ('active', 'historical');
  • vw_patient_problems similarly mapped from patient_problems.

Option B: REST API

Endpoint
GET /internal/cpoe/patients/{patientId}/context

Response

JSON
{
  "patient": {
    "id": "P202600987",
    "mrn": "MRN202600987",
    "emiratesId": "784-1985-1234567-1",
    "nameEn": "Ahmed Mohammed Al-Maktoum",
    "gender": "M",
    "dateOfBirth": "1985-03-15"
  },
  "allergies": [
    {
      "allergyId": "ALG-1001",
      "allergenCode": "70618",
      "allergenSystem": "RXNORM",
      "allergenDisplay": "Penicillin",
      "reactionType": "allergy",
      "severity": "severe",
      "manifestationCode": "39579001",
      "manifestationDisplay": "Anaphylaxis",
      "status": "active",
      "onsetDate": "2023-05-15"
    }
  ],
  "problems": [
    {
      "problemId": "PRB-2001",
      "icd10Code": "I10",
      "snomedCode": "38341003",
      "description": "Essential (primary) hypertension",
      "status": "active",
      "onsetDate": "2020-01-10",
      "priority": "chronic"
    }
  ]
}

Error Handling (INT-EHR-005)

Condition Handling Retry / Recovery
DB view unavailable CPOE detects DB error; show banner “Allergy/problem data unavailable” IT investigates DB connectivity; no automatic retry at app level
REST API timeout CPOE uses cached context (if available) and flags as “stale” Retry once; if still failing, log and alert application support
Partial data (e.g., allergies OK, problems fail) Display what is available; clearly indicate missing sections Log error; nightly job to reconcile discrepancies
  • No dead-letter queue required; internal integration, but errors must be logged in audit_log and application logs.

Retry and Recovery

Timeout and Circuit Breaker (synchronous internal integration)

Parameter Value Notes
Request timeout (REST API) 5 seconds CPOE displays cached data if timeout exceeded
DB view query timeout 3 seconds Query cancelled; CPOE shows "data unavailable" banner
Circuit breaker threshold 3 consecutive failures in 1 minute Circuit opens; CPOE operates on cached context
Circuit open duration 30 seconds Half-open probe after 30s; auto-close on success
Cache TTL 5 minutes CPOE caches patient context per session; refreshes on explicit reload
  • No DLQ required: This is a read-only, synchronous integration. CPOE pulls data from EHR; there are no queued outbound messages.
  • Degraded mode: When EHR data is unavailable, CPOE must clearly display "Allergy data unavailable — verify with patient" and "Problem list unavailable" banners. Ordering is not blocked but CDS alerts may be incomplete.
  • Alert: Application log entry + dashboard alert if CPOE-EHR circuit opens; IT investigates DB connectivity or REST API health.

Idempotency

  • Not applicable — read-only integration with no state-changing operations.

Reconciliation

  • Frequency: Nightly at 04:00.
  • Process: Batch job compares allergy and problem list counts per patient (EHR source vs CPOE cache, if persistent cache exists). Discrepancies are logged and CPOE cache invalidated for affected patients.
  • Report: Discrepancies logged in application monitoring; included in daily system health report.

INT-EHR-006: Patient Portal (FHIR R4)

Business Context

What flows

  • Patient Portal → EHR:
  • Demographic updates (contact info).
  • Document uploads (e.g., external reports).
  • Consent preferences (e.g., data sharing).
  • EHR → Patient Portal:
  • Patient demographics.
  • Clinical summaries (problems, allergies, notes).
  • Documents and consents.

When

  • On patient login and navigation in portal.
  • On patient-submitted updates.

Why

  • Enable patient engagement and UAE PDPL-compliant consent management.
  • Reduce front-desk workload for demographic updates.

How often

  • On-demand (per API call).

Error impact

  • If read fails: patient may not see latest data.
  • If write fails: patient updates not applied; must be clearly communicated to patient.

FHIR R4 Technical Detail

1. Patient Resource (Read from EHR)

Endpoint
GET /fhir/Patient/{id}

Sample JSON

JSON
{
  "resourceType": "Patient",
  "id": "MRN202600987",
  "identifier": [
    {
      "use": "usual",
      "type": {
        "coding": [
          {
            "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
            "code": "MR",
            "display": "Medical Record Number"
          }
        ]
      },
      "system": "http://ehr.gatesgroup.ae/mrn",
      "value": "MRN202600987"
    },
    {
      "use": "official",
      "type": {
        "coding": [
          {
            "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
            "code": "NI",
            "display": "National unique individual identifier"
          }
        ]
      },
      "system": "http://u.ae/emirates-id",
      "value": "784-1985-1234567-1"
    }
  ],
  "active": true,
  "name": [
    {
      "use": "official",
      "family": "Al-Maktoum",
      "given": ["Ahmed", "Mohammed"]
    },
    {
      "use": "official",
      "text": "أحمد محمد المكتوم"
    }
  ],
  "telecom": [
    {
      "system": "phone",
      "value": "+971501234567",
      "use": "mobile"
    },
    {
      "system": "email",
      "value": "[email protected]",
      "use": "home"
    }
  ],
  "gender": "male",
  "birthDate": "1985-03-15",
  "address": [
    {
      "use": "home",
      "line": ["PO BOX 12345"],
      "city": "Dubai",
      "district": "Dubai",
      "country": "AE"
    }
  ],
  "communication": [
    {
      "language": {
        "coding": [
          {
            "system": "urn:ietf:bcp:47",
            "code": "ar",
            "display": "Arabic"
          }
        ]
      },
      "preferred": true
    }
  ],
  "managingOrganization": {
    "reference": "Organization/DUBAIHOSP",
    "display": "Dubai General Hospital"
  }
}

Key Mappings

FHIR Element Table/Column
identifier[MR] patients.mrn
identifier[NI] patient_identifiers (type = EID)
name (EN/AR) patients.first_name_en/ar, last_name_en/ar
telecom patient_demographics.mobile_phone, email
address patient_demographics.address_line1_en, city, emirate, country
communication.language patient_demographics.preferred_language

Search Parameters

  • GET /fhir/Patient?identifier=http://u.ae/emirates-id|784-1985-1234567-1
  • GET /fhir/Patient?name=Al-Maktoum
  • GET /fhir/Patient?birthdate=1985-03-15

2. Patient Demographic Update (Portal → EHR)

Endpoint
PATCH /fhir/Patient/{id} (JSON Patch or FHIR Patch)

Example (simplified PUT)

JSON
{
  "resourceType": "Patient",
  "id": "MRN202600987",
  "telecom": [
    {
      "system": "phone",
      "value": "+971509999000",
      "use": "mobile"
    },
    {
      "system": "email",
      "value": "[email protected]",
      "use": "home"
    }
  ],
  "address": [
    {
      "use": "home",
      "line": ["PO BOX 77777"],
      "city": "Dubai",
      "district": "Dubai",
      "country": "AE"
    }
  ]
}
  • EHR writes changes to patient_demographics and creates an approval task if configured (e.g., for name or Emirates ID changes).

Resource: Consent

JSON
{
  "resourceType": "Consent",
  "id": "CONS-20260207-001",
  "status": "active",
  "scope": {
    "coding": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/consentscope",
        "code": "patient-privacy"
      }
    ]
  },
  "category": [
    {
      "coding": [
        {
          "system": "http://terminology.hl7.org/CodeSystem/consentcategorycodes",
          "code": "INFA",
          "display": "Information access"
        }
      ]
    }
  ],
  "patient": {
    "reference": "Patient/MRN202600987"
  },
  "dateTime": "2026-02-07T10:20:00+04:00",
  "performer": [
    {
      "reference": "Patient/MRN202600987"
    }
  ],
  "provision": {
    "type": "permit",
    "period": {
      "start": "2026-02-07T10:20:00+04:00"
    }
  }
}

Mapping

  • Consent.idpatient_consents.consent_id.
  • statuspatient_consents.status.
  • provision.period.start/endgranted_datetime / expiry_datetime.

Error Handling (INT-EHR-006)

Condition Handling Retry / Recovery
Auth failure (invalid token) Return HTTP 401/403; no data returned Portal prompts re-login; no retry from EHR side
Validation error on update Return HTTP 400 with OperationOutcome Portal displays error; patient can correct and resubmit
EHR FHIR server unavailable Portal shows “Service temporarily unavailable” Portal may retry once; EHR logs outage and alerts IT
Consent write failure Log error; do not assume consent granted Portal informs patient that consent change failed; retry after issue resolved
  • All FHIR calls logged in audit_log with resource_type = Patient, Consent, etc., and is_btg = false.

Retry and Recovery

Timeout and Circuit Breaker (synchronous FHIR API)

Parameter Value Notes
Request timeout 10 seconds Portal displays "Service temporarily unavailable" on timeout
Circuit breaker threshold 5 consecutive failures in 2 minutes Circuit opens; portal enters read-only cached mode
Circuit open duration 60 seconds Half-open probe after 60s
Portal-side retry 1 automatic retry on timeout No further automatic retries; patient informed to try again
  • Read failures (EHR → Portal): Portal may display cached data (if available) with "Data may not be current" notice. No DLQ needed for read operations.
  • Write failures (Portal → EHR): Patient-submitted updates (demographics, consents, documents) are stored in the portal's pending queue if EHR is unavailable.

Dead Letter Queue (Write Operations Only)

  • Storage: Portal-side pending queue for failed write operations (demographic updates, consent changes, document uploads).
  • Visibility: Portal admin dashboard shows pending submissions; patient sees "Update pending — we'll process it shortly" status.
  • Retention: 7 days; if unresolved, patient is notified to resubmit or contact the facility.
  • Resolution workflow: When EHR connectivity is restored, portal drains pending queue automatically. Failed items after retry are escalated to portal admin for manual processing.
  • Alerting: Portal admin alerted if pending queue depth > 20 items or any item aged > 4 hours.

Idempotency

  • Deduplication key: FHIR resource id + meta.versionId for reads; portal-generated transactionId for writes.
  • EHR-side: FHIR server uses If-Match headers (optimistic locking) to prevent stale updates; duplicate PATCH requests with same transactionId return success without re-applying changes.

Reconciliation

  • Frequency: Nightly at 05:00.
  • Process: Batch job compares portal's pending queue (any items not confirmed by EHR) and verifies that all processed updates are reflected in EHR data. Discrepancies are flagged for portal admin review.
  • Report: Reconciliation results on portal admin dashboard and in daily operations report.

Business Context

What flows

  • EHR → Payer gateway:
  • Patient demographics and insurance policy details.
  • Payer gateway → EHR:
  • Eligibility response (active/inactive, coverage details, co-pay).

When

  • On insurance capture during registration.
  • On explicit “Check Eligibility” action by registration clerk.
  • Optionally, nightly batch re-check for future scheduled encounters.

Why

  • Reduce claim denials due to inactive coverage.
  • Provide accurate co-pay information at point of service.

How often

  • Real-time for interactive checks.
  • Optional batch for scheduled appointments.

Error impact

  • If eligibility check fails, registration proceeds but flagged as “eligibility unknown”; billing risk increases.

REST API Technical Detail

Actual endpoints vary by payer; below is a generic pattern aligned with eClaimLink/DOH eClaims concepts.

Endpoint
POST /eligibility/check

Request

JSON
{
  "transactionId": "ELIG-20260207-0001",
  "payerCode": "DAMAN",
  "facilityId": "MAINHOSP",
  "patient": {
    "emiratesId": "784-1982-5556667-9",
    "firstNameEn": "Hind",
    "lastNameEn": "Al-Mazroui",
    "dateOfBirth": "1982-05-10",
    "gender": "F"
  },
  "insurance": {
    "memberId": "THIQA123456789",
    "policyNumber": "PLN-DAMAN-ENHANCED"
  },
  "serviceDate": "2026-02-07"
}

Response

JSON
{
  "transactionId": "ELIG-20260207-0001",
  "status": "eligible",
  "coverage": {
    "planName": "Daman Enhanced",
    "startDate": "2026-01-01",
    "endDate": "2026-12-31",
    "coPayPercent": 20,
    "networkStatus": "in-network"
  },
  "payerReference": "DAM-ELIG-99887766"
}

Mapping

  • statuspatients.insurance_eligibility_status (if such column exists) or stored in a dedicated eligibility table.
  • coverage.* → used by Billing & Claims for claim generation and patient estimates.

Error Handling (INT-EHR-007)

Condition Handling Retry / Recovery
Network / gateway timeout Mark eligibility as unknown; show warning to clerk Retry once automatically; further retries only on manual request
4xx error (invalid payload) Show error to clerk; do not retry Clerk corrects insurance/member ID and re-initiates check
5xx error (payer system down) Mark as unknown; log error Optionally schedule background retry; alert RCM if persistent
Eligibility status = ineligible Store response; flag encounter for RCM review Clerk may verify with payer via phone; update insurance details if needed
  • All eligibility requests/responses stored for audit and dispute resolution.

Retry and Recovery

Timeout and Circuit Breaker (synchronous external API)

Parameter Value Notes
Request timeout 15 seconds Payer gateways may be slow; generous timeout
Automatic retry 1 retry on timeout or 5xx No further automatic retries; clerk can manually re-check
Circuit breaker threshold 5 consecutive failures in 5 minutes (per payer) Circuit opens per payer; other payers unaffected
Circuit open duration 120 seconds Longer duration for external payer systems; half-open probe after 120s
  • Per-payer isolation: Circuit breakers are maintained per payer endpoint. A Daman outage does not affect ADNIC or other payer eligibility checks.
  • Degraded mode: When eligibility check fails, registration proceeds with eligibility_status = 'unknown'; encounter is flagged for RCM review. Clerk can retry manually later.

Dead Letter Queue

  • Storage: integration_message_log rows with status = 'failed' and endpoint = 'ELIGIBILITY_{payerCode}'.
  • Visibility: "Integration Exceptions" dashboard filtered by payer.
  • Retention: 30 days.
  • Resolution workflow: Failed interactive checks are not automatically retried (real-time context is lost). However, the nightly batch re-check (if configured) will automatically re-attempt eligibility for future scheduled encounters with unknown status.
  • Alerting: Dashboard alert if any payer's circuit breaker opens; email to RCM if > 10 eligibility failures in a day for a single payer.

Idempotency

  • Deduplication key: transactionId (generated per request, e.g., ELIG-{date}-{sequence}).
  • Payer-side: Most payer gateways are stateless for eligibility queries; duplicate requests simply return current eligibility status without side effects.
  • HIS-side: Eligibility responses are stored with transactionId; duplicate responses (from retries) update the same record rather than creating new entries.

Reconciliation

  • Frequency: Nightly at 00:30 (optional batch re-check).
  • Process: For all encounters scheduled in the next 48 hours with eligibility_status IN ('unknown', 'pending'), system re-runs eligibility check against the appropriate payer. Successful checks update status; persistent failures are flagged for manual follow-up by RCM.
  • Report: Batch eligibility results included in daily RCM operations report.
  • KPI: Eligibility verification rate at registration >= 95%.

Authentication & Security

Transport Security

  • All external integrations (NABIDH, Malaffi, payer APIs, portal) must use HTTPS/TLS 1.2+.
  • HL7 v2.5.1 over MLLP must be encapsulated in TLS tunnels with mutual TLS (mTLS).

Mutual TLS (mTLS)

  • NABIDH / Malaffi:
  • Client certificates issued by DHA/DOH or trusted CA.
  • Certificate rotation managed by IT security; downtime windows coordinated with HIE.
  • Payer APIs:
  • Some require mTLS; certificates managed per payer.

OAuth 2.0

  • Patient Portal:
  • Authorization Code + PKCE flow.
  • Access tokens scoped (e.g., patient/*.read, patient/*.write).
  • NABIDH:
  • Where required, use OAuth 2.0 client credentials for HIE API endpoints in addition to mTLS.
  • Internal APIs (Scheduling, Billing):
  • Use JWT-based service-to-service tokens with short lifetimes and audience restrictions.

API Key Management

  • For payer APIs that use API keys:
  • Keys stored in secure secrets vault.
  • Never hard-coded in application code.
  • Rotation procedures defined with minimal downtime.

Message Encryption & Data Protection

  • No PHI in logs beyond what is necessary for troubleshooting; Emirates ID and names should be masked where possible.
  • At-rest encryption for integration queues and logs per UAE PDPL and ADHICS/TDRA guidance.
  • Access to integration monitoring tools restricted to authorized roles (e.g., HIM Supervisor, System Administrator, Privacy Officer).

Audit & Privacy

  • All external data exchanges recorded in audit_log:
  • resource_type (e.g., HL7_ADT, FHIR_Patient, Eligibility).
  • action (send, receive, view).
  • user_id or system account.
  • timestamp, ip_address.
  • Break-the-glass (BTG) events that trigger external queries (e.g., HIE document retrieval) must be flagged with is_btg = true and reviewed by Privacy Officer.
  • Consent checks:
  • Before sending data to NABIDH/Malaffi or portal, verify patient_consents for relevant consent type (e.g., HIE sharing).
  • If consent withdrawn, suppress outbound messages except where UAE law mandates reporting (e.g., public health).

content/clinical/ehr-patient-mgmt/05-integrations.md Generated 2026-02-20 22:54