Files
lcbp3/specs/06-Decision-Records/ADR-017-ollama-data-migration.md
admin 276d06e950
All checks were successful
Build and Deploy / deploy (push) Successful in 2m49s
260228:1412 20260228: setup n8n
2026-02-28 14:12:48 +07:00

16 KiB
Raw Blame History

ADR-017: Ollama Data Migration Architecture

Status: Accepted Date: 2026-02-26 Version: 1.8.0 Decision Makers: Development Team, DevOps Engineer Related Documents:

Note: ADR-017 is clarified and hardened by ADR-018 regarding AI physical isolation. Category Enum system-driven, Idempotency Contract, Duplicate Handling Clarification, Storage Enforcement, Audit Log Enhancement, Review Queue Integration, Revision Drift Protection, Execution Time, Encoding Normalization, Security Hardening, Orchestrator on QNAP, AI Physical Isolation (Desktop Desk-5439).


Context and Problem Statement

โครงการ LCBP3-DMS มีความจำเป็นต้องนำเข้าเอกสาร PDF เก่าจำนวนกว่า 20,000 ฉบับ พร้อม Metadata ใน Excel เข้าสู่ระบบใหม่

ความท้าทายหลักคือ Data Integrity และความถูกต้องของ Metadata เนื่องจากข้อมูลเก่ามีโอกาสเกิด Human Error เราจึงต้องการ AI ช่วย Validate ก่อนนำเข้า

การส่งข้อมูลขึ้น Cloud AI Provider มีปัญหา 2 ประการ:

  1. Data Privacy: เอกสารก่อสร้างท่าเรือเป็นความลับ ห้ามออกนอกเครือข่าย
  2. Cost: ~$0.010.03 ต่อ Record = อาจสูงถึง $600 สำหรับ 20,000 records

Decision Drivers

  • Security & Privacy: ประมวลผลภายในเครือข่ายองค์กร (On-Premise) เท่านั้น
  • Cost Effectiveness: ไม่เสียค่า Pay-per-use
  • Performance: ประมวลผลได้ในระยะเวลาที่จำกัด (~34 คืน)
  • Maintainability: แยก Migration ออกจาก Core Application
  • Recoverability: Rollback ได้สมบูรณ์
  • Resilience: รองรับ Checkpoint/Resume และ Hardware Failure
  • Data Integrity: Idempotency, Revision Drift Protection, Enum Enforcement
  • Storage Governance: ทุก File Move ต้องผ่าน StorageService

Considered Options

Option 1: NestJS Custom Script + Public AI API

Pros: ไม่ต้องจัดหา Hardware เพิ่ม, AI ฉลาดสูง

Cons:

  • ผิดนโยบาย Data Privacy
  • ค่าใช้จ่ายสูง (~$600)
  • Code สกปรก ปะปนกับ Source Code หลัก

Option 2: Pure Scripting (No AI)

Pros: เร็ว ไม่มีค่าใช้จ่าย

Cons:

  • ความแม่นยำต่ำ ตรวจได้แค่ Format
  • ต้องใช้ Manual Review จำนวนมาก

Option 3: Local AI Model (Ollama) + n8n (Selected)

Pros:

  • Privacy Guaranteed
  • Zero Cost
  • Clean Architecture
  • Visual & Debuggable
  • Resilient (Checkpoint/Resume)
  • Structured Output ด้วย JSON Schema

Cons:

  • ต้องเปิด Desktop ทิ้งไว้ดูแล GPU Temperature
  • Model เล็กอาจแม่นน้อยกว่า Cloud AI → ต้องมี Human Review Queue

Decision Outcome

Chosen Option: Option 3 — Local AI Model (Ollama) + n8n

Rationale: ประยุกต์ใช้ Hardware ที่มีอยู่ โดยไม่ขัดหลัก Privacy และ Security ของโครงการ n8n ช่วยลด Risk ที่จะกระทบ Core Backend และรองรับ Checkpoint/Resume ได้ดีกว่าการเขียน Script เอง


Implementation Summary

