ข้ามไปที่เนื้อหา

Database Schema - ระบบห้องตรวจแพทย์ผู้ป่วยนอก (OPD-CPOE-AI-Assist System)

Document Version: 1.0
Date: 29 สิงหาคม 2025
Integration with: MediTech Hospital Information System - MASTER_DATABASE_SCHEMA
Backend: Nest.js + TypeScript + Prisma ORM
Database: PostgreSQL 15+ + Redis 7+

เอกสารนี้รวบรวมโครงสร้างตารางฐานข้อมูล (Database Schema) ทั้งหมดสำหรับโมดูลระบบห้องตรวจแพทย์ผู้ป่วยนอกพร้อม CPOE AI Assist ที่ปรับให้สอดคล้องกับ Master Database Schema ของระบบ MediTech HIS เพื่อให้มีการบูรณาการที่สมบูรณ์แบบระหว่างโมดูลต่างๆ


Table of Contents

  1. ตาราง opd_visits
  2. ตาราง soap_notes
  3. ตาราง clinical_assessments
  4. ตาราง medical_orders
  5. ตาราง order_items
  6. ตาราง prescriptions
  7. ตาราง prescription_items
  8. ตาราง visit_media
  9. ตาราง clinical_templates
  10. ตาราง ai_parsing_logs
  11. ตาราง drug_interactions
  12. ตาราง allergy_alerts
  13. ตาราง clinical_guidelines
  14. ตาราง package_orders
  15. ตาราง visit_documents

SHARED FOUNDATION TABLES (จาก Master Schema)

หมายเหตุ: ตารางหลักเหล่านี้ถูกกำหนดใน MASTER_DATABASE_SCHEMA.md และใช้ร่วมกันทุกโมดูล

  • patients - Master Patient Index
  • medical_visits - Visit records (แชร์กับระบบอื่น)
  • users - Healthcare providers และ staff
  • departments และ clinics - Organization structure
  • audit_logs - System audit trail
  • digital_signatures - Electronic signatures

1. ตาราง opd_visits

ตารางสำหรับข้อมูล Visit เฉพาะของผู้ป่วยนอก - ขยายจาก medical_visits ใน Master Schema

CREATE TABLE opd_visits (
    -- Primary Key
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    visit_id UUID NOT NULL REFERENCES medical_visits(id) ON DELETE CASCADE,

    -- Patient and Provider Information
    patient_id UUID NOT NULL REFERENCES patients(id),
    attending_doctor_id UUID NOT NULL REFERENCES users(id),
    resident_doctor_id UUID REFERENCES users(id),
    primary_nurse_id UUID REFERENCES users(id),

    -- Visit Context
    clinic_id UUID REFERENCES clinics(id),
    visit_number VARCHAR(20) NOT NULL,
    visit_date DATE NOT NULL DEFAULT CURRENT_DATE,
    visit_time TIME NOT NULL DEFAULT CURRENT_TIME,

    -- Chief Complaint and Priority
    chief_complaint TEXT NOT NULL,
    present_illness TEXT,
    priority_level VARCHAR(20) DEFAULT 'routine' CHECK (priority_level IN ('emergency', 'urgent', 'priority', 'routine')),

    -- Vital Signs (ตาม TOR 4.1.3)
    systolic_bp INTEGER, -- ความดันโลหิตตัวบน
    diastolic_bp INTEGER, -- ความดันโลหิตตัวล่าง  
    heart_rate INTEGER, -- อัตราการเต้นของหัวใจ
    respiratory_rate INTEGER, -- อัตราการหายใจ
    temperature DECIMAL(4,1), -- อุณหภูมิร่างกาย
    oxygen_saturation INTEGER, -- SpO2
    weight DECIMAL(5,2), -- น้ำหนัก (kg)
    height DECIMAL(5,2), -- ส่วนสูง (cm)
    bmi DECIMAL(4,1) GENERATED ALWAYS AS (
        CASE WHEN height > 0 THEN weight / POWER(height/100, 2) ELSE NULL END
    ) STORED, -- BMI คำนวณอัตโนมัติ

    -- Clinical Status
    visit_status VARCHAR(20) DEFAULT 'checked_in' CHECK (visit_status IN (
        'checked_in', 'in_examination', 'waiting_results', 'completed', 'cancelled'
    )),
    examination_completed BOOLEAN DEFAULT FALSE,
    orders_completed BOOLEAN DEFAULT FALSE,

    -- Timestamps
    checked_in_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    examination_started_at TIMESTAMP WITH TIME ZONE,
    examination_completed_at TIMESTAMP WITH TIME ZONE,

    -- Standardized Audit Fields
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    created_by UUID NOT NULL REFERENCES users(id),
    updated_by UUID REFERENCES users(id),

    -- Soft Delete Pattern
    deleted_at TIMESTAMP WITH TIME ZONE,
    deleted_by UUID REFERENCES users(id),
    is_active BOOLEAN DEFAULT TRUE,

    -- Constraints
    CONSTRAINT chk_bp_values CHECK (
        systolic_bp IS NULL OR (systolic_bp BETWEEN 50 AND 300)
    ),
    CONSTRAINT chk_diastolic_values CHECK (
        diastolic_bp IS NULL OR (diastolic_bp BETWEEN 30 AND 200)
    ),
    CONSTRAINT chk_vital_ranges CHECK (
        heart_rate IS NULL OR (heart_rate BETWEEN 20 AND 250) AND
        respiratory_rate IS NULL OR (respiratory_rate BETWEEN 5 AND 60) AND
        temperature IS NULL OR (temperature BETWEEN 30.0 AND 45.0) AND
        oxygen_saturation IS NULL OR (oxygen_saturation BETWEEN 50 AND 100)
    )
);

คำอธิบายฟิลด์ (Field Descriptions):

