690519:1719 224 to 226 AI #02
This commit is contained in:
@@ -1,4 +0,0 @@
|
||||
ALTER TABLE `attachments`
|
||||
ADD COLUMN `reference_date` DATE NULL COMMENT 'Date used for folder structure (e.g. Issue Date) to prevent broken paths';
|
||||
ALTER TABLE `attachments`
|
||||
ADD INDEX `idx_attachments_reference_date` (`reference_date`);
|
||||
@@ -1,12 +0,0 @@
|
||||
-- Add permission for Bulk RBAC Update
|
||||
-- Fix: Use existing 'user.manage_assignments' instead of creating new invalid permission
|
||||
-- This permission (ID 25) is for assigning roles/projects
|
||||
-- Grant to ADMIN (ID 2) and DC (ID 3) roles if not already present
|
||||
-- Use INSERT IGNORE to avoid duplicates
|
||||
INSERT IGNORE INTO `role_permissions` (`role_id`, `permission_id`)
|
||||
SELECT r.role_id,
|
||||
p.permission_id
|
||||
FROM `roles` r,
|
||||
`permissions` p
|
||||
WHERE r.role_name IN ('ADMIN', 'Org Admin', 'DC', 'Document Control')
|
||||
AND p.permission_name = 'user.manage_assignments';
|
||||
@@ -1,30 +0,0 @@
|
||||
-- Delta 03: Fix ENUM mismatches in document_number_audit and document_number_errors
|
||||
-- Issue: 'GENERATE' operation used by backend but not in DB ENUM → INSERT fails → correspondence creation blocked
|
||||
-- Date: 2026-03-19
|
||||
-- Applies to: lcbp3-v1.8.0-schema-02-tables.sql
|
||||
|
||||
-- 1. Add 'VOID' and 'GENERATE' to document_number_audit.operation ENUM
|
||||
ALTER TABLE document_number_audit
|
||||
MODIFY COLUMN operation ENUM(
|
||||
'RESERVE',
|
||||
'CONFIRM',
|
||||
'MANUAL_OVERRIDE',
|
||||
'VOID_REPLACE',
|
||||
'CANCEL',
|
||||
'VOID',
|
||||
'GENERATE'
|
||||
) NOT NULL DEFAULT 'CONFIRM' COMMENT 'ประเภทการดำเนินการ';
|
||||
|
||||
-- 2. Add missing error_type values to document_number_errors
|
||||
ALTER TABLE document_number_errors
|
||||
MODIFY COLUMN error_type ENUM(
|
||||
'LOCK_TIMEOUT',
|
||||
'VERSION_CONFLICT',
|
||||
'DB_ERROR',
|
||||
'REDIS_ERROR',
|
||||
'VALIDATION_ERROR',
|
||||
'SEQUENCE_EXHAUSTED',
|
||||
'RESERVATION_EXPIRED',
|
||||
'DUPLICATE_NUMBER',
|
||||
'GENERATE_ERROR'
|
||||
) NOT NULL COMMENT 'ประเภท error (9 types)';
|
||||
@@ -1,25 +0,0 @@
|
||||
-- ============================================================
|
||||
-- Delta 04: ADR-021 — Step-specific Attachments
|
||||
-- เพิ่ม FK workflow_history_id ใน attachments table
|
||||
-- ============================================================
|
||||
-- ข้อควรระวัง: ค่า NULL = ไฟล์แนบหลัก (Main Document)
|
||||
-- ค่าไม่ NULL = ไฟล์ประจำ Workflow Step นั้น
|
||||
|
||||
ALTER TABLE attachments
|
||||
ADD COLUMN workflow_history_id CHAR(36) NULL
|
||||
COMMENT 'FK to workflow_histories.id สำหรับไฟล์แนบประจำ Step (ADR-021). NULL = ไฟล์แนบหลัก',
|
||||
ADD CONSTRAINT fk_attachments_workflow_history
|
||||
FOREIGN KEY (workflow_history_id)
|
||||
REFERENCES workflow_histories (id)
|
||||
ON DELETE SET NULL
|
||||
ON UPDATE CASCADE;
|
||||
|
||||
-- Index สำหรับ optimize การดึงไฟล์แนบตาม Step + เรียงตามวันที่
|
||||
CREATE INDEX idx_att_wfhist_created
|
||||
ON attachments (workflow_history_id, created_at);
|
||||
|
||||
-- ============================================================
|
||||
-- Rollback:
|
||||
-- ALTER TABLE attachments DROP FOREIGN KEY fk_attachments_workflow_history;
|
||||
-- ALTER TABLE attachments DROP COLUMN workflow_history_id;
|
||||
-- ============================================================
|
||||
@@ -1,13 +0,0 @@
|
||||
-- Delta 05: Add deadline_date to circulations (v1.8.7 — EC-CIRC-003)
|
||||
-- Purpose: เพิ่มคอลัมน์ deadline_date ที่ตาราง circulations
|
||||
-- เพื่อรองรับ EC-CIRC-003 (Overdue Badge) และการตั้งค่ากำหนดเวลา
|
||||
-- Applied: เพิ่มทีหลัง Schema v1.8.0
|
||||
-- Author: NAP-DMS v1.8.7
|
||||
|
||||
ALTER TABLE circulations
|
||||
ADD COLUMN deadline_date DATE NULL
|
||||
COMMENT 'วันครบกำหนดส่งงาน (nullable — ถ้า NULL = ไม่มีกำหนด)'
|
||||
AFTER closed_at;
|
||||
|
||||
-- Index สำหรับ query Overdue Circulations ที่ Dashboard
|
||||
CREATE INDEX idx_circulations_deadline ON circulations (deadline_date);
|
||||
@@ -1,87 +0,0 @@
|
||||
-- ==========================================================
|
||||
-- Delta 06: Add CIRCULATION_FLOW_V1 Workflow Definition
|
||||
-- ==========================================================
|
||||
-- Purpose : สร้าง Workflow Definition สำหรับใบเวียนภายใน (Circulation)
|
||||
-- Required : ก่อน delta นี้ ตาราง workflow_definitions ต้องมีอยู่แล้ว (ADR-001)
|
||||
-- Renamed : CIRCULATION_INTERNAL_V1 → CIRCULATION_FLOW_V1 (ตาม naming convention)
|
||||
-- States :
|
||||
-- DRAFT (initial) → START → ROUTING
|
||||
-- ROUTING → COMPLETE → COMPLETED (terminal)
|
||||
-- ROUTING → FORCE_CLOSE → CANCELLED (terminal)
|
||||
-- ==========================================================
|
||||
|
||||
INSERT INTO `workflow_definitions` (
|
||||
`id`,
|
||||
`workflow_code`,
|
||||
`version`,
|
||||
`description`,
|
||||
`dsl`,
|
||||
`compiled`,
|
||||
`is_active`,
|
||||
`created_at`,
|
||||
`updated_at`
|
||||
)
|
||||
VALUES (
|
||||
UUID(),
|
||||
'CIRCULATION_FLOW_V1',
|
||||
1,
|
||||
'Circulation Workflow — DRAFT → ROUTING → COMPLETED | CANCELLED',
|
||||
JSON_OBJECT(
|
||||
'workflow', 'CIRCULATION_FLOW_V1',
|
||||
'version', 1,
|
||||
'states', JSON_ARRAY(
|
||||
JSON_OBJECT(
|
||||
'name', 'DRAFT',
|
||||
'initial', TRUE,
|
||||
'on', JSON_OBJECT(
|
||||
'START', JSON_OBJECT('to', 'ROUTING')
|
||||
)
|
||||
),
|
||||
JSON_OBJECT(
|
||||
'name', 'ROUTING',
|
||||
'on', JSON_OBJECT(
|
||||
'COMPLETE', JSON_OBJECT('to', 'COMPLETED'),
|
||||
'FORCE_CLOSE', JSON_OBJECT('to', 'CANCELLED')
|
||||
)
|
||||
),
|
||||
JSON_OBJECT('name', 'COMPLETED', 'terminal', TRUE),
|
||||
JSON_OBJECT('name', 'CANCELLED', 'terminal', TRUE)
|
||||
)
|
||||
),
|
||||
JSON_OBJECT(
|
||||
'initialState', 'DRAFT',
|
||||
'states', JSON_OBJECT(
|
||||
'DRAFT', JSON_OBJECT(
|
||||
'initial', TRUE,
|
||||
'terminal', FALSE,
|
||||
'transitions', JSON_OBJECT(
|
||||
'START', JSON_OBJECT('to', 'ROUTING', 'events', JSON_ARRAY())
|
||||
)
|
||||
),
|
||||
'ROUTING', JSON_OBJECT(
|
||||
'initial', FALSE,
|
||||
'terminal', FALSE,
|
||||
'transitions', JSON_OBJECT(
|
||||
'COMPLETE', JSON_OBJECT('to', 'COMPLETED', 'events', JSON_ARRAY()),
|
||||
'FORCE_CLOSE', JSON_OBJECT('to', 'CANCELLED', 'events', JSON_ARRAY())
|
||||
)
|
||||
),
|
||||
'COMPLETED', JSON_OBJECT(
|
||||
'initial', FALSE,
|
||||
'terminal', TRUE,
|
||||
'transitions', JSON_OBJECT()
|
||||
),
|
||||
'CANCELLED', JSON_OBJECT(
|
||||
'initial', FALSE,
|
||||
'terminal', TRUE,
|
||||
'transitions', JSON_OBJECT()
|
||||
)
|
||||
)
|
||||
),
|
||||
TRUE,
|
||||
NOW(),
|
||||
NOW()
|
||||
);
|
||||
|
||||
-- Verify
|
||||
-- SELECT workflow_code, version, is_active FROM workflow_definitions WHERE workflow_code = 'CIRCULATION_FLOW_V1';
|
||||
@@ -1,22 +0,0 @@
|
||||
-- ==========================================================
|
||||
-- Delta 07: Add contract_id to workflow_instances (C3 Contract Scoping)
|
||||
-- ==========================================================
|
||||
-- Purpose : เพิ่ม contract_id FK ใน workflow_instances เพื่อให้ Workflow Engine
|
||||
-- แยก scope ตาม Contract ได้ (C3 ตาม analysis ADR-021)
|
||||
-- Why : RFA / Correspondence / Transmittal → contract-scoped (contractId ถูกตั้ง)
|
||||
-- Circulation → organization-scoped (contractId = NULL, ใช้ Level 2 org check)
|
||||
-- Guard Level 2.5 ตรวจ contract_organizations membership เฉพาะ contractId ≠ NULL
|
||||
-- ADR : ADR-009 (no migrations — direct SQL only)
|
||||
-- ==========================================================
|
||||
ALTER TABLE workflow_instances
|
||||
ADD COLUMN contract_id INT NULL COMMENT 'Contract ที่ Workflow นี้เป็นส่วนหนึ่ง (NULL = global/legacy)'
|
||||
AFTER definition_id,
|
||||
ADD CONSTRAINT fk_wf_inst_contract FOREIGN KEY (contract_id) REFERENCES contracts (id) ON DELETE
|
||||
SET NULL;
|
||||
|
||||
-- Index สำหรับ Guard lookup: "Instances ทั้งหมดในสัญญา X"
|
||||
CREATE INDEX idx_wf_inst_contract ON workflow_instances (contract_id, entity_type, STATUS);
|
||||
|
||||
-- Verify
|
||||
-- DESCRIBE workflow_instances;
|
||||
-- SHOW INDEX FROM workflow_instances WHERE Key_name = 'idx_wf_inst_contract';
|
||||
@@ -1,11 +0,0 @@
|
||||
-- Delta 08: ADR-022 RAG — เพิ่ม rag_status และ rag_last_error ในตาราง attachments
|
||||
-- Apply: 2026-04-19
|
||||
-- Ref: specs/08-Tasks/ADR-022-Retrieval-Augmented-Generation/data-model.md §1.1
|
||||
|
||||
ALTER TABLE attachments
|
||||
ADD COLUMN rag_status ENUM('PENDING', 'PROCESSING', 'INDEXED', 'FAILED')
|
||||
NOT NULL DEFAULT 'PENDING'
|
||||
COMMENT 'สถานะ RAG ingestion ระดับ file',
|
||||
ADD COLUMN rag_last_error TEXT NULL
|
||||
COMMENT 'Error message ล่าสุดเมื่อ rag_status = FAILED',
|
||||
ADD INDEX idx_attachments_rag_status (rag_status);
|
||||
@@ -1,25 +0,0 @@
|
||||
-- Delta 08b: ADR-022 RAG — สร้างตาราง document_chunks สำหรับเก็บ vector metadata
|
||||
-- Apply: 2026-04-19
|
||||
-- Ref: specs/08-Tasks/ADR-022-Retrieval-Augmented-Generation/data-model.md §1.2
|
||||
|
||||
CREATE TABLE document_chunks (
|
||||
id CHAR(36) NOT NULL PRIMARY KEY COMMENT 'UUID = Qdrant point ID',
|
||||
document_id CHAR(36) NOT NULL COMMENT 'FK → attachments.public_id (UUIDv7)',
|
||||
chunk_index INT NOT NULL COMMENT 'ลำดับ chunk ภายใน document',
|
||||
content TEXT NOT NULL COMMENT 'เนื้อหา chunk หลัง PyThaiNLP normalize',
|
||||
doc_type VARCHAR(20) NOT NULL COMMENT 'CORR, RFA, DRAWING, CONTRACT, RPT, TRANS',
|
||||
doc_number VARCHAR(100) NULL COMMENT 'หมายเลขเอกสาร เช่น REF-2026-001',
|
||||
revision VARCHAR(20) NULL COMMENT 'Revision เช่น Rev.A',
|
||||
project_code VARCHAR(50) NOT NULL COMMENT 'รหัสโครงการ (ใช้ filter)',
|
||||
project_public_id CHAR(36) NOT NULL COMMENT 'UUIDv7 ของโครงการ (Qdrant tenant key)',
|
||||
version VARCHAR(20) NULL COMMENT 'เวอร์ชันเอกสาร เช่น 1.0, 2.1 (ถ้ามี)',
|
||||
classification ENUM('PUBLIC', 'INTERNAL', 'CONFIDENTIAL')
|
||||
NOT NULL DEFAULT 'INTERNAL',
|
||||
embedding_model VARCHAR(100) NOT NULL DEFAULT 'nomic-embed-text',
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
INDEX idx_chunks_document_id (document_id),
|
||||
INDEX idx_chunks_doc_number_rev (doc_number, revision),
|
||||
INDEX idx_chunks_project (project_public_id),
|
||||
FULLTEXT INDEX ft_chunks_content (content)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
@@ -1,8 +0,0 @@
|
||||
-- Delta 08c: ADR-022 RAG — เพิ่ม permissions สำหรับ RAG feature
|
||||
-- Apply: 2026-04-19
|
||||
-- Ref: specs/08-Tasks/ADR-022-Retrieval-Augmented-Generation/tasks.md T014
|
||||
|
||||
INSERT IGNORE INTO permissions (permission_name, description, module, created_at, updated_at)
|
||||
VALUES
|
||||
('rag.query', 'ใช้งาน RAG Q&A เพื่อค้นหาคำตอบจากเอกสาร', 'rag', NOW(), NOW()),
|
||||
('rag.manage', 'จัดการ RAG ingestion, re-index, ลบ vectors', 'rag', NOW(), NOW());
|
||||
@@ -1,17 +0,0 @@
|
||||
-- ============================================================
|
||||
-- Delta 09: ADR-001 v1.1 — Optimistic Lock for Workflow Transitions
|
||||
-- เพิ่ม version_no ใน workflow_instances สำหรับ Optimistic Concurrency Control
|
||||
-- ============================================================
|
||||
-- Feature: 003-unified-workflow-engine (FR-002)
|
||||
-- Date: 2026-05-03
|
||||
-- ข้อควรระวัง: Existing rows จะได้ค่า DEFAULT 1 อัตโนมัติ — ไม่มี Data Loss
|
||||
-- Rollback: ALTER TABLE workflow_instances DROP INDEX idx_wf_inst_version;
|
||||
-- ALTER TABLE workflow_instances DROP COLUMN version_no;
|
||||
|
||||
ALTER TABLE workflow_instances
|
||||
ADD COLUMN version_no INT NOT NULL DEFAULT 1
|
||||
COMMENT 'Optimistic lock counter — incremented on every successful transition (ADR-001 v1.1 FR-002). Client sends current value; server rejects with 409 if mismatch.';
|
||||
|
||||
-- Index เพื่อรองรับ CAS check: WHERE id = ? AND version_no = ?
|
||||
CREATE INDEX idx_wf_inst_version
|
||||
ON workflow_instances (id, version_no);
|
||||
@@ -1,14 +0,0 @@
|
||||
-- ============================================================
|
||||
-- Delta 10: ADR-001 v1.1 / ADR-019 UUID Compliance
|
||||
-- เพิ่ม action_by_user_uuid ใน workflow_histories
|
||||
-- เพื่อ expose User identity ผ่าน API โดยไม่ต้องเปิดเผย INT PK (ADR-019)
|
||||
-- ============================================================
|
||||
-- Feature: 003-unified-workflow-engine (FR-003)
|
||||
-- Date: 2026-05-03
|
||||
-- ข้อควรระวัง: NULL สำหรับ Historical records ที่สร้างก่อน delta นี้ — เป็น Acceptable
|
||||
-- NULL ในบริบทนี้ = "System Action" หรือ "Pre-migration record"
|
||||
-- Rollback: ALTER TABLE workflow_histories DROP COLUMN action_by_user_uuid;
|
||||
|
||||
ALTER TABLE workflow_histories
|
||||
ADD COLUMN action_by_user_uuid VARCHAR(36) NULL
|
||||
COMMENT 'UUID ของ User ผู้ดำเนินการ — ใช้ใน API Response แทน INT FK (ADR-019). NULL = System Action หรือ Pre-migration record';
|
||||
@@ -1,25 +0,0 @@
|
||||
-- =============================================================================
|
||||
-- Delta 11: เพิ่ม uuid column ให้ roles table
|
||||
-- =============================================================================
|
||||
-- เหตุผล: roles ไม่มี uuid column ทำให้ distribution_recipients ไม่สามารถ
|
||||
-- อ้างอิง ROLE type ด้วย publicId ได้ตาม ADR-019
|
||||
-- ใช้ใน: distribution_recipients.recipient_public_id (recipient_type = 'ROLE')
|
||||
-- ADR: ADR-019 (Hybrid Identifier Strategy)
|
||||
-- Feature: v1.9.0 RFA Approval Refactor (1-rfa-approval-refactor)
|
||||
-- Created: 2026-05-13
|
||||
-- =============================================================================
|
||||
|
||||
ALTER TABLE `roles`
|
||||
ADD COLUMN `uuid` UUID NOT NULL DEFAULT (UUID())
|
||||
COMMENT 'UUID Public Identifier (ADR-019) — ใช้ใน API Response แทน role_id'
|
||||
AFTER `role_id`;
|
||||
|
||||
-- สร้าง Unique Index สำหรับ uuid
|
||||
CREATE UNIQUE INDEX `idx_roles_uuid` ON `roles` (`uuid`);
|
||||
|
||||
-- =============================================================================
|
||||
-- หมายเหตุ: หลัง Apply delta นี้แล้ว
|
||||
-- - roles ที่มีอยู่แล้วจะได้ uuid อัตโนมัติจาก DEFAULT (UUID())
|
||||
-- - distribution_recipients.recipient_public_id (type=ROLE) ให้ใช้ roles.uuid
|
||||
-- - TypeORM Entity: เพิ่ม @Column({ unique: true }) uuid: string; ใน RoleEntity
|
||||
-- =============================================================================
|
||||
@@ -1,88 +0,0 @@
|
||||
-- File: specs/03-Data-and-Storage/deltas/12-unified-ai-architecture.sql
|
||||
-- Change Log
|
||||
-- - 2026-05-14: เพิ่ม schema delta สำหรับ ADR-023 Unified AI Architecture.
|
||||
-- ADR-009: ใช้ SQL delta โดยตรง ห้ามใช้ TypeORM migration
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS migration_review_queue (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY COMMENT 'Internal PK (ห้าม expose ใน API)',
|
||||
uuid UUID NOT NULL DEFAULT UUID() COMMENT 'UUID Public Identifier (ADR-019)',
|
||||
batch_id VARCHAR(100) NOT NULL COMMENT 'Batch ingestion identifier',
|
||||
original_file_name VARCHAR(255) NOT NULL COMMENT 'Original uploaded legacy filename',
|
||||
source_attachment_public_id UUID NULL COMMENT 'Temp attachment publicId from two-phase upload',
|
||||
temp_attachment_id INT NULL COMMENT 'Internal temp attachment id used during commit only',
|
||||
extracted_metadata JSON NULL COMMENT 'AI extracted metadata before human validation',
|
||||
confidence_score DECIMAL(4, 3) NULL COMMENT 'Overall AI confidence score 0.000-1.000',
|
||||
status ENUM('PENDING', 'IMPORTED', 'REJECTED') NOT NULL DEFAULT 'PENDING',
|
||||
error_reason TEXT NULL COMMENT 'Reason when AI processing rejected the record',
|
||||
version INT NOT NULL DEFAULT 1 COMMENT 'Optimistic locking version',
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY idx_migration_review_uuid (uuid),
|
||||
KEY idx_migration_review_batch (batch_id),
|
||||
KEY idx_migration_review_status (status)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ADR-023 AI migration review staging queue';
|
||||
|
||||
ALTER TABLE migration_review_queue
|
||||
ADD COLUMN IF NOT EXISTS uuid UUID NOT NULL DEFAULT UUID() COMMENT 'UUID Public Identifier (ADR-019)',
|
||||
ADD COLUMN IF NOT EXISTS batch_id VARCHAR(100) NULL COMMENT 'Batch ingestion identifier',
|
||||
ADD COLUMN IF NOT EXISTS original_file_name VARCHAR(255) NULL COMMENT 'Original uploaded legacy filename',
|
||||
ADD COLUMN IF NOT EXISTS source_attachment_public_id UUID NULL COMMENT 'Temp attachment publicId from two-phase upload',
|
||||
ADD COLUMN IF NOT EXISTS temp_attachment_id INT NULL COMMENT 'Internal temp attachment id used during commit only',
|
||||
ADD COLUMN IF NOT EXISTS extracted_metadata JSON NULL COMMENT 'AI extracted metadata before human validation',
|
||||
ADD COLUMN IF NOT EXISTS confidence_score DECIMAL(4, 3) NULL COMMENT 'Overall AI confidence score 0.000-1.000',
|
||||
ADD COLUMN IF NOT EXISTS error_reason TEXT NULL COMMENT 'Reason when AI processing rejected the record',
|
||||
ADD COLUMN IF NOT EXISTS version INT NOT NULL DEFAULT 1 COMMENT 'Optimistic locking version',
|
||||
ADD COLUMN IF NOT EXISTS updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
|
||||
|
||||
ALTER TABLE migration_review_queue
|
||||
MODIFY COLUMN status ENUM('PENDING', 'APPROVED', 'IMPORTED', 'REJECTED') NOT NULL DEFAULT 'PENDING';
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_migration_review_uuid ON migration_review_queue (uuid);
|
||||
CREATE INDEX IF NOT EXISTS idx_migration_review_batch ON migration_review_queue (batch_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_migration_review_status ON migration_review_queue (status);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ai_audit_logs (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY COMMENT 'Internal PK (ห้าม expose ใน API)',
|
||||
uuid UUID NOT NULL DEFAULT UUID() COMMENT 'UUID Public Identifier (ADR-019)',
|
||||
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',
|
||||
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',
|
||||
output_hash VARCHAR(64) NULL COMMENT 'Legacy SHA-256 output hash',
|
||||
status ENUM('SUCCESS', 'FAILED', 'TIMEOUT') NOT NULL DEFAULT 'SUCCESS' COMMENT 'Legacy processing status field',
|
||||
error_message TEXT NULL COMMENT 'Legacy processing error field',
|
||||
confirmed_by_user_id INT NULL COMMENT 'Internal users.user_id that confirmed the record',
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY idx_ai_audit_logs_uuid (uuid),
|
||||
KEY idx_ai_audit_document (document_public_id),
|
||||
KEY idx_ai_audit_model (ai_model),
|
||||
KEY idx_ai_audit_model_name (model_name),
|
||||
KEY idx_ai_audit_status (status),
|
||||
KEY idx_ai_audit_confirmed_by (confirmed_by_user_id),
|
||||
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';
|
||||
|
||||
ALTER TABLE ai_audit_logs
|
||||
ADD COLUMN IF NOT EXISTS ai_model VARCHAR(50) NOT NULL DEFAULT 'gemma4' COMMENT 'Legacy AI model column used by current gateway service',
|
||||
ADD COLUMN IF NOT EXISTS model_name VARCHAR(100) NULL COMMENT 'Local model name used by ADR-023 AI pipeline',
|
||||
ADD COLUMN IF NOT EXISTS ai_suggestion_json JSON NULL COMMENT 'AI suggested metadata',
|
||||
ADD COLUMN IF NOT EXISTS human_override_json JSON NULL COMMENT 'Human approved or overridden metadata',
|
||||
ADD COLUMN IF NOT EXISTS processing_time_ms INT NULL COMMENT 'Legacy processing duration field',
|
||||
ADD COLUMN IF NOT EXISTS input_hash VARCHAR(64) NULL COMMENT 'Legacy SHA-256 input hash',
|
||||
ADD COLUMN IF NOT EXISTS output_hash VARCHAR(64) NULL COMMENT 'Legacy SHA-256 output hash',
|
||||
ADD COLUMN IF NOT EXISTS status ENUM('SUCCESS', 'FAILED', 'TIMEOUT') NOT NULL DEFAULT 'SUCCESS' COMMENT 'Legacy processing status field',
|
||||
ADD COLUMN IF NOT EXISTS error_message TEXT NULL COMMENT 'Legacy processing error field',
|
||||
ADD COLUMN IF NOT EXISTS confirmed_by_user_id INT NULL COMMENT 'Internal users.user_id that confirmed the record';
|
||||
|
||||
UPDATE ai_audit_logs
|
||||
SET model_name = ai_model
|
||||
WHERE model_name IS NULL AND ai_model IS NOT NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_ai_audit_model_name ON ai_audit_logs (model_name);
|
||||
CREATE INDEX IF NOT EXISTS idx_ai_audit_confirmed_by ON ai_audit_logs (confirmed_by_user_id);
|
||||
@@ -1,56 +0,0 @@
|
||||
-- File: specs/03-Data-and-Storage/deltas/14-add-migration-review-queue.sql
|
||||
-- Change Log
|
||||
-- - 2026-05-15: เพิ่ม delta สำหรับ migration_review_queue ตาม ADR-023A โดยไม่ลบ/rename column เดิม.
|
||||
-- ADR-009: ใช้ SQL delta โดยตรง ห้ามใช้ TypeORM migration
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS migration_review_queue (
|
||||
id INT NOT NULL AUTO_INCREMENT COMMENT 'Internal PK (ห้าม expose ใน API)',
|
||||
uuid UUID NOT NULL DEFAULT UUID() COMMENT 'UUID Public Identifier (ADR-019)',
|
||||
batch_id VARCHAR(100) NOT NULL COMMENT 'n8n batch identifier',
|
||||
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',
|
||||
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', 'IMPORTED', 'REJECTED') NOT NULL DEFAULT 'PENDING',
|
||||
reviewed_by INT NULL COMMENT 'Internal users.user_id ของผู้ review',
|
||||
reviewed_at DATETIME NULL COMMENT 'เวลาที่ review record',
|
||||
rejection_reason VARCHAR(500) NULL COMMENT 'เหตุผลเมื่อ reject',
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uq_migration_review_uuid (uuid),
|
||||
UNIQUE KEY uq_migration_review_idempotency (idempotency_key),
|
||||
KEY idx_migration_review_status_created (status, created_at),
|
||||
KEY idx_migration_review_batch (batch_id),
|
||||
KEY idx_migration_review_reviewed_by (reviewed_by)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ADR-023A AI migration review staging queue';
|
||||
|
||||
ALTER TABLE migration_review_queue
|
||||
ADD COLUMN IF NOT EXISTS idempotency_key VARCHAR(200) NULL COMMENT 'Idempotency-Key สำหรับป้องกัน queue ซ้ำ',
|
||||
ADD COLUMN IF NOT EXISTS original_filename VARCHAR(500) NULL COMMENT 'ชื่อไฟล์ต้นฉบับจาก legacy source',
|
||||
ADD COLUMN IF NOT EXISTS storage_temp_path VARCHAR(1000) NULL COMMENT 'temp storage path ก่อน import',
|
||||
ADD COLUMN IF NOT EXISTS ai_metadata_json JSON NULL COMMENT 'AI suggestion payload เต็มสำหรับ human review',
|
||||
ADD COLUMN IF NOT EXISTS ocr_used TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'ระบุว่าใช้ OCR path หรือไม่',
|
||||
ADD COLUMN IF NOT EXISTS reviewed_by INT NULL COMMENT 'Internal users.user_id ของผู้ review',
|
||||
ADD COLUMN IF NOT EXISTS reviewed_at DATETIME NULL COMMENT 'เวลาที่ review record',
|
||||
ADD COLUMN IF NOT EXISTS rejection_reason VARCHAR(500) NULL COMMENT 'เหตุผลเมื่อ reject';
|
||||
|
||||
UPDATE migration_review_queue
|
||||
SET
|
||||
idempotency_key = COALESCE(idempotency_key, CONCAT(batch_id, ':', uuid)),
|
||||
original_filename = COALESCE(original_filename, original_file_name),
|
||||
ai_metadata_json = COALESCE(ai_metadata_json, extracted_metadata),
|
||||
rejection_reason = COALESCE(rejection_reason, error_reason)
|
||||
WHERE idempotency_key IS NULL
|
||||
OR original_filename IS NULL
|
||||
OR ai_metadata_json IS NULL
|
||||
OR rejection_reason IS NULL;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uq_migration_review_idempotency ON migration_review_queue (idempotency_key);
|
||||
CREATE INDEX IF NOT EXISTS idx_migration_review_status_created ON migration_review_queue (status, created_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_migration_review_batch ON migration_review_queue (batch_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_migration_review_reviewed_by ON migration_review_queue (reviewed_by);
|
||||
@@ -1,14 +0,0 @@
|
||||
-- File: specs/03-Data-and-Storage/deltas/15-add-ai-processing-status.sql
|
||||
-- Change Log
|
||||
-- - 2026-05-15: เพิ่มสถานะประมวลผล AI สำหรับเอกสารตาม ADR-023A FR-018.
|
||||
-- ADR-009: ใช้ SQL delta โดยตรง ห้ามใช้ TypeORM migration
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
-- หมายเหตุ: schema v1.9.0 ยังไม่มีตาราง documents กลาง จึงเพิ่มให้ตาราง attachments
|
||||
-- ซึ่งเป็นตารางไฟล์เอกสารรวมที่มีอยู่จริงใน canonical schema ปัจจุบัน
|
||||
ALTER TABLE attachments
|
||||
ADD COLUMN IF NOT EXISTS ai_processing_status ENUM('PENDING', 'PROCESSING', 'DONE', 'FAILED')
|
||||
NOT NULL DEFAULT 'PENDING' COMMENT 'สถานะ AI job ของไฟล์เอกสารตาม ADR-023A';
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_attachments_ai_status ON attachments (ai_processing_status);
|
||||
@@ -1,60 +0,0 @@
|
||||
-- Delta 16: Add Intent Classification Tables (ADR-024)
|
||||
-- Feature: 224-intent-classification
|
||||
-- Created: 2026-05-19
|
||||
-- เพิ่มตาราง ai_intent_definitions และ ai_intent_patterns สำหรับ Hybrid Intent Classifier
|
||||
|
||||
-- Intent Definitions Table
|
||||
CREATE TABLE IF NOT EXISTS ai_intent_definitions (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
public_id UUID NOT NULL DEFAULT UUID(),
|
||||
intent_code VARCHAR(50) NOT NULL,
|
||||
description_th VARCHAR(255) NOT NULL,
|
||||
description_en VARCHAR(255) NOT NULL,
|
||||
category ENUM('read', 'suggest', 'utility') NOT NULL,
|
||||
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
|
||||
UNIQUE KEY uk_intent_public_id (public_id),
|
||||
UNIQUE KEY uk_intent_code (intent_code),
|
||||
INDEX idx_intent_active (is_active, category)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- Intent Patterns Table
|
||||
CREATE TABLE IF NOT EXISTS ai_intent_patterns (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
public_id UUID NOT NULL DEFAULT UUID(),
|
||||
intent_code VARCHAR(50) NOT NULL,
|
||||
language ENUM('th', 'en', 'any') NOT NULL DEFAULT 'any',
|
||||
pattern_type ENUM('keyword', 'regex') NOT NULL DEFAULT 'keyword',
|
||||
pattern_value VARCHAR(255) NOT NULL,
|
||||
priority INT NOT NULL DEFAULT 100,
|
||||
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
|
||||
UNIQUE KEY uk_pattern_public_id (public_id),
|
||||
INDEX idx_pattern_intent_code (intent_code),
|
||||
INDEX idx_pattern_active_priority (is_active, priority ASC),
|
||||
CONSTRAINT fk_intent_pattern_definition
|
||||
FOREIGN KEY (intent_code) REFERENCES ai_intent_definitions(intent_code)
|
||||
ON UPDATE CASCADE ON DELETE RESTRICT
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- Seed Intent Definitions (v1) — 12 รายการตาม ADR-024
|
||||
INSERT IGNORE INTO ai_intent_definitions (intent_code, description_th, description_en, category) VALUES
|
||||
-- Read Intents
|
||||
('RAG_QUERY', 'ถามคำถามธรรมชาติ ตอบจาก vector + doc context', 'Natural language query from vector DB + document context', 'read'),
|
||||
('GET_RFA', 'ดึง RFA ตาม filter', 'Get RFA by filters', 'read'),
|
||||
('GET_DRAWING', 'ดึง Drawing revision', 'Get Drawing revision', 'read'),
|
||||
('GET_TRANSMITTAL', 'ดึง Transmittal', 'Get Transmittal', 'read'),
|
||||
('GET_CORRESPONDENCE','ดึง Correspondence ทั่วไป', 'Get Correspondence', 'read'),
|
||||
('GET_CIRCULATION', 'ดึง Circulation', 'Get Circulation', 'read'),
|
||||
('GET_RFA_DRAWINGS', 'ดึง Drawings ที่ผูกกับ RFA', 'Get Drawings linked to RFA', 'read'),
|
||||
('SUMMARIZE_DOCUMENT','สรุปเอกสารที่เปิดอยู่', 'Summarize current document', 'read'),
|
||||
('LIST_OVERDUE', 'รายการ cross-entity ที่เกินกำหนด', 'List overdue items across entities', 'read'),
|
||||
-- Suggest Intents
|
||||
('SUGGEST_METADATA', 'แนะนำ metadata สำหรับเอกสารที่อัปโหลด', 'Suggest metadata for uploaded document', 'suggest'),
|
||||
('SUGGEST_ACTION', 'แจ้งเตือนว่าควรทำอะไรต่อ', 'Suggest next actions', 'suggest'),
|
||||
-- Utility Intents
|
||||
('FALLBACK', 'ไม่เข้า intent ไหน / ไม่เกี่ยวกับระบบ', 'No matching intent / unrelated to system', 'utility');
|
||||
@@ -1,89 +0,0 @@
|
||||
-- Delta 17: Seed Intent Patterns (v1) for ADR-024 Intent Classification
|
||||
-- Feature: 224-intent-classification
|
||||
-- Created: 2026-05-19
|
||||
-- เพิ่ม patterns เริ่มต้นสำหรับ 12 Intent Definitions (keyword + regex)
|
||||
|
||||
-- RAG_QUERY patterns
|
||||
INSERT IGNORE INTO ai_intent_patterns (intent_code, language, pattern_type, pattern_value, priority) VALUES
|
||||
('RAG_QUERY', 'th', 'keyword', 'ค้นหา', 10),
|
||||
('RAG_QUERY', 'th', 'keyword', 'หาข้อมูล', 10),
|
||||
('RAG_QUERY', 'en', 'keyword', 'search', 10),
|
||||
('RAG_QUERY', 'en', 'keyword', 'find', 10),
|
||||
('RAG_QUERY', 'any', 'regex', '(?i)(what|where|who|when|how|why).*\\?', 50);
|
||||
|
||||
-- GET_RFA patterns
|
||||
INSERT IGNORE INTO ai_intent_patterns (intent_code, language, pattern_type, pattern_value, priority) VALUES
|
||||
('GET_RFA', 'th', 'keyword', 'rfa', 10),
|
||||
('GET_RFA', 'th', 'keyword', 'อาร์เอฟเอ', 10),
|
||||
('GET_RFA', 'en', 'keyword', 'request for approval', 15),
|
||||
('GET_RFA', 'any', 'regex', '(?i)rfa[- ]?\\d+', 5);
|
||||
|
||||
-- GET_DRAWING patterns
|
||||
INSERT IGNORE INTO ai_intent_patterns (intent_code, language, pattern_type, pattern_value, priority) VALUES
|
||||
('GET_DRAWING', 'th', 'keyword', 'แบบ', 20),
|
||||
('GET_DRAWING', 'th', 'keyword', 'drawing', 10),
|
||||
('GET_DRAWING', 'en', 'keyword', 'drawing', 10),
|
||||
('GET_DRAWING', 'en', 'keyword', 'revision', 20),
|
||||
('GET_DRAWING', 'any', 'regex', '(?i)(shop.?draw|dwg|rev\\.?\\s*\\d)', 5);
|
||||
|
||||
-- GET_TRANSMITTAL patterns
|
||||
INSERT IGNORE INTO ai_intent_patterns (intent_code, language, pattern_type, pattern_value, priority) VALUES
|
||||
('GET_TRANSMITTAL', 'th', 'keyword', 'transmittal', 10),
|
||||
('GET_TRANSMITTAL', 'th', 'keyword', 'ทรานส์มิตทอล', 10),
|
||||
('GET_TRANSMITTAL', 'en', 'keyword', 'transmittal', 10),
|
||||
('GET_TRANSMITTAL', 'any', 'regex', '(?i)tr[- ]?\\d+', 5);
|
||||
|
||||
-- GET_CORRESPONDENCE patterns
|
||||
INSERT IGNORE INTO ai_intent_patterns (intent_code, language, pattern_type, pattern_value, priority) VALUES
|
||||
('GET_CORRESPONDENCE', 'th', 'keyword', 'จดหมาย', 10),
|
||||
('GET_CORRESPONDENCE', 'th', 'keyword', 'หนังสือ', 15),
|
||||
('GET_CORRESPONDENCE', 'en', 'keyword', 'correspondence', 10),
|
||||
('GET_CORRESPONDENCE', 'en', 'keyword', 'letter', 15);
|
||||
|
||||
-- GET_CIRCULATION patterns
|
||||
INSERT IGNORE INTO ai_intent_patterns (intent_code, language, pattern_type, pattern_value, priority) VALUES
|
||||
('GET_CIRCULATION', 'th', 'keyword', 'เวียน', 10),
|
||||
('GET_CIRCULATION', 'th', 'keyword', 'circulation', 10),
|
||||
('GET_CIRCULATION', 'en', 'keyword', 'circulation', 10),
|
||||
('GET_CIRCULATION', 'en', 'keyword', 'distribute', 15);
|
||||
|
||||
-- GET_RFA_DRAWINGS patterns
|
||||
INSERT IGNORE INTO ai_intent_patterns (intent_code, language, pattern_type, pattern_value, priority) VALUES
|
||||
('GET_RFA_DRAWINGS', 'th', 'keyword', 'แบบใน rfa', 5),
|
||||
('GET_RFA_DRAWINGS', 'en', 'keyword', 'drawings in rfa', 5),
|
||||
('GET_RFA_DRAWINGS', 'any', 'regex', '(?i)(draw|แบบ).*(rfa|อาร์เอฟเอ)', 5);
|
||||
|
||||
-- SUMMARIZE_DOCUMENT patterns
|
||||
INSERT IGNORE INTO ai_intent_patterns (intent_code, language, pattern_type, pattern_value, priority) VALUES
|
||||
('SUMMARIZE_DOCUMENT', 'th', 'keyword', 'สรุป', 10),
|
||||
('SUMMARIZE_DOCUMENT', 'th', 'keyword', 'สรุปเอกสาร', 5),
|
||||
('SUMMARIZE_DOCUMENT', 'en', 'keyword', 'summarize', 10),
|
||||
('SUMMARIZE_DOCUMENT', 'en', 'keyword', 'summary', 10),
|
||||
('SUMMARIZE_DOCUMENT', 'any', 'regex', '(?i)(สรุป|summar|tldr|tl;dr)', 5);
|
||||
|
||||
-- LIST_OVERDUE patterns
|
||||
INSERT IGNORE INTO ai_intent_patterns (intent_code, language, pattern_type, pattern_value, priority) VALUES
|
||||
('LIST_OVERDUE', 'th', 'keyword', 'เกินกำหนด', 10),
|
||||
('LIST_OVERDUE', 'th', 'keyword', 'ค้าง', 15),
|
||||
('LIST_OVERDUE', 'th', 'keyword', 'overdue', 10),
|
||||
('LIST_OVERDUE', 'en', 'keyword', 'overdue', 10),
|
||||
('LIST_OVERDUE', 'en', 'keyword', 'late', 20),
|
||||
('LIST_OVERDUE', 'any', 'regex', '(?i)(overdue|เกินกำหนด|ล่าช้า)', 5);
|
||||
|
||||
-- SUGGEST_METADATA patterns
|
||||
INSERT IGNORE INTO ai_intent_patterns (intent_code, language, pattern_type, pattern_value, priority) VALUES
|
||||
('SUGGEST_METADATA', 'th', 'keyword', 'แนะนำ metadata', 5),
|
||||
('SUGGEST_METADATA', 'th', 'keyword', 'แท็ก', 15),
|
||||
('SUGGEST_METADATA', 'en', 'keyword', 'suggest metadata', 5),
|
||||
('SUGGEST_METADATA', 'en', 'keyword', 'tag', 15),
|
||||
('SUGGEST_METADATA', 'any', 'regex', '(?i)(suggest|แนะนำ).*(tag|meta|ประเภท)', 5);
|
||||
|
||||
-- SUGGEST_ACTION patterns
|
||||
INSERT IGNORE INTO ai_intent_patterns (intent_code, language, pattern_type, pattern_value, priority) VALUES
|
||||
('SUGGEST_ACTION', 'th', 'keyword', 'ทำอะไรต่อ', 10),
|
||||
('SUGGEST_ACTION', 'th', 'keyword', 'แนะนำ', 20),
|
||||
('SUGGEST_ACTION', 'en', 'keyword', 'what should i do', 10),
|
||||
('SUGGEST_ACTION', 'en', 'keyword', 'next step', 10),
|
||||
('SUGGEST_ACTION', 'any', 'regex', '(?i)(next.?step|ทำอะไร|ควรทำ|what.*do)', 10);
|
||||
|
||||
-- FALLBACK: ไม่ต้อง seed pattern — ใช้เป็น default เมื่อไม่ match อะไรเลย
|
||||
Reference in New Issue
Block a user