Compare commits
102 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4a808dd9c4 | |||
| e71602e90c | |||
| bd96c4122c | |||
| 661710f349 | |||
| eae94cf1f3 | |||
| eeb9f6c686 | |||
| 37174788bf | |||
| 2db4810dfc | |||
| 8b6ef392f5 | |||
| eef557675b | |||
| 1a399400ff | |||
| 29314a7ec4 | |||
| 70fbac1b49 | |||
| 1c3d9906e4 | |||
| c841be1b31 | |||
| 94583bd30f | |||
| 17dff31dec | |||
| b14a0b3d58 | |||
| 03963fd896 | |||
| 663ed13522 | |||
| 9c122c8328 | |||
| 4d243c16e6 | |||
| 994b41aa37 | |||
| b79895e6fb | |||
| fb224a116c | |||
| e0eabfb350 | |||
| 3274dede7a | |||
| 754d609399 | |||
| e4948ad4c8 | |||
| be851ee311 | |||
| cb9ecb2de6 | |||
| b939a25456 | |||
| 8909629d8f | |||
| bc754e66fd | |||
| 7f35c3a585 | |||
| 2cc07ee2e5 | |||
| 69db07fe35 | |||
| acc19f4a44 | |||
| 2bbe67b4c5 | |||
| 7bc6eefad2 | |||
| 09505f5793 | |||
| cd2bd5bf19 | |||
| 20f9fa1e85 | |||
| b8954b300d | |||
| 00ae9d3067 | |||
| 3c80617ffb | |||
| 268f34198b | |||
| ae1b1f35e1 | |||
| f86fcc05f5 | |||
| 9404596012 | |||
| 10024a66c3 | |||
| b7a7b1e84d | |||
| 30d9d721fb | |||
| c9edd62a0b | |||
| ddc9332122 | |||
| e82cb0e68b | |||
| b1c838a637 | |||
| d13d5a06cc | |||
| 3bf0f506eb | |||
| c88354347b | |||
| 33c62993d5 | |||
| 499d787aa5 | |||
| b0b7d12d5a | |||
| 1ba563aa70 | |||
| 63ded10341 | |||
| 32204c9305 | |||
| 6799cb1715 | |||
| f33487f511 | |||
| 8367ced926 | |||
| 8b05f0f05c | |||
| d19131fa75 | |||
| 95c1c31e1f | |||
| 0dcd7f460b | |||
| b68a750e4f | |||
| 5d46504c1d | |||
| 4391bbe61d | |||
| 960cd78b8a | |||
| 01de542d15 | |||
| 9502d789b9 | |||
| 83d1517afc | |||
| 1da666b090 | |||
| b3d3f6db95 | |||
| fd3bee394c | |||
| 82a0444013 | |||
| 1139e54086 | |||
| d315488d83 | |||
| 87c3defc76 | |||
| 1460ffb676 | |||
| 4267f82db9 | |||
| c9e578a33e | |||
| 256a31b38c | |||
| 001237ea35 | |||
| dcd1a9855e | |||
| 1564f8648d | |||
| 93fd95a6b3 | |||
| a63fe0fb5c | |||
| 5a17f969b8 | |||
| ff5cadc9f2 | |||
| c04c5d1902 | |||
| 3bf34ea840 | |||
| 433b149c85 | |||
| 942cda486c |
+10
-10
@@ -6,8 +6,8 @@
|
|||||||
> # Speckit Agent Infrastructure (v1.9.0)
|
> # Speckit Agent Infrastructure (v1.9.0)
|
||||||
>
|
>
|
||||||
> - Version: 1.9.0
|
> - Version: 1.9.0
|
||||||
> - Last Updated: 2026-05-13
|
> - Last Updated: 2026-05-22
|
||||||
> - Core Principle: **Sync with AGENTS.md v1.9.0**
|
> - Core Principle: **Sync with AGENTS.md v1.9.6**
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -95,18 +95,18 @@ The toolkit is organized into modular components that provide both the logic (Sc
|
|||||||
│ └── util-speckit-*.md # Utilities (checklist, diff, migrate, etc.)
|
│ └── util-speckit-*.md # Utilities (checklist, diff, migrate, etc.)
|
||||||
│
|
│
|
||||||
├── rules/ # Project Context & Validation Rules
|
├── rules/ # Project Context & Validation Rules
|
||||||
│ ├── 00-project-context.md # Role, Persona, Rule Tiers (v1.9.0)
|
│ ├── 00-project-context.md # Role, Persona, Rule Tiers (v1.9.6)
|
||||||
│ ├── 01-adr-019-uuid.md # UUID Strategy (Critical)
|
│ ├── 01-adr-019-uuid.md # UUID Strategy (Critical)
|
||||||
│ ├── 02-security.md # Security Requirements
|
│ ├── 02-security.md # Security Requirements (ADR-023/023A)
|
||||||
│ ├── 03-typescript.md # TypeScript Standards
|
│ ├── 03-typescript.md # TypeScript Standards
|
||||||
│ ├── 04-domain-terminology.md # DMS Glossary Compliance
|
│ ├── 04-domain-terminology.md # DMS Glossary Compliance
|
||||||
│ ├── 05-forbidden-actions.md # Critical Prohibited Patterns
|
│ ├── 05-forbidden-actions.md # Critical Prohibited Patterns
|
||||||
│ ├── 06-backend-patterns.md # NestJS Architecture Rules
|
│ ├── 06-backend-patterns.md # NestJS Architecture Rules
|
||||||
│ ├── 07-frontend-patterns.md # Next.js App Router Rules
|
│ ├── 07-frontend-patterns.md # Next.js App Router Rules
|
||||||
│ ├── 08-development-flow.md # Development Workflow
|
│ ├── 08-development-flow.md # Development Workflow (Tier 3 SPECIALIZED WORK)
|
||||||
│ ├── 09-commit-checklist.md # Pre-commit Validation
|
│ ├── 09-commit-checklist.md # Pre-commit Validation
|
||||||
│ ├── 10-error-handling.md # ADR-007 Compliance
|
│ ├── 10-error-handling.md # ADR-007 Compliance
|
||||||
│ └── 11-ai-integration.md # ADR-018/020 AI Boundaries
|
│ └── 11-ai-integration.md # ADR-023/023A AI Boundaries
|
||||||
│
|
│
|
||||||
└── scripts/
|
└── scripts/
|
||||||
├── bash/ # Bash Core (Kinetic logic)
|
├── bash/ # Bash Core (Kinetic logic)
|
||||||
@@ -265,9 +265,9 @@ If you change your mind mid-project:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🏗️ LCBP3-DMS Project Notes (v1.9.0)
|
## 🏗️ LCBP3-DMS Project Notes (v1.9.6)
|
||||||
|
|
||||||
### 📊 Current Status: Production Ready (2026-04-14)
|
### 📊 Current Status: Production Ready (2026-05-22)
|
||||||
|
|
||||||
| Area | Status |
|
| Area | Status |
|
||||||
| ------------- | ------------------------------- |
|
| ------------- | ------------------------------- |
|
||||||
@@ -306,7 +306,7 @@ If you change your mind mid-project:
|
|||||||
- ❌ DO NOT bypass Release Gates before deploying — `04-08-release-management-policy.md`
|
- ❌ DO NOT bypass Release Gates before deploying — `04-08-release-management-policy.md`
|
||||||
- ❌ DO NOT start Migration without Gate #1 approval — `03-06-migration-business-scope.md`
|
- ❌ DO NOT start Migration without Gate #1 approval — `03-06-migration-business-scope.md`
|
||||||
- ❌ DO NOT use TypeORM Migrations — modify schema SQL directly (ADR-009)
|
- ❌ DO NOT use TypeORM Migrations — modify schema SQL directly (ADR-009)
|
||||||
- ❌ DO NOT give Ollama direct DB access — all writes via DMS API (ADR-018)
|
- ❌ DO NOT give Ollama direct DB access — all writes via DMS API (ADR-023/023A)
|
||||||
- ❌ DO NOT use `any` TypeScript type anywhere
|
- ❌ DO NOT use `any` TypeScript type anywhere
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -325,7 +325,7 @@ If you change your mind mid-project:
|
|||||||
# Run version validation
|
# Run version validation
|
||||||
./scripts/bash/validate-versions.sh
|
./scripts/bash/validate-versions.sh
|
||||||
|
|
||||||
# Fix by updating all files to v1.9.0
|
# Fix by updating all files to v1.9.6
|
||||||
# Then re-run validation to confirm
|
# Then re-run validation to confirm
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,56 +1,164 @@
|
|||||||
# NAP-DMS Project Context & Core Rules
|
# NAP-DMS Project Context & Rules
|
||||||
|
|
||||||
- Version: 1.9.3
|
- For: Windsurf Cascade (and compatible: Codex CLI, opencode, Amp, Antigravity, AGENTS.md tools)
|
||||||
- Last Updated: 2026-05-15
|
- Version: 1.9.6 | Last synced from repo: 2026-05-22
|
||||||
- Status: Production Ready
|
- Repo: [https://git.np-dms.work/np-dms/lcbp3](https://git.np-dms.work/np-dms/lcbp3)
|
||||||
- Canonical Source: AGENTS.md
|
- Skill pack: `.agents/skills/` (v1.9.0, 21 skills) — see [`skills/README.md`](./.agents/skills/README.md) + [`skills/_LCBP3-CONTEXT.md`](./.agents/skills/_LCBP3-CONTEXT.md)
|
||||||
|
|
||||||
## 🎭 Role & Persona
|
## 🧠 Role & Persona
|
||||||
|
|
||||||
Act as a **Senior Full Stack Developer** specialized in NestJS, Next.js, and TypeScript.
|
Act as **Senior Full Stack Developer** specialized in NestJS, Next.js, TypeScript, DMS. Focus: Data Integrity, Security, Maintainability, Performance.
|
||||||
Focus on **Data Integrity, Security, Maintainability, and Performance**.
|
|
||||||
You are a **Document Intelligence Engine** — every response must be precise, spec-compliant, and production-ready.
|
You are a **Document Intelligence Engine** — not a general chatbot. Every response must be **precise**, **spec-compliant**, and **production-ready**.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔴 Tier 1 — CRITICAL (CI BLOCKER)
|
## 🧩 Thought & Planning Protocol (Powered by Everything-Claude-Code)
|
||||||
|
|
||||||
1. **Identifier Strategy (ADR-019)**
|
Before writing any code or taking any action in Tier 1 and Tier 2, the AI must demonstrate the following thinking process:
|
||||||
- ห้ามใช้ `parseInt()` บน UUID
|
|
||||||
- ใช้ `publicId` (string) สำหรับการติดต่อภายนอก (API/URL) เท่านั้น
|
### 1. Analysis Phase (Explore & Analyze)
|
||||||
2. **Database Management (ADR-009)**
|
|
||||||
- ห้ามใช้ TypeORM Migrations หรือ `synchronize: true`
|
Problem Understanding: Restate what the user wants in clear, unambiguous terms.
|
||||||
- การแก้ Schema ต้องแก้ที่ SQL files ใน `specs/03-Data-and-Storage/` เท่านั้น
|
Context Search: Identify the relevant Spec files or ADRs from the "Key Spec Files" table that must be read before starting.
|
||||||
3. **Security (ADR-016)**
|
Constraints Identification: Identify key constraints (e.g. Security rules, UUID patterns, or Domain terminology).
|
||||||
- ทุก API ต้องมี `CASL Guard` และตรวจสอบสิทธิ์ผ่าน RBAC Matrix
|
|
||||||
- การอัปโหลดไฟล์ต้องเป็น Two-Phase (Temp → Commit) และต้องสแกน ClamAV
|
### 2. Planning Phase (Plan)
|
||||||
4. **AI Boundary (ADR-018)**
|
|
||||||
- AI Agent ต้องทำงานผ่าน DMS API เท่านั้น ห้ามเขียนลง Database หรือ Storage โดยตรง
|
Alternative Exploration: Present at least 2 solution approaches (where possible) with pros/cons analysis.
|
||||||
|
Step-by-Step Roadmap: Write a file-by-file plan of changes before executing.
|
||||||
|
Verification Plan: Specify how to verify the work is complete (e.g. "which unit tests to write" or "which file to check the schema in").
|
||||||
|
|
||||||
|
### 3. Execution & Refinement (Execute & Refine)
|
||||||
|
|
||||||
|
Follow the plan step by step, and pause to ask if any uncertainty arises.
|
||||||
|
If significant logic changes are made, summarize what was done for the user after completion.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📐 TypeScript Rules & Coding Standards (v1.9.0)
|
## ⚙️ DMS Workflow Engine Protocol
|
||||||
|
|
||||||
- **File Header:** ทุกไฟล์ต้องขึ้นต้นด้วย `// File: path/filename`
|
กฎนี้ใช้คุม Logic การไหลของเอกสาร (RFA, Transmittal, Correspondence) เพื่อป้องกัน Race Condition และรักษาความถูกต้องของสถานะ:
|
||||||
- **Change Log:** ต้องมีส่วน `// Change Log` ที่หัวไฟล์
|
|
||||||
- **Language:** ตัวแปร/Logic เป็น English, Comment/JSDoc เป็น **Thai**
|
- **State Management:** ตรวจสอบสถานะปัจจุบันจาก DB ก่อนเสมอ เพื่อป้องกันการอนุมัติซ้ำซ้อน (ดู `05-06-code-snippets.md` `[workflow-transition]`)
|
||||||
- **Explicit Typing:** กำหนด Type ให้ชัดเจนเสมอ ห้ามใช้ `any`
|
- **Concurrency Control:** การจอนเลขที่เอกสารต้องใช้ **Redis Redlock** หรือ **TypeORM `@VersionColumn`** เท่านั้น (ADR-002)
|
||||||
- **Cleanliness:** ห้ามมีบรรทัดว่างในฟังก์ชัน, Export ได้เพียง 1 symbol หลักต่อไฟล์
|
- **Background Jobs:** งานนานหรือการแจ้งเตือนต้องส่งไปทำที่ **BullMQ** ห้ามเขียนแบบ Inline (ADR-008)
|
||||||
|
- **Term Consistency:** ห้ามใช้ "Approval Flow" ให้ใช้ **"Workflow Engine"** และห้ามใช้ "Letter" ให้ใช้ **"Correspondence"** (หมายเหตุ: "จดหมาย" ในคอมเมนต์ภาษาไทย = Correspondence ที่ครอบคลุมทุกประเภท)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📁 Specs Folder Organization (Hybrid Model)
|
## 🛡️ Security & Integrity Audit Protocol
|
||||||
|
|
||||||
- **Core (00-06):** ข้อมูลอ้างอิงถาวร (Permanent Source of Truth)
|
กฎนี้ให้ AI เป็น Gatekeeper ก่อน Commit โดยเน้น **Tier 1 — CRITICAL**:
|
||||||
- **Feature (100-300):** สำหรับงาน Implementation ใหม่
|
|
||||||
- `100-Infrastructures/`
|
- **UUID Validation:** ตรวจสอบว่าเป็น **UUIDv7** และห้ามใช้ `parseInt()` บน UUID (ADR-019)
|
||||||
- `200-fullstacks/`
|
- **RBAC Check:** API ใหม่ต้องมี **CASL Guard** และตรวจสอบ 4-Level RBAC Matrix (ADR-016)
|
||||||
- `300-others/`
|
- **Data Isolation:** AI ต้องรันผ่าน **Ollama บน Admin Desktop** เท่านั้น ห้ามเข้าถึง DB/storage โดยตรง (ADR-023)
|
||||||
|
- **Input Sanitization:** ไฟล์อัปโหลดต้องผ่าน **Two-Phase** (Temp → Commit) และสแกนด้วย **ClamAV** (ADR-016)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔄 Workflow Engine (ADR-001/021)
|
## 🧭 Rule Enforcement Tiers
|
||||||
|
|
||||||
- ใช้ DSL-based state machine
|
### 🔴 Tier 1 — CRITICAL (CI BLOCKER)
|
||||||
- การเปลี่ยนสถานะต้องตรวจสอบสถานะปัจจุบันจาก DB ก่อนเสมอ
|
|
||||||
- งานที่ใช้เวลานานต้องส่งไปที่ **BullMQ** เท่านั้น
|
Build fails หากละเมิด:
|
||||||
|
|
||||||
|
- Security (Auth, RBAC, Validation)
|
||||||
|
- UUID Strategy (ADR-019) — no `parseInt` / `Number` / `+` on UUID
|
||||||
|
- Database correctness — verify schema before writing queries
|
||||||
|
- File upload security (ClamAV + whitelist)
|
||||||
|
- AI validation boundary (ADR-023)
|
||||||
|
- Error handling strategy (ADR-007)
|
||||||
|
- Forbidden patterns: `any`, `console.log`, UUID misuse, `id ?? ''` fallback
|
||||||
|
|
||||||
|
### 🟡 Tier 2 — IMPORTANT (CODE REVIEW)
|
||||||
|
|
||||||
|
Must fix ก่อน merge:
|
||||||
|
|
||||||
|
- Architecture patterns (thin controller, business logic in service)
|
||||||
|
- Test coverage (80%+ business logic, 70%+ backend overall)
|
||||||
|
- Cache invalidation
|
||||||
|
- Naming conventions
|
||||||
|
- **TypeScript Standards:** Missing JSDoc, explicit types, or file headers
|
||||||
|
|
||||||
|
### 🟢 Tier 3 — SPECIALIZED WORK
|
||||||
|
|
||||||
|
Requires domain-specific knowledge:
|
||||||
|
|
||||||
|
- **ADR-021 Integration:** Workflow Engine & Context implementation
|
||||||
|
- **AI Infrastructure:** ADR-023/023A boundary enforcement and pipeline usage
|
||||||
|
- **AI Runtime Layer:** ADR-024 Intent Classification, ADR-025 Tool Layer, ADR-026 Chat UI, ADR-027 Admin Console
|
||||||
|
- **Migration Pipeline:** ADR-028 Staging Queue & post-migration cleanup
|
||||||
|
- **Complex Business Logic:** Multi-step workflows with state management
|
||||||
|
- **Performance Optimization:** Database queries, caching strategies, bulk operations
|
||||||
|
|
||||||
|
### 🔵 Tier 4 — GUIDELINES
|
||||||
|
|
||||||
|
Best practice — follow when possible:
|
||||||
|
|
||||||
|
- Code style / formatting (Prettier handles)
|
||||||
|
- Comment completeness
|
||||||
|
- Minor optimizations
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📐 TypeScript Rules & Coding Standards
|
||||||
|
|
||||||
|
### 📝 Core Standards
|
||||||
|
|
||||||
|
- **Strict Mode** — all strict checks enforced.
|
||||||
|
- **ZERO `any` types** — use proper types or `unknown` + narrowing.
|
||||||
|
- **ZERO `console.log`** — use NestJS `Logger` (backend) or remove (frontend).
|
||||||
|
- **English for Code** — use English for all code identifiers, variables, and logic.
|
||||||
|
- **Thai for Comments** — use Thai for comments, documentation, and JSDoc.
|
||||||
|
- **Explicit Typing** — explicitly define types for all variables, parameters, and return values.
|
||||||
|
- **JSDoc** — use JSDoc for all public classes and methods.
|
||||||
|
|
||||||
|
### 🏗️ File & Function Structure
|
||||||
|
|
||||||
|
- **File Headers** — every file MUST start with `// File: path/filename` on the first line.
|
||||||
|
- **Change Log** — include `// Change Log` at the top of the file to track modifications.
|
||||||
|
- **Single Export** — export **only one main symbol** per file.
|
||||||
|
- **Function Style** — avoid unnecessary blank lines inside functions.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚫 Forbidden Actions
|
||||||
|
|
||||||
|
| ❌ Forbidden | ✅ Correct Approach | ⚠️ Why |
|
||||||
|
| ----------------------------------------------- | ------------------------------------------------------- | ---------------------------------------------------- |
|
||||||
|
| SQL Triggers for business logic | NestJS Service methods | Untestable; bypasses audit log |
|
||||||
|
| `.env` files in production | `docker-compose.yml` environment section | Secrets exposed in version control |
|
||||||
|
| TypeORM migration files | Edit schema SQL directly (ADR-009) | Migration drift risk; schema managed via SQL delta |
|
||||||
|
| Inventing table/column names | Verify against `schema-02-tables.sql` | Schema mismatch causes silent runtime errors |
|
||||||
|
| `any` TypeScript type | Proper types / generics | Defeats strict mode; hides runtime type errors |
|
||||||
|
| `console.log` in committed code | NestJS Logger (backend) / remove (frontend) | Log flooding in production; risk of data leakage |
|
||||||
|
| `req: any` in controllers | `RequestWithUser` typed interface | Type safety lost; auth context unreachable |
|
||||||
|
| `parseInt()` on UUID values | Use UUID string directly (ADR-019) | `"0195…"` parsed to integer `19` — silently wrong |
|
||||||
|
| Exposing INT PK in API responses | UUIDv7 `publicId` (ADR-019) | Leaks row count; enables DB enumeration attacks |
|
||||||
|
| AI accessing DB/storage directly | AI → DMS API → DB (ADR-023/023A) | Bypasses RBAC, audit trail, and validation layer |
|
||||||
|
| Direct file operations bypassing StorageService | `StorageService` for all file moves | Orphaned files; broken ClamAV scan; no audit trail |
|
||||||
|
| Inline email/notification sending | BullMQ queue job (ADR-008) | Blocks request thread; no retry on transient failure |
|
||||||
|
| Deploying without Release Gates | Complete `04-08-release-management-policy.md` | Unverified deploy risks data loss in production |
|
||||||
|
| AI direct cloud API calls | On-premises Ollama only (ADR-023/023A) | Data privacy violation; no audit control |
|
||||||
|
| AI outputs without human validation | Human-in-the-loop validation required (ADR-023/023A) | Unvalidated AI metadata corrupts document records |
|
||||||
|
| n8n calling Ollama/Qdrant directly | n8n → DMS API → BullMQ → Ollama (ADR-023A) | Bypasses audit log, RBAC, and error handling layer |
|
||||||
|
| Qdrant query without `projectPublicId` filter | `QdrantService.search(projectPublicId, ...)` (ADR-023A) | Cross-project data leak via vector search |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚧 Out of Scope — Never Do Without Explicit Approval
|
||||||
|
|
||||||
|
| ❌ Never Do Autonomously | ⚠️ Why Approval Is Required |
|
||||||
|
| --------------------------------------------------------------- | ---------------------------------------------------------------- |
|
||||||
|
| `DROP` or `RENAME` a column / table | Irreversible data loss — requires DBA + PM sign-off |
|
||||||
|
| Push directly to `main` / `master` branch | Bypasses CI, code review, and release gates |
|
||||||
|
| Generate or insert seed data into production database | May corrupt live data or violate business state invariants |
|
||||||
|
| Delete files from permanent storage | Files may be referenced in active documents or audit trails |
|
||||||
|
| Modify RBAC permission matrix without security team approval | Defines access control for all users — security boundary change |
|
||||||
|
| Upgrade major library versions (NestJS, Next.js, TypeORM, etc.) | Breaking changes require full regression test cycle |
|
||||||
|
| Disable or modify authentication / authorization guards | Creates unguarded endpoints — immediate security risk |
|
||||||
|
| Change Redis lock TTL or disable Redlock | Risk of document number race condition (ADR-002) |
|
||||||
|
| Create or supersede an ADR unilaterally | Architecture decisions require team consensus and review process |
|
||||||
|
| Add new columns to production tables without schema review | Must update Data Dictionary + downstream queries simultaneously |
|
||||||
|
|||||||
@@ -9,9 +9,9 @@
|
|||||||
5. **Password:** bcrypt 12 salt rounds, min 8 chars, rotate every 90 days
|
5. **Password:** bcrypt 12 salt rounds, min 8 chars, rotate every 90 days
|
||||||
6. **Rate Limiting:** `ThrottlerGuard` on all auth endpoints
|
6. **Rate Limiting:** `ThrottlerGuard` on all auth endpoints
|
||||||
7. **File Upload:** Whitelist PDF/DWG/DOCX/XLSX/ZIP, max 50MB, ClamAV scan
|
7. **File Upload:** Whitelist PDF/DWG/DOCX/XLSX/ZIP, max 50MB, ClamAV scan
|
||||||
8. **AI Isolation (ADR-018):** Ollama on Admin Desktop ONLY — NO direct DB/storage access
|
8. **AI Isolation (ADR-023/023A):** Ollama on Admin Desktop ONLY — NO direct DB/storage access; 2-model stack `gemma4:e4b Q8_0` + `nomic-embed-text`; all inference via BullMQ (`ai-realtime` / `ai-batch`)
|
||||||
9. **Error Handling (ADR-007):** Use layered error classification with user-friendly messages
|
9. **Error Handling (ADR-007):** Use layered error classification with user-friendly messages
|
||||||
10. **AI Integration (ADR-020):** RFA-First approach with unified pipeline architecture
|
10. **AI Integration (ADR-023/023A):** RFA-First approach; n8n orchestrates Migration Phase only via DMS API — never calls Ollama directly; `QdrantService.search()` requires `projectPublicId` as mandatory param
|
||||||
11. **AI Audit Trail:** Log all AI interactions and human validations
|
11. **AI Audit Trail:** Log all AI interactions and human validations
|
||||||
12. **Rate Limiting:** Apply to AI endpoints to prevent abuse
|
12. **Rate Limiting:** Apply to AI endpoints to prevent abuse
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
- [ ] No SQL injection vulnerabilities
|
- [ ] No SQL injection vulnerabilities
|
||||||
- [ ] File upload validation (whitelist + ClamAV)
|
- [ ] File upload validation (whitelist + ClamAV)
|
||||||
- [ ] Rate limiting applied to auth endpoints
|
- [ ] Rate limiting applied to auth endpoints
|
||||||
- [ ] AI boundary enforcement (ADR-023) - no direct DB/storage access
|
- [ ] AI boundary enforcement (ADR-023/023A) - no direct DB/storage access
|
||||||
- [ ] AI audit logging implemented for AI interactions
|
- [ ] AI audit logging implemented for AI interactions
|
||||||
- [ ] AI outputs validated before use (human-in-the-loop)
|
- [ ] AI outputs validated before use (human-in-the-loop)
|
||||||
- [ ] Error handling follows ADR-007 layered classification
|
- [ ] Error handling follows ADR-007 layered classification
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# TypeScript Rules (v1.9.3)
|
# TypeScript Rules
|
||||||
|
|
||||||
## Core Standards
|
## Core Standards
|
||||||
|
|
||||||
|
|||||||
@@ -2,17 +2,17 @@
|
|||||||
|
|
||||||
## DMS Glossary
|
## DMS Glossary
|
||||||
|
|
||||||
| ✅ Use | ❌ Don't Use |
|
| ✅ Use | ❌ Don't Use | คำอธิบายเพิ่มเติม |
|
||||||
| ------------------ | ------------------------------------- |
|
| ------------------ | ------------------------------------- | ------------------------------------------------ |
|
||||||
| Correspondence | Letter, Communication, Document |
|
| Correspondence | Letter, Communication, Document | ครอบคลุมทุกประเภท: Letter, RFA, Memo, ฯลฯ |
|
||||||
| RFA | Approval Request, Submit for Approval |
|
| RFA | Approval Request, Submit for Approval | เอกสารขออนุมัติ (ชนิดหนึ่งของ Correspondence) |
|
||||||
| Transmittal | Delivery Note, Cover Letter |
|
| Transmittal | Delivery Note, Cover Letter | เอกสารนำส่ง (ชนิดหนึ่งของ Correspondence) |
|
||||||
| Circulation | Distribution, Routing |
|
| Circulation | Distribution, Routing | ใบเวียนเอกสารภายใน (ชนิดหนึ่งของ Correspondence) |
|
||||||
| Shop Drawing | Construction Drawing |
|
| Shop Drawing | Construction Drawing | แบบก่อสร้าง |
|
||||||
| Contract Drawing | Design Drawing, Blueprint |
|
| Contract Drawing | Design Drawing, Blueprint | แบบคู่สัญญา |
|
||||||
| Workflow Engine | Approval Flow, Process Engine |
|
| Workflow Engine | Approval Flow, Process Engine | เครื่องมือจัดการลำดับงาน |
|
||||||
| Document Numbering | Document ID, Auto Number |
|
| Document Numbering | Document ID, Auto Number | ระบบจัดการเลขที่เอกสาร |
|
||||||
| RBAC | Permission System (generic) |
|
| RBAC | Permission System (generic) | การควบคุมสิทธิ์ตามบทบาท |
|
||||||
|
|
||||||
## Full Glossary
|
## Full Glossary
|
||||||
|
|
||||||
@@ -23,13 +23,19 @@
|
|||||||
Spec priority: **`06-Decision-Records`** > **`05-Engineering-Guidelines`** > others
|
Spec priority: **`06-Decision-Records`** > **`05-Engineering-Guidelines`** > others
|
||||||
|
|
||||||
| Document | Path | Use When |
|
| Document | Path | Use When |
|
||||||
| ----------------------- | ----------------------------------------------------------------- | ------------------------------- |
|
| ------------------------------ | --------------------------------------------------------------------------- | --------------------------------- |
|
||||||
| **Glossary** | `specs/00-overview/00-02-glossary.md` | Verify domain terminology |
|
| **Glossary** | `specs/00-overview/00-02-glossary.md` | Verify domain terminology |
|
||||||
| **Schema Tables** | `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql` | Before writing any query |
|
| **Schema Tables** | `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql` | Before writing any query |
|
||||||
| **Data Dictionary** | `specs/03-Data-and-Storage/03-01-data-dictionary.md` | Field meanings + business rules |
|
| **Data Dictionary** | `specs/03-Data-and-Storage/03-01-data-dictionary.md` | Field meanings + business rules |
|
||||||
| **Edge Cases** | `specs/01-Requirements/01-06-edge-cases-and-rules.md` | Prevent bugs in flows |
|
| **Edge Cases** | `specs/01-Requirements/01-06-edge-cases-and-rules.md` | Prevent bugs in flows |
|
||||||
| **ADR-019 UUID** | `specs/06-Decision-Records/ADR-019-hybrid-identifier-strategy.md` | UUID-related work |
|
| **ADR-019 UUID** | `specs/06-Decision-Records/ADR-019-hybrid-identifier-strategy.md` | UUID-related work |
|
||||||
| **ADR-023 AI** | `specs/06-Decision-Records/ADR-023-unified-ai-architecture.md` | AI integration work |
|
| **ADR-023 AI** | `specs/06-Decision-Records/ADR-023-unified-ai-architecture.md` | AI integration work |
|
||||||
|
| **ADR-023A AI Model** | `specs/06-Decision-Records/ADR-023A-unified-ai-architecture.md` | 2-model stack, BullMQ 2-queue |
|
||||||
|
| **ADR-024 Intent Class.** | `specs/06-Decision-Records/ADR-024-intent-classification-strategy.md` | Pattern→LLM Fallback; Redis cache |
|
||||||
|
| **ADR-025 AI Tool Layer** | `specs/06-Decision-Records/ADR-025-ai-tool-layer-architecture.md` | Tool Registry; CASL-guarded |
|
||||||
|
| **ADR-026 Chat UI** | `specs/06-Decision-Records/ADR-026-document-chat-ui-pattern.md` | Side-panel; streaming SSE |
|
||||||
|
| **ADR-027 AI Admin Console** | `specs/06-Decision-Records/ADR-027-ai-admin-console-and-dynamic-control.md` | Dynamic control; admin-only |
|
||||||
|
| **ADR-028 Migration Refactor** | `specs/06-Decision-Records/ADR-028-migration-architecture-refactor.md` | Staging Queue; cleanup |
|
||||||
| **Backend Guidelines** | `specs/05-Engineering-Guidelines/05-02-backend-guidelines.md` | NestJS patterns |
|
| **Backend Guidelines** | `specs/05-Engineering-Guidelines/05-02-backend-guidelines.md` | NestJS patterns |
|
||||||
| **Frontend Guidelines** | `specs/05-Engineering-Guidelines/05-03-frontend-guidelines.md` | Next.js patterns |
|
| **Frontend Guidelines** | `specs/05-Engineering-Guidelines/05-03-frontend-guidelines.md` | Next.js patterns |
|
||||||
| **Testing Strategy** | `specs/05-Engineering-Guidelines/05-04-testing-strategy.md` | Coverage goals |
|
| **Testing Strategy** | `specs/05-Engineering-Guidelines/05-04-testing-strategy.md` | Coverage goals |
|
||||||
|
|||||||
@@ -2,25 +2,25 @@
|
|||||||
|
|
||||||
## ❌ Never Do This
|
## ❌ Never Do This
|
||||||
|
|
||||||
| ❌ Forbidden | ✅ Correct Approach |
|
| ❌ Forbidden | ✅ Correct Approach | ⚠️ Why |
|
||||||
| ----------------------------------------------- | ----------------------------------------------------------------- |
|
| ----------------------------------------------- | ------------------------------------------------------- | ---------------------------------------------------- |
|
||||||
| SQL Triggers for business logic | NestJS Service methods |
|
| SQL Triggers for business logic | NestJS Service methods | Untestable; bypasses audit log |
|
||||||
| `.env` files in production | `docker-compose.yml` environment section |
|
| `.env` files in production | `docker-compose.yml` environment section | Secrets exposed in version control |
|
||||||
| TypeORM migration files | Edit schema SQL directly (ADR-009) |
|
| TypeORM migration files | Edit schema SQL directly (ADR-009) | Migration drift risk; schema managed via SQL delta |
|
||||||
| Inventing table/column names | Verify against `lcbp3-v1.9.0-schema-02-tables.sql` |
|
| Inventing table/column names | Verify against `schema-02-tables.sql` | Schema mismatch causes silent runtime errors |
|
||||||
| `any` TypeScript type | Proper types / generics |
|
| `any` TypeScript type | Proper types / generics | Defeats strict mode; hides runtime type errors |
|
||||||
| `console.log` in committed code | NestJS Logger (backend) / remove (frontend) |
|
| `console.log` in committed code | NestJS Logger (backend) / remove (frontend) | Log flooding in production; risk of data leakage |
|
||||||
| `req: any` in controllers | `RequestWithUser` typed interface |
|
| `req: any` in controllers | `RequestWithUser` typed interface | Type safety lost; auth context unreachable |
|
||||||
| `parseInt()` on UUID values | Use UUID string directly (ADR-019) |
|
| `parseInt()` on UUID values | Use UUID string directly (ADR-019) | `"0195…"` parsed to integer `19` — silently wrong |
|
||||||
| Exposing INT PK in API responses | UUIDv7 (ADR-019) |
|
| Exposing INT PK in API responses | UUIDv7 `publicId` (ADR-019) | Leaks row count; enables DB enumeration attacks |
|
||||||
| AI accessing DB/storage directly | AI → DMS API → DB (ADR-023) |
|
| AI accessing DB/storage directly | AI → DMS API → DB (ADR-023/023A) | Bypasses RBAC, audit trail, and validation layer |
|
||||||
| Direct file operations bypassing StorageService | `StorageService` for all file moves |
|
| Direct file operations bypassing StorageService | `StorageService` for all file moves | Orphaned files; broken ClamAV scan; no audit trail |
|
||||||
| Inline email/notification sending | BullMQ queue job |
|
| Inline email/notification sending | BullMQ queue job (ADR-008) | Blocks request thread; no retry on transient failure |
|
||||||
| Deploying without Release Gates | Complete `04-08-release-management-policy.md` |
|
| Deploying without Release Gates | Complete `04-08-release-management-policy.md` | Unverified deploy risks data loss in production |
|
||||||
| AI direct cloud API calls | On-premises Ollama only (ADR-023) |
|
| AI direct cloud API calls | On-premises Ollama only (ADR-023/023A) | Data privacy violation; no audit control |
|
||||||
| AI outputs without human validation | Human-in-the-loop validation required (ADR-023) |
|
| AI outputs without human validation | Human-in-the-loop validation required (ADR-023/023A) | Unvalidated AI metadata corrupts document records |
|
||||||
| n8n calling Ollama/Qdrant directly | n8n → DMS API → BullMQ → Ollama/Qdrant (ADR-023A) |
|
| n8n calling Ollama/Qdrant directly | n8n → DMS API → BullMQ → Ollama (ADR-023A) | Bypasses audit log, RBAC, and error handling layer |
|
||||||
| Qdrant query without projectPublicId filter | QdrantService.search(projectPublicId: string) required (ADR-023A) |
|
| Qdrant query without `projectPublicId` filter | `QdrantService.search(projectPublicId, ...)` (ADR-023A) | Cross-project data leak via vector search |
|
||||||
|
|
||||||
## Schema Changes (ADR-009)
|
## Schema Changes (ADR-009)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
# Frontend Patterns (Next.js)
|
# Frontend Patterns (Next.js)
|
||||||
|
|
||||||
## Form Handling
|
## Form Handling
|
||||||
@@ -17,7 +16,7 @@ interface ProjectOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Select options
|
// Select options
|
||||||
const options = contracts.map(c => ({
|
const options = contracts.map((c) => ({
|
||||||
label: `${c.contractName} (${c.contractCode})`,
|
label: `${c.contractName} (${c.contractCode})`,
|
||||||
value: c.publicId!, // Use publicId, no fallback to id
|
value: c.publicId!, // Use publicId, no fallback to id
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
3. **Check schema** — verify table/column in `lcbp3-v1.9.0-schema-02-tables.sql`
|
3. **Check schema** — verify table/column in `lcbp3-v1.9.0-schema-02-tables.sql`
|
||||||
4. **Check data dictionary** — confirm field meanings + business rules
|
4. **Check data dictionary** — confirm field meanings + business rules
|
||||||
5. **Scan edge cases** — `01-06-edge-cases-and-rules.md`
|
5. **Scan edge cases** — `01-06-edge-cases-and-rules.md`
|
||||||
6. **Check ADRs** — verify decisions align (ADR-009, ADR-018, ADR-019)
|
6. **Check ADRs** — verify decisions align (ADR-009, ADR-019, ADR-023)
|
||||||
7. **Write code** — TypeScript strict, no `any`, no `console.log`
|
7. **Write code** — TypeScript strict, no `any`, no `console.log`
|
||||||
|
|
||||||
## 🟡 Normal Work — UI / Feature / Integration
|
## 🟡 Normal Work — UI / Feature / Integration
|
||||||
@@ -28,15 +28,87 @@
|
|||||||
- Add minimal test if logic changed
|
- Add minimal test if logic changed
|
||||||
- Check forbidden patterns before commit
|
- Check forbidden patterns before commit
|
||||||
|
|
||||||
|
### 🟢 Specialized Work — ADR-021, AI Runtime Layer, Complex Logic
|
||||||
|
|
||||||
|
**MUST complete:**
|
||||||
|
|
||||||
|
1. **Domain Knowledge Check** - Read relevant ADRs (ADR-021, ADR-023/023A, ADR-024~028)
|
||||||
|
2. **Pattern Verification** - Check existing implementations in codebase
|
||||||
|
3. **Specialized Requirements** - Follow domain-specific patterns
|
||||||
|
4. **Complex Logic Testing** - Multi-scenario test coverage
|
||||||
|
5. **Performance Validation** - Load testing if applicable
|
||||||
|
|
||||||
|
**For ADR-021 Integration:**
|
||||||
|
|
||||||
|
- Read ADR-021 - Integrated workflow & step attachments
|
||||||
|
- Check ADR-001 - Unified workflow engine patterns
|
||||||
|
- Verify WorkflowEngineService - Polymorphic instance handling
|
||||||
|
- Add workflow fields - Expose workflowInstanceId, workflowState, availableActions
|
||||||
|
- Include IntegratedBanner - Frontend workflow lifecycle display
|
||||||
|
- Test workflow transitions - State changes and action validation
|
||||||
|
|
||||||
|
**For AI Infrastructure (ADR-023/023A):**
|
||||||
|
|
||||||
|
- Verify AI boundary enforcement - No direct DB/storage access
|
||||||
|
- Check BullMQ 2-queue setup - ai-realtime + ai-batch
|
||||||
|
- Validate Qdrant multi-tenancy - projectPublicId filter required
|
||||||
|
- Test human-in-the-loop validation workflows
|
||||||
|
- Audit AI interaction logging to ai_audit_logs
|
||||||
|
|
||||||
|
**For AI Runtime Layer (ADR-024/025/026/027):**
|
||||||
|
|
||||||
|
- ADR-024: Pattern Layer first (ai_intent_patterns DB + Redis cache 5 min) → LLM Fallback (gemma4:e4b, semaphore max=3)
|
||||||
|
- ADR-025: Tool Registry dispatch — AI Gateway → Tool → Business Service; ToolResult DTO must use publicId only
|
||||||
|
- ADR-026: useAiChat() hook + side-panel UI; streaming response via SSE; TanStack Query cache
|
||||||
|
- ADR-027: Admin Console — dynamic model/prompt/intent control; CASL-guarded admin-only endpoints
|
||||||
|
|
||||||
|
**For Migration Pipeline (ADR-028):**
|
||||||
|
|
||||||
|
- Use Staging Queue pattern — never write directly to production tables
|
||||||
|
- Post-migration cleanup process required after each batch
|
||||||
|
- Migration Validation Gates must pass before promoting to production
|
||||||
|
|
||||||
|
**Expected output:**
|
||||||
|
|
||||||
|
- Backend services expose specialized context fields
|
||||||
|
- Frontend components use domain-specific patterns
|
||||||
|
- Complex state management with proper validation
|
||||||
|
- Performance metrics within acceptable thresholds
|
||||||
|
- Comprehensive test coverage for edge cases
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Context-Aware Triggers
|
## Context-Aware Triggers
|
||||||
|
|
||||||
| Request | Files to Check | Expected Response |
|
| Request | Files to Check | Expected Response |
|
||||||
| -------------------- | -------------------------------------------------------------------- | --------------------------------------------------- |
|
| --------------------------- | ------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
|
||||||
| "สร้าง API ใหม่" | `05-02-backend-guidelines.md`, `lcbp3-v1.9.0-schema-02-tables.sql` | NestJS Controller + Service + DTO + CASL Guard |
|
| "สร้าง API ใหม่" | `05-02-backend-guidelines.md`, `lcbp3-v1.9.0-schema-02-tables.sql` | NestJS Controller + Service + DTO + CASL Guard |
|
||||||
| "แก้ฟอร์ม frontend" | `05-03-frontend-guidelines.md`, `01-06-edge-cases.md` | RHF+Zod + TanStack Query + Thai comments |
|
| "แก้ฟอร์ม frontend" | `05-03-frontend-guidelines.md`, `01-06-edge-cases-and-rules.md` | RHF+Zod + TanStack Query + Thai comments |
|
||||||
| "เพิ่ม field ใหม่" | `ADR-009`, `data-dictionary.md`, `lcbp3-v1.9.0-schema-02-tables.sql` | Edit SQL directly + update Data Dictionary + Entity |
|
| "เพิ่ม field ใหม่" | `ADR-009`, `03-01-data-dictionary.md`, `lcbp3-v1.9.0-schema-02-tables.sql` | Edit SQL directly + update Data Dictionary + Entity |
|
||||||
| "ตรวจสอบ UUID" | `ADR-019`, `05-07-hybrid-uuid-implementation-plan.md` | UUIDv7 MariaDB native UUID + TransformInterceptor |
|
| "ตรวจสอบ UUID" | `ADR-019`, `05-07-hybrid-uuid-implementation-plan.md` | UUIDv7 MariaDB native UUID + TransformInterceptor |
|
||||||
| "สร้าง migration" | `ADR-009`, `03-06-migration-business-scope.md` | Edit SQL schema directly + n8n workflow |
|
| "สร้าง migration" | `ADR-009`, `03-06-migration-business-scope.md` | Edit SQL schema directly + n8n workflow |
|
||||||
| "ตรวจสอบ permission" | `seed-permissions.sql`, `ADR-016` | CASL 4-Level RBAC matrix |
|
| "ตรวจสอบ permission" | `lcbp3-v1.9.0-seed-permissions.sql`, `ADR-016` | CASL 4-Level RBAC matrix |
|
||||||
| "deploy production" | `04-08-release-management-policy.md`, `ADR-015` | Release Gates + Blue-Green strategy |
|
| "deploy production" | `04-08-release-management-policy.md`, `ADR-015` | Release Gates + Blue-Green strategy |
|
||||||
| "เพิ่ม test" | `05-04-testing-strategy.md` | Coverage goals + test patterns |
|
| "เพิ่ม test" | `05-04-testing-strategy.md` | Coverage goals + test patterns |
|
||||||
|
| "AI integration" | `ADR-023`, `ADR-023A`, `ADR-024`, `ADR-025` | AI boundary + 2-model stack + BullMQ queue policy + Intent/Tool Layer |
|
||||||
|
| "Error handling" | `ADR-007` | Layered error classification + recovery |
|
||||||
|
| "File upload" | `ADR-016`, `05-02-backend-guidelines.md`, `03-Data-and-Storage/03-03-file-storage.md` | Two-phase upload → temp → commit; ClamAV + whitelist |
|
||||||
|
| "Notifications / Queue" | `ADR-008`, `05-02-backend-guidelines.md` | BullMQ job — never inline; check retry + dead-letter |
|
||||||
|
| "Add i18n / translate" | `05-08-i18n-guidelines.md` | i18n keys only — no hardcoded text |
|
||||||
|
| "Workflow / DSL" | `ADR-001`, `01-03-modules/01-03-06-unified-workflow.md` | DSL state machine + WorkflowEngineService |
|
||||||
|
| "Document numbering" | `ADR-002`, `01-02-business-rules/01-02-02-doc-numbering-rules.md` | Redis Redlock + DB optimistic lock (double-lock) |
|
||||||
|
| "ตรวจสอบ Workflow" | `01-06-edge-cases-and-rules.md`, `05-02-backend-guidelines.md`, `ADR-001`, `ADR-002` | เช็คการเปลี่ยน State, คิว BullMQ และการล็อกเลขที่เอกสาร |
|
||||||
|
| "Transmittal submit" | `ADR-021`, `specs/200-fullstacks/201-transmittals-circulation/` | submit() with EC-RFA-004 validation |
|
||||||
|
| "Circulation reassign" | `ADR-021`, `specs/200-fullstacks/201-transmittals-circulation/` | reassignRouting() with EC-CIRC-001 |
|
||||||
|
| "สร้าง workflow ใหม่" | `ADR-001`, `ADR-021`, `specs/200-fullstacks/203-unified-workflow-engine/` | DSL workflow definition + WorkflowEngineService setup |
|
||||||
|
| "ตรวจสอบ AI boundary" | `ADR-023`, `ADR-023A` | Verify Ollama isolation + BullMQ queues + Qdrant projectPublicId filter |
|
||||||
|
| "Intent classification" | `ADR-024`, `specs/200-fullstacks/224-intent-classification/` | Pattern Layer → LLM Fallback; ai_intent_patterns; Redis cache 5 min |
|
||||||
|
| "AI Tool Layer" | `ADR-025`, `specs/200-fullstacks/225-ai-tool-layer-architecture/` | Tool Registry; CASL-guarded dispatch; ToolResult publicId only |
|
||||||
|
| "Document Chat UI" | `ADR-026`, `specs/200-fullstacks/226-document-chat-ui-pattern/` | Side-panel; useAiChat() hook; streaming SSE; TanStack Query cache |
|
||||||
|
| "AI Admin Console" | `ADR-027`, `specs/200-fullstacks/227-ai-admin-console/` | Dynamic model/prompt/intent control; admin-only CASL endpoints |
|
||||||
|
| "Migration refactor" | `ADR-028`, `specs/200-fullstacks/228-migration-arch-refactor/` | Staging Queue; post-migration cleanup; validation gates |
|
||||||
|
| "จัดการ document numbering" | `ADR-002`, `specs/03-Data-and-Storage/03-04-document-numbering.md` | Redis Redlock + template system + preview/override workflows |
|
||||||
|
| "Audit ความปลอดภัย" | `ADR-016`, `ADR-019`, `ADR-023`, `ADR-023A` | ตรวจสอบ UUID pattern, CASL Guard, AI Boundary และ Qdrant multi-tenancy |
|
||||||
|
| "แก้ bug / bugfix" | `.agents/workflows/bugfix.md`, `error-catalog.md` | ใช้ bugfix workflow สำหรับเคสที่สาเหตุชัดเจน |
|
||||||
|
| "ตรวจแอปจริง" | `.windsurf/workflows/check-real-app.md` | ตรวจ endpoint/UI/console หลัง build pass — No Fake Evidence |
|
||||||
|
| "งานค้าง / resume" | `.windsurf/workflows/resume-pending-work.md` | อ่าน checkpoint เดิม → ตรวจ build → วางแผนต่อโดยไม่ทำงานซ้ำ |
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
# Commit Checklist
|
# Commit Checklist
|
||||||
|
|
||||||
## Pre-Commit Verification
|
## Pre-Commit Verification
|
||||||
@@ -28,6 +27,7 @@ type(scope): description
|
|||||||
Types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`
|
Types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
- `feat(correspondence): add originator organization validation`
|
- `feat(correspondence): add originator organization validation`
|
||||||
- `fix(uuid): correct parseInt usage to string comparison`
|
- `fix(uuid): correct parseInt usage to string comparison`
|
||||||
- `spec(agents): bump to v1.8.5 - refactor structure`
|
- `spec(agents): bump to v1.8.5 - refactor structure`
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
# ADR-007 Error Handling Strategy
|
# ADR-007 Error Handling Strategy
|
||||||
|
|
||||||
## CRITICAL RULES
|
## CRITICAL RULES
|
||||||
@@ -12,7 +11,7 @@
|
|||||||
## Error Classification
|
## Error Classification
|
||||||
|
|
||||||
| Error Type | Description | User Message | Technical Log |
|
| Error Type | Description | User Message | Technical Log |
|
||||||
|------------|-------------|--------------|---------------|
|
| -------------- | ------------------------- | ------------------------ | -------------------------- |
|
||||||
| **Validation** | Input validation failures | Clear field-level errors | Full validation details |
|
| **Validation** | Input validation failures | Clear field-level errors | Full validation details |
|
||||||
| **Business** | Business rule violations | Actionable guidance | Business context + user ID |
|
| **Business** | Business rule violations | Actionable guidance | Business context + user ID |
|
||||||
| **System** | Infrastructure failures | Generic "try again" | Full stack trace + metrics |
|
| **System** | Infrastructure failures | Generic "try again" | Full stack trace + metrics |
|
||||||
@@ -22,12 +21,7 @@
|
|||||||
```typescript
|
```typescript
|
||||||
// Custom Exception Hierarchy
|
// Custom Exception Hierarchy
|
||||||
export class BusinessException extends HttpException {
|
export class BusinessException extends HttpException {
|
||||||
constructor(
|
constructor(message: string, userMessage: string, recoveryAction?: string, errorCode?: string) {
|
||||||
message: string,
|
|
||||||
userMessage: string,
|
|
||||||
recoveryAction?: string,
|
|
||||||
errorCode?: string
|
|
||||||
) {
|
|
||||||
super({ message, userMessage, recoveryAction, errorCode }, 400);
|
super({ message, userMessage, recoveryAction, errorCode }, 400);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
## CRITICAL RULES
|
## CRITICAL RULES
|
||||||
|
|
||||||
- **ALWAYS** follow ADR-023 AI boundary policy (isolation on Admin Desktop)
|
- **ALWAYS** follow ADR-023 AI boundary policy (isolation on Admin Desktop)
|
||||||
- **ALWAYS** use ADR-023A 2-model stack (gemma4:e4b Q8_0 + nomic-embed-text)
|
- **ALWAYS** use ADR-034 model stack (typhoon2.5-np-dms:latest + typhoon-np-dms-ocr:latest + nomic-embed-text)
|
||||||
- **ALWAYS** use BullMQ 2-queue (ai-realtime + ai-batch) for GPU overload prevention
|
- **ALWAYS** use BullMQ 2-queue (ai-realtime + ai-batch) for GPU overload prevention
|
||||||
- **NEVER** allow AI direct database/storage access
|
- **NEVER** allow AI direct database/storage access
|
||||||
- **ALWAYS** implement human-in-the-loop validation
|
- **ALWAYS** implement human-in-the-loop validation
|
||||||
@@ -26,7 +26,7 @@ n8n (Migration) → DMS API → BullMQ → Admin Desktop (Ollama) → Backend Va
|
|||||||
| ----------------- | ------------------------- | ------------------------------------------------------------------------ |
|
| ----------------- | ------------------------- | ------------------------------------------------------------------------ |
|
||||||
| **AI Gateway** | Backend (NestJS) | API endpoints, validation, audit logging |
|
| **AI Gateway** | Backend (NestJS) | API endpoints, validation, audit logging |
|
||||||
| **BullMQ Queues** | Backend (NestJS) | ai-realtime (RAG/Suggest), ai-batch (OCR/Extract/Embed) |
|
| **BullMQ Queues** | Backend (NestJS) | ai-realtime (RAG/Suggest), ai-batch (OCR/Extract/Embed) |
|
||||||
| **Ollama Engine** | Admin Desktop (Desk-5439) | gemma4:e4b Q8_0 (LLM) + nomic-embed-text (Embedding) |
|
| **Ollama Engine** | Admin Desktop (Desk-5439) | typhoon2.5-np-dms:latest (Main LLM) + typhoon-np-dms-ocr:latest (OCR, keep_alive:0) + nomic-embed-text (Embedding) |
|
||||||
| **OCR Engine** | Admin Desktop (Desk-5439) | PaddleOCR + PyThaiNLP (Thai/English text extraction) |
|
| **OCR Engine** | Admin Desktop (Desk-5439) | PaddleOCR + PyThaiNLP (Thai/English text extraction) |
|
||||||
| **Orchestrator** | QNAP NAS (n8n) | Migration Phase orchestrator only (calls DMS API, never Ollama directly) |
|
| **Orchestrator** | QNAP NAS (n8n) | Migration Phase orchestrator only (calls DMS API, never Ollama directly) |
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ export class AiService {
|
|||||||
async extractMetadata(documentId: string): Promise<AIMetadata> {
|
async extractMetadata(documentId: string): Promise<AIMetadata> {
|
||||||
// 1. Validate permissions
|
// 1. Validate permissions
|
||||||
// 2. Queue job to BullMQ (ai-batch or ai-realtime)
|
// 2. Queue job to BullMQ (ai-batch or ai-realtime)
|
||||||
// 3. Worker sends to Admin Desktop AI (gemma4:e4b Q8_0)
|
// 3. Worker sends to Admin Desktop AI (typhoon2.5-np-dms:latest)
|
||||||
// 4. Validate AI response
|
// 4. Validate AI response
|
||||||
// 5. Log audit trail to ai_audit_logs
|
// 5. Log audit trail to ai_audit_logs
|
||||||
// 6. Return validated results
|
// 6. Return validated results
|
||||||
@@ -113,9 +113,9 @@ const DocumentReviewForm = ({ document, aiSuggestions }) => {
|
|||||||
- **n8n Boundary:** n8n MUST call DMS API → BullMQ, NEVER Ollama/Qdrant directly
|
- **n8n Boundary:** n8n MUST call DMS API → BullMQ, NEVER Ollama/Qdrant directly
|
||||||
- **GPU Overload Prevention:** BullMQ 2-queue (ai-realtime + ai-batch) with concurrency=1
|
- **GPU Overload Prevention:** BullMQ 2-queue (ai-realtime + ai-batch) with concurrency=1
|
||||||
|
|
||||||
## ADR-023A Specific Rules
|
## ADR-034 Model Stack (supersedes ADR-023A §2.1)
|
||||||
|
|
||||||
- **2-Model Stack:** gemma4:e4b Q8_0 (~4.0GB) + nomic-embed-text (~0.3GB) = ~4.3GB VRAM peak
|
- **3-Model Config:** typhoon2.5-np-dms:latest (Main) + typhoon-np-dms-ocr:latest (OCR, keep_alive:0) + nomic-embed-text (Embedding)
|
||||||
- **PDF 3-Page Limit:** Classification/Tagging uses first 3 pages only (NOT RAG embedding)
|
- **PDF 3-Page Limit:** Classification/Tagging uses first 3 pages only (NOT RAG embedding)
|
||||||
- **RAG Embedding:** Full document chunked at 512 tokens/64 tokens overlap
|
- **RAG Embedding:** Full document chunked at 512 tokens/64 tokens overlap
|
||||||
- **OCR Auto-Detect:** PyMuPDF chars > 100 → Fast path, else PaddleOCR
|
- **OCR Auto-Detect:** PyMuPDF chars > 100 → Fast path, else PaddleOCR
|
||||||
@@ -129,7 +129,7 @@ const DocumentReviewForm = ({ document, aiSuggestions }) => {
|
|||||||
- [ ] BullMQ 2-queue setup (ai-realtime + ai-batch)
|
- [ ] BullMQ 2-queue setup (ai-realtime + ai-batch)
|
||||||
- [ ] QdrantService with projectPublicId enforcement
|
- [ ] QdrantService with projectPublicId enforcement
|
||||||
- [ ] DocumentReviewForm reusable component
|
- [ ] DocumentReviewForm reusable component
|
||||||
- [ ] Admin Desktop Ollama (gemma4:e4b Q8_0 + nomic-embed-text) + PaddleOCR setup
|
- [ ] Admin Desktop Ollama (typhoon2.5-np-dms:latest + typhoon-np-dms-ocr:latest + nomic-embed-text) setup
|
||||||
- [ ] n8n workflow orchestration (Migration Phase only)
|
- [ ] n8n workflow orchestration (Migration Phase only)
|
||||||
- [ ] AI audit logging and monitoring (ai_audit_logs)
|
- [ ] AI audit logging and monitoring (ai_audit_logs)
|
||||||
- [ ] Human-in-the-loop validation workflows
|
- [ ] Human-in-the-loop validation workflows
|
||||||
@@ -138,3 +138,8 @@ const DocumentReviewForm = ({ document, aiSuggestions }) => {
|
|||||||
|
|
||||||
- `specs/06-Decision-Records/ADR-023-unified-ai-architecture.md` (Base architecture)
|
- `specs/06-Decision-Records/ADR-023-unified-ai-architecture.md` (Base architecture)
|
||||||
- `specs/06-Decision-Records/ADR-023A-unified-ai-architecture.md` (Model revision - current)
|
- `specs/06-Decision-Records/ADR-023A-unified-ai-architecture.md` (Model revision - current)
|
||||||
|
- `specs/06-Decision-Records/ADR-024-intent-classification-strategy.md` (Pattern→LLM Fallback)
|
||||||
|
- `specs/06-Decision-Records/ADR-025-ai-tool-layer-architecture.md` (Tool Registry)
|
||||||
|
- `specs/06-Decision-Records/ADR-026-document-chat-ui-pattern.md` (Chat UI)
|
||||||
|
- `specs/06-Decision-Records/ADR-027-ai-admin-console-and-dynamic-control.md` (Admin Console)
|
||||||
|
- `specs/06-Decision-Records/ADR-028-migration-architecture-refactor.md` (Migration Pipeline)
|
||||||
|
|||||||
+33
-11
@@ -4,13 +4,14 @@ Critical rules and guidelines for AI agents working on LCBP3-DMS.
|
|||||||
|
|
||||||
## Version
|
## Version
|
||||||
|
|
||||||
- **Current:** v1.9.3
|
- **Current:** v1.9.6
|
||||||
- **Last Updated:** 2026-05-15
|
- **Last Updated:** 2026-05-22
|
||||||
- **Synced with:** `AGENTS.md` (v1.9.3)
|
- **Synced with:** `AGENTS.md` (v1.9.6)
|
||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
|
|
||||||
This directory contains rule files that define:
|
This directory contains rule files that define:
|
||||||
|
|
||||||
- Project context and role expectations
|
- Project context and role expectations
|
||||||
- Critical Tier 1 rules (CI blockers)
|
- Critical Tier 1 rules (CI blockers)
|
||||||
- Coding standards and patterns
|
- Coding standards and patterns
|
||||||
@@ -24,6 +25,7 @@ This directory contains rule files that define:
|
|||||||
### 🔴 Tier 1 — CRITICAL (CI BLOCKER)
|
### 🔴 Tier 1 — CRITICAL (CI BLOCKER)
|
||||||
|
|
||||||
Build fails immediately if violated:
|
Build fails immediately if violated:
|
||||||
|
|
||||||
- Security (Auth, RBAC, Validation)
|
- Security (Auth, RBAC, Validation)
|
||||||
- UUID Strategy (ADR-019) — no `parseInt` / `Number` / `+` on UUID
|
- UUID Strategy (ADR-019) — no `parseInt` / `Number` / `+` on UUID
|
||||||
- Database correctness — verify schema before writing queries
|
- Database correctness — verify schema before writing queries
|
||||||
@@ -35,15 +37,28 @@ Build fails immediately if violated:
|
|||||||
### 🟡 Tier 2 — IMPORTANT (CODE REVIEW)
|
### 🟡 Tier 2 — IMPORTANT (CODE REVIEW)
|
||||||
|
|
||||||
Must fix before merge:
|
Must fix before merge:
|
||||||
|
|
||||||
- Architecture patterns (thin controller, business logic in service)
|
- Architecture patterns (thin controller, business logic in service)
|
||||||
- Test coverage (80%+ business logic, 70%+ backend overall)
|
- Test coverage (80%+ business logic, 70%+ backend overall)
|
||||||
- Cache invalidation
|
- Cache invalidation
|
||||||
- Naming conventions
|
- Naming conventions
|
||||||
- TypeScript Standards: Missing JSDoc, explicit types, or file headers
|
- TypeScript Standards: Missing JSDoc, explicit types, or file headers
|
||||||
|
|
||||||
### 🟢 Tier 3 — GUIDELINES
|
### 🟢 Tier 3 — SPECIALIZED WORK
|
||||||
|
|
||||||
|
Requires domain-specific knowledge:
|
||||||
|
|
||||||
|
- **ADR-021 Integration:** Workflow Engine & Context implementation
|
||||||
|
- **AI Infrastructure:** ADR-023/023A boundary enforcement and pipeline usage
|
||||||
|
- **AI Runtime Layer:** ADR-024 Intent Classification, ADR-025 Tool Layer, ADR-026 Chat UI, ADR-027 Admin Console
|
||||||
|
- **Migration Pipeline:** ADR-028 Staging Queue & post-migration cleanup
|
||||||
|
- **Complex Business Logic:** Multi-step workflows with state management
|
||||||
|
- **Performance Optimization:** Database queries, caching strategies, bulk operations
|
||||||
|
|
||||||
|
### 🔵 Tier 4 — GUIDELINES
|
||||||
|
|
||||||
Best practice — follow when possible:
|
Best practice — follow when possible:
|
||||||
|
|
||||||
- Code style / formatting (Prettier handles)
|
- Code style / formatting (Prettier handles)
|
||||||
- Comment completeness
|
- Comment completeness
|
||||||
- Minor optimizations
|
- Minor optimizations
|
||||||
@@ -53,7 +68,7 @@ Best practice — follow when possible:
|
|||||||
### Core Rules (Tier 1 - CRITICAL)
|
### Core Rules (Tier 1 - CRITICAL)
|
||||||
|
|
||||||
| File | Purpose |
|
| File | Purpose |
|
||||||
|------|---------|
|
| ----------------------- | ------------------------------------------------------------------------------- |
|
||||||
| `00-project-context.md` | Project context, role & persona, tier classification, specs folder organization |
|
| `00-project-context.md` | Project context, role & persona, tier classification, specs folder organization |
|
||||||
| `01-adr-019-uuid.md` | UUID handling strategy — no parseInt, use publicId only |
|
| `01-adr-019-uuid.md` | UUID handling strategy — no parseInt, use publicId only |
|
||||||
| `02-security.md` | Security requirements, checklist, ADR-023/023A AI boundaries |
|
| `02-security.md` | Security requirements, checklist, ADR-023/023A AI boundaries |
|
||||||
@@ -61,7 +76,7 @@ Best practice — follow when possible:
|
|||||||
### Coding Standards
|
### Coding Standards
|
||||||
|
|
||||||
| File | Purpose |
|
| File | Purpose |
|
||||||
|------|---------|
|
| ------------------------- | ------------------------------------------------------- |
|
||||||
| `03-typescript.md` | TypeScript rules, file headers, i18n guidelines |
|
| `03-typescript.md` | TypeScript rules, file headers, i18n guidelines |
|
||||||
| `06-backend-patterns.md` | NestJS patterns, UUID resolution, API response patterns |
|
| `06-backend-patterns.md` | NestJS patterns, UUID resolution, API response patterns |
|
||||||
| `07-frontend-patterns.md` | Next.js patterns, RHF+Zod+TanStack Query, UUID handling |
|
| `07-frontend-patterns.md` | Next.js patterns, RHF+Zod+TanStack Query, UUID handling |
|
||||||
@@ -69,14 +84,14 @@ Best practice — follow when possible:
|
|||||||
### Domain & Workflow
|
### Domain & Workflow
|
||||||
|
|
||||||
| File | Purpose |
|
| File | Purpose |
|
||||||
|------|---------|
|
| -------------------------- | ------------------------------------------------------------- |
|
||||||
| `04-domain-terminology.md` | DMS glossary, key spec files priority table |
|
| `04-domain-terminology.md` | DMS glossary, key spec files priority table |
|
||||||
| `08-development-flow.md` | Development workflow by work type (Critical/Normal/Quick Fix) |
|
| `08-development-flow.md` | Development workflow by work type (Critical/Normal/Quick Fix) |
|
||||||
|
|
||||||
### Compliance & Architecture
|
### Compliance & Architecture
|
||||||
|
|
||||||
| File | Purpose |
|
| File | Purpose |
|
||||||
|------|---------|
|
| ------------------------- | -------------------------------------------------------------- |
|
||||||
| `05-forbidden-actions.md` | Actions that must never be done, schema changes, UUID handling |
|
| `05-forbidden-actions.md` | Actions that must never be done, schema changes, UUID handling |
|
||||||
| `09-commit-checklist.md` | Pre-commit verification, commit message format |
|
| `09-commit-checklist.md` | Pre-commit verification, commit message format |
|
||||||
| `10-error-handling.md` | ADR-007 error handling strategy, layered classification |
|
| `10-error-handling.md` | ADR-007 error handling strategy, layered classification |
|
||||||
@@ -87,13 +102,19 @@ Best practice — follow when possible:
|
|||||||
Spec priority: **`06-Decision-Records`** > **`05-Engineering-Guidelines`** > others
|
Spec priority: **`06-Decision-Records`** > **`05-Engineering-Guidelines`** > others
|
||||||
|
|
||||||
| Document | Path | Use When |
|
| Document | Path | Use When |
|
||||||
|----------|------|----------|
|
| ------------------------------ | --------------------------------------------------------------------------- | --------------------------------- |
|
||||||
| **Glossary** | `specs/00-overview/00-02-glossary.md` | Verify domain terminology |
|
| **Glossary** | `specs/00-overview/00-02-glossary.md` | Verify domain terminology |
|
||||||
| **Schema Tables** | `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql` | Before writing any query |
|
| **Schema Tables** | `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql` | Before writing any query |
|
||||||
| **Data Dictionary** | `specs/03-Data-and-Storage/03-01-data-dictionary.md` | Field meanings + business rules |
|
| **Data Dictionary** | `specs/03-Data-and-Storage/03-01-data-dictionary.md` | Field meanings + business rules |
|
||||||
| **Edge Cases** | `specs/01-Requirements/01-06-edge-cases-and-rules.md` | Prevent bugs in flows |
|
| **Edge Cases** | `specs/01-Requirements/01-06-edge-cases-and-rules.md` | Prevent bugs in flows |
|
||||||
| **ADR-019 UUID** | `specs/06-Decision-Records/ADR-019-hybrid-identifier-strategy.md` | UUID-related work |
|
| **ADR-019 UUID** | `specs/06-Decision-Records/ADR-019-hybrid-identifier-strategy.md` | UUID-related work |
|
||||||
| **ADR-023 AI** | `specs/06-Decision-Records/ADR-023-unified-ai-architecture.md` | AI integration work |
|
| **ADR-023 AI** | `specs/06-Decision-Records/ADR-023-unified-ai-architecture.md` | AI integration work |
|
||||||
|
| **ADR-023A AI Model** | `specs/06-Decision-Records/ADR-023A-unified-ai-architecture.md` | 2-model stack, BullMQ 2-queue |
|
||||||
|
| **ADR-024 Intent Class.** | `specs/06-Decision-Records/ADR-024-intent-classification-strategy.md` | Pattern→LLM Fallback; Redis cache |
|
||||||
|
| **ADR-025 AI Tool Layer** | `specs/06-Decision-Records/ADR-025-ai-tool-layer-architecture.md` | Tool Registry; CASL-guarded |
|
||||||
|
| **ADR-026 Chat UI** | `specs/06-Decision-Records/ADR-026-document-chat-ui-pattern.md` | Side-panel; streaming SSE |
|
||||||
|
| **ADR-027 AI Admin Console** | `specs/06-Decision-Records/ADR-027-ai-admin-console-and-dynamic-control.md` | Dynamic control; admin-only |
|
||||||
|
| **ADR-028 Migration Refactor** | `specs/06-Decision-Records/ADR-028-migration-architecture-refactor.md` | Staging Queue; cleanup |
|
||||||
| **Backend Guidelines** | `specs/05-Engineering-Guidelines/05-02-backend-guidelines.md` | NestJS patterns |
|
| **Backend Guidelines** | `specs/05-Engineering-Guidelines/05-02-backend-guidelines.md` | NestJS patterns |
|
||||||
| **Frontend Guidelines** | `specs/05-Engineering-Guidelines/05-03-frontend-guidelines.md` | Next.js patterns |
|
| **Frontend Guidelines** | `specs/05-Engineering-Guidelines/05-03-frontend-guidelines.md` | Next.js patterns |
|
||||||
| **Testing Strategy** | `specs/05-Engineering-Guidelines/05-04-testing-strategy.md` | Coverage goals |
|
| **Testing Strategy** | `specs/05-Engineering-Guidelines/05-04-testing-strategy.md` | Coverage goals |
|
||||||
@@ -103,10 +124,11 @@ Spec priority: **`06-Decision-Records`** > **`05-Engineering-Guidelines`** > oth
|
|||||||
When updating rules:
|
When updating rules:
|
||||||
|
|
||||||
1. **Check AGENTS.md version** — Ensure rule files are synced
|
1. **Check AGENTS.md version** — Ensure rule files are synced
|
||||||
2. **Update version numbers** — Bump version in `00-project-context.md` and `03-typescript.md`
|
2. **Update version numbers** — Bump version in `00-project-context.md` only (03-typescript.md no longer has version)
|
||||||
3. **Review ADR references** — Ensure all ADR references are current (ADR-023, ADR-023A, etc.)
|
3. **Review ADR references** — Ensure all ADR references are current (ADR-023, ADR-023A, ADR-024~028)
|
||||||
4. **Add new forbidden actions** — When new patterns are identified as violations
|
4. **Add new forbidden actions** — When new patterns are identified as violations
|
||||||
5. **Update key spec files table** — When new ADRs or guidelines are added
|
5. **Update key spec files table** — When new ADRs or guidelines are added
|
||||||
|
6. **Update Tier 3 SPECIALIZED WORK** — When new domain-specific workflows are added
|
||||||
|
|
||||||
## Related Documents
|
## Related Documents
|
||||||
|
|
||||||
|
|||||||
@@ -5,14 +5,14 @@
|
|||||||
|
|
||||||
**Project:** NAP-DMS (LCBP3) — Laem Chabang Port Phase 3 Document Management System
|
**Project:** NAP-DMS (LCBP3) — Laem Chabang Port Phase 3 Document Management System
|
||||||
**Stack:** NestJS 11 + Next.js 16 + TypeScript + MariaDB 11.8 + Redis + BullMQ + Elasticsearch + Ollama (on-prem AI)
|
**Stack:** NestJS 11 + Next.js 16 + TypeScript + MariaDB 11.8 + Redis + BullMQ + Elasticsearch + Ollama (on-prem AI)
|
||||||
**Version:** 1.8.9 (2026-04-18)
|
**Version:** 1.9.7 (2026-05-25)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📌 Canonical Rule Sources (read in this order)
|
## 📌 Canonical Rule Sources (read in this order)
|
||||||
|
|
||||||
1. **`AGENTS.md`** (repo root) — primary rule file for AI agents; supersedes legacy `GEMINI.md`.
|
1. **`AGENTS.md`** (repo root) — primary rule file for AI agents; supersedes legacy `GEMINI.md`.
|
||||||
2. **`specs/06-Decision-Records/`** — architectural decisions (22 ADRs); ADR priority > Engineering Guidelines.
|
2. **`specs/06-Decision-Records/`** — architectural decisions (29 ADRs); ADR priority > Engineering Guidelines.
|
||||||
3. **`specs/05-Engineering-Guidelines/`** — backend/frontend/testing/i18n/git patterns.
|
3. **`specs/05-Engineering-Guidelines/`** — backend/frontend/testing/i18n/git patterns.
|
||||||
4. **`specs/00-Overview/00-02-glossary.md`** — domain terminology (Correspondence / RFA / Transmittal / Circulation).
|
4. **`specs/00-Overview/00-02-glossary.md`** — domain terminology (Correspondence / RFA / Transmittal / Circulation).
|
||||||
5. **`specs/00-Overview/00-03-product-vision.md`** — project constitution (Vision, Strategic Pillars, Guardrails).
|
5. **`specs/00-Overview/00-03-product-vision.md`** — project constitution (Vision, Strategic Pillars, Guardrails).
|
||||||
@@ -29,6 +29,7 @@
|
|||||||
- **ADR-002 Document Numbering:** Redis Redlock + TypeORM `@VersionColumn` (double-lock). Never use application-side counter alone.
|
- **ADR-002 Document Numbering:** Redis Redlock + TypeORM `@VersionColumn` (double-lock). Never use application-side counter alone.
|
||||||
- **ADR-008 Notifications:** BullMQ queue — never inline email/notification in a request thread.
|
- **ADR-008 Notifications:** BullMQ queue — never inline email/notification in a request thread.
|
||||||
- **ADR-023/023A AI Boundary:** Ollama on Admin Desktop only; AI → DMS API → DB (never direct DB/storage). 2-model stack: `gemma4:e4b Q8_0` + `nomic-embed-text`. BullMQ `ai-realtime` / `ai-batch` queues. Human-in-the-loop validation required. (ADR-018 superseded by ADR-023)
|
- **ADR-023/023A AI Boundary:** Ollama on Admin Desktop only; AI → DMS API → DB (never direct DB/storage). 2-model stack: `gemma4:e4b Q8_0` + `nomic-embed-text`. BullMQ `ai-realtime` / `ai-batch` queues. Human-in-the-loop validation required. (ADR-018 superseded by ADR-023)
|
||||||
|
- **ADR-029 Dynamic Prompt Management:** Prompt templates in DB (`ai_prompts`), never hardcoded in processor; Redis cache `ai:prompt:active:{type}` TTL 60s; `activate()` runs in DB transaction + Redis DEL after commit; `system.manage_all` guard on all mutations.
|
||||||
- **ADR-007 Error Handling:** Layered (Validation / Business / System); `BusinessException` hierarchy; user-friendly `userMessage` + `recoveryAction`; technical stack only in logs.
|
- **ADR-007 Error Handling:** Layered (Validation / Business / System); `BusinessException` hierarchy; user-friendly `userMessage` + `recoveryAction`; technical stack only in logs.
|
||||||
- **TypeScript Strict:** Zero `any`, zero `console.log` (use NestJS `Logger`).
|
- **TypeScript Strict:** Zero `any`, zero `console.log` (use NestJS `Logger`).
|
||||||
- **i18n:** No hardcoded Thai/English strings in components — use i18n keys (see `05-08-i18n-guidelines.md`).
|
- **i18n:** No hardcoded Thai/English strings in components — use i18n keys (see `05-08-i18n-guidelines.md`).
|
||||||
@@ -54,7 +55,7 @@
|
|||||||
## 📁 Key Files for Generating / Validating Artifacts
|
## 📁 Key Files for Generating / Validating Artifacts
|
||||||
|
|
||||||
| When you need... | Read |
|
| When you need... | Read |
|
||||||
| ------------------------- | ------------------------------------------------------------------------------------------------------------------- |
|
| -------------------------- | ------------------------------------------------------------------------------------------------------------------- |
|
||||||
| A new feature spec | `.agents/skills/speckit-specify/templates/spec-template.md` + `specs/01-Requirements/01-06-edge-cases-and-rules.md` |
|
| A new feature spec | `.agents/skills/speckit-specify/templates/spec-template.md` + `specs/01-Requirements/01-06-edge-cases-and-rules.md` |
|
||||||
| A plan | `.agents/skills/speckit-plan/templates/plan-template.md` + relevant ADRs |
|
| A plan | `.agents/skills/speckit-plan/templates/plan-template.md` + relevant ADRs |
|
||||||
| Task breakdown | `.agents/skills/speckit-tasks/templates/tasks-template.md` + existing patterns in `specs/08-Tasks/` |
|
| Task breakdown | `.agents/skills/speckit-tasks/templates/tasks-template.md` + existing patterns in `specs/08-Tasks/` |
|
||||||
@@ -62,6 +63,12 @@
|
|||||||
| Schema / table definition | `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql` + `03-01-data-dictionary.md` |
|
| Schema / table definition | `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql` + `03-01-data-dictionary.md` |
|
||||||
| RBAC / permissions | `specs/03-Data-and-Storage/lcbp3-v1.8.0-seed-permissions.sql` + `01-02-01-rbac-matrix.md` |
|
| RBAC / permissions | `specs/03-Data-and-Storage/lcbp3-v1.8.0-seed-permissions.sql` + `01-02-01-rbac-matrix.md` |
|
||||||
| Release / hotfix | `specs/04-Infrastructure-OPS/04-08-release-management-policy.md` |
|
| Release / hotfix | `specs/04-Infrastructure-OPS/04-08-release-management-policy.md` |
|
||||||
|
| ADR-024 Intent Class. | `specs/06-Decision-Records/ADR-024-intent-classification-strategy.md` |
|
||||||
|
| ADR-025 AI Tool Layer | `specs/06-Decision-Records/ADR-025-ai-tool-layer-architecture.md` |
|
||||||
|
| ADR-026 Chat UI | `specs/06-Decision-Records/ADR-026-document-chat-ui-pattern.md` |
|
||||||
|
| ADR-027 AI Admin Console | `specs/06-Decision-Records/ADR-027-ai-admin-console-and-dynamic-control.md` |
|
||||||
|
| ADR-028 Migration Refactor | `specs/06-Decision-Records/ADR-028-migration-architecture-refactor.md` |
|
||||||
|
| ADR-029 Dynamic Prompts | `specs/06-Decision-Records/ADR-029-dynamic-prompt-management.md` |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -83,7 +90,7 @@
|
|||||||
- [ ] Business comments in Thai, code identifiers in English
|
- [ ] Business comments in Thai, code identifiers in English
|
||||||
- [ ] Schema changes via SQL directly (not migration)
|
- [ ] Schema changes via SQL directly (not migration)
|
||||||
- [ ] Test coverage meets targets (Backend 70%+, Business Logic 80%+)
|
- [ ] Test coverage meets targets (Backend 70%+, Business Logic 80%+)
|
||||||
- [ ] Relevant ADRs referenced (007/008/009/016/019/021/023/023A for AI work)
|
- [ ] Relevant ADRs referenced (007/008/009/016/019/021/023/023A/024-029 for AI work)
|
||||||
- [ ] Domain glossary terms used correctly
|
- [ ] Domain glossary terms used correctly
|
||||||
- [ ] Error handling: `Logger` + `HttpException` / `BusinessException`
|
- [ ] Error handling: `Logger` + `HttpException` / `BusinessException`
|
||||||
- [ ] i18n keys used (no hardcode text)
|
- [ ] i18n keys used (no hardcode text)
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class SkillTestSuite {
|
|||||||
this.results = {
|
this.results = {
|
||||||
passed: 0,
|
passed: 0,
|
||||||
failed: 0,
|
failed: 0,
|
||||||
errors: []
|
errors: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ class SkillTestSuite {
|
|||||||
pass: '\x1b[32m', // Green
|
pass: '\x1b[32m', // Green
|
||||||
fail: '\x1b[31m', // Red
|
fail: '\x1b[31m', // Red
|
||||||
warn: '\x1b[33m', // Yellow
|
warn: '\x1b[33m', // Yellow
|
||||||
reset: '\x1b[0m'
|
reset: '\x1b[0m',
|
||||||
};
|
};
|
||||||
|
|
||||||
const color = colors[type] || colors.info;
|
const color = colors[type] || colors.info;
|
||||||
@@ -119,11 +119,20 @@ function runAllTests() {
|
|||||||
|
|
||||||
// Test 3: Script Files
|
// Test 3: Script Files
|
||||||
testSuite.log('Test 3: Validation Scripts', 'info');
|
testSuite.log('Test 3: Validation Scripts', 'info');
|
||||||
testSuite.testFileExists(path.join(AGENTS_DIR, 'scripts', 'bash', 'validate-versions.sh'), 'bash validate-versions.sh');
|
testSuite.testFileExists(
|
||||||
|
path.join(AGENTS_DIR, 'scripts', 'bash', 'validate-versions.sh'),
|
||||||
|
'bash validate-versions.sh'
|
||||||
|
);
|
||||||
testSuite.testFileExists(path.join(AGENTS_DIR, 'scripts', 'bash', 'audit-skills.sh'), 'bash audit-skills.sh');
|
testSuite.testFileExists(path.join(AGENTS_DIR, 'scripts', 'bash', 'audit-skills.sh'), 'bash audit-skills.sh');
|
||||||
testSuite.testFileExists(path.join(AGENTS_DIR, 'scripts', 'bash', 'sync-workflows.sh'), 'bash sync-workflows.sh');
|
testSuite.testFileExists(path.join(AGENTS_DIR, 'scripts', 'bash', 'sync-workflows.sh'), 'bash sync-workflows.sh');
|
||||||
testSuite.testFileExists(path.join(AGENTS_DIR, 'scripts', 'powershell', 'validate-versions.ps1'), 'powershell validate-versions.ps1');
|
testSuite.testFileExists(
|
||||||
testSuite.testFileExists(path.join(AGENTS_DIR, 'scripts', 'powershell', 'audit-skills.ps1'), 'powershell audit-skills.ps1');
|
path.join(AGENTS_DIR, 'scripts', 'powershell', 'validate-versions.ps1'),
|
||||||
|
'powershell validate-versions.ps1'
|
||||||
|
);
|
||||||
|
testSuite.testFileExists(
|
||||||
|
path.join(AGENTS_DIR, 'scripts', 'powershell', 'audit-skills.ps1'),
|
||||||
|
'powershell audit-skills.ps1'
|
||||||
|
);
|
||||||
testSuite.log('');
|
testSuite.log('');
|
||||||
|
|
||||||
// Test 4: Version Consistency
|
// Test 4: Version Consistency
|
||||||
@@ -131,21 +140,29 @@ function runAllTests() {
|
|||||||
testSuite.testFileContent(path.join(AGENTS_DIR, 'README.md'), /v1\.8\.6/, 'README.md version');
|
testSuite.testFileContent(path.join(AGENTS_DIR, 'README.md'), /v1\.8\.6/, 'README.md version');
|
||||||
testSuite.testFileContent(path.join(SKILLS_DIR, 'VERSION'), /version: 1\.8\.6/, 'skills VERSION file');
|
testSuite.testFileContent(path.join(SKILLS_DIR, 'VERSION'), /version: 1\.8\.6/, 'skills VERSION file');
|
||||||
testSuite.testFileContent(path.join(SKILLS_DIR, 'skills.md'), /v1\.8\.6/, 'skills.md version');
|
testSuite.testFileContent(path.join(SKILLS_DIR, 'skills.md'), /v1\.8\.6/, 'skills.md version');
|
||||||
testSuite.testFileContent(path.join(AGENTS_DIR, 'rules', '00-project-context.md'), /v1\.8\.6/, 'project context version');
|
testSuite.testFileContent(
|
||||||
|
path.join(AGENTS_DIR, 'rules', '00-project-context.md'),
|
||||||
|
/v1\.8\.6/,
|
||||||
|
'project context version'
|
||||||
|
);
|
||||||
testSuite.log('');
|
testSuite.log('');
|
||||||
|
|
||||||
// Test 5: Skills Structure
|
// Test 5: Skills Structure
|
||||||
testSuite.log('Test 5: Skills Structure', 'info');
|
testSuite.log('Test 5: Skills Structure', 'info');
|
||||||
const skillDirs = fs.readdirSync(SKILLS_DIR).filter(item => {
|
const skillDirs = fs.readdirSync(SKILLS_DIR).filter((item) => {
|
||||||
const itemPath = path.join(SKILLS_DIR, item);
|
const itemPath = path.join(SKILLS_DIR, item);
|
||||||
return fs.statSync(itemPath).isDirectory() && item.startsWith('speckit-') || item === 'nestjs-best-practices' || item === 'next-best-practices';
|
return (
|
||||||
|
(fs.statSync(itemPath).isDirectory() && item.startsWith('speckit-')) ||
|
||||||
|
item === 'nestjs-best-practices' ||
|
||||||
|
item === 'next-best-practices'
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testSuite.assert(skillDirs.length >= 20, `Found at least 20 skill directories (found ${skillDirs.length})`);
|
testSuite.assert(skillDirs.length >= 20, `Found at least 20 skill directories (found ${skillDirs.length})`);
|
||||||
|
|
||||||
// Test a few key skills
|
// Test a few key skills
|
||||||
const keySkills = ['speckit-plan', 'speckit-implement', 'speckit-specify', 'speckit-validate'];
|
const keySkills = ['speckit-plan', 'speckit-implement', 'speckit-specify', 'speckit-validate'];
|
||||||
keySkills.forEach(skill => {
|
keySkills.forEach((skill) => {
|
||||||
const skillPath = path.join(SKILLS_DIR, skill);
|
const skillPath = path.join(SKILLS_DIR, skill);
|
||||||
const skillMdPath = path.join(skillPath, 'SKILL.md');
|
const skillMdPath = path.join(skillPath, 'SKILL.md');
|
||||||
testSuite.testDirectoryExists(skillPath, `${skill} directory`);
|
testSuite.testDirectoryExists(skillPath, `${skill} directory`);
|
||||||
@@ -163,12 +180,12 @@ function runAllTests() {
|
|||||||
|
|
||||||
// Test 6: Workflows Structure
|
// Test 6: Workflows Structure
|
||||||
testSuite.log('Test 6: Workflows Structure', 'info');
|
testSuite.log('Test 6: Workflows Structure', 'info');
|
||||||
const workflowFiles = fs.readdirSync(WORKFLOWS_DIR).filter(item => item.endsWith('.md'));
|
const workflowFiles = fs.readdirSync(WORKFLOWS_DIR).filter((item) => item.endsWith('.md'));
|
||||||
testSuite.assert(workflowFiles.length >= 20, `Found at least 20 workflow files (found ${workflowFiles.length})`);
|
testSuite.assert(workflowFiles.length >= 20, `Found at least 20 workflow files (found ${workflowFiles.length})`);
|
||||||
|
|
||||||
// Test key workflows
|
// Test key workflows
|
||||||
const keyWorkflows = ['00-speckit.all.md', '02-speckit.specify.md', '04-speckit.plan.md', '07-speckit.implement.md'];
|
const keyWorkflows = ['00-speckit.all.md', '02-speckit.specify.md', '04-speckit.plan.md', '07-speckit.implement.md'];
|
||||||
keyWorkflows.forEach(workflow => {
|
keyWorkflows.forEach((workflow) => {
|
||||||
const workflowPath = path.join(WORKFLOWS_DIR, workflow);
|
const workflowPath = path.join(WORKFLOWS_DIR, workflow);
|
||||||
testSuite.testFileExists(workflowPath, `${workflow} file`);
|
testSuite.testFileExists(workflowPath, `${workflow} file`);
|
||||||
});
|
});
|
||||||
@@ -177,12 +194,12 @@ function runAllTests() {
|
|||||||
// Test 7: Rules Structure
|
// Test 7: Rules Structure
|
||||||
testSuite.log('Test 7: Rules Structure', 'info');
|
testSuite.log('Test 7: Rules Structure', 'info');
|
||||||
const rulesDir = path.join(AGENTS_DIR, 'rules');
|
const rulesDir = path.join(AGENTS_DIR, 'rules');
|
||||||
const ruleFiles = fs.readdirSync(rulesDir).filter(item => item.endsWith('.md'));
|
const ruleFiles = fs.readdirSync(rulesDir).filter((item) => item.endsWith('.md'));
|
||||||
testSuite.assert(ruleFiles.length >= 10, `Found at least 10 rule files (found ${ruleFiles.length})`);
|
testSuite.assert(ruleFiles.length >= 10, `Found at least 10 rule files (found ${ruleFiles.length})`);
|
||||||
|
|
||||||
// Test key rules
|
// Test key rules
|
||||||
const keyRules = ['00-project-context.md', '01-adr-019-uuid.md', '02-security.md'];
|
const keyRules = ['00-project-context.md', '01-adr-019-uuid.md', '02-security.md'];
|
||||||
keyRules.forEach(rule => {
|
keyRules.forEach((rule) => {
|
||||||
const rulePath = path.join(rulesDir, rule);
|
const rulePath = path.join(rulesDir, rule);
|
||||||
testSuite.testFileExists(rulePath, `${rule} file`);
|
testSuite.testFileExists(rulePath, `${rule} file`);
|
||||||
});
|
});
|
||||||
@@ -209,9 +226,21 @@ function runAllTests() {
|
|||||||
|
|
||||||
// Test 9: Documentation Quality
|
// Test 9: Documentation Quality
|
||||||
testSuite.log('Test 9: Documentation Quality', 'info');
|
testSuite.log('Test 9: Documentation Quality', 'info');
|
||||||
testSuite.testFileContent(path.join(AGENTS_DIR, 'README.md'), /## Troubleshooting/, 'README.md has troubleshooting section');
|
testSuite.testFileContent(
|
||||||
testSuite.testFileContent(path.join(SKILLS_DIR, 'skills.md'), /## Skill Dependency Matrix/, 'skills.md has dependency matrix');
|
path.join(AGENTS_DIR, 'README.md'),
|
||||||
testSuite.testFileContent(path.join(AGENTS_DIR, 'README.md'), /## Architecture/, 'README.md has architecture section');
|
/## Troubleshooting/,
|
||||||
|
'README.md has troubleshooting section'
|
||||||
|
);
|
||||||
|
testSuite.testFileContent(
|
||||||
|
path.join(SKILLS_DIR, 'skills.md'),
|
||||||
|
/## Skill Dependency Matrix/,
|
||||||
|
'skills.md has dependency matrix'
|
||||||
|
);
|
||||||
|
testSuite.testFileContent(
|
||||||
|
path.join(AGENTS_DIR, 'README.md'),
|
||||||
|
/## Architecture/,
|
||||||
|
'README.md has architecture section'
|
||||||
|
);
|
||||||
testSuite.log('');
|
testSuite.log('');
|
||||||
|
|
||||||
// Results Summary
|
// Results Summary
|
||||||
@@ -221,7 +250,7 @@ function runAllTests() {
|
|||||||
|
|
||||||
if (testSuite.results.errors.length > 0) {
|
if (testSuite.results.errors.length > 0) {
|
||||||
testSuite.log('Errors:', 'fail');
|
testSuite.log('Errors:', 'fail');
|
||||||
testSuite.results.errors.forEach(error => {
|
testSuite.results.errors.forEach((error) => {
|
||||||
testSuite.log(` - ${error}`, 'fail');
|
testSuite.log(` - ${error}`, 'fail');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class WorkflowTestSuite {
|
|||||||
this.results = {
|
this.results = {
|
||||||
passed: 0,
|
passed: 0,
|
||||||
failed: 0,
|
failed: 0,
|
||||||
errors: []
|
errors: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ class WorkflowTestSuite {
|
|||||||
pass: '\x1b[32m', // Green
|
pass: '\x1b[32m', // Green
|
||||||
fail: '\x1b[31m', // Red
|
fail: '\x1b[31m', // Red
|
||||||
warn: '\x1b[33m', // Yellow
|
warn: '\x1b[33m', // Yellow
|
||||||
reset: '\x1b[0m'
|
reset: '\x1b[0m',
|
||||||
};
|
};
|
||||||
|
|
||||||
const color = colors[type] || colors.info;
|
const color = colors[type] || colors.info;
|
||||||
@@ -67,7 +67,7 @@ class WorkflowTestSuite {
|
|||||||
|
|
||||||
// Check for proper markdown formatting
|
// Check for proper markdown formatting
|
||||||
const lines = content.split('\n');
|
const lines = content.split('\n');
|
||||||
const nonEmptyLines = lines.filter(line => line.trim().length > 0);
|
const nonEmptyLines = lines.filter((line) => line.trim().length > 0);
|
||||||
this.assert(nonEmptyLines.length >= 5, `${expectedName} has sufficient content`);
|
this.assert(nonEmptyLines.length >= 5, `${expectedName} has sufficient content`);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -121,7 +121,7 @@ const expectedWorkflows = {
|
|||||||
'util-speckit.migrate.md': 'Migration utility',
|
'util-speckit.migrate.md': 'Migration utility',
|
||||||
'util-speckit.quizme.md': 'Quiz utility',
|
'util-speckit.quizme.md': 'Quiz utility',
|
||||||
'util-speckit.status.md': 'Status utility',
|
'util-speckit.status.md': 'Status utility',
|
||||||
'util-speckit.taskstoissues.md': 'Task to issues utility'
|
'util-speckit.taskstoissues.md': 'Task to issues utility',
|
||||||
};
|
};
|
||||||
|
|
||||||
// Test suite implementation
|
// Test suite implementation
|
||||||
@@ -169,7 +169,6 @@ function runWorkflowTests() {
|
|||||||
|
|
||||||
// Validate skill dependencies
|
// Validate skill dependencies
|
||||||
workflowTestSuite.validateWorkflowDependency(filename, content);
|
workflowTestSuite.validateWorkflowDependency(filename, content);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
workflowTestSuite.assert(false, `${filename} - content validation error: ${error.message}`);
|
workflowTestSuite.assert(false, `${filename} - content validation error: ${error.message}`);
|
||||||
}
|
}
|
||||||
@@ -179,7 +178,7 @@ function runWorkflowTests() {
|
|||||||
|
|
||||||
// Test 4: Workflow naming consistency
|
// Test 4: Workflow naming consistency
|
||||||
workflowTestSuite.log('Test 4: Naming Consistency', 'info');
|
workflowTestSuite.log('Test 4: Naming Consistency', 'info');
|
||||||
const actualFiles = fs.readdirSync(WORKFLOWS_DIR).filter(file => file.endsWith('.md'));
|
const actualFiles = fs.readdirSync(WORKFLOWS_DIR).filter((file) => file.endsWith('.md'));
|
||||||
|
|
||||||
for (const actualFile of actualFiles) {
|
for (const actualFile of actualFiles) {
|
||||||
if (!expectedWorkflows[actualFile]) {
|
if (!expectedWorkflows[actualFile]) {
|
||||||
@@ -211,11 +210,14 @@ function runWorkflowTests() {
|
|||||||
// Results Summary
|
// Results Summary
|
||||||
workflowTestSuite.log('=== Workflow Test Results Summary ===', 'info');
|
workflowTestSuite.log('=== Workflow Test Results Summary ===', 'info');
|
||||||
workflowTestSuite.log(`Passed: ${workflowTestSuite.results.passed}`, 'pass');
|
workflowTestSuite.log(`Passed: ${workflowTestSuite.results.passed}`, 'pass');
|
||||||
workflowTestSuite.log(`Failed: ${workflowTestSuite.results.failed}`, workflowTestSuite.results.failed > 0 ? 'fail' : 'pass');
|
workflowTestSuite.log(
|
||||||
|
`Failed: ${workflowTestSuite.results.failed}`,
|
||||||
|
workflowTestSuite.results.failed > 0 ? 'fail' : 'pass'
|
||||||
|
);
|
||||||
|
|
||||||
if (workflowTestSuite.results.errors.length > 0) {
|
if (workflowTestSuite.results.errors.length > 0) {
|
||||||
workflowTestSuite.log('Errors:', 'fail');
|
workflowTestSuite.log('Errors:', 'fail');
|
||||||
workflowTestSuite.results.errors.forEach(error => {
|
workflowTestSuite.results.errors.forEach((error) => {
|
||||||
workflowTestSuite.log(` - ${error}`, 'fail');
|
workflowTestSuite.log(` - ${error}`, 'fail');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,168 @@
|
|||||||
|
---
|
||||||
|
trigger: always_on
|
||||||
|
---
|
||||||
|
|
||||||
|
# NAP-DMS Project Context & Rules
|
||||||
|
|
||||||
|
- For: Windsurf Cascade (and compatible: Codex CLI, opencode, Amp, Antigravity, AGENTS.md tools)
|
||||||
|
- Version: 1.9.6 | Last synced from repo: 2026-05-22
|
||||||
|
- Repo: [https://git.np-dms.work/np-dms/lcbp3](https://git.np-dms.work/np-dms/lcbp3)
|
||||||
|
- Skill pack: `.agents/skills/` (v1.9.0, 21 skills) — see [`skills/README.md`](./.agents/skills/README.md) + [`skills/_LCBP3-CONTEXT.md`](./.agents/skills/_LCBP3-CONTEXT.md)
|
||||||
|
|
||||||
|
## 🧠 Role & Persona
|
||||||
|
|
||||||
|
Act as **Senior Full Stack Developer** specialized in NestJS, Next.js, TypeScript, DMS. Focus: Data Integrity, Security, Maintainability, Performance.
|
||||||
|
|
||||||
|
You are a **Document Intelligence Engine** — not a general chatbot. Every response must be **precise**, **spec-compliant**, and **production-ready**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧩 Thought & Planning Protocol (Powered by Everything-Claude-Code)
|
||||||
|
|
||||||
|
Before writing any code or taking any action in Tier 1 and Tier 2, the AI must demonstrate the following thinking process:
|
||||||
|
|
||||||
|
### 1. Analysis Phase (Explore & Analyze)
|
||||||
|
|
||||||
|
Problem Understanding: Restate what the user wants in clear, unambiguous terms.
|
||||||
|
Context Search: Identify the relevant Spec files or ADRs from the "Key Spec Files" table that must be read before starting.
|
||||||
|
Constraints Identification: Identify key constraints (e.g. Security rules, UUID patterns, or Domain terminology).
|
||||||
|
|
||||||
|
### 2. Planning Phase (Plan)
|
||||||
|
|
||||||
|
Alternative Exploration: Present at least 2 solution approaches (where possible) with pros/cons analysis.
|
||||||
|
Step-by-Step Roadmap: Write a file-by-file plan of changes before executing.
|
||||||
|
Verification Plan: Specify how to verify the work is complete (e.g. "which unit tests to write" or "which file to check the schema in").
|
||||||
|
|
||||||
|
### 3. Execution & Refinement (Execute & Refine)
|
||||||
|
|
||||||
|
Follow the plan step by step, and pause to ask if any uncertainty arises.
|
||||||
|
If significant logic changes are made, summarize what was done for the user after completion.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚙️ DMS Workflow Engine Protocol
|
||||||
|
|
||||||
|
กฎนี้ใช้คุม Logic การไหลของเอกสาร (RFA, Transmittal, Correspondence) เพื่อป้องกัน Race Condition และรักษาความถูกต้องของสถานะ:
|
||||||
|
|
||||||
|
- **State Management:** ตรวจสอบสถานะปัจจุบันจาก DB ก่อนเสมอ เพื่อป้องกันการอนุมัติซ้ำซ้อน (ดู `05-06-code-snippets.md` `[workflow-transition]`)
|
||||||
|
- **Concurrency Control:** การจอนเลขที่เอกสารต้องใช้ **Redis Redlock** หรือ **TypeORM `@VersionColumn`** เท่านั้น (ADR-002)
|
||||||
|
- **Background Jobs:** งานนานหรือการแจ้งเตือนต้องส่งไปทำที่ **BullMQ** ห้ามเขียนแบบ Inline (ADR-008)
|
||||||
|
- **Term Consistency:** ห้ามใช้ "Approval Flow" ให้ใช้ **"Workflow Engine"** และห้ามใช้ "Letter" ให้ใช้ **"Correspondence"** (หมายเหตุ: "จดหมาย" ในคอมเมนต์ภาษาไทย = Correspondence ที่ครอบคลุมทุกประเภท)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛡️ Security & Integrity Audit Protocol
|
||||||
|
|
||||||
|
กฎนี้ให้ AI เป็น Gatekeeper ก่อน Commit โดยเน้น **Tier 1 — CRITICAL**:
|
||||||
|
|
||||||
|
- **UUID Validation:** ตรวจสอบว่าเป็น **UUIDv7** และห้ามใช้ `parseInt()` บน UUID (ADR-019)
|
||||||
|
- **RBAC Check:** API ใหม่ต้องมี **CASL Guard** และตรวจสอบ 4-Level RBAC Matrix (ADR-016)
|
||||||
|
- **Data Isolation:** AI ต้องรันผ่าน **Ollama บน Admin Desktop** เท่านั้น ห้ามเข้าถึง DB/storage โดยตรง (ADR-023)
|
||||||
|
- **Input Sanitization:** ไฟล์อัปโหลดต้องผ่าน **Two-Phase** (Temp → Commit) และสแกนด้วย **ClamAV** (ADR-016)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧭 Rule Enforcement Tiers
|
||||||
|
|
||||||
|
### 🔴 Tier 1 — CRITICAL (CI BLOCKER)
|
||||||
|
|
||||||
|
Build fails หากละเมิด:
|
||||||
|
|
||||||
|
- Security (Auth, RBAC, Validation)
|
||||||
|
- UUID Strategy (ADR-019) — no `parseInt` / `Number` / `+` on UUID
|
||||||
|
- Database correctness — verify schema before writing queries
|
||||||
|
- File upload security (ClamAV + whitelist)
|
||||||
|
- AI validation boundary (ADR-023)
|
||||||
|
- Error handling strategy (ADR-007)
|
||||||
|
- Forbidden patterns: `any`, `console.log`, UUID misuse, `id ?? ''` fallback
|
||||||
|
|
||||||
|
### 🟡 Tier 2 — IMPORTANT (CODE REVIEW)
|
||||||
|
|
||||||
|
Must fix ก่อน merge:
|
||||||
|
|
||||||
|
- Architecture patterns (thin controller, business logic in service)
|
||||||
|
- Test coverage (80%+ business logic, 70%+ backend overall)
|
||||||
|
- Cache invalidation
|
||||||
|
- Naming conventions
|
||||||
|
- **TypeScript Standards:** Missing JSDoc, explicit types, or file headers
|
||||||
|
|
||||||
|
### 🟢 Tier 3 — SPECIALIZED WORK
|
||||||
|
|
||||||
|
Requires domain-specific knowledge:
|
||||||
|
|
||||||
|
- **ADR-021 Integration:** Workflow Engine & Context implementation
|
||||||
|
- **AI Infrastructure:** ADR-023/023A boundary enforcement and pipeline usage
|
||||||
|
- **AI Runtime Layer:** ADR-024 Intent Classification, ADR-025 Tool Layer, ADR-026 Chat UI, ADR-027 Admin Console
|
||||||
|
- **Migration Pipeline:** ADR-028 Staging Queue & post-migration cleanup
|
||||||
|
- **Complex Business Logic:** Multi-step workflows with state management
|
||||||
|
- **Performance Optimization:** Database queries, caching strategies, bulk operations
|
||||||
|
|
||||||
|
### 🔵 Tier 4 — GUIDELINES
|
||||||
|
|
||||||
|
Best practice — follow when possible:
|
||||||
|
|
||||||
|
- Code style / formatting (Prettier handles)
|
||||||
|
- Comment completeness
|
||||||
|
- Minor optimizations
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📐 TypeScript Rules & Coding Standards
|
||||||
|
|
||||||
|
### 📝 Core Standards
|
||||||
|
|
||||||
|
- **Strict Mode** — all strict checks enforced.
|
||||||
|
- **ZERO `any` types** — use proper types or `unknown` + narrowing.
|
||||||
|
- **ZERO `console.log`** — use NestJS `Logger` (backend) or remove (frontend).
|
||||||
|
- **English for Code** — use English for all code identifiers, variables, and logic.
|
||||||
|
- **Thai for Comments** — use Thai for comments, documentation, and JSDoc.
|
||||||
|
- **Explicit Typing** — explicitly define types for all variables, parameters, and return values.
|
||||||
|
- **JSDoc** — use JSDoc for all public classes and methods.
|
||||||
|
|
||||||
|
### 🏗️ File & Function Structure
|
||||||
|
|
||||||
|
- **File Headers** — every file MUST start with `// File: path/filename` on the first line.
|
||||||
|
- **Change Log** — include `// Change Log` at the top of the file to track modifications.
|
||||||
|
- **Single Export** — export **only one main symbol** per file.
|
||||||
|
- **Function Style** — avoid unnecessary blank lines inside functions.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚫 Forbidden Actions
|
||||||
|
|
||||||
|
| ❌ Forbidden | ✅ Correct Approach | ⚠️ Why |
|
||||||
|
| ----------------------------------------------- | ------------------------------------------------------- | ---------------------------------------------------- |
|
||||||
|
| SQL Triggers for business logic | NestJS Service methods | Untestable; bypasses audit log |
|
||||||
|
| `.env` files in production | `docker-compose.yml` environment section | Secrets exposed in version control |
|
||||||
|
| TypeORM migration files | Edit schema SQL directly (ADR-009) | Migration drift risk; schema managed via SQL delta |
|
||||||
|
| Inventing table/column names | Verify against `schema-02-tables.sql` | Schema mismatch causes silent runtime errors |
|
||||||
|
| `any` TypeScript type | Proper types / generics | Defeats strict mode; hides runtime type errors |
|
||||||
|
| `console.log` in committed code | NestJS Logger (backend) / remove (frontend) | Log flooding in production; risk of data leakage |
|
||||||
|
| `req: any` in controllers | `RequestWithUser` typed interface | Type safety lost; auth context unreachable |
|
||||||
|
| `parseInt()` on UUID values | Use UUID string directly (ADR-019) | `"0195…"` parsed to integer `19` — silently wrong |
|
||||||
|
| Exposing INT PK in API responses | UUIDv7 `publicId` (ADR-019) | Leaks row count; enables DB enumeration attacks |
|
||||||
|
| AI accessing DB/storage directly | AI → DMS API → DB (ADR-023/023A) | Bypasses RBAC, audit trail, and validation layer |
|
||||||
|
| Direct file operations bypassing StorageService | `StorageService` for all file moves | Orphaned files; broken ClamAV scan; no audit trail |
|
||||||
|
| Inline email/notification sending | BullMQ queue job (ADR-008) | Blocks request thread; no retry on transient failure |
|
||||||
|
| Deploying without Release Gates | Complete `04-08-release-management-policy.md` | Unverified deploy risks data loss in production |
|
||||||
|
| AI direct cloud API calls | On-premises Ollama only (ADR-023/023A) | Data privacy violation; no audit control |
|
||||||
|
| AI outputs without human validation | Human-in-the-loop validation required (ADR-023/023A) | Unvalidated AI metadata corrupts document records |
|
||||||
|
| n8n calling Ollama/Qdrant directly | n8n → DMS API → BullMQ → Ollama (ADR-023A) | Bypasses audit log, RBAC, and error handling layer |
|
||||||
|
| Qdrant query without `projectPublicId` filter | `QdrantService.search(projectPublicId, ...)` (ADR-023A) | Cross-project data leak via vector search |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚧 Out of Scope — Never Do Without Explicit Approval
|
||||||
|
|
||||||
|
| ❌ Never Do Autonomously | ⚠️ Why Approval Is Required |
|
||||||
|
| --------------------------------------------------------------- | ---------------------------------------------------------------- |
|
||||||
|
| `DROP` or `RENAME` a column / table | Irreversible data loss — requires DBA + PM sign-off |
|
||||||
|
| Push directly to `main` / `master` branch | Bypasses CI, code review, and release gates |
|
||||||
|
| Generate or insert seed data into production database | May corrupt live data or violate business state invariants |
|
||||||
|
| Delete files from permanent storage | Files may be referenced in active documents or audit trails |
|
||||||
|
| Modify RBAC permission matrix without security team approval | Defines access control for all users — security boundary change |
|
||||||
|
| Upgrade major library versions (NestJS, Next.js, TypeORM, etc.) | Breaking changes require full regression test cycle |
|
||||||
|
| Disable or modify authentication / authorization guards | Creates unguarded endpoints — immediate security risk |
|
||||||
|
| Change Redis lock TTL or disable Redlock | Risk of document number race condition (ADR-002) |
|
||||||
|
| Create or supersede an ADR unilaterally | Architecture decisions require team consensus and review process |
|
||||||
|
| Add new columns to production tables without schema review | Must update Data Dictionary + downstream queries simultaneously |
|
||||||
@@ -13,9 +13,9 @@ trigger: always_on
|
|||||||
5. **Password:** bcrypt 12 salt rounds, min 8 chars, rotate every 90 days
|
5. **Password:** bcrypt 12 salt rounds, min 8 chars, rotate every 90 days
|
||||||
6. **Rate Limiting:** `ThrottlerGuard` on all auth endpoints
|
6. **Rate Limiting:** `ThrottlerGuard` on all auth endpoints
|
||||||
7. **File Upload:** Whitelist PDF/DWG/DOCX/XLSX/ZIP, max 50MB, ClamAV scan
|
7. **File Upload:** Whitelist PDF/DWG/DOCX/XLSX/ZIP, max 50MB, ClamAV scan
|
||||||
8. **AI Isolation (ADR-018):** Ollama on Admin Desktop ONLY — NO direct DB/storage access
|
8. **AI Isolation (ADR-023/023A):** Ollama on Admin Desktop ONLY — NO direct DB/storage access; 2-model stack `gemma4:e4b Q8_0` + `nomic-embed-text`; all inference via BullMQ (`ai-realtime` / `ai-batch`)
|
||||||
9. **Error Handling (ADR-007):** Use layered error classification with user-friendly messages
|
9. **Error Handling (ADR-007):** Use layered error classification with user-friendly messages
|
||||||
10. **AI Integration (ADR-020):** RFA-First approach with unified pipeline architecture
|
10. **AI Integration (ADR-023/023A):** RFA-First approach; n8n orchestrates Migration Phase only via DMS API — never calls Ollama directly; `QdrantService.search()` requires `projectPublicId` as mandatory param
|
||||||
11. **AI Audit Trail:** Log all AI interactions and human validations
|
11. **AI Audit Trail:** Log all AI interactions and human validations
|
||||||
12. **Rate Limiting:** Apply to AI endpoints to prevent abuse
|
12. **Rate Limiting:** Apply to AI endpoints to prevent abuse
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ trigger: always_on
|
|||||||
- [ ] No SQL injection vulnerabilities
|
- [ ] No SQL injection vulnerabilities
|
||||||
- [ ] File upload validation (whitelist + ClamAV)
|
- [ ] File upload validation (whitelist + ClamAV)
|
||||||
- [ ] Rate limiting applied to auth endpoints
|
- [ ] Rate limiting applied to auth endpoints
|
||||||
- [ ] AI boundary enforcement (ADR-023) - no direct DB/storage access
|
- [ ] AI boundary enforcement (ADR-023/023A) - no direct DB/storage access
|
||||||
- [ ] AI audit logging implemented for AI interactions
|
- [ ] AI audit logging implemented for AI interactions
|
||||||
- [ ] AI outputs validated before use (human-in-the-loop)
|
- [ ] AI outputs validated before use (human-in-the-loop)
|
||||||
- [ ] Error handling follows ADR-007 layered classification
|
- [ ] Error handling follows ADR-007 layered classification
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
# TypeScript Rules (v1.9.3)
|
---
|
||||||
|
trigger: always_on
|
||||||
|
---
|
||||||
|
|
||||||
|
# TypeScript Rules
|
||||||
|
|
||||||
## Core Standards
|
## Core Standards
|
||||||
|
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
trigger: always_on
|
||||||
|
---
|
||||||
|
|
||||||
|
# Domain Terminology
|
||||||
|
|
||||||
|
## DMS Glossary
|
||||||
|
|
||||||
|
| ✅ Use | ❌ Don't Use | คำอธิบายเพิ่มเติม |
|
||||||
|
| ------------------ | ------------------------------------- | ------------------------------------------------ |
|
||||||
|
| Correspondence | Letter, Communication, Document | ครอบคลุมทุกประเภท: Letter, RFA, Memo, ฯลฯ |
|
||||||
|
| RFA | Approval Request, Submit for Approval | เอกสารขออนุมัติ (ชนิดหนึ่งของ Correspondence) |
|
||||||
|
| Transmittal | Delivery Note, Cover Letter | เอกสารนำส่ง (ชนิดหนึ่งของ Correspondence) |
|
||||||
|
| Circulation | Distribution, Routing | ใบเวียนเอกสารภายใน (ชนิดหนึ่งของ Correspondence) |
|
||||||
|
| Shop Drawing | Construction Drawing | แบบก่อสร้าง |
|
||||||
|
| Contract Drawing | Design Drawing, Blueprint | แบบคู่สัญญา |
|
||||||
|
| Workflow Engine | Approval Flow, Process Engine | เครื่องมือจัดการลำดับงาน |
|
||||||
|
| Document Numbering | Document ID, Auto Number | ระบบจัดการเลขที่เอกสาร |
|
||||||
|
| RBAC | Permission System (generic) | การควบคุมสิทธิ์ตามบทบาท |
|
||||||
|
|
||||||
|
## Full Glossary
|
||||||
|
|
||||||
|
`specs/00-overview/00-02-glossary.md`
|
||||||
|
|
||||||
|
## Key Spec Files Priority
|
||||||
|
|
||||||
|
Spec priority: **`06-Decision-Records`** > **`05-Engineering-Guidelines`** > others
|
||||||
|
|
||||||
|
| Document | Path | Use When |
|
||||||
|
| ------------------------------ | --------------------------------------------------------------------------- | --------------------------------- |
|
||||||
|
| **Glossary** | `specs/00-overview/00-02-glossary.md` | Verify domain terminology |
|
||||||
|
| **Schema Tables** | `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql` | Before writing any query |
|
||||||
|
| **Data Dictionary** | `specs/03-Data-and-Storage/03-01-data-dictionary.md` | Field meanings + business rules |
|
||||||
|
| **Edge Cases** | `specs/01-Requirements/01-06-edge-cases-and-rules.md` | Prevent bugs in flows |
|
||||||
|
| **ADR-019 UUID** | `specs/06-Decision-Records/ADR-019-hybrid-identifier-strategy.md` | UUID-related work |
|
||||||
|
| **ADR-023 AI** | `specs/06-Decision-Records/ADR-023-unified-ai-architecture.md` | AI integration work |
|
||||||
|
| **ADR-023A AI Model** | `specs/06-Decision-Records/ADR-023A-unified-ai-architecture.md` | 2-model stack, BullMQ 2-queue |
|
||||||
|
| **ADR-024 Intent Class.** | `specs/06-Decision-Records/ADR-024-intent-classification-strategy.md` | Pattern→LLM Fallback; Redis cache |
|
||||||
|
| **ADR-025 AI Tool Layer** | `specs/06-Decision-Records/ADR-025-ai-tool-layer-architecture.md` | Tool Registry; CASL-guarded |
|
||||||
|
| **ADR-026 Chat UI** | `specs/06-Decision-Records/ADR-026-document-chat-ui-pattern.md` | Side-panel; streaming SSE |
|
||||||
|
| **ADR-027 AI Admin Console** | `specs/06-Decision-Records/ADR-027-ai-admin-console-and-dynamic-control.md` | Dynamic control; admin-only |
|
||||||
|
| **ADR-028 Migration Refactor** | `specs/06-Decision-Records/ADR-028-migration-architecture-refactor.md` | Staging Queue; cleanup |
|
||||||
|
| **Backend Guidelines** | `specs/05-Engineering-Guidelines/05-02-backend-guidelines.md` | NestJS patterns |
|
||||||
|
| **Frontend Guidelines** | `specs/05-Engineering-Guidelines/05-03-frontend-guidelines.md` | Next.js patterns |
|
||||||
|
| **Testing Strategy** | `specs/05-Engineering-Guidelines/05-04-testing-strategy.md` | Coverage goals |
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
---
|
||||||
|
trigger: always_on
|
||||||
|
---
|
||||||
|
|
||||||
|
# Forbidden Actions
|
||||||
|
|
||||||
|
## ❌ Never Do This
|
||||||
|
|
||||||
|
| ❌ Forbidden | ✅ Correct Approach | ⚠️ Why |
|
||||||
|
| ----------------------------------------------- | ------------------------------------------------------- | ---------------------------------------------------- |
|
||||||
|
| SQL Triggers for business logic | NestJS Service methods | Untestable; bypasses audit log |
|
||||||
|
| `.env` files in production | `docker-compose.yml` environment section | Secrets exposed in version control |
|
||||||
|
| TypeORM migration files | Edit schema SQL directly (ADR-009) | Migration drift risk; schema managed via SQL delta |
|
||||||
|
| Inventing table/column names | Verify against `schema-02-tables.sql` | Schema mismatch causes silent runtime errors |
|
||||||
|
| `any` TypeScript type | Proper types / generics | Defeats strict mode; hides runtime type errors |
|
||||||
|
| `console.log` in committed code | NestJS Logger (backend) / remove (frontend) | Log flooding in production; risk of data leakage |
|
||||||
|
| `req: any` in controllers | `RequestWithUser` typed interface | Type safety lost; auth context unreachable |
|
||||||
|
| `parseInt()` on UUID values | Use UUID string directly (ADR-019) | `"0195…"` parsed to integer `19` — silently wrong |
|
||||||
|
| Exposing INT PK in API responses | UUIDv7 `publicId` (ADR-019) | Leaks row count; enables DB enumeration attacks |
|
||||||
|
| AI accessing DB/storage directly | AI → DMS API → DB (ADR-023/023A) | Bypasses RBAC, audit trail, and validation layer |
|
||||||
|
| Direct file operations bypassing StorageService | `StorageService` for all file moves | Orphaned files; broken ClamAV scan; no audit trail |
|
||||||
|
| Inline email/notification sending | BullMQ queue job (ADR-008) | Blocks request thread; no retry on transient failure |
|
||||||
|
| Deploying without Release Gates | Complete `04-08-release-management-policy.md` | Unverified deploy risks data loss in production |
|
||||||
|
| AI direct cloud API calls | On-premises Ollama only (ADR-023/023A) | Data privacy violation; no audit control |
|
||||||
|
| AI outputs without human validation | Human-in-the-loop validation required (ADR-023/023A) | Unvalidated AI metadata corrupts document records |
|
||||||
|
| n8n calling Ollama/Qdrant directly | n8n → DMS API → BullMQ → Ollama (ADR-023A) | Bypasses audit log, RBAC, and error handling layer |
|
||||||
|
| Qdrant query without `projectPublicId` filter | `QdrantService.search(projectPublicId, ...)` (ADR-023A) | Cross-project data leak via vector search |
|
||||||
|
|
||||||
|
## Schema Changes (ADR-009)
|
||||||
|
|
||||||
|
- **NO TypeORM migrations** — edit SQL schema directly
|
||||||
|
- Always check `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql` before writing queries
|
||||||
|
- Update Data Dictionary when changing fields
|
||||||
|
|
||||||
|
## UUID Handling
|
||||||
|
|
||||||
|
See `01-adr-019-uuid.md` for complete UUID rules.
|
||||||
|
|
||||||
|
Quick reminder:
|
||||||
|
|
||||||
|
- ❌ `parseInt(uuid)` → NEVER
|
||||||
|
- ❌ `Number(uuid)` → NEVER
|
||||||
|
- ✅ Use UUID string directly
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
---
|
||||||
|
trigger: always_on
|
||||||
|
---
|
||||||
|
|
||||||
|
# Development Flow
|
||||||
|
|
||||||
|
## 🔴 Critical Work — DB / API / Security / Workflow Engine
|
||||||
|
|
||||||
|
**MUST complete all steps:**
|
||||||
|
|
||||||
|
1. **Glossary check** — verify domain terms in `00-02-glossary.md`
|
||||||
|
2. **Read the spec** — select from Key Spec Files table
|
||||||
|
3. **Check schema** — verify table/column in `lcbp3-v1.9.0-schema-02-tables.sql`
|
||||||
|
4. **Check data dictionary** — confirm field meanings + business rules
|
||||||
|
5. **Scan edge cases** — `01-06-edge-cases-and-rules.md`
|
||||||
|
6. **Check ADRs** — verify decisions align (ADR-009, ADR-019, ADR-023)
|
||||||
|
7. **Write code** — TypeScript strict, no `any`, no `console.log`
|
||||||
|
|
||||||
|
## 🟡 Normal Work — UI / Feature / Integration
|
||||||
|
|
||||||
|
- Follow existing patterns in codebase.
|
||||||
|
- Check spec for relevant module only.
|
||||||
|
- **Hybrid Specs Organization:**
|
||||||
|
- Place new Infrastructure tasks in `specs/100-Infrastructures/`
|
||||||
|
- Place new Feature/Workflow tasks in `specs/200-fullstacks/`
|
||||||
|
- Place Documentation/Research in `specs/300-others/`
|
||||||
|
- Ensure no forbidden patterns (`any`, `console.log`, UUID misuse) are introduced.
|
||||||
|
|
||||||
|
## 🟢 Quick Fix — Bug Fix / Typo / Style
|
||||||
|
|
||||||
|
- Fix directly
|
||||||
|
- Add minimal test if logic changed
|
||||||
|
- Check forbidden patterns before commit
|
||||||
|
|
||||||
|
### 🟢 Specialized Work — ADR-021, AI Runtime Layer, Complex Logic
|
||||||
|
|
||||||
|
**MUST complete:**
|
||||||
|
|
||||||
|
1. **Domain Knowledge Check** - Read relevant ADRs (ADR-021, ADR-023/023A, ADR-024~028)
|
||||||
|
2. **Pattern Verification** - Check existing implementations in codebase
|
||||||
|
3. **Specialized Requirements** - Follow domain-specific patterns
|
||||||
|
4. **Complex Logic Testing** - Multi-scenario test coverage
|
||||||
|
5. **Performance Validation** - Load testing if applicable
|
||||||
|
|
||||||
|
**For ADR-021 Integration:**
|
||||||
|
|
||||||
|
- Read ADR-021 - Integrated workflow & step attachments
|
||||||
|
- Check ADR-001 - Unified workflow engine patterns
|
||||||
|
- Verify WorkflowEngineService - Polymorphic instance handling
|
||||||
|
- Add workflow fields - Expose workflowInstanceId, workflowState, availableActions
|
||||||
|
- Include IntegratedBanner - Frontend workflow lifecycle display
|
||||||
|
- Test workflow transitions - State changes and action validation
|
||||||
|
|
||||||
|
**For AI Infrastructure (ADR-023/023A):**
|
||||||
|
|
||||||
|
- Verify AI boundary enforcement - No direct DB/storage access
|
||||||
|
- Check BullMQ 2-queue setup - ai-realtime + ai-batch
|
||||||
|
- Validate Qdrant multi-tenancy - projectPublicId filter required
|
||||||
|
- Test human-in-the-loop validation workflows
|
||||||
|
- Audit AI interaction logging to ai_audit_logs
|
||||||
|
|
||||||
|
**For AI Runtime Layer (ADR-024/025/026/027):**
|
||||||
|
|
||||||
|
- ADR-024: Pattern Layer first (ai_intent_patterns DB + Redis cache 5 min) → LLM Fallback (gemma4:e4b, semaphore max=3)
|
||||||
|
- ADR-025: Tool Registry dispatch — AI Gateway → Tool → Business Service; ToolResult DTO must use publicId only
|
||||||
|
- ADR-026: useAiChat() hook + side-panel UI; streaming response via SSE; TanStack Query cache
|
||||||
|
- ADR-027: Admin Console — dynamic model/prompt/intent control; CASL-guarded admin-only endpoints
|
||||||
|
|
||||||
|
**For Migration Pipeline (ADR-028):**
|
||||||
|
|
||||||
|
- Use Staging Queue pattern — never write directly to production tables
|
||||||
|
- Post-migration cleanup process required after each batch
|
||||||
|
- Migration Validation Gates must pass before promoting to production
|
||||||
|
|
||||||
|
**Expected output:**
|
||||||
|
|
||||||
|
- Backend services expose specialized context fields
|
||||||
|
- Frontend components use domain-specific patterns
|
||||||
|
- Complex state management with proper validation
|
||||||
|
- Performance metrics within acceptable thresholds
|
||||||
|
- Comprehensive test coverage for edge cases
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Context-Aware Triggers
|
||||||
|
|
||||||
|
| Request | Files to Check | Expected Response |
|
||||||
|
| --------------------------- | ------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
|
||||||
|
| "สร้าง API ใหม่" | `05-02-backend-guidelines.md`, `lcbp3-v1.9.0-schema-02-tables.sql` | NestJS Controller + Service + DTO + CASL Guard |
|
||||||
|
| "แก้ฟอร์ม frontend" | `05-03-frontend-guidelines.md`, `01-06-edge-cases-and-rules.md` | RHF+Zod + TanStack Query + Thai comments |
|
||||||
|
| "เพิ่ม field ใหม่" | `ADR-009`, `03-01-data-dictionary.md`, `lcbp3-v1.9.0-schema-02-tables.sql` | Edit SQL directly + update Data Dictionary + Entity |
|
||||||
|
| "ตรวจสอบ UUID" | `ADR-019`, `05-07-hybrid-uuid-implementation-plan.md` | UUIDv7 MariaDB native UUID + TransformInterceptor |
|
||||||
|
| "สร้าง migration" | `ADR-009`, `03-06-migration-business-scope.md` | Edit SQL schema directly + n8n workflow |
|
||||||
|
| "ตรวจสอบ permission" | `lcbp3-v1.9.0-seed-permissions.sql`, `ADR-016` | CASL 4-Level RBAC matrix |
|
||||||
|
| "deploy production" | `04-08-release-management-policy.md`, `ADR-015` | Release Gates + Blue-Green strategy |
|
||||||
|
| "เพิ่ม test" | `05-04-testing-strategy.md` | Coverage goals + test patterns |
|
||||||
|
| "AI integration" | `ADR-023`, `ADR-023A`, `ADR-024`, `ADR-025` | AI boundary + 2-model stack + BullMQ queue policy + Intent/Tool Layer |
|
||||||
|
| "Error handling" | `ADR-007` | Layered error classification + recovery |
|
||||||
|
| "File upload" | `ADR-016`, `05-02-backend-guidelines.md`, `03-Data-and-Storage/03-03-file-storage.md` | Two-phase upload → temp → commit; ClamAV + whitelist |
|
||||||
|
| "Notifications / Queue" | `ADR-008`, `05-02-backend-guidelines.md` | BullMQ job — never inline; check retry + dead-letter |
|
||||||
|
| "Add i18n / translate" | `05-08-i18n-guidelines.md` | i18n keys only — no hardcoded text |
|
||||||
|
| "Workflow / DSL" | `ADR-001`, `01-03-modules/01-03-06-unified-workflow.md` | DSL state machine + WorkflowEngineService |
|
||||||
|
| "Document numbering" | `ADR-002`, `01-02-business-rules/01-02-02-doc-numbering-rules.md` | Redis Redlock + DB optimistic lock (double-lock) |
|
||||||
|
| "ตรวจสอบ Workflow" | `01-06-edge-cases-and-rules.md`, `05-02-backend-guidelines.md`, `ADR-001`, `ADR-002` | เช็คการเปลี่ยน State, คิว BullMQ และการล็อกเลขที่เอกสาร |
|
||||||
|
| "Transmittal submit" | `ADR-021`, `specs/200-fullstacks/201-transmittals-circulation/` | submit() with EC-RFA-004 validation |
|
||||||
|
| "Circulation reassign" | `ADR-021`, `specs/200-fullstacks/201-transmittals-circulation/` | reassignRouting() with EC-CIRC-001 |
|
||||||
|
| "สร้าง workflow ใหม่" | `ADR-001`, `ADR-021`, `specs/200-fullstacks/203-unified-workflow-engine/` | DSL workflow definition + WorkflowEngineService setup |
|
||||||
|
| "ตรวจสอบ AI boundary" | `ADR-023`, `ADR-023A` | Verify Ollama isolation + BullMQ queues + Qdrant projectPublicId filter |
|
||||||
|
| "Intent classification" | `ADR-024`, `specs/200-fullstacks/224-intent-classification/` | Pattern Layer → LLM Fallback; ai_intent_patterns; Redis cache 5 min |
|
||||||
|
| "AI Tool Layer" | `ADR-025`, `specs/200-fullstacks/225-ai-tool-layer-architecture/` | Tool Registry; CASL-guarded dispatch; ToolResult publicId only |
|
||||||
|
| "Document Chat UI" | `ADR-026`, `specs/200-fullstacks/226-document-chat-ui-pattern/` | Side-panel; useAiChat() hook; streaming SSE; TanStack Query cache |
|
||||||
|
| "AI Admin Console" | `ADR-027`, `specs/200-fullstacks/227-ai-admin-console/` | Dynamic model/prompt/intent control; admin-only CASL endpoints |
|
||||||
|
| "Migration refactor" | `ADR-028`, `specs/200-fullstacks/228-migration-arch-refactor/` | Staging Queue; post-migration cleanup; validation gates |
|
||||||
|
| "จัดการ document numbering" | `ADR-002`, `specs/03-Data-and-Storage/03-04-document-numbering.md` | Redis Redlock + template system + preview/override workflows |
|
||||||
|
| "Audit ความปลอดภัย" | `ADR-016`, `ADR-019`, `ADR-023`, `ADR-023A` | ตรวจสอบ UUID pattern, CASL Guard, AI Boundary และ Qdrant multi-tenancy |
|
||||||
|
| "แก้ bug / bugfix" | `.agents/workflows/bugfix.md`, `error-catalog.md` | ใช้ bugfix workflow สำหรับเคสที่สาเหตุชัดเจน |
|
||||||
|
| "ตรวจแอปจริง" | `.windsurf/workflows/check-real-app.md` | ตรวจ endpoint/UI/console หลัง build pass — No Fake Evidence |
|
||||||
|
| "งานค้าง / resume" | `.windsurf/workflows/resume-pending-work.md` | อ่าน checkpoint เดิม → ตรวจ build → วางแผนต่อโดยไม่ทำงานซ้ำ |
|
||||||
@@ -7,7 +7,7 @@ trigger: always_on
|
|||||||
## CRITICAL RULES
|
## CRITICAL RULES
|
||||||
|
|
||||||
- **ALWAYS** follow ADR-023 AI boundary policy (isolation on Admin Desktop)
|
- **ALWAYS** follow ADR-023 AI boundary policy (isolation on Admin Desktop)
|
||||||
- **ALWAYS** use ADR-023A 2-model stack (gemma4:e4b Q8_0 + nomic-embed-text)
|
- **ALWAYS** use ADR-023A 2-model stack (gemma4:e2b + nomic-embed-text)
|
||||||
- **ALWAYS** use BullMQ 2-queue (ai-realtime + ai-batch) for GPU overload prevention
|
- **ALWAYS** use BullMQ 2-queue (ai-realtime + ai-batch) for GPU overload prevention
|
||||||
- **NEVER** allow AI direct database/storage access
|
- **NEVER** allow AI direct database/storage access
|
||||||
- **ALWAYS** implement human-in-the-loop validation
|
- **ALWAYS** implement human-in-the-loop validation
|
||||||
@@ -30,7 +30,7 @@ n8n (Migration) → DMS API → BullMQ → Admin Desktop (Ollama) → Backend Va
|
|||||||
| ----------------- | ------------------------- | ------------------------------------------------------------------------ |
|
| ----------------- | ------------------------- | ------------------------------------------------------------------------ |
|
||||||
| **AI Gateway** | Backend (NestJS) | API endpoints, validation, audit logging |
|
| **AI Gateway** | Backend (NestJS) | API endpoints, validation, audit logging |
|
||||||
| **BullMQ Queues** | Backend (NestJS) | ai-realtime (RAG/Suggest), ai-batch (OCR/Extract/Embed) |
|
| **BullMQ Queues** | Backend (NestJS) | ai-realtime (RAG/Suggest), ai-batch (OCR/Extract/Embed) |
|
||||||
| **Ollama Engine** | Admin Desktop (Desk-5439) | gemma4:e4b Q8_0 (LLM) + nomic-embed-text (Embedding) |
|
| **Ollama Engine** | Admin Desktop (Desk-5439) | gemma4:e2b (LLM) + nomic-embed-text (Embedding) |
|
||||||
| **OCR Engine** | Admin Desktop (Desk-5439) | PaddleOCR + PyThaiNLP (Thai/English text extraction) |
|
| **OCR Engine** | Admin Desktop (Desk-5439) | PaddleOCR + PyThaiNLP (Thai/English text extraction) |
|
||||||
| **Orchestrator** | QNAP NAS (n8n) | Migration Phase orchestrator only (calls DMS API, never Ollama directly) |
|
| **Orchestrator** | QNAP NAS (n8n) | Migration Phase orchestrator only (calls DMS API, never Ollama directly) |
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ export class AiService {
|
|||||||
async extractMetadata(documentId: string): Promise<AIMetadata> {
|
async extractMetadata(documentId: string): Promise<AIMetadata> {
|
||||||
// 1. Validate permissions
|
// 1. Validate permissions
|
||||||
// 2. Queue job to BullMQ (ai-batch or ai-realtime)
|
// 2. Queue job to BullMQ (ai-batch or ai-realtime)
|
||||||
// 3. Worker sends to Admin Desktop AI (gemma4:e4b Q8_0)
|
// 3. Worker sends to Admin Desktop AI (gemma4:e2b)
|
||||||
// 4. Validate AI response
|
// 4. Validate AI response
|
||||||
// 5. Log audit trail to ai_audit_logs
|
// 5. Log audit trail to ai_audit_logs
|
||||||
// 6. Return validated results
|
// 6. Return validated results
|
||||||
@@ -119,7 +119,7 @@ const DocumentReviewForm = ({ document, aiSuggestions }) => {
|
|||||||
|
|
||||||
## ADR-023A Specific Rules
|
## ADR-023A Specific Rules
|
||||||
|
|
||||||
- **2-Model Stack:** gemma4:e4b Q8_0 (~4.0GB) + nomic-embed-text (~0.3GB) = ~4.3GB VRAM peak
|
- **2-Model Stack:** gemma4:e2b + nomic-embed-text
|
||||||
- **PDF 3-Page Limit:** Classification/Tagging uses first 3 pages only (NOT RAG embedding)
|
- **PDF 3-Page Limit:** Classification/Tagging uses first 3 pages only (NOT RAG embedding)
|
||||||
- **RAG Embedding:** Full document chunked at 512 tokens/64 tokens overlap
|
- **RAG Embedding:** Full document chunked at 512 tokens/64 tokens overlap
|
||||||
- **OCR Auto-Detect:** PyMuPDF chars > 100 → Fast path, else PaddleOCR
|
- **OCR Auto-Detect:** PyMuPDF chars > 100 → Fast path, else PaddleOCR
|
||||||
@@ -133,7 +133,7 @@ const DocumentReviewForm = ({ document, aiSuggestions }) => {
|
|||||||
- [ ] BullMQ 2-queue setup (ai-realtime + ai-batch)
|
- [ ] BullMQ 2-queue setup (ai-realtime + ai-batch)
|
||||||
- [ ] QdrantService with projectPublicId enforcement
|
- [ ] QdrantService with projectPublicId enforcement
|
||||||
- [ ] DocumentReviewForm reusable component
|
- [ ] DocumentReviewForm reusable component
|
||||||
- [ ] Admin Desktop Ollama (gemma4:e4b Q8_0 + nomic-embed-text) + PaddleOCR setup
|
- [ ] Admin Desktop Ollama (gemma4:e2b + nomic-embed-text) + PaddleOCR setup
|
||||||
- [ ] n8n workflow orchestration (Migration Phase only)
|
- [ ] n8n workflow orchestration (Migration Phase only)
|
||||||
- [ ] AI audit logging and monitoring (ai_audit_logs)
|
- [ ] AI audit logging and monitoring (ai_audit_logs)
|
||||||
- [ ] Human-in-the-loop validation workflows
|
- [ ] Human-in-the-loop validation workflows
|
||||||
@@ -142,3 +142,8 @@ const DocumentReviewForm = ({ document, aiSuggestions }) => {
|
|||||||
|
|
||||||
- `specs/06-Decision-Records/ADR-023-unified-ai-architecture.md` (Base architecture)
|
- `specs/06-Decision-Records/ADR-023-unified-ai-architecture.md` (Base architecture)
|
||||||
- `specs/06-Decision-Records/ADR-023A-unified-ai-architecture.md` (Model revision - current)
|
- `specs/06-Decision-Records/ADR-023A-unified-ai-architecture.md` (Model revision - current)
|
||||||
|
- `specs/06-Decision-Records/ADR-024-intent-classification-strategy.md` (Pattern→LLM Fallback)
|
||||||
|
- `specs/06-Decision-Records/ADR-025-ai-tool-layer-architecture.md` (Tool Registry)
|
||||||
|
- `specs/06-Decision-Records/ADR-026-document-chat-ui-pattern.md` (Chat UI)
|
||||||
|
- `specs/06-Decision-Records/ADR-027-ai-admin-console-and-dynamic-control.md` (Admin Console)
|
||||||
|
- `specs/06-Decision-Records/ADR-028-migration-architecture-refactor.md` (Migration Pipeline)
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
---
|
||||||
|
trigger: always_on
|
||||||
|
---
|
||||||
|
|
||||||
|
# LCBP3 Agent Rules
|
||||||
|
|
||||||
|
Critical rules and guidelines for AI agents working on LCBP3-DMS.
|
||||||
|
|
||||||
|
## Version
|
||||||
|
|
||||||
|
- **Current:** v1.9.6
|
||||||
|
- **Last Updated:** 2026-05-22
|
||||||
|
- **Synced with:** `AGENTS.md` (v1.9.6)
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
This directory contains rule files that define:
|
||||||
|
|
||||||
|
- Project context and role expectations
|
||||||
|
- Critical Tier 1 rules (CI blockers)
|
||||||
|
- Coding standards and patterns
|
||||||
|
- Domain terminology and glossary
|
||||||
|
- Development workflows
|
||||||
|
- Security requirements
|
||||||
|
- AI integration architecture (ADR-023/023A)
|
||||||
|
|
||||||
|
## Rule Enforcement Tiers
|
||||||
|
|
||||||
|
### 🔴 Tier 1 — CRITICAL (CI BLOCKER)
|
||||||
|
|
||||||
|
Build fails immediately if violated:
|
||||||
|
|
||||||
|
- Security (Auth, RBAC, Validation)
|
||||||
|
- UUID Strategy (ADR-019) — no `parseInt` / `Number` / `+` on UUID
|
||||||
|
- Database correctness — verify schema before writing queries
|
||||||
|
- File upload security (ClamAV + whitelist)
|
||||||
|
- AI validation boundary (ADR-023)
|
||||||
|
- Error handling strategy (ADR-007)
|
||||||
|
- Forbidden patterns: `any`, `console.log`, UUID misuse, `id ?? ''` fallback
|
||||||
|
|
||||||
|
### 🟡 Tier 2 — IMPORTANT (CODE REVIEW)
|
||||||
|
|
||||||
|
Must fix before merge:
|
||||||
|
|
||||||
|
- Architecture patterns (thin controller, business logic in service)
|
||||||
|
- Test coverage (80%+ business logic, 70%+ backend overall)
|
||||||
|
- Cache invalidation
|
||||||
|
- Naming conventions
|
||||||
|
- TypeScript Standards: Missing JSDoc, explicit types, or file headers
|
||||||
|
|
||||||
|
### 🟢 Tier 3 — SPECIALIZED WORK
|
||||||
|
|
||||||
|
Requires domain-specific knowledge:
|
||||||
|
|
||||||
|
- **ADR-021 Integration:** Workflow Engine & Context implementation
|
||||||
|
- **AI Infrastructure:** ADR-023/023A boundary enforcement and pipeline usage
|
||||||
|
- **AI Runtime Layer:** ADR-024 Intent Classification, ADR-025 Tool Layer, ADR-026 Chat UI, ADR-027 Admin Console
|
||||||
|
- **Migration Pipeline:** ADR-028 Staging Queue & post-migration cleanup
|
||||||
|
- **Complex Business Logic:** Multi-step workflows with state management
|
||||||
|
- **Performance Optimization:** Database queries, caching strategies, bulk operations
|
||||||
|
|
||||||
|
### 🔵 Tier 4 — GUIDELINES
|
||||||
|
|
||||||
|
Best practice — follow when possible:
|
||||||
|
|
||||||
|
- Code style / formatting (Prettier handles)
|
||||||
|
- Comment completeness
|
||||||
|
- Minor optimizations
|
||||||
|
|
||||||
|
## Rule Files
|
||||||
|
|
||||||
|
### Core Rules (Tier 1 - CRITICAL)
|
||||||
|
|
||||||
|
| File | Purpose |
|
||||||
|
| ----------------------- | ------------------------------------------------------------------------------- |
|
||||||
|
| `00-project-context.md` | Project context, role & persona, tier classification, specs folder organization |
|
||||||
|
| `01-adr-019-uuid.md` | UUID handling strategy — no parseInt, use publicId only |
|
||||||
|
| `02-security.md` | Security requirements, checklist, ADR-023/023A AI boundaries |
|
||||||
|
|
||||||
|
### Coding Standards
|
||||||
|
|
||||||
|
| File | Purpose |
|
||||||
|
| ------------------------- | ------------------------------------------------------- |
|
||||||
|
| `03-typescript.md` | TypeScript rules, file headers, i18n guidelines |
|
||||||
|
| `06-backend-patterns.md` | NestJS patterns, UUID resolution, API response patterns |
|
||||||
|
| `07-frontend-patterns.md` | Next.js patterns, RHF+Zod+TanStack Query, UUID handling |
|
||||||
|
|
||||||
|
### Domain & Workflow
|
||||||
|
|
||||||
|
| File | Purpose |
|
||||||
|
| -------------------------- | ------------------------------------------------------------- |
|
||||||
|
| `04-domain-terminology.md` | DMS glossary, key spec files priority table |
|
||||||
|
| `08-development-flow.md` | Development workflow by work type (Critical/Normal/Quick Fix) |
|
||||||
|
|
||||||
|
### Compliance & Architecture
|
||||||
|
|
||||||
|
| File | Purpose |
|
||||||
|
| ------------------------- | -------------------------------------------------------------- |
|
||||||
|
| `05-forbidden-actions.md` | Actions that must never be done, schema changes, UUID handling |
|
||||||
|
| `09-commit-checklist.md` | Pre-commit verification, commit message format |
|
||||||
|
| `10-error-handling.md` | ADR-007 error handling strategy, layered classification |
|
||||||
|
| `11-ai-integration.md` | ADR-023/023A AI architecture, 2-model stack, BullMQ 2-queue |
|
||||||
|
|
||||||
|
## Key Spec Files Priority
|
||||||
|
|
||||||
|
Spec priority: **`06-Decision-Records`** > **`05-Engineering-Guidelines`** > others
|
||||||
|
|
||||||
|
| Document | Path | Use When |
|
||||||
|
| ------------------------------ | --------------------------------------------------------------------------- | --------------------------------- |
|
||||||
|
| **Glossary** | `specs/00-overview/00-02-glossary.md` | Verify domain terminology |
|
||||||
|
| **Schema Tables** | `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql` | Before writing any query |
|
||||||
|
| **Data Dictionary** | `specs/03-Data-and-Storage/03-01-data-dictionary.md` | Field meanings + business rules |
|
||||||
|
| **Edge Cases** | `specs/01-Requirements/01-06-edge-cases-and-rules.md` | Prevent bugs in flows |
|
||||||
|
| **ADR-019 UUID** | `specs/06-Decision-Records/ADR-019-hybrid-identifier-strategy.md` | UUID-related work |
|
||||||
|
| **ADR-023 AI** | `specs/06-Decision-Records/ADR-023-unified-ai-architecture.md` | AI integration work |
|
||||||
|
| **ADR-023A AI Model** | `specs/06-Decision-Records/ADR-023A-unified-ai-architecture.md` | 2-model stack, BullMQ 2-queue |
|
||||||
|
| **ADR-024 Intent Class.** | `specs/06-Decision-Records/ADR-024-intent-classification-strategy.md` | Pattern→LLM Fallback; Redis cache |
|
||||||
|
| **ADR-025 AI Tool Layer** | `specs/06-Decision-Records/ADR-025-ai-tool-layer-architecture.md` | Tool Registry; CASL-guarded |
|
||||||
|
| **ADR-026 Chat UI** | `specs/06-Decision-Records/ADR-026-document-chat-ui-pattern.md` | Side-panel; streaming SSE |
|
||||||
|
| **ADR-027 AI Admin Console** | `specs/06-Decision-Records/ADR-027-ai-admin-console-and-dynamic-control.md` | Dynamic control; admin-only |
|
||||||
|
| **ADR-028 Migration Refactor** | `specs/06-Decision-Records/ADR-028-migration-architecture-refactor.md` | Staging Queue; cleanup |
|
||||||
|
| **Backend Guidelines** | `specs/05-Engineering-Guidelines/05-02-backend-guidelines.md` | NestJS patterns |
|
||||||
|
| **Frontend Guidelines** | `specs/05-Engineering-Guidelines/05-03-frontend-guidelines.md` | Next.js patterns |
|
||||||
|
| **Testing Strategy** | `specs/05-Engineering-Guidelines/05-04-testing-strategy.md` | Coverage goals |
|
||||||
|
|
||||||
|
## Maintenance
|
||||||
|
|
||||||
|
When updating rules:
|
||||||
|
|
||||||
|
1. **Check AGENTS.md version** — Ensure rule files are synced
|
||||||
|
2. **Update version numbers** — Bump version in `00-project-context.md` only (03-typescript.md no longer has version)
|
||||||
|
3. **Review ADR references** — Ensure all ADR references are current (ADR-023, ADR-023A, ADR-024~028)
|
||||||
|
4. **Add new forbidden actions** — When new patterns are identified as violations
|
||||||
|
5. **Update key spec files table** — When new ADRs or guidelines are added
|
||||||
|
6. **Update Tier 3 SPECIALIZED WORK** — When new domain-specific workflows are added
|
||||||
|
|
||||||
|
## Related Documents
|
||||||
|
|
||||||
|
- `AGENTS.md` — Master agent configuration and context
|
||||||
|
- `specs/06-Decision-Records/` — All Architecture Decision Records
|
||||||
|
- `specs/05-Engineering-Guidelines/` — Backend, frontend, and testing guidelines
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# lcbp3 Development Guidelines
|
||||||
|
|
||||||
|
Auto-generated from all feature plans. Last updated: 2026-05-30
|
||||||
|
|
||||||
|
## Active Technologies
|
||||||
|
|
||||||
|
- TypeScript 5.x (NestJS 11 backend, Next.js 16 frontend), Python 3.11 (OCR sidecar)
|
||||||
|
+ Ollama (AI runtime), BullMQ (job queues), TypeORM (ORM), Redis (caching/locks), MariaDB 11.8 (database)
|
||||||
|
(232-typhoon-ocr-integration)
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```text
|
||||||
|
backend/
|
||||||
|
frontend/
|
||||||
|
tests/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
cd src [ONLY COMMANDS FOR ACTIVE TECHNOLOGIES][ONLY COMMANDS FOR ACTIVE TECHNOLOGIES] pytest [ONLY COMMANDS FOR ACTIVE TECHNOLOGIES][ONLY COMMANDS FOR ACTIVE TECHNOLOGIES] ruff check .
|
||||||
|
|
||||||
|
## Code Style
|
||||||
|
|
||||||
|
TypeScript 5.x (NestJS 11 backend, Next.js 16 frontend), Python 3.11 (OCR sidecar)
|
||||||
|
: Follow standard conventions
|
||||||
|
|
||||||
|
## Recent Changes
|
||||||
|
|
||||||
|
- 232-typhoon-ocr-integration: Added TypeScript 5.x (NestJS 11 backend, Next.js 16 frontend), Python 3.11 (OCR sidecar)
|
||||||
@@ -5,14 +5,14 @@
|
|||||||
|
|
||||||
**Project:** NAP-DMS (LCBP3) — Laem Chabang Port Phase 3 Document Management System
|
**Project:** NAP-DMS (LCBP3) — Laem Chabang Port Phase 3 Document Management System
|
||||||
**Stack:** NestJS 11 + Next.js 16 + TypeScript + MariaDB 11.8 + Redis + BullMQ + Elasticsearch + Ollama (on-prem AI)
|
**Stack:** NestJS 11 + Next.js 16 + TypeScript + MariaDB 11.8 + Redis + BullMQ + Elasticsearch + Ollama (on-prem AI)
|
||||||
**Version:** 1.8.9 (2026-04-18)
|
**Version:** 1.9.7 (2026-05-25)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📌 Canonical Rule Sources (read in this order)
|
## 📌 Canonical Rule Sources (read in this order)
|
||||||
|
|
||||||
1. **`AGENTS.md`** (repo root) — primary rule file for AI agents; supersedes legacy `GEMINI.md`.
|
1. **`AGENTS.md`** (repo root) — primary rule file for AI agents; supersedes legacy `GEMINI.md`.
|
||||||
2. **`specs/06-Decision-Records/`** — architectural decisions (22 ADRs); ADR priority > Engineering Guidelines.
|
2. **`specs/06-Decision-Records/`** — architectural decisions (29 ADRs); ADR priority > Engineering Guidelines.
|
||||||
3. **`specs/05-Engineering-Guidelines/`** — backend/frontend/testing/i18n/git patterns.
|
3. **`specs/05-Engineering-Guidelines/`** — backend/frontend/testing/i18n/git patterns.
|
||||||
4. **`specs/00-Overview/00-02-glossary.md`** — domain terminology (Correspondence / RFA / Transmittal / Circulation).
|
4. **`specs/00-Overview/00-02-glossary.md`** — domain terminology (Correspondence / RFA / Transmittal / Circulation).
|
||||||
5. **`specs/00-Overview/00-03-product-vision.md`** — project constitution (Vision, Strategic Pillars, Guardrails).
|
5. **`specs/00-Overview/00-03-product-vision.md`** — project constitution (Vision, Strategic Pillars, Guardrails).
|
||||||
@@ -29,6 +29,7 @@
|
|||||||
- **ADR-002 Document Numbering:** Redis Redlock + TypeORM `@VersionColumn` (double-lock). Never use application-side counter alone.
|
- **ADR-002 Document Numbering:** Redis Redlock + TypeORM `@VersionColumn` (double-lock). Never use application-side counter alone.
|
||||||
- **ADR-008 Notifications:** BullMQ queue — never inline email/notification in a request thread.
|
- **ADR-008 Notifications:** BullMQ queue — never inline email/notification in a request thread.
|
||||||
- **ADR-023/023A AI Boundary:** Ollama on Admin Desktop only; AI → DMS API → DB (never direct DB/storage). 2-model stack: `gemma4:e4b Q8_0` + `nomic-embed-text`. BullMQ `ai-realtime` / `ai-batch` queues. Human-in-the-loop validation required. (ADR-018 superseded by ADR-023)
|
- **ADR-023/023A AI Boundary:** Ollama on Admin Desktop only; AI → DMS API → DB (never direct DB/storage). 2-model stack: `gemma4:e4b Q8_0` + `nomic-embed-text`. BullMQ `ai-realtime` / `ai-batch` queues. Human-in-the-loop validation required. (ADR-018 superseded by ADR-023)
|
||||||
|
- **ADR-029 Dynamic Prompt Management:** Prompt templates in DB (`ai_prompts`), never hardcoded in processor; Redis cache `ai:prompt:active:{type}` TTL 60s; `activate()` runs in DB transaction + Redis DEL after commit; `system.manage_all` guard on all mutations.
|
||||||
- **ADR-007 Error Handling:** Layered (Validation / Business / System); `BusinessException` hierarchy; user-friendly `userMessage` + `recoveryAction`; technical stack only in logs.
|
- **ADR-007 Error Handling:** Layered (Validation / Business / System); `BusinessException` hierarchy; user-friendly `userMessage` + `recoveryAction`; technical stack only in logs.
|
||||||
- **TypeScript Strict:** Zero `any`, zero `console.log` (use NestJS `Logger`).
|
- **TypeScript Strict:** Zero `any`, zero `console.log` (use NestJS `Logger`).
|
||||||
- **i18n:** No hardcoded Thai/English strings in components — use i18n keys (see `05-08-i18n-guidelines.md`).
|
- **i18n:** No hardcoded Thai/English strings in components — use i18n keys (see `05-08-i18n-guidelines.md`).
|
||||||
@@ -54,7 +55,7 @@
|
|||||||
## 📁 Key Files for Generating / Validating Artifacts
|
## 📁 Key Files for Generating / Validating Artifacts
|
||||||
|
|
||||||
| When you need... | Read |
|
| When you need... | Read |
|
||||||
| ------------------------- | ------------------------------------------------------------------------------------------------------------------- |
|
| -------------------------- | ------------------------------------------------------------------------------------------------------------------- |
|
||||||
| A new feature spec | `.agents/skills/speckit-specify/templates/spec-template.md` + `specs/01-Requirements/01-06-edge-cases-and-rules.md` |
|
| A new feature spec | `.agents/skills/speckit-specify/templates/spec-template.md` + `specs/01-Requirements/01-06-edge-cases-and-rules.md` |
|
||||||
| A plan | `.agents/skills/speckit-plan/templates/plan-template.md` + relevant ADRs |
|
| A plan | `.agents/skills/speckit-plan/templates/plan-template.md` + relevant ADRs |
|
||||||
| Task breakdown | `.agents/skills/speckit-tasks/templates/tasks-template.md` + existing patterns in `specs/08-Tasks/` |
|
| Task breakdown | `.agents/skills/speckit-tasks/templates/tasks-template.md` + existing patterns in `specs/08-Tasks/` |
|
||||||
@@ -62,6 +63,12 @@
|
|||||||
| Schema / table definition | `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql` + `03-01-data-dictionary.md` |
|
| Schema / table definition | `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql` + `03-01-data-dictionary.md` |
|
||||||
| RBAC / permissions | `specs/03-Data-and-Storage/lcbp3-v1.8.0-seed-permissions.sql` + `01-02-01-rbac-matrix.md` |
|
| RBAC / permissions | `specs/03-Data-and-Storage/lcbp3-v1.8.0-seed-permissions.sql` + `01-02-01-rbac-matrix.md` |
|
||||||
| Release / hotfix | `specs/04-Infrastructure-OPS/04-08-release-management-policy.md` |
|
| Release / hotfix | `specs/04-Infrastructure-OPS/04-08-release-management-policy.md` |
|
||||||
|
| ADR-024 Intent Class. | `specs/06-Decision-Records/ADR-024-intent-classification-strategy.md` |
|
||||||
|
| ADR-025 AI Tool Layer | `specs/06-Decision-Records/ADR-025-ai-tool-layer-architecture.md` |
|
||||||
|
| ADR-026 Chat UI | `specs/06-Decision-Records/ADR-026-document-chat-ui-pattern.md` |
|
||||||
|
| ADR-027 AI Admin Console | `specs/06-Decision-Records/ADR-027-ai-admin-console-and-dynamic-control.md` |
|
||||||
|
| ADR-028 Migration Refactor | `specs/06-Decision-Records/ADR-028-migration-architecture-refactor.md` |
|
||||||
|
| ADR-029 Dynamic Prompts | `specs/06-Decision-Records/ADR-029-dynamic-prompt-management.md` |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -83,7 +90,7 @@
|
|||||||
- [ ] Business comments in Thai, code identifiers in English
|
- [ ] Business comments in Thai, code identifiers in English
|
||||||
- [ ] Schema changes via SQL directly (not migration)
|
- [ ] Schema changes via SQL directly (not migration)
|
||||||
- [ ] Test coverage meets targets (Backend 70%+, Business Logic 80%+)
|
- [ ] Test coverage meets targets (Backend 70%+, Business Logic 80%+)
|
||||||
- [ ] Relevant ADRs referenced (007/008/009/016/019/021/023/023A for AI work)
|
- [ ] Relevant ADRs referenced (007/008/009/016/019/021/023/023A/024-029 for AI work)
|
||||||
- [ ] Domain glossary terms used correctly
|
- [ ] Domain glossary terms used correctly
|
||||||
- [ ] Error handling: `Logger` + `HttpException` / `BusinessException`
|
- [ ] Error handling: `Logger` + `HttpException` / `BusinessException`
|
||||||
- [ ] i18n keys used (no hardcode text)
|
- [ ] i18n keys used (no hardcode text)
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user