Component รายละเอียด
Migration Orchestrator n8n (Docker บน QNAP NAS)
AI Model Primary Ollama llama3.2:3b
AI Model Fallback Ollama mistral:7b-instruct-q4_K_M
Hardware QNAP NAS (Orchestrator) + Desktop Desk-5439 (AI Processing, RTX 2060 SUPER 8GB)
Data Ingestion RESTful API + Migration Token (7 วัน) + Idempotency-Key Header
Concurrency Sequential — 1 Request/ครั้ง, Delay 2 วินาที
Checkpoint MariaDB migration_progress
Fallback Auto-switch Model เมื่อ Error ≥ Threshold
Storage Backend StorageService เท่านั้น — ห้าม move file โดยตรง
Expected Runtime ~16.6 ชั่วโมง (~34 คืน) สำหรับ 20,000 records

AI Output Contract (JSON Schema)

{
  "is_valid": true,
  "confidence": 0.92,
  "suggested_category": "Correspondence",
  "detected_issues": [],
  "suggested_title": null
}
Field Type คำอธิบาย
is_valid boolean เอกสารผ่านการตรวจสอบหรือไม่
confidence float (0.01.0) ความมั่นใจของ AI
suggested_category string (enum จาก Backend) หมวดหมู่ที่ AI แนะนำ
detected_issues string[] รายการปัญหา (array ว่างถ้าไม่มี)
suggested_title string | null Title ที่แก้ไขแล้ว หรือ null

⚠️ Patch: suggested_category ต้องตรงกับ System Enum จาก GET /api/meta/categories เท่านั้น — ห้าม hardcode Category List ใน Prompt


Confidence Threshold Policy

ระดับ Confidence การดำเนินการ
>= 0.85 และ is_valid = true Auto Ingest เข้าระบบ
0.600.84 ส่งไป Human Review Queue
< 0.60 หรือ is_valid = false ส่งไป Reject Log รอ Manual Fix
AI Parse Error ส่งไป Error Log + Trigger Fallback Logic
Revision Drift ส่งไป Review Queue พร้อม reason

Idempotency Contract

HTTP Header ที่ต้องส่งทุก Request:

Idempotency-Key: <document_number>:<batch_id>

Backend Logic:

IF idempotency_key EXISTS in import_transactions → RETURN HTTP 200 (no action)
ELSE → Process normally → INSERT import_transactions → RETURN HTTP 201

ป้องกัน Revision ซ้ำกรณี n8n Retry หรือ Network Error


Duplicate Handling Clarification

Bypass Duplicate Validation Error

Hard Rules:

  • Migration Token ไม่สามารถ Overwrite Revision ที่มีอยู่
  • Migration Token ไม่สามารถ Delete Revision ก่อนหน้า
  • Migration Token trigger Revision increment logic ตามปกติเท่านั้น

Storage Governance (Patch)

ข้อห้าม:

❌ mv /data/dms/staging_ai/TCC-COR-0001.pdf /final/path/...

ข้อบังคับ:

✅ POST /api/correspondences/import
   body: { source_file_path: "/data/dms/staging_ai/TCC-COR-0001.pdf", ... }

Backend จะ:

  1. Generate UUID
  2. Enforce path strategy: /data/dms/uploads/YYYY/MM/{uuid}.pdf
  3. Move file atomically ผ่าน StorageService
  4. Create revision folder ถ้าจำเป็น

Review Queue Contract

  • migration_review_queue เป็น Temporary Table เท่านั้น — ไม่ใช่ Business Schema
  • ห้ามสร้าง Correspondence record จนกว่า Admin จะ Approve
  • Approval Flow: Review → Admin Approve → POST /api/correspondences/import

Revision Drift Protection

ถ้า Excel มี revision column:

IF excel_revision != current_db_revision + 1
→ ROUTE ไป Review Queue พร้อม reason: "Revision drift"

Execution Time Estimate

Parameter ค่า
Delay ระหว่าง Request 2 วินาที
Inference Time (avg) ~1 วินาที
เวลาต่อ Record ~3 วินาที
จำนวน Record 20,000
เวลารวม ~60,000 วินาที (~16.6 ชั่วโมง)
จำนวนคืนที่ต้องใช้ ~34 คืน (รัน 22:0006:00)

Encoding Normalization