Field Type Constraints คำอธิบาย
id UUID PRIMARY KEY รหัสเฉพาะของข้อมูล OPD Visit
visit_id UUID NOT NULL, FK รหัส Medical Visit หลักจาก Master Schema
patient_id UUID NOT NULL, FK รหัสผู้ป่วยจาก Master Patient Index
attending_doctor_id UUID NOT NULL, FK รหัสแพทย์เจ้าของไข้หลัก
resident_doctor_id UUID FK รหัสแพทย์ประจำบ้าน (ถ้ามี)
visit_number VARCHAR(20) NOT NULL หมายเลข Visit (เชื่อมโยงกับระบบคิว)
chief_complaint TEXT NOT NULL อาการสำคัญที่ผู้ป่วยมาด้วย
present_illness TEXT ประวัติการเจ็บป่วยในครั้งนี้
priority_level VARCHAR(20) CHECK ระดับความสำคัญ (emergency, urgent, priority, routine)
systolic_bp INTEGER CHECK ความดันโลหิตตัวบน (mmHg)
diastolic_bp INTEGER CHECK ความดันโลหิตตัวล่าง (mmHg)
heart_rate INTEGER CHECK อัตราการเต้นของหัวใจ (bpm)
respiratory_rate INTEGER CHECK อัตราการหายใจ (per minute)
temperature DECIMAL(4,1) CHECK อุณหภูมิร่างกาย (°C)
oxygen_saturation INTEGER CHECK ระดับออกซิเจนในเลือด (%)
weight DECIMAL(5,2) น้ำหนัก (กิโลกรัม)
height DECIMAL(5,2) ส่วนสูง (เซนติเมตร)
bmi DECIMAL(4,1) GENERATED ดัชนีมวลกาย (คำนวณอัตโนมัติ)
visit_status VARCHAR(20) CHECK สถานะการตรวจ
examination_completed BOOLEAN DEFAULT FALSE สถานะการตรวจเสร็จสิ้น

Indexes:

-- Performance indexes
CREATE INDEX idx_opd_visits_patient ON opd_visits(patient_id, visit_date DESC);
CREATE INDEX idx_opd_visits_doctor ON opd_visits(attending_doctor_id, visit_date DESC);
CREATE INDEX idx_opd_visits_clinic ON opd_visits(clinic_id, visit_date DESC);
CREATE INDEX idx_opd_visits_status ON opd_visits(visit_status, visit_date);
CREATE INDEX idx_opd_visits_priority ON opd_visits(priority_level, checked_in_at);
CREATE INDEX idx_opd_visits_completion ON opd_visits(examination_completed, orders_completed);

2. ตาราง soap_notes

ตารางสำหรับบันทึกผลตรวจแบบ SOAP Note (ตาม TOR 4.2)

CREATE TABLE soap_notes (
    -- Primary Key
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    opd_visit_id UUID NOT NULL REFERENCES opd_visits(id) ON DELETE CASCADE,

    -- SOAP Components (ตาม REQ-OPD-009)
    subjective TEXT, -- S: อาการที่ผู้ป่วยบอก
    objective TEXT, -- O: ผลการตรวจร่างกาย
    assessment TEXT, -- A: การวินิจฉัย
    plan TEXT, -- P: แผนการรักษา

    -- Additional Clinical Data
    review_of_systems JSONB, -- Review of Systems checklist
    physical_examination JSONB, -- Structured physical exam data
    clinical_impression TEXT, -- Clinical impression summary

    -- Template and Version Control
    template_id UUID REFERENCES clinical_templates(id),
    template_version INTEGER DEFAULT 1,
    note_version INTEGER DEFAULT 1,

    -- AI Processing Status (เชื่อมกับ CPOE AI)
    ai_processed BOOLEAN DEFAULT FALSE,
    ai_processing_status VARCHAR(20) DEFAULT 'pending' CHECK (ai_processing_status IN (
        'pending', 'processing', 'completed', 'failed', 'manual_override'
    )),
    ai_extracted_orders JSONB, -- AI extracted orders from Plan
    ai_confidence_score DECIMAL(3,2), -- AI confidence level (0.00-1.00)

    -- Documentation Status
    is_completed BOOLEAN DEFAULT FALSE,
    is_locked BOOLEAN DEFAULT FALSE, -- Lock after completion (ตาม TOR 4.2.15)
    completion_timestamp TIMESTAMP WITH TIME ZONE,
    locked_at TIMESTAMP WITH TIME ZONE,
    locked_by UUID REFERENCES users(id),

    -- Standardized Audit Fields
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    created_by UUID NOT NULL REFERENCES users(id),
    updated_by UUID REFERENCES users(id),

    -- Soft Delete Pattern
    deleted_at TIMESTAMP WITH TIME ZONE,
    deleted_by UUID REFERENCES users(id),
    is_active BOOLEAN DEFAULT TRUE,

    -- Edit Control (ตาม REQ-OPD-027)
    edit_reason TEXT, -- เหตุผลการแก้ไข
    original_soap_id UUID REFERENCES soap_notes(id), -- อ้างอิงถึง SOAP เดิม
    superseded_at TIMESTAMP WITH TIME ZONE,
    superseded_by UUID REFERENCES users(id)
);

คำอธิบายฟิลด์ (Field Descriptions):

Field Type Constraints คำอธิบาย
id UUID PRIMARY KEY รหัสเฉพาะของ SOAP Note
opd_visit_id UUID NOT NULL, FK รหัส OPD Visit ที่เชื่อมโยง
subjective TEXT S: อาการที่ผู้ป่วยบอก
objective TEXT O: ผลการตรวจร่างกาย
assessment TEXT A: การวินิจฉัยและการประเมิน
plan TEXT P: แผนการรักษาและคำสั่ง
review_of_systems JSONB ข้อมูล Review of Systems แบบ structured
physical_examination JSONB ข้อมูลการตรวจร่างกายแบบ structured
template_id UUID FK รหัส Template ที่ใช้ (ถ้ามี)
ai_processed BOOLEAN DEFAULT FALSE สถานะการประมวลผลด้วย AI
ai_processing_status VARCHAR(20) CHECK สถานะการประมวลผลโดย CPOE AI
ai_extracted_orders JSONB คำสั่งที่ AI สกัดจาก Plan
ai_confidence_score DECIMAL(3,2) ระดับความมั่นใจของ AI (0-1)
is_completed BOOLEAN DEFAULT FALSE สถานะการเสร็จสิ้น
is_locked BOOLEAN DEFAULT FALSE สถานะการล็อค (ไม่ให้แก้ไข)
edit_reason TEXT เหตุผลในการแก้ไข
original_soap_id UUID FK รหัส SOAP เดิม (กรณีแก้ไข)

Indexes:

-- Performance indexes  
CREATE INDEX idx_soap_notes_visit ON soap_notes(opd_visit_id);
CREATE INDEX idx_soap_notes_created ON soap_notes(created_at DESC);
CREATE INDEX idx_soap_notes_status ON soap_notes(is_completed, is_locked);
CREATE INDEX idx_soap_notes_ai_status ON soap_notes(ai_processing_status, ai_processed);
CREATE INDEX idx_soap_notes_template ON soap_notes(template_id) WHERE template_id IS NOT NULL;
CREATE INDEX idx_soap_notes_original ON soap_notes(original_soap_id) WHERE original_soap_id IS NOT NULL;

