Pharmacy Information System Integration Specifications

Pharmacy Information System Integration Specifications

Integration Summary

ID Target System Direction Trigger Event Data Exchanged Protocol Frequency Auth
INT-PIS-001 CPOE Bidirectional Order signed; order verified/dispensed Inbound: medication orders. Outbound: dispensing status, pharmacist interventions HL7 v2.5.1 (RDE^O11) + FHIR R4 (MedicationRequest, MedicationDispense, DetectedIssue) Real-time mTLS (internal)
INT-PIS-002 EHR (Patient Chart) Outbound Medication dispensed, administered, or reconciled Medication list, eMAR records, pharmacy notes Internal API + FHIR R4 (MedicationStatement, MedicationAdministration, MedicationRequest, Annotation) Real-time Internal token / mTLS
INT-PIS-003 LIS (Antimicrobial Stewardship) Bidirectional Culture finalized; antimicrobial order placed Inbound: culture/sensitivity results. Outbound: antimicrobial orders and stewardship linkage Internal REST/Message API Real-time mTLS (intra-DC)
INT-PIS-004 Billing & Claims Outbound Medication dispensed Dispensing charges (drug, quantity, RxNorm/NDC, cost, payer linkage) Internal API + HL7 v2.5.1 DFT^P03 Real-time mTLS
INT-PIS-005 NABIDH (Dubai HIE) Outbound Medication dispensed Medication dispensing events, active medication list HL7 v2.5.1 over MLLP/TLS (NABIDH pharmacy profile) Near real-time mTLS + OAuth 2.0 (per NABIDH)
INT-PIS-006 Malaffi (Abu Dhabi HIE) Outbound Medication dispensed Medication dispensing events, active medication list HL7 v2.5.1 over MLLP/TLS (Malaffi pharmacy profile) Near real-time mTLS (DOH-issued cert)
INT-PIS-007 UAE MOH (Controlled Substances) Outbound Monthly reporting cycle; discrepancy event Controlled substance dispensing reports, inventory reconciliation, discrepancy events Secure file transfer (SFTP over SSH) and/or MOH web portal upload (CSV/XML) Monthly batch + event-driven VPN + key-based SFTP / MOH portal credentials
INT-PIS-008 Patient Portal Outbound Medication dispensed; refill available; patient views meds Medication list, refill status, instructions FHIR R4 REST API (MedicationRequest, MedicationDispense, MedicationStatement) On-demand (portal pull) + event push OAuth 2.0 (Authorization Code) + mTLS (internal)

INT-PIS-001: CPOE

Business Context

What flows

  • Inbound to PIS (from CPOE)
  • Medication orders: drug (RxNorm), dose, route, frequency, duration, indication, priority (STAT/routine), PRN details
  • Patient context: patient_id, encounter_id, demographics, allergies, weight, renal/hepatic function summary
  • Ordering provider: provider_id, specialty, DEA-equivalent authority flags for controlled substances (per MOH rules)

  • Outbound from PIS (to CPOE)

  • Order status updates: verified, rejected, modified, on-hold
  • Pharmacist interventions: type, recommendation, prescriber response
  • Dispensing status: first-dose dispensed, partial fill, backordered

When

  • Inbound: immediately when a provider signs a medication order in CPOE.
  • Outbound: when pharmacist verifies/rejects/modifies an order, and when dispensing events occur.

Why

  • Enables pharmacist clinical verification before dispensing.
  • Keeps prescribers informed of pharmacy actions and interventions.
  • Supports closed-loop medication management and auditability (DOH/DHA, UAE PDPL).

How often

  • High volume, real-time; every medication order and status change.

Error impact

  • Inbound failure: orders not visible to pharmacy; risk of delayed therapy.
  • Outbound failure: CPOE shows stale status; prescribers may duplicate orders or miss critical interventions.
  • All failures must be visible in an integration dashboard and logged for ADHICS/NESA audit.

HL7 v2.5.1 Technical Detail

Message Types

  • Inbound to PIS: RDE^O11 (Pharmacy/Treatment Encoded Order) – preferred for medication orders.
  • Outbound to CPOE: RDE^O11 with updated ORC/RXE status, or RDE^O11 + NTE for interventions.

Sample Inbound Order Message (CPOE → PIS)

HL7 v2
MSH|^~\&|HIS_CPOE|DUBAIHOSP|PIS|DUBAIHOSP|20260207103015+0400||RDE^O11|PIS20260207103015001|P|2.5.1|||AL|NE||UTF-8
PID|1||2026009876^^^DUBAIHOSP^MR~784-1985-1234567-1^^^AE^EID||AL-MAKTOUM^AHMED^HASSAN||19850315|M|||PO BOX 12345^^DUBAI^^00000^AE||+971501234567|||M||||||||||AE
PV1|1|I|4B^412^01^DUBAIHOSP||||KHAN^SARA^A^^^DR|||MED||||||||ENC2026020700456|||||||||||||||||||||||||20260207090000+0400
AL1|1|DA|70618^Penicillin^RXNORM|SV|Anaphylaxis|20230515
AL1|2|DA|763875^Sulfonamide^RXNORM|MO|Rash|20210110
ORC|NW|ORD-20260207-000123^HIS_CPOE|ORD-20260207-000123^PIS||SC|||^^^20260207110000+0400^^R|20260207103015+0400|||KHAN^SARA^A^^^DR^MD^^^^^PRC|+971504445555^WP^PH^^^+971^504445555|PO BOX 56789^^DUBAI^^00000^AE||PHARM^Inpatient Pharmacy^DUBAIHOSP
RXE|1|10|mg^milligram^UCUM|314076^Lisinopril 10 MG Oral Tablet^RXNORM|PO^Oral^HL70162|QD^Once daily^HL70335|||90|TAB^Tablet^UCUM|20260207103015+0400|||R|N|||I10^Essential hypertension^ICD10AM|||||||
RXR|PO^Oral^HL70162
OBX|1|NM|29463-7^Body weight^LN||78|kg^kilogram^UCUM|60-100|N|||F|||20260207080000+0400
OBX|2|NM|2160-0^Creatinine^LN||1.3|mg/dL^milligram/deciliter^UCUM|0.7-1.3|N|||F|||20260207080000+0400
NTE|1||Take once daily in the morning. Monitor blood pressure.

Key Segment Notes

  • PID-3: MRN + Emirates ID (EID) – required for UAE HIE alignment.
  • PV1-19: ENC2026020700456 maps to encounters.encounter_id.
  • ORC-1: NW (new order); later updates use XO (change) or CA (cancel).
  • ORC-2: CPOE order ID; primary key for idempotency.
  • RXE: Encoded order – dose, units, route, frequency, quantity, indication.
  • OBX: Optional clinical context (weight, creatinine) to support dose checking.

Sample Outbound Status/Intervention Message (PIS → CPOE)

