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
- ตาราง
opd_visits - ตาราง
soap_notes - ตาราง
clinical_assessments - ตาราง
medical_orders - ตาราง
order_items - ตาราง
prescriptions - ตาราง
prescription_items - ตาราง
visit_media - ตาราง
clinical_templates - ตาราง
ai_parsing_logs - ตาราง
drug_interactions - ตาราง
allergy_alerts - ตาราง
clinical_guidelines - ตาราง
package_orders - ตาราง
visit_documents
SHARED FOUNDATION TABLES (จาก Master Schema)
หมายเหตุ: ตารางหลักเหล่านี้ถูกกำหนดใน MASTER_DATABASE_SCHEMA.md และใช้ร่วมกันทุกโมดูล
patients- Master Patient Indexmedical_visits- Visit records (แชร์กับระบบอื่น)users- Healthcare providers และ staffdepartmentsและclinics- Organization structureaudit_logs- System audit traildigital_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
patients- Master Patient Index พร้อมข้อมูล demographicsmedical_visits- Visit records ที่แชร์กับทุกโมดูลusers- Healthcare providers (แพทย์, พยาบาล, เจ้าหน้าที่)departmentsและclinics- โครงสร้างองค์กรaudit_logs- System-wide audit traildigital_signatures- ลายเซ็นอิเล็กทรอนิกส์notifications- ระบบแจ้งเตือน multi-channel
OPD-CPOE Specific Tables
opd_visits- ข้อมูล Visit เฉพาะ OPDsoap_notes- บันทึกการตรวจแบบ SOAPclinical_assessments- การวินิจฉัยและ ICD codesmedical_orders- คำสั่งทางการแพทย์ทั้งหมดprescriptions- ใบสั่งยาเฉพาะvisit_media- ไฟล์มัลติมีเดียai_parsing_logs- บันทึกการทำงานของ AIclinical_templates- Template สำหรับ SOAP Notepackage_orders- ชุดคำสั่งที่บันทึกไว้visit_documents- เอกสารที่ออกจาก Visit
Cross-Module Integration Points
| โมดูลเป้าหมาย | ตารางที่เชื่อมโยง | ประเภทการเชื่อมโยง |
|---|---|---|
| ระบบคิว | visit_queues |
Real-time queue status |
| ระบบห้องปฏิบัติการ | lab_orders ← medical_orders |
Lab order transmission |
| ระบบรังสี | imaging_orders ← medical_orders |
Imaging order integration |
| ระบบเภสัชกรรม | prescriptions → pharmacy_orders |
Prescription transmission |
| ระบบการเงิน | medical_orders.total_cost |
Cost calculation |
| ระบบนัดหมาย | appointments ← medical_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 เพื่อเพิ่มประสิทธิภาพการทำงานของแพทย์และความปลอดภัยของผู้ป่วย