3. ตาราง clinical_assessments

ตารางสำหรับการวินิจฉัยและรหัส ICD-10 (ตาม TOR 4.2.7)

CREATE TABLE clinical_assessments (
    -- Primary Key
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    soap_note_id UUID NOT NULL REFERENCES soap_notes(id) ON DELETE CASCADE,

    -- Diagnosis Information
    diagnosis_text TEXT NOT NULL, -- ข้อความการวินิจฉัยต้นฉบับ
    icd10_code VARCHAR(10), -- รหัส ICD-10
    icd10_description TEXT, -- คำอธิบาย ICD-10

    -- Diagnosis Classification
    diagnosis_type VARCHAR(20) NOT NULL CHECK (diagnosis_type IN (
        'primary', 'secondary', 'differential', 'rule_out', 'chronic', 'acute'
    )),

    -- Clinical Context
    severity VARCHAR(10) CHECK (severity IN ('mild', 'moderate', 'severe', 'critical')),
    certainty VARCHAR(15) CHECK (certainty IN ('confirmed', 'probable', 'possible', 'ruled_out')),
    onset_type VARCHAR(10) CHECK (onset_type IN ('acute', 'chronic', 'subacute')),

    -- AI Processing
    ai_suggested BOOLEAN DEFAULT FALSE, -- AI แนะนำหรือไม่
    ai_confidence DECIMAL(3,2), -- ความมั่นใจของ AI suggestion
    physician_verified BOOLEAN DEFAULT FALSE, -- แพทย์ยืนยันแล้ว

    -- Sequence and Status
    sequence_order INTEGER DEFAULT 1,

    -- Standardized Audit Fields
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    created_by UUID NOT NULL REFERENCES users(id),
    updated_by UUID REFERENCES users(id),

    -- Soft Delete Pattern
    deleted_at TIMESTAMP WITH TIME ZONE,
    deleted_by UUID REFERENCES users(id),
    is_active BOOLEAN DEFAULT TRUE
);

คำอธิบายฟิลด์ (Field Descriptions):

Field Type Constraints คำอธิบาย
diagnosis_text TEXT NOT NULL ข้อความการวินิจฉัยที่แพทย์เขียน
icd10_code VARCHAR(10) รหัส ICD-10 ที่แปลงได้
icd10_description TEXT คำอธิบาย ICD-10
diagnosis_type VARCHAR(20) NOT NULL, CHECK ประเภทการวินิจฉัย (primary, secondary, etc.)
severity VARCHAR(10) CHECK ระดับความรุนแรง
certainty VARCHAR(15) CHECK ระดับความแน่ใจ
ai_suggested BOOLEAN DEFAULT FALSE AI แนะนำรหัสนี้หรือไม่
physician_verified BOOLEAN DEFAULT FALSE แพทย์ยืนยันแล้ว

4. ตาราง medical_orders

ตารางหลักสำหรับคำสั่งทางการแพทย์ทั้งหมด (ตาม TOR 4.2.5)

CREATE TABLE medical_orders (
    -- Primary Key
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    soap_note_id UUID NOT NULL REFERENCES soap_notes(id) ON DELETE CASCADE,
    opd_visit_id UUID NOT NULL REFERENCES opd_visits(id),

    -- Order Classification
    order_type VARCHAR(20) NOT NULL CHECK (order_type IN (
        'medication', 'laboratory', 'radiology', 'procedure', 'consult', 
        'referral', 'admission', 'appointment', 'diet', 'activity',
        'iv_fluid', 'injection', 'nursing', 'functional_test', 
        'mental_test', 'certificate', 'isolation'
    )),
    order_subtype VARCHAR(30), -- ประเภทย่อย เช่น "prescription", "stat", "routine"

    -- Order Details
    order_text TEXT NOT NULL, -- ข้อความคำสั่งต้นฉบับจาก Plan
    structured_order JSONB, -- คำสั่งที่ parsed แล้ว

    -- Priority and Timing
    priority VARCHAR(10) DEFAULT 'routine' CHECK (priority IN ('stat', 'urgent', 'routine')),
    order_date DATE NOT NULL DEFAULT CURRENT_DATE,
    order_time TIME NOT NULL DEFAULT CURRENT_TIME,
    start_date DATE,
    end_date DATE,

    -- Cost Information (ตาม TOR 4.2.6)
    total_cost DECIMAL(10,2),
    insurance_covered DECIMAL(10,2),
    patient_cost DECIMAL(10,2),
    cost_calculated_at TIMESTAMP WITH TIME ZONE,

    -- AI Processing
    ai_extracted BOOLEAN DEFAULT FALSE, -- AI สกัดจาก Plan text
    ai_confidence DECIMAL(3,2),
    ai_parsing_log_id UUID REFERENCES ai_parsing_logs(id),

    -- Status Management
    order_status VARCHAR(15) DEFAULT 'ordered' CHECK (order_status IN (
        'ordered', 'confirmed', 'in_progress', 'completed', 'cancelled', 'expired'
    )),
    cancelled_reason TEXT,

    -- Provider Information
    ordering_provider_id UUID NOT NULL REFERENCES users(id),
    confirming_provider_id UUID REFERENCES users(id),

    -- Standardized Audit Fields
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    created_by UUID NOT NULL REFERENCES users(id),
    updated_by UUID REFERENCES users(id),

    -- Additional Timestamps
    confirmed_at TIMESTAMP WITH TIME ZONE,
    cancelled_at TIMESTAMP WITH TIME ZONE,

    -- Soft Delete Pattern
    deleted_at TIMESTAMP WITH TIME ZONE,
    deleted_by UUID REFERENCES users(id),
    is_active BOOLEAN DEFAULT TRUE,

    -- Constraints
    CONSTRAINT chk_cost_logic CHECK (
        total_cost IS NULL OR 
        (total_cost = COALESCE(insurance_covered, 0) + COALESCE(patient_cost, 0))
    )
);

คำอธิบายฟิลด์ (Field Descriptions):

Field Type Constraints คำอธิบาย
order_type VARCHAR(20) NOT NULL, CHECK ประเภทคำสั่งหลัก (medication, laboratory, etc.)
order_subtype VARCHAR(30) ประเภทย่อย
order_text TEXT NOT NULL ข้อความคำสั่งต้นฉบับ
structured_order JSONB คำสั่งที่ parsed และ structured แล้ว
total_cost DECIMAL(10,2) ค่าใช้จ่ายรวม
insurance_covered DECIMAL(10,2) จำนวนที่สิทธิคุ้มครอง
patient_cost DECIMAL(10,2) จำนวนที่ผู้ป่วยต้องจ่ายเอง
ai_extracted BOOLEAN DEFAULT FALSE คำสั่งนี้มาจาก AI extraction
order_status VARCHAR(15) CHECK สถานะคำสั่ง