HL7 v2
MSH|^~\&|PIS|DUBAIHOSP|HIS_CPOE|DUBAIHOSP|20260207104030+0400||RDE^O11|PIS20260207104030002|P|2.5.1|||AL|NE||UTF-8
PID|1||2026009876^^^DUBAIHOSP^MR~784-1985-1234567-1^^^AE^EID
PV1|1|I|4B^412^01^DUBAIHOSP||||KHAN^SARA^A^^^DR|||MED||||||||ENC2026020700456
ORC|OK|ORD-20260207-000123^HIS_CPOE|ORD-20260207-000123^PIS||CM|||^^^20260207110000+0400^^R|20260207104000+0400|||ALI^FATIMA^OMAR^^^PHARM^RPh||||PHARM^Inpatient Pharmacy^DUBAIHOSP
RXE|1|10|mg^milligram^UCUM|314076^Lisinopril 10 MG Oral Tablet^RXNORM|PO^Oral^HL70162|QD^Once daily^HL70335|||90|TAB^Tablet^UCUM|20260207104000+0400|||R|N|||I10^Essential hypertension^ICD10AM
NTE|1||Pharmacist intervention: Confirmed indication and renal function. Dose appropriate. No changes required.

Field Mapping to PIS Tables (Inbound)

HL7 Field PIS Table.Column
PID-3(1).ID (MRN) (via patient master) patients.patient_id
PID-3(2).ID (EID) patient_identifiers.identifier_value (type=EID)
PV1-19 pharmacy_orders.encounter_id
ORC-2 pharmacy_orders.order_id
ORC-9 (Date/Time of Transaction) pharmacy_orders.order_received_datetime
ORC-12 (Ordering Provider) pharmacy_orders.ordering_provider_id
RXE-5.1 (RxNorm code) pharmacy_orders.drug_code_rxnorm
RXE-5.2 pharmacy_orders.drug_name
RXE-3 + RXE-4 pharmacy_orders.dose, pharmacy_orders.dose_unit
RXE-6 pharmacy_orders.route
RXE-7 pharmacy_orders.frequency
RXE-10 pharmacy_orders.duration_days
RXE-15 pharmacy_orders.order_status (e.g., R=requested)
RXE-19 (Diagnosis) link to diagnosis table; optional in PIS
NTE-3 pharmacy_orders.special_instructions (additional column)

Field Mapping to PIS Tables (Outbound)

HL7 Field Source Table.Column
ORC-1 derived from pharmacy_orders.order_status (OK, CA, etc.)
ORC-9 pharmacy_orders.verified_datetime
ORC-12 pharmacy_orders.verified_by (pharmacist)
NTE-3 pharmacy_interventions.description / recommendation

FHIR R4 Technical Detail

Resources

  • Inbound: MedicationRequest (CPOE → PIS).
  • Outbound:
  • MedicationRequest (status updates)
  • MedicationDispense (dispensing status)
  • DetectedIssue (CDS alerts / pharmacist interventions, optional).

Sample Inbound MedicationRequest (CPOE → PIS)

JSON
{
  "resourceType": "MedicationRequest",
  "id": "ORD-20260207-000123",
  "status": "active",
  "intent": "order",
  "priority": "routine",
  "medicationCodeableConcept": {
    "coding": [
      {
        "system": "http://www.nlm.nih.gov/research/umls/rxnorm",
        "code": "314076",
        "display": "Lisinopril 10 MG Oral Tablet"
      }
    ],
    "text": "Lisinopril 10mg Tablet"
  },
  "subject": {
    "reference": "Patient/2026009876",
    "display": "Ahmed Hassan Al-Maktoum"
  },
  "encounter": {
    "reference": "Encounter/ENC2026020700456"
  },
  "authoredOn": "2026-02-07T10:30:15+04:00",
  "requester": {
    "reference": "Practitioner/KHAN-SARA",
    "display": "Dr. Sara Khan"
  },
  "reasonCode": [
    {
      "coding": [
        {
          "system": "http://hl7.org/fhir/sid/icd-10-am",
          "code": "I10",
          "display": "Essential hypertension"
        }
      ]
    }
  ],
  "dosageInstruction": [
    {
      "text": "Take 10mg by mouth once daily in the morning",
      "timing": {
        "repeat": {
          "frequency": 1,
          "period": 1,
          "periodUnit": "d"
        },
        "code": {
          "coding": [
            {
              "system": "http://terminology.hl7.org/CodeSystem/v3-GTSAbbreviation",
              "code": "QD",
              "display": "Once daily"
            }
          ]
        }
      },
      "route": {
        "coding": [
          {
            "system": "http://snomed.info/sct",
            "code": "26643006",
            "display": "Oral route"
          }
        ]
      },
      "doseAndRate": [
        {
          "doseQuantity": {
            "value": 10,
            "unit": "mg",
            "system": "http://unitsofmeasure.org",
            "code": "mg"
          }
        }
      ]
    }
  ],
  "dispenseRequest": {
    "quantity": {
      "value": 90,
      "unit": "tablet"
    },
    "expectedSupplyDuration": {
      "value": 90,
      "unit": "days",
      "system": "http://unitsofmeasure.org",
      "code": "d"
    }
  },
  "note": [
    {
      "text": "Take once daily in the morning. Monitor blood pressure."
    }
  ]
}

Key Element Mapping

FHIR Element PIS Table.Column
id pharmacy_orders.order_id
status pharmacy_orders.order_status
subject.reference pharmacy_orders.patient_id
encounter.reference pharmacy_orders.encounter_id
requester.reference pharmacy_orders.ordering_provider_id
medicationCodeableConcept.coding[rxnorm].code pharmacy_orders.drug_code_rxnorm
medicationCodeableConcept.text pharmacy_orders.drug_name
dosageInstruction[0].doseAndRate[0].doseQuantity.value pharmacy_orders.dose
dosageInstruction[0].doseAndRate[0].doseQuantity.code pharmacy_orders.dose_unit
dosageInstruction[0].route.coding[0].code pharmacy_orders.route (mapped)
dosageInstruction[0].timing.repeat pharmacy_orders.frequency (coded)
dispenseRequest.expectedSupplyDuration.value pharmacy_orders.duration_days

Sample Outbound MedicationDispense (PIS → CPOE)

JSON
{
  "resourceType": "MedicationDispense",
  "id": "DISP-20260207-000789",
  "status": "completed",
  "medicationCodeableConcept": {
    "coding": [
      {
        "system": "http://www.nlm.nih.gov/research/umls/rxnorm",
        "code": "314076",
        "display": "Lisinopril 10 MG Oral Tablet"
      }
    ]
  },
  "subject": {
    "reference": "Patient/2026009876"
  },
  "context": {
    "reference": "Encounter/ENC2026020700456"
  },
  "authorizingPrescription": [
    {
      "reference": "MedicationRequest/ORD-20260207-000123"
    }
  ],
  "quantity": {
    "value": 90,
    "unit": "tablet"
  },
  "whenHandedOver": "2026-02-07T11:05:00+04:00",
  "performer": [
    {
      "actor": {
        "reference": "Practitioner/ALI-FATIMA",
        "display": "Fatima Omar Ali, RPh"
      }
    }
  ]
}

