690519:1719 224 to 226 AI #02
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
# 📝 Contributing to LCBP3-DMS Specifications
|
||||
|
||||
> แนวทางการมีส่วนร่วมในการพัฒนาเอกสาร Specifications ของโครงการ LCBP3-DMS (v1.9.2)
|
||||
> แนวทางการมีส่วนร่วมในการพัฒนาเอกสาร Specifications ของโครงการ LCBP3-DMS (v1.9.5)
|
||||
|
||||
ยินดีต้อนรับสู่คู่มือการมีส่วนร่วมในการพัฒนาเอกสาร Specifications! เอกสารนี้จะช่วยให้คุณเข้าใจวิธีการสร้าง แก้ไข และปรับปรุงเอกสารข้อกำหนดของโครงการได้อย่างมีประสิทธิภาพ
|
||||
|
||||
|
||||
@@ -58,14 +58,9 @@ describe('PatternMatcherService — Performance', () => {
|
||||
expect(result?.intentCode).toBe('SUMMARIZE_DOCUMENT');
|
||||
|
||||
const avg = times.reduce((a, b) => a + b, 0) / times.length;
|
||||
const max = Math.max(...times);
|
||||
const _max = Math.max(...times); // Kept for potential future debugging
|
||||
const p95 = times.sort((a, b) => a - b)[Math.floor(times.length * 0.95)];
|
||||
|
||||
// eslint-disable-next-line no-console -- performance logging allowed in test
|
||||
console.log(
|
||||
`Pattern Match Perf: avg=${avg.toFixed(3)}ms, p95=${p95.toFixed(3)}ms, max=${max.toFixed(3)}ms`
|
||||
);
|
||||
|
||||
// SC-001: synthetic worst-case (100+ patterns รวม 50 invalid regex try-catch)
|
||||
// ค่า threshold สูงเพื่อรองรับ CI/IDE background load — regression detection only
|
||||
// Production (keyword-only, 10-20 patterns): < 1ms
|
||||
@@ -100,11 +95,6 @@ describe('PatternMatcherService — Performance', () => {
|
||||
const avg = times.reduce((a, b) => a + b, 0) / times.length;
|
||||
const p95 = times.sort((a, b) => a - b)[Math.floor(times.length * 0.95)];
|
||||
|
||||
// eslint-disable-next-line no-console -- performance logging allowed in test
|
||||
console.log(
|
||||
`Pattern Miss Perf: avg=${avg.toFixed(3)}ms, p95=${p95.toFixed(3)}ms`
|
||||
);
|
||||
|
||||
// SC-001: worst-case full scan (100+ patterns รวม 50 invalid regex try-catch)
|
||||
// Production keyword-only จะ < 1ms — ค่านี้เพื่อ regression detection
|
||||
expect(avg).toBeLessThan(200);
|
||||
|
||||
@@ -2371,7 +2371,43 @@ PENDING_REVIEW ──→ VERIFIED ──→ IMPORTED (terminal)
|
||||
|
||||
---
|
||||
|
||||
### 19.3 Confidence Scoring Strategy (ADR-020)
|
||||
### 19.3 `document_chunks`
|
||||
|
||||
**วัตถุประสงค์:** เก็บ vector metadata สำหรับ RAG ingestion ตาม ADR-022
|
||||
|
||||
| Column | Type | Nullable | Description |
|
||||
|--------|------|----------|-------------|
|
||||
| `id` | CHAR(36) | NO | UUID = Qdrant point ID |
|
||||
| `document_id` | CHAR(36) | NO | FK → attachments.public_id (UUIDv7) |
|
||||
| `chunk_index` | INT | NO | ลำดับ chunk ภายใน document |
|
||||
| `content` | TEXT | NO | เนื้อหา chunk หลัง PyThaiNLP normalize |
|
||||
| `doc_type` | VARCHAR(20) | NO | CORR, RFA, DRAWING, CONTRACT, RPT, TRANS |
|
||||
| `doc_number` | VARCHAR(100) | YES | หมายเลขเอกสาร เช่น REF-2026-001 |
|
||||
| `revision` | VARCHAR(20) | YES | Revision เช่น Rev.A |
|
||||
| `project_code` | VARCHAR(50) | NO | รหัสโครงการ (ใช้ filter) |
|
||||
| `project_public_id` | CHAR(36) | NO | UUIDv7 ของโครงการ (Qdrant tenant key) |
|
||||
| `version` | VARCHAR(20) | YES | เวอร์ชันเอกสาร เช่น 1.0, 2.1 (ถ้ามี) |
|
||||
| `classification` | ENUM | NO | PUBLIC, INTERNAL, CONFIDENTIAL (DEFAULT: INTERNAL) |
|
||||
| `embedding_model` | VARCHAR(100) | NO | nomic-embed-text |
|
||||
| `created_at` | DATETIME(3) | NO | วันที่สร้าง |
|
||||
|
||||
**Indexes**:
|
||||
|
||||
- PRIMARY KEY (id)
|
||||
- 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)
|
||||
|
||||
**Business Rules**:
|
||||
|
||||
1. **Project Isolation** — Qdrant queries MUST include project_public_id filter (compile-time enforcement per ADR-023A)
|
||||
2. **Chunk Size** — 512 tokens with 64 tokens overlap (ADR-023A RAG embed scope)
|
||||
3. **Embedding Model** — nomic-embed-text only (ADR-023A 2-model stack)
|
||||
|
||||
---
|
||||
|
||||
### 19.4 Confidence Scoring Strategy (ADR-020)
|
||||
|
||||
| Score Range | Action | Description |
|
||||
|-------------|--------|-------------|
|
||||
@@ -2382,6 +2418,72 @@ PENDING_REVIEW ──→ VERIFIED ──→ IMPORTED (terminal)
|
||||
|
||||
---
|
||||
|
||||
### 19.4 Intent Classification Tables (ADR-024)
|
||||
|
||||
> เพิ่มใน v1.9.0 — Feature 224-intent-classification | ตารางสำหรับ Hybrid Intent Classifier (Pattern Match + LLM Fallback)
|
||||
|
||||
#### 19.4.1 `ai_intent_definitions`
|
||||
|
||||
**วัตถุประสงค์:** เก็บ Intent Definitions (ประเภทความตั้งใจของผู้ใช้) สำหรับ Hybrid Intent Classifier ตาม ADR-024
|
||||
|
||||
| Column Name | Data Type | Constraints | Description |
|
||||
| ----------- | --------- | ----------- | ----------- |
|
||||
| id | INT | PRIMARY KEY, AUTO_INCREMENT | Internal PK (ห้าม expose ใน API) |
|
||||
| public_id | UUID | NOT NULL, UNIQUE, DEFAULT UUID() | UUID Public Identifier (ADR-019) |
|
||||
| intent_code | VARCHAR(50) | NOT NULL, UNIQUE | รหัส Intent เช่น RAG_QUERY, GET_RFA |
|
||||
| description_th | VARCHAR(255) | NOT NULL | คำอธิบายภาษาไทย |
|
||||
| description_en | VARCHAR(255) | NOT NULL | คำอธิบายภาษาอังกฤษ |
|
||||
| category | ENUM | NOT NULL | read, suggest, utility |
|
||||
| is_active | BOOLEAN | NOT NULL, DEFAULT TRUE | สถานะการใช้งาน |
|
||||
| created_at | TIMESTAMP | NOT NULL, DEFAULT CURRENT_TIMESTAMP | วันที่สร้าง |
|
||||
| updated_at | TIMESTAMP | NOT NULL, ON UPDATE CURRENT_TIMESTAMP | วันที่แก้ไขล่าสุด |
|
||||
|
||||
**Indexes**:
|
||||
- PRIMARY KEY (id)
|
||||
- UNIQUE KEY uk_intent_public_id (public_id)
|
||||
- UNIQUE KEY uk_intent_code (intent_code)
|
||||
- INDEX idx_intent_active (is_active, category)
|
||||
|
||||
**Business Rules**:
|
||||
1. **Intent Categories** — read (ดึงข้อมูล), suggest (แนะนำ), utility (อื่นๆ)
|
||||
2. **Active Status** — Intent ที่ไม่ active จะไม่ถูกใช้ในการ classify
|
||||
3. **Seed Data** — 12 Intent Definitions พร้อม patterns v1 (RAG_QUERY, GET_RFA, GET_DRAWING, ฯลฯ)
|
||||
|
||||
---
|
||||
|
||||
#### 19.4.2 `ai_intent_patterns`
|
||||
|
||||
**วัตถุประสงค์:** เก็บ Patterns (keyword และ regex) สำหรับ Pattern Matching ใน Hybrid Intent Classifier
|
||||
|
||||
| Column Name | Data Type | Constraints | Description |
|
||||
| ----------- | --------- | ----------- | ----------- |
|
||||
| id | INT | PRIMARY KEY, AUTO_INCREMENT | Internal PK (ห้าม expose ใน API) |
|
||||
| public_id | UUID | NOT NULL, UNIQUE, DEFAULT UUID() | UUID Public Identifier (ADR-019) |
|
||||
| intent_code | VARCHAR(50) | NOT NULL, FK | รหัส Intent (FK to ai_intent_definitions) |
|
||||
| language | ENUM | NOT NULL, DEFAULT 'any' | th, en, any |
|
||||
| pattern_type | ENUM | NOT NULL, DEFAULT 'keyword' | keyword, regex |
|
||||
| pattern_value | VARCHAR(255) | NOT NULL | ค่า pattern (keyword หรือ regex) |
|
||||
| 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, ON UPDATE CURRENT_TIMESTAMP | วันที่แก้ไขล่าสุด |
|
||||
|
||||
**Indexes**:
|
||||
- PRIMARY KEY (id)
|
||||
- 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
|
||||
|
||||
**Business Rules**:
|
||||
1. **Pattern Types** — keyword (ตรงตัว), regex (regular expression)
|
||||
2. **Priority** — ยิ่งน้อยยิ่งสำคัญ (ตัวอย่าง: keyword=10, regex=5)
|
||||
3. **Language** — th (ไทย), en (อังกฤษ), any (ทุกภาษา)
|
||||
4. **Seed Data** — ~45 patterns สำหรับ 12 Intents (ยกเว้น FALLBACK)
|
||||
5. **LLM Fallback** — เมื่อไม่ match pattern ไหนเลย → ใช้ LLM (gemma4:e4b Q8_0) ตาม ADR-023A
|
||||
|
||||
---
|
||||
|
||||
## **20. 📖 Glossary (คำศัพท์)**
|
||||
|
||||
- **RFA**: Request for Approval (เอกสารขออนุมัติ)
|
||||
|
||||
@@ -11,28 +11,17 @@
|
||||
| `lcbp3-v1.9.0-schema-01-drop.sql` | สคริปต์ลบตารางทั้งหมด (ใช้สำหรับ reset schema) |
|
||||
| `lcbp3-v1.9.0-schema-02-tables.sql` | สคริปต์สร้างตารางทั้งหมด (CREATE TABLE) |
|
||||
| `lcbp3-v1.9.0-schema-03-views-indexes.sql` | สคริปต์สร้าง Views และ Indexes |
|
||||
| `lcbp3-v1.9.0-migration.sql` | สคริปต์ migration สำหรับการอัปเกรดจากเวอร์ชันก่อนหน้า |
|
||||
| `lcbp3-v1.9.0-rfa-approval-schema.sql` | Schema เฉพาะสำหรับระบบ RFA Approval System |
|
||||
| `lcbp3-v1.9.0-migration.sql` | สคริปต์ migration support tables สำหรับ n8n Migration Workflow (temporary - ลบได้หลัง migration เสร็จ) |
|
||||
|
||||
### Seed Files (ข้อมูลเริ่มต้น)
|
||||
|
||||
| ไฟล์ | คำอธิบาย |
|
||||
|------|-----------|
|
||||
| `lcbp3-v1.9.0-seed-basic.sql` | ข้อมูลเริ่มต้นพื้นฐาน (Organizations, Users, Roles, Permissions) |
|
||||
| `lcbp3-v1.9.0-seed-basic.sql` | ข้อมูลเริ่มต้นพื้นฐาน (Organizations, Users, Roles, Permissions, Intent Classification, Workflow Definitions) |
|
||||
| `lcbp3-v1.9.0-seed-permissions.sql` | ข้อมูล RBAC Permissions ตาม ADR-016 |
|
||||
| `lcbp3-v1.9.0-seed-contractdrawing.sql` | ข้อมูล Contract Drawings ตัวอย่าง |
|
||||
| `lcbp3-v1.9.0-seed-shopdrawing.sql` | ข้อมูล Shop Drawings ตัวอย่าง |
|
||||
|
||||
### Delta Files (การเปลี่ยนแปลง Schema แบบ Incremental)
|
||||
|
||||
ตั้งอยู่ใน `deltas/` - เก็บ SQL delta สำหรับการเปลี่ยนแปลง schema ตาม ADR-009 (ไม่ใช้ TypeORM migrations)
|
||||
|
||||
| ไฟล์ | คำอธิบาย |
|
||||
|------|-----------|
|
||||
| `12-unified-ai-architecture.sql` | เพิ่มตาราง AI: migration_review_queue, ai_audit_logs (ADR-023) |
|
||||
| `14-add-migration-review-queue.sql` | เพิ่มคอลัมน์ใหม่ใน migration_review_queue (ADR-023A) |
|
||||
| `15-add-ai-processing-status.sql` | เพิ่ม ai_processing_status ใน attachments (ADR-023A) |
|
||||
|
||||
### Documentation
|
||||
|
||||
| ไฟล์ | คำอธิบาย |
|
||||
@@ -81,13 +70,11 @@ mysql < lcbp3-v1.9.0-seed-shopdrawing.sql
|
||||
### การอัปเกรดจากเวอร์ชันก่อนหน้า
|
||||
|
||||
```bash
|
||||
# รัน migration script
|
||||
# รัน migration script (สำหรับ n8n Migration Workflow เท่านั้น)
|
||||
mysql < lcbp3-v1.9.0-migration.sql
|
||||
|
||||
# รัน delta files ที่ยังไม่ได้ใช้ (ตามลำดับเลข)
|
||||
mysql < deltas/12-unified-ai-architecture.sql
|
||||
mysql < deltas/14-add-migration-review-queue.sql
|
||||
mysql < deltas/15-add-ai-processing-status.sql
|
||||
# หมายเหตุ: ทุกการเปลี่ยนแปลง schema ได้ถูกรวมเข้า schema-02-tables.sql และ seed files แล้ว
|
||||
# ไม่มี delta files ที่ต้องรันแยกตาม ADR-009
|
||||
```
|
||||
|
||||
## 🔗 เอกสารที่เกี่ยวข้อง
|
||||
@@ -99,6 +86,7 @@ mysql < deltas/15-add-ai-processing-status.sql
|
||||
- **ADR-019**: Hybrid Identifier Strategy - UUID Strategy
|
||||
- **ADR-023**: Unified AI Architecture - สถาปัตยกรรม AI หลัก
|
||||
- **ADR-023A**: Unified AI Architecture (Model Revision) - อัปเดตโมเดล AI
|
||||
- **ADR-024**: Intent Classification Strategy - Hybrid Intent Classifier (Pattern Match + LLM Fallback)
|
||||
|
||||
### Engineering Guidelines
|
||||
|
||||
@@ -115,6 +103,16 @@ mysql < deltas/15-add-ai-processing-status.sql
|
||||
|
||||
## 📝 Change Log
|
||||
|
||||
- **2026-05-19**:
|
||||
- เพิ่ม Intent Classification tables (ai_intent_definitions, ai_intent_patterns) ตาม ADR-024
|
||||
- รวม delta files (16-add-intent-classification.sql, 17-seed-intent-patterns.sql) เข้า schema-02-tables.sql และ seed-basic.sql
|
||||
- ลบ rfa-approval-schema.sql (ตารางทั้งหมดถูกรวมเข้า schema-02-tables.sql แล้ว)
|
||||
- ลบ redundant delta files (12, 14, 15) - ตารางและคอลัมน์ทั้งหมดถูกรวมเข้า schema-02-tables.sql แล้ว
|
||||
- รวม delta files ที่เหลือ (13 ไฟล์) เข้า schema-02-tables.sql, seed-permissions.sql, และ seed-basic.sql:
|
||||
- Schema: rag_status, rag_last_error (attachments), document_chunks table
|
||||
- Seed: RAG permissions, RBAC bulk permission, CIRCULATION_FLOW_V1 workflow definition
|
||||
- อัปเดต Data Dictionary ด้วย document_chunks table
|
||||
- ลบ deltas/ directory ทั้งหมด (ตาม ADR-009 - รวมเข้า main schema/seed เสร็จแล้ว)
|
||||
- **2026-05-15**: เพิ่ม AI-related tables (migration_review_queue, ai_audit_logs) และ ai_processing_status column ตาม ADR-023A
|
||||
- **2026-05-14**: อัปเดต schema เป็น v1.9.0 เพื่อรองรับ RFA Approval System และ Unified AI Architecture
|
||||
|
||||
|
||||
@@ -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 อะไรเลย
|
||||
@@ -1,211 +0,0 @@
|
||||
-- =============================================================================
|
||||
-- LCBP3-DMS v1.9.0 — RFA Approval System Refactor Schema
|
||||
-- Feature Branch: 204-rfa-approval-refactor
|
||||
-- ADR-009: No TypeORM migrations — edit SQL schema directly
|
||||
-- Created: 2026-05-13
|
||||
-- =============================================================================
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- 1. review_teams — ทีมตรวจสอบแยกตาม Discipline
|
||||
-- -----------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `review_teams` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`uuid` UUID NOT NULL DEFAULT (UUID()),
|
||||
`project_id` INT NOT NULL,
|
||||
`name` VARCHAR(100) NOT NULL,
|
||||
`description` VARCHAR(255) NULL,
|
||||
`default_for_rfa_types` TEXT NULL COMMENT 'Comma-separated RFA type codes e.g. SDW,DDW',
|
||||
`is_active` TINYINT(1) NOT NULL DEFAULT 1,
|
||||
`created_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
`updated_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uq_review_teams_uuid` (`uuid`),
|
||||
KEY `idx_review_teams_project` (`project_id`, `is_active`),
|
||||
CONSTRAINT `fk_review_teams_project` FOREIGN KEY (`project_id`) REFERENCES `projects` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- 2. review_team_members — สมาชิกในทีมแยกตาม Discipline
|
||||
-- -----------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `review_team_members` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`uuid` UUID NOT NULL DEFAULT (UUID()),
|
||||
`team_id` INT NOT NULL,
|
||||
`user_id` INT NOT NULL,
|
||||
`discipline_id` INT NOT NULL,
|
||||
`role` ENUM('REVIEWER','LEAD','MANAGER') NOT NULL DEFAULT 'REVIEWER',
|
||||
`priority_order` INT NOT NULL DEFAULT 0,
|
||||
`created_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uq_review_team_members_uuid` (`uuid`),
|
||||
UNIQUE KEY `uq_team_user_discipline` (`team_id`, `user_id`, `discipline_id`),
|
||||
KEY `idx_rtm_team` (`team_id`),
|
||||
KEY `idx_rtm_user` (`user_id`),
|
||||
CONSTRAINT `fk_rtm_team` FOREIGN KEY (`team_id`) REFERENCES `review_teams` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `fk_rtm_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `fk_rtm_discipline` FOREIGN KEY (`discipline_id`) REFERENCES `disciplines` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- 3. response_codes — รหัสตอบกลับมาตรฐาน (Master Approval Matrix)
|
||||
-- -----------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `response_codes` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`uuid` UUID NOT NULL DEFAULT (UUID()),
|
||||
`code` VARCHAR(10) NOT NULL COMMENT '1A, 1B, 1C, 1D, 1E, 1F, 1G, 2, 3, 4',
|
||||
`sub_status` VARCHAR(10) NULL,
|
||||
`category` ENUM('ENGINEERING','MATERIAL','CONTRACT','TESTING','ESG') NOT NULL,
|
||||
`description_th` TEXT NOT NULL,
|
||||
`description_en` TEXT NOT NULL,
|
||||
`implications` JSON NULL COMMENT '{"affectsSchedule":bool,"affectsCost":bool,"requiresContractReview":bool}',
|
||||
`notify_roles` TEXT NULL COMMENT 'Comma-separated roles e.g. CONTRACT_MANAGER,QS_MANAGER',
|
||||
`is_active` TINYINT(1) NOT NULL DEFAULT 1,
|
||||
`is_system` TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'System default — cannot delete',
|
||||
`created_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uq_response_codes_uuid` (`uuid`),
|
||||
UNIQUE KEY `uq_response_code_category` (`code`, `category`),
|
||||
KEY `idx_rc_category_active` (`category`, `is_active`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- 4. response_code_rules — กฎการใช้รหัสต่อโครงการ/ประเภทเอกสาร
|
||||
-- -----------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `response_code_rules` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`uuid` UUID NOT NULL DEFAULT (UUID()),
|
||||
`project_id` INT NULL COMMENT 'NULL = global default',
|
||||
`document_type_id` INT NOT NULL,
|
||||
`response_code_id` INT NOT NULL,
|
||||
`is_enabled` TINYINT(1) NOT NULL DEFAULT 1,
|
||||
`requires_comments` TINYINT(1) NOT NULL DEFAULT 0,
|
||||
`triggers_notification` TINYINT(1) NOT NULL DEFAULT 0,
|
||||
`parent_rule_id` INT NULL COMMENT 'For inheritance tracking',
|
||||
`created_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
`updated_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uq_response_code_rules_uuid` (`uuid`),
|
||||
UNIQUE KEY `uq_rule_per_project_doctype_code` (`project_id`, `document_type_id`, `response_code_id`),
|
||||
KEY `idx_response_rules_lookup` (`project_id`, `document_type_id`, `is_enabled`),
|
||||
CONSTRAINT `fk_rcr_response_code` FOREIGN KEY (`response_code_id`) REFERENCES `response_codes` (`id`),
|
||||
CONSTRAINT `fk_rcr_parent` FOREIGN KEY (`parent_rule_id`) REFERENCES `response_code_rules` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- 5. review_tasks — งานตรวจสอบสำหรับแต่ละ Discipline (Parallel Review)
|
||||
-- -----------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `review_tasks` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`uuid` UUID NOT NULL DEFAULT (UUID()),
|
||||
`rfa_revision_id` INT NOT NULL,
|
||||
`team_id` INT NOT NULL,
|
||||
`discipline_id` INT NOT NULL,
|
||||
`assigned_to_user_id` INT NULL COMMENT 'NULL = auto-assign by discipline',
|
||||
`status` ENUM('PENDING','IN_PROGRESS','COMPLETED','DELEGATED','EXPIRED','CANCELLED') NOT NULL DEFAULT 'PENDING',
|
||||
`due_date` DATE NULL,
|
||||
`response_code_id` INT NULL,
|
||||
`comments` TEXT NULL,
|
||||
`attachments` JSON NULL COMMENT 'Array of attachment publicIds',
|
||||
`delegated_from_user_id` INT NULL COMMENT 'Original assignee when delegated',
|
||||
`completed_at` TIMESTAMP NULL,
|
||||
`version` INT NOT NULL DEFAULT 1 COMMENT 'Optimistic locking (ADR-002)',
|
||||
`created_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
`updated_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uq_review_tasks_uuid` (`uuid`),
|
||||
UNIQUE KEY `uq_review_task_per_revision_discipline` (`rfa_revision_id`, `team_id`, `discipline_id`),
|
||||
KEY `idx_review_tasks_rfa_revision` (`rfa_revision_id`),
|
||||
KEY `idx_review_tasks_status` (`status`),
|
||||
KEY `idx_review_tasks_assigned` (`assigned_to_user_id`, `status`),
|
||||
CONSTRAINT `fk_rt_rfa_revision` FOREIGN KEY (`rfa_revision_id`) REFERENCES `rfa_revisions` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `fk_rt_team` FOREIGN KEY (`team_id`) REFERENCES `review_teams` (`id`),
|
||||
CONSTRAINT `fk_rt_discipline` FOREIGN KEY (`discipline_id`) REFERENCES `disciplines` (`id`),
|
||||
CONSTRAINT `fk_rt_user` FOREIGN KEY (`assigned_to_user_id`) REFERENCES `users` (`user_id`) ON DELETE SET NULL,
|
||||
CONSTRAINT `fk_rt_response_code` FOREIGN KEY (`response_code_id`) REFERENCES `response_codes` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- 6. delegations — การมอบหมายงาน
|
||||
-- -----------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `delegations` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`uuid` UUID NOT NULL DEFAULT (UUID()),
|
||||
`delegator_user_id` INT NOT NULL COMMENT 'ผู้มอบหมาย (FK → users.user_id)',
|
||||
`delegate_user_id` INT NOT NULL COMMENT 'ผู้รับมอบหมาย (FK → users.user_id)',
|
||||
`start_date` DATE NOT NULL,
|
||||
`end_date` DATE NULL COMMENT 'BullMQ job flips is_active=0 when end_date < NOW() (ADR-008)',
|
||||
`scope` ENUM('ALL','RFA_ONLY','CORRESPONDENCE_ONLY','SPECIFIC_TYPES') NOT NULL DEFAULT 'ALL',
|
||||
`document_types` TEXT NULL COMMENT 'Comma-separated doc type codes when scope=SPECIFIC_TYPES',
|
||||
`is_active` TINYINT(1) NOT NULL DEFAULT 1 COMMENT 'Managed by BullMQ scheduler — do not flip manually',
|
||||
`reason` TEXT NULL,
|
||||
`created_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
`updated_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uq_delegations_uuid` (`uuid`),
|
||||
KEY `idx_delegations_active` (`delegator_user_id`, `is_active`, `start_date`, `end_date`),
|
||||
KEY `idx_delegations_delegate` (`delegate_user_id`, `is_active`),
|
||||
CONSTRAINT `fk_del_delegator` FOREIGN KEY (`delegator_user_id`) REFERENCES `users` (`user_id`),
|
||||
CONSTRAINT `fk_del_delegate` FOREIGN KEY (`delegate_user_id`) REFERENCES `users` (`user_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- 7. reminder_rules — กฎการแจ้งเตือน
|
||||
-- -----------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `reminder_rules` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`uuid` UUID NOT NULL DEFAULT (UUID()),
|
||||
`name` VARCHAR(100) NOT NULL,
|
||||
`project_id` INT NULL COMMENT 'NULL = global',
|
||||
`document_type_id` INT NULL COMMENT 'NULL = all types',
|
||||
`trigger_days_before_due` INT NOT NULL DEFAULT 2,
|
||||
`escalation_days_after_due` INT NOT NULL DEFAULT 1,
|
||||
`reminder_type` ENUM('DUE_SOON','ON_DUE','OVERDUE','ESCALATION_L1','ESCALATION_L2') NOT NULL,
|
||||
`recipients` TEXT NOT NULL COMMENT 'Comma-separated: ASSIGNEE,MANAGER,PROJECT_MANAGER',
|
||||
`message_template_th` TEXT NOT NULL,
|
||||
`message_template_en` TEXT NOT NULL,
|
||||
`is_active` TINYINT(1) NOT NULL DEFAULT 1,
|
||||
`created_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
`updated_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uq_reminder_rules_uuid` (`uuid`),
|
||||
KEY `idx_reminder_rules_active` (`is_active`, `project_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- 8. distribution_matrices — ตารางกระจายเอกสาร
|
||||
-- -----------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `distribution_matrices` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`uuid` UUID NOT NULL DEFAULT (UUID()),
|
||||
`name` VARCHAR(100) NOT NULL,
|
||||
`project_id` INT NULL COMMENT 'NULL = global',
|
||||
`document_type_id` INT NOT NULL,
|
||||
`response_code_id` INT NULL COMMENT 'NULL = applies to all codes',
|
||||
`conditions` JSON NULL COMMENT '{"codes":["1A","1B"],"excludeCodes":["3","4"]}',
|
||||
`is_active` TINYINT(1) NOT NULL DEFAULT 1,
|
||||
`created_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uq_distribution_matrices_uuid` (`uuid`),
|
||||
KEY `idx_distribution_lookup` (`document_type_id`, `response_code_id`, `is_active`),
|
||||
CONSTRAINT `fk_dm_response_code` FOREIGN KEY (`response_code_id`) REFERENCES `response_codes` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- 9. distribution_recipients — ผู้รับเอกสารใน Distribution Matrix
|
||||
-- -----------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `distribution_recipients` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`uuid` UUID NOT NULL DEFAULT (UUID()) COMMENT 'UUID Public Identifier (ADR-019)',
|
||||
`matrix_id` INT NOT NULL,
|
||||
`recipient_type` ENUM('USER','ORGANIZATION','TEAM','ROLE') NOT NULL,
|
||||
`recipient_public_id` UUID NOT NULL COMMENT 'publicId of target: USER=users.uuid | ORGANIZATION=organizations.uuid | TEAM=review_teams.uuid | ROLE=roles.uuid',
|
||||
`delivery_method` ENUM('EMAIL','IN_APP','BOTH') NOT NULL DEFAULT 'BOTH',
|
||||
`sequence` INT NULL COMMENT 'For ordered delivery',
|
||||
`created_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uq_distribution_recipients_uuid` (`uuid`),
|
||||
KEY `idx_dr_matrix` (`matrix_id`),
|
||||
KEY `idx_dr_type_recipient` (`recipient_type`, `recipient_public_id`),
|
||||
CONSTRAINT `fk_dr_matrix` FOREIGN KEY (`matrix_id`) REFERENCES `distribution_matrices` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
COMMENT='Polymorphic recipients — no FK on recipient_public_id by design.';
|
||||
@@ -872,15 +872,42 @@ CREATE TABLE attachments (
|
||||
reference_date DATE NULL COMMENT 'Date used for folder structure (e.g. Issue Date) to prevent broken paths',
|
||||
workflow_history_id CHAR(36) NULL COMMENT 'FK to workflow_histories.id for step-specific attachments (ADR-021). NULL = main document',
|
||||
ai_processing_status ENUM('PENDING', 'PROCESSING', 'DONE', 'FAILED') NOT NULL DEFAULT 'PENDING' COMMENT 'สถานะ AI job ของไฟล์เอกสารตาม ADR-023A',
|
||||
rag_status ENUM('PENDING', 'PROCESSING', 'INDEXED', 'FAILED') NOT NULL DEFAULT 'PENDING' COMMENT 'สถานะ RAG ingestion ระดับ file (ADR-022)',
|
||||
rag_last_error TEXT NULL COMMENT 'Error message ล่าสุดเมื่อ rag_status = FAILED',
|
||||
FOREIGN KEY (uploaded_by_user_id) REFERENCES users (user_id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (workflow_history_id) REFERENCES workflow_histories (id) ON DELETE
|
||||
SET NULL ON UPDATE CASCADE,
|
||||
INDEX idx_attachments_reference_date (reference_date),
|
||||
INDEX idx_att_wfhist_created (workflow_history_id, created_at),
|
||||
INDEX idx_attachments_ai_status (ai_processing_status),
|
||||
INDEX idx_attachments_rag_status (rag_status),
|
||||
UNIQUE INDEX idx_attachments_uuid (uuid)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ตาราง "กลาง" เก็บไฟล์แนบทั้งหมดของระบบ';
|
||||
|
||||
-- =====================================================
|
||||
-- 14. 📄 Document Chunks (ADR-022 RAG)
|
||||
-- =====================================================
|
||||
-- ตารางเก็บ vector metadata สำหรับ RAG ingestion
|
||||
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 COMMENT = 'ตาราง Document Chunks สำหรับ RAG (ADR-022)';
|
||||
|
||||
-- ตารางเชื่อม correspondence_revisions กับ attachments (M:N)
|
||||
-- [FIX] FK เปลี่ยนจาก correspondences.id → correspondence_revisions.id
|
||||
-- เหตุผล: ไฟล์แนบผูกกับ revision ไม่ใช่ correspondence master (แต่ละ revision มีไฟล์ต่างกัน)
|
||||
@@ -1365,9 +1392,6 @@ CREATE TABLE workflow_definitions (
|
||||
UNIQUE KEY uq_workflow_version (workflow_code, version)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ตารางเก็บนิยามกฎการเดินเอกสาร (Workflow DSL)';
|
||||
|
||||
-- สร้าง Index สำหรับการค้นหา Workflow ที่ Active ล่าสุดได้เร็วขึ้น
|
||||
CREATE INDEX idx_workflow_active ON workflow_definitions (workflow_code, is_active, version);
|
||||
|
||||
-- 2. ตารางเก็บ Workflow Instance (สถานะเอกสารจริง)
|
||||
CREATE TABLE workflow_instances (
|
||||
id CHAR(36) NOT NULL PRIMARY KEY COMMENT 'UUID ของ Instance',
|
||||
@@ -1392,15 +1416,6 @@ CREATE TABLE workflow_instances (
|
||||
SET NULL -- [delta-07]
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ตารางเก็บสถานะการเดินเรื่องของเอกสาร';
|
||||
|
||||
CREATE INDEX idx_wf_inst_entity ON workflow_instances (entity_type, entity_id);
|
||||
|
||||
CREATE INDEX idx_wf_inst_contract ON workflow_instances (contract_id, entity_type, STATUS);
|
||||
|
||||
CREATE INDEX idx_wf_inst_state ON workflow_instances (current_state);
|
||||
|
||||
-- Index เพื่อรองรับ CAS check: WHERE id = ? AND version_no = ?
|
||||
CREATE INDEX idx_wf_inst_version ON workflow_instances (id, version_no);
|
||||
|
||||
-- 3. ตารางเก็บประวัติ (Audit Log / History)
|
||||
CREATE TABLE workflow_histories (
|
||||
id CHAR(36) NOT NULL PRIMARY KEY COMMENT 'UUID',
|
||||
@@ -1416,10 +1431,6 @@ CREATE TABLE workflow_histories (
|
||||
CONSTRAINT fk_wf_hist_inst FOREIGN KEY (instance_id) REFERENCES workflow_instances (id) ON DELETE CASCADE
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ตารางประวัติการเปลี่ยนสถานะ Workflow';
|
||||
|
||||
CREATE INDEX idx_wf_hist_instance ON workflow_histories (instance_id);
|
||||
|
||||
CREATE INDEX idx_wf_hist_user ON workflow_histories (action_by_user_id);
|
||||
|
||||
-- =====================================================
|
||||
-- 11. 🤖 AI Gateway (ตาราง AI Integration - ADR-018, ADR-020)
|
||||
-- =====================================================
|
||||
@@ -1507,6 +1518,43 @@ CREATE TABLE ai_audit_logs (
|
||||
SET NULL
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ADR-023 AI development feedback log';
|
||||
|
||||
-- =====================================================
|
||||
-- 13. 🤖 Intent Classification (ADR-024)
|
||||
-- =====================================================
|
||||
-- Intent Definitions Table
|
||||
CREATE TABLE IF NOT EXISTS ai_intent_definitions (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY COMMENT 'Internal PK (ห้าม expose ใน API)',
|
||||
public_id UUID NOT NULL DEFAULT UUID() COMMENT 'UUID Public Identifier (ADR-019)',
|
||||
intent_code VARCHAR(50) NOT NULL COMMENT 'รหัส Intent เช่น RAG_QUERY, GET_RFA',
|
||||
description_th VARCHAR(255) NOT NULL COMMENT 'คำอธิบายภาษาไทย',
|
||||
description_en VARCHAR(255) NOT NULL COMMENT 'คำอธิบายภาษาอังกฤษ',
|
||||
category ENUM('read', 'suggest', 'utility') NOT NULL COMMENT 'ประเภท Intent',
|
||||
is_active BOOLEAN NOT NULL DEFAULT TRUE COMMENT 'สถานะการใช้งาน',
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่สร้าง',
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'วันที่แก้ไขล่าสุด',
|
||||
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 COMMENT = 'ตาราง Intent Definitions สำหรับ Hybrid Intent Classifier (ADR-024)';
|
||||
|
||||
-- Intent Patterns Table
|
||||
CREATE TABLE IF NOT EXISTS ai_intent_patterns (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY COMMENT 'Internal PK (ห้าม expose ใน API)',
|
||||
public_id UUID NOT NULL DEFAULT UUID() COMMENT 'UUID Public Identifier (ADR-019)',
|
||||
intent_code VARCHAR(50) NOT NULL COMMENT 'รหัส Intent (FK to ai_intent_definitions)',
|
||||
language ENUM('th', 'en', 'any') NOT NULL DEFAULT 'any' COMMENT 'ภาษาของ pattern',
|
||||
pattern_type ENUM('keyword', 'regex') NOT NULL DEFAULT 'keyword' COMMENT 'ประเภท pattern',
|
||||
pattern_value VARCHAR(255) NOT NULL COMMENT 'ค่า pattern (keyword หรือ regex)',
|
||||
priority INT NOT NULL DEFAULT 100 COMMENT 'ลำดับความสำคัญ (ยิ่งน้อยยิ่งสำคัญ)',
|
||||
is_active BOOLEAN NOT NULL DEFAULT TRUE COMMENT 'สถานะการใช้งาน',
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่สร้าง',
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'วันที่แก้ไขล่าสุด',
|
||||
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 COMMENT = 'ตาราง Intent Patterns สำหรับ Hybrid Intent Classifier (ADR-024)';
|
||||
|
||||
-- =============================================================================
|
||||
-- 20. RFA Approval System (v1.9.0)
|
||||
-- =============================================================================
|
||||
|
||||
@@ -93,6 +93,23 @@ CREATE INDEX idx_backup_logs_started_at ON backup_logs (started_at);
|
||||
|
||||
CREATE INDEX idx_backup_logs_completed_at ON backup_logs (completed_at);
|
||||
|
||||
-- Indexes for workflow_definitions (ADR-001 Unified Workflow Engine)
|
||||
CREATE INDEX idx_workflow_active ON workflow_definitions (workflow_code, is_active, version);
|
||||
|
||||
-- Indexes for workflow_instances (ADR-001 Unified Workflow Engine)
|
||||
CREATE INDEX idx_wf_inst_entity ON workflow_instances (entity_type, entity_id);
|
||||
|
||||
CREATE INDEX idx_wf_inst_contract ON workflow_instances (contract_id, entity_type, STATUS);
|
||||
|
||||
CREATE INDEX idx_wf_inst_state ON workflow_instances (current_state);
|
||||
|
||||
CREATE INDEX idx_wf_inst_version ON workflow_instances (id, version_no);
|
||||
|
||||
-- Indexes for workflow_histories (ADR-001 Unified Workflow Engine)
|
||||
CREATE INDEX idx_wf_hist_instance ON workflow_histories (instance_id);
|
||||
|
||||
CREATE INDEX idx_wf_hist_user ON workflow_histories (action_by_user_id);
|
||||
|
||||
-- =====================================================
|
||||
-- Additional Composite Indexes for Performance
|
||||
-- =====================================================
|
||||
|
||||
@@ -2197,3 +2197,530 @@ VALUES (
|
||||
'2025-12-16 09:34:10',
|
||||
'2025-12-16 09:34:10'
|
||||
);
|
||||
|
||||
-- =====================================================
|
||||
-- Intent Classification Seed (ADR-024)
|
||||
-- =====================================================
|
||||
-- Intent Definitions (v1) — 12 รายการ
|
||||
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'
|
||||
);
|
||||
|
||||
-- Intent Patterns Seed (ADR-024)
|
||||
-- =====================================================
|
||||
-- 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 อะไรเลย
|
||||
-- =====================================================
|
||||
-- Workflow Definitions Seed (ADR-001)
|
||||
-- =====================================================
|
||||
-- CIRCULATION_FLOW_V1 Workflow Definition
|
||||
INSERT IGNORE 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()
|
||||
);
|
||||
|
||||
@@ -1155,10 +1155,24 @@ VALUES (
|
||||
'ลบ AiAuditLog เดี่ยวโดย publicId (Superadmin Only)',
|
||||
'ai',
|
||||
1
|
||||
),
|
||||
(
|
||||
187,
|
||||
'rag.query',
|
||||
'ใช้งาน RAG Q&A เพื่อค้นหาคำตอบจากเอกสาร',
|
||||
'rag',
|
||||
1
|
||||
),
|
||||
(
|
||||
188,
|
||||
'rag.manage',
|
||||
'จัดการ RAG ingestion, re-index, ลบ vectors',
|
||||
'rag',
|
||||
1
|
||||
);
|
||||
|
||||
-- Role 1: Superadmin — ได้รับทุก permission โดยอัตโนมัติผ่าน SELECT-all pattern (บรรทัด 825-829)
|
||||
-- Role 2: Org Admin — ai.suggest, ai.rag_query, ai.migration_manage, ai.read_analytics
|
||||
-- Role 2: Org Admin — ai.suggest, ai.rag_query, ai.migration_manage, ai.read_analytics, rag.query
|
||||
INSERT IGNORE INTO role_permissions (role_id, permission_id)
|
||||
VALUES (2, 181),
|
||||
-- ai.suggest
|
||||
@@ -1166,10 +1180,12 @@ VALUES (2, 181),
|
||||
-- ai.rag_query
|
||||
(2, 183),
|
||||
-- ai.migration_manage
|
||||
(2, 185);
|
||||
(2, 185),
|
||||
-- ai.read_analytics
|
||||
(2, 187);
|
||||
|
||||
-- ai.read_analytics
|
||||
-- Role 3: Document Control — ai.suggest, ai.rag_query, ai.migration_manage, ai.read_analytics
|
||||
-- rag.query
|
||||
-- Role 3: Document Control — ai.suggest, ai.rag_query, ai.migration_manage, ai.read_analytics, rag.query
|
||||
INSERT IGNORE INTO role_permissions (role_id, permission_id)
|
||||
VALUES (3, 181),
|
||||
-- ai.suggest
|
||||
@@ -1177,8 +1193,22 @@ VALUES (3, 181),
|
||||
-- ai.rag_query
|
||||
(3, 183),
|
||||
-- ai.migration_manage
|
||||
(3, 185);
|
||||
(3, 185),
|
||||
-- ai.read_analytics
|
||||
(3, 187);
|
||||
|
||||
-- ai.read_analytics
|
||||
-- rag.query
|
||||
-- rag.manage (188) — Superadmin เท่านั้น, ไม่ grant ให้ Role อื่น
|
||||
-- ai.migration_manage
|
||||
-- ai.audit_log_delete (184) — Superadmin เท่านั้น, ไม่ grant ให้ Role อื่น
|
||||
-- ==========================================================
|
||||
-- 19. RBAC Bulk Permission (Delta 02)
|
||||
-- ==========================================================
|
||||
-- Grant user.manage_assignments to ADMIN, Org Admin, DC, Document Control roles
|
||||
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,7 +1,7 @@
|
||||
# Architecture Decision Records (ADRs)
|
||||
|
||||
**Version:** 1.9.1
|
||||
**Last Updated:** 2026-05-14
|
||||
**Version:** 1.9.5
|
||||
**Last Updated:** 2026-05-18
|
||||
**Project:** LCBP3-DMS (Laem Chabang Port Phase 3 - Document Management System)
|
||||
|
||||
---
|
||||
@@ -95,6 +95,7 @@ Architecture Decision Records (ADRs) เป็นเอกสารที่บ
|
||||
| [ADR-020](./ADR-020-ai-intelligence-integration.md) | AI Intelligence Integration Architecture | ❌ Superseded | 2026-04-03 | ถูกแทนที่โดย ADR-023: Unified AI Architecture |
|
||||
| [ADR-022](./ADR-022-retrieval-augmented-generation.md) | Retrieval-Augmented Generation (RAG) | ❌ Superseded | 2026-04-20 | ถูกแทนที่โดย ADR-023: Unified AI Architecture |
|
||||
| [ADR-023](./ADR-023-unified-ai-architecture.md) | Unified AI Architecture | ✅ Accepted | 2026-05-14 | สถาปัตยกรรม AI หลักแบบรวมศูนย์ (Boundary, RAG, Workflows และ Isolation) |
|
||||
| [ADR-023A](./ADR-023A-unified-ai-architecture.md) | AI Model Revision | ✅ Accepted | 2026-05-15 | 2-Model Stack (gemma4:e4b Q8_0 + nomic-embed-text), BullMQ 2-Queue, RAG embed scope, OCR auto-detect |
|
||||
|
||||
---
|
||||
|
||||
@@ -146,16 +147,12 @@ Architecture Decision Records (ADRs) เป็นเอกสารที่บ
|
||||
|
||||
### 9. AI & Data Integration
|
||||
|
||||
- **ADR-017:** Ollama Data Migration - (Superseded by ADR-023)
|
||||
- **ADR-017B:** Smart Document Digitization - (Superseded by ADR-023)
|
||||
- **ADR-018:** AI Boundary Policy - (Superseded by ADR-023)
|
||||
- **ADR-020:** AI Intelligence Integration - (Superseded by ADR-023)
|
||||
- **ADR-022:** Retrieval-Augmented Generation - (Superseded by ADR-023)
|
||||
- **ADR-023:** Unified AI Architecture - สถาปัตยกรรม AI หลักของระบบ ครอบคลุม Boundary, Workflows, RAG และ Hardware Isolation
|
||||
- **ADR-023A:** AI Model Revision - 2-Model Stack (gemma4:e4b Q8_0 + nomic-embed-text), BullMQ 2-Queue, OCR auto-detect
|
||||
|
||||
---
|
||||
|
||||
## 📖 How to Read ADRs
|
||||
## How to Read ADRs
|
||||
|
||||
### ADR Structure
|
||||
|
||||
@@ -379,8 +376,8 @@ graph TB
|
||||
|
||||
---
|
||||
|
||||
**Version:** 1.9.1 (Consolidated AI ADRs into ADR-023)
|
||||
**Last Review:** 2026-05-14
|
||||
**Version:** 1.9.5 (Added ADR-023A AI Model Revision)
|
||||
**Last Review:** 2026-05-18
|
||||
**Next Review:** 2026-10-10
|
||||
|
||||
---
|
||||
|
||||
@@ -16,7 +16,12 @@
|
||||
## ตัวอย่างงานที่อยู่ในโฟลเดอร์นี้
|
||||
|
||||
- `201-transmittals-circulation` - Transmittals + Circulation Integration
|
||||
- `202-adr-021-integrated-workflow-conte` - ADR-021 Integrated Workflow Context
|
||||
- `203-unified-workflow-engine` - Unified Workflow Engine
|
||||
- `204-rfa-approval-refactor` - RFA Approval Refactor
|
||||
- `224-intent-classification` - AI Intent Classification
|
||||
- `225-ai-tool-layer-architecture` - AI Tool Layer Architecture
|
||||
- `226-document-chat-ui-pattern` - Document Chat UI Pattern
|
||||
|
||||
## การตั้งชื่อโฟลเดอร์
|
||||
|
||||
|
||||
+6
-4
@@ -1,7 +1,7 @@
|
||||
# 📚 LCBP3-DMS Specifications Directory
|
||||
|
||||
**Version:** 1.9.0 (Global Standards & Agent Sync)
|
||||
**Last Updated:** 2026-05-13
|
||||
**Version:** 1.9.2 (AI Model Revision & Hybrid Staging)
|
||||
**Last Updated:** 2026-05-18
|
||||
**Project:** LCBP3-DMS (Laem Chabang Port Phase 3 - Document Management System)
|
||||
**Status:** ✅ Production Ready — 10/10 Documentation Gaps Closed • Hybrid Specs Structure Applied
|
||||
|
||||
@@ -80,10 +80,12 @@ specs/
|
||||
│ ├── 05-07-hybrid-uuid-implementation-plan.md # ADR-019 Implementation Guide
|
||||
│ └── README.md # ภาพรวมเป้าหมายงาน Engineering
|
||||
│
|
||||
├── 06-Decision-Records/ # Architecture Decision Records (17 + Patch + ADR-019)
|
||||
├── 06-Decision-Records/ # Architecture Decision Records (23 ADRs)
|
||||
│ ├── ADR-001 to ADR-017... # ไฟล์อธิบายสถาปัตยกรรม (ADR)
|
||||
│ ├── ADR-018-ai-boundary.md # ★ Patch 1.8.1: AI/Ollama Isolation Policy
|
||||
│ ├── ADR-018-ai-boundary.md # ★ Patch 1.8.1: AI/Ollama Isolation Policy (Superseded by ADR-023)
|
||||
│ ├── ADR-019-hybrid-identifier-strategy.md # ★ Hybrid ID: INT PK + UUIDv7 Public API
|
||||
│ ├── ADR-023-unified-ai-architecture.md # ★ Unified AI Architecture (Consolidates ADR-017/017B/018/020/022)
|
||||
│ ├── ADR-023A-unified-ai-architecture.md # ★ AI Model Revision: 2-Model Stack + BullMQ 2-Queue
|
||||
│ └── README.md # รายชื่อ ADR ทั้งหมดพร้อมสถานะและวันที่
|
||||
│
|
||||
├── 100-Infrastructures/ # Feature Work: Infrastructure (Deployment, Monitoring, Docker Compose, Network)
|
||||
|
||||
Reference in New Issue
Block a user