5. ตาราง order_items

ตารางสำหรับรายการย่อยของแต่ละคำสั่ง

CREATE TABLE order_items (
    -- Primary Key  
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    medical_order_id UUID NOT NULL REFERENCES medical_orders(id) ON DELETE CASCADE,

    -- Item Details
    item_type VARCHAR(30) NOT NULL, -- drug, test, procedure, etc.
    item_code VARCHAR(50), -- รหัสยา/รหัสการตรวจ
    item_name TEXT NOT NULL,
    item_description TEXT,

    -- Dosage and Instructions (สำหรับยา)
    dosage VARCHAR(100), -- ขนาด เช่น "500mg", "1 tablet"
    frequency VARCHAR(50), -- ความถี่ เช่น "BID", "TID", "q6h"
    route VARCHAR(20), -- ทาง เช่น "PO", "IV", "IM"
    duration VARCHAR(20), -- ระยะเวลา เช่น "7 days", "until finished"
    special_instructions TEXT, -- คำแนะนำพิเศษ

    -- Quantity and Dispensing
    quantity DECIMAL(10,3), -- จำนวน
    unit VARCHAR(20), -- หน่วย
    refill_count INTEGER DEFAULT 0, -- จำนวนครั้งที่เติมได้

    -- Clinical Context
    indication TEXT, -- ข้อบ่งชี้การใช้
    contraindication TEXT, -- ข้อห้ามใช้

    -- Cost per Item
    unit_cost DECIMAL(10,2),
    total_item_cost DECIMAL(10,2),

    -- Status
    item_status VARCHAR(15) DEFAULT 'ordered' CHECK (item_status IN (
        'ordered', 'dispensed', 'administered', 'completed', 'cancelled'
    )),

    -- Standardized Audit Fields
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    created_by UUID NOT NULL REFERENCES users(id),
    updated_by UUID REFERENCES users(id),

    -- Soft Delete Pattern
    deleted_at TIMESTAMP WITH TIME ZONE,
    deleted_by UUID REFERENCES users(id),
    is_active BOOLEAN DEFAULT TRUE
);

6. ตาราง prescriptions

ตารางสำหรับใบสั่งยาเฉพาะ (แยกจาก medical_orders)

CREATE TABLE prescriptions (
    -- Primary Key
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    opd_visit_id UUID NOT NULL REFERENCES opd_visits(id),
    medical_order_id UUID REFERENCES medical_orders(id),

    -- Prescription Number
    prescription_number VARCHAR(20) UNIQUE NOT NULL,
    prescription_date DATE NOT NULL DEFAULT CURRENT_DATE,

    -- Provider Information
    prescribing_doctor_id UUID NOT NULL REFERENCES users(id),
    supervising_doctor_id UUID REFERENCES users(id), -- สำหรับแพทย์ประจำบ้าน

    -- Patient Safety (ตาม TOR 4.2.11-4.2.12)
    allergy_checked BOOLEAN DEFAULT FALSE,
    allergy_override_reason TEXT,
    drug_interaction_checked BOOLEAN DEFAULT FALSE,
    interaction_override_reason TEXT,

    -- Special Authorization (ตาม TOR 4.2.13-4.2.14)
    requires_authorization BOOLEAN DEFAULT FALSE,
    authorization_form_id UUID, -- Link to authorization document
    authorization_status VARCHAR(20) DEFAULT 'not_required' CHECK (authorization_status IN (
        'not_required', 'pending', 'approved', 'rejected'
    )),

    -- Digital Signature
    digital_signature_id UUID REFERENCES digital_signatures(id),
    signed_at TIMESTAMP WITH TIME ZONE,

    -- Prescription Status
    prescription_status VARCHAR(15) DEFAULT 'draft' CHECK (prescription_status IN (
        'draft', 'signed', 'sent_to_pharmacy', 'dispensed', 'cancelled'
    )),

    -- Cost Summary
    total_prescription_cost DECIMAL(10,2),
    insurance_coverage DECIMAL(10,2),
    patient_payment DECIMAL(10,2),

    -- Standardized Audit Fields
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    created_by UUID NOT NULL REFERENCES users(id),
    updated_by UUID REFERENCES users(id),

    -- Soft Delete Pattern
    deleted_at TIMESTAMP WITH TIME ZONE,
    deleted_by UUID REFERENCES users(id),
    is_active BOOLEAN DEFAULT TRUE
);

7. ตาราง prescription_items

ตารางสำหรับรายการยาในใบสั่งยา

CREATE TABLE prescription_items (
    -- Primary Key
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    prescription_id UUID NOT NULL REFERENCES prescriptions(id) ON DELETE CASCADE,

    -- Drug Information
    drug_code VARCHAR(50) NOT NULL, -- รหัสยาในระบบ
    drug_name TEXT NOT NULL,
    generic_name TEXT,
    strength VARCHAR(50), -- ความแรง เช่น "500mg"
    dosage_form VARCHAR(30), -- รูปแบบยา เช่น "tablet", "capsule", "syrup"

    -- Prescription Details
    prescribed_dose VARCHAR(100) NOT NULL, -- ขนาดที่สั่ง
    frequency VARCHAR(50) NOT NULL, -- ความถี่การใช้
    route VARCHAR(20) DEFAULT 'PO', -- ทางการใช้ยา
    duration VARCHAR(30), -- ระยะเวลาการใช้
    quantity_prescribed DECIMAL(10,3) NOT NULL, -- จำนวนที่สั่ง
    quantity_unit VARCHAR(20) NOT NULL, -- หน่วยจำนวน

    -- Clinical Instructions
    administration_instructions TEXT, -- วิธีการใช้
    food_instructions VARCHAR(50), -- การทานเกี่ยวกับอาหาร (before/after/with meal)
    special_precautions TEXT, -- ข้อควรระวัง

    -- Safety Checks
    allergy_risk VARCHAR(20) CHECK (allergy_risk IN ('none', 'low', 'moderate', 'high')),
    interaction_risk VARCHAR(20) CHECK (interaction_risk IN ('none', 'low', 'moderate', 'high')),
    contraindication_checked BOOLEAN DEFAULT FALSE,

    -- Dispensing Information
    substitute_allowed BOOLEAN DEFAULT TRUE,
    refill_count INTEGER DEFAULT 0,
    max_refills INTEGER DEFAULT 0,

    -- Cost per Drug
    unit_price DECIMAL(10,2),
    total_cost DECIMAL(10,2),
    insurance_covered DECIMAL(10,2),
    patient_cost DECIMAL(10,2),

    -- Status
    item_status VARCHAR(15) DEFAULT 'prescribed' CHECK (item_status IN (
        'prescribed', 'verified', 'dispensed', 'cancelled'
    )),

    -- Standardized Audit Fields
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    created_by UUID NOT NULL REFERENCES users(id),
    updated_by UUID REFERENCES users(id),

    -- Soft Delete Pattern
    deleted_at TIMESTAMP WITH TIME ZONE,
    deleted_by UUID REFERENCES users(id),
    is_active BOOLEAN DEFAULT TRUE
);