Search Parameters (PIS as FHIR server for CPOE)

  • GET /MedicationRequest?patient={id}&status=active – active orders for a patient.
  • GET /MedicationDispense?authorizingPrescription={order-id} – dispensing history for an order.
  • GET /DetectedIssue?implicated=MedicationRequest/{id} – pharmacist interventions for an order.

Error Handling (INT-PIS-001)

Scenario Handling Retry / Alert
Network timeout (HL7 or FHIR) Message persisted in integration_message_log with status pending; not acknowledged to source Exponential backoff: 30s, 1m, 2m, 5m, 10m; after 5 failures, raise alert to integration support and pharmacy supervisor
HL7 negative ACK (AE/AR) from PIS or CPOE Log full message + ACK; mark as error; no auto-retry Manual review via integration console; corrected order can be re-sent with same order_id
FHIR 4xx from either side Validation error; parse OperationOutcome and store No auto-retry; show error in UI (if synchronous) or integration dashboard
FHIR 5xx Temporary remote failure Same exponential backoff as above; after 15 minutes continuous failure, send email/SMS to on-call
Duplicate order (same order_id) Idempotent processing: ignore if already processed with same payload hash Logged as duplicate for audit
Message parsing error Store raw payload; mark as parse_error No retry; manual fix required

Manual recovery: integration admin can requeue failed messages from integration_message_log by ID; all replays must be audit-logged (user, timestamp, reason) for ADHICS compliance.

Retry and Recovery

Retry Strategy

Failure Type Retry Interval Max Attempts Backoff Final Action
HL7 MLLP timeout (no ACK) 30s, 1m, 2m, 5m, 10m 5 Exponential with jitter Move to DLQ; alert pharmacy supervisor + integration support
FHIR 5xx (server error) 30s, 1m, 2m, 5m, 10m 5 Exponential with jitter Move to DLQ; alert on-call support
FHIR 429 (rate limited) Respect Retry-After header; default 60s 10 Per server directive Move to DLQ; review rate limits with CPOE team
HL7 negative ACK (AE/AR) No auto-retry 0 N/A Log error; manual review in integration console
FHIR 4xx (validation error) No auto-retry 0 N/A Log OperationOutcome; manual correction required
Message parse error No auto-retry 0 N/A Store raw payload; alert integration team

Dead Letter Queue

Failed messages are written to the integration_dlq table:

Column Value
source_system CPOE or PIS (depending on direction)
message_type RDE^O11, MedicationRequest, MedicationDispense, DetectedIssue
failure_reason Timeout, negative ACK code, HTTP status, parse error description
retry_count Number of attempts before DLQ entry
raw_payload Full message content (HL7 or FHIR JSON)
created_at Timestamp of DLQ entry
resolved_at NULL until manually resolved
resolved_by User ID of admin who resolved

DLQ review cadence: every 4 hours during pharmacy operating hours; critical items (STAT orders, interventions) reviewed within 30 minutes.

Idempotency

  • Inbound (CPOE to PIS): Deduplication key = ORC-2 (placer order number) + ORC-1 (order control) + MSH-10 (message control ID). If a message with the same ORC-2 and matching payload hash already exists in pharmacy_orders, the duplicate is logged and discarded.
  • Outbound (PIS to CPOE): Deduplication key = [dispensing_id]_[message_type]_[event_datetime]. CPOE must ignore duplicate status updates with the same composite key.

Reconciliation

  • Hourly: Automated count comparison — orders received in CPOE (ORC-1 = NW) vs. orders present in pharmacy_orders for the same hour window.
  • Daily: Full reconciliation report comparing CPOE order IDs with PIS verification/dispensing status; unmatched orders flagged for investigation.
  • Post-outage: PIS requests a FHIR MedicationRequest?_lastUpdated=gt[outage_start] query to CPOE to retrieve any orders missed during downtime.

INT-PIS-002: EHR (Patient Chart)

Business Context

What flows

  • Active and historical medication list (orders + dispenses).
  • eMAR records (actual administrations, holds, refusals, PRN responses).
  • Pharmacy notes/interventions relevant to the patient chart.

When

  • On each dispense, administration, reconciliation, or order status change.
  • On-demand when EHR requests latest medication timeline.

Why

  • Provides clinicians a consolidated view of medications in the EHR.
  • Supports clinical decision-making and continuity of care.
  • Required for NABIDH/Malaffi-aligned longitudinal medication history.

How often

  • Real-time event push + on-demand queries.

Error impact

  • If updates fail, EHR medication list may be stale; risk of duplicate therapy or missed doses.
  • Must be clearly indicated in EHR UI if medication data is not current.

Technical Detail (Internal API + FHIR)

No HL7 v2 here; internal REST/FHIR.

Primary Resources

  • MedicationRequest – order-level view.
  • MedicationDispense – dispensing events.
  • MedicationAdministration – eMAR.
  • MedicationStatement – reconciled/home meds.
  • Annotation – pharmacy notes (embedded).

Sample MedicationAdministration (PIS → EHR)

JSON
{
  "resourceType": "MedicationAdministration",
  "id": "ADMIN-20260207-001234",
  "status": "completed",
  "medicationCodeableConcept": {
    "coding": [
      {
        "system": "http://www.nlm.nih.gov/research/umls/rxnorm",
        "code": "314076",
        "display": "Lisinopril 10 MG Oral Tablet"
      }
    ]
  },
  "subject": {
    "reference": "Patient/2026009876",
    "display": "Ahmed Hassan Al-Maktoum"
  },
  "context": {
    "reference": "Encounter/ENC2026020700456"
  },
  "effectiveDateTime": "2026-02-07T09:00:00+04:00",
  "performer": [
    {
      "actor": {
        "reference": "Practitioner/NURSE-001",
        "display": "Nurse Aisha Al-Nahyan"
      }
    }
  ],
  "dosage": {
    "route": {
      "coding": [
        {
          "system": "http://snomed.info/sct",
          "code": "26643006",
          "display": "Oral route"
        }
      ]
    },
    "dose": {
      "value": 10,
      "unit": "mg",
      "system": "http://unitsofmeasure.org",
      "code": "mg"
    }
  },
  "request": {
    "reference": "MedicationRequest/ORD-20260207-000123"
  },
  "note": [
    {
      "text": "Barcode verified; patient tolerated well."
    }
  ]
}

Mapping to PIS Tables

FHIR Element PIS Table.Column
id medication_administration.admin_id
status medication_administration.status
subject.reference medication_administration.patient_id
context.reference medication_administration.encounter_id
effectiveDateTime medication_administration.actual_datetime
dosage.dose.value medication_administration.dose_given
dosage.route medication_administration.route
performer.actor medication_administration.administered_by
note[0].text medication_administration.notes (additional column)

Search Parameters (EHR → PIS)

  • GET /MedicationAdministration?patient={id}&date=ge2026-02-01
  • GET /MedicationRequest?patient={id}&status=active
  • GET /MedicationStatement?patient={id} – reconciled/home meds.

