🧩 Module Spec · M2 PCBP · Pre-Consult Briefing · DETAIL · 26 April 2026
← Modules M2 · PCBP DETAIL Sprint 2.1 · 5-18 Jul 2026

M2 — Pre-Consult Briefing Packet

Bridge dari M1 Patient PA ke M4 Doctor PA. Doktor terima briefing lengkap (simptom timeline · triage · history excerpts · vitals · CDSS hint) sebelum pesakit masuk bilik konsult.

1. 📌 Overview & Purpose

Goal: Eliminate "tanya simptom semula" di awal konsult. Doktor jimat 2-3 minit/pesakit dgn pre-loaded context + structured briefing card. Pesakit malu/lupa tak masalah — AI dah kumpul + summarise.

Wait-time productivity: Pesakit tunggu giliran tu mengadu kat M1, M2 transform jadi briefing structured. Doctor scan briefing 30 saat — terus masuk topik. Cycle savings: 30 pesakit × 2.5 min = 75 min/hari.

What it is NOT: Bukan diagnosis. Bukan ganti history-taking. Briefing = jump-start, doktor tetap konfirm + clarify face-to-face.

2. 👤 User Stories

US-2.1 (Doktor · Pre-arrival)

Sebagai doktor on-duty, saya nak tengok briefing packet pesakit appointment hari ni — ringkasan simptom + triage + history — supaya saya sedia <30 saat sebelum dia masuk bilik.

US-2.2 (Doktor · Real-time refresh)

Pesakit tambah simptom baru via M1 sambil tunggu giliran — saya nak briefing auto-refresh, tak perlu reload manual.

US-2.3 (Doktor · Acknowledge)

Saya tap "Acknowledge briefing" → audit log capture saya dah baca · pesakit mobile app reflect doktor dah ready.

US-2.4 (Pesakit · Trust)

Sebagai pesakit, saya nak yakin "doktor dah baca apa saya bagitahu AI" — bila saya masuk bilik dia terus tanya specific, saya tak rasa terbuang masa.

US-2.5 (Doktor · Red-flag)

Kalau M1 escalate pesakit MERAH yang dah on-the-way, saya nak briefing dgn HIGH-PRIORITY badge · auto-page sound notification.

US-2.6 (Doktor · Mobile/tablet)

Saya guna iPad antara bilik · briefing render mobile-friendly, swipeable cards.

3. ✅ Functional Requirements

MUSTFR-2.1: Trigger on event appointment.booked from M1 atau manual via M7
MUSTFR-2.2: Aggregate inputs: full M1 symptom session · 11-section Patient Profile (allergies/meds/chronic) · last 3 encounter SOAP excerpts · recent 3-month vitals trend · ADR registry
MUSTFR-2.3: LLM compose briefing as STRUCTURED JSON (S/O skeleton, no A/P — doktor decide)
MUSTFR-2.4: Render briefing card di M4 Doctor PA encounter detail (top, expandable)
MUSTFR-2.5: Doctor "Acknowledge briefing" event → audit log + patient app status update
MUSTFR-2.6: Real-time refresh kalau M1 add new turn (WebSocket atau polling 5s)
MUSTFR-2.7: RED-flag escalation badge + audio notification untuk MERAH triage en-route
MUSTFR-2.8: Mobile-friendly (iPad/tablet) responsive · swipeable card
MUSTFR-2.9: Briefing TTL 24h post encounter complete (audio refs purge per M9 retention)
MUSTFR-2.10: CDSS hint preview (top-3 DDx based on symptom + history) — informational only
MUSTFR-2.11: Patient timeline visual (encounter dates · key events)
SHOULDFR-2.12: Briefing PDF export (untuk doctor offline reference)
SHOULDFR-2.13: Multi-language toggle (BM/EN per doktor preference)
SHOULDFR-2.14: Voice-read briefing (TTS option · BM accent)
MAYFR-2.15: Briefing diff highlight (apa yg berubah vs last visit)

4. ⚙️ Non-Functional Requirements

AspectTargetNotes
Briefing generation latency<3s post-triggerLlama 70B chained · cached patient context
Briefing load di doctor UI<1sPre-fetched on appointment book event
Real-time refresh latency<5sWebSocket push · fallback poll 10s
Citation coverage100% suggestionsNPRA · MOH CPG · prior encounter source
Briefing length~300-500 wordsScannable in 30s
Token cost / briefing~4K tokens avgConservative model
Concurrent briefing generation≥10 simultaneousPilot scale

5. 🗄️ Data Model

TableKey fieldsPurpose
briefing_packetsid, session_id (M1), encounter_id?, doctor_id, patient_id, packet_json, generated_at, viewed_at, acknowledged_at, versionPer-briefing record
briefing_revisionsbriefing_id, revision_no, change_summary, refreshed_atFR-2.6 history