8. ตาราง visit_media

ตารางสำหรับจัดการไฟล์มัลติมีเดีย (ตาม TOR 4.2.2-4.2.4)

CREATE TABLE visit_media (
    -- Primary Key
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    opd_visit_id UUID NOT NULL REFERENCES opd_visits(id) ON DELETE CASCADE,
    soap_note_id UUID REFERENCES soap_notes(id),

    -- Media Classification
    media_type VARCHAR(20) NOT NULL CHECK (media_type IN (
        'photo', 'video', 'sketch', 'document', 'audio'
    )),
    media_category VARCHAR(30), -- clinical_photo, body_map, procedure_video, etc.

    -- File Information
    original_filename VARCHAR(255) NOT NULL,
    stored_filename VARCHAR(255) NOT NULL UNIQUE,
    file_path VARCHAR(500) NOT NULL,
    file_size BIGINT NOT NULL,
    mime_type VARCHAR(100) NOT NULL,
    file_extension VARCHAR(10) NOT NULL,

    -- Media Properties
    width INTEGER, -- สำหรับรูปภาพ/วิดีโอ
    height INTEGER, -- สำหรับรูปภาพ/วิดีโอ
    duration_seconds INTEGER, -- สำหรับวิดีโอ/เสียง

    -- Clinical Context
    body_part VARCHAR(50), -- ส่วนของร่างกาย
    clinical_finding TEXT, -- สิ่งที่พบทางคลินิก
    description TEXT, -- คำอธิบายเพิ่มเติม

    -- Image Annotation (ตาม TOR 4.2.3)
    has_annotations BOOLEAN DEFAULT FALSE,
    annotations JSONB, -- JSON สำหรับเก็บ annotation data
    annotation_tools_used VARCHAR(100), -- เครื่องมือที่ใช้ในการ annotate

    -- Sketch Data (ตาม TOR 4.2.4)
    sketch_data JSONB, -- JSON สำหรับ drawing data
    canvas_width INTEGER,
    canvas_height INTEGER,

    -- Privacy and Access
    privacy_level VARCHAR(20) DEFAULT 'clinical' CHECK (privacy_level IN (
        'public', 'clinical', 'restricted', 'confidential'
    )),
    requires_consent BOOLEAN DEFAULT FALSE,
    patient_consent_obtained BOOLEAN DEFAULT FALSE,

    -- Processing Status
    processing_status VARCHAR(15) DEFAULT 'uploaded' CHECK (processing_status IN (
        'uploading', 'uploaded', 'processing', 'ready', 'failed'
    )),
    compression_applied BOOLEAN DEFAULT FALSE,
    thumbnail_generated BOOLEAN DEFAULT FALSE,
    thumbnail_path VARCHAR(500),

    -- Audit and Version
    uploaded_by UUID NOT NULL REFERENCES users(id),
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,

    -- Constraints
    CONSTRAINT chk_media_dimensions CHECK (
        (media_type = 'photo' AND width > 0 AND height > 0) OR
        (media_type = 'video' AND width > 0 AND height > 0 AND duration_seconds > 0) OR
        (media_type NOT IN ('photo', 'video'))
    )
);

9. ตาราง clinical_templates

ตารางสำหรับเก็บ Template ต่างๆ (ตาม TOR 4.2.2)

CREATE TABLE clinical_templates (
    -- Primary Key
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),

    -- Template Information
    template_name VARCHAR(100) NOT NULL,
    template_description TEXT,
    template_type VARCHAR(30) NOT NULL CHECK (template_type IN (
        'soap_note', 'physical_exam', 'review_of_systems', 'procedure_note',
        'discharge_summary', 'referral_letter', 'certificate'
    )),

    -- Specialty and Context
    specialty VARCHAR(50), -- Internal Medicine, Surgery, Pediatrics, etc.
    condition_specific VARCHAR(100), -- DM, HT, COPD, etc.

    -- Template Content
    template_structure JSONB NOT NULL, -- JSON structure ของ template
    default_values JSONB, -- ค่า default
    validation_rules JSONB, -- กฎการตรวจสอบ

    -- Template Settings
    is_active BOOLEAN DEFAULT TRUE,
    is_public BOOLEAN DEFAULT FALSE, -- แชร์ให้แพทย์อื่นได้หรือไม่
    usage_count INTEGER DEFAULT 0, -- จำนวนครั้งที่ใช้

    -- Version Control
    version INTEGER DEFAULT 1,
    parent_template_id UUID REFERENCES clinical_templates(id),

    -- Ownership
    created_by UUID NOT NULL REFERENCES users(id),
    shared_with_department_id UUID REFERENCES departments(id),

    -- Standardized Audit Fields
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    created_by UUID NOT NULL REFERENCES users(id),
    updated_by UUID REFERENCES users(id),

    -- Soft Delete Pattern
    deleted_at TIMESTAMP WITH TIME ZONE,
    deleted_by UUID REFERENCES users(id),
    is_active BOOLEAN DEFAULT TRUE,
    last_used_at TIMESTAMP WITH TIME ZONE
);

10. ตาราง ai_parsing_logs

ตารางสำหรับบันทึกการทำงานของ CPOE AI (ตาม TOR 4.2.5)