Error Handling (INT-PIS-002)

  • Internal API calls are synchronous; if PIS is unavailable, EHR shows an inline error and may retry after 5–10 seconds.
  • Event pushes (webhooks or message bus) use the same retry/backoff pattern as INT-PIS-001.
  • Dead-letter queue for events that fail >5 times; visible in integration console.
  • Manual reconciliation: EHR can request a full medication sync for a patient (/MedicationAdministration?patient=...&_since=...) after outages.

Retry and Recovery

Retry Strategy

Failure Type Retry Interval Max Attempts Backoff Final Action
Synchronous API timeout (EHR → PIS query) 5s, 10s 2 Linear Show inline error in EHR UI; user can retry manually
Event push failure (PIS → EHR webhook/bus) 30s, 1m, 2m, 5m, 10m 5 Exponential with jitter Move to DLQ; alert integration support
Event push 5xx from EHR 30s, 1m, 2m, 5m, 10m 5 Exponential with jitter Move to DLQ
Event push 4xx (validation) No auto-retry 0 N/A Log; manual correction; alert integration team

Dead Letter Queue

Failed event pushes are written to integration_dlq:

Column Value
source_system PIS
target_system EHR
message_type MedicationDispense, MedicationAdministration, MedicationStatement
failure_reason Timeout, HTTP error code, validation error
raw_payload FHIR resource JSON

DLQ review cadence: every 4 hours; critical medication administration events reviewed within 1 hour.

Idempotency

  • Event push deduplication key = [resource_type]_[resource_id]_[lastUpdated]. EHR discards events where the resource version is older than or equal to the currently stored version.
  • Synchronous queries are inherently idempotent (read-only GET requests).

Reconciliation

  • Post-outage: EHR triggers a full medication sync per patient using GET /MedicationAdministration?patient={id}&_since={outage_start} and GET /MedicationDispense?patient={id}&_since={outage_start}.
  • Daily: Automated comparison of pharmacy_dispensing records vs. EHR MedicationDispense resources for the past 24 hours; discrepancies flagged in integration dashboard.

INT-PIS-003: LIS (Antimicrobial Stewardship)

Business Context

What flows

  • Inbound from LIS: culture and sensitivity results, organism, MIC, susceptibility (S/I/R).
  • Outbound from PIS: antimicrobial orders, stewardship review linkage, recommendations.

When

  • Inbound: when LIS finalizes culture/sensitivity results.
  • Outbound: when antimicrobial orders are placed or stewardship reviews are recorded.

Why

  • Supports antimicrobial stewardship pharmacists in optimizing therapy, reducing resistance, and meeting facility and MOH quality expectations.

How often

  • Real-time; moderate volume.

Error impact

  • Missing culture data → delayed de-escalation, prolonged broad-spectrum use.
  • Missing outbound stewardship data → incomplete audit trail and metrics.

Technical Detail (Internal API)

Typical pattern: JSON over HTTPS between PIS and LIS/stewardship engine.

Example Inbound Culture Result (LIS → PIS)

JSON
{
  "cultureResultId": "CULT-20260207-00045",
  "patientId": "2026009876",
  "encounterId": "ENC2026020700456",
  "specimen": "Blood",
  "collectionDateTime": "2026-02-06T22:15:00+04:00",
  "organisms": [
    {
      "code": "112283007",
      "system": "http://snomed.info/sct",
      "display": "Escherichia coli",
      "susceptibilities": [
        {
          "antibioticRxNorm": "197361",
          "antibioticName": "Ceftriaxone",
          "mic": "0.5",
          "interpretation": "S"
        },
        {
          "antibioticRxNorm": "36567",
          "antibioticName": "Ciprofloxacin",
          "mic": "4",
          "interpretation": "R"
        }
      ]
    }
  ],
  "status": "final"
}

Mapping

  • cultureResultIdantimicrobial_stewardship_reviews.culture_result_id
  • patientIdantimicrobial_stewardship_reviews.patient_id
  • Organism/susceptibility stored in a LIS-owned schema or a shared stewardship schema (not in PIS core tables).

Example Outbound Stewardship Review (PIS → LIS / Analytics)

JSON
{
  "reviewId": "AST-20260207-00012",
  "orderId": "ORD-20260207-000555",
  "patientId": "2026009876",
  "antibioticRxNorm": "197361",
  "reviewType": "de-escalation",
  "indication": "Urosepsis",
  "cultureResultId": "CULT-20260207-00045",
  "recommendation": "De-escalate from meropenem to ceftriaxone based on susceptibility.",
  "accepted": true,
  "reviewedBy": "PHARM-AST-001",
  "reviewedDateTime": "2026-02-07T11:30:00+04:00",
  "prescriberResponse": "Accepted; order changed to ceftriaxone."
}

Maps directly to antimicrobial_stewardship_reviews table.


Error Handling (INT-PIS-003)

  • If LIS push fails, LIS queues and retries; PIS logs inbound failures.
  • If PIS push of stewardship review fails, messages are queued with backoff; stewardship dashboard shows “pending export” status.
  • No data loss allowed; all culture IDs and review IDs must be idempotent.

Retry and Recovery

Retry Strategy

Failure Type Retry Interval Max Attempts Backoff Final Action
LIS → PIS push failure (culture result) 30s, 1m, 2m, 5m 5 Exponential with jitter Move to DLQ on LIS side; alert LIS integration support + stewardship pharmacist
PIS → LIS push failure (stewardship review) 30s, 1m, 2m, 5m 5 Exponential with jitter Move to DLQ on PIS side; stewardship dashboard shows "pending export"
REST API timeout (either direction) 10s, 20s, 40s 3 Exponential Move to DLQ; alert integration team
4xx validation error No auto-retry 0 N/A Log error; manual review; alert integration team

Dead Letter Queue

Column Value
source_system LIS (for inbound culture results) or PIS (for outbound stewardship reviews)
message_type DiagnosticReport (culture), stewardship_review_notification
failure_reason Timeout, HTTP error, validation failure
raw_payload FHIR JSON or internal API payload

DLQ review cadence: every 2 hours (culture results are clinically time-sensitive for antimicrobial stewardship decisions).

Idempotency

  • Inbound culture results: Deduplication key = [diagnostic_report_id]_[result_status]_[last_updated]. Duplicate results with same report ID and version are discarded; updated results (amended/final) replace prior preliminary data.
  • Outbound stewardship reviews: Deduplication key = [stewardship_review_id]_[review_status]. LIS ignores duplicate notifications for the same review at the same status.

Reconciliation

  • Every 6 hours: PIS queries LIS for finalized culture reports for patients with active antimicrobial orders (GET /DiagnosticReport?category=microbiology&status=final&date=gt{6h_ago}); any missing reports are flagged.
  • Daily: Cross-reference antimicrobial_stewardship_reviews with LIS culture result log to ensure all positive cultures with active antimicrobial orders have been reviewed.

INT-PIS-004: Billing & Claims

