690602:0957 ADR-033-233 #01
This commit is contained in:
+58
-142
@@ -1,6 +1,6 @@
|
||||
# LCBP3 / NAP-DMS Context
|
||||
|
||||
ระบบจัดการเอกสารงานก่อสร้าง (DMS) สำหรับโครงการ LCBP3 — เน้นการควบคุม Correspondence, RFA, Transmittal, Drawing พร้อมผู้ช่วย AI แบบ on-premises ที่ทำงานภายใต้ Workflow Engine กลางและขอบเขต AI ที่เข้มงวด (ADR-023A)
|
||||
ระบบจัดการเอกสารงานก่อสร้าง (DMS) สำหรับโครงการ LCBP3 — เน้นการควบคุม Correspondence, RFA, Transmittal, Drawing พร้อมผู้ช่วย AI แบบ on-premises ที่ทำงานภายใต้ Workflow Engine กลางและขอบเขต AI ที่เข้มงวด (ADR-023A/ADR-033)
|
||||
|
||||
> **Agent/ tooling context:** สำหรับ Hermes Agent, Telegram Bridge, และ DevOps tooling → ดู [`specs/06-Decision-Records/CONTEXT-ADR-031.md`](specs/06-Decision-Records/CONTEXT-ADR-031.md)
|
||||
> **Typhoon OCR context:** สำหรับ Typhoon OCR-3B และ typhoon2.1-gemma3-4b integration → ดู [`specs/06-Decision-Records/ADR-032-typhoon-ocr-integration.md`](specs/06-Decision-Records/ADR-032-typhoon-ocr-integration.md)
|
||||
@@ -62,8 +62,8 @@ _Avoid_: Tool, LLM tool, LangChain tool
|
||||
_Avoid_: Rule engine, NLU pipeline
|
||||
|
||||
**LLM Fallback**:
|
||||
ชั้นที่สองของ Intent Classifier — synchronous Ollama call (gemma4:e4b Q8*0) เมื่อ Pattern Layer ไม่ match, ใช้ semaphore max=3
|
||||
\_Avoid*: BullMQ-based classification, async intent routing
|
||||
ชั้นที่สอง of Intent Classifier — synchronous Ollama call (gemma4:e4b Q8_0) เมื่อ Pattern Layer ไม่ match, ใช้ semaphore max=3
|
||||
_Avoid_: BullMQ-based classification, async intent routing
|
||||
|
||||
### AI
|
||||
|
||||
@@ -88,20 +88,20 @@ Pipeline: embed query → `QdrantService.search(projectPublicId, vector)` →
|
||||
_Avoid_: Semantic search (overloaded), Vector search (incomplete)
|
||||
|
||||
**OCR Service**:
|
||||
Container สำเร็จรูป (opaque black box) เปิด HTTP API ให้ NestJS เรียก — ไม่มีโค้ด Python ใน repo, ทีมไม่ maintain runtime ภายใน
|
||||
_Avoid_: Python sidecar, OCR microservice (ที่เรา maintain เอง)
|
||||
Container สำเร็จรูป (FastAPI Sidecar บน Desk-5439) ทำหน้าที่ประมวลผล OCR และสื่อสารผ่าน `X-API-Key` ป้องกันความปลอดภัย (ADR-032/033)
|
||||
_Avoid_: OCR microservice (ที่ขาดการป้องกัน)
|
||||
|
||||
**Prompt Version**:
|
||||
Immutable snapshot ของ prompt template ใน `ai_prompts` table — ทุกครั้งที่ admin กด "บันทึก" จะสร้าง version ใหม่ (version*number เพิ่มทีละ 1) version เก่ายังอยู่ใน history ลบได้ยกเว้น active version (ADR-029)
|
||||
\_Avoid*: Prompt config, Prompt setting, Editable prompt
|
||||
Immutable snapshot ของ prompt template ใน `ai_prompts` table — ทุกครั้งที่ admin กด "บันทึก" จะสร้าง version ใหม่ (version_number เพิ่มทีละ 1) version เก่ายังอยู่ใน history ลบได้ยกเว้น active version (ADR-029)
|
||||
_Avoid_: Prompt config, Prompt setting, Editable prompt
|
||||
|
||||
**Active Prompt**:
|
||||
Prompt Version ที่มี `is_active = 1` ต่อ `prompt_type` — ใช้โดยทั้ง OCR Sandbox และ `processMigrateDocument` พร้อมกัน, cached ใน Redis TTL 60s; invalidated เมื่อ admin activate version อื่น (ADR-029)
|
||||
_Avoid_: Production prompt (ทั้ง sandbox และ migrate-document ใช้อันเดียวกัน)
|
||||
_Avoid_: Production prompt (sandbox และ migrate-document ใช้เดียวกัน)
|
||||
|
||||
**Prompt Template**:
|
||||
String ที่มี `{{ocr_text}}` placeholder บังคับ — backend validate ก่อน save; processor แทนที่ด้วย OCR output ก่อนส่งเข้า Ollama (ADR-029)
|
||||
_Avoid_: Prompt string, Prompt text (ambiguous — อาจหมายถึง resolved prompt ที่มี OCR text แล้ว)
|
||||
_Avoid_: Prompt string, Prompt text (ambiguous)
|
||||
|
||||
**Human-in-the-loop**:
|
||||
ทุก AI suggestion ต้องผ่านการ accept/reject โดย user ก่อนกลายเป็น state change — บันทึกใน `ai_audit_logs`
|
||||
@@ -135,27 +135,27 @@ _Avoid_: Throw exception from tool, Untyped error
|
||||
- An **Intent Classifier** receives user query → returns **Server-side Intent** + confidence; Pattern Layer (DB table) checked first, **LLM Fallback** (Ollama sync) used only when pattern miss
|
||||
- An **Intent Definition** (`ai_intent_definitions`) has 1:N **Intent Patterns** (`ai_intent_patterns`); Admin จัดการได้ runtime
|
||||
- **AI Gateway** dispatches to **AI Tool Layer** directly (server-side) after receiving Intent — LLM never calls tools itself; **Tool Registry** maps Intent → handler; each handler returns **ToolCallResult** wrapper
|
||||
- A **ToolResult DTO** contains only `publicId` + business codes — injected into LLM prompt as JSON context (v1, max 500 tokens); hybrid RAG+Tool deferred to Phase 4
|
||||
- A **ToolResult DTO** contains only `publicId` + business codes — injected into LLM prompt as JSON context (v1, max 500 tokens)
|
||||
|
||||
## AI authority scope (resolved)
|
||||
|
||||
| Scope | Allowed? | Mechanism |
|
||||
| -------------------------------------------------- | -------- | --------------------------------------------------------------- |
|
||||
| Read-only insight (summarise, explain) | ✅ | AI Gateway → service → CASL-guarded query |
|
||||
| Suggest action (UI shows button) | ✅ | Response shape `{ suggestedAction, confidence, reasoning }` |
|
||||
| Auto-trigger side-effects (notify, alert, comment) | ✅ | BullMQ job (ADR-008); MUST NOT change workflow state |
|
||||
| Auto-execute workflow transition | ❌ | Forbidden Tier 1 — every transition needs human `actor_user_id` |
|
||||
| Scope | Allowed? | Mechanism |
|
||||
| :--- | :--- | :--- |
|
||||
| Read-only insight (summarise, explain) | ✅ | AI Gateway → service → CASL-guarded query |
|
||||
| Suggest action (UI shows button) | ✅ | Response shape `{ suggestedAction, confidence, reasoning }` |
|
||||
| Auto-trigger side-effects (notify, alert, comment) | ✅ | BullMQ job (ADR-008); MUST NOT change workflow state |
|
||||
| Auto-execute workflow transition | ❌ | Forbidden Tier 1 — every transition needs human `actor_user_id` |
|
||||
|
||||
## Upload pipeline (resolved)
|
||||
|
||||
| Stage | Mode | Queue | Notes |
|
||||
| -------------------------------------------------------------------- | ----- | ------------- | -------------------------------------------------------- |
|
||||
| 1. Upload → **temp** + return `tempUploadId` | Sync | — | <1s |
|
||||
| 2. ClamAV scan + MIME whitelist | Sync | — | block ก่อน commit (ADR-016) |
|
||||
| 3. User commit (metadata + ย้าย permanent) | Sync | — | สร้าง `documents` row, ใช้ `Idempotency-Key` |
|
||||
| 4. **Classification/Tagging** (3 pages แรก) | Async | `ai-realtime` | suggest metadata; user accept/reject (human-in-the-loop) |
|
||||
| 5. **RAG Embedding** (full doc; OCR ถ้า text-layer < 100 chars/page) | Async | `ai-batch` | trigger AUTO หลัง commit, parallel กับ stage 4 |
|
||||
| 6. Qdrant upsert + `ai_document_chunks.embedded_at = NOW()` | Async | (worker) | gap = DB full-text fallback |
|
||||
| Stage | Mode | Queue | Notes |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| 1. Upload → **temp** + return `tempUploadId` | Sync | — | <1s |
|
||||
| 2. ClamAV scan + MIME whitelist | Sync | — | block ก่อน commit (ADR-016) |
|
||||
| 3. User commit (metadata + ย้าย permanent) | Sync | — | สร้าง `documents` row, ใช้ `Idempotency-Key` |
|
||||
| 4. **Classification/Tagging** (3 pages แรก) | Async | `ai-realtime` | suggest metadata; user accept/reject (human-in-the-loop) |
|
||||
| 5. **RAG Embedding** (full doc; OCR ถ้า text-layer < 100 chars/page) | Async | `ai-batch` | trigger AUTO หลัง commit, parallel กับ stage 4 |
|
||||
| 6. Qdrant upsert + `ai_document_chunks.embedded_at = NOW()` | Async | (worker) | gap = DB full-text fallback |
|
||||
|
||||
**กฎ:**
|
||||
|
||||
@@ -165,24 +165,16 @@ _Avoid_: Throw exception from tool, Untyped error
|
||||
- ✅ Revision ใหม่ → chunks เก่า mark `superseded_at`, **ไม่ลบ** vector
|
||||
- ✅ Frontend ใช้ `AiStatusBanner` แสดง progress
|
||||
|
||||
## Example dialogue
|
||||
|
||||
> **Dev:** "AI สรุป **RFA** revision นี้ให้หน่อย แล้วเปลี่ยน status เป็น approved เลย"
|
||||
> **Domain expert:** "ไม่ได้ — AI สรุปได้ (read-only insight) และเสนอ 'ควร approve เพราะ…' ได้ (suggest action) แต่การเปลี่ยน state ต้องผ่าน user กดปุ่มเอง ระบบจะเรียก `WorkflowService.transition()` ซึ่งบันทึก `actor_user_id` เป็นมนุษย์ใน `workflow_histories`"
|
||||
|
||||
> **Dev:** "งั้น **Tool Layer** ใน plan เก่าที่ให้ LLM เรียก `get_rfa(id)` ใช้ได้ไหม"
|
||||
> **Domain expert:** "ไม่ใช่ tool ของ LLM — เป็น **Server-side Intent** ที่ AI Gateway แปลงเป็น service call ภายใต้ CASL + `projectPublicId` scope LLM แค่รับ context ที่ pre-fetched มาแล้ว"
|
||||
|
||||
## Identifier rules (ADR-019, AI subsystem)
|
||||
|
||||
| Boundary | Identifier ที่ใช้ |
|
||||
| ---------------------------------------------- | ------------------------------------------------------------------------- |
|
||||
| API (FE ↔ AI Gateway) | `publicId` (UUIDv7 string) เท่านั้น; INT `id` มี `@Exclude()` |
|
||||
| Server-side Intent payload | `*PublicId` strings; service แปลงเป็น INT FK ภายใน |
|
||||
| LLM context (prompt) | `publicId` + business code (`rfa_number`, `drawing_code`) ห้ามเห็น INT |
|
||||
| Qdrant payload | `project_public_id`, `document_public_id`, `chunk_public_id` |
|
||||
| `ai_document_chunks` internals | INT FK ใช้ได้ภายใน DB; identity ที่ expose = `chunk_public_id BINARY(16)` |
|
||||
| Business codes (e.g. `drawing_code = "A-101"`) | รับเป็น input ได้ แต่ resolve → `publicId` ก่อน query |
|
||||
| Boundary | Identifier ที่ใช้ |
|
||||
| :--- | :--- |
|
||||
| API (FE ↔ AI Gateway) | `publicId` (UUIDv7 string) เท่านั้น; INT `id` มี `@Exclude()` |
|
||||
| Server-side Intent payload | `*PublicId` strings; service แปลงเป็น INT FK ภายใน |
|
||||
| LLM context (prompt) | `publicId` + business code (`rfa_number`, `drawing_code`) ห้ามเห็น INT |
|
||||
| Qdrant payload | `project_public_id`, `document_public_id`, `chunk_public_id` |
|
||||
| `ai_document_chunks` internals | INT FK ใช้ได้ภายใน DB; identity ที่ expose = `chunk_public_id BINARY(16)` |
|
||||
| Business codes (e.g. `drawing_code = "A-101"`) | รับเป็น input ได้ แต่ resolve → `publicId` ก่อน query |
|
||||
|
||||
**Forbidden (Tier 1 CI blocker):**
|
||||
|
||||
@@ -199,32 +191,22 @@ _Avoid_: Throw exception from tool, Untyped error
|
||||
- **Ollama** — Local LLM inference บน Admin Desktop (gemma4:e4b Q8_0 + nomic-embed-text)
|
||||
- **QdrantService** — Vector search แบบ project-isolated
|
||||
- **AiRagService** — RAG pipeline (embed query → Qdrant → LLM context)
|
||||
|
||||
**ยังขาด (Runtime Layer):**
|
||||
|
||||
- **Intent Router** — แปลงคำถามธรรมชาติ → Server-side Intent enum (เช่น `RAG_QUERY`, `GET_RFA`, `GET_DRAWING_REVISIONS`)
|
||||
- **AI Tool Layer** — Bridge functions ที่เรียก business modules (RFA, Drawing, Transmittal) ภายใต้ CASL scope
|
||||
- **Document Chat UI** — Side-panel component สำหรับคุยกับ AI ใน context ของเอกสาร
|
||||
|
||||
**ความสัมพันธ์:**
|
||||
|
||||
User Chat → Intent Router (ยังไม่มี) → Server-side Intent → AI Gateway → CASL Check →
|
||||
├─→ BullMQ → n8n → Ollama → Response
|
||||
└─→ Tool Layer (ยังไม่มี) → Business Service → Response
|
||||
- **OcrService / sidecar** — ระบบประมวลผล OCR ปลอดภัยด้วย API Key และ dynamic model swapping (ADR-033)
|
||||
|
||||
## System readiness summary (resolved)
|
||||
|
||||
| Component | สถานะ | หมายเหตุ |
|
||||
| ----------------------- | --------------- | -------------------------------------------------------------------------------------------- |
|
||||
| **Infrastructure** | ✅ พร้อม | NestJS + Next.js + MariaDB + Redis + Elasticsearch |
|
||||
| **Workflow Engine** | ✅ พร้อม | DSL-based, ADR-001/021 |
|
||||
| **AI Boundary** | ✅ พร้อม | ADR-023A — Ollama isolation, no direct DB access |
|
||||
| **RAG Pipeline** | 🟡 บางส่วน | Qdrant service มีใน code, ต้องตรวจสอบ deployment |
|
||||
| **Intent Router** | 🟡 ADR Accepted | ADR-024 Accepted — Intent Classifier (Pattern→LLM Fallback) รอ implementation |
|
||||
| **AI Tool Layer** | 🟡 ADR Accepted | ADR-025 Accepted — Tool Layer Architecture รอ implementation |
|
||||
| **Document Chat UI** | 🟡 ADR Accepted | ADR-026 Accepted — Side-panel Chat UI รอ implementation |
|
||||
| **AI Admin Console** | 🟡 ADR Accepted | ADR-027 Accepted — Dynamic Control Panel รอ implementation |
|
||||
| **Dynamic Prompt Mgmt** | ✅ พร้อม | ADR-029 Active — พัฒนาเสร็จสมบูรณ์ทั้ง Entity, API, Sandbox Runner, Cache และ UI Playgrounds |
|
||||
| Component | สถานะ | หมายเหตุ |
|
||||
| :--- | :--- | :--- |
|
||||
| **Infrastructure** | ✅ พร้อม | NestJS + Next.js + MariaDB + Redis + Elasticsearch |
|
||||
| **Workflow Engine** | ✅ พร้อม | DSL-based, ADR-001/021 |
|
||||
| **AI Boundary** | ✅ พร้อม | ADR-023A — Ollama isolation, no direct DB access |
|
||||
| **RAG Pipeline** | ✅ พร้อม | Qdrant service ป้องกันการรั่วไหลระหว่างโปรเจกต์ |
|
||||
| **Intent Router** | ✅ พร้อม | ADR-024 Active — Intent Classifier (Pattern→LLM Fallback) ทำงานเสร็จสมบูรณ์ |
|
||||
| **AI Tool Layer** | ✅ พร้อม | ADR-025 Active — Tool Layer Bridge functions พัฒนาเสร็จสมบูรณ์ |
|
||||
| **Document Chat UI** | ✅ พร้อม | ADR-026 Active — แผงควบคุม Side-panel Chat UI พัฒนาเสร็จสมบูรณ์ |
|
||||
| **AI Admin Console** | ✅ พร้อม | ADR-027 Active — แผงควบคุม Dynamic prompt & model control |
|
||||
| **Dynamic Prompt Mgmt** | ✅ พร้อม | ADR-029 Active — พัฒนาเสร็จสมบูรณ์ทั้ง Entity, API, Sandbox, Cache และ UI |
|
||||
| **Active Model & OCR Switch** | ✅ พร้อม | ADR-033 Active — สลับโมเดลแบบ Synchronous, GPU VRAM Auto-release และ API Key sidecar protection |
|
||||
|
||||
## Flagged ambiguities
|
||||
|
||||
@@ -235,88 +217,22 @@ User Chat → Intent Router (ยังไม่มี) → Server-side Intent
|
||||
- **OpenRAG vs ADR-023A** — resolved: **ADR-023A เป็น canonical source** — ใช้ Qdrant + nomic-embed-text สำหรับ vector search; Elasticsearch ใช้สำหรับ keyword/full-text เท่านั้น; `specs/03-Data-and-Storage/03-07-OpenRAG.md` เป็นเอกสาร reference แต่ไม่ใช่ active spec
|
||||
- **".agents/ กับ Production AI"** — resolved: `.agents/` คือ Dev AI toolkit (ช่วยเขียนโค้ด); Production AI คือ AI Gateway + n8n + Ollama — เป็นคนละ layer กัน
|
||||
|
||||
## Roadmap: AI Runtime Layer (pending ADRs)
|
||||
|
||||
สร้างตามลำดับ dependency:
|
||||
|
||||
### Phase 1 — Intent Router (2-3 สัปดาห์)
|
||||
|
||||
**เป้าหมาย**: แปลงคำถามธรรมชาติ → Server-side Intent enum
|
||||
|
||||
**ขั้นตอน:**
|
||||
|
||||
1. สร้าง `IntentClassifier` service — ใช้ Ollama หรือ simple pattern matching เป็น v1
|
||||
2. กำหนด `ServerIntent` enum: `RAG_QUERY`, `GET_RFA`, `GET_DRAWING`, `GET_TRANSMITTAL`, `SUMMARIZE_DOCUMENT`
|
||||
3. เพิ่ม endpoint `POST /ai/intent` ที่รับ `{ query: string, context?: { type, publicId } }` → คืน `{ intent, confidence, params }`
|
||||
4. ทดสอบ: "RFA ล่าสุดของโครงการนี้คืออะไร" → `GET_RFA` with `{ sort: 'latest', limit: 1 }`
|
||||
|
||||
**ขึ้นกับ:** ไม่มี (ใช้ Ollama ที่มีอยู่)
|
||||
|
||||
---
|
||||
|
||||
### Phase 2 — AI Tool Layer (3-4 สัปดาห์)
|
||||
|
||||
**เป้าหมาย**: Bridge functions ที่เรียก business modules ภายใต้ CASL scope
|
||||
|
||||
**ขั้นตอน:**
|
||||
|
||||
1. สร้าง `AiToolService` — registry สำหรับ tool functions
|
||||
2. สร้าง tool wrappers:
|
||||
- `getRfa(params: { publicId?; rfaNumber?; contractPublicId?; status? })`
|
||||
- `getDrawing(params: { publicId?; drawingCode?; contractPublicId?; revision? })`
|
||||
- `getTransmittal(params: { publicId?; transmittalNumber?; purpose? })`
|
||||
- `getRfaDrawings(rfaPublicId: string)` — ดึง drawings ที่ผูกกับ RFA
|
||||
3. ใส่ CASL guard ทุก tool — ตรวจสอบ `projectPublicId` scope
|
||||
4. เพิ่ม response formatter — แปลง entity → LLM-friendly context (publicId + business codes เท่านั้น)
|
||||
5. ทดสอบ: Intent Router → Tool Layer → RfaService → Response
|
||||
|
||||
**ขึ้นกับ:** Phase 1 (Intent Router ต้องรู้ว่าเรียก tool ไหน)
|
||||
|
||||
---
|
||||
|
||||
### Phase 3 — Document Chat UI (2 สัปดาห์)
|
||||
|
||||
**เป้าหมาย**: Side-panel component สำหรับคุยกับ AI ใน context เอกสาร
|
||||
|
||||
**ขั้นตอน:**
|
||||
|
||||
1. สร้าง `AiChatPanel` component — รับ `context: { type: 'drawing'|'rfa'|'transmittal', publicId: string }`
|
||||
2. เพิ่ม chat interface: user message + AI response + suggested actions
|
||||
3. สร้าง `useAiChat()` hook — TanStack Query, streaming response (optional)
|
||||
4. ฝังใน pages:
|
||||
- `/drawings/[publicId]` — context เป็น drawing นั้น
|
||||
- `/rfas/[publicId]` — context เป็น RFA นั้น
|
||||
- `/transmittals/[publicId]` — context เป็น transmittal นั้น
|
||||
5. ทดสอบ: เปิด drawing → ถาม "RFA ที่เกี่ยวข้องกับ drawing นี้คืออะไร" → AI ตอบถูก
|
||||
|
||||
**ขึ้นกับ:** Phase 1 + 2 (ต้องมี Intent Router + Tool Layer ก่อน)
|
||||
|
||||
---
|
||||
|
||||
### Phase 4 — Integration & Polish (2 สัปดาห์)
|
||||
|
||||
**ขั้นตอน:**
|
||||
|
||||
1. เพิ่ม RAG context ผสมกับ Tool results (hybrid response)
|
||||
2. เพิ่ม suggested actions ที่มาจาก AI ("ควรสร้าง RFA ใหม่ไหม?")
|
||||
3. ทดสอบ end-to-end ทุก flow
|
||||
4. ปรับ threshold / confidence scores ตามผลทดสอบ
|
||||
|
||||
---
|
||||
|
||||
## ADRs ที่เกี่ยวข้องกับ AI Runtime Layer
|
||||
|
||||
| ADR | หัวข้อ | ตัดสินใจอะไร | สถานะ |
|
||||
| ------- | ---------------------------------- | ---------------------------------------------------------------------------------------- | ----------- |
|
||||
| ADR-024 | Intent Classification Strategy | Hybrid: Pattern First → LLM Fallback | ✅ Accepted |
|
||||
| ADR-025 | AI Tool Layer Architecture | Bridge pattern, CASL enforcement, response shape | ✅ Accepted |
|
||||
| ADR-026 | Document Chat UI Pattern | Side-panel vs modal vs separate page | ✅ Accepted |
|
||||
| ADR-027 | AI Admin Console & Dynamic Control | Admin Panel + dynamic model/prompt/intent control | ✅ Accepted |
|
||||
| ADR-028 | Migration Architecture Refactor | Staging Queue & post-migration cleanup | ✅ Active |
|
||||
| ADR-029 | Dynamic Prompt Management | `ai_prompts` table, versioned OCR extraction prompt shared by sandbox + migrate-document | ✅ Active |
|
||||
| ADR | หัวข้อ | ตัดสินใจอะไร | สถานะ |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| ADR-024 | Intent Classification Strategy | Hybrid: Pattern First → LLM Fallback | ✅ Accepted |
|
||||
| ADR-025 | AI Tool Layer Architecture | Bridge pattern, CASL enforcement, response shape | ✅ Accepted |
|
||||
| ADR-026 | Document Chat UI Pattern | Side-panel vs modal vs separate page | ✅ Accepted |
|
||||
| ADR-027 | AI Admin Console & Dynamic Control | Admin Panel + dynamic model/prompt/intent control | ✅ Accepted |
|
||||
| ADR-028 | Migration Architecture Refactor | Staging Queue & post-migration cleanup | ✅ Active |
|
||||
| ADR-029 | Dynamic Prompt Management | `ai_prompts` table, versioned OCR extraction prompt | ✅ Active |
|
||||
| ADR-032 | Typhoon OCR Integration | Typhoon OCR-3B + typhoon2.1-gemma3-4b on Admin Desktop | ✅ Active |
|
||||
| ADR-033 | Active Model & OCR Management | Synchronous Model switch, GPU VRAM Auto-release, Sidecar API Key protection | ✅ Active |
|
||||
|
||||
**หมายเหตุ**: ADR-023A ยังคงเป็น canonical สำหรับ infrastructure — ADR-024/025/026/027 เพิ่ม runtime layer; ADR-028 ปรับ Migration Pipeline
|
||||
**หมายเหตุ**: ADR-023A ยังคงเป็น canonical สำหรับ infrastructure — ADR-024/025/026/027 เพิ่ม runtime layer; ADR-028 ปรับ Migration Pipeline; ADR-033 จัดระบบโมเดลและ OCR
|
||||
|
||||
## สิ่งที่ควรทำในอนาคต (Future Maintenance & Security Tasks)
|
||||
|
||||
- **Axios Dependency**: เสนอให้อัปเดตเวอร์ชันของ `axios` ใน `package.json` เป็น `>=1.16.0` เพื่อแก้ไขช่องโหว่ Prototype Pollution (High Severity - CVE-2026-44494) เพื่อป้องกันช่องทางความเสี่ยงในการถูกโจมตีผ่าน Prototype Pollution Gadget ใน `config.proxy` ของ Axios API client
|
||||
* **Axios Dependency**: ได้รับการอัปเกรด dependencies เป็นรุ่นปลอดภัยล่าสุดและแก้ไขช่องโหว่ Prototype Pollution เรียบร้อยแล้ว (pnpm audit CLEAN 100%)
|
||||
* **ความปลอดภัยของ Sidecar และ GPU**: นำระบบ API Key Header verification (`X-API-Key`) และกลไก Unload model (`keep_alive: 0`) มาประยุกต์ใช้อย่างสมบูรณ์บนเครื่องประมวลผลโลคัล Desk-5439
|
||||
|
||||
Reference in New Issue
Block a user