CREATE TABLE ai_parsing_logs (
    -- Primary Key
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    soap_note_id UUID NOT NULL REFERENCES soap_notes(id) ON DELETE CASCADE,

    -- Input Data
    input_text TEXT NOT NULL, -- ข้อความ Plan ต้นฉบับ
    input_type VARCHAR(20) DEFAULT 'plan_text', -- ประเภท input

    -- Processing Information
    processing_started_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    processing_completed_at TIMESTAMP WITH TIME ZONE,
    processing_duration_ms INTEGER,

    -- AI Model Information
    ai_model_name VARCHAR(50),
    ai_model_version VARCHAR(20),
    api_endpoint VARCHAR(200),

    -- Processing Results
    parsing_status VARCHAR(15) DEFAULT 'processing' CHECK (parsing_status IN (
        'processing', 'completed', 'failed', 'timeout', 'manual_override'
    )),

    -- Extracted Orders
    extracted_orders JSONB, -- คำสั่งที่ AI สกัดได้
    confidence_scores JSONB, -- คะแนนความมั่นใจแต่ละคำสั่ง

    -- ICD Code Suggestions (ตาม TOR 4.2.7-4.2.8)
    suggested_icd10 JSONB, -- รหัส ICD-10 ที่แนะนำ
    suggested_icd9 JSONB, -- รหัส ICD-9 ที่แนะนำ

    -- Cost Calculations (ตาม TOR 4.2.6)
    calculated_costs JSONB, -- ค่าใช้จ่ายที่คำนวณได้
    cost_calculation_method VARCHAR(50),

    -- Error Handling
    error_message TEXT,
    error_code VARCHAR(20),
    retry_count INTEGER DEFAULT 0,

    -- Manual Override
    manual_override_by UUID REFERENCES users(id),
    manual_override_reason TEXT,
    manual_override_at TIMESTAMP WITH TIME ZONE,

    -- Quality Metrics
    processing_accuracy DECIMAL(3,2), -- ความแม่นยำหลังจากแพทย์ review
    physician_feedback TEXT, -- ความเห็นของแพทย์
    feedback_rating INTEGER CHECK (feedback_rating BETWEEN 1 AND 5),

    -- Standardized Audit Fields
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    created_by UUID NOT NULL REFERENCES users(id),
    updated_by UUID REFERENCES users(id),

    -- Soft Delete Pattern
    deleted_at TIMESTAMP WITH TIME ZONE,
    deleted_by UUID REFERENCES users(id),
    is_active BOOLEAN DEFAULT TRUE
);

11. ตาราง drug_interactions

ตารางสำหรับตรวจสอบปฏิกิริยาระหว่างยา (ตาม TOR 4.2.12)

CREATE TABLE drug_interactions (
    -- Primary Key
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),

    -- Drug Pair
    drug_1_code VARCHAR(50) NOT NULL,
    drug_1_name TEXT NOT NULL,
    drug_2_code VARCHAR(50) NOT NULL,  
    drug_2_name TEXT NOT NULL,

    -- Interaction Details
    interaction_type VARCHAR(20) NOT NULL CHECK (interaction_type IN (
        'major', 'moderate', 'minor', 'contraindicated'
    )),
    severity_level INTEGER NOT NULL CHECK (severity_level BETWEEN 1 AND 5),

    -- Clinical Information
    mechanism TEXT, -- กลไกการเกิดปฏิกิริยา
    clinical_effect TEXT, -- ผลทางคลินิก
    management_recommendation TEXT, -- คำแนะนำการจัดการ

    -- Evidence and References
    evidence_level VARCHAR(15) CHECK (evidence_level IN (
        'established', 'probable', 'suspected', 'theoretical'
    )),
    literature_references TEXT,

    -- Timing and Context
    onset_time VARCHAR(30), -- เวลาเริ่มมีผล
    duration VARCHAR(30), -- ระยะเวลาของผล

    -- System Management
    is_active BOOLEAN DEFAULT TRUE,
    alert_enabled BOOLEAN DEFAULT TRUE,
    override_allowed BOOLEAN DEFAULT TRUE,

    -- Standardized Audit Fields
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    created_by UUID NOT NULL REFERENCES users(id),
    updated_by UUID REFERENCES users(id),

    -- Soft Delete Pattern
    deleted_at TIMESTAMP WITH TIME ZONE,
    deleted_by UUID REFERENCES users(id),
    is_active BOOLEAN DEFAULT TRUE,

    -- Ensure unique drug pairs (both directions)
    CONSTRAINT uq_drug_interaction_pair UNIQUE (drug_1_code, drug_2_code)
);

12. ตาราง allergy_alerts

ตารางสำหรับตรวจสอบการแพ้ยา (ตาม TOR 4.2.11)

CREATE TABLE allergy_alerts (
    -- Primary Key
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    prescription_item_id UUID NOT NULL REFERENCES prescription_items(id),
    patient_id UUID NOT NULL REFERENCES patients(id),

    -- Allergy Information
    allergen_type VARCHAR(20) NOT NULL CHECK (allergen_type IN (
        'drug', 'food', 'environmental', 'contrast', 'latex'
    )),
    allergen_code VARCHAR(50), -- รหัสของสารที่แพ้
    allergen_name TEXT NOT NULL, -- ชื่อสารที่แพ้

    -- Alert Details  
    alert_severity VARCHAR(15) NOT NULL CHECK (alert_severity IN (
        'mild', 'moderate', 'severe', 'life_threatening'
    )),
    reaction_type VARCHAR(30), -- anaphylaxis, rash, nausea, etc.

    -- Clinical Context
    previous_reaction_description TEXT,
    reaction_date DATE,
    cross_reactivity_risk BOOLEAN DEFAULT FALSE,

    -- Alert Status
    alert_status VARCHAR(15) DEFAULT 'active' CHECK (alert_status IN (
        'active', 'acknowledged', 'overridden', 'resolved'
    )),

    -- Override Information
    override_reason TEXT,
    override_by UUID REFERENCES users(id),
    override_at TIMESTAMP WITH TIME ZONE,

    -- Audit
    detected_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    created_by UUID REFERENCES users(id),
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

13. ตาราง clinical_guidelines

ตารางสำหรับเก็บแนวทางการรักษาและ Clinical Decision Support

CREATE TABLE clinical_guidelines (
    -- Primary Key
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),

    -- Guideline Information
    guideline_name VARCHAR(200) NOT NULL,
    guideline_description TEXT,
    guideline_type VARCHAR(30) NOT NULL CHECK (guideline_type IN (
        'treatment', 'diagnostic', 'preventive', 'drug_dosing', 'safety'
    )),

    -- Clinical Context
    condition_icd10 VARCHAR(10), -- ICD-10 ที่เกี่ยวข้อง
    specialty VARCHAR(50), -- แผนกที่เกี่ยวข้อง
    patient_population TEXT, -- กลุ่มผู้ป่วยที่เหมาะสม

    -- Guideline Content
    criteria JSONB NOT NULL, -- เงื่อนไขการใช้ guideline
    recommendations JSONB NOT NULL, -- คำแนะนำ
    contraindications JSONB, -- ข้อห้าม

    -- Evidence and Authority
    evidence_level VARCHAR(10) CHECK (evidence_level IN ('A', 'B', 'C', 'D')),
    source_organization VARCHAR(100), -- องค์กรที่ออก guideline
    publication_date DATE,
    last_updated DATE,

    -- System Integration
    automated_alerts BOOLEAN DEFAULT FALSE, -- แจ้งเตือนอัตโนมัติ
    integration_rules JSONB, -- กฎการบูรณาการกับระบบ

    -- Status
    is_active BOOLEAN DEFAULT TRUE,
    effective_date DATE NOT NULL,
    expiry_date DATE,

    -- Standardized Audit Fields
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    created_by UUID NOT NULL REFERENCES users(id),
    updated_by UUID REFERENCES users(id),

    -- Soft Delete Pattern
    deleted_at TIMESTAMP WITH TIME ZONE,
    deleted_by UUID REFERENCES users(id),
    is_active BOOLEAN DEFAULT TRUE
);