Business Context

What flows

  • Chargeable dispensing events with: patient, encounter, payer, drug (RxNorm + NDC if available), quantity, unit cost, total cost, charge code (CPT/HCPCS or internal), and flags for controlled substances.

When

  • Each time a medication is dispensed (inpatient or outpatient).

Why

  • Enables accurate pharmacy revenue capture and integration with eClaimLink (DHA) / DOH eClaims via the billing module.
  • Supports cost analytics and stock valuation.

How often

  • Real-time; high volume.

Error impact

  • Failed charges → revenue leakage, manual reconciliation.
  • Duplicate charges → claim rejections, patient complaints.

HL7 v2.5.1 Technical Detail

Message Type: DFT^P03 (Detailed Financial Transaction)

Sample DFT^P03 (PIS → Billing)

HL7 v2
MSH|^~\&|PIS|DUBAIHOSP|BILLING|DUBAIHOSP|20260207111530+0400||DFT^P03|DFT20260207111530001|P|2.5.1|||AL|NE||UTF-8
EVN|P03|20260207111530+0400
PID|1||2026009876^^^DUBAIHOSP^MR~784-1985-1234567-1^^^AE^EID||AL-MAKTOUM^AHMED^HASSAN||19850315|M
PV1|1|I|4B^412^01^DUBAIHOSP||||KHAN^SARA^A^^^DR|||MED||||||||ENC2026020700456
FT1|1|20260207111000+0400|20260207111000+0400|CG|RX^Pharmacy charge^C4|DISP-20260207-000321|314076^Lisinopril 10 MG Oral Tablet^RXNORM|2|TAB^Tablet^UCUM|5.00|10.00|AED^UAE Dirham^ISO4217|||PHARM-TECH-001^HASSAN^OMAR^^^TECH|PHARM^Inpatient Pharmacy^DUBAIHOSP|||NDC12345678
ZPH|DISP-20260207-000321|ORD-20260207-000123|10.00|5.00|unit_cost

Key Segment Notes

  • FT1-6: Transaction type CG (charge).
  • FT1-7: Transaction ID = pharmacy_dispensing.dispensing_id.
  • FT1-8: RxNorm-coded drug.
  • FT1-9: Quantity dispensed.
  • FT1-11/FT1-12: Unit price and total amount.
  • FT1-13: Currency (AED).
  • Custom ZPH segment carries additional pharmacy-specific data (order_id, unit_cost).

Mapping

HL7 Field PIS Table.Column
FT1-7 pharmacy_dispensing.dispensing_id
FT1-8.1 pharmacy_dispensing.drug_code_rxnorm
FT1-9 pharmacy_dispensing.quantity_dispensed
FT1-11 pharmacy_dispensing.unit_cost
FT1-12 computed total cost
FT1-16 pharmacy_dispensing.dispensed_by
ZPH-2 pharmacy_orders.order_id

Error Handling (INT-PIS-004)

  • If billing system is down, DFT messages are queued; no user-facing error in pharmacy UI.
  • Duplicate detection by FT1-7 (dispensing_id) on billing side.
  • Reconciliation report compares pharmacy_dispensing vs. accepted charges daily.

Retry and Recovery

Retry Strategy

Failure Type Retry Interval Max Attempts Backoff Final Action
HL7 MLLP timeout (DFT) 30s, 1m, 2m, 5m, 10m 5 Exponential with jitter Move to DLQ; alert revenue cycle team
HL7 negative ACK (AE/AR) No auto-retry 0 N/A Log; manual review in integration console
Internal API timeout 10s, 20s 2 Linear Move to DLQ; alert integration support
Billing system unavailable (planned maintenance) Queue all DFT messages; resume on recovery N/A N/A Drain queue in FIFO order on recovery; alert if queue > 1000 messages

Dead Letter Queue

Column Value
source_system PIS
target_system BILLING
message_type DFT^P03
failure_reason Timeout, negative ACK code, billing validation error
raw_payload Full HL7 DFT message

DLQ review cadence: every 4 hours during business hours. Revenue integrity team reviews daily for completeness.

Idempotency

  • Deduplication key = FT1-7 (dispensing_id). Billing system rejects duplicate charges with the same dispensing_id; returns AE with duplicate indicator.
  • Credit/reversal messages use FT1-6 = CR with the original FT1-7 to reverse prior charges.

Reconciliation

  • Daily: Automated reconciliation report compares pharmacy_dispensing (all records with status = DISPENSED for the day) against accepted charges in billing. Unmatched dispensing records are flagged for resubmission.
  • Monthly: Revenue integrity review compares total drug cost from pharmacy_dispensing against total pharmacy charges posted in billing for the month; variance > 1% triggers investigation.
  • Post-outage: PIS replays all queued DFT messages in chronological order; billing system deduplicates using FT1-7.

INT-PIS-005: NABIDH (Dubai HIE)

Business Context

What flows

  • Outbound reporting of medication dispensing events and current medication list for Dubai-licensed facilities, per NABIDH pharmacy profile.

When

  • Each time a medication is dispensed for a patient whose encounter is in a NABIDH-participating Dubai facility.

Why

  • Supports cross-facility medication reconciliation and safety.
  • Required by DHA NABIDH policies for connected providers.

How often

  • Near real-time; messages buffered and sent within minutes.

Error impact

  • Failed submissions reduce HIE completeness; KPI “NABIDH/Malaffi Dispensing Submission Rate” must remain ≥ 99.5%.
  • Facility must be able to demonstrate retry and error management to DHA.

HL7 v2.5.1 Technical Detail (NABIDH Profile)

Message Type: Typically RDE^O11 or RDS^O13-like profile for dispenses; exact profile per NABIDH spec. Here we model as RDE^O11 with dispense context.

Sample Message (PIS → NABIDH)

HL7 v2
MSH|^~\&|PIS|DUBAIHOSP|NABIDH|DHA|20260207113000+0400||RDE^O11|NABIDH20260207113000001|P|2.5.1|||AL|NE||UTF-8
PID|1||2026009876^^^DUBAIHOSP^MR~784-1985-1234567-1^^^AE^EID||AL-MAKTOUM^AHMED^HASSAN||19850315|M|||PO BOX 12345^^DUBAI^^00000^AE||+971501234567
PV1|1|O|OPD^PHARM^01^DUBAIHOSP||||KHAN^SARA^A^^^DR|||OPD||||||||ENC2026020700789
ORC|RE|ORD-20260207-000789^HIS_CPOE|ORD-20260207-000789^PIS||CM|||^^^20260207112500+0400^^R|20260207112500+0400|||ALI^FATIMA^OMAR^^^PHARM^RPh
RXE|1|500|mg^milligram^UCUM|202531^Amoxicillin 500 MG Oral Capsule^RXNORM|PO^Oral^HL70162|TID^Three times daily^HL70335|||21|CAP^Capsule^UCUM|20260207112500+0400|||A|N|||J02.9^Acute pharyngitis^ICD10AM
RXD|1|20260207112500+0400|202531^Amoxicillin 500 MG Oral Capsule^RXNORM|21|CAP^Capsule^UCUM||ALI^FATIMA^OMAR^^^PHARM^RPh||LOT12345|20270201|DUBAIHOSP^Main Pharmacy^DUBAIHOSP

