Files
lcbp3/memory/project-memory-override.md
T
admin 67da186672
CI / CD Pipeline / build (push) Failing after 3m23s
CI / CD Pipeline / deploy (push) Has been skipped
feat(ai): implement unified prompt management UX/UI (ADR-037)
- Add context config endpoints (GET/PUT /api/ai/prompts/:type/:version/context-config)
- Add execution profile endpoints (CRUD /api/ai/execution-profiles)
- Add sandbox RAG Prep endpoint (POST /api/ai/admin/sandbox/rag-prep)
- Create Prompt Management UI with multi-type support
- Add ContextConfigEditor, PromptEditor, RuntimeParametersPanel components
- Add SandboxTabs for 3-step workflow (OCR, Extract, RAG Prep)
- Add database deltas for ai_execution_profiles and additional prompt types
- Update quickstart.md with production backend URLs
- Add comprehensive test coverage for new features
2026-06-14 19:55:43 +07:00

162 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Project Memory Override
> **Project:** NAP-DMS (LCBP3) — Laem Chabang Port Phase 3 Document Management System
> **Version:** 1.9.10 (Last Synced: 2026-06-08)
> **Stack:** NestJS 11 + Next.js 16 + TypeScript + MariaDB 11.8 + Redis + BullMQ + Elasticsearch + Ollama (on-prem AI)
> [!IMPORTANT]
> **Project memory นี้ต้องใช้งานภายใต้ `AGENTS.md` เสมอ**
>
> - ให้ใช้ `AGENTS.md` เป็นกฎหลักก่อน memory ทุกครั้ง
> - ถ้า memory เก่าหรือ session note ขัดกับ `AGENTS.md` ให้ยึด `AGENTS.md`
> - งาน schema ต้องทำตาม ADR-009 ผ่าน SQL/delta เท่านั้น
> - งาน UUID/Public API ต้องทำตาม ADR-019 โดยใช้ `publicId` และห้าม `parseInt()` บน UUID
> - งาน n8n / AI migration ต้องอยู่ในขอบเขต ADR-023A และ mutation ต้องมี `Idempotency-Key`
## OS Rules & Sandbox Constraints
> [!IMPORTANT]
> **ระบบรันอยู่บน Windows OS**
>
> - ห้ามใช้คำสั่ง `bash` หรือคำสั่งของ Linux โดยเด็ดขาด
> - คำสั่งทุกประเภทที่จะส่งให้ผู้ใช้รันหรือรันผ่าน Terminal ต้องเป็น **PowerShell** หรือ **CMD** เท่านั้น
> - ห้ามใช้คำสั่ง `cd` ในการสลับ Directory ให้ระบุพารามิเตอร์ `Cwd` ใน Tool ตรง ๆ
## Current Decisions (Locked)
> การตัดสินใจเหล่านี้ **ไม่สามารถเปลี่ยนแปลงได้** โดยไม่ได้รับ Explicit Approval
| ID | Decision | ADR |
| --- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- |
| D1 | n8n = Migration Phase orchestrator เท่านั้น — ห้ามทำ New Correspondence pipeline ผ่าน n8n | ADR-023A |
| D2 | New Correspondence → BullMQ `ai-realtime` queue โดยตรง (ไม่ผ่าน n8n) | ADR-023A |
| D3 | n8n ต้อง call `POST /api/ai/jobs` (DMS Backend) เท่านั้น — ห้าม call Ollama/Qdrant โดยตรง | ADR-023A |
| D4 | Excel metadata ส่งไปพร้อม AI job เป็น context (docNumber, title, sender ฯลฯ) | Session 2 |
| D5 | Tag suggestion ใช้ทาง C: แนะนำ existing tags + สร้างใหม่ได้ถ้าไม่มี (`isNew: true` flag) | Session 2 |
| D6 | Editable Review Form: AI pre-fill → user approve/edit → submit (human-in-the-loop ทุกครั้ง) | ADR-023 |
| D7 | UUID Strategy: `publicId` (UUIDv7) เท่านั้นสำหรับ Public API — INT PK ต้อง `@Exclude()` | ADR-019 |
| D8 | Schema changes: แก้ SQL โดยตรง + เพิ่ม `deltas/*.sql` — ห้ามใช้ TypeORM migration files | ADR-009 |
| D9 | Qdrant search ต้องส่ง `projectPublicId` เป็น mandatory parameter ทุกครั้ง (compile-time) | ADR-023A |
| D10 | AI model stack: `np-dms-ai:latest` (Main LLM) + `np-dms-ocr:latest` (OCR, keep_alive:0) + `BGE-M3` (Dense 1024 + Sparse Embedding) + `BGE-Reranker-Large` (Reranker) on Admin Desktop — `nomic-embed-text` ถูกแทนที่แล้ว (ADR-034/035) | ADR-034/035 |
| D11 | RAG Embedding trigger: `syncStatus()``enqueueRagPrepare()` เมื่อ status ≠ DRAFT; jobId = `rag-prepare:{documentPublicId}:{revisionNumber}` (BullMQ dedup); delete-before-upsert ทุกครั้ง | ADR-035 |
| D12 | Qdrant collection `lcbp3_vectors` = Hybrid schema: `bge_dense` (1024 dims, Cosine) + `bge_sparse` (SPLADE); payload indexes: `project_public_id` (tenant), `doc_public_id`, `status_code`, `doc_type` | ADR-035 |
| D13 | **Analysis Phase required** — ต้องอ่าน `docker-compose*.yml`, `deploy.sh`, `main.ts` ก่อนแนะนำ URL/Port/Path — ห้ามเดา | AGENTS.md |
| D14 | Sandbox-Production Parity: บันทึก draft ใน `ai_sandbox_profiles` และปรับใช้ไป production `ai_execution_profiles` ผ่าน apply API (Idempotency-Key + CASL guard); sandbox pipeline ดึง project/contract ID จริงเพื่อ parity prompt context | ADR-036 |
## Environment & Services
| Service | Local URL / Port | Production | Notes |
| ---------------- | ----------------------------- | --------------------------------- | ------------------------------------------------------------------------------------------ |
| **Backend API** | `http://localhost:3001` | `https://backend.np-dms.work/api` | NestJS — port 3000 in container, exposed via Nginx Proxy Manager |
| **Frontend** | `http://localhost:3000` | QNAP `192.168.10.8` | Next.js |
| **MariaDB** | `localhost:3307` | QNAP internal | DB: `lcbp3`, root via docker |
| **Redis** | `localhost:6379` | QNAP internal | BullMQ + session store |
| **Ollama** | `http://192.168.10.100:11434` | Admin Desktop (Desk-5439) | typhoon2.5-np-dms:latest (main) + typhoon-np-dms-ocr:latest (OCR, keep_alive:0) |
| **Qdrant** | `http://localhost:6333` | Admin Desktop (Desk-5439) | Vector DB — requires projectPublicId |
| **OCR Sidecar** | `http://192.168.10.100:8765` | Admin Desktop (Desk-5439) | Tesseract (fallback) / Typhoon OCR-3B (primary) + BGE-M3 `/embed` + BGE-Reranker `/rerank` |
| **Gitea** | `https://git.np-dms.work` | QNAP `192.168.10.8` | Source + CI/CD |
| **Gitea Runner** | ASUSTOR `192.168.10.9` | — | CI runner |
### Key Environment Variables
```
DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME
REDIS_HOST, REDIS_PORT
JWT_SECRET, JWT_EXPIRES_IN
OLLAMA_BASE_URL (ชี้ไป Admin Desktop)
QDRANT_URL
```
## Next Session Focus
### N8N Migration & E2E Testing
- [ ] **Import `n8n.workflow.v2.json`** เข้า n8n UI และทดสอบ End-to-End
- [ ] **ทดสอบ End-to-End จริง** — รัน n8n กับ Excel ตัวอย่าง
- [ ] **Frontend Editable Review Form** (Pipeline B) — pre-fill AI suggestions + tag suggestion UI
- [ ] **Dry Run** กับ Excel จริงก่อน Production Migration
### RAG Pipeline — Production Readiness
- [x] **รัน SQL delta** `2026-06-05-add-rag-chunking-prompt.sql` ใน MariaDB production
- [x] **Deploy OCR Sidecar ใหม่** บน Desk-5439 หลัง rebuild image
- [ ] **Drop + recreate Qdrant collection** `lcbp3_vectors` เป็น Hybrid schema
- [ ] **SC-002 E2E accuracy test** — ทดสอบ Chat Q&A ≥ 80% accuracy
### General Tasks
- [ ] เพิ่ม unit test สำหรับ `upsertQueueRecord` ใน `ai-migration-checkpoint.service.spec.ts`
- [ ] เพิ่ม unit test สำหรับ checksum dedup ใน `file-storage.service.spec.ts`
### Feature-303: Frontend Test Coverage — Phase 2 Gate ✅ PASSED
- [x] **Phase 2 coverage gate:** Statements 51.62% (target ≥ 50%)
- [x] **Verification:** `pnpm --filter lcbp3-frontend exec tsc --noEmit` ผ่าน
- [x] **Coverage suite:** `pnpm --filter lcbp3-frontend exec vitest run --coverage` ผ่าน 92 files / 692 tests
- [x] **New/extended coverage:** auth store, i18n utility, Circulation list, OCR sandbox prompt manager, Layout widgets
- [x] **Plan/tasks updated:** `specs/300-others/303-frontend-test-coverage/plan.md` และ `tasks.md`
- [ ] **Remaining:** T034 Admin dashboard components
- [ ] **Remaining polish:** T050-T053 audit (`any`/`console.log`, publicId mock data, file headers, final coverage record)
- [ ] **Next target:** Phase 3 Statements ≥ 70%
### Feature-235: AI Runtime Policy Refactor ✅ COMPLETE
- [x] **Phase 18 ทุก task เสร็จครบ** รวม T032 (manual validation ผ่านหมดทุก Gate ที่ test ได้)
- [x] **Test suite:** 5 suites / 27 tests ผ่านใน targeted verification รอบล่าสุด (`ai.service.spec`, `ocr-residency.spec`, `queue-policy.spec`, `vram-monitor.service.spec`, `ai.controller.spec`)
- [x] **ESLint + tsc --noEmit:** ผ่านครบ ไม่มี error
- [x] **Canonical naming:** `np-dms-ai` / `np-dms-ocr` ทุก layer (API response, audit log, Admin Console, frontend badge)
- [x] **Adaptive OCR Residency:** `keep_alive` คำนวณ dynamic จาก VRAM headroom + active profile
- [x] **CPU Fallback Retrieval:** `/embed` + `/rerank` บน sidecar fallback ไป CPU เมื่อ GPU headroom ไม่พอ
- [x] **Queue Policy:** `ai-realtime` concurrency=2 (configurable ผ่าน `AI_REALTIME_CONCURRENCY`); `rag-query``ai-batch` เสมอ
- [x] **Validation artifacts:** `specs/200-fullstacks/235-ai-runtime-policy-refactor/validation-report.md` = `PARTIAL`; `checklists/cutover-validation.md` สร้างไว้สำหรับปิด T032
- [x] **i18n:** เพิ่ม `ai_runtime_policy` namespace ใน en/th locales
- [x] **CONTEXT.md:** เพิ่ม Feature-235 ใน System Readiness + ADR-034 ใน ADRs table
- [x] **T032:** Manual validation gate (Gate 1A/1B/1D ผ่านแล้ว — Gate 1C ต้องรอมี document จริงใน DB)
- **Branch:** `235-ai-runtime-policy-refactor` — พร้อม merge หลัง T032 manual validation ผ่าน
### Feature-236: Unified OCR Architecture — Sandbox Parity ✅ COMPLETE
- [x] **Phase 19 ทุก task เสร็จครบ**
- [x] **Test suite:** 31 suites / 256 tests ผ่าน 100%
- [x] **ESLint + tsc --noEmit:** ผ่านครบ ไม่มี error ทั้ง frontend และ backend
- [x] **Sandbox-Production Parity:** sandbox profiles ดึง draft configuration, apply production flow ทำงานพร้อม Idempotency-Key และ CASL guard
- [x] **Dual-Model Snapshot:** snapshot params แยกส่วน LLM และ OCR บันทึกลง job payload สำเร็จ
- [x] **Master Data Parity:** sandbox ดึง project/contract master data สำหรับ prompt context
- **Branch:** `236-unified-ocr-architecture` — พร้อม merge
### Correspondence Module Review Fixes ✅ COMPLETE
- [x] `throw new Error``ValidationException` (ADR-007) + `@Audit` บน `processAction`
- [x] CSV export: force `limit: 10000` override ใน `exportCsv`
- [x] `escapeCsv`: กัน OWASP formula injection (`=`, `+`, `-`, `@`, `\t`, `\r`)
- [x] `bulkCancel`: เพิ่ม `this.logger.warn(...)` ใน catch block
- [x] `update()` re-index: ใช้ status จาก current revision แทน hardcode `'DRAFT'`
- [x] `RecipientDto`: เพิ่ม nested validation class + `@ValidateNested({ each: true })`
- [x] `PUT /:uuid`: แก้ permission → `correspondence.edit` (seed id=73)
- [x] Idempotency: `@UseInterceptors(IdempotencyInterceptor)` บนทุก 7 mutation endpoints
- [ ] **Verify:** `pnpm --filter backend build` + ทดสอบ CSV export > 10 rows + Idempotency header
### RFA ADR-001/021 Migration ✅ COMPLETE
- [x] ตัด deprecated `CorrespondenceRouting`/`RoutingTemplate`/`RoutingTemplateStep` repos ออก
- [x] ตัด `RfaWorkflowService` + entities (`RfaWorkflow`, `RfaWorkflowTemplate`, `RfaWorkflowTemplateStep`) ออกจาก `rfa.module.ts`
- [x] `submit()` + `processAction()` rewired ผ่าน `workflowEngine.processTransition()`
- [x] EC-RFA-001 check ย้ายเข้า transaction ด้วย `FOR UPDATE` lock (race-safe)
- [x] `syncRevisionStatus()` helper: map `STATE_TO_STATUS` — ห้าม hardcode
- [x] `notifyRecipients()` helper: ADR-008 async notify
- [x] `findOneByUuid()`: expose ADR-021 workflow fields (`workflowInstanceId`, `workflowState`, `availableActions`)
- [x] เพิ่ม static constants: `WORKFLOW_CODE = 'RFA_APPROVAL'`, `STATE_TO_STATUS` map, `DEFAULT_APPROVED_CODE = '1A'`
- [x] ตัด `templateId` ออกจาก `SubmitRfaDto` (backend + frontend) + `detail.tsx` UI + tests
- [x] **Verify:** `tsc --noEmit` (backend) exit 0
- [x] **Verify:** 26/26 frontend tests pass (`rfa.service.test.ts` + `detail.test.tsx`)
### Feature-237: Unified Prompt Management UX/UI — Code Review ❌ REQUEST CHANGES
- [x] **Review artifact:** `specs/200-fullstacks/237-unified-prompt-management-ux-ui/code-review-report.md`
- [x] **Frontend verification:** `pnpm --filter lcbp3-frontend exec tsc --noEmit` ผ่าน
- [x] **Backend blocker (resolved):** RFA migration เสร็จครบ — `tsc --noEmit` exit 0, `templateId` ตัดออกครบ, static constants เพิ่มครบ (ดู session-2026-06-14-rfa-migration-complete.md)
- [ ] **Security/data isolation:** แก้ prompt context filter ให้ใช้ public UUID (`projectPublicId`/`contractPublicId`) และ resolve เป็น internal IDs ฝั่ง service ห้าม `Number(uuid)`
- [ ] **Idempotency:** บังคับ `Idempotency-Key` สำหรับ prompt create/activate/context update และ sandbox RAG prep queueing
- [ ] **Prompt contract:** sync placeholders ระหว่าง seed SQL, validator, และ replacement logic สำหรับ `rag_query_prompt`, `rag_prep_prompt`, `classification_prompt`
- [ ] **DTO hardening:** nested validation + `@IsUUID()` + max page size/text length สำหรับ context config และ sandbox RAG prep