1. 📌 Overview & Purpose
Goal: Setiap preskripsi sampai kaunter farmasi di-validate AI dlm <3s — DDI, allergy, dose paeds/renal/hepatic, halal status, NPRA stock. Farmasis verify visual + barcode → dispense. Closed-loop verify untuk safety zero compromise.
Per Doc Zam mock (slide 7): Prescription Queue (8 prescriptions visible) · Verification panel · Print Label · Counsel checklist.
HITL gate: AI propose check, pharmacist final approve. Tiada auto-dispense.
2. 👤 User Stories
RX masuk dari M4 · saya nak AI dah pre-check DDI/allergy/dose · saya scan barcode dispense + counsel checklist · dah!
Pesakit pakai amlodipine, doctor preskripsi clarithromycin (MAJOR DDI · QT prolong) · saya nak AI alert merah, suggest azithromycin alt, hold dispense pending doctor confirm.
Bayi 8kg dpt ubat paracetamol — saya nak AI auto-calc dose (10-15mg/kg) dan flag kalau preskripsi over-dose.
Saya muslim · saya nak AI flag kalau ada gelatin animal-source dlm capsule, suggest halal alternative.
RX brand mahal · panel insurance hanya cover generic · AI suggest generic equivalent dgn cost saving · doctor approve once-off.
Pesakit ngadu side effect 2 hari kemudian (M6) · saya terima alert · auto-block re-dispense same drug class for that patient.
3. ✅ Functional Requirements
4. ⚙️ Non-Functional Requirements
| Aspect | Target | Notes |
|---|---|---|
| DDI check latency | <3s p99 | Cached lookup · NPRA + Lexicomp local |
| Allergy cross-ref | <500ms | In-memory patient registry |
| Dose calc | <100ms | Local algorithm · no LLM needed |
| Barcode scan to verify | <1s | Local USB · no network |
| Label print | <3s | Zebra direct · USB / network printer |
| NPRA DB freshness | ≤24h delay | Daily cron sync |
| Concurrent RX queue | ≥20 simultaneous | Pilot scale |
| HITL approve round-trip | <1s UI | Pharmacist 1-tap |
| Token cost / RX | ~1K tokens | Mostly rule-based · LLM only for explanation |
5. 🗄️ Data Model
| Table | Key fields | Purpose |
|---|---|---|
prescriptions | id, encounter_id, doctor_id, patient_id, status (queued · verifying · approved · dispensed · cancelled), justification, items_count | RX header |
prescription_items | rx_id, line_no, drug_code (NPRA), drug_name_brand, drug_name_generic, dose_mg, frequency, route, duration_days, halal_status, ai_suggested_substitute | RX lines |
ddi_alerts | rx_id, drug_a, drug_b, severity (MINOR/MOD/MAJOR/CONTRA), description, citation, suggested_alt, pharmacist_action | FR-5.2 audit |
allergy_alerts | rx_id, drug_class, patient_allergy, severity, cross_class_reactivity, pharmacist_action | FR-5.3 audit |
dispense_log | rx_id, item_id, dispensed_by_pharmacist, barcode_hash, dispensed_at, counsel_completed, label_url | FR-5.11 closed-loop |
drugs_npra | npra_code, generic_name, brand_name, halal_status, halal_cert_no, schedule_class (controlled/Rx/OTC), gelatin_source, excipients_json | NPRA mirror |
drug_interactions | drug_a_code, drug_b_code, severity, description, source (NPRA/Lexicomp/MOH) | DDI database |
inventory | tenant_id, npra_code, qty_on_hand, reorder_threshold, last_received, expiry_date | FR-5.7 |
6. 🔌 API + MCP
GET /api/v1/pharmacy/queue # ready/verifying/pending
POST /api/v1/pharmacy/{rx_id}/verify # AI run all checks
Returns: { ddi_alerts, allergy_alerts, dose_warnings, halal_flags, generic_suggestions }
POST /api/v1/pharmacy/{rx_id}/approve # pharmacist HITL approve
Body: { line_decisions: [{ line_no, action: "dispense"|"substitute"|"hold"|"cancel", reason }] }
POST /api/v1/pharmacy/{rx_id}/dispense # post barcode scan
Body: { line_no, barcode, quantity }
Returns: { dispense_id, label_pdf_url }
POST /api/v1/pharmacy/{rx_id}/print-label # generate label PDF
POST /api/v1/pharmacy/{rx_id}/counsel-done # close encounter
GET /api/v1/pharmacy/inventory/check/{drug_code}
POST /api/v1/pharmacy/inventory/reorder
# MCP Tools
ddi_check Drug-drug interaction · severity + alternatives
allergy_lookup Patient allergy registry cross-ref
dose_calc Paeds/eGFR/hepatic adjusted
halal_filter NPRA halal index check
generic_suggest Substitution + cost compare
npra_stock Drug DB lookup
barcode_verify Match scanned barcode vs RX
7. 🔁 State Machine
┌──────────────────┐
│ RX_RECEIVED │ from M4 sign-off
└────────┬─────────┘
▼
┌──────────────────┐
│ AI_VERIFYING │ DDI · allergy · dose · halal · stock parallel
└────────┬─────────┘
▼
┌──────────────────┐ ┌──────────────────┐
│ ALERTS_RAISED │────────►│ HITL_REVIEW │ pharmacist decide
└────────┬─────────┘ └────────┬─────────┘
│ no alerts │
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ READY_TO_DISPENSE│ │ APPROVED/HOLD/ │
└────────┬─────────┘ │ SUB/CANCEL │
│ └────────┬─────────┘
▼ │ approved
┌──────────────────┐ │
│ BARCODE_SCAN │◄─────────────────┘
└────────┬─────────┘
▼ match
┌──────────────────┐
│ DISPENSED │ label print · counsel · log
└────────┬─────────┘
▼
┌──────────────────┐
│ COUNSEL_COMPLETE │
└────────┬─────────┘
▼
┌──────────────────┐
│ CLOSED │ → emit event for M6 monitoring
└──────────────────┘
8. 🤖 Agent Specification
M5 mostly rule-based + structured DB lookup. LLM hanya untuk: (a) generate counsel checklist explanation BM/EN, (b) explain DDI severity to patient (kalau pesakit tanya).
- Model: Llama 8B (rule-based heavy + light explanation)
- Memory: NPRA drug DB · DDI matrix (in-memory) · patient allergy registry
- Guardrails: HITL pharmacist final approve · dispense block on CONTRAINDICATED · audit per click
9. 🎨 UI/UX
Per Doc Zam mock slide 7: Prescription Queue + Verification panel.
- Filament 3 Pharmacy panel · 2-column layout
- Left: queue list (Ready · Verifying · Pending · Completed)
- Right: verification detail card · per-line item · alerts color-coded
- DDI alert: red banner · severity · alternatives card
- Halal flag: green/red icon · capsule source disclosure
- Approve/Substitute/Hold/Cancel buttons per-line
- Barcode scan input · confirmation chime
- Print Label button · counsel checklist modal
- Bottom stats: Total Today · Average Time · Pending Approvals
10. ✔️ Acceptance Criteria
- AC-5.1: 50 RX clinical safety scenarios → 100% MAJOR/CONTRA DDI detected
- AC-5.2: 30 paeds dose scenarios → 100% under/over-dose flagged
- AC-5.3: Halal flag accuracy ≥95% pada 100 sample drugs
- AC-5.4: Barcode mismatch detection 100% (10 swap test)
- AC-5.5: Generic substitution cost saving ≥20% on average
- AC-5.6: HITL pharmacist gate enforced — 0 auto-dispense on CONTRA
- AC-5.7: Label print BM/EN dual format · scannable barcode included
- AC-5.8: Adverse loop M6 trigger working — block re-dispense within 5 min
- AC-5.9: Counsel checklist completion required before close encounter
- AC-5.10: Doc Zam clinical pharmacist review 20 sample RX → ≥18 acceptable
11. 🧪 Test Plan
| Tier | Cases | Coverage |
|---|---|---|
| Unit | DDI matrix lookup · dose calc (paeds/renal/hepatic) · halal filter · barcode hash | ≥90% |
| Integration | RX intake from M4 · all 5 verification checks parallel · HITL gate · M6 adverse trigger | 100% paths |
| Clinical safety | 50 DDI · 30 dose paeds · 20 allergy cross-class · 100 halal · 10 barcode swap | 0 critical miss |
| Hardware integration | USB barcode scanner · Zebra label printer · network printer fallback | 3 scanner brands tested |
| Load | 20 concurrent RX queue · 5 simultaneous label prints | p99 <3s |
| UAT | 2 weeks pharmacist usage · NPS · time-to-dispense | NPS ≥7 · time savings ≥20% |
12. 🔗 Dependencies
- Hard: M9 (audit + HITL gate) · M4 DRPA (RX source · sign-off event)
- Soft: M6 ARXL (adverse loop) · M7 ADPA (billing trigger) · M1 PSPA (allergy intake)
- External: NPRA drug DB · NPRA halal index · Lexicomp DDI (or MIMS Malaysia) · Zebra/BPL label printer SDK · USB barcode scanner driver
13. 🏃 Sprint Allocation
- Day 1-2: NPRA DB ingestion · drug + DDI matrix · halal index seed
- Day 3-4: 5 verification check engines (DDI · allergy · dose · halal · stock)
- Day 5-6: Filament Pharmacy panel · queue UI · verification card
- Day 7-8: HITL gate · barcode scan integration · label printer
- Day 9-10: M6 adverse trigger hook · counsel checklist
- Day 11: Doc Zam pharmacist review (20 RX scenarios) · iteration
- Day 12: E2E test · sprint review
14. ⚠️ Module-Specific Risks
| Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|
| NPRA DDI database outdated | Med | 🟠 Wrong alert | Daily NPRA sync · Lexicomp backup · alert if >24h stale · pharmacist override allowed |
| Halal filter false positive (block essential drug) | Med | 🟢 Patient frustration | Patient explicit halal-only opt-in · default warn-not-block · suggest alternative |
| DDI false positive (block essential RX) | Med | 🟠 Care delay | Severity tier · pharmacist override audited · clinical justification required |
| Barcode scan spoof / wrong drug missed | Low | 🔴 Patient harm | Verify code + name + visual check · counsel checklist requires drug name confirm |
| Generic substitution cost saved but bioequivalence concern | Low | 🟠 Therapeutic concern | NPRA-bioequivalent only · pharmacist flag if narrow therapeutic index drug |
| Label printer hardware fail | Med | 🟢 Workflow stop | Network printer fallback · PDF generate option · pharmacist hand-write emergency |
| Inventory desync with physical stock | Med | 🟢 Stock-out surprise | Daily reconciliation · barcode dispense decrements · monthly physical count |