NABIDH Requirements (Conceptual)

  • Emirates ID in PID-3 or PID-18 as per NABIDH profile.
  • Facility and provider identifiers aligned with DHA master codes.
  • Use RxNorm for medications; ICD-10-AM for indications.
  • TLS 1.2+ with DHA-issued mTLS certificates.
  • HL7 ACK handling: PIS must process ACK and update integration_message_log.hie_submission_status.

Mapping

  • Same as internal RDE, plus:
  • RXD segment fields map to pharmacy_dispensing (lot, expiry, location).
  • integration_message_log tracks message_control_id, hie_submission_status, hie_submission_datetime.

Error Handling (INT-PIS-005)

  • If NABIDH connection fails, messages remain in an outbound queue with status pending_hie.
  • Retry schedule: every 5 minutes for 1 hour, then hourly for 24 hours.
  • After 24 hours, mark as failed_hie and alert IT + compliance.
  • Negative ACKs (AE/AR) logged with reason; no auto-retry unless error is transient (e.g., AR due to temporary validation service outage).
  • KPI “NABIDH/Malaffi Dispensing Submission Rate” computed from integration_message_log.

Retry and Recovery

Retry Strategy

Failure Type Retry Interval Max Attempts Backoff Final Action
MLLP connection timeout 5m, 5m, 5m, 5m, 5m, 5m, 5m, 5m, 5m, 5m, 5m, 5m 12 (1 hour) Fixed 5-min interval Switch to hourly retry for 24 hours
Hourly retry (post-1-hour failure) 1h intervals 24 Fixed 1-hour interval Mark as failed_hie; alert IT + compliance team
HL7 negative ACK (AE) — transient 5m, 10m, 15m 3 Linear Move to DLQ; manual review
HL7 negative ACK (AR) — permanent rejection No auto-retry 0 N/A Log rejection reason; manual correction required
TLS/certificate error No auto-retry 0 N/A Alert IT security; certificate renewal required

Dead Letter Queue

Column Value
source_system PIS
target_system NABIDH
message_type HL7 pharmacy dispensing message (NABIDH profile)
failure_reason Connection timeout, negative ACK code/reason, TLS error
raw_payload Full HL7 message
nabidh_submission_id NABIDH-assigned submission ID (if received before failure)

DLQ review cadence: every 2 hours. Compliance team notified if any messages remain in DLQ > 24 hours (regulatory SLA risk).

Idempotency

  • Deduplication key = [dispensing_id]_[message_type]_[event_datetime]. NABIDH gateway processes each unique dispensing event once; duplicate submissions return an ACK with duplicate indicator.
  • Resubmissions after correction use a new MSH-10 (message control ID) but retain the original dispensing_id for NABIDH to match and update.

Reconciliation

  • Daily: Compare pharmacy_dispensing records for the day against integration_message_log entries with target_system = NABIDH and status = acknowledged. Any dispensing records without a corresponding acknowledged NABIDH submission are requeued.
  • Weekly: NABIDH submission rate KPI reviewed by compliance team; target > 99% within 24 hours.
  • Post-outage: Bulk resubmission of all pending_hie and failed_hie messages in chronological order with rate limiting to avoid overwhelming NABIDH gateway.

INT-PIS-006: Malaffi (Abu Dhabi HIE)

Business Context

Similar to NABIDH but for DOH Abu Dhabi’s Malaffi HIE, with DOH-specific profiles and facility/provider codes.

What flows

  • Medication dispensing events and medication list for Abu Dhabi encounters.

When

  • On each dispense in an Abu Dhabi DOH-licensed facility.

Why

  • DOH Malaffi participation requirement; supports cross-facility care.

How often

  • Near real-time.

Error impact

  • Same as NABIDH; monitored jointly via the shared KPI.

HL7 v2.5.1 Technical Detail (Malaffi Profile)

Message Type: RDE^O11 or Malaffi-specific pharmacy profile.

Sample Message (PIS → Malaffi)

HL7 v2
MSH|^~\&|PIS|ABUDHABIHOSP|MALAFFI|DOH|20260207114500+0400||RDE^O11|MALAFFI20260207114500001|P|2.5.1|||AL|NE||UTF-8
PID|1||2026012345^^^ABUDHABIHOSP^MR~784-1990-7654321-3^^^AE^EID||AL-NAHYAN^FATIMA^MOHAMMED||19900320|F|||PO BOX 67890^^ABU DHABI^^00000^AE||+971502223344
PV1|1|O|OPD^PHARM^01^ABUDHABIHOSP||||OMAR^KHALID^Y^^^DR|||OPD||||||||ENC2026020700999
ORC|RE|ORD-20260207-001234^HIS_CPOE|ORD-20260207-001234^PIS||CM|||^^^20260207114000+0400^^R|20260207114000+0400|||ALI^FATIMA^OMAR^^^PHARM^RPh
RXE|1|20|mg^milligram^UCUM|617314^Omeprazole 20 MG Delayed Release Capsule^RXNORM|PO^Oral^HL70162|QD^Once daily^HL70335|||30|CAP^Capsule^UCUM|20260207114000+0400|||A|N|||K21.9^Gastro-oesophageal reflux disease^ICD10AM
RXD|1|20260207114000+0400|617314^Omeprazole 20 MG Delayed Release Capsule^RXNORM|30|CAP^Capsule^UCUM||TECH-002^YOUSEF^ALI^^^TECH||LOT67890|20280131|ABUDHABIHOSP^Main Pharmacy^ABUDHABIHOSP

Malaffi Requirements (Conceptual)

  • DOH facility and provider codes in MSH-4, PV1-7.
  • ADHICS-compliant logging and encryption.
  • mTLS with DOH-issued certificates; IP whitelisting.

Error handling mirrors NABIDH.

Retry and Recovery

Retry Strategy

Mirrors INT-PIS-005 (NABIDH) with Malaffi-specific parameters:

Failure Type Retry Interval Max Attempts Backoff Final Action
MLLP connection timeout 5m intervals 12 (1 hour) Fixed 5-min interval Switch to hourly retry for 24 hours
Hourly retry (post-1-hour failure) 1h intervals 24 Fixed 1-hour interval Mark as failed_hie; alert IT + compliance team
HL7 negative ACK (AE) — transient 5m, 10m, 15m 3 Linear Move to DLQ; manual review
HL7 negative ACK (AR) — permanent rejection No auto-retry 0 N/A Log rejection reason; manual correction required
TLS/certificate error (DOH-issued cert) No auto-retry 0 N/A Alert IT security; coordinate with DOH for certificate renewal

Dead Letter Queue

Column Value
source_system PIS
target_system MALAFFI
message_type HL7 pharmacy dispensing message (Malaffi profile)
failure_reason Connection timeout, negative ACK code/reason, TLS/cert error
raw_payload Full HL7 message