14. ตาราง package_orders

ตารางสำหรับชุดคำสั่งแพทย์ที่บันทึกไว้ (ตาม TOR 4.2.10)

CREATE TABLE package_orders (
    -- Primary Key
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),

    -- Package Information
    package_name VARCHAR(100) NOT NULL,
    package_description TEXT,
    package_type VARCHAR(30) NOT NULL CHECK (package_type IN (
        'disease_specific', 'procedure_based', 'health_screening', 'follow_up', 'emergency'
    )),

    -- Clinical Context
    target_diagnosis VARCHAR(200), -- การวินิจฉัยที่เป็นเป้าหมาย
    target_icd10 VARCHAR(10), -- ICD-10 ที่เกี่ยวข้อง
    specialty VARCHAR(50), -- แผนกที่เกี่ยวข้อง

    -- Package Content
    order_items JSONB NOT NULL, -- รายการคำสั่งในชุด
    default_instructions JSONB, -- คำแนะนำ default
    customizable_fields JSONB, -- ฟิลด์ที่สามารถปรับแต่งได้

    -- Usage and Sharing
    usage_count INTEGER DEFAULT 0, -- จำนวนครั้งที่ใช้
    is_public BOOLEAN DEFAULT FALSE, -- แชร์ให้แพทย์อื่นได้
    is_personal BOOLEAN DEFAULT TRUE, -- เป็นของส่วนตัว
    shared_departments JSONB, -- แผนกที่แชร์ให้

    -- Cost Information
    estimated_total_cost DECIMAL(10,2),
    cost_calculation_date DATE,

    -- Quality and Validation
    clinical_validation_status VARCHAR(20) DEFAULT 'draft' CHECK (clinical_validation_status IN (
        'draft', 'under_review', 'validated', 'approved', 'deprecated'
    )),
    validated_by UUID REFERENCES users(id),
    validation_date DATE,

    -- Ownership
    created_by UUID NOT NULL REFERENCES users(id),
    department_id UUID REFERENCES departments(id),

    -- Standardized Audit Fields
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    created_by UUID NOT NULL REFERENCES users(id),
    updated_by UUID REFERENCES users(id),

    -- Soft Delete Pattern
    deleted_at TIMESTAMP WITH TIME ZONE,
    deleted_by UUID REFERENCES users(id),
    is_active BOOLEAN DEFAULT TRUE,
    last_used_at TIMESTAMP WITH TIME ZONE
);

15. ตาราง visit_documents

ตารางสำหรับเอกสารต่างๆ ที่สร้างจาก Visit (ตาม TOR 4.2.16)

CREATE TABLE visit_documents (
    -- Primary Key
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    opd_visit_id UUID NOT NULL REFERENCES opd_visits(id) ON DELETE CASCADE,

    -- Document Information
    document_type VARCHAR(30) NOT NULL CHECK (document_type IN (
        'medical_certificate', 'sick_leave', 'referral_letter', 
        'drug_authorization', 'controlled_substance_form', 
        'fitness_certificate', 'disability_certificate',
        'insurance_form', 'lab_requisition', 'imaging_order'
    )),

    -- Document Content
    document_title VARCHAR(200) NOT NULL,
    document_content TEXT, -- เนื้อหาเอกสาร
    template_used UUID REFERENCES clinical_templates(id),

    -- Document Properties
    document_number VARCHAR(50) UNIQUE, -- เลขที่เอกสาร
    issue_date DATE NOT NULL DEFAULT CURRENT_DATE,
    valid_until DATE, -- วันหมดอายุ (ถ้ามี)

    -- Digital Properties
    file_path VARCHAR(500), -- ไฟล์ PDF ที่สร้างแล้ว
    digital_signature_id UUID REFERENCES digital_signatures(id),
    qr_code_data TEXT, -- ข้อมูล QR Code สำหรับตรวจสอบ

    -- Recipient Information
    recipient_name VARCHAR(100), -- ผู้รับเอกสาร
    recipient_organization VARCHAR(200), -- หน่วยงานผู้รับ

    -- Status and Control
    document_status VARCHAR(15) DEFAULT 'draft' CHECK (document_status IN (
        'draft', 'signed', 'issued', 'cancelled', 'expired'
    )),

    -- Authorization (สำหรับเอกสารที่ต้องอนุมัติ)
    requires_approval BOOLEAN DEFAULT FALSE,
    approved_by UUID REFERENCES users(id),
    approval_date DATE,
    approval_comments TEXT,

    -- Usage Tracking
    printed_count INTEGER DEFAULT 0,
    last_printed_at TIMESTAMP WITH TIME ZONE,
    emailed_to VARCHAR(100), -- อีเมลที่ส่งไป

    -- Audit
    created_by UUID NOT NULL REFERENCES users(id),
    signed_by UUID REFERENCES users(id),
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    signed_at TIMESTAMP WITH TIME ZONE
);

INTEGRATION WITH MEDITECH MASTER SCHEMA

Foundation Tables ที่ใช้จาก Master Schema

  1. patients - Master Patient Index พร้อมข้อมูล demographics
  2. medical_visits - Visit records ที่แชร์กับทุกโมดูล
  3. users - Healthcare providers (แพทย์, พยาบาล, เจ้าหน้าที่)
  4. departments และ clinics - โครงสร้างองค์กร
  5. audit_logs - System-wide audit trail
  6. digital_signatures - ลายเซ็นอิเล็กทรอนิกส์
  7. notifications - ระบบแจ้งเตือน multi-channel