ก่อน Ingestion ทุกครั้ง:

  • Excel data → Convert เป็น UTF-8
  • Filename → Normalize เป็น NFC UTF-8 ป้องกันปัญหาภาษาไทยเพี้ยนข้าม OS

Security Constraints

  1. Migration Token อายุ ≤ 7 วัน — Revoke ทันทีหลัง Migration
  2. Token Bypass ได้เฉพาะ: Virus Scan, Duplicate Validation Error, Created-by
  3. Token ไม่มีสิทธิ์ ลบหรือ Overwrite Record เดิม
  4. ทุก Request บันทึก Audit Log: action=IMPORT, source=MIGRATION, created_by=SYSTEM_IMPORT
  5. IP Whitelist: ใช้ได้เฉพาะจาก <NAS_IP>
  6. Nginx Rate Limit: limit_req zone=migration burst=5 nodelay
  7. Docker Hardening: mem_limit: 2g, log rotation max-size: 10m, max-file: 3

Rollback Strategy

  1. Disable Migration Token ใน DB ทันที
  2. ลบ Records ทั้งหมด created_by = 'SYSTEM_IMPORT' ผ่าน Transaction SQL (รวม import_transactions)
  3. ย้ายไฟล์ PDF กลับ migration_temp/
  4. Reset migration_progress และ migration_fallback_state
  5. วิเคราะห์ Root Cause ก่อนรันใหม่

รายละเอียดดูที่ 03-04-legacy-data-migration.md หัวข้อ 4


Architecture Validation Checklist (GO-LIVE GATE)

🟢 A. Infrastructure Validation

Check Expected
Ollama /api/tags reachable HTTP 200
Backend /health OK HTTP 200
MariaDB reachable SELECT 1
staging_ai mounted RO ls works
migration_logs mounted RW write test OK
GPU VRAM < 70% idle safe margin
Disk space > 30% free safe

🟢 B. Security Validation

Check Expected
Migration Token expiry ≤ 7 days Verified
Token IP Whitelist = NAS IP only Verified
Token cannot DELETE records Verified
Token cannot UPDATE non-import records Verified
Audit Log records source=MIGRATION Verified
Nginx rate limit configured Verified
Docker mem_limit = 2g Verified

🟢 C. Data Integrity Validation

Check Expected
Enum fetched from /api/meta/categories Not hardcoded
Idempotency-Key header enforced Verified
Duplicate revision test (run same batch twice) No overwrite
Revision drift test Sent to Review
Storage path matches Core Storage Spec v1.8.0 Verified
Encoding normalization NFC UTF-8 Verified

🟢 D. Workflow Validation (Dry Run 20 Records)

Check Expected
JSON parse success rate > 95%
Confidence distribution reasonable Mean 0.70.9
Checkpoint updates every 10 records Verified
Fallback model not prematurely triggered Verified
Reject log written to migration_logs/ Verified
Error log written to migration_logs/ Verified
Review queue inserts to DB Verified

🟢 E. Performance Validation

Check Expected
10 records processed < 1 minute Verified
GPU temp < 80°C Verified
No memory leak after 1 hour Verified
No duplicate revision created Verified

🟢 F. Rollback Test (Mandatory)

Check Expected
Disable token works is_active = false
Delete SYSTEM_IMPORT records works COUNT = 0
import_transactions cleared COUNT = 0
Checkpoint reset to 0 Verified
Fallback state reset Verified

GO / NO-GO Criteria

GO ถ้า:

  • A, B, C ทุก Check = PASS
  • Dry run error rate < 10%
  • JSON parse failure < 5%
  • Revision conflict < 3%

NO-GO ถ้า:

  • Enum mismatch (Category hardcoded)
  • Idempotency ไม่ได้ implement
  • Storage bypass (move file โดยตรง)
  • Audit log ไม่ครบ

Final Architectural Assessment

Area Status
ADR Compliance Fully aligned
Security Hardened (IP Whitelist, Rate Limit, Docker)
Data Integrity Controlled (Idempotency, Revision Drift, Enum)
Storage Governance Enforced (StorageService only)
Operational Safety Production Grade

สำหรับขั้นตอนปฏิบัติงานแบบละเอียด ดูที่ 03-04-legacy-data-migration.md และ 03-05-n8n-migration-setup-guide.md