260322:1648 Correct Coresspondence / Doing RFA / Correct CI
CI Pipeline / build (push) Failing after 12m41s
Build and Deploy / deploy (push) Failing after 2m44s

This commit is contained in:
admin
2026-03-22 16:48:12 +07:00
parent e5deedb42e
commit 11984bfa29
683 changed files with 105251 additions and 29068 deletions
@@ -35,25 +35,28 @@
### Phase 1: การเตรียม Infrastructure และ Storage (สัปดาห์ที่ 1)
**File Migration:**
- ย้ายไฟล์ PDF ทั้งหมดจากแหล่งเก็บไปยัง Folder ชั่วคราวบน NAS (QNAP)
- Target Path: `/share/np-dms/staging_ai/`
**Mount Folder:**
- Bind Mount `/share/np-dms/staging_ai/` เข้ากับ n8n Container แบบ **read-only**
- สร้าง `/share/np-dms/n8n/migration_logs/` Volume แยกสำหรับเขียน Log แบบ **read-write**
**Ollama Config:**
- ติดตั้ง Ollama บน Desktop (Desk-5439, RTX 2060 SUPER 8GB)
- No DB credentials, Internal network only
#### 🔍 เปรียบเทียบผลลัพธ์ที่คาดหวัง
| งาน | Typhoon2-4B | Qwen2.5-7B | OpenThaiGPT-7B |
|-----|-------------|------------|----------------|
| ความเร็ว (ток/วินาที) | ~35-45 | ~8-12 | ~10-15 |
| ความเข้าใจบริบทไทย | ดีมาก | ดี | ดีมาก |
| การสร้างแท็กแม่นยำ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| ความเสถียรบน 8GB | ✅ สูง | ⚠️ ปานกลาง | ⚠️ ปานกลาง |
| งาน | Typhoon2-4B | Qwen2.5-7B | OpenThaiGPT-7B |
| --------------------- | ----------- | ---------- | -------------- |
| ความเร็ว (ток/วินาที) | ~35-45 | ~8-12 | ~10-15 |
| ความเข้าใจบริบทไทย | ดีมาก | ดี | ดีมาก |
| การสร้างแท็กแม่นยำ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| ความเสถียรบน 8GB | ✅ สูง | ⚠️ ปานกลาง | ⚠️ ปานกลาง |
```bash
# แนะนำ: llama3.2:3b (เร็ว, VRAM ~3GB, เหมาะ Classification) หรือ ollama run llama3.2:3b
@@ -79,15 +82,18 @@ watch -n 1 nvidia-smi
# Fallback: mistral:7b-instruct-q4_K_M (แม่นกว่า, VRAM ~5GB)
# ollama pull mistral:7b-instruct-q4_K_M
```
ใช้ ทางเลือกที่ 1
**ทดสอบ Ollama:**
```bash
curl http://192.168.20.100:11434/api/generate \
-d '{"model":"llama3.2:3b","prompt":"reply: ok","stream":false}'
```
**Concurrency Configuration:**
- Sequential: Batch Size = 1, Delay ≥ 2 วินาที, ปิด Parallel Execution
- เพิ่ม Health Check Node ก่อนเริ่ม Batch เพื่อป้องกัน Workflow ค้างหาก Desktop Sleep หรือ Overheat
@@ -96,6 +102,7 @@ curl http://192.168.20.100:11434/api/generate \
### Phase 2: การเตรียม Target Database และ API (สัปดาห์ที่ 1)
**SQL Indexing:**
```sql
ALTER TABLE correspondences ADD INDEX idx_doc_number (document_number);
ALTER TABLE correspondences ADD INDEX idx_deleted_at (deleted_at);
@@ -103,6 +110,7 @@ ALTER TABLE correspondences ADD INDEX idx_created_by (created_by);
```
**Checkpoint Table:**
```sql
CREATE TABLE IF NOT EXISTS migration_progress (
batch_id VARCHAR(50) PRIMARY KEY,
@@ -113,6 +121,7 @@ CREATE TABLE IF NOT EXISTS migration_progress (
```
**Tags Table (สำหรับ AI Tag Extraction):**
```sql
-- ตาราง Master เก็บ Tags (Global หรือ Project-specific)
CREATE TABLE tags (
@@ -143,6 +152,7 @@ CREATE TABLE correspondence_tags (
```
**Idempotency Table :**
```sql
CREATE TABLE IF NOT EXISTS import_transactions (
id INT AUTO_INCREMENT PRIMARY KEY,
@@ -158,6 +168,7 @@ CREATE TABLE IF NOT EXISTS import_transactions (
> **Idempotency Logic:** ถ้า `idempotency_key` ซ้ำ → Backend คืน HTTP 200 ทันที (ไม่สร้าง Revision ซ้ำ) ถ้าไม่ซ้ำ → ประมวลผลปกติ
**API Authentication — Migration Token:**
```sql
INSERT INTO users (username, email, role, is_active)
VALUES ('migration_bot', 'migration@system.internal', 'SYSTEM_ADMIN', true);
@@ -165,14 +176,14 @@ VALUES ('migration_bot', 'migration@system.internal', 'SYSTEM_ADMIN', true);
**Scope ของ Migration Token (Patch — คำนิยามชัดเจน):**
| สิทธิ์ | ปกติ | Migration Token | หมายเหตุ |
| ------------------------------------- | --- | --------------- | --------------------------------- |
| Bypass File Virus Scan | ❌ | ✅ | ไฟล์ผ่าน Scan มาแล้วก่อน Import |
| Bypass Duplicate **Validation Error** | ❌ | ✅ | **Revision Logic ยัง enforce ปกติ** |
| Bypass Created-by User validation | ❌ | ✅ | |
| Overwrite existing revision | ❌ | ❌ | **ห้ามโดยเด็ดขาด** |
| Delete previous revision | ❌ | ❌ | **ห้ามโดยเด็ดขาด** |
| ลบ / แก้ไข Record อื่น | ❌ | ❌ | **ห้ามโดยเด็ดขาด** |
| สิทธิ์ | ปกติ | Migration Token | หมายเหตุ |
| ------------------------------------- | ---- | --------------- | ----------------------------------- |
| Bypass File Virus Scan | ❌ | ✅ | ไฟล์ผ่าน Scan มาแล้วก่อน Import |
| Bypass Duplicate **Validation Error** | ❌ | ✅ | **Revision Logic ยัง enforce ปกติ** |
| Bypass Created-by User validation | ❌ | ✅ | |
| Overwrite existing revision | ❌ | ❌ | **ห้ามโดยเด็ดขาด** |
| Delete previous revision | ❌ | ❌ | **ห้ามโดยเด็ดขาด** |
| ลบ / แก้ไข Record อื่น | ❌ | ❌ | **ห้ามโดยเด็ดขาด** |
> ⚠️ **Patch Clarification:** "Bypass Duplicate Number Check" ถูกแทนด้วย "Bypass Duplicate **Validation Error**" — Revision increment logic ยังทำงานตามปกติทุกกรณี
@@ -194,21 +205,25 @@ VALUES ('migration_bot', 'migration@system.internal', 'SYSTEM_ADMIN', true);
4. File Mount Check → `staging_ai` มีไฟล์, `migration_logs` เขียนได้
**Fetch System Categories (Patch — ห้าม hardcode):**
```http
GET /api/meta/categories
Authorization: Bearer <MIGRATION_TOKEN>
```
Response:
```json
{ "categories": ["Correspondence","RFA","Drawing","Transmittal","Report","Other"] }
{ "categories": ["Correspondence", "RFA", "Drawing", "Transmittal", "Report", "Other"] }
```
n8n ต้องเก็บ categories นี้ไว้ใน Workflow Variable (`system_categories`) และ inject เข้า AI Prompt ทุก Request
#### Node 1: Data Reader & Checkpoint
#### Node 1: Data Reader & Checkpoint
- อ่าน Checkpoint จาก **MariaDB Node แยก**
- อ่าน Checkpoint จาก **MariaDB Node แยก**
- Batch ทีละ **50100 แถว** ตาม `$env.MIGRATION_BATCH_SIZE` (ควรจำกัด Batch Size ป้องกัน DB Connection Overload)
- ติด `original_index` ทุก Item และ Normalize Encoding (UTF-8 NFC) สำหรับ ชื่อไฟล์ และ เลขเอกสารเก่า
@@ -221,7 +236,7 @@ n8n ต้องเก็บ categories นี้ไว้ใน Workflow Variab
3. แปลง `receiver_code` -> `receiver_organization_id`
4. หา Tags ที่มีอยู่ในโปรเจ็กต์: `SELECT * FROM tags WHERE project_id = {{project_id}}`
- **Output:** n8n เก็บ `project_id`, `organization_ids` และ `existing_tags_json` ไว้ในแต่ละ item
- *ถ้าหารหัสโปรเจ็กต์ไม่เจอ ให้ส่งเข้า Error Log ไม่ทำต่อ*
- _ถ้าหารหัสโปรเจ็กต์ไม่เจอ ให้ส่งเข้า Error Log ไม่ทำต่อ_
#### Node 3: File Processor (Extract PDF Text & Temp Upload)
@@ -235,6 +250,7 @@ n8n ต้องเก็บ categories นี้ไว้ใน Workflow Variab
#### Node 4: AI Analysis (Sequential เท่านั้น)
**System Prompt:**
```text
You are a Document Controller for a large construction project.
Your task is to validate document metadata, summarize content, and suggest relevant tags.
@@ -242,6 +258,7 @@ You MUST respond ONLY with valid JSON. No explanation, no markdown.
```
**User Prompt:**
```text
Validate and summarize this document. Respond in JSON.
Document Number: {{$json.document_number}}
@@ -273,12 +290,14 @@ Respond ONLY with this exact JSON structure:
ข้อมูลทั้งหมดที่ผ่าน n8n และ AI Model **จะต้องไม่ถูกอัพเดทเข้าตารางหลักอัตโนมัติ** แต่จะถูกบังคับนำเข้าตาราง Staging `migration_review_queue` แทน เพื่อรอมนุษย์จัดการผ่าน Frontend UI
**Status Routing Policy:**
- `confidence >= 0.85` และ `is_valid = true` -> Status **`PENDING`** (พร้อมรับ Batch Import)
- `confidence >= 0.60` และ `< 0.85` -> Status **`PENDING`** (ติด Flag ให้ระวัง)
- `confidence < 0.60` หรือ `is_valid = false` -> Status **`REJECTED`**
- Parse Error / AI ไม่ตอบ -> **Error Log** (Node ถัดไป)
**Insert into staging:**
```sql
INSERT INTO migration_review_queue (
document_number, title, project_id, sender_organization_id, receiver_organization_id,
@@ -290,7 +309,7 @@ ON DUPLICATE KEY UPDATE status = VALUES(status), ai_summary = VALUES(ai_summary)
#### Node 6: Error Log & Reject Log
- Parse Error → เขียนลงไฟล์ `/share/np-dms/n8n/migration_logs/error_log.csv`
- Parse Error → เขียนลงไฟล์ `/share/np-dms/n8n/migration_logs/error_log.csv`
- ทุก 10-50 ราบการอัพเดท MariaDB `migration_progress` เพื่อเป็น Checkpoint.
---
@@ -308,10 +327,12 @@ ON DUPLICATE KEY UPDATE status = VALUES(status), ai_summary = VALUES(ai_summary)
### Phase 4: แผนการทดสอบ (Testing & QA)
**Dry Run Policy (Mandatory):**
- All migrations MUST run with `--dry-run`
- No DB commit until validation approved
**Dry Run Validation (2050 แถว):**
- JSON Parse Success Rate > 95%
- Category ที่ AI ตอบตรงกับ System Enum ทุกรายการ
- รัน Batch เดิมซ้ำ 2 รอบ → ต้องไม่สร้าง Duplicate หรือ Revision ซ้ำ (Idempotency Test)
@@ -319,6 +340,7 @@ ON DUPLICATE KEY UPDATE status = VALUES(status), ai_summary = VALUES(ai_summary)
- Revision Drift ถูก route ไป Review Queue
**Integrity Check:**
```sql
-- ตรวจยอด
SELECT COUNT(*) FROM correspondences WHERE created_by = 'SYSTEM_IMPORT';
@@ -351,11 +373,13 @@ WHERE created_by = 'SYSTEM_IMPORT' AND action = 'IMPORT';
## 4. Rollback Plan
**Step 1:** หยุด n8n และ Disable Token
```sql
UPDATE users SET is_active = false WHERE username = 'migration_bot';
```
**Step 2:** ลบ Records (Transaction)
```sql
START TRANSACTION;
DELETE FROM correspondence_files
@@ -369,6 +393,7 @@ COMMIT;
**Step 3:** ย้ายไฟล์กลับ `/share/np-dms/staging_ai/` ผ่าน Script แยก
**Step 4:** Reset State
```sql
UPDATE migration_progress
SET status = 'FAILED', last_processed_index = 0
@@ -383,19 +408,19 @@ WHERE batch_id = 'migration_20260226';
## 5. แผนรับมือความเสี่ยง (Risk Management)
| ลำดับที่ | ความเสี่ยง | การจัดการ (Mitigation) |
| ---- | -------------------------- | -------------------------------------------------- |
| 1 | AI Node หรือ GPU ค้าง | Timeout 30 วินาที, Retry 3 รอบ, Delay 60 วินาที |
| 2 | Ollama ตอบไม่ใช่ JSON | JSON Pre-processor + ส่ง Human Review Queue |
| 3 | Category ไม่ตรง System Enum | Fetch `/api/meta/categories` ก่อน Batch ทุกครั้ง |
| 4 | Idempotency ซ้ำ | `import_transactions` table + Backend คืน HTTP 200 |
| 5 | Revision Drift | ตรวจ Excel revision column → Route ไป Review Queue |
| 6 | Storage bypass | ห้าม move file โดยตรง — ผ่าน Backend API เท่านั้น |
| 7 | GPU VRAM Overflow | ใช้เฉพาะ Quantized Model (q4_K_M) |
| 8 | ดิสก์ NAS เต็ม | ปิด "Save Successful Executions" ใน n8n |
| 9 | Migration Token ถูกขโมย | Token 7 วัน, IP Whitelist `<NAS_IP>` เท่านั้น |
| 11 | AI Tag Extraction ผิดพลาด | Tag confidence < 0.6 → ส่งไป Review Queue / บันทึกใน metadata |
| 12 | Tag ซ้ำ/คล้ายกัน | Normalization ก่อนบันทึก (lowercase, trim, deduplicate) |
| ลำดับที่ | ความเสี่ยง | การจัดการ (Mitigation) |
| -------- | --------------------------- | ------------------------------------------------------------- |
| 1 | AI Node หรือ GPU ค้าง | Timeout 30 วินาที, Retry 3 รอบ, Delay 60 วินาที |
| 2 | Ollama ตอบไม่ใช่ JSON | JSON Pre-processor + ส่ง Human Review Queue |
| 3 | Category ไม่ตรง System Enum | Fetch `/api/meta/categories` ก่อน Batch ทุกครั้ง |
| 4 | Idempotency ซ้ำ | `import_transactions` table + Backend คืน HTTP 200 |
| 5 | Revision Drift | ตรวจ Excel revision column → Route ไป Review Queue |
| 6 | Storage bypass | ห้าม move file โดยตรง — ผ่าน Backend API เท่านั้น |
| 7 | GPU VRAM Overflow | ใช้เฉพาะ Quantized Model (q4_K_M) |
| 8 | ดิสก์ NAS เต็ม | ปิด "Save Successful Executions" ใน n8n |
| 9 | Migration Token ถูกขโมย | Token 7 วัน, IP Whitelist `<NAS_IP>` เท่านั้น |
| 11 | AI Tag Extraction ผิดพลาด | Tag confidence < 0.6 → ส่งไป Review Queue / บันทึกใน metadata |
| 12 | Tag ซ้ำ/คล้ายกัน | Normalization ก่อนบันทึก (lowercase, trim, deduplicate) |
---