5a. Briefing JSON Schema

{
  "briefing_id": "brf_abc123",
  "version": 2,
  "patient_summary": {
    "mrn": "2026-001245",
    "age": 45,
    "gender": "M",
    "preferred_language": "ms"
  },
  "triage": {
    "color": "YELLOW",
    "confidence": 0.84,
    "reasoning": "Persistent headache 3 days + photophobia",
    "red_flags_checked": ["chest_pain", "stroke_signs", "neurological_deficit"],
    "red_flags_present": []
  },
  "chief_complaint": "Sakit kepala 3 hari, sebelah kanan, berdenyut",
  "symptom_timeline": [
    { "ts": "2026-05-25T10:00", "symptom": "Onset: throbbing right-side", "source": "patient_pa" },
    { "ts": "2026-05-26T08:00", "symptom": "Photophobia added", "source": "patient_pa" }
  ],
  "history_excerpts": [
    { "encounter_id": "ENC-2025-1115-042", "date": "2025-11-15", "relevant": "Migraine episode · responded to triptan" }
  ],
  "active_meds": [
    { "drug": "Amlodipine 5mg OD", "since": "2024-08" }
  ],
  "allergies": [
    { "substance": "Penicillin", "severity": "MAJOR", "reaction": "rash + urticaria" }
  ],
  "vitals_recent": {
    "bp": "138/86 (today)", "hr": 78, "temp": "36.8C", "weight": "78kg"
  },
  "cdss_hint_top3": [
    { "ddx": "Migraine without aura", "icd10": "G43.0", "confidence": 0.72, "citation": "MOH Headache CPG 2018" },
    { "ddx": "Tension-type headache", "icd10": "G44.2", "confidence": 0.18 },
    { "ddx": "Cluster headache", "icd10": "G44.0", "confidence": 0.10 }
  ],
  "recommended_questions": [
    "Tanya: ada aura visual/numbness sebelum sakit?",
    "Tanya: keturunan migraine?",
    "Tanya: trigger food/stress recent?"
  ],
  "generated_at": "2026-05-26T10:30:00+08:00",
  "patient_consent_to_share": true
}

6. 🔌 API + MCP

POST   /api/v1/briefings/compose                    # internal · trigger by event bus
       Body: { session_id, encounter_id?, doctor_id }
       Response: { briefing_id, ready_at }

GET    /api/v1/briefings/{briefing_id}              # doctor fetch
       Response: full JSON schema

POST   /api/v1/briefings/{briefing_id}/acknowledge  # doctor ack
       → audit log + patient app status update

GET    /api/v1/briefings/{briefing_id}/refresh      # force refresh
GET    /api/v1/briefings/{briefing_id}/diff         # FR-2.15
GET    /api/v1/briefings/{briefing_id}/pdf          # FR-2.12 export

WebSocket: /ws/doctor/{doctor_id}/briefings         # FR-2.6 real-time push

# MCP Tools
briefing_compose       Generate briefing from session + history
briefing_refresh       Re-compose with new symptom turn
patient_history_fetch  Aggregate prior encounters for context
cdss_hint              Top-3 DDx from symptom + history

7. 🔁 State Machine

┌──────────────────────┐
│ APPOINTMENT_BOOKED   │ trigger from M7 / M1
└──────────┬───────────┘
           ▼
┌──────────────────────┐
│ COMPOSE_PENDING      │ async LangGraph job queued
└──────────┬───────────┘
           ▼
┌──────────────────────┐
│ AGGREGATE_CONTEXT    │ fetch M1 session + 11-section profile + last 3 SOAP + vitals + ADR
└──────────┬───────────┘
           ▼
┌──────────────────────┐
│ LLM_GENERATE         │ Llama 70B compose structured briefing JSON
└──────────┬───────────┘
           ▼
┌──────────────────────┐
│ VALIDATE             │ schema validate · citation enforce · PII strip check
└──────────┬───────────┘
           ▼
┌──────────────────────┐
│ READY                │ persist to DB · push WebSocket to doctor
└──────────┬───────────┘
           ▼ (M1 update event)
┌──────────────────────┐
│ REFRESH              │ regenerate · increment version
└──────────┬───────────┘
           ▼ (doctor tap acknowledge)
┌──────────────────────┐
│ ACKNOWLEDGED         │ audit log · patient app notify
└──────────┬───────────┘
           ▼ (encounter sign-off)
┌──────────────────────┐
│ ARCHIVED             │ TTL 24h post sign-off · audio purge
└──────────────────────┘

8. 🤖 Agent Specification

  • Model: Llama 70B Q5 (clinical synthesis quality) · cloud burst gpt-4o
  • Memory: Working (Redis · briefing_pending) + Patient long-term (pgvector) + Procedural (CPG)
  • Tools: patient_history_fetch · cdss_hint · cpg_lookup · allergy_lookup