DLQ review cadence: every 2 hours. Compliance team notified if messages remain in DLQ > 24 hours. All DLQ operations logged per ADHICS requirements.

Idempotency

  • Deduplication key = [dispensing_id]_[message_type]_[event_datetime]. Malaffi gateway deduplicates on the same basis as NABIDH.
  • DOH facility code and provider code in MSH-4 and PV1-7 must match registered values; mismatches cause AR rejection (not retryable without correction).

Reconciliation

  • Daily: Compare pharmacy_dispensing records against integration_message_log entries with target_system = MALAFFI and status = acknowledged. Requeue any unsubmitted records.
  • Weekly: Malaffi submission rate KPI reviewed by compliance team; target > 99% within 24 hours.
  • Post-outage: Bulk resubmission with rate limiting; all replay operations ADHICS-logged (user, timestamp, reason, message count).

INT-PIS-007: UAE MOH (Controlled Substances)

Business Context

What flows

  • Monthly batch reports of all controlled substance transactions (dispense, return, waste, adjustment) with chain-of-custody.
  • Event-driven discrepancy reports (loss, suspected diversion).

When

  • Monthly, on a configured schedule (e.g., 3rd of month for prior month).
  • Immediately when a discrepancy is finalized in controlled_substance_log.

Why

  • Compliance with UAE MOH controlled substance regulations (Federal Law No. 14 of 1995 and amendments).
  • Supports audits and investigations.

How often

  • Monthly batch + low-volume event-driven.

Error impact

  • Failed submissions may put facility at regulatory risk; must be detected and corrected before MOH deadlines.

Technical Detail (File-Based / Portal)

Batch File Content (CSV Example)

Each row corresponds to a controlled substance transaction.

Text
log_id,facility_code,drug_rxnorm,drug_name,controlled_schedule,transaction_type,quantity,balance_after,from_user,to_user,witness_id,patient_mrn,patient_eid,waste_amount,location,transaction_datetime,discrepancy_flag,discrepancy_reason
CS-202602-000001,DH-DUBAIHOSP,865098,Tramadol 50 MG Oral Capsule,III,DISPENSE,10,90,PHARM-VAULT,NURSE-001,NURSE-002,2026009876,784-1985-1234567-1,0,4B-412,2026-02-01T10:15:00+04:00,N,
CS-202602-000250,DH-DUBAIHOSP,865098,Tramadol 50 MG Oral Capsule,III,WASTE,2,88,NURSE-001,PHARM-VAULT,NURSE-003,2026009876,784-1985-1234567-1,2,4B-412,2026-02-05T09:00:00+04:00,N,
CS-202602-000400,DH-DUBAIHOSP,865098,Tramadol 50 MG Oral Capsule,III,ADJUSTMENT,-5,83,PHARM-VAULT,,SUP-001,,,0,VAULT-01,2026-02-10T18:30:00+04:00,Y,Stock count discrepancy

Mapping

CSV Column PIS Table.Column
log_id controlled_substance_log.log_id
drug_rxnorm controlled_substance_log.drug_code_rxnorm
controlled_schedule controlled_substance_log.controlled_schedule
transaction_type controlled_substance_log.transaction_type
quantity controlled_substance_log.quantity
balance_after controlled_substance_log.balance_after
from_user controlled_substance_log.from_user
to_user controlled_substance_log.to_user
witness_id controlled_substance_log.witness_id
patient_mrn/patient_eid controlled_substance_log.patient_id (via patient master)
waste_amount controlled_substance_log.waste_amount
location controlled_substance_log.location
transaction_datetime controlled_substance_log.transaction_datetime
discrepancy_flag derived from transaction_type and reconciliation logic

Files are transferred via SFTP over VPN to MOH or uploaded via MOH portal; exact format will follow MOH specification.


Error Handling (INT-PIS-007)

  • Batch generation failures logged and alerted to pharmacy supervisor and compliance.
  • SFTP transfer failures retried every 30 minutes until success or until MOH deadline minus 24 hours, then escalated.
  • Portal upload failures require manual retry; system logs export file hash and timestamp for audit.
  • Discrepancy events that fail to send are queued and retried every 10 minutes; if still failing after 2 hours, on-call pharmacist notified.

Retry and Recovery

Retry Strategy

Failure Type Retry Interval Max Attempts Backoff Final Action
SFTP connection failure (monthly batch) 30m, 30m, 30m, 30m 4 (2 hours) Fixed 30-min interval Alert pharmacy supervisor + compliance; switch to manual MOH portal upload
SFTP authentication failure No auto-retry 0 N/A Alert IT security; key/credential renewal required
SFTP transfer interrupted (partial upload) Restart from beginning (new SFTP session) 3 15m intervals Alert IT; manual upload via MOH portal
MOH portal upload failure Manual retry by pharmacist N/A N/A Log attempt; escalate to compliance if deadline approaching
Discrepancy event push failure 10m intervals 12 (2 hours) Fixed 10-min interval Alert on-call pharmacist + pharmacy director; log for manual follow-up
Batch report generation failure Immediate re-run 2 5m interval Alert pharmacy supervisor; manual data extraction if system issue persists

Dead Letter Queue

Column Value
source_system PIS
target_system MOH_CONTROLLED
message_type monthly_batch_report or discrepancy_event
failure_reason SFTP error, generation failure, portal upload error
raw_payload Report file content (CSV/XML) or discrepancy event data
file_hash SHA-256 hash of the report file for integrity verification

DLQ review cadence: immediately for discrepancy events; daily for batch reports. Compliance team notified of any unresolved items.

Idempotency

  • Monthly batch reports: Each report is identified by [report_period]_[facility_id]_[generation_datetime]. Resubmission of the same report period replaces the prior submission at the MOH level.
  • Discrepancy events: Deduplication key = [discrepancy_id]_[event_type]_[event_datetime]. MOH system accepts updates to existing discrepancy IDs.
  • File hash (SHA-256) is computed before transmission and stored in integration_message_log; retransmitted files must match the original hash.

Reconciliation

  • Monthly: After successful batch transmission, PIS compares the count of controlled substance transactions in controlled_substance_log for the reporting period against the row count in the transmitted CSV/XML file. Any mismatch triggers a re-generation and resubmission.
  • Post-failure: If SFTP fails and manual portal upload is used, pharmacist uploads the system-generated file (same hash) and logs the manual submission with timestamp and confirmation number in integration_message_log.
  • Annual audit: Full year reconciliation of controlled_substance_log against MOH-acknowledged submissions; discrepancies documented and resolved before regulatory review.

INT-PIS-008: Patient Portal

Business Context

What flows

  • Patient-facing medication list (current and recent).
  • Refill status and eligibility for outpatient prescriptions.
  • Patient-friendly instructions (English/Arabic).

When

  • On-demand when patient opens medication section in portal.
  • Event-driven updates when a new dispense occurs or refill becomes available.

