690619:1226 240 #03
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
---
|
||||
title: 'Data & Storage: Data Dictionary and Data Model Architecture'
|
||||
version: 1.9.1
|
||||
version: 1.9.2
|
||||
status: released
|
||||
owner: Nattanin Peancharoen
|
||||
last_updated: 2026-05-16
|
||||
last_updated: 2026-06-19
|
||||
related:
|
||||
- specs/01-requirements/02-architecture.md
|
||||
- specs/01-requirements/03-functional-requirements.md
|
||||
@@ -2345,8 +2345,14 @@ PENDING_REVIEW ──→ VERIFIED ──→ IMPORTED (terminal)
|
||||
| `document_public_id` | UUID | YES | Imported document publicId when available |
|
||||
| `ai_model` | VARCHAR(50) | NO | Legacy AI model column used by current gateway service (default: gemma4) |
|
||||
| `model_name` | VARCHAR(100) | NO | Local model name used by ADR-023 AI pipeline |
|
||||
| `ai_suggestion_json` | JSON | YES | AI suggested metadata |
|
||||
| `human_override_json` | JSON | YES | Human approved or overridden metadata |
|
||||
| `effective_profile` | VARCHAR(50) | YES | ExecutionProfile ที่ backend กำหนด: interactive\|standard\|quality\|deep-analysis (Feature-235) |
|
||||
| `canonical_model` | VARCHAR(50) | YES | Canonical model identity: np-dms-ai หรือ np-dms-ocr (Feature-235, ADR-023) |
|
||||
| `snapshot_params_json` | LONGTEXT | YES | Runtime parameters snapshot ณ เวลา dispatch — ใช้จริงใน Ollama call (FR-A09, Feature-235) |
|
||||
| `model_type` | VARCHAR(50) | YES | ประเภท OCR/LLM model ที่ใช้ เช่น tesseract, typhoon-ocr-3b |
|
||||
| `vram_usage_mb` | INT | YES | VRAM ที่ใช้จริง (MB) ณ เวลาประมวลผล |
|
||||
| `cache_hit` | TINYINT(1) | NO | 1 = ผลลัพธ์มาจาก Redis cache, 0 = OCR ใหม่ |
|
||||
| `ai_suggestion_json` | LONGTEXT | YES | AI suggested metadata |
|
||||
| `human_override_json` | LONGTEXT | YES | Human approved or overridden metadata |
|
||||
| `processing_time_ms` | INT | YES | Legacy processing duration field |
|
||||
| `confidence_score` | DECIMAL(4,3) | YES | AI confidence score 0.000-1.000 |
|
||||
| `input_hash` | VARCHAR(64) | YES | Legacy SHA-256 input hash |
|
||||
@@ -2365,6 +2371,9 @@ PENDING_REVIEW ──→ VERIFIED ──→ IMPORTED (terminal)
|
||||
- KEY idx_ai_audit_model_name (model_name)
|
||||
- KEY idx_ai_audit_status (status)
|
||||
- KEY idx_ai_audit_confirmed_by (confirmed_by_user_id)
|
||||
- KEY idx_ai_audit_model_type (model_type)
|
||||
- KEY idx_ai_audit_effective_profile (effective_profile)
|
||||
- KEY idx_ai_audit_canonical_model (canonical_model)
|
||||
- CONSTRAINT fk_ai_audit_confirmed_by_user FOREIGN KEY (confirmed_by_user_id) REFERENCES users (user_id) ON DELETE SET NULL
|
||||
|
||||
#### Business Rules
|
||||
@@ -2375,7 +2384,145 @@ PENDING_REVIEW ──→ VERIFIED ──→ IMPORTED (terminal)
|
||||
|
||||
---
|
||||
|
||||
### 19.3 `document_chunks`
|
||||
### 19.3 `ai_available_models`
|
||||
|
||||
**วัตถุประสงค์:** เก็บรายการโมเดล AI ที่ให้เลือกใช้งานในระบบ (ADR-027, ADR-034)
|
||||
|
||||
| Column | Type | Nullable | Description |
|
||||
|--------|------|----------|-------------|
|
||||
| `id` | INT AUTO_INCREMENT | NO | ID ของตาราง |
|
||||
| `model_name` | VARCHAR(100) | NO | ชื่อโมเดล เช่น gemma4:e2b, gemma4:e4b |
|
||||
| `model_version` | VARCHAR(50) | NO | เวอร์ชั่นของโมเดล |
|
||||
| `description` | VARCHAR(500) | YES | รายละเอียดโมเดล |
|
||||
| `vram_gb` | DECIMAL(4,2) | YES | VRAM ที่ใช้โดยประมาณ (GB) |
|
||||
| `is_active` | TINYINT(1) | NO | สถานะใช้งาน |
|
||||
| `is_default` | TINYINT(1) | NO | โมเดลเริ่มต้น |
|
||||
| `created_by` | INT | YES | ผู้สร้าง |
|
||||
| `updated_by` | INT | YES | ผู้แก้ไขล่าสุด |
|
||||
| `created_at` | DATETIME(3) | NO | วันที่สร้าง |
|
||||
| `updated_at` | DATETIME(3) | NO | วันที่แก้ไขล่าสุด |
|
||||
| `deleted_at` | DATETIME(3) | YES | วันที่ลบ (Soft Delete) |
|
||||
|
||||
**Indexes**:
|
||||
- PRIMARY KEY (id)
|
||||
- UNIQUE KEY uk_model_name (model_name)
|
||||
- KEY idx_is_active (is_active)
|
||||
- KEY idx_is_default (is_default)
|
||||
|
||||
---
|
||||
|
||||
### 19.4 `ai_prompts`
|
||||
|
||||
**วัตถุประสงค์:** ตาราง versioned prompt templates สำหรับ OCR extraction (ADR-029)
|
||||
|
||||
| Column | Type | Nullable | Description |
|
||||
|--------|------|----------|-------------|
|
||||
| `id` | INT AUTO_INCREMENT | NO | ID ภายใน (ไม่ expose ใน API) |
|
||||
| `public_id` | UUID | NO | UUID Public Identifier (ADR-019) |
|
||||
| `prompt_type` | VARCHAR(50) | NO | ประเภท prompt เช่น ocr_extraction |
|
||||
| `version_number` | INT | NO | เลข version ต่อเนื่องต่อ prompt_type (1, 2, 3...) |
|
||||
| `template` | TEXT | NO | prompt template ที่มี {{ocr_text}} placeholder บังคับ |
|
||||
| `field_schema` | LONGTEXT | YES | definition ของ fields ที่คาดหวังในผลลัพธ์ JSON |
|
||||
| `is_active` | TINYINT(1) | NO | 1 = version นี้ใช้งานจริงทั้ง sandbox และ migrate-document (1 per prompt_type) |
|
||||
| `test_result_json` | LONGTEXT | YES | ผลลัพธ์ JSON จาก sandbox run ล่าสุด (auto-save โดย processor) |
|
||||
| `manual_note` | TEXT | YES | หมายเหตุ/annotation จาก admin (manual input) |
|
||||
| `last_tested_at` | TIMESTAMP | YES | เวลาที่ sandbox รันครั้งล่าสุดสำหรับ version นี้ |
|
||||
| `activated_at` | TIMESTAMP | YES | เวลาที่ version นี้ถูก activate เป็น active |
|
||||
| `created_by` | INT | NO | user_id ของผู้สร้าง version นี้ |
|
||||
| `created_at` | TIMESTAMP | NO | วันที่สร้าง |
|
||||
| `context_config` | LONGTEXT | YES | Configuration สำหรับ context ที่ backend ต้องส่งให้ AI (filter, pageSize, language, etc.) |
|
||||
| `version` | INT | NO | Optimistic locking version |
|
||||
|
||||
**Indexes**:
|
||||
- PRIMARY KEY (id)
|
||||
- UNIQUE KEY uk_type_version (prompt_type, version_number)
|
||||
- KEY idx_prompt_type_active (prompt_type, is_active)
|
||||
- KEY created_by (created_by)
|
||||
- CONSTRAINT ai_prompts_ibfk_1 FOREIGN KEY (created_by) REFERENCES users (user_id)
|
||||
|
||||
---
|
||||
|
||||
### 19.5 `ai_execution_profiles`
|
||||
|
||||
**วัตถุประสงค์:** ตาราง execution profile parameters สำหรับ np-dms-ai (ADR-025, ADR-027)
|
||||
|
||||
| Column | Type | Nullable | Description |
|
||||
|--------|------|----------|-------------|
|
||||
| `id` | INT AUTO_INCREMENT | NO | ID ภายใน |
|
||||
| `profile_name` | VARCHAR(50) | NO | ชื่อ profile |
|
||||
| `canonical_model` | VARCHAR(20) | NO | Model identity (default: np-dms-ai) |
|
||||
| `temperature` | DECIMAL(4,3) | NO | LLM temperature |
|
||||
| `top_p` | DECIMAL(4,3) | NO | LLM top_p |
|
||||
| `max_tokens` | INT | YES | Maximum tokens |
|
||||
| `num_ctx` | INT | YES | Context window size |
|
||||
| `repeat_penalty` | DECIMAL(5,3) | NO | Repeat penalty |
|
||||
| `keep_alive_seconds` | INT | NO | Model keep_alive in seconds |
|
||||
| `is_active` | TINYINT(1) | NO | 1 = active; 0 = disabled |
|
||||
| `updated_by` | INT | YES | user_id |
|
||||
| `updated_at` | TIMESTAMP | NO | วันที่แก้ไขล่าสุด |
|
||||
| `created_at` | TIMESTAMP | NO | วันที่สร้าง |
|
||||
|
||||
**Indexes**:
|
||||
- PRIMARY KEY (id)
|
||||
- UNIQUE KEY uk_profile_name (profile_name)
|
||||
- KEY idx_profile_active (profile_name, is_active)
|
||||
- KEY updated_by (updated_by)
|
||||
- CONSTRAINT ai_execution_profiles_ibfk_1 FOREIGN KEY (updated_by) REFERENCES users (user_id)
|
||||
|
||||
---
|
||||
|
||||
### 19.6 `ai_sandbox_profiles`
|
||||
|
||||
**วัตถุประสงค์:** ตาราง sandbox profile parameters
|
||||
|
||||
| Column | Type | Nullable | Description |
|
||||
|--------|------|----------|-------------|
|
||||
| `id` | INT AUTO_INCREMENT | NO | ID ภายใน |
|
||||
| `profile_name` | VARCHAR(50) | NO | ชื่อ profile |
|
||||
| `canonical_model` | VARCHAR(20) | NO | Model identity (default: np-dms-ai) |
|
||||
| `temperature` | DECIMAL(4,3) | NO | LLM temperature |
|
||||
| `top_p` | DECIMAL(4,3) | NO | LLM top_p |
|
||||
| `max_tokens` | INT | YES | Maximum tokens |
|
||||
| `num_ctx` | INT | NO | Context window size |
|
||||
| `repeat_penalty` | DECIMAL(5,3) | NO | Repeat penalty |
|
||||
| `keep_alive_seconds` | INT | NO | Model keep_alive in seconds |
|
||||
| `updated_by` | INT | YES | user_id |
|
||||
| `updated_at` | TIMESTAMP | NO | วันที่แก้ไขล่าสุด |
|
||||
| `created_at` | TIMESTAMP | NO | วันที่สร้าง |
|
||||
|
||||
**Indexes**:
|
||||
- PRIMARY KEY (id)
|
||||
- UNIQUE KEY uk_profile_name (profile_name)
|
||||
- KEY idx_ai_sandbox_profile_model (canonical_model)
|
||||
- KEY updated_by (updated_by)
|
||||
- CONSTRAINT ai_sandbox_profiles_ibfk_1 FOREIGN KEY (updated_by) REFERENCES users (user_id)
|
||||
|
||||
---
|
||||
|
||||
### 19.7 `migration_errors`
|
||||
|
||||
**วัตถุประสงค์:** ตาราง Error Log สำหรับ Migration (ลบได้หลัง Migration เสร็จ) (ADR-028)
|
||||
|
||||
| Column | Type | Nullable | Description |
|
||||
|--------|------|----------|-------------|
|
||||
| `id` | INT AUTO_INCREMENT | NO | ID |
|
||||
| `batch_id` | VARCHAR(50) | YES | n8n batch identifier |
|
||||
| `document_number` | VARCHAR(100) | YES | เลขที่เอกสาร |
|
||||
| `error_type` | ENUM | YES | FILE_NOT_FOUND, MISSING_FILENAME, FILE_ERROR, AI_PARSE_ERROR, API_ERROR, DB_ERROR, SECURITY, UNKNOWN |
|
||||
| `error_message` | TEXT | YES | ข้อความ error |
|
||||
| `job_id` | VARCHAR(100) | YES | BullMQ Job ID |
|
||||
| `raw_ai_response` | TEXT | YES | AI response ดิบ |
|
||||
| `created_at` | TIMESTAMP | NO | วันที่สร้าง |
|
||||
|
||||
**Indexes**:
|
||||
- PRIMARY KEY (id)
|
||||
- KEY idx_batch_id (batch_id)
|
||||
- KEY idx_job_id (job_id)
|
||||
- KEY idx_error_type (error_type)
|
||||
|
||||
---
|
||||
|
||||
### 19.8 `document_chunks`
|
||||
|
||||
**วัตถุประสงค์:** เก็บ vector metadata สำหรับ RAG ingestion ตาม ADR-022
|
||||
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
-- File: specs/03-Data-and-Storage/deltas/2026-05-22-alter-migration-review-queue.rollback.sql
|
||||
-- Change Log:
|
||||
-- - 2026-05-22: ลบคอลัมน์ ai_job_id ออกจากตาราง migration_review_queue ตาม ADR-028
|
||||
|
||||
-- Delta Rollback: ลบคอลัมน์ ai_job_id ในตาราง migration_review_queue
|
||||
-- Date: 2026-05-22
|
||||
-- Related ADR: ADR-028, ADR-023A
|
||||
|
||||
-- ------------------------------------------------------------
|
||||
-- การลบคอลัมน์ (Rollback changes)
|
||||
-- ------------------------------------------------------------
|
||||
|
||||
ALTER TABLE migration_review_queue
|
||||
DROP COLUMN ai_job_id;
|
||||
@@ -1,16 +0,0 @@
|
||||
-- File: specs/03-Data-and-Storage/deltas/2026-05-22-alter-migration-review-queue.sql
|
||||
-- Change Log:
|
||||
-- - 2026-05-22: เพิ่มคอลัมน์ ai_job_id ในตาราง migration_review_queue ตาม ADR-028
|
||||
|
||||
-- Delta: เพิ่มคอลัมน์ ai_job_id ในตาราง migration_review_queue
|
||||
-- Date: 2026-05-22
|
||||
-- Related ADR: ADR-028, ADR-023A
|
||||
-- Applied in: v1.9.0 -> v1.9.5
|
||||
|
||||
-- ------------------------------------------------------------
|
||||
-- การปรับปรุงตาราง migration_review_queue (Schema changes)
|
||||
-- ------------------------------------------------------------
|
||||
|
||||
ALTER TABLE migration_review_queue
|
||||
ADD COLUMN ai_job_id VARCHAR(36) NULL COMMENT 'BullMQ Job ID สำหรับงานประมวลผล AI'
|
||||
AFTER storage_temp_path;
|
||||
@@ -1,10 +0,0 @@
|
||||
-- Delta Rollback: ลบตาราง system_settings
|
||||
-- Date: 2026-05-22
|
||||
-- Related ADR: ADR-027
|
||||
-- Applied in: v1.9.0 -> v1.9.5
|
||||
|
||||
-- ------------------------------------------------------------
|
||||
-- การย้อนกลับโครงสร้างฐานข้อมูล (Rollback changes)
|
||||
-- ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS system_settings;
|
||||
@@ -1,48 +0,0 @@
|
||||
-- Delta: สร้างตาราง system_settings และ Seed ข้อมูล AI_FEATURES_ENABLED
|
||||
-- Date: 2026-05-22
|
||||
-- Related ADR: ADR-027
|
||||
-- Applied in: v1.9.0 -> v1.9.5
|
||||
|
||||
-- ------------------------------------------------------------
|
||||
-- การเปลี่ยนแปลงโครงสร้างฐานข้อมูล (Schema changes)
|
||||
-- ------------------------------------------------------------
|
||||
|
||||
CREATE TABLE IF NOT EXISTS system_settings (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
|
||||
setting_key VARCHAR(100) NOT NULL UNIQUE COMMENT 'คีย์การตั้งค่าระบบ',
|
||||
setting_value TEXT NOT NULL COMMENT 'ค่าที่บันทึก (stringified)',
|
||||
data_type ENUM('string', 'number', 'boolean', 'json') NOT NULL DEFAULT 'string' COMMENT 'ประเภทข้อมูลสำหรับ validation',
|
||||
category VARCHAR(50) COMMENT 'หมวดหมู่',
|
||||
is_encrypted TINYINT(1) DEFAULT 0 COMMENT 'เข้ารหัสค่า sensitive',
|
||||
validation_rules JSON COMMENT 'กฎ validation',
|
||||
description TEXT COMMENT 'คำอธิบายข้อมูลการตั้งค่า',
|
||||
is_public TINYINT(1) DEFAULT 0 COMMENT 'เผยแพร่ให้ frontend อ่านได้หรือ admin only',
|
||||
updated_by INT COMMENT 'ผู้แก้ไขล่าสุด',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (updated_by) REFERENCES users(user_id) ON DELETE SET NULL,
|
||||
INDEX idx_system_settings_category (category),
|
||||
INDEX idx_system_settings_is_public (is_public)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเก็บข้อมูลการตั้งค่าระบบไดนามิก';
|
||||
|
||||
-- ------------------------------------------------------------
|
||||
-- การเพิ่มข้อมูลพื้นฐาน (Seed Data)
|
||||
-- ------------------------------------------------------------
|
||||
|
||||
INSERT INTO system_settings (
|
||||
setting_key,
|
||||
setting_value,
|
||||
data_type,
|
||||
category,
|
||||
description,
|
||||
is_public
|
||||
)
|
||||
VALUES (
|
||||
'AI_FEATURES_ENABLED',
|
||||
'true',
|
||||
'boolean',
|
||||
'ai',
|
||||
'สถานะเปิด/ปิดการใช้งานฟีเจอร์ AI ทั้งระบบ สำหรับผู้ใช้ทั่วไป',
|
||||
1
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE setting_key = setting_key;
|
||||
@@ -1,14 +0,0 @@
|
||||
-- File: specs/03-Data-and-Storage/deltas/2026-05-22-create-tags-tables.rollback.sql
|
||||
-- Change Log:
|
||||
-- - 2026-05-22: ย้อนกลับตาราง tags และ correspondence_tags ตาม ADR-028
|
||||
|
||||
-- Delta Rollback: ลบตาราง tags และ correspondence_tags
|
||||
-- Date: 2026-05-22
|
||||
-- Related ADR: ADR-028
|
||||
|
||||
-- ------------------------------------------------------------
|
||||
-- การลบตาราง (Rollback changes)
|
||||
-- ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS correspondence_tags;
|
||||
DROP TABLE IF EXISTS tags;
|
||||
@@ -1,47 +0,0 @@
|
||||
-- File: specs/03-Data-and-Storage/deltas/2026-05-22-create-tags-tables.sql
|
||||
-- Change Log:
|
||||
-- - 2026-05-22: สร้างตาราง tags และ correspondence_tags ตาม ADR-028
|
||||
|
||||
-- Delta: สร้างตาราง tags และ correspondence_tags
|
||||
-- Date: 2026-05-22
|
||||
-- Related ADR: ADR-028, ADR-019
|
||||
-- Applied in: v1.9.0 -> v1.9.5
|
||||
|
||||
-- ------------------------------------------------------------
|
||||
-- การสร้างตาราง tags (Schema changes)
|
||||
-- ------------------------------------------------------------
|
||||
|
||||
CREATE TABLE IF NOT EXISTS tags (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ภายในระบบ',
|
||||
public_id CHAR(36) NOT NULL UNIQUE COMMENT 'UUIDv7 สำหรับการใช้งานภายนอก (ADR-019)',
|
||||
project_id INT NULL COMMENT 'ID โครงการ (NULL = Global Tag)',
|
||||
tag_name VARCHAR(100) NOT NULL COMMENT 'ชื่อแท็ก',
|
||||
color_code VARCHAR(30) DEFAULT 'default' COMMENT 'รหัสสีสำหรับ UI',
|
||||
description TEXT COMMENT 'คำอธิบายเพิ่มเติม',
|
||||
created_by INT COMMENT 'ผู้สร้างแท็ก',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่สร้าง',
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'วันที่แก้ไขล่าสุด',
|
||||
deleted_at TIMESTAMP NULL COMMENT 'วันที่ลบ (Soft Delete)',
|
||||
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (created_by) REFERENCES users(user_id) ON DELETE SET NULL,
|
||||
UNIQUE KEY uq_tag_project (project_id, tag_name),
|
||||
INDEX idx_tags_deleted_at (deleted_at)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเก็บข้อมูลแท็กจัดหมวดหมู่เอกสาร';
|
||||
|
||||
-- ------------------------------------------------------------
|
||||
-- การสร้างตาราง correspondence_tags (Schema changes)
|
||||
-- ------------------------------------------------------------
|
||||
|
||||
CREATE TABLE IF NOT EXISTS correspondence_tags (
|
||||
correspondence_id INT NOT NULL COMMENT 'ID ของเอกสาร',
|
||||
tag_id INT NOT NULL COMMENT 'ID ของแท็ก',
|
||||
is_ai_suggested BOOLEAN DEFAULT FALSE COMMENT 'แท็กนี้แนะนำโดย AI หรือไม่',
|
||||
confidence DECIMAL(4,3) NULL COMMENT 'ค่าความมั่นใจของ AI (0.000–1.000)',
|
||||
created_by INT COMMENT 'ผู้เชื่อมโยงแท็ก',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่เชื่อมโยง',
|
||||
PRIMARY KEY (correspondence_id, tag_id),
|
||||
FOREIGN KEY (correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (created_by) REFERENCES users(user_id) ON DELETE SET NULL,
|
||||
INDEX idx_correspondence_tags_lookup (tag_id)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเชื่อมโยงความสัมพันธ์แบบ M:N ระหว่างเอกสารและแท็ก';
|
||||
@@ -1,97 +0,0 @@
|
||||
-- File: specs/03-Data-and-Storage/deltas/2026-05-22-drop-migration-tables.rollback.sql
|
||||
-- Change Log:
|
||||
-- - 2026-05-22: กู้คืนโครงสร้างตาราง staging ทั้งหมด 5 ตารางสำหรับระบบย้ายข้อมูลกรณีเกิดเหตุฉุกเฉิน (Phase 6)
|
||||
|
||||
-- Delta Rollback: กู้คืนตาราง Staging ชั่วคราว (Recreate Staging Tables)
|
||||
-- Date: 2026-05-22
|
||||
-- Related ADR: ADR-028
|
||||
|
||||
-- ------------------------------------------------------------
|
||||
-- การกู้คืนตาราง Staging ทั้งหมด 5 ตาราง
|
||||
-- ------------------------------------------------------------
|
||||
|
||||
-- 1. กู้คืนตารางความคืบหน้าของ Migration Progress
|
||||
CREATE TABLE IF NOT EXISTS migration_progress (
|
||||
batch_id VARCHAR(50) PRIMARY KEY,
|
||||
last_processed_index INT DEFAULT 0,
|
||||
STATUS ENUM('RUNNING', 'COMPLETED', 'FAILED') DEFAULT 'RUNNING',
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'Migration: Batch Progress';
|
||||
|
||||
-- 2. กู้คืนตารางคิวตรวจสอบสำหรับเอกสาร (Review Queue)
|
||||
CREATE TABLE IF NOT EXISTS migration_review_queue (
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
uuid CHAR(36) NOT NULL DEFAULT (uuid()) COMMENT 'UUID Public Identifier (ADR-019)',
|
||||
document_number VARCHAR(100) NOT NULL,
|
||||
subject TEXT COMMENT 'หัวข้อเรื่องภาษาไทยหรืออังกฤษ',
|
||||
original_subject TEXT COMMENT 'หัวข้อเรื่องเดิมจากระบบจัดเก็บเดิม',
|
||||
body TEXT NULL COMMENT 'เนื้อความย่อจาก AI',
|
||||
ai_suggested_category VARCHAR(50),
|
||||
ai_confidence DECIMAL(4, 3),
|
||||
ai_issues JSON,
|
||||
review_reason VARCHAR(255),
|
||||
status ENUM('PENDING', 'APPROVED', 'IMPORTED', 'REJECTED') NOT NULL DEFAULT 'PENDING',
|
||||
reviewed_by VARCHAR(100),
|
||||
reviewed_at TIMESTAMP NULL,
|
||||
project_id INT NULL COMMENT 'Project ID ของโครงการ',
|
||||
sender_organization_id INT NULL COMMENT 'Sender ID ของผู้ส่ง',
|
||||
receiver_organization_id INT NULL COMMENT 'Receiver ID ของผู้รับ',
|
||||
received_date DATE NULL,
|
||||
issued_date DATE NULL,
|
||||
remarks TEXT,
|
||||
ai_summary TEXT,
|
||||
extracted_tags JSON,
|
||||
temp_attachment_id INT NULL,
|
||||
ai_job_id VARCHAR(36) NULL COMMENT 'BullMQ Job ID สำหรับงานประมวลผล AI',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uq_doc_number (document_number),
|
||||
UNIQUE KEY uq_migration_review_uuid (uuid)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'Migration: Review Queue';
|
||||
|
||||
-- 3. กู้คืนตารางแสดงประวัติข้อผิดพลาดการย้ายข้อมูล (Error Log)
|
||||
CREATE TABLE IF NOT EXISTS migration_errors (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
batch_id VARCHAR(50),
|
||||
document_number VARCHAR(100),
|
||||
error_type ENUM(
|
||||
'FILE_NOT_FOUND',
|
||||
'MISSING_FILENAME',
|
||||
'FILE_ERROR',
|
||||
'AI_PARSE_ERROR',
|
||||
'API_ERROR',
|
||||
'DB_ERROR',
|
||||
'SECURITY',
|
||||
'UNKNOWN'
|
||||
),
|
||||
error_message TEXT,
|
||||
job_id VARCHAR(100) NULL,
|
||||
raw_ai_response TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
INDEX idx_batch_id (batch_id),
|
||||
INDEX idx_job_id (job_id),
|
||||
INDEX idx_error_type (error_type)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'Migration: Error Log';
|
||||
|
||||
-- 4. กู้คืนตารางสถานะสำหรับ AI Model Fallback State
|
||||
CREATE TABLE IF NOT EXISTS migration_fallback_state (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
batch_id VARCHAR(50) UNIQUE,
|
||||
recent_error_count INT DEFAULT 0,
|
||||
is_fallback_active BOOLEAN DEFAULT FALSE,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'Migration: Fallback Model State';
|
||||
|
||||
-- 5. กู้คืนตารางแสดงข้อมูลสรุปรายวันของ Migration (Daily Summary)
|
||||
CREATE TABLE IF NOT EXISTS migration_daily_summary (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
batch_id VARCHAR(50),
|
||||
summary_date DATE,
|
||||
total_processed INT DEFAULT 0,
|
||||
auto_ingested INT DEFAULT 0,
|
||||
sent_to_review INT DEFAULT 0,
|
||||
rejected INT DEFAULT 0,
|
||||
errors INT DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY uq_batch_date (batch_id, summary_date)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'Migration: Daily Summary';
|
||||
@@ -1,26 +0,0 @@
|
||||
-- File: specs/03-Data-and-Storage/deltas/2026-05-22-drop-migration-tables.sql
|
||||
-- Change Log:
|
||||
-- - 2026-05-22: ดรอปตาราง staging ทั้งหมดหลังย้ายข้อมูลเสร็จสิ้น (Phase 6) โดยยังคงรักษาตาราง import_transactions ไว้ป้องกันการย้ายข้อมูลซ้ำ
|
||||
|
||||
-- Delta: ดรอปตาราง Staging ชั่วคราว (Post-Migration Cleanup)
|
||||
-- Date: 2026-05-22
|
||||
-- Related ADR: ADR-028
|
||||
|
||||
-- ------------------------------------------------------------
|
||||
-- การล้างตาราง Staging เพื่อประหยัดพื้นที่ระบบจัดเก็บข้อมูล (Cleanups)
|
||||
-- ------------------------------------------------------------
|
||||
|
||||
-- ลบตารางแสดงข้อมูลสรุปรายวันของ Migration
|
||||
DROP TABLE IF EXISTS migration_daily_summary;
|
||||
|
||||
-- ลบตารางสถานะสำหรับ AI Model Fallback State
|
||||
DROP TABLE IF EXISTS migration_fallback_state;
|
||||
|
||||
-- ลบตารางแสดงประวัติข้อผิดพลาดการย้ายข้อมูล
|
||||
DROP TABLE IF EXISTS migration_errors;
|
||||
|
||||
-- ลบตารางคิวตรวจสอบสำหรับเอกสาร
|
||||
DROP TABLE IF EXISTS migration_review_queue;
|
||||
|
||||
-- ลบตารางความคืบหน้าของ Migration Progress
|
||||
DROP TABLE IF EXISTS migration_progress;
|
||||
@@ -1,15 +0,0 @@
|
||||
-- File: specs/03-Data-and-Storage/deltas/2026-05-23-alter-migration-review-queue-enum.sql
|
||||
-- Change Log:
|
||||
-- - 2026-05-23: เพิ่ม PENDING_REVIEW เข้า status ENUM ของ migration_review_queue (TypeORM-managed)
|
||||
-- n8n workflow ไม่ใช้ MySQL direct access แล้ว — ใช้ POST /api/ai/migration/queue/record แทน (ADR-023A)
|
||||
-- Delta: เพิ่ม PENDING_REVIEW ใน status column ของ migration_review_queue
|
||||
-- Date: 2026-05-23
|
||||
-- Related: ADR-028, ADR-023A
|
||||
-- รันก่อน deploy backend ที่มี PENDING_REVIEW ใน MigrationReviewRecordStatus enum
|
||||
ALTER TABLE migration_review_queue
|
||||
MODIFY COLUMN STATUS ENUM(
|
||||
'PENDING',
|
||||
'PENDING_REVIEW',
|
||||
'IMPORTED',
|
||||
'REJECTED'
|
||||
) DEFAULT 'PENDING';
|
||||
@@ -1,10 +0,0 @@
|
||||
-- File: specs/03-Data-and-Storage/deltas/2026-05-24-add-migration-errors-job-id.rollback.sql
|
||||
-- Change Log:
|
||||
-- - 2026-05-24: Rollback สำหรับลบ job_id ออกจาก migration_errors
|
||||
|
||||
-- Delta Rollback: ลบคอลัมน์ job_id สำหรับ Migration Error Log
|
||||
-- Related ADR: ADR-009, ADR-023A, ADR-028
|
||||
|
||||
ALTER TABLE migration_errors
|
||||
DROP INDEX idx_migration_errors_job_id,
|
||||
DROP COLUMN job_id;
|
||||
@@ -1,11 +0,0 @@
|
||||
-- File: specs/03-Data-and-Storage/deltas/2026-05-24-add-migration-errors-job-id.sql
|
||||
-- Change Log:
|
||||
-- - 2026-05-24: เพิ่ม job_id ใน migration_errors เพื่อผูก error log กับ BullMQ AI job
|
||||
|
||||
-- Delta: เพิ่มคอลัมน์ job_id สำหรับ Migration Error Log
|
||||
-- Related ADR: ADR-009, ADR-023A, ADR-028
|
||||
|
||||
ALTER TABLE migration_errors
|
||||
ADD COLUMN job_id VARCHAR(100) NULL COMMENT 'BullMQ Job ID สำหรับ trace error ของ AI migration'
|
||||
AFTER error_message,
|
||||
ADD INDEX idx_migration_errors_job_id (job_id);
|
||||
@@ -1,8 +0,0 @@
|
||||
-- Rollback: Drop ai_available_models table
|
||||
-- Date: 2026-05-25
|
||||
|
||||
-- Remove system setting first
|
||||
DELETE FROM system_settings WHERE setting_key = 'AI_ACTIVE_MODEL';
|
||||
|
||||
-- Drop table
|
||||
DROP TABLE IF EXISTS ai_available_models;
|
||||
@@ -1,43 +0,0 @@
|
||||
-- Delta: Create ai_available_models table for dynamic AI model selection
|
||||
-- Date: 2026-05-25
|
||||
-- Author: AI Assistant
|
||||
-- Related: ADR-027 AI Admin Console - Dynamic model control
|
||||
|
||||
-- Create table for available AI models
|
||||
CREATE TABLE IF NOT EXISTS ai_available_models (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
model_name VARCHAR(100) NOT NULL COMMENT 'ชื่อโมเดล เช่น gemma4:e2b, gemma4:e4b',
|
||||
model_version VARCHAR(50) NOT NULL COMMENT 'เวอร์ชั่นของโมเดล',
|
||||
description VARCHAR(500) NULL COMMENT 'รายละเอียดโมเดล',
|
||||
vram_gb DECIMAL(4,2) NULL COMMENT 'VRAM ที่ใช้โดยประมาณ (GB)',
|
||||
is_active BOOLEAN DEFAULT TRUE COMMENT 'สถานะใช้งาน',
|
||||
is_default BOOLEAN DEFAULT FALSE COMMENT 'โมเดลเริ่มต้น',
|
||||
created_by INT NULL,
|
||||
updated_by INT NULL,
|
||||
created_at DATETIME(3) DEFAULT CURRENT_TIMESTAMP(3),
|
||||
updated_at DATETIME(3) DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||||
deleted_at DATETIME(3) NULL,
|
||||
|
||||
UNIQUE KEY uk_model_name (model_name),
|
||||
INDEX idx_is_active (is_active),
|
||||
INDEX idx_is_default (is_default)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
COMMENT='ตารางเก็บรายการโมเดล AI ที่ให้เลือกใช้งานในระบบ (ADR-027)';
|
||||
|
||||
-- Insert default models per ADR-023A
|
||||
INSERT INTO ai_available_models (model_name, model_version, description, vram_gb, is_active, is_default) VALUES
|
||||
('gemma4:e2b', 'e2b', 'Gemma 4 E2B - 2-bit quantized, ~2GB VRAM, recommended per ADR-023A', 2.00, TRUE, TRUE),
|
||||
('gemma4:e4b', 'e4b', 'Gemma 4 E4B - 4-bit quantized, ~4GB VRAM', 4.00, TRUE, FALSE);
|
||||
|
||||
-- Add system setting for active model (reference to ai_available_models)
|
||||
INSERT INTO system_settings (setting_key, setting_value, data_type, category, description, is_public, created_at, updated_at)
|
||||
SELECT
|
||||
'AI_ACTIVE_MODEL',
|
||||
(SELECT model_name FROM ai_available_models WHERE is_default = TRUE LIMIT 1),
|
||||
'string',
|
||||
'ai',
|
||||
'โมเดล AI ที่ใช้งานอยู่ในระบบ (global)',
|
||||
TRUE,
|
||||
CURRENT_TIMESTAMP(3),
|
||||
CURRENT_TIMESTAMP(3)
|
||||
WHERE NOT EXISTS (SELECT 1 FROM system_settings WHERE setting_key = 'AI_ACTIVE_MODEL');
|
||||
@@ -1,4 +0,0 @@
|
||||
-- Rollback: ลบตาราง ai_prompts (ADR-029)
|
||||
-- Date: 2026-05-25
|
||||
|
||||
DROP TABLE IF EXISTS ai_prompts;
|
||||
@@ -1,73 +0,0 @@
|
||||
-- Delta: สร้างตาราง ai_prompts สำหรับ Dynamic Prompt Management
|
||||
-- Date: 2026-05-25
|
||||
-- Related ADR: ADR-029
|
||||
-- Applied in: v1.9.0 -> v1.9.6
|
||||
-- ------------------------------------------------------------
|
||||
-- การเปลี่ยนแปลงโครงสร้างฐานข้อมูล (Schema changes)
|
||||
-- ------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS ai_prompts (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ภายใน (ไม่ expose ใน API)',
|
||||
prompt_type VARCHAR(50) NOT NULL COMMENT 'ประเภท prompt เช่น ocr_extraction',
|
||||
version_number INT NOT NULL COMMENT 'เลข version ต่อเนื่องต่อ prompt_type (1, 2, 3...)',
|
||||
template TEXT NOT NULL COMMENT 'prompt template ที่มี {{ocr_text}} placeholder บังคับ',
|
||||
field_schema JSON NULL COMMENT 'definition ของ fields ที่คาดหวังในผลลัพธ์ JSON',
|
||||
is_active TINYINT(1) NOT NULL DEFAULT 0 COMMENT '1 = version นี้ใช้งานจริงทั้ง sandbox และ migrate-document (1 per prompt_type)',
|
||||
test_result_json JSON NULL COMMENT 'ผลลัพธ์ JSON จาก sandbox run ล่าสุด (auto-save โดย processor)',
|
||||
manual_note TEXT NULL COMMENT 'หมายเหตุ/annotation จาก admin (manual input)',
|
||||
last_tested_at TIMESTAMP NULL COMMENT 'เวลาที่ sandbox รันครั้งล่าสุดสำหรับ version นี้',
|
||||
activated_at TIMESTAMP NULL COMMENT 'เวลาที่ version นี้ถูก activate เป็น active',
|
||||
created_by INT NOT NULL COMMENT 'user_id ของผู้สร้าง version นี้',
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY uk_type_version (prompt_type, version_number),
|
||||
INDEX idx_prompt_type_active (prompt_type, is_active),
|
||||
FOREIGN KEY (created_by) REFERENCES users(user_id)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ตาราง versioned prompt templates สำหรับ OCR extraction (ADR-029)';
|
||||
|
||||
-- ------------------------------------------------------------
|
||||
-- Seed: migrate hardcoded prompt เป็น active version 1
|
||||
-- (8 fields รวม category, tags, summary — ใช้ร่วมกันทั้ง sandbox และ migrate-document)
|
||||
-- ------------------------------------------------------------
|
||||
INSERT INTO ai_prompts (
|
||||
prompt_type,
|
||||
version_number,
|
||||
template,
|
||||
field_schema,
|
||||
is_active,
|
||||
manual_note,
|
||||
activated_at,
|
||||
created_by
|
||||
)
|
||||
VALUES (
|
||||
'ocr_extraction',
|
||||
1,
|
||||
'You are a professional document intelligence engine.\nAnalyze the following OCR text extracted from a project document and extract the metadata fields.\n\nOCR TEXT:\n{{ocr_text}}\n\nExtract these fields:\n1. documentNumber: The official document number or code. If not found, return null.\n2. subject: The main subject, title, or topic of the document. If not found, return null.\n3. discipline: Must be exactly one of: "Civil", "Mechanical", "Electrical", "Architectural", or null if not specified.\n4. category: Must be exactly one of: "Correspondence", "Transmittal", "Circulation", "RFA", "Shop Drawing", "Contract Drawing", or null if not specified.\n5. date: The issue/document date in YYYY-MM-DD format. If not found, return null.\n6. confidence: A float between 0.0 and 1.0 indicating your confidence in this extraction.\n7. tags: An array of tags/keywords (strings) that describe the document.\n8. summary: A short 1-2 sentence summary of the document contents.\nReturn ONLY a valid JSON object matching this schema. Do NOT include markdown code blocks, HTML, or any conversational text. Example:\n{\n "documentNumber": "LCBP3-CIV-001",\n "subject": "Foundation Inspection Report",\n "discipline": "Civil",\n "category": "Correspondence",\n "date": "2026-05-20",\n "confidence": 0.95,\n "tags": ["foundation", "inspection", "concrete"],\n "summary": "This document is a foundation inspection report for the LCBP3 project, confirming concrete strength."\n}',
|
||||
JSON_OBJECT(
|
||||
'documentNumber',
|
||||
'string|null',
|
||||
'subject',
|
||||
'string|null',
|
||||
'discipline',
|
||||
'enum:Civil,Mechanical,Electrical,Architectural|null',
|
||||
'category',
|
||||
'enum:Correspondence,Transmittal,Circulation,RFA,Shop Drawing,Contract Drawing|null',
|
||||
'date',
|
||||
'date:YYYY-MM-DD|null',
|
||||
'confidence',
|
||||
'float:0-1',
|
||||
'tags',
|
||||
'string[]',
|
||||
'summary',
|
||||
'string|null'
|
||||
),
|
||||
1,
|
||||
'Migrated from hardcoded prompt in processSandboxExtract / processMigrateDocument (ADR-029)',
|
||||
CURRENT_TIMESTAMP,
|
||||
(
|
||||
SELECT user_id
|
||||
FROM users
|
||||
WHERE username = 'superadmin'
|
||||
LIMIT 1
|
||||
) -- PREREQUISITE: user seed (user.seed.ts) MUST run before this delta;
|
||||
-- 'superadmin' is always the first user inserted per standard deployment order
|
||||
) ON DUPLICATE KEY
|
||||
UPDATE prompt_type = prompt_type;
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
-- File: specs/03-Data-and-Storage/deltas/2026-05-25-grant-ai-permissions-to-superadmin.rollback.sql
|
||||
-- Change Log:
|
||||
-- - 2026-05-25: Rollback — ลบ ai.* permissions ออกจาก role_id=1 (Superadmin)
|
||||
-- ==========================================================
|
||||
DELETE rp FROM role_permissions rp
|
||||
JOIN permissions p ON rp.permission_id = p.permission_id
|
||||
WHERE rp.role_id = 1
|
||||
AND p.permission_name IN (
|
||||
'ai.suggest',
|
||||
'ai.rag_query',
|
||||
'ai.migration_manage',
|
||||
'ai.audit_log_delete',
|
||||
'ai.read_analytics',
|
||||
'ai.delete_audit'
|
||||
);
|
||||
@@ -1,23 +0,0 @@
|
||||
-- File: specs/03-Data-and-Storage/deltas/2026-05-25-grant-ai-permissions-to-superadmin.sql
|
||||
-- Change Log:
|
||||
-- - 2026-05-25: Grant ai.* permissions ให้ Superadmin (role_id=1) ที่ขาดหายไปจาก seed
|
||||
-- ==========================================================
|
||||
-- Root Cause:
|
||||
-- Seed script (lcbp3-v1.9.0-seed-permissions.sql) รัน:
|
||||
-- INSERT INTO role_permissions SELECT 1, permission_id FROM permissions WHERE is_active = 1
|
||||
-- ก่อนที่ ai.* permissions (permission_id 181-186) จะถูก INSERT เข้า permissions table
|
||||
-- ทำให้ role_id=1 (Superadmin) ไม่มี ai.* ใน role_permissions
|
||||
-- ผลกระทบ: migration_bot (user_id=5, role_id=1) ถูก RbacGuard block ที่ POST /api/ai/jobs
|
||||
-- ==========================================================
|
||||
INSERT IGNORE INTO role_permissions (role_id, permission_id)
|
||||
SELECT 1, permission_id
|
||||
FROM permissions
|
||||
WHERE permission_name IN (
|
||||
'ai.suggest',
|
||||
'ai.rag_query',
|
||||
'ai.migration_manage',
|
||||
'ai.audit_log_delete',
|
||||
'ai.read_analytics',
|
||||
'ai.delete_audit'
|
||||
)
|
||||
AND is_active = 1;
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
-- Rollback Delta: Remove context_config & publicId from ai_prompts & Revert CC whitespace typo
|
||||
-- Date: 2026-05-27
|
||||
-- Related ADR: ADR-030, ADR-019
|
||||
-- ------------------------------------------------------------
|
||||
-- 1. ย้อนกลับตาราง correspondence_recipients ให้มี whitespace ENUM เหมือนเดิม
|
||||
ALTER TABLE correspondence_recipients
|
||||
MODIFY COLUMN recipient_type ENUM('TO', 'CC ') NOT NULL COMMENT 'ประเภทผู้รับ (TO หรือ CC)';
|
||||
|
||||
-- ย้อนคืนข้อมูลจาก CC เป็น CC
|
||||
UPDATE correspondence_recipients
|
||||
SET recipient_type = 'CC '
|
||||
WHERE recipient_type = 'CC';
|
||||
|
||||
-- 2. ลบคอลัมน์ publicId จาก ai_prompts
|
||||
ALTER TABLE ai_prompts DROP COLUMN public_id;
|
||||
|
||||
-- 3. ลบคอลัมน์ context_config จาก ai_prompts
|
||||
ALTER TABLE ai_prompts DROP COLUMN context_config;
|
||||
|
||||
-- 4. ลบ Seed Prompt Version 2 และเปิดใช้งาน Version 1 แทน
|
||||
DELETE FROM ai_prompts
|
||||
WHERE prompt_type = 'ocr_extraction'
|
||||
AND version_number = 2;
|
||||
|
||||
UPDATE ai_prompts
|
||||
SET is_active = 1
|
||||
WHERE prompt_type = 'ocr_extraction'
|
||||
AND version_number = 1;
|
||||
-108
@@ -1,108 +0,0 @@
|
||||
-- Delta: Add context_config & publicId to ai_prompts & Clean up CC whitespace typo
|
||||
-- Date: 2026-05-27
|
||||
-- Related ADR: ADR-030, ADR-019
|
||||
-- Applied in: v1.9.7 -> main
|
||||
-- ------------------------------------------------------------
|
||||
-- 1. ล้าง whitespace typo 'CC ' ในตารางผู้รับเอกสาร
|
||||
-- อัปเดตข้อมูลเก่าให้เรียบร้อยก่อนเพื่อไม่ให้เกิดข้อผิดพลาดในการเปลี่ยน Schema
|
||||
UPDATE correspondence_recipients
|
||||
SET recipient_type = 'CC'
|
||||
WHERE recipient_type = 'CC ';
|
||||
|
||||
-- แก้ไขประเภทคอลัมน์ของ correspondence_recipients ตัดช่องว่างออก
|
||||
ALTER TABLE correspondence_recipients
|
||||
MODIFY COLUMN recipient_type ENUM('TO', 'CC') NOT NULL COMMENT 'ประเภทผู้รับ (TO หรือ CC)';
|
||||
|
||||
-- 2. เพิ่มคอลัมน์ publicId (UUID) ใน ai_prompts ตาม ADR-019
|
||||
ALTER TABLE ai_prompts
|
||||
ADD COLUMN public_id UUID NULL UNIQUE COMMENT 'Public UUID สำหรับ API exposure (ADR-019)';
|
||||
|
||||
-- สร้าง UUID สำหรับ records ที่มีอยู่เดิม
|
||||
UPDATE ai_prompts
|
||||
SET public_id = UUID()
|
||||
WHERE public_id IS NULL;
|
||||
|
||||
-- ตั้งค่า publicId เป็น NOT NULL หลังจาก populate ข้อมูลเดิม
|
||||
ALTER TABLE ai_prompts
|
||||
MODIFY COLUMN public_id UUID NOT NULL UNIQUE COMMENT 'Public UUID สำหรับ API exposure (ADR-019)';
|
||||
|
||||
-- 3. เพิ่มคอลัมน์ context_config JSON ใน ai_prompts
|
||||
ALTER TABLE ai_prompts
|
||||
ADD COLUMN context_config JSON NULL COMMENT 'Configuration สำหรับ context ที่ backend ต้องส่งให้ AI (filter, pageSize, language, etc.)';
|
||||
|
||||
-- 4. อัปเดต Seed Prompt Version 2 (ภาษาไทย พร้อม Context-Aware layout)
|
||||
-- ปิดใช้งานเวอร์ชัน 1
|
||||
UPDATE ai_prompts
|
||||
SET is_active = 0
|
||||
WHERE prompt_type = 'ocr_extraction'
|
||||
AND version_number = 1;
|
||||
|
||||
-- แทรก Prompt Version 2 (ภาษาไทย) เข้าสู่ตาราง ai_prompts
|
||||
INSERT INTO ai_prompts (
|
||||
prompt_type,
|
||||
version_number,
|
||||
template,
|
||||
field_schema,
|
||||
is_active,
|
||||
context_config,
|
||||
manual_note,
|
||||
activated_at,
|
||||
created_by
|
||||
)
|
||||
VALUES (
|
||||
'ocr_extraction',
|
||||
2,
|
||||
'คุณคือเอนจิ้นสกัดข้อมูลอัจฉริยะ (Document Intelligence Engine)
|
||||
วิเคราะห์ข้อความ OCR ที่ได้รับจากเอกสารของโครงการ Laem Chabang Port Phase 3 และสกัดข้อมูลเมตาดาต้าให้ออกมาเป็น JSON object ที่ถูกต้องตามโครงสร้างที่กำหนด
|
||||
|
||||
ข้อความ OCR ที่สกัดได้:
|
||||
{{ocr_text}}
|
||||
|
||||
ข้อมูลอ้างอิงของระบบ (Master Data Context):
|
||||
{{master_data_context}}
|
||||
|
||||
กฎการสกัดข้อมูล:
|
||||
1. วิเคราะห์และจับคู่ข้อมูลจากข้อความ OCR กับข้อมูลอ้างอิงที่ระบุใน Master Data Context เสมอ
|
||||
2. สำหรับโครงการ (project) ให้ค้นหาและสกัดส่งกลับเป็น UUID ของโครงการ (projectPublicId)
|
||||
3. สำหรับประเภทเอกสารโต้ตอบ (correspondence type) ให้สกัดรหัสส่งกลับมา (correspondenceTypeCode) เช่น RFA, Transmittal
|
||||
4. สำหรับสาขางาน (discipline) ให้ส่งคืนรหัสส่งกลับมา (disciplineCode) เช่น GEN, STR
|
||||
5. สำหรับหน่วยงานผู้ส่ง (originator) ค้นหาจาก availableOrganizations และส่งกลับมาเป็น UUID (originatorOrganizationPublicId)
|
||||
6. สำหรับหน่วยงานผู้รับ (recipients) ให้ส่งกลับมาเป็นรายการ Array ของออบเจกต์ ซึ่งมี UUID ขององค์กร (organizationPublicId) และประเภทผู้รับ (recipientType: "TO" หรือ "CC") เสมอ
|
||||
7. สำหรับหัวข้อเอกสาร (subject) ให้สกัดหัวข้อหรือชื่อเรื่องของเอกสารภาษาไทยหรือภาษาอังกฤษ
|
||||
8. วันที่ของเอกสาร (documentDate) ให้ส่งคืนในรูปแบบ YYYY-MM-DD
|
||||
9. รายการแท็ก (tags) สกัดคำสำคัญหรือคำแนะนำ Tags (สอดคล้องกับ availableTags หากมี)
|
||||
10. สรุปความเนื้อหา (summary) เขียนสรุปรายละเอียดเอกสารสั้นกระชับ 4-5 ประโยคเป็นภาษาไทยอย่างสละสลวย
|
||||
11. confidence: ค่าความมั่นใจในการสกัดข้อมูลนี้ (ทศนิยมระหว่าง 0.0 ถึง 1.0)
|
||||
|
||||
ส่งคืนคำตอบเฉพาะ JSON Object ที่ถูกต้องเท่านั้น ห้ามใส่บล็อกโค้ด markdown หรือคำอธิบายเพิ่มเติมใดๆ
|
||||
โครงสร้าง JSON ผลลัพธ์:
|
||||
{
|
||||
"projectPublicId": "string หรือ null",
|
||||
"correspondenceTypeCode": "string หรือ null",
|
||||
"disciplineCode": "string หรือ null",
|
||||
"originatorOrganizationPublicId": "string หรือ null",
|
||||
"recipients": [
|
||||
{
|
||||
"organizationPublicId": "string",
|
||||
"recipientType": "TO หรือ CC"
|
||||
}
|
||||
],
|
||||
"subject": "string หรือ null",
|
||||
"documentDate": "string:YYYY-MM-DD หรือ null",
|
||||
"tags": ["string"],
|
||||
"summary": "string หรือ null",
|
||||
"confidence": 0.95
|
||||
}',
|
||||
'{"projectPublicId":"string|null","correspondenceTypeCode":"string|null","disciplineCode":"string|null","originatorOrganizationPublicId":"string|null","recipients":"array:object(organizationPublicId:string|null,recipientType:string|null)","subject":"string|null","documentDate":"date:YYYY-MM-DD|null","tags":"string[]","summary":"string|null","confidence":"float:0-1"}',
|
||||
1,
|
||||
'{"filter":null,"pageSize":3,"language":"th","outputLanguage":"th"}',
|
||||
'Seed Prompt ภาษาไทย เวอร์ชัน 2 รองรับ Context-Aware และการล้าง Typo CC (ADR-030)',
|
||||
CURRENT_TIMESTAMP,
|
||||
(
|
||||
SELECT user_id
|
||||
FROM users
|
||||
WHERE username = 'superadmin'
|
||||
LIMIT 1
|
||||
)
|
||||
) ON DUPLICATE KEY
|
||||
UPDATE prompt_type = prompt_type;
|
||||
@@ -1,21 +0,0 @@
|
||||
-- Delta: เพิ่ม publicId column ให้ ai_prompts table เพื่อ ADR-019 compliance
|
||||
-- Date: 2026-05-30
|
||||
-- Related ADR: ADR-019 (Hybrid UUID Strategy)
|
||||
-- Applied in: v1.9.6 -> v1.9.7
|
||||
-- ------------------------------------------------------------
|
||||
-- การเปลี่ยนแปลงโครงสร้างฐานข้อมูล (Schema changes)
|
||||
-- ------------------------------------------------------------
|
||||
-- เพิ่ม publicId column (MariaDB native UUID type ตาม ADR-019)
|
||||
ALTER TABLE ai_prompts
|
||||
ADD COLUMN publicId CHAR(36) UNIQUE COMMENT 'UUIDv7 public identifier (ADR-019)';
|
||||
|
||||
-- Generate UUIDv7 for existing records
|
||||
-- ใช้ MariaDB UUID() function สำหรับสร้าง UUID v4 (fallback)
|
||||
-- หมายเหตุ: UUIDv7 จริงๆ ต้องใช้ timestamp แต่ MariaDB ยังไม่รองรับ UUIDv7 native
|
||||
-- ใช้ UUID() เป็น workaround และจะถูก replace ด้วย UUIDv7 จริงเมื่อ migrate document
|
||||
UPDATE ai_prompts
|
||||
SET publicId = UUID()
|
||||
WHERE publicId IS NULL;
|
||||
|
||||
-- Add index for publicId (optional but recommended for performance)
|
||||
CREATE INDEX idx_ai_prompts_publicId ON ai_prompts(publicId);
|
||||
@@ -1,50 +0,0 @@
|
||||
-- File: specs/03-Data-and-Storage/deltas/2026-05-30-add-typhoon-ocr-prompt.sql
|
||||
-- เพิ่ม Typhoon OCR System Prompt ลงใน ai_prompts table
|
||||
-- ตาม ADR-029: Dynamic Prompt Management, ADR-032: Typhoon OCR Integration
|
||||
-- Change Log:
|
||||
-- - 2026-05-30: Initial seed สำหรับ typhoon_ocr_system prompt (T005)
|
||||
-- - 2026-05-30: Fix: เพิ่ม public_id (UUID) และ context_config (NULL)
|
||||
-- ai_prompts entity มี publicId NOT NULL column ตาม ADR-019 (เพิ่มเมื่อ 2026-05-27)
|
||||
-- ใช้ UUID() ของ MariaDB เพื่อสร้าง UUIDv4 ที่ valid
|
||||
|
||||
INSERT INTO ai_prompts (
|
||||
public_id,
|
||||
prompt_type,
|
||||
version_number,
|
||||
template,
|
||||
field_schema,
|
||||
context_config,
|
||||
is_active,
|
||||
manual_note,
|
||||
activated_at,
|
||||
created_by
|
||||
)
|
||||
SELECT
|
||||
UUID(),
|
||||
'typhoon_ocr_system',
|
||||
1,
|
||||
'สกัดข้อความภาษาไทยและอังกฤษทั้งหมดจากภาพนี้อย่างถูกต้อง รักษาโครงสร้างบรรทัดและการเว้นวรรคให้ใกล้เคียงต้นฉบับมากที่สุด ห้ามเพิ่มคำอธิบายใดๆ',
|
||||
JSON_OBJECT(
|
||||
'type', 'system_prompt',
|
||||
'model', 'scb10x/typhoon-ocr-3b',
|
||||
'temperature', 0.0,
|
||||
'top_p', 0.9,
|
||||
'repeat_penalty', 1.0,
|
||||
'keep_alive', 0
|
||||
),
|
||||
NULL,
|
||||
1,
|
||||
'System prompt สำหรับ Typhoon OCR-3B เพื่อสกัดข้อความภาษาไทย/อังกฤษจากภาพเอกสาร (ADR-032)',
|
||||
CURRENT_TIMESTAMP,
|
||||
(
|
||||
SELECT user_id
|
||||
FROM users
|
||||
WHERE username = 'superadmin'
|
||||
LIMIT 1
|
||||
)
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM ai_prompts
|
||||
WHERE prompt_type = 'typhoon_ocr_system'
|
||||
AND version_number = 1
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE prompt_type = prompt_type;
|
||||
@@ -1,21 +0,0 @@
|
||||
-- File: specs/03-Data-and-Storage/deltas/2026-05-30-extend-ai-audit-logs.sql
|
||||
-- เพิ่ม fields สำหรับ Typhoon OCR integration ใน ai_audit_logs
|
||||
-- ตาม ADR-032: modelType, vramUsageMB, cacheHit
|
||||
-- Change Log:
|
||||
-- - 2026-05-30: Initial delta สำหรับ Typhoon OCR audit fields (T004)
|
||||
|
||||
-- เพิ่ม modelType: ระบุประเภทของ model ที่ใช้ (tesseract, typhoon-ocr-3b, typhoon2.1-gemma3-4b)
|
||||
ALTER TABLE ai_audit_logs
|
||||
ADD COLUMN IF NOT EXISTS model_type VARCHAR(50) NULL COMMENT 'ประเภท OCR/LLM model ที่ใช้ เช่น tesseract, typhoon-ocr-3b' AFTER model_name;
|
||||
|
||||
-- เพิ่ม vramUsageMB: การใช้ VRAM จริง (MB) หลังประมวลผล
|
||||
ALTER TABLE ai_audit_logs
|
||||
ADD COLUMN IF NOT EXISTS vram_usage_mb INT NULL COMMENT 'VRAM ที่ใช้จริง (MB) ณ เวลาประมวลผล' AFTER model_type;
|
||||
|
||||
-- เพิ่ม cacheHit: ระบุว่าผลลัพธ์นี้มาจาก Redis cache หรือ OCR จริง
|
||||
ALTER TABLE ai_audit_logs
|
||||
ADD COLUMN IF NOT EXISTS cache_hit TINYINT(1) NOT NULL DEFAULT 0 COMMENT '1 = ผลลัพธ์มาจาก Redis cache, 0 = OCR ใหม่' AFTER vram_usage_mb;
|
||||
|
||||
-- เพิ่ม index สำหรับ model_type เพื่อ analytics queries
|
||||
ALTER TABLE ai_audit_logs
|
||||
ADD INDEX IF NOT EXISTS idx_ai_audit_model_type (model_type);
|
||||
@@ -1,24 +0,0 @@
|
||||
-- Delta: Seed Typhoon model option into ai_available_models
|
||||
-- Date: 2026-05-30
|
||||
-- Related: ADR-027, ADR-032, specs/200-fullstacks/232-typhoon-ocr-integration
|
||||
|
||||
INSERT INTO ai_available_models (
|
||||
model_name,
|
||||
model_version,
|
||||
description,
|
||||
vram_gb,
|
||||
is_active,
|
||||
is_default
|
||||
)
|
||||
SELECT
|
||||
'typhoon2.1-gemma3-4b',
|
||||
'4b',
|
||||
'Typhoon 2.1 Gemma3 4B - Thai-focused local LLM option for AI Admin Console',
|
||||
4.50,
|
||||
TRUE,
|
||||
FALSE
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM ai_available_models
|
||||
WHERE model_name = 'typhoon2.1-gemma3-4b'
|
||||
);
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
-- File: specs/03-Data-and-Storage/deltas/2026-06-02-add-temp-attachment-id-to-migration-review-queue.rollback.sql
|
||||
-- Change Log:
|
||||
-- - 2026-06-02: ลบคอลัมน์ temp_attachment_id ออกจากตาราง migration_review_queue
|
||||
|
||||
-- Rollback Delta: ลบคอลัมน์ temp_attachment_id ออกจากตาราง migration_review_queue
|
||||
-- Date: 2026-06-02
|
||||
-- Related ADR: ADR-028, ADR-023A
|
||||
-- Applied in: v1.9.8
|
||||
|
||||
ALTER TABLE migration_review_queue
|
||||
DROP COLUMN temp_attachment_id;
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
-- File: specs/03-Data-and-Storage/deltas/2026-06-02-add-temp-attachment-id-to-migration-review-queue.sql
|
||||
-- Change Log:
|
||||
-- - 2026-06-02: เพิ่มคอลัมน์ temp_attachment_id ในตาราง migration_review_queue เพื่อแก้บั๊ก CleanupTempFilesWorker
|
||||
|
||||
-- Delta: เพิ่มคอลัมน์ temp_attachment_id ในตาราง migration_review_queue
|
||||
-- Date: 2026-06-02
|
||||
-- Related ADR: ADR-028, ADR-023A
|
||||
-- Applied in: v1.9.8
|
||||
|
||||
-- ------------------------------------------------------------
|
||||
-- การปรับปรุงตาราง migration_review_queue (Schema changes)
|
||||
-- ------------------------------------------------------------
|
||||
|
||||
ALTER TABLE migration_review_queue
|
||||
ADD COLUMN temp_attachment_id INT NULL COMMENT 'Temporary attachment ID referencing attachments.id (ADR-028)'
|
||||
AFTER STATUS;
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
-- Rollback: Revert ai_available_models to gemma4 stack (undo ADR-034 delta)
|
||||
-- Date: 2026-06-03
|
||||
-- Pair: 2026-06-03-update-ai-available-models-typhoon.sql
|
||||
|
||||
-- 1. Remove Typhoon models
|
||||
DELETE FROM ai_available_models
|
||||
WHERE model_name IN ('typhoon2.5-np-dms:latest', 'typhoon-np-dms-ocr:latest');
|
||||
|
||||
-- 2. Restore gemma4:e2b as default
|
||||
UPDATE ai_available_models
|
||||
SET is_default = TRUE, updated_at = NOW()
|
||||
WHERE model_name = 'gemma4:e2b';
|
||||
|
||||
-- 3. Revert system_settings active model
|
||||
UPDATE system_settings
|
||||
SET setting_value = 'gemma4:e2b',
|
||||
updated_at = NOW()
|
||||
WHERE setting_key = 'AI_ACTIVE_MODEL';
|
||||
@@ -1,49 +0,0 @@
|
||||
-- Delta: Update ai_available_models for Thai-Optimized Model Stack (ADR-034)
|
||||
-- Date: 2026-06-03
|
||||
-- Author: AI Assistant
|
||||
-- Related: ADR-034 — Thai-Optimized AI Model Stack, supersedes ADR-023A Section 2.1
|
||||
-- Rollback: 2026-06-03-update-ai-available-models-typhoon.rollback.sql
|
||||
|
||||
-- 1. Insert new main model (typhoon2.5-np-dms) as default, demote old defaults
|
||||
INSERT INTO ai_available_models (model_name, model_version, description, vram_gb, is_active, is_default)
|
||||
VALUES (
|
||||
'typhoon2.5-np-dms:latest',
|
||||
'latest',
|
||||
'Thai-optimized main AI model based on typhoon2.5-qwen3-4b (~2.5GB VRAM, standby mode) — ADR-034',
|
||||
2.50,
|
||||
TRUE,
|
||||
TRUE
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
description = VALUES(description),
|
||||
vram_gb = VALUES(vram_gb),
|
||||
is_active = TRUE,
|
||||
is_default = TRUE,
|
||||
updated_at = NOW();
|
||||
|
||||
-- Demote old gemma4 models from default status
|
||||
UPDATE ai_available_models
|
||||
SET is_default = FALSE, updated_at = NOW()
|
||||
WHERE model_name IN ('gemma4:e2b', 'gemma4:e4b', 'typhoon2.1-gemma3-4b');
|
||||
|
||||
-- 2. Insert OCR model (typhoon-np-dms-ocr) — not default, keep_alive=0 (unload after each job)
|
||||
INSERT INTO ai_available_models (model_name, model_version, description, vram_gb, is_active, is_default)
|
||||
VALUES (
|
||||
'typhoon-np-dms-ocr:latest',
|
||||
'latest',
|
||||
'Thai OCR model based on typhoon-ocr1.5-3b (~3.2GB VRAM, unloads after each job) — ADR-034',
|
||||
3.20,
|
||||
TRUE,
|
||||
FALSE
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
description = VALUES(description),
|
||||
vram_gb = VALUES(vram_gb),
|
||||
is_active = TRUE,
|
||||
updated_at = NOW();
|
||||
|
||||
-- 3. Update active model in system_settings to typhoon2.5-np-dms:latest
|
||||
UPDATE system_settings
|
||||
SET setting_value = 'typhoon2.5-np-dms:latest',
|
||||
updated_at = NOW()
|
||||
WHERE setting_key = 'AI_ACTIVE_MODEL';
|
||||
@@ -1,8 +0,0 @@
|
||||
-- File: specs/03-Data-and-Storage/deltas/2026-06-05-add-rag-chunking-prompt.rollback.sql
|
||||
-- Rollback การเพิ่ม Prompt สำหรับ Semantic Chunking
|
||||
-- Change Log:
|
||||
-- - 2026-06-05: Initial rollback (T002)
|
||||
|
||||
DELETE FROM ai_prompts
|
||||
WHERE prompt_type = 'rag_chunking'
|
||||
AND version_number = 1;
|
||||
@@ -1,47 +0,0 @@
|
||||
-- File: specs/03-Data-and-Storage/deltas/2026-06-05-add-rag-chunking-prompt.sql
|
||||
-- เพิ่ม Prompt สำหรับ Semantic Chunking ลงใน ai_prompts table
|
||||
-- ตาม ADR-035 และ FR-004a
|
||||
-- Change Log:
|
||||
-- - 2026-06-05: Initial seed สำหรับ rag_chunking prompt (T002)
|
||||
|
||||
INSERT INTO ai_prompts (
|
||||
public_id,
|
||||
prompt_type,
|
||||
version_number,
|
||||
template,
|
||||
field_schema,
|
||||
context_config,
|
||||
is_active,
|
||||
manual_note,
|
||||
activated_at,
|
||||
created_by
|
||||
)
|
||||
SELECT
|
||||
UUID(),
|
||||
'rag_chunking',
|
||||
1,
|
||||
'คุณเป็นผู้ช่วยวิเคราะห์เอกสารและแบ่งเนื้อหาเป็นส่วนๆ ตามหัวข้อ (Semantic Chunking)\nหน้าที่ของคุณคืออ่านข้อความเอกสารที่ได้จาก OCR ด้านล่างนี้ แล้วแบ่งเอกสารออกเป็นชิ้นๆ (Chunks) ตามเนื้อหาและหัวข้อหลัก\nสำหรับแต่ละส่วนที่คุณแบ่ง ให้ล้อมรอบด้วยแท็ก <chunk topic=\"หัวข้อหลักของเนื้อหาส่วนนี้\"> [เนื้อหาในส่วนนี้] </chunk>\n\nกฎในการแบ่งข้อมูล:\n1. ห้ามแก้ไขคำหรือข้อความใดๆ ในเอกสารเด็ดขาด ให้ใช้ข้อความดั้งเดิมจาก OCR ทั้งหมด\n2. พยายามแบ่งส่วนตามขอบเขตเนื้อหาที่สมเหตุสมผล เช่น เมื่อขึ้นหัวข้อใหม่ หรือส่วนเนื้อความที่คนละประเด็นกัน\n3. แต่ละส่วนควรมีความยาวที่อ่านเข้าใจได้และไม่ยาวจนเกินไป\n4. ห้ามตอบข้อความบทนำหรือบทสรุปใดๆ นอกเหนือจากแท็ก <chunk> และข้อความภายในแท็ก\n\nข้อความเอกสาร OCR:\n{{ocr_text}}',
|
||||
JSON_OBJECT(
|
||||
'type', 'semantic_chunking',
|
||||
'model', 'typhoon2.5-np-dms:latest',
|
||||
'temperature', 0.1,
|
||||
'top_p', 0.9,
|
||||
'repeat_penalty', 1.1,
|
||||
'keep_alive', -1
|
||||
),
|
||||
NULL,
|
||||
1,
|
||||
'Prompt สำหรับแบ่งข้อความจาก OCR เป็น Chunk ตามหัวข้อความหมายด้วย typhoon2.5 (ADR-035)',
|
||||
CURRENT_TIMESTAMP,
|
||||
(
|
||||
SELECT user_id
|
||||
FROM users
|
||||
WHERE username = 'superadmin'
|
||||
LIMIT 1
|
||||
)
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM ai_prompts
|
||||
WHERE prompt_type = 'rag_chunking'
|
||||
AND version_number = 1
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE prompt_type = prompt_type;
|
||||
@@ -1,23 +0,0 @@
|
||||
-- Delta: เพิ่ม public_id และ context_config columns ใน ai_prompts
|
||||
-- Date: 2026-06-06
|
||||
-- Related ADR: ADR-019 (UUID strategy), ADR-029 (Dynamic Prompts)
|
||||
-- ------------------------------------------------------------
|
||||
-- การเปลี่ยนแปลงโครงสร้างฐานข้อมูล (Schema changes)
|
||||
-- ------------------------------------------------------------
|
||||
|
||||
-- เพิ่ม public_id column (UUIDv7) สำหรับ ADR-019 compliance
|
||||
ALTER TABLE ai_prompts
|
||||
ADD COLUMN public_id UUID UNIQUE COMMENT 'Public UUID สำหรับ API (ADR-019)';
|
||||
|
||||
-- เพิ่ม context_config column สำหรับ ADR-029 context filtering
|
||||
ALTER TABLE ai_prompts
|
||||
ADD COLUMN context_config JSON NULL COMMENT 'Configuration สำหรับ Master Data context filtering (project/contract scope)';
|
||||
|
||||
-- สร้าง UUID สำหรับ records ที่มีอยู่แล้ว
|
||||
UPDATE ai_prompts
|
||||
SET public_id = UUID()
|
||||
WHERE public_id IS NULL;
|
||||
|
||||
-- ตั้ง public_id เป็น NOT NULL หลังจาก populate ครบแล้ว
|
||||
ALTER TABLE ai_prompts
|
||||
MODIFY COLUMN public_id UUID NOT NULL;
|
||||
@@ -1,6 +0,0 @@
|
||||
-- Rollback: ลบตาราง ai_execution_profiles
|
||||
-- Date: 2026-06-11
|
||||
-- Related Delta: 2026-06-11-create-ai-execution-profiles.sql
|
||||
-- ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS ai_execution_profiles;
|
||||
@@ -1,38 +0,0 @@
|
||||
-- Delta: สร้างตาราง ai_execution_profiles สำหรับ AI Runtime Policy Refactor
|
||||
-- Date: 2026-06-11
|
||||
-- Related ADR: ADR-029, Feature-235
|
||||
-- Source of defaults: docs/ai-profiles.md
|
||||
-- Applied in: v1.9.x (AI Runtime Policy Refactor cutover)
|
||||
-- ------------------------------------------------------------
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ai_execution_profiles (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ภายใน (ไม่ expose ใน API)',
|
||||
profile_name VARCHAR(50) NOT NULL COMMENT 'ชื่อ profile: interactive, standard, quality, deep-analysis',
|
||||
temperature DECIMAL(4,3) NOT NULL COMMENT 'LLM temperature parameter',
|
||||
top_p DECIMAL(4,3) NOT NULL COMMENT 'LLM top_p parameter',
|
||||
max_tokens INT NOT NULL COMMENT 'Maximum tokens to generate',
|
||||
num_ctx INT NOT NULL COMMENT 'Context window size (tokens)',
|
||||
repeat_penalty DECIMAL(5,3) NOT NULL COMMENT 'Repeat penalty parameter',
|
||||
keep_alive_seconds INT NOT NULL COMMENT 'Model keep_alive in seconds (0 = unload immediately)',
|
||||
is_active TINYINT(1) NOT NULL DEFAULT 1 COMMENT '1 = profile นี้ใช้งานได้; 0 = disabled',
|
||||
updated_by INT NULL COMMENT 'user_id ที่แก้ไขล่าสุด (NULL = seed default)',
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY uk_profile_name (profile_name),
|
||||
INDEX idx_profile_active (profile_name, is_active),
|
||||
FOREIGN KEY (updated_by) REFERENCES users(user_id)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci
|
||||
COMMENT = 'ตาราง execution profile parameters สำหรับ np-dms-ai (ADR-029, Feature-235); ค่า default จาก docs/ai-profiles.md';
|
||||
|
||||
-- ------------------------------------------------------------
|
||||
-- Seed: default profiles จาก docs/ai-profiles.md
|
||||
-- ------------------------------------------------------------
|
||||
INSERT INTO ai_execution_profiles (
|
||||
profile_name, temperature, top_p, max_tokens, num_ctx, repeat_penalty, keep_alive_seconds
|
||||
) VALUES
|
||||
('interactive', 0.700, 0.900, 2048, 4096, 1.150, 300), -- keep_alive: "5m"
|
||||
('standard', 0.500, 0.800, 4096, 8192, 1.150, 600), -- keep_alive: "10m"
|
||||
('quality', 0.100, 0.950, 8192, 8192, 1.150, 600), -- keep_alive: "10m"
|
||||
('deep-analysis', 0.300, 0.850, 8192, 32768, 1.150, 0) -- keep_alive: "0" (admin sandbox only)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
profile_name = profile_name; -- no-op: ไม่ overwrite ค่าที่ admin calibrate ไว้แล้ว
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
-- Rollback: ลบ fields ที่เพิ่มสำหรับ AI Runtime Policy Refactor
|
||||
-- Date: 2026-06-11
|
||||
-- Related Delta: 2026-06-11-extend-ai-audit-logs-runtime-policy.sql
|
||||
-- ------------------------------------------------------------
|
||||
|
||||
ALTER TABLE ai_audit_logs
|
||||
DROP INDEX IF EXISTS idx_ai_audit_canonical_model;
|
||||
|
||||
ALTER TABLE ai_audit_logs
|
||||
DROP INDEX IF EXISTS idx_ai_audit_effective_profile;
|
||||
|
||||
ALTER TABLE ai_audit_logs
|
||||
DROP COLUMN IF EXISTS snapshot_params_json;
|
||||
|
||||
ALTER TABLE ai_audit_logs
|
||||
DROP COLUMN IF EXISTS canonical_model;
|
||||
|
||||
ALTER TABLE ai_audit_logs
|
||||
DROP COLUMN IF EXISTS effective_profile;
|
||||
@@ -1,37 +0,0 @@
|
||||
-- Delta: เพิ่ม fields สำหรับ AI Runtime Policy Refactor ใน ai_audit_logs
|
||||
-- Date: 2026-06-11
|
||||
-- Related ADR: ADR-023, ADR-029, Feature-235
|
||||
-- Applied in: AI Runtime Policy Refactor cutover (big bang)
|
||||
-- ------------------------------------------------------------
|
||||
-- เพิ่ม 3 columns:
|
||||
-- effective_profile — profile name ที่ backend กำหนด (interactive/standard/quality/deep-analysis)
|
||||
-- canonical_model — canonical model identity (np-dms-ai / np-dms-ocr)
|
||||
-- snapshot_params_json — parameters snapshot ณ เวลา dispatch (FR-A09)
|
||||
-- ------------------------------------------------------------
|
||||
|
||||
-- effective_profile: ชื่อ ExecutionProfile ที่ backend กำหนดจาก job.type
|
||||
ALTER TABLE ai_audit_logs
|
||||
ADD COLUMN IF NOT EXISTS effective_profile VARCHAR(50) NULL
|
||||
COMMENT 'ExecutionProfile ที่ backend กำหนด: interactive|standard|quality|deep-analysis (Feature-235)'
|
||||
AFTER model_name;
|
||||
|
||||
-- canonical_model: ชื่อ canonical identity — ไม่ใช่ runtime tag
|
||||
ALTER TABLE ai_audit_logs
|
||||
ADD COLUMN IF NOT EXISTS canonical_model VARCHAR(50) NULL
|
||||
COMMENT 'Canonical model identity: np-dms-ai หรือ np-dms-ocr (Feature-235, ADR-023)'
|
||||
AFTER effective_profile;
|
||||
|
||||
-- snapshot_params_json: parameters ที่ถูก snapshot ตอน dispatch โดย AiPolicyService (FR-A09)
|
||||
-- { temperature, topP, maxTokens, numCtx, repeatPenalty, keepAliveSeconds }
|
||||
ALTER TABLE ai_audit_logs
|
||||
ADD COLUMN IF NOT EXISTS snapshot_params_json JSON NULL
|
||||
COMMENT 'Runtime parameters snapshot ณ เวลา dispatch — ใช้จริงใน Ollama call (FR-A09, Feature-235)'
|
||||
AFTER canonical_model;
|
||||
|
||||
-- index สำหรับ analytics queries ตาม profile
|
||||
ALTER TABLE ai_audit_logs
|
||||
ADD INDEX IF NOT EXISTS idx_ai_audit_effective_profile (effective_profile);
|
||||
|
||||
-- index สำหรับ canonical_model
|
||||
ALTER TABLE ai_audit_logs
|
||||
ADD INDEX IF NOT EXISTS idx_ai_audit_canonical_model (canonical_model);
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
-- File: specs/03-Data-and-Storage/deltas/2026-06-13-extend-ai-execution-profiles-ocr.rollback.sql
|
||||
-- Change Log:
|
||||
-- - 2026-06-13: Rollback for ADR-036 OCR execution profile extension.
|
||||
|
||||
DROP TABLE IF EXISTS ai_sandbox_profiles;
|
||||
|
||||
DELETE FROM ai_execution_profiles
|
||||
WHERE profile_name = 'ocr-extract'
|
||||
AND canonical_model = 'np-dms-ocr';
|
||||
|
||||
ALTER TABLE ai_execution_profiles
|
||||
MODIFY COLUMN max_tokens INT NOT NULL COMMENT 'Maximum tokens to generate',
|
||||
MODIFY COLUMN num_ctx INT NOT NULL COMMENT 'Context window size (tokens)';
|
||||
|
||||
ALTER TABLE ai_execution_profiles
|
||||
DROP COLUMN IF EXISTS canonical_model;
|
||||
@@ -1,58 +0,0 @@
|
||||
-- File: specs/03-Data-and-Storage/deltas/2026-06-13-extend-ai-execution-profiles-ocr.sql
|
||||
-- Change Log:
|
||||
-- - 2026-06-13: ADR-036 — extend execution profiles for OCR defaults and sandbox drafts.
|
||||
|
||||
-- ADR-036: production parameter store remains ai_execution_profiles.
|
||||
ALTER TABLE ai_execution_profiles
|
||||
ADD COLUMN IF NOT EXISTS canonical_model VARCHAR(20) NOT NULL DEFAULT 'np-dms-ai'
|
||||
COMMENT 'Canonical model identity: np-dms-ai หรือ np-dms-ocr'
|
||||
AFTER profile_name;
|
||||
|
||||
ALTER TABLE ai_execution_profiles
|
||||
MODIFY COLUMN max_tokens INT NULL COMMENT 'Maximum tokens to generate; NULL when model does not use token limit',
|
||||
MODIFY COLUMN num_ctx INT NULL COMMENT 'Context window size; NULL when model does not use context window';
|
||||
|
||||
INSERT INTO ai_execution_profiles (
|
||||
profile_name,
|
||||
canonical_model,
|
||||
temperature,
|
||||
top_p,
|
||||
max_tokens,
|
||||
num_ctx,
|
||||
repeat_penalty,
|
||||
keep_alive_seconds,
|
||||
is_active
|
||||
) VALUES (
|
||||
'ocr-extract',
|
||||
'np-dms-ocr',
|
||||
0.100,
|
||||
0.100,
|
||||
NULL,
|
||||
NULL,
|
||||
1.100,
|
||||
0,
|
||||
1
|
||||
) ON DUPLICATE KEY UPDATE
|
||||
canonical_model = VALUES(canonical_model),
|
||||
max_tokens = VALUES(max_tokens),
|
||||
num_ctx = VALUES(num_ctx);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ai_sandbox_profiles (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ภายใน (ไม่ expose ใน API)',
|
||||
profile_name VARCHAR(50) NOT NULL COMMENT 'ชื่อ profile หรือ model-defaults row เช่น ocr-extract',
|
||||
canonical_model VARCHAR(20) NOT NULL DEFAULT 'np-dms-ai' COMMENT 'Canonical model identity: np-dms-ai หรือ np-dms-ocr',
|
||||
temperature DECIMAL(4,3) NOT NULL COMMENT 'Model temperature parameter',
|
||||
top_p DECIMAL(4,3) NOT NULL COMMENT 'Model top_p parameter',
|
||||
max_tokens INT NULL COMMENT 'Maximum tokens to generate; NULL for OCR',
|
||||
num_ctx INT NULL COMMENT 'Context window size; NULL for OCR',
|
||||
repeat_penalty DECIMAL(5,3) NOT NULL COMMENT 'Repeat penalty parameter',
|
||||
keep_alive_seconds INT NOT NULL COMMENT 'Model keep_alive in seconds; resource policy remains ADR-033',
|
||||
updated_by INT NULL COMMENT 'user_id ที่แก้ไขล่าสุด',
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY uk_ai_sandbox_profile_name (profile_name),
|
||||
INDEX idx_ai_sandbox_profile_model (canonical_model),
|
||||
CONSTRAINT fk_ai_sandbox_profiles_updated_by
|
||||
FOREIGN KEY (updated_by) REFERENCES users(user_id)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci
|
||||
COMMENT = 'Sandbox draft execution profile parameters สำหรับ ADR-036';
|
||||
@@ -1,42 +0,0 @@
|
||||
-- File: specs/03-Data-and-Storage/deltas/2026-06-14-create-ai-execution-profiles.sql
|
||||
-- Change Log:
|
||||
-- - 2026-06-14: Created ai_execution_profiles and ai_sandbox_profiles tables (conforming to task T001)
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ai_execution_profiles (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ภายใน',
|
||||
profile_name VARCHAR(50) NOT NULL COMMENT 'ชื่อ profile',
|
||||
canonical_model VARCHAR(20) NOT NULL DEFAULT 'np-dms-ai' COMMENT 'Model identity',
|
||||
temperature DECIMAL(4,3) NOT NULL COMMENT 'LLM temperature',
|
||||
top_p DECIMAL(4,3) NOT NULL COMMENT 'LLM top_p',
|
||||
max_tokens INT NULL COMMENT 'Maximum tokens',
|
||||
num_ctx INT NULL COMMENT 'Context window size',
|
||||
repeat_penalty DECIMAL(5,3) NOT NULL COMMENT 'Repeat penalty',
|
||||
keep_alive_seconds INT NOT NULL COMMENT 'Model keep_alive in seconds',
|
||||
is_active TINYINT(1) NOT NULL DEFAULT 1 COMMENT '1 = active; 0 = disabled',
|
||||
updated_by INT NULL COMMENT 'user_id',
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY uk_profile_name (profile_name),
|
||||
INDEX idx_profile_active (profile_name, is_active),
|
||||
FOREIGN KEY (updated_by) REFERENCES users(user_id)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci
|
||||
COMMENT = 'ตาราง execution profile parameters สำหรับ np-dms-ai';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ai_sandbox_profiles (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ภายใน',
|
||||
profile_name VARCHAR(50) NOT NULL COMMENT 'ชื่อ profile',
|
||||
canonical_model VARCHAR(20) NOT NULL DEFAULT 'np-dms-ai' COMMENT 'Model identity',
|
||||
temperature DECIMAL(4,3) NOT NULL COMMENT 'LLM temperature',
|
||||
top_p DECIMAL(4,3) NOT NULL COMMENT 'LLM top_p',
|
||||
max_tokens INT NULL COMMENT 'Maximum tokens',
|
||||
num_ctx INT NULL COMMENT 'Context window size',
|
||||
repeat_penalty DECIMAL(5,3) NOT NULL COMMENT 'Repeat penalty',
|
||||
keep_alive_seconds INT NOT NULL COMMENT 'Model keep_alive in seconds',
|
||||
updated_by INT NULL COMMENT 'user_id',
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY uk_ai_sandbox_profile_name (profile_name),
|
||||
INDEX idx_ai_sandbox_profile_model (canonical_model),
|
||||
FOREIGN KEY (updated_by) REFERENCES users(user_id)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci
|
||||
COMMENT = 'ตาราง sandbox profile parameters';
|
||||
@@ -1,54 +0,0 @@
|
||||
-- File: specs/03-Data-and-Storage/deltas/2026-06-14-seed-additional-prompt-types.sql
|
||||
-- Change Log:
|
||||
-- - 2026-06-14: Seed additional prompt types for RAG Query, RAG Prep, and Classification (conforming to task T003)
|
||||
|
||||
INSERT INTO ai_prompts (
|
||||
public_id,
|
||||
prompt_type,
|
||||
version_number,
|
||||
template,
|
||||
field_schema,
|
||||
context_config,
|
||||
is_active,
|
||||
manual_note,
|
||||
activated_at,
|
||||
created_by
|
||||
) VALUES
|
||||
(
|
||||
UUID(),
|
||||
'rag_query_prompt',
|
||||
1,
|
||||
'You are a professional assistant analyzing project documents. Based on the provided context, answer the user query.\n\nContext:\n{{context}}\n\nUser Query:\n{{ocr_text}}\n\nAnswer:',
|
||||
NULL,
|
||||
NULL,
|
||||
1,
|
||||
'Initial seed for RAG query prompt',
|
||||
CURRENT_TIMESTAMP,
|
||||
(SELECT user_id FROM users WHERE username = 'superadmin' LIMIT 1)
|
||||
),
|
||||
(
|
||||
UUID(),
|
||||
'rag_prep_prompt',
|
||||
1,
|
||||
'Analyze the following OCR text and prepare chunks for retrieval database.\n\nOCR TEXT:\n{{ocr_text}}\n\nChunks:',
|
||||
NULL,
|
||||
NULL,
|
||||
1,
|
||||
'Initial seed for RAG prep prompt',
|
||||
CURRENT_TIMESTAMP,
|
||||
(SELECT user_id FROM users WHERE username = 'superadmin' LIMIT 1)
|
||||
),
|
||||
(
|
||||
UUID(),
|
||||
'classification_prompt',
|
||||
1,
|
||||
'Classify the following document based on its OCR text.\n\nOCR TEXT:\n{{ocr_text}}\n\nClassification (Correspondence, Transmittal, Circulation, RFA, Shop Drawing, Contract Drawing):',
|
||||
NULL,
|
||||
NULL,
|
||||
1,
|
||||
'Initial seed for Classification prompt',
|
||||
CURRENT_TIMESTAMP,
|
||||
(SELECT user_id FROM users WHERE username = 'superadmin' LIMIT 1)
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
prompt_type = prompt_type;
|
||||
@@ -1,21 +0,0 @@
|
||||
-- File: specs/03-Data-and-Storage/deltas/2026-06-14-seed-execution-profiles.sql
|
||||
-- Change Log:
|
||||
-- - 2026-06-14: Seed default profiles for execution profiles (conforming to task T002)
|
||||
|
||||
INSERT INTO ai_execution_profiles (
|
||||
profile_name, canonical_model, temperature, top_p, max_tokens, num_ctx, repeat_penalty, keep_alive_seconds, is_active
|
||||
) VALUES
|
||||
('interactive', 'np-dms-ai', 0.700, 0.900, 2048, 4096, 1.150, 300, 1),
|
||||
('standard', 'np-dms-ai', 0.500, 0.800, 4096, 8192, 1.150, 600, 1),
|
||||
('quality', 'np-dms-ai', 0.100, 0.950, 8192, 8192, 1.150, 600, 1),
|
||||
('deep-analysis', 'np-dms-ai', 0.300, 0.850, 8192, 32768, 1.150, 0, 1),
|
||||
('ocr-extract', 'np-dms-ocr', 0.100, 0.100, NULL, NULL, 1.100, 0, 1)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
canonical_model = VALUES(canonical_model),
|
||||
temperature = VALUES(temperature),
|
||||
top_p = VALUES(top_p),
|
||||
max_tokens = VALUES(max_tokens),
|
||||
num_ctx = VALUES(num_ctx),
|
||||
repeat_penalty = VALUES(repeat_penalty),
|
||||
keep_alive_seconds = VALUES(keep_alive_seconds),
|
||||
is_active = VALUES(is_active);
|
||||
@@ -1,10 +0,0 @@
|
||||
-- Delta: 2026-06-15-fix-ai-prompts-columns.sql
|
||||
-- Fix: (1) Drop duplicate camelCase publicId column (TypeORM mapping bug)
|
||||
-- (2) Add version column for optimistic locking (T066)
|
||||
-- ADR-009: Edit schema directly, no TypeORM migrations
|
||||
|
||||
-- ลบ duplicate column ที่ TypeORM สร้างผิด (camelCase แทน snake_case)
|
||||
ALTER TABLE ai_prompts DROP COLUMN IF EXISTS `publicId`;
|
||||
|
||||
-- เพิ่ม version column สำหรับ @VersionColumn (optimistic locking)
|
||||
ALTER TABLE ai_prompts ADD COLUMN IF NOT EXISTS `version` INT NOT NULL DEFAULT 1;
|
||||
@@ -1,25 +0,0 @@
|
||||
-- Delta: 2026-06-17-seed-ocr-system-prompt.sql
|
||||
-- Purpose: Seed default OCR system prompt for np-dms-ocr model (Feature 238)
|
||||
-- ADR-009: Edit schema directly, no TypeORM migrations
|
||||
|
||||
-- version column มีอยู่แล้วจาก 2026-06-15-fix-ai-prompts-columns.sql — บรรทัดนี้ idempotent เผื่อ env เก่า
|
||||
ALTER TABLE ai_prompts ADD COLUMN IF NOT EXISTS `version` INT NOT NULL DEFAULT 1;
|
||||
|
||||
-- Seed default OCR system prompt (ถ้ายังไม่มี active ของ type นี้)
|
||||
-- ใช้ created_by INT FK → users(user_id) และ username='superadmin' ตาม pattern ของ delta เดิม
|
||||
INSERT INTO ai_prompts (
|
||||
public_id, prompt_type, version_number, template,
|
||||
context_config, is_active, activated_at, created_by
|
||||
)
|
||||
SELECT
|
||||
UUID(),
|
||||
'ocr_system',
|
||||
1,
|
||||
'Extract all text from this PDF page accurately.',
|
||||
'{"temperature": 0.1, "topP": 0.6}',
|
||||
1,
|
||||
CURRENT_TIMESTAMP,
|
||||
(SELECT user_id FROM users WHERE username = 'superadmin' LIMIT 1)
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM ai_prompts WHERE prompt_type = 'ocr_system' AND is_active = 1
|
||||
);
|
||||
@@ -124,29 +124,12 @@ CREATE TABLE system_settings (
|
||||
updated_by INT COMMENT 'ผู้แก้ไขล่าสุด',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (updated_by) REFERENCES users(user_id) ON DELETE SET NULL,
|
||||
INDEX idx_system_settings_category (category),
|
||||
INDEX idx_system_settings_is_public (is_public)
|
||||
FOREIGN KEY (updated_by) REFERENCES users(user_id) ON DELETE
|
||||
SET NULL,
|
||||
INDEX idx_system_settings_category (category),
|
||||
INDEX idx_system_settings_is_public (is_public)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเก็บข้อมูลการตั้งค่าระบบไดนามิก';
|
||||
|
||||
INSERT INTO system_settings (
|
||||
setting_key,
|
||||
setting_value,
|
||||
data_type,
|
||||
category,
|
||||
description,
|
||||
is_public
|
||||
)
|
||||
VALUES (
|
||||
'AI_FEATURES_ENABLED',
|
||||
'true',
|
||||
'boolean',
|
||||
'ai',
|
||||
'สถานะเปิด/ปิดการใช้งานฟีเจอร์ AI ทั้งระบบ สำหรับผู้ใช้ทั่วไป',
|
||||
1
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE setting_key = setting_key;
|
||||
|
||||
-- ตาราง Master เก็บ "บทบาท" ของผู้ใช้ในระบบ
|
||||
CREATE TABLE roles (
|
||||
role_id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
|
||||
@@ -395,31 +378,37 @@ CREATE TABLE correspondence_revisions (
|
||||
-- ตาราง Master เก็บ Tags ทั้งหมดที่ใช้ในระบบ
|
||||
CREATE TABLE tags (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
|
||||
public_id CHAR(36) NOT NULL UNIQUE COMMENT 'UUIDv7 สำหรับการใช้งานภายนอก (ADR-019)',
|
||||
project_id INT NULL COMMENT 'ID โครงการ (NULL = Global Tag)',
|
||||
tag_name VARCHAR(100) NOT NULL COMMENT 'ชื่อ Tag',
|
||||
color_code VARCHAR(30) DEFAULT 'default' COMMENT 'รหัสสี หรือชื่อคลาสสำหรับ UI',
|
||||
description TEXT COMMENT 'คำอธิบายแท็ก',
|
||||
tag_name VARCHAR(100) NOT NULL COMMENT 'ชื่อแท็ก',
|
||||
color_code VARCHAR(30) DEFAULT 'default' COMMENT 'รหัสสีสำหรับ UI',
|
||||
description TEXT COMMENT 'คำอธิบายเพิ่มเติม',
|
||||
created_by INT COMMENT 'ผู้สร้างแท็ก',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่สร้าง',
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'วันที่แก้ไขล่าสุด',
|
||||
created_by INT COMMENT 'ผู้สร้าง',
|
||||
deleted_at DATETIME NULL COMMENT 'ลบแบบ Soft Delete',
|
||||
-- Constraints & Indexes
|
||||
deleted_at TIMESTAMP NULL COMMENT 'วันที่ลบ (Soft Delete)',
|
||||
FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (created_by) REFERENCES users (user_id) ON DELETE
|
||||
SET NULL,
|
||||
UNIQUE KEY ux_tag_project (project_id, tag_name),
|
||||
UNIQUE KEY uq_tag_project (project_id, tag_name),
|
||||
INDEX idx_tags_deleted_at (deleted_at)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตาราง Master เก็บ Tags ย่อยตาม Project';
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเก็บข้อมูลแท็กจัดหมวดหมู่เอกสาร';
|
||||
|
||||
-- ตารางเชื่อมระหว่าง correspondences และ tags (M:N)
|
||||
CREATE TABLE correspondence_tags (
|
||||
correspondence_id INT COMMENT 'ID ของเอกสาร',
|
||||
tag_id INT COMMENT 'ID ของ Tag',
|
||||
correspondence_id INT NOT NULL COMMENT 'ID ของเอกสาร',
|
||||
tag_id INT NOT NULL COMMENT 'ID ของแท็ก',
|
||||
is_ai_suggested BOOLEAN DEFAULT FALSE COMMENT 'แท็กนี้แนะนำโดย AI หรือไม่',
|
||||
confidence DECIMAL(4, 3) NULL COMMENT 'ค่าความมั่นใจของ AI (0.000–1.000)',
|
||||
created_by INT COMMENT 'ผู้เชื่อมโยงแท็ก',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่เชื่อมโยง',
|
||||
PRIMARY KEY (correspondence_id, tag_id),
|
||||
FOREIGN KEY (correspondence_id) REFERENCES correspondences (id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (tag_id) REFERENCES tags (id) ON DELETE CASCADE,
|
||||
INDEX idx_tag_lookup (tag_id)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเชื่อมระหว่าง correspondences และ tags (M:N)';
|
||||
FOREIGN KEY (created_by) REFERENCES users (user_id) ON DELETE
|
||||
SET NULL,
|
||||
INDEX idx_correspondence_tags_lookup (tag_id)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเชื่อมโยงความสัมพันธ์แบบ M:N ระหว่างเอกสารและแท็ก';
|
||||
|
||||
-- ตารางเชื่อมการอ้างอิงระหว่างเอกสาร (M:N)
|
||||
CREATE TABLE correspondence_references (
|
||||
@@ -1017,10 +1006,7 @@ CREATE TABLE contract_drawing_attachments (
|
||||
'OTHER '
|
||||
) COMMENT 'ประเภทไฟล์',
|
||||
is_main_document BOOLEAN DEFAULT FALSE COMMENT '(1 = ไฟล์หลัก)',
|
||||
PRIMARY KEY (
|
||||
contract_drawing_id,
|
||||
attachment_id
|
||||
),
|
||||
PRIMARY KEY (contract_drawing_id, attachment_id),
|
||||
FOREIGN KEY (contract_drawing_id) REFERENCES contract_drawings (id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (attachment_id) REFERENCES attachments (id) ON DELETE CASCADE
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเชื่อม contract_drawings กับ attachments (M :N)';
|
||||
@@ -1042,10 +1028,7 @@ CREATE TABLE document_number_formats (
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'วันที่แก้ไขล่าสุด',
|
||||
FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (correspondence_type_id) REFERENCES correspondence_types (id) ON DELETE CASCADE,
|
||||
UNIQUE KEY unique_format (
|
||||
project_id,
|
||||
correspondence_type_id
|
||||
)
|
||||
UNIQUE KEY unique_format (project_id, correspondence_type_id)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตาราง Master เก็บ "รูปแบบ" Template ของเลขที่เอกสาร';
|
||||
|
||||
-- ==========================================================
|
||||
@@ -1395,11 +1378,7 @@ CREATE TABLE backup_logs (
|
||||
backup_type ENUM('DATABASE', 'FILES', 'FULL') NOT NULL COMMENT 'ประเภท (DATABASE, FILES, FULL)',
|
||||
backup_path VARCHAR(500) NOT NULL COMMENT 'ตำแหน่งไฟล์สำรอง',
|
||||
file_size BIGINT COMMENT 'ขนาดไฟล์',
|
||||
STATUS ENUM(
|
||||
'STARTED',
|
||||
'COMPLETED',
|
||||
'FAILED'
|
||||
) NOT NULL COMMENT 'สถานะ',
|
||||
STATUS ENUM('STARTED', 'COMPLETED', 'FAILED') NOT NULL COMMENT 'สถานะ',
|
||||
started_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'เวลาเริ่มต้น',
|
||||
completed_at TIMESTAMP NULL COMMENT 'เวลาเสร็จสิ้น',
|
||||
error_message TEXT COMMENT 'ข้อความผิดพลาด (ถ้ามี)'
|
||||
@@ -1508,10 +1487,16 @@ CREATE TABLE migration_review_queue (
|
||||
idempotency_key VARCHAR(200) NOT NULL COMMENT 'Idempotency-Key สำหรับป้องกัน queue ซ้ำ',
|
||||
original_filename VARCHAR(500) NOT NULL COMMENT 'ชื่อไฟล์ต้นฉบับจาก legacy source',
|
||||
storage_temp_path VARCHAR(1000) NOT NULL COMMENT 'temp storage path ก่อน import',
|
||||
ai_metadata_json JSON NOT NULL COMMENT 'AI suggestion payload เต็มสำหรับ human review',
|
||||
ai_job_id VARCHAR(36) NULL COMMENT 'BullMQ Job ID สำหรับงานประมวลผล AI',
|
||||
ai_metadata_json LONGTEXT NOT NULL COMMENT 'AI suggestion payload เต็มสำหรับ human review' CHECK (json_valid(`ai_metadata_json`)),
|
||||
confidence_score DECIMAL(5, 4) NOT NULL COMMENT 'AI confidence score 0.0000-1.0000',
|
||||
ocr_used TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'ระบุว่าใช้ OCR path หรือไม่',
|
||||
STATUS ENUM('PENDING', 'APPROVED', 'IMPORTED', 'REJECTED') NOT NULL DEFAULT 'PENDING',
|
||||
STATUS ENUM(
|
||||
'PENDING',
|
||||
'PENDING_REVIEW',
|
||||
'IMPORTED',
|
||||
'REJECTED'
|
||||
) NOT NULL DEFAULT 'PENDING',
|
||||
temp_attachment_id INT NULL COMMENT 'Temporary attachment ID referencing attachments.id (ADR-028)',
|
||||
reviewed_by INT NULL COMMENT 'Internal users.user_id ของผู้ review',
|
||||
reviewed_at DATETIME NULL COMMENT 'เวลาที่ review record',
|
||||
@@ -1536,8 +1521,14 @@ CREATE TABLE ai_audit_logs (
|
||||
document_public_id UUID NULL COMMENT 'Imported document publicId when available',
|
||||
ai_model VARCHAR(50) NOT NULL DEFAULT 'gemma4' COMMENT 'Legacy AI model column used by current gateway service',
|
||||
model_name VARCHAR(100) NOT NULL COMMENT 'Local model name used by ADR-023 AI pipeline',
|
||||
ai_suggestion_json JSON NULL COMMENT 'AI suggested metadata',
|
||||
human_override_json JSON NULL COMMENT 'Human approved or overridden metadata',
|
||||
effective_profile VARCHAR(50) NULL COMMENT 'ExecutionProfile ที่ backend กำหนด: interactive|standard|quality|deep-analysis (Feature-235)',
|
||||
canonical_model VARCHAR(50) NULL COMMENT 'Canonical model identity: np-dms-ai หรือ np-dms-ocr (Feature-235, ADR-023)',
|
||||
snapshot_params_json LONGTEXT NULL COMMENT 'Runtime parameters snapshot ณ เวลา dispatch — ใช้จริงใน Ollama call (FR-A09, Feature-235)' CHECK (json_valid(`snapshot_params_json`)),
|
||||
model_type VARCHAR(50) NULL COMMENT 'ประเภท OCR/LLM model ที่ใช้ เช่น tesseract, typhoon-ocr-3b',
|
||||
vram_usage_mb INT NULL COMMENT 'VRAM ที่ใช้จริง (MB) ณ เวลาประมวลผล',
|
||||
cache_hit TINYINT(1) NOT NULL DEFAULT 0 COMMENT '1 = ผลลัพธ์มาจาก Redis cache, 0 = OCR ใหม่',
|
||||
ai_suggestion_json LONGTEXT NULL COMMENT 'AI suggested metadata' CHECK (json_valid(`ai_suggestion_json`)),
|
||||
human_override_json LONGTEXT NULL COMMENT 'Human approved or overridden metadata' CHECK (json_valid(`human_override_json`)),
|
||||
processing_time_ms INT NULL COMMENT 'Legacy processing duration field',
|
||||
confidence_score DECIMAL(4, 3) NULL COMMENT 'AI confidence score 0.000-1.000',
|
||||
input_hash VARCHAR(64) NULL COMMENT 'Legacy SHA-256 input hash',
|
||||
@@ -1552,12 +1543,132 @@ CREATE TABLE ai_audit_logs (
|
||||
KEY idx_ai_audit_model_name (model_name),
|
||||
KEY idx_ai_audit_status (STATUS),
|
||||
KEY idx_ai_audit_confirmed_by (confirmed_by_user_id),
|
||||
KEY idx_ai_audit_model_type (model_type),
|
||||
KEY idx_ai_audit_effective_profile (effective_profile),
|
||||
KEY idx_ai_audit_canonical_model (canonical_model),
|
||||
CONSTRAINT fk_ai_audit_confirmed_by_user FOREIGN KEY (confirmed_by_user_id) REFERENCES users (user_id) ON DELETE
|
||||
SET NULL
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ADR-023 AI development feedback log';
|
||||
|
||||
-- =====================================================
|
||||
-- 13. 🤖 Intent Classification (ADR-024)
|
||||
-- 13. 🤖 AI Available Models (ADR-027, ADR-034)
|
||||
-- =====================================================
|
||||
-- ตารางเก็บรายการโมเดล AI ที่ให้เลือกใช้งานในระบบ
|
||||
CREATE TABLE ai_available_models (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY COMMENT 'ID ของตาราง',
|
||||
model_name VARCHAR(100) NOT NULL UNIQUE COMMENT 'ชื่อโมเดล เช่น gemma4:e2b, gemma4:e4b',
|
||||
model_version VARCHAR(50) NOT NULL COMMENT 'เวอร์ชั่นของโมเดล',
|
||||
description VARCHAR(500) NULL COMMENT 'รายละเอียดโมเดล',
|
||||
vram_gb DECIMAL(4, 2) NULL COMMENT 'VRAM ที่ใช้โดยประมาณ (GB)',
|
||||
is_active TINYINT(1) DEFAULT 1 COMMENT 'สถานะใช้งาน',
|
||||
is_default TINYINT(1) DEFAULT 0 COMMENT 'โมเดลเริ่มต้น',
|
||||
created_by INT NULL,
|
||||
updated_by INT NULL,
|
||||
created_at DATETIME(3) DEFAULT CURRENT_TIMESTAMP(3),
|
||||
updated_at DATETIME(3) DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||||
deleted_at DATETIME(3) NULL,
|
||||
UNIQUE KEY uk_model_name (model_name),
|
||||
KEY idx_is_active (is_active),
|
||||
KEY idx_is_default (is_default)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ตารางเก็บรายการโมเดล AI ที่ให้เลือกใช้งานในระบบ (ADR-027)';
|
||||
|
||||
-- =====================================================
|
||||
-- 14. 🤖 AI Prompts (ADR-029)
|
||||
-- =====================================================
|
||||
-- ตาราง versioned prompt templates สำหรับ OCR extraction
|
||||
CREATE TABLE ai_prompts (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY COMMENT 'ID ภายใน (ไม่ expose ใน API)',
|
||||
public_id UUID NOT NULL UNIQUE COMMENT 'UUID Public Identifier (ADR-019)',
|
||||
prompt_type VARCHAR(50) NOT NULL COMMENT 'ประเภท prompt เช่น ocr_extraction',
|
||||
version_number INT NOT NULL COMMENT 'เลข version ต่อเนื่องต่อ prompt_type (1, 2, 3...)',
|
||||
template TEXT NOT NULL COMMENT 'prompt template ที่มี {{ocr_text}} placeholder บังคับ',
|
||||
field_schema LONGTEXT NULL COMMENT 'definition ของ fields ที่คาดหวังในผลลัพธ์ JSON' CHECK (json_valid(`field_schema`)),
|
||||
is_active TINYINT(1) NOT NULL DEFAULT 0 COMMENT '1 = version นี้ใช้งานจริงทั้ง sandbox และ migrate-document (1 per prompt_type)',
|
||||
test_result_json LONGTEXT NULL COMMENT 'ผลลัพธ์ JSON จาก sandbox run ล่าสุด (auto-save โดย processor)' CHECK (json_valid(`test_result_json`)),
|
||||
manual_note TEXT NULL COMMENT 'หมายเหตุ/annotation จาก admin (manual input)',
|
||||
last_tested_at TIMESTAMP NULL COMMENT 'เวลาที่ sandbox รันครั้งล่าสุดสำหรับ version นี้',
|
||||
activated_at TIMESTAMP NULL COMMENT 'เวลาที่ version นี้ถูก activate เป็น active',
|
||||
created_by INT NOT NULL COMMENT 'user_id ของผู้สร้าง version นี้',
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
context_config LONGTEXT NULL COMMENT 'Configuration สำหรับ context ที่ backend ต้องส่งให้ AI (filter, pageSize, language, etc.)' CHECK (json_valid(`context_config`)),
|
||||
version INT NOT NULL DEFAULT 1,
|
||||
UNIQUE KEY uk_type_version (prompt_type, version_number),
|
||||
KEY idx_prompt_type_active (prompt_type, is_active),
|
||||
KEY created_by (created_by),
|
||||
CONSTRAINT ai_prompts_ibfk_1 FOREIGN KEY (created_by) REFERENCES users (user_id)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ตาราง versioned prompt templates สำหรับ OCR extraction (ADR-029)';
|
||||
|
||||
-- =====================================================
|
||||
-- 15. 🤖 AI Execution Profiles (ADR-025, ADR-027)
|
||||
-- =====================================================
|
||||
-- ตาราง execution profile parameters สำหรับ np-dms-ai
|
||||
CREATE TABLE ai_execution_profiles (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY COMMENT 'ID ภายใน',
|
||||
profile_name VARCHAR(50) NOT NULL UNIQUE COMMENT 'ชื่อ profile',
|
||||
canonical_model VARCHAR(20) NOT NULL DEFAULT 'np-dms-ai' COMMENT 'Model identity',
|
||||
temperature DECIMAL(4, 3) NOT NULL COMMENT 'LLM temperature',
|
||||
top_p DECIMAL(4, 3) NOT NULL COMMENT 'LLM top_p',
|
||||
max_tokens INT NULL COMMENT 'Maximum tokens',
|
||||
num_ctx INT NULL COMMENT 'Context window size',
|
||||
repeat_penalty DECIMAL(5, 3) NOT NULL COMMENT 'Repeat penalty',
|
||||
keep_alive_seconds INT NOT NULL COMMENT 'Model keep_alive in seconds',
|
||||
is_active TINYINT(1) NOT NULL DEFAULT 1 COMMENT '1 = active; 0 = disabled',
|
||||
updated_by INT NULL COMMENT 'user_id',
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
KEY idx_profile_active (profile_name, is_active),
|
||||
KEY updated_by (updated_by),
|
||||
CONSTRAINT ai_execution_profiles_ibfk_1 FOREIGN KEY (updated_by) REFERENCES users (user_id)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ตาราง execution profile parameters สำหรับ np-dms-ai';
|
||||
|
||||
-- ตาราง sandbox profile parameters
|
||||
CREATE TABLE ai_sandbox_profiles (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY COMMENT 'ID ภายใน',
|
||||
profile_name VARCHAR(50) NOT NULL UNIQUE COMMENT 'ชื่อ profile',
|
||||
canonical_model VARCHAR(20) NOT NULL DEFAULT 'np-dms-ai' COMMENT 'Model identity',
|
||||
temperature DECIMAL(4, 3) NOT NULL COMMENT 'LLM temperature',
|
||||
top_p DECIMAL(4, 3) NOT NULL COMMENT 'LLM top_p',
|
||||
max_tokens INT NULL COMMENT 'Maximum tokens',
|
||||
num_ctx INT NOT NULL COMMENT 'Context window size',
|
||||
repeat_penalty DECIMAL(5, 3) NOT NULL COMMENT 'Repeat penalty',
|
||||
keep_alive_seconds INT NOT NULL COMMENT 'Model keep_alive in seconds',
|
||||
updated_by INT NULL COMMENT 'user_id',
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
KEY idx_ai_sandbox_profile_model (canonical_model),
|
||||
KEY updated_by (updated_by),
|
||||
CONSTRAINT ai_sandbox_profiles_ibfk_1 FOREIGN KEY (updated_by) REFERENCES users (user_id)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ตาราง sandbox profile parameters';
|
||||
|
||||
-- =====================================================
|
||||
-- 16. 🤖 Migration Errors (ADR-028)
|
||||
-- =====================================================
|
||||
-- ตาราง Error Log สำหรับ Migration (ลบได้หลัง Migration เสร็จ)
|
||||
CREATE TABLE migration_errors (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
batch_id VARCHAR(50) NULL,
|
||||
document_number VARCHAR(100) NULL,
|
||||
error_type ENUM(
|
||||
'FILE_NOT_FOUND',
|
||||
'MISSING_FILENAME',
|
||||
'FILE_ERROR',
|
||||
'AI_PARSE_ERROR',
|
||||
'API_ERROR',
|
||||
'DB_ERROR',
|
||||
'SECURITY',
|
||||
'UNKNOWN'
|
||||
) NULL,
|
||||
error_message TEXT NULL,
|
||||
job_id VARCHAR(100) NULL,
|
||||
raw_ai_response TEXT NULL,
|
||||
created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
KEY idx_batch_id (batch_id),
|
||||
KEY idx_job_id (job_id),
|
||||
KEY idx_error_type (error_type)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'Migration: Error Log (ลบได้หลัง Migration เสร็จ)';
|
||||
|
||||
-- =====================================================
|
||||
-- 17. 🤖 Intent Classification (ADR-024)
|
||||
-- =====================================================
|
||||
-- Intent Definitions Table
|
||||
CREATE TABLE IF NOT EXISTS ai_intent_definitions (
|
||||
|
||||
@@ -18,6 +18,43 @@
|
||||
-- 2.1 username = migration_bot
|
||||
-- 2.2
|
||||
-- ==========================================================
|
||||
-- System Settings
|
||||
INSERT INTO system_settings (
|
||||
setting_key,
|
||||
setting_value,
|
||||
data_type,
|
||||
category,
|
||||
description,
|
||||
is_public
|
||||
)
|
||||
VALUES (
|
||||
'AI_FEATURES_ENABLED',
|
||||
'true',
|
||||
'boolean',
|
||||
'ai',
|
||||
'สถานะเปิด/ปิดการใช้งานฟีเจอร์ AI ทั้งระบบ สำหรับผู้ใช้ทั่วไป',
|
||||
1
|
||||
) ON DUPLICATE KEY
|
||||
UPDATE setting_key = setting_key;
|
||||
|
||||
INSERT INTO system_settings (
|
||||
setting_key,
|
||||
setting_value,
|
||||
data_type,
|
||||
category,
|
||||
description,
|
||||
is_public
|
||||
)
|
||||
VALUES (
|
||||
'AI_ACTIVE_MODEL',
|
||||
'typhoon2.5-np-dms:latest',
|
||||
'string',
|
||||
'ai',
|
||||
'โมเดล AI ที่ใช้งานอยู่ในระบบ (global)',
|
||||
1
|
||||
) ON DUPLICATE KEY
|
||||
UPDATE setting_key = setting_key;
|
||||
|
||||
INSERT INTO organization_roles (id, role_name)
|
||||
VALUES (1, 'OWNER'),
|
||||
(2, 'DESIGNER'),
|
||||
@@ -2648,3 +2685,156 @@ VALUES (
|
||||
NOW(),
|
||||
NOW()
|
||||
);
|
||||
|
||||
-- ==========================================================
|
||||
-- AI Seed Data (ADR-027, ADR-029, ADR-034)
|
||||
-- ==========================================================
|
||||
-- AI Available Models
|
||||
INSERT INTO ai_available_models (
|
||||
model_name,
|
||||
model_version,
|
||||
description,
|
||||
vram_gb,
|
||||
is_active,
|
||||
is_default,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
VALUES (
|
||||
'typhoon2.5-np-dms:latest',
|
||||
'latest',
|
||||
'Thai-optimized main AI model based on typhoon2.5-qwen3-4b (~2.5GB VRAM, standby mode) — ADR-034',
|
||||
2.50,
|
||||
1,
|
||||
1,
|
||||
NOW(3),
|
||||
NOW(3)
|
||||
),
|
||||
(
|
||||
'typhoon-np-dms-ocr:latest',
|
||||
'latest',
|
||||
'Thai OCR model based on typhoon-ocr1.5-3b (~3.2GB VRAM, unloads after each job) — ADR-034',
|
||||
3.20,
|
||||
1,
|
||||
0,
|
||||
NOW(3),
|
||||
NOW(3)
|
||||
);
|
||||
|
||||
-- AI Execution Profiles
|
||||
INSERT INTO ai_execution_profiles (
|
||||
profile_name,
|
||||
canonical_model,
|
||||
temperature,
|
||||
top_p,
|
||||
max_tokens,
|
||||
num_ctx,
|
||||
repeat_penalty,
|
||||
keep_alive_seconds,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
VALUES (
|
||||
'interactive',
|
||||
'np-dms-ai',
|
||||
0.7,
|
||||
0.9,
|
||||
2048,
|
||||
4096,
|
||||
1.1,
|
||||
300,
|
||||
1,
|
||||
NOW(),
|
||||
NOW()
|
||||
),
|
||||
(
|
||||
'standard',
|
||||
'np-dms-ai',
|
||||
0.5,
|
||||
0.8,
|
||||
4096,
|
||||
8192,
|
||||
1.15,
|
||||
300,
|
||||
1,
|
||||
NOW(),
|
||||
NOW()
|
||||
),
|
||||
(
|
||||
'quality',
|
||||
'np-dms-ai',
|
||||
0.3,
|
||||
0.7,
|
||||
8192,
|
||||
16384,
|
||||
1.2,
|
||||
300,
|
||||
1,
|
||||
NOW(),
|
||||
NOW()
|
||||
),
|
||||
(
|
||||
'deep-analysis',
|
||||
'np-dms-ai',
|
||||
0.2,
|
||||
0.6,
|
||||
16384,
|
||||
32768,
|
||||
1.25,
|
||||
300,
|
||||
1,
|
||||
NOW(),
|
||||
NOW()
|
||||
),
|
||||
(
|
||||
'ocr-extract',
|
||||
'np-dms-ocr',
|
||||
0.1,
|
||||
0.5,
|
||||
NULL,
|
||||
8192,
|
||||
1.0,
|
||||
0,
|
||||
1,
|
||||
NOW(),
|
||||
NOW()
|
||||
);
|
||||
|
||||
-- AI Sandbox Profiles
|
||||
INSERT INTO ai_sandbox_profiles (
|
||||
profile_name,
|
||||
canonical_model,
|
||||
temperature,
|
||||
top_p,
|
||||
max_tokens,
|
||||
num_ctx,
|
||||
repeat_penalty,
|
||||
keep_alive_seconds,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
VALUES (
|
||||
'ocr-extract',
|
||||
'np-dms-ocr',
|
||||
0.1,
|
||||
0.5,
|
||||
NULL,
|
||||
8192,
|
||||
1.0,
|
||||
0,
|
||||
NOW(),
|
||||
NOW()
|
||||
),
|
||||
(
|
||||
'standard',
|
||||
'np-dms-ai',
|
||||
0.5,
|
||||
0.8,
|
||||
4096,
|
||||
8192,
|
||||
1.15,
|
||||
300,
|
||||
NOW(),
|
||||
NOW()
|
||||
);
|
||||
|
||||
@@ -34,4 +34,6 @@
|
||||
| 2026-06-18 | v1.9.10 | Feature-238 OCR AI Prompt Separation — SandboxTabs โหลด active prompts ทั้ง ocr_system + ocr_extraction, แสดง prompt info ทั้ง 2 steps, ส่ง active version ที่ถูกต้อง | ✅ Complete |
|
||||
| 2026-06-18 | v1.9.10 | VRAM Monitor Fix — Backend ส่ง loadedModels พร้อม vramUsageMB, frontend รองรับ format ใหม่, แสดง VRAM usage ถูกต้อง | ✅ Complete |
|
||||
| 2026-06-19 | v1.9.10 | Feature-240 AI Admin Console Collapsible Cards — เพิ่มปุ่มและฟังก์ชันพับ/คลี่การ์ดและเซกชัน พร้อมบันทึกสถานะลง localStorage และรักษา background query polling | ✅ Complete |
|
||||
| 2026-06-19 | v1.9.10 | Deployment Timeout Fix — Added clamav health check before recreation (skip if healthy), increased CI timeout 20→30 min | ✅ Complete |
|
||||
| 2026-06-19 | v1.9.10 | AI Admin Response Normalization — recursive data unwrap for VRAM/prompt payloads, fixed Sandbox `.map()` crash and false OOM Guard | ✅ Complete |
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
# Session — 2026-06-19 (AI Admin Response Normalization)
|
||||
|
||||
## Summary
|
||||
|
||||
แก้ bug หน้า `admin/ai` เมื่อกดแท็บ `3-Step Pipeline Sandbox` แล้วขึ้น `Admin Panel Error e.map is not a function` และแก้ VRAM GPU Monitor ที่แสดง `0 MB / 0 MB` แต่ขึ้น `หน่วยความจำไม่เพียงพอ (OOM Guard)` ผิดสถานะ
|
||||
|
||||
## ปัญหาที่พบ (Root Cause)
|
||||
|
||||
Frontend AI Admin service unwrap API response ได้เพียงชั้นเดียว ทำให้ response ที่ถูกห่อ `data` ซ้อนกันอ่านค่า VRAM เป็น `0/0` และ prompt list กลายเป็น object แทน array ก่อนส่งเข้า component ที่ใช้ `.find()` / `.map()`
|
||||
|
||||
## การแก้ไข (Fix)
|
||||
|
||||
| ไฟล์ | การเปลี่ยนแปลง |
|
||||
| ---- | --------------- |
|
||||
| `frontend/lib/services/admin-ai.service.ts` | เพิ่ม recursive `extractData()` สำหรับ API envelope ซ้อนกัน และปรับ VRAM unknown capacity (`totalVRAMMB = 0`) ไม่ให้แสดง OOM Guard |
|
||||
| `frontend/lib/services/admin-ai-prompt.service.ts` | เพิ่ม response normalization ให้ `getPrompts()` คืน array เสมอ และ unwrap response สำหรับ create/activate/update note |
|
||||
| `frontend/lib/services/__tests__/admin-ai.service.test.ts` | เพิ่ม regression tests สำหรับ VRAM double-wrapper, unknown VRAM, prompt list wrapper, และ non-array prompt payload |
|
||||
|
||||
## กฎที่ Lock แล้ว
|
||||
|
||||
- AI Admin frontend service ต้อง normalize API response envelope ที่อาจซ้อน `data` ก่อนส่งให้ UI render
|
||||
- `totalVRAMMB = 0` ใน frontend หมายถึง capacity unknown ไม่ใช่ OOM; ห้ามแสดง OOM Guard จากข้อมูล VRAM ที่ไม่รู้ total
|
||||
|
||||
## Verification
|
||||
|
||||
- [x] `pnpm --filter lcbp3-frontend exec vitest run lib/services/__tests__/admin-ai.service.test.ts components/admin/ai/__tests__/SandboxTabs.test.tsx components/admin/ai/__tests__/sandbox-tabs.test.tsx` ผ่าน 3 files / 9 tests
|
||||
- [x] `pnpm --filter lcbp3-frontend exec tsc --noEmit` ผ่าน
|
||||
- [x] `git diff --check -- frontend/lib/services/admin-ai.service.ts frontend/lib/services/admin-ai-prompt.service.ts frontend/lib/services/__tests__/admin-ai.service.test.ts` ผ่าน
|
||||
@@ -0,0 +1,34 @@
|
||||
# Session — 2026-06-19 (Deployment Timeout Fix)
|
||||
|
||||
## Summary
|
||||
|
||||
Fixed CI/CD deployment timeout issue caused by ClamAV container recreation taking 5+ minutes during healthcheck, causing SSH connection to timeout before deployment completed.
|
||||
|
||||
## ปัญหาที่พบ (Root Cause)
|
||||
|
||||
**Error:** `context deadline exceeded` during container recreation on QNAP
|
||||
|
||||
**Root Cause:**
|
||||
- CI workflow SSH timeout: `ConnectTimeout=30` + `ServerAliveCountMax=10` (5 minutes total keepalive)
|
||||
- ClamAV healthcheck `start_period: 300s` (5 minutes) before it's considered healthy
|
||||
- Backend depends on clamav being healthy before starting
|
||||
- `docker compose up -d --force-recreate` recreates clamav first, which takes 5+ minutes to become healthy
|
||||
- No output during this period → SSH connection times out
|
||||
|
||||
## การแก้ไข (Fix)
|
||||
|
||||
| ไฟล์ | การเปลี่ยนแปลง |
|
||||
| -------------- | ---------------------- |
|
||||
| `scripts/deploy.sh` | Added clamav health check before recreation - if healthy, only recreate backend/frontend (skip 5-minute delay) |
|
||||
| `.gitea/workflows/ci-deploy.yml` | Increased CI timeout from 20 to 30 minutes as safety net |
|
||||
|
||||
## กฎที่ Lock แล้ว
|
||||
|
||||
- **D18:** Deploy script must check ClamAV health status before recreation to avoid unnecessary 5-minute healthcheck delay
|
||||
- **D19:** CI timeout should be at least 30 minutes to accommodate ClamAV startup if full recreation is needed
|
||||
|
||||
## Verification
|
||||
|
||||
- [ ] Deploy script tested locally to verify clamav health check logic
|
||||
- [ ] CI workflow tested with new timeout setting
|
||||
- [ ] Next deployment completes without SSH timeout
|
||||
Reference in New Issue
Block a user