System Prompt (template)

You are M2 Pre-Consult Briefing composer dlm MediEco eco.

ROLE:
- Aggregate patient symptom intake (from M1) + medical history + recent vitals
- Compose CONCISE briefing (≤500 words) untuk doctor reading 30 saat
- Output strict JSON per schema
- DO NOT make diagnoses — provide CDSS hint as advisory only
- Highlight RED FLAGS prominently if present

INPUT:
- M1 symptom session full transcript + extractions
- 11-section Patient Profile (allergies · meds · chronic · primary care)
- Last 3 encounter SOAP excerpts (semantic-relevant)
- Recent 3-month vitals
- ADR registry

OUTPUT (strict JSON):
{ chief_complaint, symptom_timeline, triage, history_excerpts,
  active_meds, allergies, vitals_recent, cdss_hint_top3,
  recommended_questions, citations }

GUARDRAILS:
- PII strip applied (M9 middleware)
- Citation per CDSS suggestion (NPRA/MOH/SOP)
- Confidence score on triage + CDSS
- Recommended questions = open-ended, NOT diagnosis-leading

REMEMBER: Doctor scan 30 saat. Be concise. Highlight unusual/critical.

9. 🎨 UI/UX

  • Embedded di M4 Doctor PA encounter detail — top card, default expanded
  • Sections: Chief Complaint (heading) · Triage badge (color) · Timeline (visual) · History excerpts · Allergies (alert) · Active meds · Vitals · CDSS hint · Recommended questions
  • RED-flag triage = full-width red banner + sound alert
  • Citation cards collapsible
  • "Acknowledge" button bottom · disabled until 5s minimum read time
  • Mobile/tablet swipeable cards (FR-2.8)
  • PDF export button untuk offline reference
  • Visual diff badge bila refreshed (FR-2.15)

10. ✔️ Acceptance Criteria

  • AC-2.1: Briefing generated <3s post appointment booked event
  • AC-2.2: Doctor can scan + understand briefing <30s (UAT measured)
  • AC-2.3: 100% briefings include citations on CDSS hints
  • AC-2.4: RED-flag triage triggers visible alert + audio in <1s
  • AC-2.5: Real-time refresh on M1 update arrives within 10s
  • AC-2.6: Doctor cycle time savings ≥30% measured pilot vs baseline
  • AC-2.7: No PII leak in audit log (M9 enforced)
  • AC-2.8: Acknowledge event triggers patient app status update <5s
  • AC-2.9: Doc Zam clinical review: 20 sample briefings, ≥18/20 acceptable

11. 🧪 Test Plan

TierCasesCoverage
UnitBriefing schema validate · context aggregator · refresh diff calc · citation enforcer≥80%
IntegrationEvent-driven trigger flow · LLM round-trip · WebSocket push · DB persist100% paths
E2E3 scenarios: GREEN routine · YELLOW returning patient · RED escalation3/3 pass
Clinical20 briefing samples by Doc Zam clinical review≥18/20 acceptable
Load10 concurrent briefings · burst 30 in 1 minp99 <5s
MobileiPad Safari · Android Chrome · responsive 768/1024pxWCAG AA

12. 🔗 Dependencies

  • Hard: M1 PSPA (input source) · M4 DRPA (UI consumer) · M9 (audit + PII strip) · 11-section Patient model
  • Soft: M7 ADPA (manual trigger) · M6 ARXL (allergy registry)
  • Event: subscribes to appointment.booked + patient.symptom.turn

13. 🏃 Sprint Allocation

Sprint 2.1 · 5-18 Jul 2026 (1 minggu shared with M5)
  • Day 1-2: Briefing JSON schema + DB tables
  • Day 3-4: LangGraph agent · context aggregator · LLM call
  • Day 5: M4 UI integration · embed briefing card
  • Day 6: WebSocket real-time refresh
  • Day 7: Doc Zam review (20 samples) · final tweak
Capacity: 1 backend (Python+Laravel) · prompt engineer assist · Doc Zam advisory Day 7

14. ⚠️ Module-Specific Risks

RiskLikelihoodImpactMitigation
Briefing inaccurate (LLM miss key info)Med🟠 Doctor mistrust · revert to old workflowDoc Zam 20-sample review · iteration · doctor edit feedback loop
RED-flag missed in briefingLow🔴 Patient harmInherit M1 red-flag classifier · double-check at briefing layer · audit FN rate
Briefing overload (too long)Med🟢 Doctor skim · skill decayHard cap 500 words · scannable structure · UAT validate
Refresh storm (M1 high-frequency turn)Low🟢 Cost / latencyDebounce 30s · diff threshold · only refresh on material change
Stale briefing if doctor delayMed🟢 OutdatedVisual "freshness" indicator · auto-refresh on doctor open