Why

  • Supports patient engagement, adherence, and PDPL-compliant access to personal data.
  • Reduces calls to pharmacy for routine queries.

How often

  • On-demand + low-volume event push.

Error impact

  • If unavailable, portal should clearly indicate that medication data is temporarily unavailable; no clinical risk but impacts patient experience.

FHIR R4 Technical Detail

Portal acts as FHIR client; PIS (or EHR) exposes FHIR server.

Resources

  • MedicationRequest – prescriptions.
  • MedicationDispense – fills and refills.
  • MedicationStatement – reconciled/home meds.

Sample MedicationRequest for Portal

JSON
{
  "resourceType": "MedicationRequest",
  "id": "RX-20260207-000999",
  "status": "active",
  "intent": "order",
  "category": [
    {
      "coding": [
        {
          "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-category",
          "code": "outpatient"
        }
      ]
    }
  ],
  "medicationCodeableConcept": {
    "coding": [
      {
        "system": "http://www.nlm.nih.gov/research/umls/rxnorm",
        "code": "617314",
        "display": "Omeprazole 20 MG Delayed Release Capsule"
      }
    ],
    "text": "Omeprazole 20mg Capsule"
  },
  "subject": {
    "reference": "Patient/2026012345",
    "display": "Fatima Mohammed Al-Nahyan"
  },
  "authoredOn": "2026-02-07",
  "dosageInstruction": [
    {
      "text": "Take one capsule by mouth once daily before breakfast",
      "patientInstruction": "تناول كبسولة واحدة عن طريق الفم مرة يومياً قبل الإفطار"
    }
  ],
  "dispenseRequest": {
    "numberOfRepeatsAllowed": 2,
    "quantity": {
      "value": 30,
      "unit": "capsule"
    },
    "expectedSupplyDuration": {
      "value": 30,
      "unit": "days",
      "system": "http://unitsofmeasure.org",
      "code": "d"
    }
  }
}

Sample MedicationDispense (Refill Status)

JSON
{
  "resourceType": "MedicationDispense",
  "id": "DISP-20260207-001000",
  "status": "completed",
  "medicationCodeableConcept": {
    "coding": [
      {
        "system": "http://www.nlm.nih.gov/research/umls/rxnorm",
        "code": "617314",
        "display": "Omeprazole 20 MG Delayed Release Capsule"
      }
    ]
  },
  "subject": {
    "reference": "Patient/2026012345"
  },
  "authorizingPrescription": [
    {
      "reference": "MedicationRequest/RX-20260207-000999"
    }
  ],
  "quantity": {
    "value": 30,
    "unit": "capsule"
  },
  "whenHandedOver": "2026-02-07T12:00:00+04:00"
}

Search Parameters (Portal → PIS/EHR)

  • GET /MedicationRequest?patient={id}&status=active
  • GET /MedicationDispense?patient={id}&_sort=-whenHandedOver
  • GET /MedicationStatement?patient={id}

Error Handling (INT-PIS-008)

  • Portal uses OAuth 2.0; if token invalid, returns 401/403; no PHI leakage.
  • If FHIR server unavailable, portal shows “Medication data temporarily unavailable” and logs error.
  • No retries on user-initiated GET; user can refresh manually.
  • Event push failures (if used) follow the standard backoff/queue pattern.

Retry and Recovery

Retry Strategy

Failure Type Retry Interval Max Attempts Backoff Final Action
Patient-initiated GET timeout (FHIR server) No auto-retry 0 N/A Portal displays "Medication data temporarily unavailable"; user can refresh
OAuth 2.0 token expired (401) Automatic token refresh via refresh_token 1 Immediate If refresh fails, redirect to login; log session expiry
OAuth 2.0 forbidden (403) No retry 0 N/A Display "Access denied"; log for security review
Event push failure (PIS → Portal notification) 30s, 1m, 2m, 5m 4 Exponential Move to DLQ; notification delivered on next patient login
FHIR server 5xx Circuit breaker: open after 5 failures in 60s; half-open after 30s Per circuit breaker N/A Portal shows cached data (if available) or graceful error

Circuit Breaker (FHIR Server Availability)

State Condition Behavior
CLOSED < 5 failures in 60-second window Normal operation; all requests pass through
OPEN >= 5 failures in 60-second window All requests immediately return cached response or "temporarily unavailable"
HALF-OPEN 30 seconds after circuit opened Allow 1 probe request; if successful, close circuit; if failed, reopen

Dead Letter Queue (Event Push Only)

Column Value
source_system PIS
target_system PATIENT_PORTAL
message_type medication_dispensed_notification, refill_available_notification
failure_reason Push timeout, portal webhook error
raw_payload Notification payload (non-PHI summary; full data retrieved on-demand)

DLQ review cadence: daily. Non-critical notifications; patients retrieve full data on next portal login regardless.

Idempotency

  • Patient GET requests are inherently idempotent (read-only FHIR queries).
  • Event push notifications: Deduplication key = [patient_id]_[event_type]_[event_datetime]. Portal discards duplicate notifications.
  • Portal caches the last-known medication list per patient; cache invalidated on new dispensing event or after 15-minute TTL.

Reconciliation

  • No formal reconciliation required for on-demand pull model — patient always receives current data from PIS on each portal query.
  • For event push notifications: weekly review of DLQ to clear stale notifications older than 7 days (events are informational; data is always available on-demand).

Authentication & Security

Across all PIS integrations:

  • mTLS Certificates
  • Used for all HL7 v2.5.1 over MLLP/TLS (CPOE, NABIDH, Malaffi, Billing).
  • Certificates issued by internal CA for intra-hospital; DHA/DOH CAs for HIE endpoints.
  • Certificate rotation and revocation managed per TDRA/NESA and ADHICS guidelines.

  • OAuth 2.0

  • Authorization Code flow for patient portal access to FHIR APIs.
  • Client Credentials flow for system-to-system FHIR calls (CPOE ↔ PIS, EHR ↔ PIS).
  • Scopes limited to least privilege (e.g., medications.read, medications.write).

  • API Keys / Internal Tokens

  • For internal REST integrations where OAuth overhead is not required; keys stored in secure vault, rotated regularly.

  • Encryption

  • In transit: TLS 1.2+ for all HTTP(S) and SFTP; MLLP wrapped in TLS.
  • At rest: database and message logs encrypted per facility policy and UAE PDPL requirements.

  • Audit & Logging

  • All integration calls logged with timestamp, user/system identity, patient_id, and outcome.
  • Logs retained per MOH/DOH/DHA and PDPL retention policies.
  • Access to logs restricted and monitored.

  • Data Minimization & PDPL

  • Only necessary fields included in external integrations (NABIDH, Malaffi, MOH).
  • Patient identifiers limited to MRN + Emirates ID where required by regulation.
  • Cross-border transfers (if any) require explicit PDPL-compliant assessment and approvals.

This specification provides the developer-ready integration details for the Pharmacy Information System within the UAE regulatory context.

content/clinical/pis/05-integrations.md Generated 2026-02-20 22:54