OPD-CPOE Specific Tables

  1. opd_visits - ข้อมูล Visit เฉพาะ OPD
  2. soap_notes - บันทึกการตรวจแบบ SOAP
  3. clinical_assessments - การวินิจฉัยและ ICD codes
  4. medical_orders - คำสั่งทางการแพทย์ทั้งหมด
  5. prescriptions - ใบสั่งยาเฉพาะ
  6. visit_media - ไฟล์มัลติมีเดีย
  7. ai_parsing_logs - บันทึกการทำงานของ AI
  8. clinical_templates - Template สำหรับ SOAP Note
  9. package_orders - ชุดคำสั่งที่บันทึกไว้
  10. visit_documents - เอกสารที่ออกจาก Visit

Cross-Module Integration Points

โมดูลเป้าหมาย ตารางที่เชื่อมโยง ประเภทการเชื่อมโยง
ระบบคิว visit_queues Real-time queue status
ระบบห้องปฏิบัติการ lab_ordersmedical_orders Lab order transmission
ระบบรังสี imaging_ordersmedical_orders Imaging order integration
ระบบเภสัชกรรม prescriptionspharmacy_orders Prescription transmission
ระบบการเงิน medical_orders.total_cost Cost calculation
ระบบนัดหมาย appointmentsmedical_orders Follow-up scheduling

AI-Assist Integration Architecture

-- AI Processing Flow
CREATE OR REPLACE FUNCTION process_soap_plan_with_ai()
RETURNS TRIGGER AS $$
BEGIN
    -- Trigger AI processing when Plan is updated
    IF NEW.plan IS NOT NULL AND NEW.plan != OLD.plan THEN
        INSERT INTO ai_parsing_logs (
            soap_note_id, 
            input_text, 
            parsing_status
        ) VALUES (
            NEW.id, 
            NEW.plan, 
            'processing'
        );

        -- Update AI processing status
        UPDATE soap_notes 
        SET ai_processing_status = 'processing'
        WHERE id = NEW.id;
    END IF;

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_soap_ai_processing
    AFTER UPDATE OF plan ON soap_notes
    FOR EACH ROW
    EXECUTE FUNCTION process_soap_plan_with_ai();

Performance Optimization

-- Critical indexes for OPD operations
CREATE INDEX idx_opd_visits_active_queue ON opd_visits(visit_status, checked_in_at) 
    WHERE visit_status IN ('checked_in', 'in_examination');

CREATE INDEX idx_soap_notes_ai_pending ON soap_notes(ai_processing_status, created_at)
    WHERE ai_processing_status = 'pending';

CREATE INDEX idx_medical_orders_cost ON medical_orders(total_cost, patient_cost)
    WHERE total_cost IS NOT NULL;

CREATE INDEX idx_prescriptions_safety_check ON prescriptions(allergy_checked, drug_interaction_checked)
    WHERE prescription_status = 'draft';

-- Partitioning strategy for large tables
CREATE TABLE opd_visits_y2025 PARTITION OF opd_visits
    FOR VALUES FROM ('2025-01-01') TO ('2026-01-01');

CREATE TABLE soap_notes_y2025 PARTITION OF soap_notes  
    FOR VALUES FROM ('2025-01-01') TO ('2026-01-01');

Business Rules และ Triggers

-- ตรวจสอบการแพ้ยาก่อนสั่งยา
CREATE OR REPLACE FUNCTION check_drug_allergy()
RETURNS TRIGGER AS $$
DECLARE
    allergy_count INTEGER;
BEGIN
    -- Check patient allergies against new prescription
    SELECT COUNT(*) INTO allergy_count
    FROM patient_allergies pa
    WHERE pa.patient_id = (
        SELECT ov.patient_id 
        FROM opd_visits ov 
        WHERE ov.id = NEW.opd_visit_id
    )
    AND pa.allergen_code = NEW.drug_code
    AND pa.is_active = TRUE;

    IF allergy_count > 0 THEN
        INSERT INTO allergy_alerts (
            prescription_item_id,
            patient_id,
            allergen_type,
            allergen_code,
            allergen_name,
            alert_severity
        ) VALUES (
            NEW.id,
            (SELECT ov.patient_id FROM opd_visits ov WHERE ov.id = NEW.opd_visit_id),
            'drug',
            NEW.drug_code,
            NEW.drug_name,
            'severe'
        );
    END IF;

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_check_drug_allergy
    AFTER INSERT ON prescription_items
    FOR EACH ROW
    EXECUTE FUNCTION check_drug_allergy();

Security และ PDPA Compliance

-- Row Level Security สำหรับข้อมูลผู้ป่วย
ALTER TABLE opd_visits ENABLE ROW LEVEL SECURITY;

CREATE POLICY opd_visits_access_policy ON opd_visits
    FOR ALL TO authenticated_users
    USING (
        -- แพทย์เจ้าของไข้
        attending_doctor_id = current_user_id() OR
        -- แพทย์ในแผนกเดียวกัน
        clinic_id IN (SELECT clinic_id FROM user_clinic_access WHERE user_id = current_user_id()) OR
        -- Admin/Medical Records staff
        current_user_has_role('admin') OR current_user_has_role('medical_records')
    );

-- Audit trigger สำหรับ SOAP Notes
CREATE OR REPLACE FUNCTION audit_soap_changes()
RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO audit_logs (
        table_name, record_id, action, old_values, new_values,
        changed_by, changed_at
    ) VALUES (
        'soap_notes', 
        COALESCE(NEW.id, OLD.id),
        TG_OP,
        to_jsonb(OLD),
        to_jsonb(NEW),
        current_user_id(),
        CURRENT_TIMESTAMP
    );

    RETURN COALESCE(NEW, OLD);
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_audit_soap_notes
    AFTER INSERT OR UPDATE OR DELETE ON soap_notes
    FOR EACH ROW
    EXECUTE FUNCTION audit_soap_changes();

สรุป Benefits ของ Database Schema

CPOE AI Integration: ระบบ AI parsing และ clinical decision support
Patient Safety: Drug allergy และ interaction checking
Multimedia Support: Image annotation, video recording, sketch tools
Clinical Templates: Standardized SOAP note templates
Cost Transparency: Real-time cost calculation และ insurance coverage
Digital Signatures: Legal compliance สำหรับ prescription
Audit Compliance: Complete audit trail ตาม medical record regulations
Performance Optimization: Strategic indexing และ partitioning
Cross-Module Integration: Seamless data exchange กับโมดูลอื่น

Database schema นี้รองรับ OPD workflow ทั้งหมดตาม TOR และ SRS พร้อมการบูรณาการ AI technology เพื่อเพิ่มประสิทธิภาพการทำงานของแพทย์และความปลอดภัยของผู้ป่วย