Pharmacy Information System Data Specifications

Pharmacy Information System Data Specifications

Shared Entity References

This module references the following shared entities defined in their owning modules. PIS does not redefine these tables — it uses foreign-key references only.

Shared Entity Owning Module Table(s) FK Used Here
Patients ehr-patient-mgmt patients, patient_demographics, patient_identifiers patients.patient_id
Providers ehr-patient-mgmt providers, provider_credentials providers.provider_id
Encounters scheduling encounters, encounter_details encounters.encounter_id
Users & Auth ehr-patient-mgmt users, roles, permissions users.user_id
Facilities ehr-patient-mgmt facilities, departments, locations facilities.facility_id, departments.department_id, locations.location_id
Payers policy-contract-mgmt payers, insurance_plans, contracts payers.payer_id
Patient Allergies ehr-patient-mgmt patient_allergies patient_allergies.allergy_id

Entity Relationship Diagram

erDiagram patients ||--o{ pharmacy_orders : "has" encounters ||--o{ pharmacy_orders : "context for" providers ||--o{ pharmacy_orders : "ordered by" facilities ||--o{ pharmacy_orders : "at" users ||--o{ pharmacy_orders : "verified by" pharmacy_orders ||--o{ pharmacy_dispensing : "fulfilled by" pharmacy_orders ||--o{ medication_administration : "administered as" pharmacy_orders ||--o{ iv_admixture_orders : "has admixture" pharmacy_orders ||--o{ pharmacy_interventions : "has" pharmacy_orders ||--o{ antimicrobial_stewardship_reviews : "reviewed in" pharmacy_orders ||--o{ medication_reconciliation : "referenced by" formulary ||--o{ formulary_items : "contains" formulary_items ||--o{ pharmacy_orders : "constrains" formulary_items ||--o{ pharmacy_inventory : "stocks" formulary_items ||--o{ iv_admixture_orders : "uses" pharmacy_inventory ||--o{ inventory_transactions : "tracked by" pharmacy_inventory ||--o{ controlled_substance_log : "controlled in" patients ||--o{ medication_administration : "receives" encounters ||--o{ medication_administration : "during" users ||--o{ medication_administration : "administered by" patients ||--o{ medication_reconciliation : "has" encounters ||--o{ medication_reconciliation : "at transition" pharmacy_orders { bigint order_id PK bigint patient_id FK bigint encounter_id FK bigint ordering_provider_id FK bigint facility_id FK bigint verified_by FK } pharmacy_dispensing { bigint dispensing_id PK bigint order_id FK bigint patient_id FK bigint dispensed_by FK bigint verified_by FK bigint dispensing_location_id FK } medication_administration { bigint admin_id PK bigint order_id FK bigint patient_id FK bigint encounter_id FK bigint administered_by FK bigint witness_id FK } formulary { bigint formulary_id PK bigint facility_id FK bigint approved_by FK } formulary_items { bigint item_id PK bigint formulary_id FK } drug_interactions { bigint interaction_id PK } pharmacy_inventory { bigint inventory_id PK bigint facility_id FK bigint location_id FK } inventory_transactions { bigint transaction_id PK bigint inventory_id FK bigint from_location_id FK bigint to_location_id FK bigint performed_by FK } controlled_substance_log { bigint log_id PK bigint from_user_id FK bigint to_user_id FK bigint witness_id FK bigint patient_id FK bigint waste_witnessed_by FK bigint location_id FK } iv_admixture_orders { bigint admixture_id PK bigint order_id FK bigint prepared_by FK bigint verified_by FK } pharmacy_interventions { bigint intervention_id PK bigint order_id FK bigint pharmacist_id FK } medication_reconciliation { bigint recon_id PK bigint patient_id FK bigint encounter_id FK bigint new_order_id FK bigint reconciled_by FK } antimicrobial_stewardship_reviews { bigint review_id PK bigint order_id FK bigint patient_id FK bigint reviewed_by FK }

Table Definitions

Conventions:
- All timestamps are in TIMESTAMP WITH TIME ZONE unless noted.
- All PKs use GENERATED ALWAYS AS IDENTITY.
- DB syntax is PostgreSQL-compatible.
- UAE-specific: controlled substance fields aligned with UAE MOH schedules; no US-specific schedules.


1. pharmacy_orders

Purpose
Stores all medication orders as received and managed by the Pharmacy Information System, including inpatient, outpatient, and discharge prescriptions. Supports clinical decision support, formulary checks, and UAE MOH controlled substance compliance.

Field Specifications

Field Type Nullable Default Constraint Description
order_id BIGINT NO IDENTITY PK Internal pharmacy order identifier
external_order_id VARCHAR(50) YES NULL Unique per source ID from CPOE/LIS if applicable
order_source_system VARCHAR(30) NO 'CPOE' IN ('CPOE','OPD','ED','Manual') Source of order
patient_id BIGINT NO FK → patients.patient_id Patient receiving medication
encounter_id BIGINT YES NULL FK → encounters.encounter_id Encounter context (nullable for pure outpatient retail)
ordering_provider_id BIGINT NO FK → providers.provider_id Prescribing clinician
facility_id BIGINT NO FK → facilities.facility_id Ordering facility
department_id BIGINT YES NULL FK → departments.department_id Ordering department/ward
order_type VARCHAR(20) NO 'inpatient' IN ('inpatient','outpatient','discharge') Context of order
order_status VARCHAR(20) NO 'pending_verification' IN ('pending_verification','verified','rejected','on_hold','discontinued','completed','cancelled') Pharmacy order status
priority VARCHAR(10) NO 'routine' IN ('stat','urgent','first_dose','routine') Priority for verification/dispensing
drug_code_rxnorm VARCHAR(20) NO RxNorm code Ordered drug code
drug_name VARCHAR(255) NO Display name (usually generic + strength + form)
dose NUMERIC(12,3) NO > 0 Dose amount per administration
dose_unit VARCHAR(20) NO UCUM code Dose unit (e.g., mg, mL)
route VARCHAR(30) NO From Administration Routes MD Route of administration
frequency VARCHAR(30) NO From Medication Frequencies MD Frequency code (e.g., BID, Q8H)
duration_days INT YES NULL > 0 if not null Planned duration in days
prn_flag BOOLEAN NO FALSE As-needed medication flag
prn_indication VARCHAR(255) YES NULL Required if prn_flag = TRUE Reason for PRN use
indication_icd10 VARCHAR(10) YES NULL ICD-10-AM format Diagnosis code for indication
indication_text VARCHAR(500) YES NULL Free-text indication
weight_kg_at_order NUMERIC(6,2) YES NULL ≥ 0 Patient weight used for dosing
bsa_m2_at_order NUMERIC(5,3) YES NULL ≥ 0 Body surface area if used
renal_function_json JSONB YES NULL Snapshot of creatinine clearance/eGFR used for dosing
order_datetime TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP When order was received in PIS
verified_by BIGINT YES NULL FK → users.user_id Pharmacist who verified
verified_datetime TIMESTAMP WITH TIME ZONE YES NULL order_datetime When verification completed
verification_outcome VARCHAR(20) YES NULL IN ('approved','modified','rejected') Outcome of verification
verification_notes TEXT YES NULL Rationale for modifications/rejections
formulary_item_id BIGINT YES NULL FK → formulary_items.item_id Linked formulary item if applicable
non_formulary_reason VARCHAR(255) YES NULL Reason for non-formulary use
insurance_payer_id BIGINT YES NULL FK → payers.payer_id Payer at time of order
prior_auth_required BOOLEAN NO FALSE From formulary/plan rules
prior_auth_status VARCHAR(20) YES NULL IN ('not_required','pending','approved','denied') PA status
is_controlled BOOLEAN NO FALSE UAE MOH controlled substance flag
controlled_schedule VARCHAR(20) YES NULL UAE MOH schedule (e.g., 'CDa-Narcotic','CDa-Psychotropic','CDb') UAE controlled classification
uep_required BOOLEAN NO FALSE Requires MOH electronic prescription (UEP)
uep_prescription_id VARCHAR(50) YES NULL ID returned by MOH UEP system
max_daily_dose NUMERIC(12,3) YES NULL ≥ 0 Calculated max daily dose for safety
cds_alerts_json JSONB YES NULL Snapshot of CDS alerts at verification
override_flags_json JSONB YES NULL Documented overrides (allergy, interaction, etc.)
created_by BIGINT NO FK → users.user_id User who created record
updated_by BIGINT YES NULL FK → users.user_id Last user to update
created_at TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP Creation timestamp
updated_at TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP ON UPDATE Last update timestamp

SQL DDL

SQL
CREATE TABLE pharmacy_orders (
    order_id                BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    external_order_id       VARCHAR(50),
    order_source_system     VARCHAR(30) NOT NULL DEFAULT 'CPOE',
    patient_id              BIGINT NOT NULL,
    encounter_id            BIGINT,
    ordering_provider_id    BIGINT NOT NULL,
    facility_id             BIGINT NOT NULL,
    department_id           BIGINT,
    order_type              VARCHAR(20) NOT NULL DEFAULT 'inpatient',
    order_status            VARCHAR(20) NOT NULL DEFAULT 'pending_verification',
    priority                VARCHAR(10) NOT NULL DEFAULT 'routine',
    drug_code_rxnorm        VARCHAR(20) NOT NULL,
    drug_name               VARCHAR(255) NOT NULL,
    dose                    NUMERIC(12,3) NOT NULL,
    dose_unit               VARCHAR(20) NOT NULL,
    route                   VARCHAR(30) NOT NULL,
    frequency               VARCHAR(30) NOT NULL,
    duration_days           INT,
    prn_flag                BOOLEAN NOT NULL DEFAULT FALSE,
    prn_indication          VARCHAR(255),
    indication_icd10        VARCHAR(10),
    indication_text         VARCHAR(500),
    weight_kg_at_order      NUMERIC(6,2),
    bsa_m2_at_order         NUMERIC(5,3),
    renal_function_json     JSONB,
    order_datetime          TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
    verified_by             BIGINT,
    verified_datetime       TIMESTAMP WITH TIME ZONE,
    verification_outcome    VARCHAR(20),
    verification_notes      TEXT,
    formulary_item_id       BIGINT,
    non_formulary_reason    VARCHAR(255),
    insurance_payer_id      BIGINT,
    prior_auth_required     BOOLEAN NOT NULL DEFAULT FALSE,
    prior_auth_status       VARCHAR(20),
    is_controlled           BOOLEAN NOT NULL DEFAULT FALSE,
    controlled_schedule     VARCHAR(20),
    uep_required            BOOLEAN NOT NULL DEFAULT FALSE,
    uep_prescription_id     VARCHAR(50),
    max_daily_dose          NUMERIC(12,3),
    cds_alerts_json         JSONB,
    override_flags_json     JSONB,
    created_by              BIGINT NOT NULL,
    updated_by              BIGINT,
    created_at              TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at              TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE pharmacy_orders
    ADD CONSTRAINT fk_pharm_orders_patient
        FOREIGN KEY (patient_id) REFERENCES patients(patient_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT fk_pharm_orders_encounter
        FOREIGN KEY (encounter_id) REFERENCES encounters(encounter_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT fk_pharm_orders_provider
        FOREIGN KEY (ordering_provider_id) REFERENCES providers(provider_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT fk_pharm_orders_facility
        FOREIGN KEY (facility_id) REFERENCES facilities(facility_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT fk_pharm_orders_department
        FOREIGN KEY (department_id) REFERENCES departments(department_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT fk_pharm_orders_formulary_item
        FOREIGN KEY (formulary_item_id) REFERENCES formulary_items(item_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT fk_pharm_orders_payer
        FOREIGN KEY (insurance_payer_id) REFERENCES payers(payer_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT fk_pharm_orders_verified_by
        FOREIGN KEY (verified_by) REFERENCES users(user_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT fk_pharm_orders_created_by
        FOREIGN KEY (created_by) REFERENCES users(user_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT fk_pharm_orders_updated_by
        FOREIGN KEY (updated_by) REFERENCES users(user_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT chk_pharm_orders_order_type
        CHECK (order_type IN ('inpatient','outpatient','discharge')),
    ADD CONSTRAINT chk_pharm_orders_status
        CHECK (order_status IN ('pending_verification','verified','rejected','on_hold','discontinued','completed','cancelled')),
    ADD CONSTRAINT chk_pharm_orders_priority
        CHECK (priority IN ('stat','urgent','first_dose','routine')),
    ADD CONSTRAINT chk_pharm_orders_dose_positive
        CHECK (dose > 0),
    ADD CONSTRAINT chk_pharm_orders_duration_positive
        CHECK (duration_days IS NULL OR duration_days > 0),
    ADD CONSTRAINT chk_pharm_orders_prn_indication
        CHECK (prn_flag = FALSE OR prn_indication IS NOT NULL),
    ADD CONSTRAINT chk_pharm_orders_verification_outcome
        CHECK (verification_outcome IS NULL OR verification_outcome IN ('approved','modified','rejected')),
    ADD CONSTRAINT chk_pharm_orders_prior_auth_status
        CHECK (prior_auth_status IS NULL OR prior_auth_status IN ('not_required','pending','approved','denied')),
    ADD CONSTRAINT chk_pharm_orders_controlled_schedule
        CHECK (is_controlled = FALSE OR controlled_schedule IS NOT NULL);

CREATE INDEX idx_pharm_orders_patient ON pharmacy_orders(patient_id);
CREATE INDEX idx_pharm_orders_encounter ON pharmacy_orders(encounter_id);
CREATE INDEX idx_pharm_orders_status ON pharmacy_orders(order_status);
CREATE INDEX idx_pharm_orders_priority ON pharmacy_orders(priority);
CREATE INDEX idx_pharm_orders_verified_dt ON pharmacy_orders(verified_datetime);
CREATE INDEX idx_pharm_orders_drug ON pharmacy_orders(drug_code_rxnorm);
CREATE INDEX idx_pharm_orders_controlled ON pharmacy_orders(is_controlled) WHERE is_controlled = TRUE;
CREATE INDEX idx_pharm_orders_facility_status ON pharmacy_orders(facility_id, order_status);

Terminology Bindings

Field Terminology Example Value
drug_code_rxnorm RxNorm 1049630 (paracetamol 500 mg tablet)
dose_unit UCUM mg, mL, unit
route SNOMED CT / HL7 Route Codes PO (oral), IV, IM
frequency Facility Medication Frequencies MD BID, Q8H, PRN
indication_icd10 ICD-10-AM E11.9
controlled_schedule UAE MOH Controlled Substance Schedules MD CDa-Narcotic

FHIR Resource Mapping

Table Field FHIR Resource FHIR Path
order_id MedicationRequest MedicationRequest.id
patient_id MedicationRequest MedicationRequest.subject.reference (Patient/{id})
encounter_id MedicationRequest MedicationRequest.encounter.reference
ordering_provider_id MedicationRequest MedicationRequest.requester.reference (Practitioner/{id})
order_type MedicationRequest MedicationRequest.category (inpatient/outpatient)
order_status MedicationRequest MedicationRequest.status
priority MedicationRequest MedicationRequest.priority
drug_code_rxnorm MedicationRequest MedicationRequest.medicationCodeableConcept.coding[RxNorm].code
drug_name MedicationRequest MedicationRequest.medicationCodeableConcept.text
dose, dose_unit MedicationRequest MedicationRequest.dosageInstruction.doseAndRate.doseQuantity
route MedicationRequest MedicationRequest.dosageInstruction.route
frequency, duration_days MedicationRequest MedicationRequest.dosageInstruction.timing
prn_flag, prn_indication MedicationRequest MedicationRequest.dosageInstruction.asNeeded[x], .patientInstruction
indication_icd10, indication_text MedicationRequest MedicationRequest.reasonCode
order_datetime MedicationRequest MedicationRequest.authoredOn
verified_by, verified_datetime MedicationRequest Extension: pharmacist verification details
is_controlled, controlled_schedule, uep_prescription_id MedicationRequest UAE-specific extensions for controlled substances

2. pharmacy_dispensing

Purpose
Captures each dispensing event (fill) associated with a pharmacy order, including inpatient unit-dose and outpatient prescription fills. Supports billing, inventory decrement, and HIE reporting (NABIDH/Malaffi).

Field Specifications

Field Type Nullable Default Constraint Description
dispensing_id BIGINT NO IDENTITY PK Unique dispensing event
order_id BIGINT NO FK → pharmacy_orders.order_id Related pharmacy order
patient_id BIGINT NO FK → patients.patient_id Patient
encounter_id BIGINT YES NULL FK → encounters.encounter_id Encounter if applicable
facility_id BIGINT NO FK → facilities.facility_id Dispensing facility
dispensing_location_id BIGINT YES NULL FK → locations.location_id Pharmacy/ADC location
drug_code_rxnorm VARCHAR(20) NO RxNorm Dispensed drug code
ndc_code VARCHAR(20) YES NULL Local pack code / GTIN if used
quantity_dispensed NUMERIC(12,3) NO > 0 Quantity dispensed
quantity_unit VARCHAR(20) NO 'unit' UCUM Unit for quantity (e.g., tablet, mL)
days_supply INT YES NULL > 0 For outpatient fills
lot_number VARCHAR(50) YES NULL Batch/lot identifier
expiry_date DATE YES NULL Expiry of dispensed lot
dispensed_by BIGINT NO FK → users.user_id Technician/pharmacist who dispensed
verified_by BIGINT YES NULL FK → users.user_id Pharmacist final check
dispensing_datetime TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP When dispensed
label_printed BOOLEAN NO FALSE Label printed flag
label_language VARCHAR(10) YES NULL IN ('en','ar','bilingual') Label language
billing_status VARCHAR(20) NO 'pending' IN ('pending','sent','accepted','rejected','not_billable') Billing integration status
billing_reference VARCHAR(50) YES NULL Reference to billing/DFT message
is_controlled BOOLEAN NO FALSE Copied from order/formulary
controlled_log_id BIGINT YES NULL FK → controlled_substance_log.log_id Linked controlled log entry
hie_submission_status VARCHAR(20) NO 'pending' IN ('pending','accepted','rejected','error','not_required') NABIDH/Malaffi status
hie_last_attempt TIMESTAMP WITH TIME ZONE YES NULL Last HIE submission attempt
hie_error_message TEXT YES NULL Last HIE error details
created_at TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP Creation timestamp
updated_at TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP ON UPDATE Last update timestamp

SQL DDL

SQL
CREATE TABLE pharmacy_dispensing (
    dispensing_id           BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    order_id                BIGINT NOT NULL,
    patient_id              BIGINT NOT NULL,
    encounter_id            BIGINT,
    facility_id             BIGINT NOT NULL,
    dispensing_location_id  BIGINT,
    drug_code_rxnorm        VARCHAR(20) NOT NULL,
    ndc_code                VARCHAR(20),
    quantity_dispensed      NUMERIC(12,3) NOT NULL,
    quantity_unit           VARCHAR(20) NOT NULL DEFAULT 'unit',
    days_supply             INT,
    lot_number              VARCHAR(50),
    expiry_date             DATE,
    dispensed_by            BIGINT NOT NULL,
    verified_by             BIGINT,
    dispensing_datetime     TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
    label_printed           BOOLEAN NOT NULL DEFAULT FALSE,
    label_language          VARCHAR(10),
    billing_status          VARCHAR(20) NOT NULL DEFAULT 'pending',
    billing_reference       VARCHAR(50),
    is_controlled           BOOLEAN NOT NULL DEFAULT FALSE,
    controlled_log_id       BIGINT,
    hie_submission_status   VARCHAR(20) NOT NULL DEFAULT 'pending',
    hie_last_attempt        TIMESTAMP WITH TIME ZONE,
    hie_error_message       TEXT,
    created_at              TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at              TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE pharmacy_dispensing
    ADD CONSTRAINT fk_disp_order
        FOREIGN KEY (order_id) REFERENCES pharmacy_orders(order_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT fk_disp_patient
        FOREIGN KEY (patient_id) REFERENCES patients(patient_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT fk_disp_encounter
        FOREIGN KEY (encounter_id) REFERENCES encounters(encounter_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT fk_disp_facility
        FOREIGN KEY (facility_id) REFERENCES facilities(facility_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT fk_disp_location
        FOREIGN KEY (dispensing_location_id) REFERENCES locations(location_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT fk_disp_dispensed_by
        FOREIGN KEY (dispensed_by) REFERENCES users(user_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT fk_disp_verified_by
        FOREIGN KEY (verified_by) REFERENCES users(user_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT fk_disp_controlled_log
        FOREIGN KEY (controlled_log_id) REFERENCES controlled_substance_log(log_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT chk_disp_quantity_positive
        CHECK (quantity_dispensed > 0),
    ADD CONSTRAINT chk_disp_days_supply
        CHECK (days_supply IS NULL OR days_supply > 0),
    ADD CONSTRAINT chk_disp_billing_status
        CHECK (billing_status IN ('pending','sent','accepted','rejected','not_billable')),
    ADD CONSTRAINT chk_disp_hie_status
        CHECK (hie_submission_status IN ('pending','accepted','rejected','error','not_required')),
    ADD CONSTRAINT chk_disp_label_language
        CHECK (label_language IS NULL OR label_language IN ('en','ar','bilingual'));

CREATE INDEX idx_disp_order ON pharmacy_dispensing(order_id);
CREATE INDEX idx_disp_patient ON pharmacy_dispensing(patient_id);
CREATE INDEX idx_disp_datetime ON pharmacy_dispensing(dispensing_datetime);
CREATE INDEX idx_disp_billing_status ON pharmacy_dispensing(billing_status);
CREATE INDEX idx_disp_hie_status ON pharmacy_dispensing(hie_submission_status);
CREATE INDEX idx_disp_facility_datetime ON pharmacy_dispensing(facility_id, dispensing_datetime);

Terminology Bindings

Field Terminology Example Value
drug_code_rxnorm RxNorm 1049630
quantity_unit UCUM / local tablet, mL

FHIR Resource Mapping

Table Field FHIR Resource FHIR Path
dispensing_id MedicationDispense MedicationDispense.id
order_id MedicationDispense MedicationDispense.authorizingPrescription.reference
patient_id MedicationDispense MedicationDispense.subject.reference
encounter_id MedicationDispense MedicationDispense.context.reference
drug_code_rxnorm MedicationDispense MedicationDispense.medicationCodeableConcept.coding[RxNorm].code
quantity_dispensed, quantity_unit MedicationDispense MedicationDispense.quantity
days_supply MedicationDispense MedicationDispense.daysSupply
dispensing_datetime MedicationDispense MedicationDispense.whenHandedOver
dispensed_by MedicationDispense MedicationDispense.performer.actor
lot_number, expiry_date MedicationDispense MedicationDispense.batch
billing_status MedicationDispense Extension for billing status
hie_submission_status MedicationDispense Extension for HIE submission tracking

3. medication_administration

Purpose
Represents the electronic Medication Administration Record (eMAR) for inpatient and certain outpatient administrations, including barcode verification, PRN response, and refusal/hold reasons.

Field Specifications

Field Type Nullable Default Constraint Description
admin_id BIGINT NO IDENTITY PK Unique administration event
order_id BIGINT NO FK → pharmacy_orders.order_id Related order
dispensing_id BIGINT YES NULL FK → pharmacy_dispensing.dispensing_id Source dispensing event
patient_id BIGINT NO FK → patients.patient_id Patient
encounter_id BIGINT NO FK → encounters.encounter_id Encounter
facility_id BIGINT NO FK → facilities.facility_id Facility
location_id BIGINT YES NULL FK → locations.location_id Bed/ward at time of admin
drug_code_rxnorm VARCHAR(20) NO RxNorm Drug administered
scheduled_datetime TIMESTAMP WITH TIME ZONE NO Scheduled time
actual_datetime TIMESTAMP WITH TIME ZONE YES NULL Actual administration time
dose_given NUMERIC(12,3) YES NULL ≥ 0 Dose actually given
dose_unit VARCHAR(20) YES NULL UCUM Unit of dose given
route VARCHAR(30) YES NULL Route used
site VARCHAR(50) YES NULL SNOMED CT body site if used Site for injections, etc.
status VARCHAR(20) NO 'scheduled' IN ('scheduled','in_progress','completed','held','refused','omitted','cancelled') Administration status
hold_reason VARCHAR(255) YES NULL Required if status='held' Reason for hold
refuse_reason VARCHAR(255) YES NULL Required if status='refused' Reason for refusal
omission_reason VARCHAR(255) YES NULL Required if status='omitted' Reason for omission
administered_by BIGINT YES NULL FK → users.user_id Nurse administering
witness_id BIGINT YES NULL FK → users.user_id Witness for high-risk/controlled
barcode_verified BOOLEAN NO FALSE Barcode scan success
patient_barcode VARCHAR(50) YES NULL Scanned patient wristband value
medication_barcode VARCHAR(50) YES NULL Scanned medication barcode
prn_indication VARCHAR(255) YES NULL Reason for PRN dose
prn_response TEXT YES NULL Clinical response to PRN
notes TEXT YES NULL Additional nursing notes
created_at TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP Creation timestamp
updated_at TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP ON UPDATE Last update timestamp

SQL DDL

SQL
CREATE TABLE medication_administration (
    admin_id            BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    order_id            BIGINT NOT NULL,
    dispensing_id       BIGINT,
    patient_id          BIGINT NOT NULL,
    encounter_id        BIGINT NOT NULL,
    facility_id         BIGINT NOT NULL,
    location_id         BIGINT,
    drug_code_rxnorm    VARCHAR(20) NOT NULL,
    scheduled_datetime  TIMESTAMP WITH TIME ZONE NOT NULL,
    actual_datetime     TIMESTAMP WITH TIME ZONE,
    dose_given          NUMERIC(12,3),
    dose_unit           VARCHAR(20),
    route               VARCHAR(30),
    site                VARCHAR(50),
    status              VARCHAR(20) NOT NULL DEFAULT 'scheduled',
    hold_reason         VARCHAR(255),
    refuse_reason       VARCHAR(255),
    omission_reason     VARCHAR(255),
    administered_by     BIGINT,
    witness_id          BIGINT,
    barcode_verified    BOOLEAN NOT NULL DEFAULT FALSE,
    patient_barcode     VARCHAR(50),
    medication_barcode  VARCHAR(50),
    prn_indication      VARCHAR(255),
    prn_response        TEXT,
    notes               TEXT,
    created_at          TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at          TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE medication_administration
    ADD CONSTRAINT fk_medadmin_order
        FOREIGN KEY (order_id) REFERENCES pharmacy_orders(order_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT fk_medadmin_dispensing
        FOREIGN KEY (dispensing_id) REFERENCES pharmacy_dispensing(dispensing_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT fk_medadmin_patient
        FOREIGN KEY (patient_id) REFERENCES patients(patient_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT fk_medadmin_encounter
        FOREIGN KEY (encounter_id) REFERENCES encounters(encounter_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT fk_medadmin_facility
        FOREIGN KEY (facility_id) REFERENCES facilities(facility_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT fk_medadmin_location
        FOREIGN KEY (location_id) REFERENCES locations(location_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT fk_medadmin_admin_by
        FOREIGN KEY (administered_by) REFERENCES users(user_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT fk_medadmin_witness
        FOREIGN KEY (witness_id) REFERENCES users(user_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT chk_medadmin_status
        CHECK (status IN ('scheduled','in_progress','completed','held','refused','omitted','cancelled')),
    ADD CONSTRAINT chk_medadmin_dose_nonnegative
        CHECK (dose_given IS NULL OR dose_given >= 0),
    ADD CONSTRAINT chk_medadmin_hold_reason
        CHECK (status <> 'held' OR hold_reason IS NOT NULL),
    ADD CONSTRAINT chk_medadmin_refuse_reason
        CHECK (status <> 'refused' OR refuse_reason IS NOT NULL),
    ADD CONSTRAINT chk_medadmin_omission_reason
        CHECK (status <> 'omitted' OR omission_reason IS NOT NULL);

CREATE INDEX idx_medadmin_patient ON medication_administration(patient_id);
CREATE INDEX idx_medadmin_encounter ON medication_administration(encounter_id);
CREATE INDEX idx_medadmin_order ON medication_administration(order_id);
CREATE INDEX idx_medadmin_status ON medication_administration(status);
CREATE INDEX idx_medadmin_sched_dt ON medication_administration(scheduled_datetime);
CREATE INDEX idx_medadmin_barcode_verified ON medication_administration(barcode_verified);

Terminology Bindings

Field Terminology Example Value
drug_code_rxnorm RxNorm 1049630
dose_unit UCUM mg
route SNOMED CT / HL7 Route Codes IV, PO
site SNOMED CT body structure 368209003 (Left deltoid region)

FHIR Resource Mapping

Table Field FHIR Resource FHIR Path
admin_id MedicationAdministration MedicationAdministration.id
patient_id MedicationAdministration MedicationAdministration.subject.reference
encounter_id MedicationAdministration MedicationAdministration.context.reference
order_id MedicationAdministration MedicationAdministration.request.reference
drug_code_rxnorm MedicationAdministration MedicationAdministration.medicationCodeableConcept.coding[RxNorm].code
scheduled_datetime MedicationAdministration MedicationAdministration.effectivePeriod.start
actual_datetime MedicationAdministration MedicationAdministration.effectiveDateTime
dose_given, dose_unit MedicationAdministration MedicationAdministration.dosage.dose
route MedicationAdministration MedicationAdministration.dosage.route
site MedicationAdministration MedicationAdministration.dosage.site
administered_by MedicationAdministration MedicationAdministration.performer.actor
status MedicationAdministration MedicationAdministration.status
barcode_verified MedicationAdministration Extension for barcode verification result
prn_indication, prn_response MedicationAdministration MedicationAdministration.reasonCode, MedicationAdministration.note

4. formulary

Purpose
Defines facility-level formularies (e.g., main hospital, specialty hospital) and their lifecycle (active, retired). Header table for formulary items.

Field Specifications

Field Type Nullable Default Constraint Description
formulary_id BIGINT NO IDENTITY PK Formulary identifier
formulary_name VARCHAR(100) NO Unique per facility Name (e.g., "Main Hospital Adult Formulary")
facility_id BIGINT NO FK → facilities.facility_id Facility
effective_date DATE NO CURRENT_DATE Start date
end_date DATE YES NULL > effective_date End date if retired
approved_by BIGINT NO FK → users.user_id Chief pharmacist/director
status VARCHAR(20) NO 'active' IN ('draft','active','retired') Lifecycle status
notes TEXT YES NULL Additional notes
created_at TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP Creation timestamp
updated_at TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP ON UPDATE Last update timestamp

SQL DDL

SQL
CREATE TABLE formulary (
    formulary_id    BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    formulary_name  VARCHAR(100) NOT NULL,
    facility_id     BIGINT NOT NULL,
    effective_date  DATE NOT NULL DEFAULT CURRENT_DATE,
    end_date        DATE,
    approved_by     BIGINT NOT NULL,
    status          VARCHAR(20) NOT NULL DEFAULT 'active',
    notes           TEXT,
    created_at      TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at      TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT uq_formulary_name_facility UNIQUE (formulary_name, facility_id)
);

ALTER TABLE formulary
    ADD CONSTRAINT fk_formulary_facility
        FOREIGN KEY (facility_id) REFERENCES facilities(facility_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT fk_formulary_approved_by
        FOREIGN KEY (approved_by) REFERENCES users(user_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT chk_formulary_status
        CHECK (status IN ('draft','active','retired')),
    ADD CONSTRAINT chk_formulary_dates
        CHECK (end_date IS NULL OR end_date > effective_date);

CREATE INDEX idx_formulary_facility_status ON formulary(facility_id, status);

FHIR Mapping

Formulary is not a core FHIR resource; map via Medication and List:

Table Field FHIR Resource FHIR Path
formulary_id List List.id
formulary_name List List.title
facility_id Organization List.managingEntity
status List List.status
effective_date, end_date List List.date / extensions

5. formulary_items

Purpose
Defines individual medications within a formulary, including formulary status, restrictions, therapeutic class, and controlled substance schedule.

Field Specifications

Field Type Nullable Default Constraint Description
item_id BIGINT NO IDENTITY PK Formulary item
formulary_id BIGINT NO FK → formulary.formulary_id Parent formulary
drug_code_rxnorm VARCHAR(20) NO RxNorm Drug code
drug_name VARCHAR(255) NO Display name
generic_name VARCHAR(255) YES NULL Generic name
strength VARCHAR(50) YES NULL Strength (e.g., 500 mg)
dosage_form VARCHAR(50) YES NULL Tablet, injection, etc.
formulary_status VARCHAR(20) NO 'on_formulary' IN ('on_formulary','non_formulary','restricted','obsolete') Status
restriction_type VARCHAR(50) YES NULL e.g., "ID approval", "Oncology only"
therapeutic_class VARCHAR(50) YES NULL ATC code Therapeutic class
therapeutic_alternative_rxnorm VARCHAR(20) YES NULL RxNorm Suggested alternative
requires_prior_auth BOOLEAN NO FALSE Insurance PA required
is_high_alert BOOLEAN NO FALSE High-alert medication flag
is_controlled BOOLEAN NO FALSE UAE MOH controlled substance
controlled_schedule VARCHAR(20) YES NULL UAE MOH schedule Controlled classification
default_route VARCHAR(30) YES NULL Default route
default_frequency VARCHAR(30) YES NULL Default frequency
default_dose NUMERIC(12,3) YES NULL ≥ 0 Default dose
default_dose_unit VARCHAR(20) YES NULL UCUM Default dose unit
active_flag BOOLEAN NO TRUE Active in formulary
created_at TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP Creation timestamp
updated_at TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP ON UPDATE Last update timestamp

SQL DDL

SQL
CREATE TABLE formulary_items (
    item_id                       BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    formulary_id                  BIGINT NOT NULL,
    drug_code_rxnorm              VARCHAR(20) NOT NULL,
    drug_name                     VARCHAR(255) NOT NULL,
    generic_name                  VARCHAR(255),
    strength                      VARCHAR(50),
    dosage_form                   VARCHAR(50),
    formulary_status              VARCHAR(20) NOT NULL DEFAULT 'on_formulary',
    restriction_type              VARCHAR(50),
    therapeutic_class             VARCHAR(50),
    therapeutic_alternative_rxnorm VARCHAR(20),
    requires_prior_auth           BOOLEAN NOT NULL DEFAULT FALSE,
    is_high_alert                 BOOLEAN NOT NULL DEFAULT FALSE,
    is_controlled                 BOOLEAN NOT NULL DEFAULT FALSE,
    controlled_schedule           VARCHAR(20),
    default_route                 VARCHAR(30),
    default_frequency             VARCHAR(30),
    default_dose                  NUMERIC(12,3),
    default_dose_unit             VARCHAR(20),
    active_flag                   BOOLEAN NOT NULL DEFAULT TRUE,
    created_at                    TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at                    TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE formulary_items
    ADD CONSTRAINT fk_formulary_items_formulary
        FOREIGN KEY (formulary_id) REFERENCES formulary(formulary_id) ON UPDATE CASCADE ON DELETE CASCADE,
    ADD CONSTRAINT chk_formulary_items_status
        CHECK (formulary_status IN ('on_formulary','non_formulary','restricted','obsolete')),
    ADD CONSTRAINT chk_formulary_items_controlled_schedule
        CHECK (is_controlled = FALSE OR controlled_schedule IS NOT NULL);

CREATE INDEX idx_formulary_items_formulary ON formulary_items(formulary_id);
CREATE INDEX idx_formulary_items_drug ON formulary_items(drug_code_rxnorm);
CREATE INDEX idx_formulary_items_status ON formulary_items(formulary_status) WHERE active_flag = TRUE;

Terminology Bindings

Field Terminology Example Value
drug_code_rxnorm RxNorm 1049630
therapeutic_class ATC N02BE01 (paracetamol)
default_dose_unit UCUM mg
controlled_schedule UAE MOH Controlled Substance Schedules CDa-Narcotic

FHIR Mapping

Table Field FHIR Resource FHIR Path
item_id Medication Medication.id
drug_code_rxnorm Medication Medication.code.coding[RxNorm].code
drug_name Medication Medication.code.text
generic_name Medication Extension or Medication.code.text
dosage_form Medication Medication.form
strength Medication Medication.ingredient.strength (parsed)
formulary_status Medication Extension for formulary status
restriction_type Medication Extension for restriction
is_controlled, controlled_schedule Medication UAE-specific extensions

6. drug_interactions

Purpose
Knowledge base of drug–drug interactions used by CDS during order verification.

Field Specifications

Field Type Nullable Default Constraint Description
interaction_id BIGINT NO IDENTITY PK Interaction rule
drug_a_rxnorm VARCHAR(20) NO RxNorm First drug
drug_b_rxnorm VARCHAR(20) NO RxNorm Second drug
severity VARCHAR(20) NO IN ('contraindicated','major','moderate','minor') Severity
description TEXT NO Description of interaction
clinical_significance TEXT YES NULL Clinical impact
recommendation TEXT YES NULL Recommended action
evidence_level VARCHAR(20) YES NULL e.g., "Level 1", "High"
source VARCHAR(100) YES NULL Vendor/source (FDB, Medi-Span, etc.)
active_flag BOOLEAN NO TRUE Active rule
created_at TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP Creation timestamp
updated_at TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP ON UPDATE Last update timestamp

SQL DDL

SQL
CREATE TABLE drug_interactions (
    interaction_id        BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    drug_a_rxnorm         VARCHAR(20) NOT NULL,
    drug_b_rxnorm         VARCHAR(20) NOT NULL,
    severity              VARCHAR(20) NOT NULL,
    description           TEXT NOT NULL,
    clinical_significance TEXT,
    recommendation        TEXT,
    evidence_level        VARCHAR(20),
    source                VARCHAR(100),
    active_flag           BOOLEAN NOT NULL DEFAULT TRUE,
    created_at            TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at            TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT uq_drug_interactions_pair UNIQUE (drug_a_rxnorm, drug_b_rxnorm)
);

ALTER TABLE drug_interactions
    ADD CONSTRAINT chk_drug_interactions_severity
        CHECK (severity IN ('contraindicated','major','moderate','minor'));

CREATE INDEX idx_drug_interactions_drug_a ON drug_interactions(drug_a_rxnorm) WHERE active_flag = TRUE;
CREATE INDEX idx_drug_interactions_drug_b ON drug_interactions(drug_b_rxnorm) WHERE active_flag = TRUE;

Terminology Bindings

Field Terminology Example Value
drug_a_rxnorm RxNorm 1049630
drug_b_rxnorm RxNorm 617314

FHIR Mapping

Interactions are typically exposed via DetectedIssue or CDS services:

Table Field FHIR Resource FHIR Path
interaction_id DetectedIssue DetectedIssue.id (when instantiated)
severity DetectedIssue DetectedIssue.severity
description DetectedIssue DetectedIssue.detail
recommendation DetectedIssue DetectedIssue.mitigation.action

7. pharmacy_inventory

Purpose
Tracks current stock levels of medications per facility and location (central pharmacy, satellites, ADCs), including lot and expiry for traceability and UAE MOH controlled substance compliance.

Field Specifications

Field Type Nullable Default Constraint Description
inventory_id BIGINT NO IDENTITY PK Inventory record
drug_code_rxnorm VARCHAR(20) NO RxNorm Drug
ndc_code VARCHAR(20) YES NULL Local pack code / GTIN
facility_id BIGINT NO FK → facilities.facility_id Facility
location_id BIGINT NO FK → locations.location_id Storage location (vault, ADC, shelf)
lot_number VARCHAR(50) YES NULL Lot/batch
expiry_date DATE YES NULL Expiry date
quantity_on_hand NUMERIC(14,3) NO 0 ≥ 0 Current stock
reorder_point NUMERIC(14,3) YES NULL ≥ 0 Threshold for reorder
par_level NUMERIC(14,3) YES NULL ≥ 0 Target stock level
last_count_date DATE YES NULL Last physical count
unit_cost NUMERIC(12,4) YES NULL ≥ 0 Cost per unit
is_controlled BOOLEAN NO FALSE Controlled substance flag
controlled_schedule VARCHAR(20) YES NULL UAE MOH schedule
active_flag BOOLEAN NO TRUE Active inventory line
created_at TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP Creation timestamp
updated_at TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP ON UPDATE Last update timestamp

SQL DDL

SQL
CREATE TABLE pharmacy_inventory (
    inventory_id        BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    drug_code_rxnorm    VARCHAR(20) NOT NULL,
    ndc_code            VARCHAR(20),
    facility_id         BIGINT NOT NULL,
    location_id         BIGINT NOT NULL,
    lot_number          VARCHAR(50),
    expiry_date         DATE,
    quantity_on_hand    NUMERIC(14,3) NOT NULL DEFAULT 0,
    reorder_point       NUMERIC(14,3),
    par_level           NUMERIC(14,3),
    last_count_date     DATE,
    unit_cost           NUMERIC(12,4),
    is_controlled       BOOLEAN NOT NULL DEFAULT FALSE,
    controlled_schedule VARCHAR(20),
    active_flag         BOOLEAN NOT NULL DEFAULT TRUE,
    created_at          TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at          TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE pharmacy_inventory
    ADD CONSTRAINT fk_inventory_facility
        FOREIGN KEY (facility_id) REFERENCES facilities(facility_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT fk_inventory_location
        FOREIGN KEY (location_id) REFERENCES locations(location_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT chk_inventory_qty_nonnegative
        CHECK (quantity_on_hand >= 0),
    ADD CONSTRAINT chk_inventory_reorder_nonnegative
        CHECK (reorder_point IS NULL OR reorder_point >= 0),
    ADD CONSTRAINT chk_inventory_par_nonnegative
        CHECK (par_level IS NULL OR par_level >= 0),
    ADD CONSTRAINT chk_inventory_unit_cost_nonnegative
        CHECK (unit_cost IS NULL OR unit_cost >= 0),
    ADD CONSTRAINT chk_inventory_controlled_schedule
        CHECK (is_controlled = FALSE OR controlled_schedule IS NOT NULL);

CREATE INDEX idx_inventory_drug_loc ON pharmacy_inventory(drug_code_rxnorm, facility_id, location_id);
CREATE INDEX idx_inventory_expiry ON pharmacy_inventory(expiry_date) WHERE active_flag = TRUE;
CREATE INDEX idx_inventory_controlled ON pharmacy_inventory(is_controlled) WHERE is_controlled = TRUE;

Terminology Bindings

Field Terminology Example Value
drug_code_rxnorm RxNorm 1049630
controlled_schedule UAE MOH Controlled Substance Schedules CDb

FHIR Mapping

Inventory is not directly represented in core FHIR; can be mapped to Medication + InventoryItem (if using R5) or custom extensions.


8. inventory_transactions

Purpose
Audit trail of all inventory movements (receipts, issues, returns, adjustments, transfers), supporting stock reconciliation and UAE MOH controlled substance tracking.

Field Specifications

Field Type Nullable Default Constraint Description
transaction_id BIGINT NO IDENTITY PK Transaction
inventory_id BIGINT NO FK → pharmacy_inventory.inventory_id Affected inventory line
transaction_type VARCHAR(20) NO IN ('receipt','issue','return','adjustment','transfer_out','transfer_in','waste') Type
quantity NUMERIC(14,3) NO <> 0 Quantity change (positive or negative)
from_location_id BIGINT YES NULL FK → locations.location_id Source location
to_location_id BIGINT YES NULL FK → locations.location_id Destination location
reference_type VARCHAR(30) YES NULL e.g., order, invoice, reconciliation
reference_id BIGINT YES NULL ID in reference table (e.g., order_id)
performed_by BIGINT NO FK → users.user_id User performing transaction
transaction_datetime TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP When performed
reason VARCHAR(255) YES NULL Reason (e.g., "expiry", "breakage")
is_controlled BOOLEAN NO FALSE Controlled substance flag snapshot
created_at TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP Creation timestamp

SQL DDL

SQL
CREATE TABLE inventory_transactions (
    transaction_id        BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    inventory_id          BIGINT NOT NULL,
    transaction_type      VARCHAR(20) NOT NULL,
    quantity              NUMERIC(14,3) NOT NULL,
    from_location_id      BIGINT,
    to_location_id        BIGINT,
    reference_type        VARCHAR(30),
    reference_id          BIGINT,
    performed_by          BIGINT NOT NULL,
    transaction_datetime  TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
    reason                VARCHAR(255),
    is_controlled         BOOLEAN NOT NULL DEFAULT FALSE,
    created_at            TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE inventory_transactions
    ADD CONSTRAINT fk_inv_tx_inventory
        FOREIGN KEY (inventory_id) REFERENCES pharmacy_inventory(inventory_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT fk_inv_tx_from_location
        FOREIGN KEY (from_location_id) REFERENCES locations(location_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT fk_inv_tx_to_location
        FOREIGN KEY (to_location_id) REFERENCES locations(location_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT fk_inv_tx_performed_by
        FOREIGN KEY (performed_by) REFERENCES users(user_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT chk_inv_tx_type
        CHECK (transaction_type IN ('receipt','issue','return','adjustment','transfer_out','transfer_in','waste')),
    ADD CONSTRAINT chk_inv_tx_quantity_nonzero
        CHECK (quantity <> 0);

CREATE INDEX idx_inv_tx_inventory ON inventory_transactions(inventory_id);
CREATE INDEX idx_inv_tx_datetime ON inventory_transactions(transaction_datetime);
CREATE INDEX idx_inv_tx_type ON inventory_transactions(transaction_type);
CREATE INDEX idx_inv_tx_controlled ON inventory_transactions(is_controlled) WHERE is_controlled = TRUE;

9. controlled_substance_log

Purpose
Perpetual inventory and chain-of-custody log for controlled substances, compliant with UAE MOH requirements (Federal Law No. 14 of 1995 and amendments). Captures all movements, administration, and waste with dual signatures where required.

Field Specifications

Field Type Nullable Default Constraint Description
log_id BIGINT NO IDENTITY PK Log entry
inventory_id BIGINT YES NULL FK → pharmacy_inventory.inventory_id Related inventory line
drug_code_rxnorm VARCHAR(20) NO RxNorm Drug
controlled_schedule VARCHAR(20) NO UAE MOH schedule Controlled class
transaction_type VARCHAR(20) NO IN ('receipt','dispense_to_unit','return_to_pharmacy','administer_to_patient','waste','adjustment','loss_theft') Type
quantity NUMERIC(14,3) NO > 0 Quantity involved
balance_after NUMERIC(14,3) NO ≥ 0 Balance after transaction
from_user_id BIGINT YES NULL FK → users.user_id From user (e.g., pharmacist)
to_user_id BIGINT YES NULL FK → users.user_id To user (e.g., nurse)
witness_id BIGINT YES NULL FK → users.user_id Witness for handover
patient_id BIGINT YES NULL FK → patients.patient_id Patient if administered
encounter_id BIGINT YES NULL FK → encounters.encounter_id Encounter if administered
waste_amount NUMERIC(14,3) YES NULL ≥ 0 Amount wasted
waste_witnessed_by BIGINT YES NULL FK → users.user_id Witness for waste
location_id BIGINT NO FK → locations.location_id Vault/ADC/ward
transaction_datetime TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP When occurred
reason VARCHAR(255) YES NULL Reason (e.g., "partial dose", "breakage")
reported_to_moh BOOLEAN NO FALSE Flag if reported (loss/theft)
moh_report_reference VARCHAR(50) YES NULL MOH report ID
created_at TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP Creation timestamp

SQL DDL

SQL
CREATE TABLE controlled_substance_log (
    log_id               BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    inventory_id         BIGINT,
    drug_code_rxnorm     VARCHAR(20) NOT NULL,
    controlled_schedule  VARCHAR(20) NOT NULL,
    transaction_type     VARCHAR(20) NOT NULL,
    quantity             NUMERIC(14,3) NOT NULL,
    balance_after        NUMERIC(14,3) NOT NULL,
    from_user_id         BIGINT,
    to_user_id           BIGINT,
    witness_id           BIGINT,
    patient_id           BIGINT,
    encounter_id         BIGINT,
    waste_amount         NUMERIC(14,3),
    waste_witnessed_by   BIGINT,
    location_id          BIGINT NOT NULL,
    transaction_datetime TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
    reason               VARCHAR(255),
    reported_to_moh      BOOLEAN NOT NULL DEFAULT FALSE,
    moh_report_reference VARCHAR(50),
    created_at           TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE controlled_substance_log
    ADD CONSTRAINT fk_cslog_inventory
        FOREIGN KEY (inventory_id) REFERENCES pharmacy_inventory(inventory_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT fk_cslog_from_user
        FOREIGN KEY (from_user_id) REFERENCES users(user_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT fk_cslog_to_user
        FOREIGN KEY (to_user_id) REFERENCES users(user_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT fk_cslog_witness
        FOREIGN KEY (witness_id) REFERENCES users(user_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT fk_cslog_patient
        FOREIGN KEY (patient_id) REFERENCES patients(patient_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT fk_cslog_encounter
        FOREIGN KEY (encounter_id) REFERENCES encounters(encounter_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT fk_cslog_waste_witness
        FOREIGN KEY (waste_witnessed_by) REFERENCES users(user_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT fk_cslog_location
        FOREIGN KEY (location_id) REFERENCES locations(location_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT chk_cslog_type
        CHECK (transaction_type IN ('receipt','dispense_to_unit','return_to_pharmacy','administer_to_patient','waste','adjustment','loss_theft')),
    ADD CONSTRAINT chk_cslog_quantity_positive
        CHECK (quantity > 0),
    ADD CONSTRAINT chk_cslog_balance_nonnegative
        CHECK (balance_after >= 0),
    ADD CONSTRAINT chk_cslog_waste_amount
        CHECK (waste_amount IS NULL OR waste_amount >= 0);

CREATE INDEX idx_cslog_drug_loc ON controlled_substance_log(drug_code_rxnorm, location_id);
CREATE INDEX idx_cslog_datetime ON controlled_substance_log(transaction_datetime);
CREATE INDEX idx_cslog_patient ON controlled_substance_log(patient_id);
CREATE INDEX idx_cslog_type ON controlled_substance_log(transaction_type);

10. iv_admixture_orders

Purpose
Stores IV admixture compounding orders and preparation details for sterile products, including beyond-use dating and verification.

Field Specifications

Field Type Nullable Default Constraint Description
admixture_id BIGINT NO IDENTITY PK IV admixture record
order_id BIGINT NO FK → pharmacy_orders.order_id Parent order
patient_id BIGINT NO FK → patients.patient_id Patient
encounter_id BIGINT NO FK → encounters.encounter_id Encounter
base_solution VARCHAR(100) NO Base solution (e.g., "NaCl 0.9% 100 mL")
base_solution_rxnorm VARCHAR(20) YES NULL RxNorm Base solution code
additive_drug VARCHAR(255) NO Additive drug name
additive_drug_rxnorm VARCHAR(20) YES NULL RxNorm Additive code
additive_dose NUMERIC(12,3) NO > 0 Additive dose
additive_dose_unit VARCHAR(20) NO UCUM Dose unit
concentration VARCHAR(50) YES NULL e.g., "4 mg/mL"
total_volume NUMERIC(12,3) NO > 0 Final volume (mL)
infusion_rate NUMERIC(12,3) YES NULL ≥ 0 Rate (mL/h)
beyond_use_datetime TIMESTAMP WITH TIME ZONE NO > preparation_datetime BUD
prepared_by BIGINT NO FK → users.user_id Technician/pharmacist who prepared
verified_by BIGINT NO FK → users.user_id Pharmacist verifying
preparation_datetime TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP When prepared
status VARCHAR(20) NO 'prepared' IN ('queued','in_progress','prepared','released','discarded') Status
hood_location_id BIGINT YES NULL FK → locations.location_id Cleanroom/hood
gravimetric_verification_json JSONB YES NULL Data from gravimetric system
label_printed BOOLEAN NO FALSE Label printed
created_at TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP Creation timestamp

SQL DDL

SQL
CREATE TABLE iv_admixture_orders (
    admixture_id                 BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    order_id                     BIGINT NOT NULL,
    patient_id                   BIGINT NOT NULL,
    encounter_id                 BIGINT NOT NULL,
    base_solution                VARCHAR(100) NOT NULL,
    base_solution_rxnorm        VARCHAR(20),
    additive_drug               VARCHAR(255) NOT NULL,
    additive_drug_rxnorm        VARCHAR(20),
    additive_dose               NUMERIC(12,3) NOT NULL,
    additive_dose_unit          VARCHAR(20) NOT NULL,
    concentration               VARCHAR(50),
    total_volume                NUMERIC(12,3) NOT NULL,
    infusion_rate               NUMERIC(12,3),
    beyond_use_datetime         TIMESTAMP WITH TIME ZONE NOT NULL,
    prepared_by                 BIGINT NOT NULL,
    verified_by                 BIGINT NOT NULL,
    preparation_datetime        TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
    status                      VARCHAR(20) NOT NULL DEFAULT 'prepared',
    hood_location_id            BIGINT,
    gravimetric_verification_json JSONB,
    label_printed               BOOLEAN NOT NULL DEFAULT FALSE,
    created_at                  TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE iv_admixture_orders
    ADD CONSTRAINT fk_iv_order
        FOREIGN KEY (order_id) REFERENCES pharmacy_orders(order_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT fk_iv_patient
        FOREIGN KEY (patient_id) REFERENCES patients(patient_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT fk_iv_encounter
        FOREIGN KEY (encounter_id) REFERENCES encounters(encounter_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT fk_iv_prepared_by
        FOREIGN KEY (prepared_by) REFERENCES users(user_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT fk_iv_verified_by
        FOREIGN KEY (verified_by) REFERENCES users(user_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT fk_iv_hood_location
        FOREIGN KEY (hood_location_id) REFERENCES locations(location_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT chk_iv_status
        CHECK (status IN ('queued','in_progress','prepared','released','discarded')),
    ADD CONSTRAINT chk_iv_additive_dose_positive
        CHECK (additive_dose > 0),
    ADD CONSTRAINT chk_iv_total_volume_positive
        CHECK (total_volume > 0),
    ADD CONSTRAINT chk_iv_infusion_rate_nonnegative
        CHECK (infusion_rate IS NULL OR infusion_rate >= 0),
    ADD CONSTRAINT chk_iv_bud_after_prep
        CHECK (beyond_use_datetime > preparation_datetime);

CREATE INDEX idx_iv_order ON iv_admixture_orders(order_id);
CREATE INDEX idx_iv_patient ON iv_admixture_orders(patient_id);
CREATE INDEX idx_iv_status ON iv_admixture_orders(status);
CREATE INDEX idx_iv_bud ON iv_admixture_orders(beyond_use_datetime);

11. pharmacy_interventions

Purpose
Documents clinical pharmacy interventions on orders (dose adjustments, therapy changes, clarifications), supporting quality metrics and regulatory reporting.

Field Specifications

Field Type Nullable Default Constraint Description
intervention_id BIGINT NO IDENTITY PK Intervention
order_id BIGINT NO FK → pharmacy_orders.order_id Related order
patient_id BIGINT NO FK → patients.patient_id Patient
encounter_id BIGINT YES NULL FK → encounters.encounter_id Encounter
pharmacist_id BIGINT NO FK → users.user_id Pharmacist
intervention_type VARCHAR(50) NO e.g., "dose adjustment", "interaction prevention" Type
description TEXT NO Description of issue
recommendation TEXT YES NULL Recommendation to prescriber
prescriber_contacted BOOLEAN NO FALSE Contacted flag
prescriber_response VARCHAR(50) YES NULL e.g., "accepted", "rejected", "pending"
outcome VARCHAR(50) YES NULL Clinical outcome if known
intervention_datetime TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP When recorded
time_spent_minutes INT YES NULL ≥ 0 Time spent
cds_triggered BOOLEAN NO FALSE Triggered by CDS alert
created_at TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP Creation timestamp

SQL DDL

SQL
CREATE TABLE pharmacy_interventions (
    intervention_id        BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    order_id               BIGINT NOT NULL,
    patient_id             BIGINT NOT NULL,
    encounter_id           BIGINT,
    pharmacist_id          BIGINT NOT NULL,
    intervention_type      VARCHAR(50) NOT NULL,
    description            TEXT NOT NULL,
    recommendation         TEXT,
    prescriber_contacted   BOOLEAN NOT NULL DEFAULT FALSE,
    prescriber_response    VARCHAR(50),
    outcome                VARCHAR(50),
    intervention_datetime  TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
    time_spent_minutes     INT,
    cds_triggered          BOOLEAN NOT NULL DEFAULT FALSE,
    created_at             TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE pharmacy_interventions
    ADD CONSTRAINT fk_intervention_order
        FOREIGN KEY (order_id) REFERENCES pharmacy_orders(order_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT fk_intervention_patient
        FOREIGN KEY (patient_id) REFERENCES patients(patient_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT fk_intervention_encounter
        FOREIGN KEY (encounter_id) REFERENCES encounters(encounter_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT fk_intervention_pharmacist
        FOREIGN KEY (pharmacist_id) REFERENCES users(user_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT chk_intervention_time_spent
        CHECK (time_spent_minutes IS NULL OR time_spent_minutes >= 0);

CREATE INDEX idx_intervention_order ON pharmacy_interventions(order_id);
CREATE INDEX idx_intervention_patient ON pharmacy_interventions(patient_id);
CREATE INDEX idx_intervention_datetime ON pharmacy_interventions(intervention_datetime);
CREATE INDEX idx_intervention_type ON pharmacy_interventions(intervention_type);

12. medication_reconciliation

Purpose
Captures reconciliation actions at admission, transfer, and discharge, including comparison between home, inpatient, and discharge medications.

Field Specifications

Field Type Nullable Default Constraint Description
recon_id BIGINT NO IDENTITY PK Reconciliation record
patient_id BIGINT NO FK → patients.patient_id Patient
encounter_id BIGINT NO FK → encounters.encounter_id Encounter
reconciliation_type VARCHAR(20) NO IN ('admission','transfer','discharge') Type
home_medication_rxnorm VARCHAR(20) YES NULL RxNorm Home med code
home_medication_name VARCHAR(255) YES NULL Home med name
home_dose VARCHAR(50) YES NULL Home dose (free text)
home_route VARCHAR(30) YES NULL Home route
home_frequency VARCHAR(30) YES NULL Home frequency
source_of_information VARCHAR(50) YES NULL e.g., "patient", "family", "community pharmacy"
action_taken VARCHAR(20) YES NULL IN ('continue','hold','modify','discontinue','new') Action
new_order_id BIGINT YES NULL FK → pharmacy_orders.order_id New/modified order
discrepancy_type VARCHAR(50) YES NULL e.g., "omission", "duplication"
reconciled_by BIGINT NO FK → users.user_id Pharmacist/physician
reconciled_datetime TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP When reconciled
notes TEXT YES NULL Additional notes
created_at TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP Creation timestamp

SQL DDL

SQL
CREATE TABLE medication_reconciliation (
    recon_id               BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    patient_id             BIGINT NOT NULL,
    encounter_id           BIGINT NOT NULL,
    reconciliation_type    VARCHAR(20) NOT NULL,
    home_medication_rxnorm VARCHAR(20),
    home_medication_name   VARCHAR(255),
    home_dose              VARCHAR(50),
    home_route             VARCHAR(30),
    home_frequency         VARCHAR(30),
    source_of_information  VARCHAR(50),
    action_taken           VARCHAR(20),
    new_order_id           BIGINT,
    discrepancy_type       VARCHAR(50),
    reconciled_by          BIGINT NOT NULL,
    reconciled_datetime    TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
    notes                  TEXT,
    created_at             TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE medication_reconciliation
    ADD CONSTRAINT fk_recon_patient
        FOREIGN KEY (patient_id) REFERENCES patients(patient_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT fk_recon_encounter
        FOREIGN KEY (encounter_id) REFERENCES encounters(encounter_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT fk_recon_new_order
        FOREIGN KEY (new_order_id) REFERENCES pharmacy_orders(order_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT fk_recon_user
        FOREIGN KEY (reconciled_by) REFERENCES users(user_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT chk_recon_type
        CHECK (reconciliation_type IN ('admission','transfer','discharge')),
    ADD CONSTRAINT chk_recon_action
        CHECK (action_taken IS NULL OR action_taken IN ('continue','hold','modify','discontinue','new'));

CREATE INDEX idx_recon_patient ON medication_reconciliation(patient_id);
CREATE INDEX idx_recon_encounter ON medication_reconciliation(encounter_id);
CREATE INDEX idx_recon_type ON medication_reconciliation(reconciliation_type);
CREATE INDEX idx_recon_datetime ON medication_reconciliation(reconciled_datetime);

13. antimicrobial_stewardship_reviews

Purpose
Tracks antimicrobial stewardship reviews, recommendations, and prescriber responses, including linkage to culture/sensitivity results from LIS.

Field Specifications

Field Type Nullable Default Constraint Description
review_id BIGINT NO IDENTITY PK Review
order_id BIGINT NO FK → pharmacy_orders.order_id Antimicrobial order
patient_id BIGINT NO FK → patients.patient_id Patient
encounter_id BIGINT YES NULL FK → encounters.encounter_id Encounter
antibiotic_rxnorm VARCHAR(20) NO RxNorm Antibiotic
review_type VARCHAR(20) NO IN ('prospective','retrospective','automatic') Type
indication VARCHAR(255) YES NULL Indication (e.g., "HAP", "UTI")
culture_result_id BIGINT YES NULL LIS culture ID (external reference)
recommendation TEXT YES NULL Stewardship recommendation
accepted BOOLEAN YES NULL Whether prescriber accepted
reviewed_by BIGINT NO FK → users.user_id Stewardship pharmacist/ID physician
reviewed_datetime TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP When reviewed
prescriber_response VARCHAR(255) YES NULL Prescriber comments
ddd_value NUMERIC(10,3) YES NULL ≥ 0 Defined daily doses for utilization metrics
created_at TIMESTAMP WITH TIME ZONE NO CURRENT_TIMESTAMP Creation timestamp

SQL DDL

SQL
CREATE TABLE antimicrobial_stewardship_reviews (
    review_id           BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    order_id            BIGINT NOT NULL,
    patient_id          BIGINT NOT NULL,
    encounter_id        BIGINT,
    antibiotic_rxnorm   VARCHAR(20) NOT NULL,
    review_type         VARCHAR(20) NOT NULL,
    indication          VARCHAR(255),
    culture_result_id   BIGINT,
    recommendation      TEXT,
    accepted            BOOLEAN,
    reviewed_by         BIGINT NOT NULL,
    reviewed_datetime   TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
    prescriber_response VARCHAR(255),
    ddd_value           NUMERIC(10,3),
    created_at          TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE antimicrobial_stewardship_reviews
    ADD CONSTRAINT fk_steward_order
        FOREIGN KEY (order_id) REFERENCES pharmacy_orders(order_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT fk_steward_patient
        FOREIGN KEY (patient_id) REFERENCES patients(patient_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT fk_steward_encounter
        FOREIGN KEY (encounter_id) REFERENCES encounters(encounter_id) ON UPDATE CASCADE ON DELETE SET NULL,
    ADD CONSTRAINT fk_steward_reviewer
        FOREIGN KEY (reviewed_by) REFERENCES users(user_id) ON UPDATE CASCADE ON DELETE RESTRICT,
    ADD CONSTRAINT chk_steward_review_type
        CHECK (review_type IN ('prospective','retrospective','automatic')),
    ADD CONSTRAINT chk_steward_ddd_nonnegative
        CHECK (ddd_value IS NULL OR ddd_value >= 0);

CREATE INDEX idx_steward_order ON antimicrobial_stewardship_reviews(order_id);
CREATE INDEX idx_steward_patient ON antimicrobial_stewardship_reviews(patient_id);
CREATE INDEX idx_steward_datetime ON antimicrobial_stewardship_reviews(reviewed_datetime);
CREATE INDEX idx_steward_review_type ON antimicrobial_stewardship_reviews(review_type);

Data Volume Estimates

Approximate for a 300-bed UAE hospital.

Table Initial Rows (Year 1) Annual Growth Notes
pharmacy_orders 1,000,000 +1,000,000 / year High volume across inpatient/outpatient
pharmacy_dispensing 1,500,000 +1,500,000 / year Multiple fills per order
medication_administration 8,000,000 +8,000,000 / year Multiple administrations per day per patient
formulary 10 +2 / year Few formularies per facility
formulary_items 3,000 +300 / year Based on master data brief
drug_interactions 50,000 +5,000 / year From vendor updates
pharmacy_inventory 10,000 +1,000 / year Per facility/location/lot
inventory_transactions 500,000 +500,000 / year All movements
controlled_substance_log 50,000 +50,000 / year All controlled movements
iv_admixture_orders 80,000 +80,000 / year High for critical care/oncology
pharmacy_interventions 100,000 +100,000 / year Active clinical pharmacy
medication_reconciliation 120,000 +120,000 / year Per admission/transfer/discharge
antimicrobial_stewardship_reviews 40,000 +40,000 / year Restricted/broad-spectrum antibiotics

Data Retention Policy (UAE Context)

Retention aligned with UAE MOH, DOH, DHA guidance and UAE PDPL (minimums; facilities may choose longer retention).

Table Recommended Retention Rationale / Notes
pharmacy_orders ≥ 25 years from last encounter Core part of medical record; supports medico-legal and MOH audits
pharmacy_dispensing ≥ 15 years Medication history, billing disputes, HIE traceability
medication_administration ≥ 25 years Part of clinical record and nursing documentation
formulary ≥ 10 years after retirement Policy/audit trail for formulary decisions
formulary_items ≥ 10 years after retirement Supports retrospective clinical audits
drug_interactions 5 years after deactivation Knowledge base; keep for CDS auditability
pharmacy_inventory 10 years Stock management, recall traceability
inventory_transactions 10 years Financial and audit trail, especially for high-cost drugs
controlled_substance_log ≥ 15 years UAE MOH controlled substance regulations and potential investigations
iv_admixture_orders ≥ 15 years High-risk sterile preparations; supports adverse event investigations
pharmacy_interventions ≥ 15 years Quality metrics, medico-legal support
medication_reconciliation ≥ 25 years Part of longitudinal medication history
antimicrobial_stewardship_reviews ≥ 10 years Stewardship program reporting, resistance trend analysis

Data older than the retention period should be archived in encrypted, access-controlled storage, with access governed by UAE PDPL (data minimisation, purpose limitation, and subject rights).

content/clinical/pis/03-data-specifications.md Generated 2026-02-20 22:54