690608:0012 ADR-035-135 #08
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# NAP-DMS Project Context & Rules
|
||||
|
||||
- For: Windsurf Cascade (and compatible: Codex CLI, opencode, Amp, Antigravity, AGENTS.md tools)
|
||||
- For: Devin Cascade (and compatible: Codex CLI, opencode, Amp, Antigravity, AGENTS.md tools)
|
||||
- Version: 1.9.10 | Last synced from repo: 2026-06-06
|
||||
- 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)
|
||||
|
||||
@@ -42,7 +42,7 @@ init_agent_registry() {
|
||||
[qwen]="Qwen Code"
|
||||
[opencode]="opencode"
|
||||
[codex]="Codex CLI"
|
||||
[windsurf]="Windsurf"
|
||||
[devin]="Devin"
|
||||
[kilocode]="Kilo Code"
|
||||
[auggie]="Auggie CLI"
|
||||
[roo]="Roo Code"
|
||||
|
||||
@@ -30,12 +30,12 @@
|
||||
#
|
||||
# 5. Multi-Agent Support
|
||||
# - Handles agent-specific file paths and naming conventions
|
||||
# - Supports: Claude, Gemini, Copilot, Cursor, Qwen, opencode, Codex, Windsurf, Kilo Code, Auggie CLI, Roo Code, CodeBuddy CLI, Qoder CLI, Amp, SHAI, or Amazon Q Developer CLI
|
||||
# - Supports: Claude, Gemini, Copilot, Cursor, Qwen, opencode, Codex, Devin, Kilo Code, Auggie CLI, Roo Code, CodeBuddy CLI, Qoder CLI, Amp, SHAI, or Amazon Q Developer CLI
|
||||
# - Can update single agents or all existing agent files
|
||||
# - Creates default Claude file if no agent files exist
|
||||
#
|
||||
# Usage: ./update-agent-context.sh [agent_type]
|
||||
# Agent types: claude|gemini|copilot|cursor-agent|qwen|opencode|codex|windsurf|kilocode|auggie|shai|q|bob|qoder
|
||||
# Agent types: claude|gemini|copilot|cursor-agent|qwen|opencode|codex|devin|kilocode|auggie|shai|q|bob|qoder
|
||||
# Leave empty to update all existing agent files
|
||||
|
||||
set -e
|
||||
@@ -609,8 +609,8 @@ update_specific_agent() {
|
||||
codex)
|
||||
update_agent_file "$AGENTS_FILE" "Codex CLI"
|
||||
;;
|
||||
windsurf)
|
||||
update_agent_file "$WINDSURF_FILE" "Windsurf"
|
||||
devin)
|
||||
update_agent_file "$DEVIN_FILE" "Devin"
|
||||
;;
|
||||
kilocode)
|
||||
update_agent_file "$KILOCODE_FILE" "Kilo Code"
|
||||
@@ -681,8 +681,8 @@ update_all_existing_agents() {
|
||||
found_agent=true
|
||||
fi
|
||||
|
||||
if [[ -f "$WINDSURF_FILE" ]]; then
|
||||
update_agent_file "$WINDSURF_FILE" "Windsurf"
|
||||
if [[ -f "$DEVIN_FILE" ]]; then
|
||||
update_agent_file "$DEVIN_FILE" "Devin"
|
||||
found_agent=true
|
||||
fi
|
||||
|
||||
|
||||
+15
-16
@@ -1,8 +1,8 @@
|
||||
# `.agents/skills/` — LCBP3 Agent Skill Pack
|
||||
|
||||
**Version:** 1.9.0 | **Last Updated:** 2026-05-17 | **Total Skills:** 23
|
||||
**Version:** 1.9.0 | **Last Updated:** 2026-06-07 | **Total Skills:** 24
|
||||
|
||||
Agent skills for AI-assisted development in **Windsurf IDE** (and compatible agents: Codex CLI, opencode, Amp, Antigravity, AGENTS.md-aware tools).
|
||||
Agent skills for AI-assisted development in **Devin IDE** (and compatible agents: Codex CLI, opencode, Amp, Antigravity, AGENTS.md-aware tools).
|
||||
|
||||
---
|
||||
|
||||
@@ -14,6 +14,7 @@ Agent skills for AI-assisted development in **Windsurf IDE** (and compatible age
|
||||
├── skills.md # Overview + dependency matrix + health monitoring
|
||||
├── _LCBP3-CONTEXT.md # Shared LCBP3 context injected into every speckit-* skill
|
||||
├── README.md # (this file)
|
||||
├── save-memory/ # Session log & project memory update
|
||||
├── nestjs-best-practices/ # Backend rules (40 rules across 10 categories)
|
||||
├── next-best-practices/ # Frontend rules (Next.js 15+)
|
||||
├── e2e-testing/ # Playwright E2E testing patterns (POM, flaky tests, CI/CD)
|
||||
@@ -30,12 +31,10 @@ Each skill directory contains:
|
||||
|
||||
---
|
||||
|
||||
## 🚀 How Windsurf Invokes These Skills
|
||||
## 🚀 How Devin Invokes These Skills
|
||||
|
||||
Windsurf exposes two entry points:
|
||||
|
||||
1. **Skill tool** — Windsurf discovers skills by scanning `.agents/skills/*/SKILL.md` frontmatter. Skills marked `user-invocable: false` are used silently by Cascade.
|
||||
2. **Slash commands** — `.windsurf/workflows/*.md` wraps each skill as a slash command (e.g. `/04-speckit.plan`). The workflow file is short; the heavy lifting is delegated to the skill via `skill` tool.
|
||||
1. **Skill tool** — Devin discovers skills by scanning `.agents/skills/*/SKILL.md` frontmatter. Skills marked `user-invocable: false` are used silently by Cascade.
|
||||
2. **Slash commands** — `.devin/workflows/*.md` wraps each skill as a slash command (e.g. `/04-speckit.plan`). The workflow file is short; the heavy lifting is delegated to the skill via `skill` tool.
|
||||
|
||||
Both paths end up executing the same `SKILL.md` instructions.
|
||||
|
||||
@@ -65,14 +64,14 @@ Use `/00-speckit.all` to run specify → clarify → plan → tasks → analyze
|
||||
|
||||
From repo root:
|
||||
|
||||
| Script | Purpose |
|
||||
| --------------------------------------------------------- | ----------------------------------------------------------- |
|
||||
| `./.agents/scripts/bash/check-prerequisites.sh --json` | Emit `FEATURE_DIR` + `AVAILABLE_DOCS` for a feature branch |
|
||||
| `./.agents/scripts/bash/setup-plan.sh --json` | Emit `FEATURE_SPEC`, `IMPL_PLAN`, `SPECS_DIR`, `BRANCH` |
|
||||
| `./.agents/scripts/bash/update-agent-context.sh windsurf` | Append tech entries to `AGENTS.md` |
|
||||
| `./.agents/scripts/bash/audit-skills.sh` | Validate all `SKILL.md` frontmatter + presence |
|
||||
| `./.agents/scripts/bash/validate-versions.sh` | Version consistency check |
|
||||
| `./.agents/scripts/bash/sync-workflows.sh` | Verify every skill has a `.windsurf/workflows/*.md` wrapper |
|
||||
| Script | Purpose |
|
||||
| ------------------------------------------------------ | ---------------------------------------------------------- |
|
||||
| `./.agents/scripts/bash/check-prerequisites.sh --json` | Emit `FEATURE_DIR` + `AVAILABLE_DOCS` for a feature branch |
|
||||
| `./.agents/scripts/bash/setup-plan.sh --json` | Emit `FEATURE_SPEC`, `IMPL_PLAN`, `SPECS_DIR`, `BRANCH` |
|
||||
| `./.agents/scripts/bash/update-agent-context.sh devin` | Append tech entries to `AGENTS.md` |
|
||||
| `./.agents/scripts/bash/audit-skills.sh` | Validate all `SKILL.md` frontmatter + presence |
|
||||
| `./.agents/scripts/bash/validate-versions.sh` | Version consistency check |
|
||||
| `./.agents/scripts/bash/sync-workflows.sh` | Verify every skill has a `.devin/workflows/*.md` wrapper |
|
||||
|
||||
All scripts mirror to `.agents/scripts/powershell/*.ps1` for Windows.
|
||||
|
||||
@@ -97,7 +96,7 @@ To add a new skill:
|
||||
|
||||
1. Create `NAME/SKILL.md` with frontmatter: `name`, `description`, `version: 1.9.0`, `scope`, `depends-on`.
|
||||
2. Append an LCBP3 context reference pointing to `_LCBP3-CONTEXT.md`.
|
||||
3. Wrap with `.windsurf/workflows/NAME.md` so it becomes a slash command.
|
||||
3. Wrap with `.devin/workflows/NAME.md` so it becomes a slash command.
|
||||
4. Update [`skills.md`](./skills.md) dependency matrix.
|
||||
5. Run `./.agents/scripts/bash/audit-skills.sh` → must pass.
|
||||
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
---
|
||||
name: save-memory
|
||||
description: บันทึก session log และอัปเดต project memory ตามโครงสร้างใหม่
|
||||
version: 1.9.0
|
||||
scope: project-management
|
||||
depends-on: []
|
||||
user-invocable: true
|
||||
---
|
||||
|
||||
# บันทึก Memory (Save Memory)
|
||||
|
||||
Skill นี้ใช้สำหรับบันทึก session log และอัปเดต project memory ตามโครงสร้างใหม่ที่ reorganization แล้ว
|
||||
|
||||
## โครงสร้าง Memory ใหม่
|
||||
|
||||
```
|
||||
memory/
|
||||
├── README.md (index + overview)
|
||||
├── mcp-tools.md (MCP MariaDB + Memory Tools)
|
||||
└── project-memory-override.md (OS rules, Current Decisions, Environment, Next Session Focus)
|
||||
|
||||
specs/88-logs/
|
||||
├── rollouts.md (Recent rollouts table)
|
||||
└── session-YYYY-MM-DD-[topic].md (Session logs)
|
||||
```
|
||||
|
||||
## ขั้นตอนการบันทึก Memory
|
||||
|
||||
### 1. สร้าง Session Log (ถ้ามีงาน session ใหม่)
|
||||
|
||||
เมื่อทำงาน session ใหม่ให้:
|
||||
|
||||
1. **สร้างไฟล์ session log ใหม่** ใน `specs/88-logs/`
|
||||
- ชื่อไฟล์: `session-YYYY-MM-DD-[topic].md`
|
||||
- ตัวอย่าง: `session-2026-06-07-memory-reorganization.md`
|
||||
|
||||
2. **บันทึกเนื้อหาใน session log**:
|
||||
|
||||
```markdown
|
||||
# Session [N] — YYYY-MM-DD ([Topic])
|
||||
|
||||
## Summary
|
||||
|
||||
[สรุปสิ่งที่ทำใน session นี้]
|
||||
|
||||
## ปัญหาที่พบ (Root Cause)
|
||||
|
||||
[อธิบายปัญหาและสาเหตุ]
|
||||
|
||||
## การแก้ไข (Fix)
|
||||
|
||||
| ไฟล์ | การเปลี่ยนแปลง |
|
||||
| -------------- | ---------------------- |
|
||||
| [path/to/file] | [อธิบายการเปลี่ยนแปลง] |
|
||||
|
||||
## กฎที่ Lock แล้ว
|
||||
|
||||
[บันทึก pattern หรือ decision ที่ตกลง]
|
||||
|
||||
## Verification
|
||||
|
||||
[วิธีตรวจสอบว่างานสำเร็จ]
|
||||
```
|
||||
|
||||
3. **อัปเดต `specs/88-logs/rollouts.md`**
|
||||
- เพิ่ม entry ใหม่ในตาราง Recent Rollouts
|
||||
- รูปแบบ: `| วันที่ | Version | รายการ | สถานะ |`
|
||||
|
||||
### 2. อัปเดต Project Memory (ถ้ามี decision ใหม่)
|
||||
|
||||
เมื่อมีการตัดสินใจสำคัญใหม่ให้:
|
||||
|
||||
1. **เปิดไฟล์ `memory/project-memory-override.md`**
|
||||
|
||||
2. **อัปเดตตาราง "Current Decisions (Locked)"**
|
||||
- เพิ่ม entry ใหม่ถ้ามี decision ใหม่
|
||||
- รูปแบบ: `| ID | Decision | ADR |`
|
||||
|
||||
3. **อัปเดต "Next Session Focus"**
|
||||
- เพิ่มงานใหม่ถ้ามี
|
||||
- ทำเครื่องหมาย `[ ]` สำหรับงานที่ยังไม่เสร็จ
|
||||
- ทำเครื่องหมาย `[X]` สำหรับงานที่เสร็จแล้ว
|
||||
|
||||
4. **อัปเดต "Environment & Services"** (ถ้ามีการเปลี่ยนแปลง)
|
||||
- อัปเดต URL, port, หรือ notes ถ้ามีการเปลี่ยน infrastructure
|
||||
|
||||
### 3. อัปเดต MCP Tools (ถ้ามี tools ใหม่)
|
||||
|
||||
เมื่อมี MCP tools ใหม่ให้:
|
||||
|
||||
1. **เปิดไฟล์ `memory/mcp-tools.md`**
|
||||
|
||||
2. **เพิ่ม tool ใหม่ในตาราง "Available Tools"**
|
||||
- รูปแบบ: `| Tool | Purpose | Example Usage |`
|
||||
|
||||
3. **เพิ่ม usage example และ warnings** ถ้าจำเป็น
|
||||
|
||||
### 4. อัปเดต Root Documentation (ถ้ามีการเปลี่ยนแปลง)
|
||||
|
||||
เมื่อมีการเปลี่ยนแปลงที่ส่งผลต่อเอกสารระดับ root ให้:
|
||||
|
||||
1. **ARCHITECTURE.md** — อัปเดตเมื่อ:
|
||||
- เปลี่ยน architecture หลัก
|
||||
- เพิ่ม/ลบ component สำคัญ
|
||||
- เปลี่ยน data flow หรือ integration pattern
|
||||
|
||||
2. **CHANGELOG.md** — อัปเดตเมื่อ:
|
||||
- Deploy version ใหม่
|
||||
- เพิ่ม feature หรือ breaking change สำคัญ
|
||||
- รูปแบบ: `## [version] (YYYY-MM-DD)` → `### feat(scope): description`
|
||||
|
||||
3. **CONTEXT.md** — อัปเดตเมื่อ:
|
||||
- เปลี่ยน domain terminology หลัก
|
||||
- เพิ่ม concept ใหม่ที่ใช้ทั่ว project
|
||||
- อัปเดต glossary หรือ business rules
|
||||
|
||||
4. **CONTRIBUTING.md** — อัปเดตเมื่อ:
|
||||
- เปลี่ยน workflow การทำงาน
|
||||
- เพิ่ม/เปลี่ยน coding standards
|
||||
- อัปเดต CI/CD process
|
||||
|
||||
5. **README.md** — อัปเดตเมื่อ:
|
||||
- เปลี่ยน project structure
|
||||
- เพิ่ม/เปลี่ยน installation steps
|
||||
- อัปเดต feature overview หรือ tech stack
|
||||
|
||||
## Template สำหรับ Session Log
|
||||
|
||||
```markdown
|
||||
# Session [N] — YYYY-MM-DD ([Topic])
|
||||
|
||||
## Summary
|
||||
|
||||
[สรุปสิ่งที่ทำใน session นี้ใน 1-2 ประโยค]
|
||||
|
||||
## ปัญหาที่พบ (Root Cause)
|
||||
|
||||
[อธิบายปัญหาและสาเหตุหลัก]
|
||||
|
||||
## การแก้ไข (Fix)
|
||||
|
||||
| ไฟล์ | การเปลี่ยนแปลง |
|
||||
| -------------- | ---------------------- |
|
||||
| `path/to/file` | [อธิบายการเปลี่ยนแปลง] |
|
||||
|
||||
## กฎที่ Lock แล้ว
|
||||
|
||||
[บันทึก pattern หรือ decision ที่ตกลงและไม่ควรเปลี่ยน]
|
||||
|
||||
## Verification
|
||||
|
||||
- [ ] [check 1]
|
||||
- [ ] [check 2]
|
||||
```
|
||||
|
||||
## ข้อควรระวัง
|
||||
|
||||
- **ห้าม** บันทึก rules ที่ซ้ำกับ specs/ (ADRs, glossary, guidelines)
|
||||
- **ห้าม** บันทึก commands ที่ซ้ำกับ specs/05-Engineering-Guidelines/
|
||||
- **ห้าม** บันทึก environment ที่ซ้ำกับ specs/04-Infrastructure-OPS/
|
||||
- **ใช้** `specs/88-logs/` สำหรับ session history และ rollouts
|
||||
- **ใช้** `memory/project-memory-override.md` สำหรับ OS rules, decisions, environment ที่ไม่มีใน specs
|
||||
- **ใช้** `memory/mcp-tools.md` สำหรับ MCP tools documentation
|
||||
- **อัปเดต Root Documentation** (ARCHITECTURE.md, CHANGELOG.md, CONTEXT.md, CONTRIBUTING.md, README.md) เฉพาะเมื่อมีการเปลี่ยนแปลงที่ส่งผลต่อ project architecture, version, terminology, workflow หรือ structure
|
||||
|
||||
## ตัวอย่างการใช้งาน
|
||||
|
||||
### กรณีที่ 1: ทำงาน session ใหม่
|
||||
|
||||
```
|
||||
1. สร้างไฟล์ specs/88-logs/session-2026-06-07-bug-fix.md
|
||||
2. บันทึกปัญหา, การแก้ไข, verification
|
||||
3. อัปเดต specs/88-logs/rollouts.md
|
||||
```
|
||||
|
||||
### กรณีที่ 2: มี decision ใหม่
|
||||
|
||||
```
|
||||
1. เปิด memory/project-memory-override.md
|
||||
2. เพิ่ม entry ใหม่ในตาราง Current Decisions
|
||||
3. อัปเดต Next Session Focus
|
||||
```
|
||||
|
||||
### กรณีที่ 3: เปลี่ยน infrastructure
|
||||
|
||||
```
|
||||
1. เปิด memory/project-memory-override.md
|
||||
2. อัปเดตตาราง Environment & Services
|
||||
3. อัปเดต Key Environment Variables ถ้าจำเป็น
|
||||
```
|
||||
|
||||
### กรณีที่ 4: อัปเดต Root Documentation
|
||||
|
||||
```
|
||||
1. ตรวจสอบว่ามีการเปลี่ยนแปลงที่ส่งผลต่อ ARCHITECTURE.md, CHANGELOG.md, CONTEXT.md, CONTRIBUTING.md, หรือ README.md
|
||||
2. อัปเดตไฟล์ที่เกี่ยวข้องตามรูปแบบที่กำหนด
|
||||
3. ตรวจสอบว่าการเปลี่ยนแปลงสอดคล้องกับ specs/ และ ADRs
|
||||
```
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
ไฟล์นี้กำหนดทักษะและความสามารถเฉพาะทางของ Document Intelligence Engine สำหรับโครงการ LCBP3 v1.9.0 เพื่อรักษามาตรฐานสูงสุดด้าน Security และ Data Integrity
|
||||
|
||||
**Status**: Production Ready | **Last Updated**: 2026-05-17 | **Total Skills**: 23
|
||||
**Status**: Production Ready | **Last Updated**: 2026-06-07 | **Total Skills**: 24
|
||||
|
||||
> 📌 Shared context for all speckit-\* skills: see [`_LCBP3-CONTEXT.md`](./_LCBP3-CONTEXT.md).
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
| **speckit-status** | None | None | Progress tracking |
|
||||
| **speckit-taskstoissues** | speckit-tasks | None | Issue sync |
|
||||
| **speckit-checklist** | speckit-plan | None | Requirements validation |
|
||||
| **save-memory** | None | None | Session log & memory update |
|
||||
| **nestjs-best-practices** | None | speckit-implement | Backend patterns |
|
||||
| **next-best-practices** | None | speckit-implement | Frontend patterns |
|
||||
| **speckit-security-audit** | None | speckit-reviewer | Security validation |
|
||||
@@ -99,7 +100,7 @@
|
||||
|
||||
### Health Metrics
|
||||
|
||||
- **Total Skills**: 23 implemented
|
||||
- **Total Skills**: 24 implemented
|
||||
- **Version Alignment**: v1.9.0 across all skills
|
||||
- **Template Coverage**: 100% for skills requiring templates
|
||||
- **Documentation**: Complete front matter + shared `_LCBP3-CONTEXT.md` appendix
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
description: บันทึก session log และอัปเดต project memory
|
||||
---
|
||||
|
||||
# บันทึก Memory
|
||||
|
||||
ใช้ skill `save-memory` เพื่อบันทึก session log และอัปเดต project memory ตามโครงสร้างใหม่
|
||||
|
||||
```bash
|
||||
skill save-memory
|
||||
```
|
||||
@@ -4,7 +4,7 @@ trigger: always_on
|
||||
|
||||
# NAP-DMS Project Context & Rules
|
||||
|
||||
- For: Windsurf Cascade (and compatible: Codex CLI, opencode, Amp, Antigravity, AGENTS.md tools)
|
||||
- For: Devin Cascade (and compatible: Codex CLI, opencode, Amp, Antigravity, AGENTS.md tools)
|
||||
- Version: 1.9.10 | Last synced from repo: 2026-06-06
|
||||
- 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)
|
||||
|
||||
+15
-16
@@ -1,8 +1,8 @@
|
||||
# `.agents/skills/` — LCBP3 Agent Skill Pack
|
||||
|
||||
**Version:** 1.9.0 | **Last Updated:** 2026-05-17 | **Total Skills:** 23
|
||||
**Version:** 1.9.0 | **Last Updated:** 2026-06-07 | **Total Skills:** 24
|
||||
|
||||
Agent skills for AI-assisted development in **Windsurf IDE** (and compatible agents: Codex CLI, opencode, Amp, Antigravity, AGENTS.md-aware tools).
|
||||
Agent skills for AI-assisted development in **Devin IDE** (and compatible agents: Codex CLI, opencode, Amp, Antigravity, AGENTS.md-aware tools).
|
||||
|
||||
---
|
||||
|
||||
@@ -14,6 +14,7 @@ Agent skills for AI-assisted development in **Windsurf IDE** (and compatible age
|
||||
├── skills.md # Overview + dependency matrix + health monitoring
|
||||
├── _LCBP3-CONTEXT.md # Shared LCBP3 context injected into every speckit-* skill
|
||||
├── README.md # (this file)
|
||||
├── save-memory/ # Session log & project memory update
|
||||
├── nestjs-best-practices/ # Backend rules (40 rules across 10 categories)
|
||||
├── next-best-practices/ # Frontend rules (Next.js 15+)
|
||||
├── e2e-testing/ # Playwright E2E testing patterns (POM, flaky tests, CI/CD)
|
||||
@@ -30,12 +31,10 @@ Each skill directory contains:
|
||||
|
||||
---
|
||||
|
||||
## 🚀 How Windsurf Invokes These Skills
|
||||
## 🚀 How Devin Invokes These Skills
|
||||
|
||||
Windsurf exposes two entry points:
|
||||
|
||||
1. **Skill tool** — Windsurf discovers skills by scanning `.agents/skills/*/SKILL.md` frontmatter. Skills marked `user-invocable: false` are used silently by Cascade.
|
||||
2. **Slash commands** — `.windsurf/workflows/*.md` wraps each skill as a slash command (e.g. `/04-speckit.plan`). The workflow file is short; the heavy lifting is delegated to the skill via `skill` tool.
|
||||
1. **Skill tool** — Devin discovers skills by scanning `.agents/skills/*/SKILL.md` frontmatter. Skills marked `user-invocable: false` are used silently by Cascade.
|
||||
2. **Slash commands** — `.devin/workflows/*.md` wraps each skill as a slash command (e.g. `/04-speckit.plan`). The workflow file is short; the heavy lifting is delegated to the skill via `skill` tool.
|
||||
|
||||
Both paths end up executing the same `SKILL.md` instructions.
|
||||
|
||||
@@ -65,14 +64,14 @@ Use `/00-speckit.all` to run specify → clarify → plan → tasks → analyze
|
||||
|
||||
From repo root:
|
||||
|
||||
| Script | Purpose |
|
||||
| --------------------------------------------------------- | ----------------------------------------------------------- |
|
||||
| `./.agents/scripts/bash/check-prerequisites.sh --json` | Emit `FEATURE_DIR` + `AVAILABLE_DOCS` for a feature branch |
|
||||
| `./.agents/scripts/bash/setup-plan.sh --json` | Emit `FEATURE_SPEC`, `IMPL_PLAN`, `SPECS_DIR`, `BRANCH` |
|
||||
| `./.agents/scripts/bash/update-agent-context.sh windsurf` | Append tech entries to `AGENTS.md` |
|
||||
| `./.agents/scripts/bash/audit-skills.sh` | Validate all `SKILL.md` frontmatter + presence |
|
||||
| `./.agents/scripts/bash/validate-versions.sh` | Version consistency check |
|
||||
| `./.agents/scripts/bash/sync-workflows.sh` | Verify every skill has a `.windsurf/workflows/*.md` wrapper |
|
||||
| Script | Purpose |
|
||||
| ------------------------------------------------------ | ---------------------------------------------------------- |
|
||||
| `./.agents/scripts/bash/check-prerequisites.sh --json` | Emit `FEATURE_DIR` + `AVAILABLE_DOCS` for a feature branch |
|
||||
| `./.agents/scripts/bash/setup-plan.sh --json` | Emit `FEATURE_SPEC`, `IMPL_PLAN`, `SPECS_DIR`, `BRANCH` |
|
||||
| `./.agents/scripts/bash/update-agent-context.sh devin` | Append tech entries to `AGENTS.md` |
|
||||
| `./.agents/scripts/bash/audit-skills.sh` | Validate all `SKILL.md` frontmatter + presence |
|
||||
| `./.agents/scripts/bash/validate-versions.sh` | Version consistency check |
|
||||
| `./.agents/scripts/bash/sync-workflows.sh` | Verify every skill has a `.devin/workflows/*.md` wrapper |
|
||||
|
||||
All scripts mirror to `.agents/scripts/powershell/*.ps1` for Windows.
|
||||
|
||||
@@ -97,7 +96,7 @@ To add a new skill:
|
||||
|
||||
1. Create `NAME/SKILL.md` with frontmatter: `name`, `description`, `version: 1.9.0`, `scope`, `depends-on`.
|
||||
2. Append an LCBP3 context reference pointing to `_LCBP3-CONTEXT.md`.
|
||||
3. Wrap with `.windsurf/workflows/NAME.md` so it becomes a slash command.
|
||||
3. Wrap with `.devin/workflows/NAME.md` so it becomes a slash command.
|
||||
4. Update [`skills.md`](./skills.md) dependency matrix.
|
||||
5. Run `./.agents/scripts/bash/audit-skills.sh` → must pass.
|
||||
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
---
|
||||
name: save-memory
|
||||
description: บันทึก session log และอัปเดต project memory ตามโครงสร้างใหม่
|
||||
version: 1.9.0
|
||||
scope: project-management
|
||||
depends-on: []
|
||||
user-invocable: true
|
||||
---
|
||||
|
||||
# บันทึก Memory (Save Memory)
|
||||
|
||||
Skill นี้ใช้สำหรับบันทึก session log และอัปเดต project memory ตามโครงสร้างใหม่ที่ reorganization แล้ว
|
||||
|
||||
## โครงสร้าง Memory ใหม่
|
||||
|
||||
```
|
||||
memory/
|
||||
├── README.md (index + overview)
|
||||
├── mcp-tools.md (MCP MariaDB + Memory Tools)
|
||||
└── project-memory-override.md (OS rules, Current Decisions, Environment, Next Session Focus)
|
||||
|
||||
specs/88-logs/
|
||||
├── rollouts.md (Recent rollouts table)
|
||||
└── session-YYYY-MM-DD-[topic].md (Session logs)
|
||||
```
|
||||
|
||||
## ขั้นตอนการบันทึก Memory
|
||||
|
||||
### 1. สร้าง Session Log (ถ้ามีงาน session ใหม่)
|
||||
|
||||
เมื่อทำงาน session ใหม่ให้:
|
||||
|
||||
1. **สร้างไฟล์ session log ใหม่** ใน `specs/88-logs/`
|
||||
- ชื่อไฟล์: `session-YYYY-MM-DD-[topic].md`
|
||||
- ตัวอย่าง: `session-2026-06-07-memory-reorganization.md`
|
||||
|
||||
2. **บันทึกเนื้อหาใน session log**:
|
||||
|
||||
```markdown
|
||||
# Session [N] — YYYY-MM-DD ([Topic])
|
||||
|
||||
## Summary
|
||||
|
||||
[สรุปสิ่งที่ทำใน session นี้]
|
||||
|
||||
## ปัญหาที่พบ (Root Cause)
|
||||
|
||||
[อธิบายปัญหาและสาเหตุ]
|
||||
|
||||
## การแก้ไข (Fix)
|
||||
|
||||
| ไฟล์ | การเปลี่ยนแปลง |
|
||||
| -------------- | ---------------------- |
|
||||
| [path/to/file] | [อธิบายการเปลี่ยนแปลง] |
|
||||
|
||||
## กฎที่ Lock แล้ว
|
||||
|
||||
[บันทึก pattern หรือ decision ที่ตกลง]
|
||||
|
||||
## Verification
|
||||
|
||||
[วิธีตรวจสอบว่างานสำเร็จ]
|
||||
```
|
||||
|
||||
3. **อัปเดต `specs/88-logs/rollouts.md`**
|
||||
- เพิ่ม entry ใหม่ในตาราง Recent Rollouts
|
||||
- รูปแบบ: `| วันที่ | Version | รายการ | สถานะ |`
|
||||
|
||||
### 2. อัปเดต Project Memory (ถ้ามี decision ใหม่)
|
||||
|
||||
เมื่อมีการตัดสินใจสำคัญใหม่ให้:
|
||||
|
||||
1. **เปิดไฟล์ `memory/project-memory-override.md`**
|
||||
|
||||
2. **อัปเดตตาราง "Current Decisions (Locked)"**
|
||||
- เพิ่ม entry ใหม่ถ้ามี decision ใหม่
|
||||
- รูปแบบ: `| ID | Decision | ADR |`
|
||||
|
||||
3. **อัปเดต "Next Session Focus"**
|
||||
- เพิ่มงานใหม่ถ้ามี
|
||||
- ทำเครื่องหมาย `[ ]` สำหรับงานที่ยังไม่เสร็จ
|
||||
- ทำเครื่องหมาย `[X]` สำหรับงานที่เสร็จแล้ว
|
||||
|
||||
4. **อัปเดต "Environment & Services"** (ถ้ามีการเปลี่ยนแปลง)
|
||||
- อัปเดต URL, port, หรือ notes ถ้ามีการเปลี่ยน infrastructure
|
||||
|
||||
### 3. อัปเดต MCP Tools (ถ้ามี tools ใหม่)
|
||||
|
||||
เมื่อมี MCP tools ใหม่ให้:
|
||||
|
||||
1. **เปิดไฟล์ `memory/mcp-tools.md`**
|
||||
|
||||
2. **เพิ่ม tool ใหม่ในตาราง "Available Tools"**
|
||||
- รูปแบบ: `| Tool | Purpose | Example Usage |`
|
||||
|
||||
3. **เพิ่ม usage example และ warnings** ถ้าจำเป็น
|
||||
|
||||
### 4. อัปเดต Root Documentation (ถ้ามีการเปลี่ยนแปลง)
|
||||
|
||||
เมื่อมีการเปลี่ยนแปลงที่ส่งผลต่อเอกสารระดับ root ให้:
|
||||
|
||||
1. **ARCHITECTURE.md** — อัปเดตเมื่อ:
|
||||
- เปลี่ยน architecture หลัก
|
||||
- เพิ่ม/ลบ component สำคัญ
|
||||
- เปลี่ยน data flow หรือ integration pattern
|
||||
|
||||
2. **CHANGELOG.md** — อัปเดตเมื่อ:
|
||||
- Deploy version ใหม่
|
||||
- เพิ่ม feature หรือ breaking change สำคัญ
|
||||
- รูปแบบ: `## [version] (YYYY-MM-DD)` → `### feat(scope): description`
|
||||
|
||||
3. **CONTEXT.md** — อัปเดตเมื่อ:
|
||||
- เปลี่ยน domain terminology หลัก
|
||||
- เพิ่ม concept ใหม่ที่ใช้ทั่ว project
|
||||
- อัปเดต glossary หรือ business rules
|
||||
|
||||
4. **CONTRIBUTING.md** — อัปเดตเมื่อ:
|
||||
- เปลี่ยน workflow การทำงาน
|
||||
- เพิ่ม/เปลี่ยน coding standards
|
||||
- อัปเดต CI/CD process
|
||||
|
||||
5. **README.md** — อัปเดตเมื่อ:
|
||||
- เปลี่ยน project structure
|
||||
- เพิ่ม/เปลี่ยน installation steps
|
||||
- อัปเดต feature overview หรือ tech stack
|
||||
|
||||
## Template สำหรับ Session Log
|
||||
|
||||
```markdown
|
||||
# Session [N] — YYYY-MM-DD ([Topic])
|
||||
|
||||
## Summary
|
||||
|
||||
[สรุปสิ่งที่ทำใน session นี้ใน 1-2 ประโยค]
|
||||
|
||||
## ปัญหาที่พบ (Root Cause)
|
||||
|
||||
[อธิบายปัญหาและสาเหตุหลัก]
|
||||
|
||||
## การแก้ไข (Fix)
|
||||
|
||||
| ไฟล์ | การเปลี่ยนแปลง |
|
||||
| -------------- | ---------------------- |
|
||||
| `path/to/file` | [อธิบายการเปลี่ยนแปลง] |
|
||||
|
||||
## กฎที่ Lock แล้ว
|
||||
|
||||
[บันทึก pattern หรือ decision ที่ตกลงและไม่ควรเปลี่ยน]
|
||||
|
||||
## Verification
|
||||
|
||||
- [ ] [check 1]
|
||||
- [ ] [check 2]
|
||||
```
|
||||
|
||||
## ข้อควรระวัง
|
||||
|
||||
- **ห้าม** บันทึก rules ที่ซ้ำกับ specs/ (ADRs, glossary, guidelines)
|
||||
- **ห้าม** บันทึก commands ที่ซ้ำกับ specs/05-Engineering-Guidelines/
|
||||
- **ห้าม** บันทึก environment ที่ซ้ำกับ specs/04-Infrastructure-OPS/
|
||||
- **ใช้** `specs/88-logs/` สำหรับ session history และ rollouts
|
||||
- **ใช้** `memory/project-memory-override.md` สำหรับ OS rules, decisions, environment ที่ไม่มีใน specs
|
||||
- **ใช้** `memory/mcp-tools.md` สำหรับ MCP tools documentation
|
||||
- **อัปเดต Root Documentation** (ARCHITECTURE.md, CHANGELOG.md, CONTEXT.md, CONTRIBUTING.md, README.md) เฉพาะเมื่อมีการเปลี่ยนแปลงที่ส่งผลต่อ project architecture, version, terminology, workflow หรือ structure
|
||||
|
||||
## ตัวอย่างการใช้งาน
|
||||
|
||||
### กรณีที่ 1: ทำงาน session ใหม่
|
||||
|
||||
```
|
||||
1. สร้างไฟล์ specs/88-logs/session-2026-06-07-bug-fix.md
|
||||
2. บันทึกปัญหา, การแก้ไข, verification
|
||||
3. อัปเดต specs/88-logs/rollouts.md
|
||||
```
|
||||
|
||||
### กรณีที่ 2: มี decision ใหม่
|
||||
|
||||
```
|
||||
1. เปิด memory/project-memory-override.md
|
||||
2. เพิ่ม entry ใหม่ในตาราง Current Decisions
|
||||
3. อัปเดต Next Session Focus
|
||||
```
|
||||
|
||||
### กรณีที่ 3: เปลี่ยน infrastructure
|
||||
|
||||
```
|
||||
1. เปิด memory/project-memory-override.md
|
||||
2. อัปเดตตาราง Environment & Services
|
||||
3. อัปเดต Key Environment Variables ถ้าจำเป็น
|
||||
```
|
||||
|
||||
### กรณีที่ 4: อัปเดต Root Documentation
|
||||
|
||||
```
|
||||
1. ตรวจสอบว่ามีการเปลี่ยนแปลงที่ส่งผลต่อ ARCHITECTURE.md, CHANGELOG.md, CONTEXT.md, CONTRIBUTING.md, หรือ README.md
|
||||
2. อัปเดตไฟล์ที่เกี่ยวข้องตามรูปแบบที่กำหนด
|
||||
3. ตรวจสอบว่าการเปลี่ยนแปลงสอดคล้องกับ specs/ และ ADRs
|
||||
```
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
ไฟล์นี้กำหนดทักษะและความสามารถเฉพาะทางของ Document Intelligence Engine สำหรับโครงการ LCBP3 v1.9.0 เพื่อรักษามาตรฐานสูงสุดด้าน Security และ Data Integrity
|
||||
|
||||
**Status**: Production Ready | **Last Updated**: 2026-05-17 | **Total Skills**: 23
|
||||
**Status**: Production Ready | **Last Updated**: 2026-06-07 | **Total Skills**: 24
|
||||
|
||||
> 📌 Shared context for all speckit-\* skills: see [`_LCBP3-CONTEXT.md`](./_LCBP3-CONTEXT.md).
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
| **speckit-status** | None | None | Progress tracking |
|
||||
| **speckit-taskstoissues** | speckit-tasks | None | Issue sync |
|
||||
| **speckit-checklist** | speckit-plan | None | Requirements validation |
|
||||
| **save-memory** | None | None | Session log & memory update |
|
||||
| **nestjs-best-practices** | None | speckit-implement | Backend patterns |
|
||||
| **next-best-practices** | None | speckit-implement | Frontend patterns |
|
||||
| **speckit-security-audit** | None | speckit-reviewer | Security validation |
|
||||
@@ -99,7 +100,7 @@
|
||||
|
||||
### Health Metrics
|
||||
|
||||
- **Total Skills**: 23 implemented
|
||||
- **Total Skills**: 24 implemented
|
||||
- **Version Alignment**: v1.9.0 across all skills
|
||||
- **Template Coverage**: 100% for skills requiring templates
|
||||
- **Documentation**: Complete front matter + shared `_LCBP3-CONTEXT.md` appendix
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
description: บันทึก session log และอัปเดต project memory
|
||||
---
|
||||
|
||||
# บันทึก Memory
|
||||
|
||||
ใช้ skill `save-memory` เพื่อบันทึก session log และอัปเดต project memory ตามโครงสร้างใหม่
|
||||
|
||||
```bash
|
||||
skill save-memory
|
||||
```
|
||||
@@ -68,36 +68,36 @@ $script:NEW_FRAMEWORK = ''
|
||||
$script:NEW_DB = ''
|
||||
$script:NEW_PROJECT_TYPE = ''
|
||||
|
||||
function Write-Info {
|
||||
function Write-Info {
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$Message
|
||||
)
|
||||
Write-Host "INFO: $Message"
|
||||
Write-Host "INFO: $Message"
|
||||
}
|
||||
|
||||
function Write-Success {
|
||||
function Write-Success {
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$Message
|
||||
)
|
||||
Write-Host "$([char]0x2713) $Message"
|
||||
Write-Host "$([char]0x2713) $Message"
|
||||
}
|
||||
|
||||
function Write-WarningMsg {
|
||||
function Write-WarningMsg {
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$Message
|
||||
)
|
||||
Write-Warning $Message
|
||||
Write-Warning $Message
|
||||
}
|
||||
|
||||
function Write-Err {
|
||||
function Write-Err {
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$Message
|
||||
)
|
||||
Write-Host "ERROR: $Message" -ForegroundColor Red
|
||||
Write-Host "ERROR: $Message" -ForegroundColor Red
|
||||
}
|
||||
|
||||
function Validate-Environment {
|
||||
@@ -130,7 +130,7 @@ function Extract-PlanField {
|
||||
# Lines like **Language/Version**: Python 3.12
|
||||
$regex = "^\*\*$([Regex]::Escape($FieldPattern))\*\*: (.+)$"
|
||||
Get-Content -LiteralPath $PlanFile -Encoding utf8 | ForEach-Object {
|
||||
if ($_ -match $regex) {
|
||||
if ($_ -match $regex) {
|
||||
$val = $Matches[1].Trim()
|
||||
if ($val -notin @('NEEDS CLARIFICATION','N/A')) { return $val }
|
||||
}
|
||||
@@ -170,15 +170,15 @@ function Format-TechnologyStack {
|
||||
return ($parts -join ' + ')
|
||||
}
|
||||
|
||||
function Get-ProjectStructure {
|
||||
function Get-ProjectStructure {
|
||||
param(
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]$ProjectType
|
||||
)
|
||||
if ($ProjectType -match 'web') { return "backend/`nfrontend/`ntests/" } else { return "src/`ntests/" }
|
||||
if ($ProjectType -match 'web') { return "backend/`nfrontend/`ntests/" } else { return "src/`ntests/" }
|
||||
}
|
||||
|
||||
function Get-CommandsForLanguage {
|
||||
function Get-CommandsForLanguage {
|
||||
param(
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]$Lang
|
||||
@@ -191,12 +191,12 @@ function Get-CommandsForLanguage {
|
||||
}
|
||||
}
|
||||
|
||||
function Get-LanguageConventions {
|
||||
function Get-LanguageConventions {
|
||||
param(
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]$Lang
|
||||
)
|
||||
if ($Lang) { "${Lang}: Follow standard conventions" } else { 'General: Follow standard conventions' }
|
||||
if ($Lang) { "${Lang}: Follow standard conventions" } else { 'General: Follow standard conventions' }
|
||||
}
|
||||
|
||||
function New-AgentFile {
|
||||
@@ -223,7 +223,7 @@ function New-AgentFile {
|
||||
$content = Get-Content -LiteralPath $temp -Raw -Encoding utf8
|
||||
$content = $content -replace '\[PROJECT NAME\]',$ProjectName
|
||||
$content = $content -replace '\[DATE\]',$Date.ToString('yyyy-MM-dd')
|
||||
|
||||
|
||||
# Build the technology stack string safely
|
||||
$techStackForTemplate = ""
|
||||
if ($escaped_lang -and $escaped_framework) {
|
||||
@@ -233,7 +233,7 @@ function New-AgentFile {
|
||||
} elseif ($escaped_framework) {
|
||||
$techStackForTemplate = "- $escaped_framework ($escaped_branch)"
|
||||
}
|
||||
|
||||
|
||||
$content = $content -replace '\[EXTRACTED FROM ALL PLAN.MD FILES\]',$techStackForTemplate
|
||||
# For project structure we manually embed (keep newlines)
|
||||
$escapedStructure = [Regex]::Escape($projectStructure)
|
||||
@@ -241,7 +241,7 @@ function New-AgentFile {
|
||||
# Replace escaped newlines placeholder after all replacements
|
||||
$content = $content -replace '\[ONLY COMMANDS FOR ACTIVE TECHNOLOGIES\]',$commands
|
||||
$content = $content -replace '\[LANGUAGE-SPECIFIC, ONLY FOR LANGUAGES IN USE\]',$languageConventions
|
||||
|
||||
|
||||
# Build the recent changes string safely
|
||||
$recentChangesForTemplate = ""
|
||||
if ($escaped_lang -and $escaped_framework) {
|
||||
@@ -251,7 +251,7 @@ function New-AgentFile {
|
||||
} elseif ($escaped_framework) {
|
||||
$recentChangesForTemplate = "- ${escaped_branch}: Added ${escaped_framework}"
|
||||
}
|
||||
|
||||
|
||||
$content = $content -replace '\[LAST 3 FEATURES AND WHAT THEY ADDED\]',$recentChangesForTemplate
|
||||
# Convert literal \n sequences introduced by Escape to real newlines
|
||||
$content = $content -replace '\\n',[Environment]::NewLine
|
||||
@@ -276,14 +276,14 @@ function Update-ExistingAgentFile {
|
||||
$newTechEntries = @()
|
||||
if ($techStack) {
|
||||
$escapedTechStack = [Regex]::Escape($techStack)
|
||||
if (-not (Select-String -Pattern $escapedTechStack -Path $TargetFile -Quiet)) {
|
||||
$newTechEntries += "- $techStack ($CURRENT_BRANCH)"
|
||||
if (-not (Select-String -Pattern $escapedTechStack -Path $TargetFile -Quiet)) {
|
||||
$newTechEntries += "- $techStack ($CURRENT_BRANCH)"
|
||||
}
|
||||
}
|
||||
if ($NEW_DB -and $NEW_DB -notin @('N/A','NEEDS CLARIFICATION')) {
|
||||
$escapedDB = [Regex]::Escape($NEW_DB)
|
||||
if (-not (Select-String -Pattern $escapedDB -Path $TargetFile -Quiet)) {
|
||||
$newTechEntries += "- $NEW_DB ($CURRENT_BRANCH)"
|
||||
if (-not (Select-String -Pattern $escapedDB -Path $TargetFile -Quiet)) {
|
||||
$newTechEntries += "- $NEW_DB ($CURRENT_BRANCH)"
|
||||
}
|
||||
}
|
||||
$newChangeEntry = ''
|
||||
@@ -377,7 +377,7 @@ function Update-SpecificAgent {
|
||||
'qwen' { Update-AgentFile -TargetFile $QWEN_FILE -AgentName 'Qwen Code' }
|
||||
'opencode' { Update-AgentFile -TargetFile $AGENTS_FILE -AgentName 'opencode' }
|
||||
'codex' { Update-AgentFile -TargetFile $AGENTS_FILE -AgentName 'Codex CLI' }
|
||||
'windsurf' { Update-AgentFile -TargetFile $WINDSURF_FILE -AgentName 'Windsurf' }
|
||||
'devin' { Update-AgentFile -TargetFile $DEVIN_FILE -AgentName 'Devin' }
|
||||
'kilocode' { Update-AgentFile -TargetFile $KILOCODE_FILE -AgentName 'Kilo Code' }
|
||||
'auggie' { Update-AgentFile -TargetFile $AUGGIE_FILE -AgentName 'Auggie CLI' }
|
||||
'roo' { Update-AgentFile -TargetFile $ROO_FILE -AgentName 'Roo Code' }
|
||||
@@ -386,7 +386,7 @@ function Update-SpecificAgent {
|
||||
'shai' { Update-AgentFile -TargetFile $SHAI_FILE -AgentName 'SHAI' }
|
||||
'q' { Update-AgentFile -TargetFile $Q_FILE -AgentName 'Amazon Q Developer CLI' }
|
||||
'bob' { Update-AgentFile -TargetFile $BOB_FILE -AgentName 'IBM Bob' }
|
||||
default { Write-Err "Unknown agent type '$Type'"; Write-Err 'Expected: claude|gemini|copilot|cursor-agent|qwen|opencode|codex|windsurf|kilocode|auggie|roo|codebuddy|amp|shai|q|bob'; return $false }
|
||||
default { Write-Err "Unknown agent type '$Type'"; Write-Err 'Expected: claude|gemini|copilot|cursor-agent|qwen|opencode|codex|devin|kilocode|auggie|roo|codebuddy|amp|shai|q|bob'; return $false }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -399,7 +399,7 @@ function Update-AllExistingAgents {
|
||||
if (Test-Path $CURSOR_FILE) { if (-not (Update-AgentFile -TargetFile $CURSOR_FILE -AgentName 'Cursor IDE')) { $ok = $false }; $found = $true }
|
||||
if (Test-Path $QWEN_FILE) { if (-not (Update-AgentFile -TargetFile $QWEN_FILE -AgentName 'Qwen Code')) { $ok = $false }; $found = $true }
|
||||
if (Test-Path $AGENTS_FILE) { if (-not (Update-AgentFile -TargetFile $AGENTS_FILE -AgentName 'Codex/opencode')) { $ok = $false }; $found = $true }
|
||||
if (Test-Path $WINDSURF_FILE) { if (-not (Update-AgentFile -TargetFile $WINDSURF_FILE -AgentName 'Windsurf')) { $ok = $false }; $found = $true }
|
||||
if (Test-Path $DEVIN_FILE) { if (-not (Update-AgentFile -TargetFile $DEVIN_FILE -AgentName 'Devin')) { $ok = $false }; $found = $true }
|
||||
if (Test-Path $KILOCODE_FILE) { if (-not (Update-AgentFile -TargetFile $KILOCODE_FILE -AgentName 'Kilo Code')) { $ok = $false }; $found = $true }
|
||||
if (Test-Path $AUGGIE_FILE) { if (-not (Update-AgentFile -TargetFile $AUGGIE_FILE -AgentName 'Auggie CLI')) { $ok = $false }; $found = $true }
|
||||
if (Test-Path $ROO_FILE) { if (-not (Update-AgentFile -TargetFile $ROO_FILE -AgentName 'Roo Code')) { $ok = $false }; $found = $true }
|
||||
|
||||
@@ -137,8 +137,8 @@ Spec priority: **`06-Decision-Records`** > **`05-Engineering-Guidelines`** > oth
|
||||
| **ADR-019 UUID** | `specs/06-Decision-Records/ADR-019-hybrid-identifier-strategy.md` | ✅ Active | UUID-related work |
|
||||
| **ADR-021 Workflow Context** | `specs/06-Decision-Records/ADR-021-workflow-context.md` | ✅ Active | Integrated workflow & step attachments |
|
||||
| **ADR-023 AI Architecture** | `specs/06-Decision-Records/ADR-023-unified-ai-architecture.md` | ✅ Active | Unified AI boundaries and pipeline (base architecture) |
|
||||
| **ADR-023A AI Model Rev.** | `specs/06-Decision-Records/ADR-023A-unified-ai-architecture.md` | ✅ Active | 2-queue, RAG embed scope, OCR auto-detect (model stack superseded by ADR-034) |
|
||||
| **ADR-034 Thai Model Stack** | `specs/06-Decision-Records/ADR-034-AI-model-change.md` | ✅ Active | typhoon2.5-np-dms:latest (Main) + typhoon-np-dms-ocr:latest (OCR, keep_alive:0) |
|
||||
| **ADR-023A AI Model Rev.** | `specs/06-Decision-Records/ADR-023A-unified-ai-architecture.md` | ✅ Active | 2-queue, RAG embed scope, OCR auto-detect (model stack superseded by ADR-034) |
|
||||
| **ADR-034 Thai Model Stack** | `specs/06-Decision-Records/ADR-034-AI-model-change.md` | ✅ Active | typhoon2.5-np-dms:latest (Main) + typhoon-np-dms-ocr:latest (OCR, keep_alive:0) |
|
||||
| **ADR-024 Intent Class.** | `specs/06-Decision-Records/ADR-024-intent-classification-strategy.md` | ✅ Active | Hybrid Pattern→LLM Fallback; ai_intent_patterns DB; Redis cache 5 min |
|
||||
| **ADR-025 AI Tool Layer** | `specs/06-Decision-Records/ADR-025-ai-tool-layer-architecture.md` | ✅ Active | Server-side Tool dispatch; CASL-guarded bridge; ToolResult uses publicId only |
|
||||
| **ADR-026 Chat UI** | `specs/06-Decision-Records/ADR-026-document-chat-ui-pattern.md` | ✅ Active | Side-panel Document Chat UI; useAiChat() hook; streaming response support |
|
||||
@@ -459,40 +459,40 @@ Full glossary: `specs/00-overview/00-02-glossary.md`
|
||||
|
||||
When user asks about... check these files:
|
||||
|
||||
| Request | Status | 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 |
|
||||
| "Dynamic Prompt / Prompt" | ✅ | `ADR-029`, `specs/06-Decision-Records/ADR-029-dynamic-prompt-management.md` | ai_prompts table; Redis cache `ai:prompt:active:{type}` TTL 60s |
|
||||
| "AI Model / OCR Active Switch"| ✅ | `ADR-032`, `ADR-033`, `specs/200-fullstacks/233-ai-model-ocr-runner-management/` | Synchronous LLM switches, VRAM Release, sidecar API Key protection |
|
||||
| "จัดการ 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 → วางแผนต่อโดยไม่ทำงานซ้ำ |
|
||||
| Request | Status | 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 |
|
||||
| "Dynamic Prompt / Prompt" | ✅ | `ADR-029`, `specs/06-Decision-Records/ADR-029-dynamic-prompt-management.md` | ai_prompts table; Redis cache `ai:prompt:active:{type}` TTL 60s |
|
||||
| "AI Model / OCR Active Switch" | ✅ | `ADR-032`, `ADR-033`, `specs/200-fullstacks/233-ai-model-ocr-runner-management/` | Synchronous LLM switches, VRAM Release, sidecar API Key protection |
|
||||
| "จัดการ 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 → วางแผนต่อโดยไม่ทำงานซ้ำ |
|
||||
|
||||
**Status Legend:**
|
||||
|
||||
@@ -514,30 +514,33 @@ MCP MariaDB server ให้เครื่องมือสำหรับต
|
||||
|
||||
### Available Tools
|
||||
|
||||
| Tool | หน้าที่ | ตัวอย่างการใช้งาน |
|
||||
|------|----------|------------------|
|
||||
| `mcp1_mysql_test_connection` | ทดสอบ connection กับ database | ตรวจสอบว่า MCP server เชื่อมต่อได้ |
|
||||
| `mcp1_mysql_show_databases` | แสดง databases ทั้งหมด | ดูว่ามี database อะไรบ้าง |
|
||||
| `mcp1_mysql_show_tables` | แสดง tables ทั้งหมดใน database | ดูรายชื่อ tables ใน `lcbp3` |
|
||||
| `mcp1_mysql_describe_table` | ดู structure/columns ของ table | ตรวจสอบ columns, types, keys ของ `correspondences` |
|
||||
| `mcp1_mysql_query` | รัน SELECT query | ดู data ใน table หรือ join query |
|
||||
| `mcp1_mysql_insert` | INSERT data | เพิ่ม seed data หรือ test data |
|
||||
| `mcp1_mysql_update` | UPDATE data | แก้ไข data ใน table |
|
||||
| `mcp1_mysql_delete` | DELETE data | ลบ data ใน table |
|
||||
| Tool | หน้าที่ | ตัวอย่างการใช้งาน |
|
||||
| ---------------------------- | ------------------------------ | -------------------------------------------------- |
|
||||
| `mcp1_mysql_test_connection` | ทดสอบ connection กับ database | ตรวจสอบว่า MCP server เชื่อมต่อได้ |
|
||||
| `mcp1_mysql_show_databases` | แสดง databases ทั้งหมด | ดูว่ามี database อะไรบ้าง |
|
||||
| `mcp1_mysql_show_tables` | แสดง tables ทั้งหมดใน database | ดูรายชื่อ tables ใน `lcbp3` |
|
||||
| `mcp1_mysql_describe_table` | ดู structure/columns ของ table | ตรวจสอบ columns, types, keys ของ `correspondences` |
|
||||
| `mcp1_mysql_query` | รัน SELECT query | ดู data ใน table หรือ join query |
|
||||
| `mcp1_mysql_insert` | INSERT data | เพิ่ม seed data หรือ test data |
|
||||
| `mcp1_mysql_update` | UPDATE data | แก้ไข data ใน table |
|
||||
| `mcp1_mysql_delete` | DELETE data | ลบ data ใน table |
|
||||
|
||||
### การใช้งานร่วมกับ Development Flow
|
||||
|
||||
**เมื่อเขียน query ใหม่:**
|
||||
|
||||
1. ใช้ `mcp1_mysql_describe_table` เพื่อตรวจสอบ columns และ types
|
||||
2. เปรียบเทียบกับ `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql`
|
||||
3. ใช้ `mcp1_mysql_query` เพื่อทดสอบ query ก่อน implement
|
||||
|
||||
**เมื่อเปลี่ยน schema (ADR-009):**
|
||||
|
||||
1. ใช้ `mcp1_mysql_describe_table` เพื่อดู structure ปัจจุบัน
|
||||
2. สร้าง SQL delta ใน `specs/03-Data-and-Storage/deltas/`
|
||||
3. ใช้ `mcp1_mysql_query` เพื่อตรวจสอบผลลัพธ์หลัง apply delta
|
||||
|
||||
**เมื่อ debug ปัญหา database:**
|
||||
|
||||
1. ใช้ `mcp1_mysql_query` เพื่อดู data จริง
|
||||
2. เปรียบเทียบกับ spec และ data dictionary
|
||||
3. ตรวจสอบ foreign keys และ constraints
|
||||
@@ -561,31 +564,34 @@ MCP Memory server ให้เครื่องมือสำหรับจ
|
||||
|
||||
### Available Tools
|
||||
|
||||
| Tool | หน้าที่ | ตัวอย่างการใช้งาน |
|
||||
|------|----------|------------------|
|
||||
| `mcp3_create_entities` | สร้าง entities ใหม่หลายตัวพร้อม observations | สร้าง entity ใหม่เช่น Project, User, Task |
|
||||
| `mcp3_create_relations` | สร้าง relations ระหว่าง entities | สร้าง relation: Project → has → User |
|
||||
| `mcp3_add_observations` | เพิ่ม observations ให้ entity ที่มีอยู่แล้ว | เพิ่ม context เพิ่มเติมให้ entity |
|
||||
| `mcp3_delete_entities` | ลบ entities และ relations ที่เกี่ยวข้อง | ลบ entity ที่ไม่ใช้แล้ว |
|
||||
| `mcp3_delete_relations` | ลบ relations ระหว่าง entities | ลบ relation ที่ผิดหรือไม่ใช้แล้ว |
|
||||
| `mcp3_delete_observations` | ลบ observations จาก entity | ลบ context ที่ผิดหรือล้าสุด |
|
||||
| `mcp3_open_nodes` | ดึงข้อมูล entities ตามชื่อ | ดึง entity ที่ระบุชื่อ |
|
||||
| `mcp3_read_graph` | อ่าน knowledge graph ทั้งหมด | ดูทั้ง graph structure |
|
||||
| `mcp3_search_nodes` | ค้นหา entities ตาม query | ค้นหา entity จากชื่อ, type, หรือ observation |
|
||||
| Tool | หน้าที่ | ตัวอย่างการใช้งาน |
|
||||
| -------------------------- | -------------------------------------------- | -------------------------------------------- |
|
||||
| `mcp3_create_entities` | สร้าง entities ใหม่หลายตัวพร้อม observations | สร้าง entity ใหม่เช่น Project, User, Task |
|
||||
| `mcp3_create_relations` | สร้าง relations ระหว่าง entities | สร้าง relation: Project → has → User |
|
||||
| `mcp3_add_observations` | เพิ่ม observations ให้ entity ที่มีอยู่แล้ว | เพิ่ม context เพิ่มเติมให้ entity |
|
||||
| `mcp3_delete_entities` | ลบ entities และ relations ที่เกี่ยวข้อง | ลบ entity ที่ไม่ใช้แล้ว |
|
||||
| `mcp3_delete_relations` | ลบ relations ระหว่าง entities | ลบ relation ที่ผิดหรือไม่ใช้แล้ว |
|
||||
| `mcp3_delete_observations` | ลบ observations จาก entity | ลบ context ที่ผิดหรือล้าสุด |
|
||||
| `mcp3_open_nodes` | ดึงข้อมูล entities ตามชื่อ | ดึง entity ที่ระบุชื่อ |
|
||||
| `mcp3_read_graph` | อ่าน knowledge graph ทั้งหมด | ดูทั้ง graph structure |
|
||||
| `mcp3_search_nodes` | ค้นหา entities ตาม query | ค้นหา entity จากชื่อ, type, หรือ observation |
|
||||
|
||||
### การใช้งานร่วมกับ Development Flow
|
||||
|
||||
**เมื่อบันทึก context ใหม่:**
|
||||
|
||||
1. ใช้ `mcp3_create_entities` เพื่อสร้าง entities ใหม่ (ถ้ายังไม่มี)
|
||||
2. ใช้ `mcp3_create_relations` เพื่อเชื่อมโยง entities
|
||||
3. ใช้ `mcp3_add_observations` เพื่อเพิ่ม context/observations
|
||||
|
||||
**เมื่อค้นหา context:**
|
||||
|
||||
1. ใช้ `mcp3_search_nodes` เพื่อค้นหา entities ที่เกี่ยวข้อง
|
||||
2. ใช้ `mcp3_open_nodes` เพื่อดึงข้อมูล entities ที่ต้องการ
|
||||
3. ใช้ `mcp3_read_graph` เพื่อดู relations ระหว่าง entities
|
||||
|
||||
**เมื่อแก้ไข context:**
|
||||
|
||||
1. ใช้ `mcp3_add_observations` เพื่อเพิ่ม observations ใหม่
|
||||
2. ใช้ `mcp3_delete_observations` เพื่อลบ observations ที่ผิด
|
||||
3. ใช้ `mcp3_create_relations` หรือ `mcp3_delete_relations` เพื่อปรับ relations
|
||||
@@ -709,30 +715,30 @@ This file is a **quick reference**. For detailed information:
|
||||
|
||||
## 🔄 Change Log
|
||||
|
||||
| Version | Date | Changes | Updated By |
|
||||
| ------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------- |
|
||||
| Version | Date | Changes | Updated By |
|
||||
| ------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- |
|
||||
| 1.9.10 | 2026-06-06 | Added MCP MariaDB Tools section with available tools (test_connection, show_databases, show_tables, describe_table, query, insert, update, delete), usage guidelines for development flow, and safety warnings for DDL operations; Added MCP Memory Tools section with Knowledge Graph management tools (create_entities, create_relations, add_observations, delete_entities, delete_relations, delete_observations, open_nodes, read_graph, search_nodes) for long-term context storage | Windsurf AI |
|
||||
| 1.9.9 | 2026-06-03 | ADR-034 Thai-Optimized AI Model Stack: typhoon2.5-np-dms:latest (main) + typhoon-np-dms-ocr:latest (OCR); model switching in ai-batch processor; AiSettingsService static constants; SQL delta; updated Key Spec Files + AI isolation rule | Windsurf AI |
|
||||
| 1.9.8 | 2026-06-02 | Added ADR-033 Active Model & OCR Runner Management; implemented Synchronous LLM switches, GPU Memory Auto-release, sidecar `X-API-Key` headers protection; updated Key Spec Files & Specialized Work AI runtime sections | Windsurf AI |
|
||||
| 1.9.7 | 2026-05-25 | Added ADR-029 Dynamic Prompt Management to Key Spec Files table; fixed gemma4 model name e2b→e4b Q8_0; added Dynamic Prompt context trigger; added ADR-029 to Tier 3 AI checklist; bumped last synced date | Windsurf AI |
|
||||
| 1.9.6 | 2026-05-22 | Added ADR-024/025/026/027/028 to Key Spec Files table; Tier 3 expanded with AI Runtime Layer + Migration Pipeline tiers; Specialized Work section updated with ADR-024~028 patterns; 6 new Context-Aware Triggers; bumped Last synced date | Windsurf AI |
|
||||
| 1.9.5 | 2026-05-18 | **Grill-with-Docs Session:** Domain terminology clarified (Correspondence = all doc types), Tier 3: SPECIALIZED WORK added, Context-Aware Triggers with Status column, Tier-specific Final Checklists | Windsurf AI |
|
||||
| 1.9.4 | 2026-05-16 | Added ADR-015 Release Strategy to Key Spec Files table (Blue-Green deployment + release gates) | Human Dev |
|
||||
| 1.9.3 | 2026-05-15 | ADR-023A: Model revision — gemma4:9b+Typhoon→gemma4:e2b (2-model stack), BullMQ 2-queue split, RAG full-doc embed, OCR auto-detect, n8n→DMS API boundary, QdrantService multi-tenancy contract | Windsurf AI |
|
||||
| 1.9.2 | 2026-05-14 | Consolidated legacy AI ADRs (017, 017B, 018, 020, 022) into master ADR-023: Unified AI Architecture | Antigravity AI |
|
||||
| 1.9.1 | 2026-05-13 | Added `bugfix` workflow and skill (migrated and improved from `docs/bugfix.md`) | Windsurf AI |
|
||||
| 1.9.0 | 2026-05-03 | Integrated Global TypeScript Coding Standards (Headers, JSDoc, Thai comments, Single Export, No blank lines) | Windsurf AI |
|
||||
| 1.8.9 | 2026-04-22 | `.agents/skills/` LCBP3-native rebuild (20 skills @ v1.8.9) + `_LCBP3-CONTEXT.md` appendix + `specs/03-Data-and-Storage/deltas/` + AGENTS.md sync | Windsurf AI |
|
||||
| 1.8.8 | 2026-04-14 | Workflow attachments (ADR-021) + step-attachment envelope fields | Windsurf AI |
|
||||
| 1.8.7 | 2026-04-14 | + ADR-021 Workflow Context integration, + ADR-021 Integration Work tier, + Transmittal/Circulation context triggers, updated ADR-020 status | Windsurf AI |
|
||||
| 1.8.6 | 2026-04-10 | + DMS Workflow Engine Protocol, + Security & Integrity Audit Protocol, + 2 Context-Aware Triggers, ADR Status column, Forbidden Why column | Human Dev |
|
||||
| 1.8.5 | 2026-04-04 | Added ADR-007 error handling, ADR-020 AI integration, updated security rules | Windsurf AI |
|
||||
| 1.8.4 | 2026-03-24 | Phase 5.4→✅ DONE, Tailwind 3.4.3, ADR count(16), MariaDB UUID note | Windsurf AI |
|
||||
| 1.8.3 | 2026-03-21 | + Rule Enforcement Tiers (🔴🟡🟢), + Tiered Development Flow | Human Dev + AI |
|
||||
| 1.8.2 | 2026-03-21 | + Context Triggers, + Code Snippets, + Error Handling, + i18n | Human Dev + AI |
|
||||
| 1.8.1 | 2026-03-21 | + ADR-019 UUID patterns, + Phase 5.4 pending files | Claude Sonnet |
|
||||
| 1.8.0 | 2026-03-19 | + Security overrides, + UAT criteria reference | Human Dev |
|
||||
| 1.7.2 | 2026-03-15 | + AI Boundary rules (ADR-018) | Gemini Pro |
|
||||
| 1.9.9 | 2026-06-03 | ADR-034 Thai-Optimized AI Model Stack: typhoon2.5-np-dms:latest (main) + typhoon-np-dms-ocr:latest (OCR); model switching in ai-batch processor; AiSettingsService static constants; SQL delta; updated Key Spec Files + AI isolation rule | Windsurf AI |
|
||||
| 1.9.8 | 2026-06-02 | Added ADR-033 Active Model & OCR Runner Management; implemented Synchronous LLM switches, GPU Memory Auto-release, sidecar `X-API-Key` headers protection; updated Key Spec Files & Specialized Work AI runtime sections | Windsurf AI |
|
||||
| 1.9.7 | 2026-05-25 | Added ADR-029 Dynamic Prompt Management to Key Spec Files table; fixed gemma4 model name e2b→e4b Q8_0; added Dynamic Prompt context trigger; added ADR-029 to Tier 3 AI checklist; bumped last synced date | Windsurf AI |
|
||||
| 1.9.6 | 2026-05-22 | Added ADR-024/025/026/027/028 to Key Spec Files table; Tier 3 expanded with AI Runtime Layer + Migration Pipeline tiers; Specialized Work section updated with ADR-024~028 patterns; 6 new Context-Aware Triggers; bumped Last synced date | Windsurf AI |
|
||||
| 1.9.5 | 2026-05-18 | **Grill-with-Docs Session:** Domain terminology clarified (Correspondence = all doc types), Tier 3: SPECIALIZED WORK added, Context-Aware Triggers with Status column, Tier-specific Final Checklists | Windsurf AI |
|
||||
| 1.9.4 | 2026-05-16 | Added ADR-015 Release Strategy to Key Spec Files table (Blue-Green deployment + release gates) | Human Dev |
|
||||
| 1.9.3 | 2026-05-15 | ADR-023A: Model revision — gemma4:9b+Typhoon→gemma4:e2b (2-model stack), BullMQ 2-queue split, RAG full-doc embed, OCR auto-detect, n8n→DMS API boundary, QdrantService multi-tenancy contract | Windsurf AI |
|
||||
| 1.9.2 | 2026-05-14 | Consolidated legacy AI ADRs (017, 017B, 018, 020, 022) into master ADR-023: Unified AI Architecture | Antigravity AI |
|
||||
| 1.9.1 | 2026-05-13 | Added `bugfix` workflow and skill (migrated and improved from `docs/bugfix.md`) | Windsurf AI |
|
||||
| 1.9.0 | 2026-05-03 | Integrated Global TypeScript Coding Standards (Headers, JSDoc, Thai comments, Single Export, No blank lines) | Windsurf AI |
|
||||
| 1.8.9 | 2026-04-22 | `.agents/skills/` LCBP3-native rebuild (20 skills @ v1.8.9) + `_LCBP3-CONTEXT.md` appendix + `specs/03-Data-and-Storage/deltas/` + AGENTS.md sync | Windsurf AI |
|
||||
| 1.8.8 | 2026-04-14 | Workflow attachments (ADR-021) + step-attachment envelope fields | Windsurf AI |
|
||||
| 1.8.7 | 2026-04-14 | + ADR-021 Workflow Context integration, + ADR-021 Integration Work tier, + Transmittal/Circulation context triggers, updated ADR-020 status | Windsurf AI |
|
||||
| 1.8.6 | 2026-04-10 | + DMS Workflow Engine Protocol, + Security & Integrity Audit Protocol, + 2 Context-Aware Triggers, ADR Status column, Forbidden Why column | Human Dev |
|
||||
| 1.8.5 | 2026-04-04 | Added ADR-007 error handling, ADR-020 AI integration, updated security rules | Windsurf AI |
|
||||
| 1.8.4 | 2026-03-24 | Phase 5.4→✅ DONE, Tailwind 3.4.3, ADR count(16), MariaDB UUID note | Windsurf AI |
|
||||
| 1.8.3 | 2026-03-21 | + Rule Enforcement Tiers (🔴🟡🟢), + Tiered Development Flow | Human Dev + AI |
|
||||
| 1.8.2 | 2026-03-21 | + Context Triggers, + Code Snippets, + Error Handling, + i18n | Human Dev + AI |
|
||||
| 1.8.1 | 2026-03-21 | + ADR-019 UUID patterns, + Phase 5.4 pending files | Claude Sonnet |
|
||||
| 1.8.0 | 2026-03-19 | + Security overrides, + UAT criteria reference | Human Dev |
|
||||
| 1.7.2 | 2026-03-15 | + AI Boundary rules (ADR-018) | Gemini Pro |
|
||||
|
||||
---
|
||||
|
||||
|
||||
+1
-1
@@ -168,7 +168,7 @@
|
||||
|
||||
#### Summary
|
||||
|
||||
การปรับปรุงระบบ RFA Approval ให้สมบูรณ์พร้อมใช้งานจริง และสร้างมาตรฐานใหม่สำหรับการทำงานร่วมกับ AI Agent (Antigravity/Windsurf/CLI) ให้เป็นเอกภาพทั่วทั้งโครงการ (Agent-Agnostic) พร้อมปรับปรุงโครงสร้างการเก็บ Specification ให้รองรับการขยายตัวในอนาคต
|
||||
การปรับปรุงระบบ RFA Approval ให้สมบูรณ์พร้อมใช้งานจริง และสร้างมาตรฐานใหม่สำหรับการทำงานร่วมกับ AI Agent (Antigravity/Devin/CLI) ให้เป็นเอกภาพทั่วทั้งโครงการ (Agent-Agnostic) พร้อมปรับปรุงโครงสร้างการเก็บ Specification ให้รองรับการขยายตัวในอนาคต
|
||||
|
||||
#### Changes
|
||||
|
||||
|
||||
+3
-3
@@ -722,19 +722,19 @@ Create `.markdownlint.json`:
|
||||
|
||||
## 🤖 AI-Assisted Contributions
|
||||
|
||||
โปรเจกต์นี้รองรับ AI agents (Windsurf Cascade, Codex CLI, opencode, Amp, Antigravity) ในการเขียน / review / refactor โค้ด — ผ่านคู่มือกลางคือ [`AGENTS.md`](./AGENTS.md) และชุดทักษะใน [`.agents/skills/`](./.agents/skills/)
|
||||
โปรเจกต์นี้รองรับ AI agents (Devin Cascade, Codex CLI, opencode, Amp, Antigravity) ในการเขียน / review / refactor โค้ด — ผ่านคู่มือกลางคือ [`AGENTS.md`](./AGENTS.md) และชุดทักษะใน [`.agents/skills/`](./.agents/skills/)
|
||||
|
||||
### Canonical Rule Sources (อ่านตามลำดับนี้)
|
||||
|
||||
1. **[`AGENTS.md`](./AGENTS.md)** — quick-reference rules + change log (supersedes legacy `GEMINI.md`)
|
||||
2. **[`.agents/skills/_LCBP3-CONTEXT.md`](./.agents/skills/_LCBP3-CONTEXT.md)** — shared context loaded by every speckit-\* skill
|
||||
3. **[`.agents/skills/README.md`](./.agents/skills/README.md)** — skill-pack layout + Windsurf invocation guide
|
||||
3. **[`.agents/skills/README.md`](./.agents/skills/README.md)** — skill-pack layout + Devin invocation guide
|
||||
4. `specs/06-Decision-Records/` (โดยเฉพาะ ADR-019 — UUID **March 2026 pattern**)
|
||||
5. `specs/05-Engineering-Guidelines/` (backend / frontend / testing / i18n / git conventions)
|
||||
|
||||
### Invocation (v1.9.0 Unified)
|
||||
|
||||
ใช้ slash commands ผ่านโฟลเดอร์หลักคือ [`.agents/workflows/`](./.agents/workflows/) (ซึ่งถูก Mirror ไปยัง `.windsurf/workflows/` อัตโนมัติ):
|
||||
ใช้ slash commands ผ่านโฟลเดอร์หลักคือ [`.agents/workflows/`](./.agents/workflows/) (ซึ่งถูก Mirror ไปยัง `.devin/workflows/` อัตโนมัติ):
|
||||
|
||||
- `/00-speckit.all` → Full Pipeline (Specify → Validate)
|
||||
- `/102-speckit.specify` → สร้าง spec.md (ต้องระบุหมวดหมู่ 100/200/300)
|
||||
|
||||
@@ -16,17 +16,17 @@
|
||||
|
||||
> v1.9.7 (ADR-029 + sidecar) May 25; v1.9.8 (ADR-033 Model/OCR Sync & Security) June 2.
|
||||
|
||||
| Area | Status | หมายเหตุ |
|
||||
| ---------------------- | ------------------------ | ------------------------------------------------------------------ |
|
||||
| 🔧 **Backend** | ✅ Production Ready | NestJS 11, Express v5, 0 Vulnerabilities |
|
||||
| 🎨 **Frontend** | ✅ 100% Complete | Next.js 16.2.0, React 19.2.4, ESLint 9 |
|
||||
| 💾 **Database** | ✅ Schema v1.9.0 Stable | MariaDB 11.8, No-migration Policy |
|
||||
| 📘 **Documentation** | ✅ **10/10 Gaps Closed** | Product Vision → Release Policy (33 ADRs — v1.9.8) |
|
||||
| 🤖 **AI Architecture** | ✅ 33 ADRs Accepted | ADR-023A + ADR-024~029 + ADR-033 Model Sync & Security |
|
||||
| 🔄 **Workflow Engine** | ✅ ADR-021 Integrated | Transmittals & Circulation with Integrated Context |
|
||||
| 🧪 **Testing** | ✅ UAT Ready | E2E + Acceptance Criteria ready |
|
||||
| 🚀 **Deployment** | ✅ Production Ready | Blue-Green on QNAP Container Station |
|
||||
| 🔒 **Infrastructure** | ✅ Hardened (v1.9.8) | Sidecar APIs secured; dynamic VRAM Release; container hardened |
|
||||
| Area | Status | หมายเหตุ |
|
||||
| ---------------------- | ------------------------ | -------------------------------------------------------------- |
|
||||
| 🔧 **Backend** | ✅ Production Ready | NestJS 11, Express v5, 0 Vulnerabilities |
|
||||
| 🎨 **Frontend** | ✅ 100% Complete | Next.js 16.2.0, React 19.2.4, ESLint 9 |
|
||||
| 💾 **Database** | ✅ Schema v1.9.0 Stable | MariaDB 11.8, No-migration Policy |
|
||||
| 📘 **Documentation** | ✅ **10/10 Gaps Closed** | Product Vision → Release Policy (33 ADRs — v1.9.8) |
|
||||
| 🤖 **AI Architecture** | ✅ 33 ADRs Accepted | ADR-023A + ADR-024~029 + ADR-033 Model Sync & Security |
|
||||
| 🔄 **Workflow Engine** | ✅ ADR-021 Integrated | Transmittals & Circulation with Integrated Context |
|
||||
| 🧪 **Testing** | ✅ UAT Ready | E2E + Acceptance Criteria ready |
|
||||
| 🚀 **Deployment** | ✅ Production Ready | Blue-Green on QNAP Container Station |
|
||||
| 🔒 **Infrastructure** | ✅ Hardened (v1.9.8) | Sidecar APIs secured; dynamic VRAM Release; container hardened |
|
||||
|
||||
---
|
||||
|
||||
@@ -297,7 +297,7 @@ lcbp3-dms/
|
||||
│ ├── scripts/ # Audit & Sync scripts
|
||||
│ └── archive/ # Archived outdated tools
|
||||
│
|
||||
├── .windsurf/ # Windsurf-specific (Mirrored from .agents)
|
||||
├── .devin/ # Devin-specific (Mirrored from .agents)
|
||||
│
|
||||
├── .github/ # GitHub Actions workflows
|
||||
├── AGENTS.md # AI agent rules & project context (v1.9.0) [★ primary]
|
||||
@@ -314,20 +314,20 @@ lcbp3-dms/
|
||||
|
||||
### เอกสารหลัก (specs/ folder)
|
||||
|
||||
| เอกสาร | คำอธิบาย | Gap | ไฟล์หลัก |
|
||||
| ----------------------- | -------------------------------------------------------- | --------- | --------------------------------------- |
|
||||
| **Product Vision** | Vision, Strategic Pillars, Guardrails | Gap 1 ✅ | `00-03-product-vision.md` |
|
||||
| **User Stories** | 27 Stories, 8 Epics, MoSCoW | Gap 2 ✅ | `01-04-user-stories.md` |
|
||||
| **Acceptance Criteria** | UAT Criteria, Sign-off Process | Gap 3 ✅ | `01-05-acceptance-criteria.md` |
|
||||
| **UI/UX Wireframes** | 26 Screens, ASCII Wireframes, Design System | Gap 4 ✅ | `01-07-ui-wireframes.md` |
|
||||
| **Stakeholder & Risk** | Sign-off, Risk Register, Change Control | Gap 5 ✅ | `00-04-stakeholder-signoff-and-risk.md` |
|
||||
| **KPI Baseline** | 14 KPIs, SQL Queries, Grafana Specs | Gap 6 ✅ | `00-05-kpi-baseline.md` |
|
||||
| **Migration Scope** | 20K Docs, 3 Tiers, Go/No-Go Gates | Gap 7 ✅ | `03-06-migration-business-scope.md` |
|
||||
| **Release Policy** | SemVer, 5 Gates, Hotfix, Rollback | Gap 8 ✅ | `04-08-release-management-policy.md` |
|
||||
| **Training Plan** | Curriculum per Role, UAT Training | Gap 9 ✅ | `00-06-training-plan.md` |
|
||||
| **Edge Cases & Rules** | 37 Edge Cases, Business Logic Guards | Gap 10 ✅ | `01-06-edge-cases-and-rules.md` |
|
||||
| **Schema v1.9.0** | Tables, Views, Indexes (3-file split) | — | `lcbp3-v1.9.0-schema-*.sql` |
|
||||
| **Data Dictionary** | Field Meanings, Business Rules | — | `03-01-data-dictionary.md` |
|
||||
| เอกสาร | คำอธิบาย | Gap | ไฟล์หลัก |
|
||||
| ----------------------- | ----------------------------------------------------------------- | --------- | --------------------------------------- |
|
||||
| **Product Vision** | Vision, Strategic Pillars, Guardrails | Gap 1 ✅ | `00-03-product-vision.md` |
|
||||
| **User Stories** | 27 Stories, 8 Epics, MoSCoW | Gap 2 ✅ | `01-04-user-stories.md` |
|
||||
| **Acceptance Criteria** | UAT Criteria, Sign-off Process | Gap 3 ✅ | `01-05-acceptance-criteria.md` |
|
||||
| **UI/UX Wireframes** | 26 Screens, ASCII Wireframes, Design System | Gap 4 ✅ | `01-07-ui-wireframes.md` |
|
||||
| **Stakeholder & Risk** | Sign-off, Risk Register, Change Control | Gap 5 ✅ | `00-04-stakeholder-signoff-and-risk.md` |
|
||||
| **KPI Baseline** | 14 KPIs, SQL Queries, Grafana Specs | Gap 6 ✅ | `00-05-kpi-baseline.md` |
|
||||
| **Migration Scope** | 20K Docs, 3 Tiers, Go/No-Go Gates | Gap 7 ✅ | `03-06-migration-business-scope.md` |
|
||||
| **Release Policy** | SemVer, 5 Gates, Hotfix, Rollback | Gap 8 ✅ | `04-08-release-management-policy.md` |
|
||||
| **Training Plan** | Curriculum per Role, UAT Training | Gap 9 ✅ | `00-06-training-plan.md` |
|
||||
| **Edge Cases & Rules** | 37 Edge Cases, Business Logic Guards | Gap 10 ✅ | `01-06-edge-cases-and-rules.md` |
|
||||
| **Schema v1.9.0** | Tables, Views, Indexes (3-file split) | — | `lcbp3-v1.9.0-schema-*.sql` |
|
||||
| **Data Dictionary** | Field Meanings, Business Rules | — | `03-01-data-dictionary.md` |
|
||||
| **ADRs (33)** | All Architecture Decisions incl. ADR-019/021/023/024-029, ADR-033 | - | `06-Decision-Records/` |
|
||||
|
||||
---
|
||||
@@ -366,7 +366,7 @@ lcbp3-dms/
|
||||
- Development Process
|
||||
- Pull Request Process
|
||||
- Coding Standards
|
||||
- **AI-Assisted Contributions** (AGENTS.md + `.agents/skills/` skill pack + Windsurf slash commands)
|
||||
- **AI-Assisted Contributions** (AGENTS.md + `.agents/skills/` skill pack + Devin slash commands)
|
||||
|
||||
### 🤖 For AI Agents
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
// - 2026-06-03: ADR-034 — เปลี่ยน default model เป็น typhoon2.5-np-dms; เพิ่ม ocrModel field, keepAlive param ใน loadModel(), model option ใน OllamaGenerateOptions, getOcrModelName()
|
||||
// - 2026-06-06: เพิ่ม system prompt support ใน OllamaGenerateOptions และ generate() method เพื่อรองรับ Typhoon model ที่ต้องการ system prompt แยกต่างหาก
|
||||
// - 2026-06-06: [T036] แก้ไข default URL เป็น http://192.168.10.100:11434 (Desk-5439) แทน localhost; เพิ่ม options และ keepAlive ใน OllamaGenerateOptions เพื่อรองรับ Typhoon model parameters
|
||||
// - 2026-06-08: เพิ่ม num_predict ใน OllamaGenerateOptions.options — ป้องกัน JSON truncation เมื่อ LLM สร้าง structured output
|
||||
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
@@ -27,6 +28,8 @@ export interface OllamaGenerateOptions {
|
||||
repeat_penalty?: number;
|
||||
num_gpu?: number;
|
||||
num_ctx?: number;
|
||||
/** จำนวน tokens สูงสุดที่ LLM จะสร้าง — ป้องกัน JSON truncation */
|
||||
num_predict?: number;
|
||||
};
|
||||
/** keep_alive: -1 = stay loaded, 0 = unload immediately, N = seconds */
|
||||
keepAlive?: number;
|
||||
|
||||
+1
-1
@@ -726,7 +726,7 @@ AI-powered Document Management System
|
||||
6 Automation workflow
|
||||
7 Security
|
||||
```
|
||||
## 💬 Prompt Templates สำหรับถาม Windsurf
|
||||
## 💬 Prompt Templates สำหรับถาม Devin
|
||||
|
||||
### เมื่อต้องการสร้างฟีเจอร์ใหม่
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# AI Knowledge Base for NAP-DMS (LCBP3)
|
||||
|
||||
คลังความรู้สำหรับ AI Assistant (Antigravity, Windsurf, Codex) เพื่อช่วยในการพัฒนาระบบ Document Management System (DMS)
|
||||
คลังความรู้สำหรับ AI Assistant (Antigravity, Devin, Codex) เพื่อช่วยในการพัฒนาระบบ Document Management System (DMS)
|
||||
|
||||
## 📁 โครงสร้างโฟลเดอร์
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
- `core/`: กฎพื้นฐานและมาตรฐานการเขียนโค้ด
|
||||
- `dms/`: เฉพาะทางด้านระบบจัดการเอกสาร
|
||||
- `infra/`: งานด้าน Infrastructure และ Network
|
||||
- `codex/`: คำสั่งเฉพาะสำหรับ Windsurf/Codex
|
||||
- `codex/`: คำสั่งเฉพาะสำหรับ Devin/Codex
|
||||
- `templates/`: แม่แบบเอกสารต่างๆ (Spec, Bug Report, etc.)
|
||||
- `playbooks/`: คู่มือขั้นตอนการทำงานที่ซับซ้อน
|
||||
- `checklists/`: รายการตรวจสอบก่อนส่งงานหรือ Deploy
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// File: docs/ai-knowledge-base/prompts/codex/codex-bugfix.md
|
||||
# Bug Fix Prompt (Windsurf/Codex)
|
||||
# Bug Fix Prompt (Devin/Codex)
|
||||
|
||||
## ⭐ Role: Debugging Specialist
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// File: docs/ai-knowledge-base/prompts/codex/codex-feature.md
|
||||
# Feature Implementation Prompt (Windsurf/Codex)
|
||||
# Feature Implementation Prompt (Devin/Codex)
|
||||
|
||||
## ⭐ Role: Senior Full Stack Developer (DMS Specialist)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// File: docs/ai-knowledge-base/prompts/codex/codex-review.md
|
||||
# Code Review Prompt (Windsurf/Codex)
|
||||
# Code Review Prompt (Devin/Codex)
|
||||
|
||||
## ⭐ Role: Senior Code Reviewer (DMS Specialist)
|
||||
|
||||
|
||||
+4
-4
@@ -18,7 +18,7 @@ npx playwright install chromium
|
||||
npx playwright install
|
||||
```
|
||||
|
||||
### 3. **MCP Server สำหรับ Windsurf**
|
||||
### 3. **MCP Server สำหรับ Devin**
|
||||
|
||||
เพิ่มใน [.windsurfrc](cci:7://file:///e:/np-dms/lcbp3/.windsurfrc:0:0-0:0):
|
||||
|
||||
@@ -33,9 +33,9 @@ npx playwright install
|
||||
}
|
||||
```
|
||||
|
||||
**Restart Windsurf** แล้วจะเห็น Playwright MCP panel
|
||||
**Restart Devin** แล้วจะเห็น Playwright MCP panel
|
||||
|
||||
### 4. **การใช้งานผ่าน Windsurf Cascade**
|
||||
### 4. **การใช้งานผ่าน Devin Cascade**
|
||||
|
||||
เมื่อ MCP พร้อมแล้ว สามารถใช้คำสั่ง:
|
||||
|
||||
@@ -101,7 +101,7 @@ npx playwright test --headed
|
||||
npx playwright show-report
|
||||
```
|
||||
|
||||
### 8. **ถ้าใช้ MCP ผ่าน Windsurf**
|
||||
### 8. **ถ้าใช้ MCP ผ่าน Devin**
|
||||
|
||||
Cascade จะมี tool ให้ใช้:
|
||||
- `browser_navigate` - เปิด URL
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
# Memory Directory
|
||||
|
||||
This directory contains project-specific memory and context that is NOT already covered in the specs/ directory.
|
||||
|
||||
## Purpose
|
||||
|
||||
The `memory/` directory is for:
|
||||
- MCP Tools documentation (MariaDB + Memory tools)
|
||||
- Project memory override rules (referencing AGENTS.md)
|
||||
- Context that doesn't fit into the specs/ structure
|
||||
|
||||
## What's NOT Here
|
||||
|
||||
The following content has been moved to `specs/88-logs/`:
|
||||
- Session history logs
|
||||
- Recent rollouts
|
||||
- Rules and decisions (now in specs/06-Decision-Records/ ADRs)
|
||||
- Domain terminology (now in specs/00-overview/00-02-glossary.md)
|
||||
- Known commands (now in specs/05-Engineering-Guidelines/)
|
||||
- Environment & Services (now in specs/04-Infrastructure-OPS/)
|
||||
|
||||
## Files
|
||||
|
||||
- `mcp-tools.md` — MCP MariaDB Tools and MCP Memory Tools documentation
|
||||
- `project-memory-override.md` — Project memory override rule referencing AGENTS.md
|
||||
|
||||
## Single Source of Truth
|
||||
|
||||
For project rules, decisions, and specifications, always refer to:
|
||||
- `AGENTS.md` — Project context and rules
|
||||
- `specs/06-Decision-Records/` — Architecture Decision Records (ADRs)
|
||||
- `specs/00-overview/00-02-glossary.md` — Domain terminology
|
||||
- `specs/05-Engineering-Guidelines/` — Backend, frontend, and testing guidelines
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,95 @@
|
||||
# MCP Tools Documentation
|
||||
|
||||
## MCP MariaDB Tools
|
||||
|
||||
MCP MariaDB server provides tools for direct database inspection and management. Used for:
|
||||
|
||||
- Verifying schema against spec file `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql`
|
||||
- Debugging database issues without entering MySQL client
|
||||
- Checking data in production/staging
|
||||
- Validating schema changes before deploy
|
||||
|
||||
### Available Tools
|
||||
|
||||
| Tool | Purpose | Example Usage |
|
||||
|------|---------|----------------|
|
||||
| `mcp1_mysql_test_connection` | Test database connection | Verify MCP server connectivity |
|
||||
| `mcp1_mysql_show_databases` | List all databases | See available databases |
|
||||
| `mcp1_mysql_show_tables` | List all tables in database | See tables in `lcbp3` |
|
||||
| `mcp1_mysql_describe_table` | View table structure/columns | Check columns, types, keys of `correspondences` |
|
||||
| `mcp1_mysql_query` | Run SELECT query | View data in table or join query |
|
||||
| `mcp1_mysql_insert` | INSERT data | Add seed data or test data |
|
||||
| `mcp1_mysql_update` | UPDATE data | Modify data in table |
|
||||
| `mcp1_mysql_delete` | DELETE data | Delete data from table |
|
||||
|
||||
### Usage with Development Flow
|
||||
|
||||
**When writing new queries:**
|
||||
1. Use `mcp1_mysql_describe_table` to check columns and types
|
||||
2. Compare with `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql`
|
||||
3. Use `mcp1_mysql_query` to test query before implement
|
||||
|
||||
**When changing schema (ADR-009):**
|
||||
1. Use `mcp1_mysql_describe_table` to see current structure
|
||||
2. Create SQL delta in `specs/03-Data-and-Storage/deltas/`
|
||||
3. Use `mcp1_mysql_query` to verify result after apply delta
|
||||
|
||||
**When debugging database issues:**
|
||||
1. Use `mcp1_mysql_query` to see actual data
|
||||
2. Compare with spec and data dictionary
|
||||
3. Check foreign keys and constraints
|
||||
|
||||
### Warnings
|
||||
|
||||
- **❌ NEVER use MCP MariaDB for DDL operations** (CREATE/ALTER/DROP) directly — must use SQL delta per ADR-009
|
||||
- **✅ Use for DQL/DML operations** (SELECT/INSERT/UPDATE/DELETE) for debug and test only
|
||||
- **⚠️ Be careful with DELETE operations** — may lose data in production
|
||||
- **✅ Always verify schema against spec file** before writing queries
|
||||
|
||||
---
|
||||
|
||||
## MCP Memory Tools
|
||||
|
||||
MCP Memory server provides tools for managing Knowledge Graph and Long-term Memory. Used for:
|
||||
|
||||
- Storing project knowledge and context in Graph format (Entities + Relations + Observations)
|
||||
- Searching and retrieving context from memory saved in previous sessions
|
||||
- Creating/editing/deleting entities, relations, and observations in knowledge graph
|
||||
|
||||
### Available Tools
|
||||
|
||||
| Tool | Purpose | Example Usage |
|
||||
|------|---------|----------------|
|
||||
| `mcp3_create_entities` | Create multiple new entities with observations | Create new entities like Project, User, Task |
|
||||
| `mcp3_create_relations` | Create relations between entities | Create relation: Project → has → User |
|
||||
| `mcp3_add_observations` | Add observations to existing entities | Add additional context to entity |
|
||||
| `mcp3_delete_entities` | Delete entities and related relations | Delete unused entities |
|
||||
| `mcp3_delete_relations` | Delete relations between entities | Delete incorrect or unused relations |
|
||||
| `mcp3_delete_observations` | Delete observations from entity | Delete incorrect or stale context |
|
||||
| `mcp3_open_nodes` | Retrieve entities by name | Get specific entity by name |
|
||||
| `mcp3_read_graph` | Read entire knowledge graph | See full graph structure |
|
||||
| `mcp3_search_nodes` | Search entities by query | Find entity by name, type, or observation |
|
||||
|
||||
### Usage with Development Flow
|
||||
|
||||
**When saving new context:**
|
||||
1. Use `mcp3_create_entities` to create new entities (if not exist)
|
||||
2. Use `mcp3_create_relations` to link entities
|
||||
3. Use `mcp3_add_observations` to add context/observations
|
||||
|
||||
**When searching context:**
|
||||
1. Use `mcp3_search_nodes` to find relevant entities
|
||||
2. Use `mcp3_open_nodes` to get specific entity data
|
||||
3. Use `mcp3_read_graph` to see relations between entities
|
||||
|
||||
**When editing context:**
|
||||
1. Use `mcp3_add_observations` to add new observations
|
||||
2. Use `mcp3_delete_observations` to delete incorrect observations
|
||||
3. Use `mcp3_create_relations` or `mcp3_delete_relations` to adjust relations
|
||||
|
||||
### Warnings
|
||||
|
||||
- **✅ Use for storing context that needs to be shared across multiple sessions** — e.g., important decisions, architecture decisions, rollout history
|
||||
- **⚠️ Be careful when deleting entities** — may lose context still in use
|
||||
- **✅ Check if entity exists before creating** — use `mcp3_search_nodes` or `mcp3_open_nodes` first
|
||||
- **✅ Use clear and unique entity names** — to prevent confusion
|
||||
@@ -0,0 +1,87 @@
|
||||
# Project Memory Override
|
||||
|
||||
> **Project:** NAP-DMS (LCBP3) — Laem Chabang Port Phase 3 Document Management System
|
||||
> **Version:** 1.9.9 (Last Synced: 2026-06-03)
|
||||
> **Stack:** NestJS 11 + Next.js 16 + TypeScript + MariaDB 11.8 + Redis + BullMQ + Elasticsearch + Ollama (on-prem AI)
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **Project memory นี้ต้องใช้งานภายใต้ `AGENTS.md` เสมอ**
|
||||
>
|
||||
> - ให้ใช้ `AGENTS.md` เป็นกฎหลักก่อน memory ทุกครั้ง
|
||||
> - ถ้า memory เก่าหรือ session note ขัดกับ `AGENTS.md` ให้ยึด `AGENTS.md`
|
||||
> - งาน schema ต้องทำตาม ADR-009 ผ่าน SQL/delta เท่านั้น
|
||||
> - งาน UUID/Public API ต้องทำตาม ADR-019 โดยใช้ `publicId` และห้าม `parseInt()` บน UUID
|
||||
> - งาน n8n / AI migration ต้องอยู่ในขอบเขต ADR-023A และ mutation ต้องมี `Idempotency-Key`
|
||||
|
||||
## OS Rules & Sandbox Constraints
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **ระบบรันอยู่บน Windows OS**
|
||||
>
|
||||
> - ห้ามใช้คำสั่ง `bash` หรือคำสั่งของ Linux โดยเด็ดขาด
|
||||
> - คำสั่งทุกประเภทที่จะส่งให้ผู้ใช้รันหรือรันผ่าน Terminal ต้องเป็น **PowerShell** หรือ **CMD** เท่านั้น
|
||||
> - ห้ามใช้คำสั่ง `cd` ในการสลับ Directory ให้ระบุพารามิเตอร์ `Cwd` ใน Tool ตรง ๆ
|
||||
|
||||
## Current Decisions (Locked)
|
||||
|
||||
> การตัดสินใจเหล่านี้ **ไม่สามารถเปลี่ยนแปลงได้** โดยไม่ได้รับ Explicit Approval
|
||||
|
||||
| ID | Decision | ADR |
|
||||
| --- | ------------------------------------------------------------------------------------------- | --------- |
|
||||
| D1 | n8n = Migration Phase orchestrator เท่านั้น — ห้ามทำ New Correspondence pipeline ผ่าน n8n | ADR-023A |
|
||||
| D2 | New Correspondence → BullMQ `ai-realtime` queue โดยตรง (ไม่ผ่าน n8n) | ADR-023A |
|
||||
| D3 | n8n ต้อง call `POST /api/ai/jobs` (DMS Backend) เท่านั้น — ห้าม call Ollama/Qdrant โดยตรง | ADR-023A |
|
||||
| D4 | Excel metadata ส่งไปพร้อม AI job เป็น context (docNumber, title, sender ฯลฯ) | Session 2 |
|
||||
| D5 | Tag suggestion ใช้ทาง C: แนะนำ existing tags + สร้างใหม่ได้ถ้าไม่มี (`isNew: true` flag) | Session 2 |
|
||||
| D6 | Editable Review Form: AI pre-fill → user approve/edit → submit (human-in-the-loop ทุกครั้ง) | ADR-023 |
|
||||
| D7 | UUID Strategy: `publicId` (UUIDv7) เท่านั้นสำหรับ Public API — INT PK ต้อง `@Exclude()` | ADR-019 |
|
||||
| D8 | Schema changes: แก้ SQL โดยตรง + เพิ่ม `deltas/*.sql` — ห้ามใช้ TypeORM migration files | ADR-009 |
|
||||
| D9 | Qdrant search ต้องส่ง `projectPublicId` เป็น mandatory parameter ทุกครั้ง (compile-time) | ADR-023A |
|
||||
| D10 | AI model stack: `typhoon2.5-np-dms:latest` (Main LLM) + `typhoon-np-dms-ocr:latest` (OCR, keep_alive:0) + `BGE-M3` (Dense 1024 + Sparse Embedding) + `BGE-Reranker-Large` (Reranker) on Admin Desktop — `nomic-embed-text` ถูกแทนที่แล้ว (ADR-034/035) | ADR-034/035 |
|
||||
| D11 | RAG Embedding trigger: `syncStatus()` → `enqueueRagPrepare()` เมื่อ status ≠ DRAFT; jobId = `rag-prepare:{documentPublicId}:{revisionNumber}` (BullMQ dedup); delete-before-upsert ทุกครั้ง | ADR-035 |
|
||||
| D12 | Qdrant collection `lcbp3_vectors` = Hybrid schema: `bge_dense` (1024 dims, Cosine) + `bge_sparse` (SPLADE); payload indexes: `project_public_id` (tenant), `doc_public_id`, `status_code`, `doc_type` | ADR-035 |
|
||||
|
||||
## Environment & Services
|
||||
|
||||
| Service | Local URL / Port | Production | Notes |
|
||||
| ----------------- | ----------------------------- | ------------------------- | ------------------------------------ |
|
||||
| **Backend API** | `http://localhost:3001` | QNAP `192.168.10.8` | NestJS — `/api` prefix |
|
||||
| **Frontend** | `http://localhost:3000` | QNAP `192.168.10.8` | Next.js |
|
||||
| **MariaDB** | `localhost:3307` | QNAP internal | DB: `lcbp3`, root via docker |
|
||||
| **Redis** | `localhost:6379` | QNAP internal | BullMQ + session store |
|
||||
| **Ollama** | `http://192.168.10.100:11434` | Admin Desktop (Desk-5439) | typhoon2.5-np-dms:latest (main) + typhoon-np-dms-ocr:latest (OCR, keep_alive:0) |
|
||||
| **Qdrant** | `http://localhost:6333` | Admin Desktop (Desk-5439) | Vector DB — requires projectPublicId |
|
||||
| **OCR Sidecar** | `http://192.168.10.100:8765` | Admin Desktop (Desk-5439) | Tesseract (fallback) / Typhoon OCR-3B (primary) + BGE-M3 `/embed` + BGE-Reranker `/rerank` |
|
||||
| **Gitea** | `https://git.np-dms.work` | QNAP `192.168.10.8` | Source + CI/CD |
|
||||
| **Gitea Runner** | ASUSTOR `192.168.10.9` | — | CI runner |
|
||||
|
||||
### Key Environment Variables
|
||||
|
||||
```
|
||||
DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME
|
||||
REDIS_HOST, REDIS_PORT
|
||||
JWT_SECRET, JWT_EXPIRES_IN
|
||||
OLLAMA_BASE_URL (ชี้ไป Admin Desktop)
|
||||
QDRANT_URL
|
||||
```
|
||||
|
||||
## Next Session Focus
|
||||
|
||||
### N8N Migration & E2E Testing
|
||||
|
||||
- [ ] **Import `n8n.workflow.v2.json`** เข้า n8n UI และทดสอบ End-to-End
|
||||
- [ ] **ทดสอบ End-to-End จริง** — รัน n8n กับ Excel ตัวอย่าง
|
||||
- [ ] **Frontend Editable Review Form** (Pipeline B) — pre-fill AI suggestions + tag suggestion UI
|
||||
- [ ] **Dry Run** กับ Excel จริงก่อน Production Migration
|
||||
|
||||
### RAG Pipeline — Production Readiness
|
||||
|
||||
- [X] **รัน SQL delta** `2026-06-05-add-rag-chunking-prompt.sql` ใน MariaDB production
|
||||
- [ ] **Deploy OCR Sidecar ใหม่** บน Desk-5439 หลัง rebuild image
|
||||
- [ ] **Drop + recreate Qdrant collection** `lcbp3_vectors` เป็น Hybrid schema
|
||||
- [ ] **SC-002 E2E accuracy test** — ทดสอบ Chat Q&A ≥ 80% accuracy
|
||||
|
||||
### General Tasks
|
||||
|
||||
- [ ] เพิ่ม unit test สำหรับ `upsertQueueRecord` ใน `ai-migration-checkpoint.service.spec.ts`
|
||||
- [ ] เพิ่ม unit test สำหรับ checksum dedup ใน `file-storage.service.spec.ts`
|
||||
@@ -4,7 +4,7 @@
|
||||
- **Status:** Active
|
||||
- **Version:** 1.9.0
|
||||
- **Date:** 2026-05-13
|
||||
- **Author:** Senior Full Stack Developer (Windsurf AI)
|
||||
- **Author:** Senior Full Stack Developer (Devin AI)
|
||||
- **Reference:** ADR-001 (Workflow Engine), ADR-002 (Redlock), ADR-016 (Security)
|
||||
|
||||
---
|
||||
|
||||
@@ -212,7 +212,7 @@ Invalidate: หลัง activate สำเร็จ (AiPromptsService.activate(
|
||||
## Grilling Session Log
|
||||
|
||||
```
|
||||
2026-05-25 — grilling session ผ่าน Windsurf Cascade
|
||||
2026-05-25 — grilling session ผ่าน Devin Cascade
|
||||
Q1: prompt_type scope → 'ocr_extraction' เดียว (8 fields) ร่วมกันทั้งคู่
|
||||
Q2: activation model → Option A (single is_active flag)
|
||||
Q3: result storage → Option C (auto-save + manual_note)
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
* **Dev Qdrant:** Separate Qdrant instance บน ASUSTOR สำหรับ codebase embedding โดยเฉพาะ — ห้ามใช้ Qdrant instance เดียวกับ DMS document RAG (ADR-023A)
|
||||
* **SOUL.md:** Hermes working journal อยู่ใน container เท่านั้น (`/volume1/docker/hermes/SOUL.md`) ไม่ sync กลับ repo
|
||||
* **Context Source:** Hermes ดึง project context จาก `specs/06-Decision-Records/CONTEXT-ADR-031.md` + `AGENTS.md` โดยตรง ไม่ใช้ Obsidian หรือ external knowledge base
|
||||
* **Sub-agent Delegation:** Hermes orchestrate โดย (1) Cloud sub-agents ใช้ model เล็กกว่า (Claude Haiku/GPT-4o-mini) สำหรับ code generation tasks และ (2) MCP invocations ไปยัง Windsurf/agy ที่มีอยู่แล้ว
|
||||
* **Sub-agent Delegation:** Hermes orchestrate โดย (1) Cloud sub-agents ใช้ model เล็กกว่า (Claude Haiku/GPT-4o-mini) สำหรับ code generation tasks และ (2) MCP invocations ไปยัง Devin/agy ที่มีอยู่แล้ว
|
||||
* **Git Identity:** Hermes ใช้ Gitea service account (`hermes-bot`) push เฉพาะ `hermes/*` branches — ห้าม push ตรง `main`/`develop` ทุกกรณี — ทุก change ต้องผ่าน PR ที่ human approve
|
||||
|
||||
## Context
|
||||
@@ -97,7 +97,7 @@ Hermes ทำหน้าที่เป็น "Lead Developer" / "Conductor"
|
||||
┌───────┴────────┐
|
||||
▼ ▼
|
||||
[Cloud Sub-agents] [MCP Tool Invocations]
|
||||
Claude Haiku / Windsurf / agy / Codex
|
||||
Claude Haiku / Devin / agy / Codex
|
||||
GPT-4o-mini (existing tools, no new models)
|
||||
│ ▼
|
||||
└────────┬───────
|
||||
@@ -173,7 +173,7 @@ Orchestrator
|
||||
→ MCP hermes-tools: bash/git operations บน ASUSTOR
|
||||
→ MCP mariadb: schema lookup (read-only)
|
||||
→ MCP gitea: PR/issue management
|
||||
→ Triggers Windsurf/agy ถ้า complex scaffolding needed
|
||||
→ Triggers Devin/agy ถ้า complex scaffolding needed
|
||||
```
|
||||
|
||||
**Data Classification Enforcement:**
|
||||
@@ -582,7 +582,7 @@ HERMES_TELEGRAM_RATE_LIMIT_WINDOW_MS=60000
|
||||
Hermes รันได้ 3 mode หลักที่ share config/data เดียวกันใน `~/.hermes`:
|
||||
- **CLI/TUI** — `hermes --tui` interactive session
|
||||
- **Messaging Gateway** — รองรับ 22 platform (Telegram, Discord, Slack, WhatsApp, Signal, LINE, Mattermost, Matrix, Teams, Google Chat ฯลฯ)
|
||||
- **IDE Integration** — เชื่อมกับ Windsurf / Codex ผ่าน MCP
|
||||
- **IDE Integration** — เชื่อมกับ Devin / Codex ผ่าน MCP
|
||||
|
||||
#### CLI Commands
|
||||
|
||||
@@ -644,7 +644,7 @@ Hermes รันบน ASUSTOR ตลอด 24/7 การ SSH เข้าไ
|
||||
|
||||
| สถานการณ์ | Interface | ทำไม |
|
||||
|---|---|---|
|
||||
| นั่งทำงานที่โต๊ะ coding | Windsurf Cascade | IDE context + MCP |
|
||||
| นั่งทำงานที่โต๊ะ coding | Devin Cascade | IDE context + MCP |
|
||||
| สั่ง task ซับซ้อน / multi-agent | `agy` CLI หรือ Desktop | parallel subagents |
|
||||
| batch ops / scaffolding | Codex CLI | bash execution |
|
||||
| อยู่นอกบ้าน / มือถือ | Telegram → Hermes | always-on บน ASUSTOR สำหรับ DevOps commands เท่านั้น |
|
||||
@@ -870,7 +870,7 @@ ASUSTOR (VLAN ใดก็ตาม) → QNAP VLAN 10 (MariaDB :3306, Gitea :300
|
||||
|
||||
* Hermes, Telegram Bridge, MCP, และ hermes proxy ต้องเป็น optional DevOps tooling ไม่ใช่ dependency ของ DMS production runtime
|
||||
* หาก Hermes stack ล่ม ผู้ใช้ DMS ต้องยังใช้งาน frontend/backend, Workflow Engine, notification, และ AI pipeline ตาม ADR-023A ได้ตามปกติ
|
||||
* Degraded mode คือกลับไปใช้ IDE, Gitea UI, CI UI, SSH/manual ops, และ Codex/Windsurf local workflow ตามปกติ
|
||||
* Degraded mode คือกลับไปใช้ IDE, Gitea UI, CI UI, SSH/manual ops, และ Codex/Devin local workflow ตามปกติ
|
||||
* ห้ามให้ production deploy, Workflow Engine transition, AI inference, หรือ document ingestion รอ Hermes availability
|
||||
* Monitoring ต้องแจ้งเตือนเฉพาะ operator/devops team ไม่ alert เป็น production DMS outage เว้นแต่มีผลกระทบจริงกับ DMS service
|
||||
|
||||
@@ -990,6 +990,6 @@ ADR-031 ต้อง rollout แบบเป็น stage เพื่อลด
|
||||
| 2026-05-28 | 1.0.0 | Initial ADR creation - Merged from CONTEXT-ADR-031 and CONTEXT-ADR-031-Added |
|
||||
| 2026-05-28 | 1.1.0 | Added sections 4–6 from CONTEXT-ADR-031-Added-2: Hermes Interface Modes, agy+Hermes MCP Integration, Deploy Prerequisites; fixed port conflict (hermes proxy :8766, not :8765) |
|
||||
| 2026-05-29 | 1.1.1 | Aligned with CONTEXT-ADR-031.md grill-with-docs: fixed monorepo structure (flat layout), corrected file paths, updated repo URL to git.np-dms.work, added AGENTS.md v1.9.7 reference |
|
||||
| 2026-05-29 | 1.1.2 | Linked root CONTEXT.md with specs/CONTEXT-ADR-031.md; fixed setup-context.sh paths; updated Windsurf/agy/Hermes symlink targets |
|
||||
| 2026-05-29 | 1.1.2 | Linked root CONTEXT.md with specs/CONTEXT-ADR-031.md; fixed setup-context.sh paths; updated Devin/agy/Hermes symlink targets |
|
||||
| 2026-05-29 | 2.0.0 | **v2.0 Rewrite** — grill-with-docs: Orchestration as primary concern; Added Autonomous Dev Loop architecture; Cloud AI exception (Data Classification Policy C); Separate Dev Qdrant on ASUSTOR; SOUL.md container-local journal; Sub-agent delegation (Cloud+MCP); Git identity hermes-bot + hermes/* branches + PR-only flow |
|
||||
| 2026-05-29 | 2.0.1 | Step 1 context assembly: เพิ่ม `CONTEXT.md` (root domain terminology) เป็น selective context source สำหรับ DMS feature coding และ Schema/DB work tasks |
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# LCBP3 DMS — Agent Context (ADR-031)
|
||||
# Single source of truth สำหรับทุก agent tool (Hermes, agy, Windsurf)
|
||||
# Single source of truth สำหรับทุก agent tool (Hermes, agy, Devin)
|
||||
#
|
||||
# ที่อยู่ไฟล์: specs/06-Decision-Records/CONTEXT-ADR-031.md
|
||||
#
|
||||
# Tool ที่อ่านไฟล์นี้:
|
||||
# Hermes → /volume1/docker/hermes/config/MEMORY.md (symlink หรือ copy)
|
||||
# agy → ~/.gemini/antigravity-cli/settings.json > contextFiles[]
|
||||
# Windsurf → .windsurfrules > @import specs/06-Decision-Records/CONTEXT-ADR-031.md
|
||||
# Devin → .devin/rules > @import specs/06-Decision-Records/CONTEXT-ADR-031.md
|
||||
#
|
||||
# Domain context (Correspondence, RFA, AI Architecture): ดู CONTEXT.md ที่ root
|
||||
#
|
||||
@@ -23,7 +23,7 @@
|
||||
| Domain | Construction project document management |
|
||||
| Owner | เป้ |
|
||||
| Repo | Gitea: `https://git.np-dms.work/np-dms/lcbp3` (internal) |
|
||||
| Primary IDE | Windsurf (Cascade + MCP) |
|
||||
| Primary IDE | Devin (Cascade + MCP) |
|
||||
| Agent stack | Hermes (ASUSTOR) · agy CLI · Codex CLI |
|
||||
|
||||
---
|
||||
@@ -37,7 +37,7 @@ lcbp3/
|
||||
├── specs/ ADRs, specs, data dictionary
|
||||
├── .agents/ Agent skills and rules
|
||||
├── .gitea/workflows/ CI/CD pipeline definitions
|
||||
├── .windsurf/ Windsurf workflows and rules
|
||||
├── .devin/ Devin workflows and rules
|
||||
├── memory/ Agent memory
|
||||
└── CONTEXT.md ← this file
|
||||
```
|
||||
@@ -180,9 +180,9 @@ Assumption ที่ตั้งใจจะใช้: [assumption]
|
||||
- Max parallel subagents: 3
|
||||
- Delegate bash/git execution → Hermes via MCP
|
||||
|
||||
### Windsurf / Cascade
|
||||
### Devin / Cascade
|
||||
- MCP: MariaDB (schema lookup), Gitea (PR/issue)
|
||||
- Rules enforced via `AGENTS.md` v1.9.7 (master), synced to `.windsurfrules` และ `.agents/rules/`
|
||||
- Rules enforced via `AGENTS.md` v1.9.7 (master), synced to `.devin/rules` และ `.agents/rules/`
|
||||
- Primary tool สำหรับ active coding
|
||||
|
||||
## Setup context
|
||||
@@ -190,7 +190,7 @@ Assumption ที่ตั้งใจจะใช้: [assumption]
|
||||
# setup-context.sh — wire CONTEXT-ADR-031.md ไปยัง tools ทุกตัว
|
||||
#
|
||||
# รันจาก: specs/06-Decision-Records/CONTEXT-ADR-031.md (ดูส่วนท้ายไฟล์)
|
||||
# รันบน: laptop (สำหรับ agy + Windsurf) และ ASUSTOR (สำหรับ Hermes)
|
||||
# รันบน: laptop (สำหรับ agy + Devin) และ ASUSTOR (สำหรับ Hermes)
|
||||
#
|
||||
# Usage:
|
||||
# cd specs/06-Decision-Records && bash CONTEXT-ADR-031.sh laptop
|
||||
@@ -266,26 +266,26 @@ PYEOF
|
||||
fi
|
||||
}
|
||||
|
||||
# ── laptop: Windsurf ─────────────────────────────────────────
|
||||
setup_windsurf() {
|
||||
section "Windsurf .windsurfrules"
|
||||
# ── laptop: Devin ─────────────────────────────────────────
|
||||
setup_devin() {
|
||||
section "Devin .devin/rules"
|
||||
|
||||
RULES="$REPO_ROOT/.windsurfrules"
|
||||
RULES="$REPO_ROOT/.devin/rules"
|
||||
IMPORT_LINE="@import specs/06-Decision-Records/CONTEXT-ADR-031.md"
|
||||
|
||||
if [ ! -f "$RULES" ]; then
|
||||
warn ".windsurfrules ไม่พบ — ข้ามขั้นตอนนี้"
|
||||
warn ".devin/rules ไม่พบ — ข้ามขั้นตอนนี้"
|
||||
return
|
||||
fi
|
||||
|
||||
if grep -q "@import specs/06-Decision-Records/CONTEXT-ADR-031.md" "$RULES"; then
|
||||
info "@import specs/06-Decision-Records/CONTEXT-ADR-031.md มีอยู่แล้วใน .windsurfrules"
|
||||
info "@import specs/06-Decision-Records/CONTEXT-ADR-031.md มีอยู่แล้วใน .devin/rules"
|
||||
else
|
||||
# เพิ่ม import ที่บรรทัดแรก
|
||||
TMPFILE=$(mktemp)
|
||||
echo "$IMPORT_LINE" | cat - "$RULES" > "$TMPFILE"
|
||||
mv "$TMPFILE" "$RULES"
|
||||
info "เพิ่ม @import specs/06-Decision-Records/CONTEXT-ADR-031.md ที่บรรทัดแรกของ .windsurfrules"
|
||||
info "เพิ่ม @import specs/06-Decision-Records/CONTEXT-ADR-031.md ที่บรรทัดแรกของ .devin/rules"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -224,7 +224,7 @@ hermes/
|
||||
|
||||
- ProxyService (OpenAI-compatible API, port 8766)
|
||||
- Secret payload detection middleware (reject if production data detected)
|
||||
- MCP server endpoint (/mcp) for agy + Windsurf integration
|
||||
- MCP server endpoint (/mcp) for agy + Devin integration
|
||||
- HermesMemoryMcpTool (expose DMS context for agy recall)
|
||||
- HermesToolsMcpTool (expose bash/git execution capability)
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
|
||||
- [ ] T037 [US4] Create `hermes/src/proxy/proxy.service.ts` — OpenAI-compatible API (port 8766); forward coding/devops requests ไป Cloud AI พร้อม DMS context injection; validate payload ไม่มี production data (ใช้ secret-redactor.util.ts); ห้าม forward ถ้าตรวจพบ production data
|
||||
- [ ] T038 [US4] Create `hermes/src/proxy/proxy.module.ts` + controller — bind ที่ port 8766 แยกจาก main API port 8080; API Key auth; LAN/VPN-only note ใน config
|
||||
- [ ] T039 [P] [US4] Create `hermes/src/integrations/mcp/mcp-server.service.ts` — expose `/mcp` endpoint สำหรับ agy + Windsurf integration; implement `hermes-memory` tool (recall DMS context); implement `hermes-tools` tool (bash/git execution on ASUSTOR)
|
||||
- [ ] T039 [P] [US4] Create `hermes/src/integrations/mcp/mcp-server.service.ts` — expose `/mcp` endpoint สำหรับ agy + Devin integration; implement `hermes-memory` tool (recall DMS context); implement `hermes-tools` tool (bash/git execution on ASUSTOR)
|
||||
- [ ] T040 [P] [US4] Create `hermes/src/integrations/mcp/mcp.module.ts` — wire MCP server providers
|
||||
- [ ] T041 [P] [US4] Verify port isolation: proxy port 8766 ≠ PaddleOCR sidecar port 8765 (ADR-023A) — add port validation assertion ใน `hermes/src/config/hermes.config.ts` ที่ startup
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# Recent Rollouts
|
||||
|
||||
| วันที่ | Version | รายการ | สถานะ |
|
||||
| ---------- | ------- | ---------------------------------------------------------------------------------------------------- | ----------------------------- |
|
||||
| 2026-05-23 | v1.9.6 | Specs reorganization (`100/200/300-*` folders), AGENTS.md v1.9.6 update | ✅ Complete |
|
||||
| 2026-05-23 | v1.9.6 | N8N Workflow v2 (`n8n.workflow.v2.json`) — ADR-023A compliant, ลบ Ollama direct | ⏳ Pending import to n8n UI |
|
||||
| 2026-05-24 | v1.9.6 | AGENTS.md Project Memory Override rule (Devin / Antigravity / Codex) | ✅ Complete |
|
||||
| 2026-05-25 | v1.9.6 | Migration Queue attachment UUID fix — DTO + Service + n8n.workflow.v2.json (Session 3) | ✅ Complete (tsc verified) |
|
||||
| 2026-05-25 | v1.9.6 | Migration error normalization + `job_id` logging — workflow + backend + SQL/delta (Session 4) | ✅ Complete |
|
||||
| 2026-05-25 | v1.9.6 | PaddleOCR Sidecar บน Desk-5439 — FastAPI `/ocr`+`/normalize`, CIFS mount, path remapping (Session 7) | ✅ Running |
|
||||
| 2026-05-27 | v1.9.7 | Context-Aware Prompt Templates & DB CC Whitespace Cleanup (ADR-030) (Session 9) | ✅ Complete (v1.9.7 main) |
|
||||
| 2026-05-30 | v1.9.7 | OCR Engine Migration — PaddleOCR → Tesseract (Session 8) | ✅ Complete (pending rebuild) |
|
||||
| 2026-05-30 | v1.9.7 | OCR Sandbox Two-Step Flow (ADR-030/231) — Step 1 OCR-only → Step 2 AI Extraction (Session 10) | ✅ Complete |
|
||||
| 2026-05-30 | v1.9.7 | Typhoon OCR & LLM Integration (ADR-032) — Dynamic model switching + VRAM Monitor (Session 11) | ✅ Complete |
|
||||
| 2026-06-03 | v1.9.8 | Thai-Optimized AI Model Stack (ADR-034) — typhoon2.5-np-dms:latest + typhoon-np-dms-ocr:latest | ✅ Complete |
|
||||
| 2026-06-05 | v1.9.8 | RAG Pipeline Enhancements (Spec 234 / ADR-035) — BGE-M3 + BGE-Reranker + Hybrid Qdrant (Session 14/15) | ✅ Complete |
|
||||
| 2026-06-06 | v1.9.9 | LLM JSON Parse Failure & VRAM Fix (ADR-035-135) — retry logic + keep_alive=0 + ESLint heap fix | ✅ Complete |
|
||||
@@ -0,0 +1,45 @@
|
||||
# Session 2 — 2026-05-23 (N8N Workflow Refactor)
|
||||
|
||||
## Decisions ที่ Lock แล้ว (จาก QuizMe Session)
|
||||
|
||||
| # | Decision |
|
||||
| ------- | ------------------------------------------------------------------------------------ |
|
||||
| S1 | **n8n = Migration only** — New Correspondence ใช้ Backend pipeline (BullMQ) |
|
||||
| S2 | New Correspondence → BullMQ `ai-realtime` (ไม่ผ่าน n8n) |
|
||||
| S3 | n8n call `POST /api/ai/jobs` (Backend) แทน Ollama direct (ADR-023A) |
|
||||
| PA | Excel metadata (`docNumber`, `title`, `sender`, etc.) ส่งไปพร้อม AI job เป็น context |
|
||||
| PB-Tags | Tag suggestion ทาง C — แนะนำ existing + สร้าง tag ใหม่ได้ถ้าไม่มี (`isNew` flag) |
|
||||
| PB-UX | Editable form pre-filled ด้วย AI suggestions — user approve/edit ก่อน submit |
|
||||
|
||||
## Endpoint ที่ Verified แล้ว
|
||||
|
||||
- `POST /api/ai/jobs` (`type: migrate-document`) — **พร้อมใช้งานแล้ว** (verified 2026-05-23)
|
||||
- `GET /api/ai/jobs/:jobId` — polling endpoint พร้อม
|
||||
- `POST /api/storage/upload` — two-phase upload พร้อม
|
||||
|
||||
## ไฟล์ที่สร้าง/แก้ไข
|
||||
|
||||
| ไฟล์ | การเปลี่ยนแปลง |
|
||||
| -------------------------------------------------------------- | -------------------------------------------------------------- |
|
||||
| `specs/03-Data-and-Storage/CONTEXT-N8N-Refactor.md` | ✅ สร้างใหม่ — context doc สำหรับ implement |
|
||||
| `specs/03-Data-and-Storage/n8n.workflow.v2.json` | ✅ สร้างใหม่ — ADR-023A compliant workflow |
|
||||
| `specs/03-Data-and-Storage/03-05-n8n-migration-setup-guide.md` | ✅ อัพเดต v1.9.0 — ลบ Ollama direct, เพิ่มขั้นตอน update token |
|
||||
| `specs/03-Data-and-Storage/03-06-migration-business-scope.md` | ✅ อัพเดต — Gate #1 blocker → Verified 2026-05-23 |
|
||||
|
||||
## สาระสำคัญของ n8n.workflow.v2.json
|
||||
|
||||
**Nodes ที่ลบ (ADR-023A violations):** `Ollama AI Analysis`, `Build AI Prompt`, `Extract PDF Text` (Tika), `Check/Update Fallback State`, `Import to Backend`, `Upsert Tags`, `Link Tags`
|
||||
|
||||
**Nodes ใหม่:** `Validate Token` → `Upload PDF to Backend` → `Build AI Job Payload` → `Submit AI Job` → `Poll AI Job Status`
|
||||
|
||||
**Flow สรุป:**
|
||||
|
||||
```
|
||||
Form Trigger → Set Config → Health/Token Check → Fetch Master Data
|
||||
→ File Mount Check → Read Excel → Read Checkpoint
|
||||
→ [Per Record: File Validate → Upload PDF → Submit AI Job → Poll → Parse/Route]
|
||||
→ Auto/Flagged → migration_review_queue
|
||||
→ Rejected → CSV Log
|
||||
→ Error → CSV + DB Log
|
||||
→ Save Checkpoint → Delay → Loop
|
||||
```
|
||||
@@ -0,0 +1,14 @@
|
||||
# Session 1 — 2026-05-23 (Specs Reorganization)
|
||||
|
||||
## งานที่ทำ
|
||||
|
||||
- Reorganize โครงสร้างโฟลเดอร์ `specs/` สำเร็จ (`100-Infrastructures`, `200-fullstacks`, `300-others`)
|
||||
- อัปเดตกฎ `AGENTS.md` และ `GEMINI.md` ให้ตรงกับมาตรฐานใหม่
|
||||
- ริเริ่มระบบ `memory/agent-memory.md`
|
||||
|
||||
## ไฟล์ที่แก้ไข
|
||||
|
||||
- `specs/` folder structure reorganization
|
||||
- `AGENTS.md` update
|
||||
- `GEMINI.md` update
|
||||
- `memory/agent-memory.md` initial creation
|
||||
@@ -0,0 +1,26 @@
|
||||
# Session 3 — 2026-05-24 (Migration Queue Attachment UUID Bug Fix)
|
||||
|
||||
## ปัญหาที่พบ (Root Cause)
|
||||
|
||||
ไฟล์ `n8n.workflow.v2.json` (โหนด `Insert Review Queue`) ส่งค่า `tempAttachmentId` โดยใช้ `{{parseInt($json.attachmentId)}}` ซึ่งพยายามแปลง UUID string เป็นตัวเลข ผลลัพธ์คือค่า `NaN` หรือตัวเลขที่ผิดพลาด (เช่น `"0195..."` → `19`) ทำให้คอลัมน์ `temp_attachment_id` ใน `migration_review_queue` เป็น `NULL` เสมอ — ละเมิด ADR-019 Tier 1 Blocker
|
||||
|
||||
## การแก้ไข (Fix)
|
||||
|
||||
| ไฟล์ | การเปลี่ยนแปลง |
|
||||
| ----------------------------------------------------------- | ---------------------------------------------------------------------------------- |
|
||||
| `backend/src/modules/ai/dto/migration-checkpoint.dto.ts` | ปรับ `tempAttachmentId` เป็น `@IsOptional()` รองรับทั้ง UUID string และ Integer PK |
|
||||
| `backend/src/modules/ai/ai-migration-checkpoint.service.ts` | เพิ่ม UUID→INT resolution: `SELECT id FROM attachments WHERE uuid = ? LIMIT 1` |
|
||||
| `specs/03-Data-and-Storage/n8n.workflow.v2.json` | เปลี่ยนส่ง `temp_attachment_public_id` (UUID string) แทน `parseInt(...)` ที่ผิด |
|
||||
|
||||
## Pattern ที่ตกลง (Locked)
|
||||
|
||||
```
|
||||
n8n ส่ง: { tempAttachmentId: "019505a1-7c3e-7000-..." } ← UUID string
|
||||
Backend รับ: ตรวจสอบประเภท → ถ้าเป็น string → query DB → ได้ INT id จริง
|
||||
DB บันทึก: migration_review_queue.temp_attachment_id = <INT> ← ถูกต้อง
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
- `npx tsc --noEmit` — ✅ ผ่าน ไม่มี type error
|
||||
- ตรวจสอบ logic ใน Service แล้ว ไม่มีการเขียนทับ `tempAttachmentId` ด้วย `undefined` (guard check แล้ว)
|
||||
@@ -0,0 +1,46 @@
|
||||
# Session 4 — 2026-05-25 (Migration Error Normalization ตาม AGENTS.md)
|
||||
|
||||
## ปัญหาที่พบ (Root Cause)
|
||||
|
||||
- `Log Error to CSV` และ `Log Error to DB` ใน `n8n.workflow.v2.json` ส่ง `error_type` บางค่าไม่ตรง enum ของ `migration_errors`
|
||||
- ค่าที่พบจริงและต้อง normalize: `AI_JOB_FAILED`, `PARSE_ERROR`, `TOKEN_EXPIRED`
|
||||
- backend `AiMigrationCheckpointService.logError()` เดิม insert ค่า `dto.errorType` ตรง ๆ ทำให้เสี่ยง DB enum reject
|
||||
- ตาราง `migration_errors` เดิมไม่มี `job_id` แม้ workflow/DTO จะมี `jobId` อยู่แล้ว ทำให้ trace กลับไป BullMQ job ไม่ครบ
|
||||
|
||||
## การแก้ไข (Fix)
|
||||
|
||||
| ไฟล์ | การเปลี่ยนแปลย |
|
||||
| -------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
|
||||
| `specs/03-Data-and-Storage/n8n.workflow.v2.json` | normalize `error_type`, `document_number`, `error`, `job_id` ก่อนเขียน CSV/DB |
|
||||
| `backend/src/modules/ai/ai-migration-checkpoint.service.ts` | map/validate `errorType` ซ้ำก่อน insert และเพิ่ม `job_id` ใน SQL insert |
|
||||
| `backend/src/modules/migration/entities/migration-error.entity.ts` | เพิ่ม field `jobId?: string` |
|
||||
| `specs/03-Data-and-Storage/lcbp3-v1.9.0-migration.sql` | เพิ่มคอลัมน์ `job_id VARCHAR(100) NULL` และ index |
|
||||
| `specs/03-Data-and-Storage/deltas/2026-05-22-drop-migration-tables.rollback.sql` | อัปเดต table definition ของ `migration_errors` ให้มี `job_id` |
|
||||
| `specs/03-Data-and-Storage/deltas/2026-05-24-add-migration-errors-job-id.sql` | เพิ่ม delta สำหรับ add `job_id` |
|
||||
| `specs/03-Data-and-Storage/deltas/2026-05-24-add-migration-errors-job-id.rollback.sql` | เพิ่ม rollback สำหรับ drop `job_id` |
|
||||
| `backend/src/modules/ai/ai-migration-checkpoint.service.spec.ts` | เพิ่ม regression tests สำหรับ error normalization + `job_id` |
|
||||
|
||||
## Mapping ที่ Lock แล้ว
|
||||
|
||||
```
|
||||
AI_JOB_FAILED -> API_ERROR
|
||||
PARSE_ERROR -> AI_PARSE_ERROR
|
||||
TOKEN_EXPIRED -> API_ERROR
|
||||
unsupported value -> UNKNOWN
|
||||
```
|
||||
|
||||
## กฎใช้งานต่อไป
|
||||
|
||||
- ให้ถือ enum ของ `migration_errors.error_type` เป็น source of truth เสมอ
|
||||
- workflow ต้อง normalize ก่อนส่งเข้า backend และ backend ต้อง normalize ซ้ำอีกชั้น
|
||||
- ห้ามพึ่ง DB enum reject เป็น validation mechanism
|
||||
- การเพิ่มคอลัมน์ `job_id` ต้องทำผ่าน SQL/delta ตาม ADR-009 เท่านั้น
|
||||
|
||||
## Verification
|
||||
|
||||
- workflow normalization assertion — ✅ ผ่าน
|
||||
- `pnpm --filter backend build` — ✅ ผ่าน
|
||||
- `pnpm --filter backend test -- --runTestsByPath src/modules/ai/ai-migration-checkpoint.service.spec.ts` — ✅ ผ่าน
|
||||
- regression seam ที่เพิ่มยืนยัน:
|
||||
- `AI_JOB_FAILED` map เป็น `API_ERROR`
|
||||
- unsupported error type fallback เป็น `UNKNOWN`
|
||||
@@ -0,0 +1,40 @@
|
||||
# Session 5 — 2026-05-25 (N8N Submit AI Job Debug + Upload Dedup)
|
||||
|
||||
## ปัญหาที่พบ (Root Cause)
|
||||
|
||||
**Bug 1: `Submit AI Job` → 400 Bad Request**
|
||||
|
||||
- n8n HTTP Request node `typeVersion: 4.1` เมื่อ `specifyBody: "json"` และ `jsonBody` เป็น expression ที่ return **object** → n8n ส่ง body เป็น `"[object Object]"` แทน JSON string
|
||||
- แก้ด้วย `JSON.stringify($json.submit_payload)`
|
||||
|
||||
**Bug 2: `Submit AI Job` → 403 Forbidden**
|
||||
|
||||
- `migration_bot` (user_id=5, role_id=1/Superadmin) ไม่มี `ai.suggest` ใน `role_permissions`
|
||||
- Root cause: Seed script `INSERT INTO role_permissions SELECT 1, permission_id FROM permissions WHERE is_active = 1` รันก่อน `ai.*` permissions (id 181-186) ถูก insert เข้า `permissions` table
|
||||
- แก้ด้วย delta SQL grant ai.\* ให้ role_id=1
|
||||
|
||||
**Bug 3: Upload ซ้ำเมื่อ n8n retry**
|
||||
|
||||
- `FileStorageService.upload()` เดิมไม่มี dedup → ทุก retry สร้าง orphan temp attachment ใหม่
|
||||
- แก้ด้วย checksum-based dedup: query หา temp record ที่มี checksum+userId เดิมและยังไม่หมดอายุ → คืน record เดิมแทน
|
||||
|
||||
## การแก้ไข (Fix)
|
||||
|
||||
| ไฟล์ | การเปลี่ยนแปลย |
|
||||
| --------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
|
||||
| `specs/03-Data-and-Storage/n8n.workflow.v2.json` | `jsonBody` เปลี่ยนเป็น `JSON.stringify($json.submit_payload)` |
|
||||
| `specs/03-Data-and-Storage/deltas/2026-05-25-grant-ai-permissions-to-superadmin.sql` | INSERT IGNORE ai.\* permissions สำหรับ role_id=1 (Superadmin) |
|
||||
| `specs/03-Data-and-Storage/deltas/2026-05-25-grant-ai-permissions-to-superadmin.rollback.sql` | Rollback DELETE สำหรับ delta ข้างบน |
|
||||
| `backend/src/common/file-storage/file-storage.service.ts` | เพิ่ม checksum dedup ใน `upload()` ก่อน write file |
|
||||
|
||||
## กฎที่ Lock แล้ว
|
||||
|
||||
- `jsonBody` ใน n8n HTTP Request `typeVersion >= 4.1` ต้องใช้ `JSON.stringify(...)` เมื่อ `specifyBody: "json"` และค่าเป็น object
|
||||
- ทุกครั้งที่เพิ่ม permission ใหม่ใน `permissions` table ต้อง grant ให้ Superadmin (role_id=1) ด้วยทันที — ห้ามปล่อยให้ขาดหาย
|
||||
- `FileStorageService.upload()` เป็น idempotent ผ่าน SHA-256 checksum + userId + expiresAt
|
||||
|
||||
## Verification ที่ยังต้องทำ
|
||||
|
||||
- รัน delta SQL ใน MariaDB (ถ้ายังไม่รัน): `2026-05-25-grant-ai-permissions-to-superadmin.sql`
|
||||
- Import `n8n.workflow.v2.json` ใหม่เข้า n8n UI
|
||||
- `pnpm --filter backend test -- file-storage` — ยืนยัน checksum dedup
|
||||
@@ -0,0 +1,51 @@
|
||||
# Session 7 — 2026-05-25 (PaddleOCR Sidecar Setup)
|
||||
|
||||
## สิ่งที่ทำ
|
||||
|
||||
- แก้ `AggregateError` (empty message) ใน `ocr.service.ts` — wrap เป็น Error พร้อม context ที่ชัดเจน
|
||||
- สร้าง PaddleOCR + PyThaiNLP FastAPI sidecar รันบน Desk-5439 (Windows 10/11, Docker Desktop WSL2)
|
||||
- เพิ่ม path remapping `remapPath()` ใน `OcrService` — แปลง `/app/uploads/...` → `/mnt/uploads/...`
|
||||
|
||||
## ไฟล์ที่สร้าง/แก้ไข
|
||||
|
||||
| ไฟล์ | การเปลี่ยนแปลย |
|
||||
| ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
|
||||
| `specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/ocr-sidecar/Dockerfile` | ✅ สร้างใหม่ — Python 3.10 slim, ลบ pre-download step (segfault) |
|
||||
| `specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/ocr-sidecar/app.py` | ✅ สร้างใหม่ — FastAPI: `/health`, `/ocr` (PaddleOCR), `/normalize` (PyThaiNLP) |
|
||||
| `specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/ocr-sidecar/requirements.txt` | ✅ สร้างใหม่ — `numpy<2.0` ต้องอยู่ก่อน paddlepaddle (ABI fix) |
|
||||
| `specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/ocr-sidecar/docker-compose.yml` | ✅ สร้างใหม่ — CIFS volume mount + named volume สำหรับ model cache |
|
||||
| `specs/04-Infrastructure-OPS/04-00-docker-compose/QNAP/app/docker-compose-app.yml` | เพิ่ม `OCR_API_URL`, `OCR_CHAR_THRESHOLD`, `OCR_SIDECAR_UPLOAD_BASE` |
|
||||
| `specs/04-Infrastructure-OPS/04-00-docker-compose/QNAP/app/.env.example` | เพิ่ม `OCR_API_URL`, `OCR_CHAR_THRESHOLD`, `OCR_SIDECAR_UPLOAD_BASE` |
|
||||
| `backend/src/modules/ai/services/ocr.service.ts` | เพิ่ม `remapPath()`, AggregateError fix |
|
||||
|
||||
## Known Issues / Fixes
|
||||
|
||||
- `numpy<2.0` ต้องอยู่ก่อน `paddlepaddle` — ABI mismatch กับ cv2 (numpy 2.x)
|
||||
- Docker Desktop WSL2 ไม่รองรับ bind mount จาก network drive (Z:\) → ใช้ CIFS volume แทน
|
||||
- Pre-download model ใน Dockerfile ทำให้ segfault (exit 139) → ลบออก download ตอน runtime
|
||||
- `OLLAMA_RAG_MODEL` → เปลี่ยนเป็น `OLLAMA_MODEL_MAIN=gemma4:e2b` ตาม ADR-023A
|
||||
|
||||
## CIFS Volume Config
|
||||
|
||||
```yaml
|
||||
volumes:
|
||||
qnap_uploads:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: cifs
|
||||
o: 'username=${QNAP_USER},password=${QNAP_PASS},vers=3.0,uid=0,gid=0'
|
||||
device: '//192.168.10.8/np-dms-as/data/uploads'
|
||||
```
|
||||
|
||||
## Path Remapping
|
||||
|
||||
```
|
||||
backend: /app/uploads/temp/xxx.pdf → sidecar: /mnt/uploads/temp/xxx.pdf
|
||||
OCR_SIDECAR_UPLOAD_BASE=/mnt/uploads (env var)
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
- `curl http://localhost:8765/health` → `{"status":"ok","engine":"paddleocr"}` ✅
|
||||
- `POST /ocr` ทดสอบกับไฟล์จริงใน `/mnt/uploads/temp/` → ได้ text กลับ ✅
|
||||
- 78 test suites, 672 tests ผ่านทั้งหมด ✅
|
||||
@@ -0,0 +1,226 @@
|
||||
# Session 9 — 2026-05-26 (System Memories Consolidation)
|
||||
|
||||
## QNAP SSH Key Authentication & CI/CD Deployment
|
||||
|
||||
### Infrastructure
|
||||
|
||||
- QNAP `192.168.10.8` — target deploy server (runs Gitea + app containers)
|
||||
- ASUSTOR `192.168.10.9` — Gitea runner
|
||||
|
||||
### SSH Key Setup (Persistent)
|
||||
|
||||
- Private key: `/etc/config/ssh/gitea-runner`
|
||||
- Public key: `/etc/config/ssh/gitea-runner.pub`
|
||||
- Fingerprint: `SHA256:OhPbRe9vi4aWTyzBqCQ6T3MLl+JK9lFtH5bPrx+ICPw`
|
||||
- Authorized keys: `/etc/config/ssh/authorized_keys` (symlinked from `/root/.ssh/`)
|
||||
- QNAP SSH config: `/etc/config/ssh/sshd_config` (persistent — ใช้อันนี้เท่านั้น ไม่ใช่ `/etc/ssh/sshd_config`)
|
||||
|
||||
### Critical Fix: AuthorizedKeysFile
|
||||
|
||||
```
|
||||
AuthorizedKeysFile /etc/config/ssh/authorized_keys
|
||||
```
|
||||
|
||||
ต้องใช้ **absolute path** — ถ้าใช้ `.ssh/authorized_keys` จะ resolve ไปที่ `/share/homes/admin/.ssh/` ซึ่งผิด (admin home = `/share/homes/admin` แต่ symlink อยู่ที่ `/root/.ssh`)
|
||||
|
||||
### Reload QNAP SSH daemon
|
||||
|
||||
```bash
|
||||
kill -HUP $(ps | grep "/usr/sbin/sshd -f /etc/config" | grep -v grep | awk '{print $1}')
|
||||
```
|
||||
|
||||
ไม่มี `pgrep` และไม่มี `systemctl` บน QNAP
|
||||
|
||||
### Gitea Secrets
|
||||
|
||||
| Secret | Value |
|
||||
|--------|-------|
|
||||
| HOST | `192.168.10.8` |
|
||||
| PORT | `22` |
|
||||
| USERNAME | `admin` |
|
||||
| SSH_KEY | private key content from `/etc/config/ssh/gitea-runner` |
|
||||
|
||||
### deploy.sh Fix
|
||||
|
||||
```bash
|
||||
# scripts/deploy.sh line 10 — correct path:
|
||||
COMPOSE_FILE="$SOURCE_DIR/specs/04-Infrastructure-OPS/04-00-docker-compose/QNAP/app/docker-compose-app.yml"
|
||||
```
|
||||
|
||||
ไม่ใช่ `...04-00-docker-compose/docker-compose-app.yml` (ขาด `QNAP/app/`)
|
||||
|
||||
### Root Causes (ทั้งหมด)
|
||||
|
||||
1. `authorized_keys` เสียหาย — 2 keys บรรทัดเดียว
|
||||
2. SSH key pair หายหลัง reboot — QNAP `/` เป็น RAM, ต้องเก็บใน `/etc/config/`
|
||||
3. `AuthorizedKeysFile` ใช้ relative path — resolve ผิด directory
|
||||
4. HOST secret ชี้ไปผิด server (Go SSH) — แก้เป็น `192.168.10.8:22`
|
||||
5. `deploy.sh` COMPOSE_FILE path ผิด — ขาด `QNAP/app/` subdirectory
|
||||
|
||||
## Backend TransformInterceptor Double Registration Bug
|
||||
|
||||
### Issue
|
||||
|
||||
API responses were double-wrapped `{ data: { data: actualData } }` causing frontend detail pages to fail loading data.
|
||||
|
||||
### Root Cause
|
||||
|
||||
TransformInterceptor registered in TWO places:
|
||||
|
||||
1. `backend/src/main.ts`: `app.useGlobalInterceptors(new TransformInterceptor())`
|
||||
2. `backend/src/common/common.module.ts`: `{ provide: APP_INTERCEPTOR, useClass: TransformInterceptor }`
|
||||
|
||||
### Fix
|
||||
|
||||
Removed duplicate registration from `main.ts` (keep only APP_INTERCEPTOR in CommonModule).
|
||||
|
||||
### Why list page still worked
|
||||
|
||||
Paginated responses were re-detected as paginated by second interceptor, preventing double-nesting. Non-paginated (detail) endpoints were affected.
|
||||
|
||||
### Verification
|
||||
|
||||
`curl http://localhost:3001/api/correspondences/{uuid}` now returns single-wrapped `{ data: {...} }` instead of double-wrapped.
|
||||
|
||||
### Pattern to Avoid
|
||||
|
||||
Never register global interceptors/filters in both `main.ts` AND via `APP_INTERCEPTOR`/`APP_FILTER` providers.
|
||||
|
||||
## ADR-021 Integration: Transmittals & Circulation
|
||||
|
||||
### Summary
|
||||
|
||||
Successfully integrated ADR-021 (Integrated Workflow Context & Step-specific Attachments) into Transmittals and Circulation modules. All backend services, frontend pages, and tests are wired to the Unified Workflow Engine.
|
||||
|
||||
### Backend Changes (B1-B9)
|
||||
|
||||
- **WorkflowEngineService**: Added `getInstanceByEntity(entityType, entityId)` for polymorphic workflow instance lookup
|
||||
- **TransmittalService**:
|
||||
- Expose `workflowInstanceId`, `workflowState`, `availableActions` in `findOneByUuid()`
|
||||
- Added purpose filter to `findAll()`
|
||||
- Added `submit()` with EC-RFA-004 validation (prevents submission if any item correspondence is DRAFT)
|
||||
- Starts workflow instance `TRANSMITTAL_FLOW_V1` and updates CorrespondenceRevision status
|
||||
- **TransmittalController**: Added `POST /:uuid/submit` endpoint with RBAC and Audit
|
||||
- **TransmittalModule**: Imported `WorkflowEngineModule` and `CorrespondenceRevision`
|
||||
- **CirculationService**:
|
||||
- Expose workflow fields in `findOneByUuid()`
|
||||
- Added `reassignRouting()` (EC-CIRC-001) for PENDING routing reassignment
|
||||
- Added `forceClose()` (EC-CIRC-002) with transactional rollback and reason validation
|
||||
- **CirculationController**: Added `PATCH /:uuid/routing/:routingId/reassign` and `POST /:uuid/force-close`
|
||||
- **Circulation Entity**: Added `deadlineDate` column for EC-CIRC-003 Overdue badge
|
||||
- **Schema Delta**: `05-add-circulation-deadline.sql` per ADR-009 (no migrations)
|
||||
|
||||
### Frontend Changes (F1-F7)
|
||||
|
||||
- **Types**: Extended `Transmittal` and `Circulation` interfaces with workflow fields; added `deadlineDate` to Circulation
|
||||
- **Hooks**: Created `useTransmittal()` and extended `useCirculation()` hooks with TanStack Query
|
||||
- **Detail Pages**:
|
||||
- Both wired with `IntegratedBanner` and `WorkflowLifecycle` using live workflow data
|
||||
- Circulation page includes EC-CIRC-003 Overdue badge logic (`isOverdue()`)
|
||||
- **List Page**: Added purpose filter dropdown to `transmittals/page.tsx`
|
||||
|
||||
### Tests (T1-T2): 19/19 Passing
|
||||
|
||||
- **TransmittalService**: 7 tests covering EC-RFA-004 validation, workflow instance creation, and error cases
|
||||
- **CirculationService**: 12 tests covering EC-CIRC-001 (reassign), EC-CIRC-002 (forceClose), EC-CIRC-003 (deadlineDate exposure)
|
||||
|
||||
### Key Technical Decisions
|
||||
|
||||
- Followed ADR-019 UUID handling (no parseInt, use string UUIDs)
|
||||
- Used ADR-009 direct schema edits (no TypeORM migrations)
|
||||
- Enforced RBAC with CASL guards and Audit decorators
|
||||
- Implemented transactional force-close with proper rollback
|
||||
- Maintained existing patterns for error handling and service architecture
|
||||
|
||||
### Remaining Work
|
||||
|
||||
- I1: i18n keys for new workflow actions (low priority)
|
||||
|
||||
## Correspondence Detail Display Fixes
|
||||
|
||||
### Issue
|
||||
|
||||
`/correspondences/[uuid]` detail display inconsistency
|
||||
|
||||
### Fix
|
||||
|
||||
Made backend `findOneByUuid` query deterministic with explicit relation joins and revision ordering (rev.revisionNumber DESC, rev.createdAt DESC), and normalized recipient_type values in frontend detail page before TO/CC filtering to handle whitespace variants per schema (e.g., 'CC ').
|
||||
|
||||
### Files Modified
|
||||
|
||||
- `backend/src/modules/correspondence/correspondence.service.ts`
|
||||
- `frontend/components/correspondences/detail.tsx`
|
||||
|
||||
## Correspondence Create Permission Bypass
|
||||
|
||||
### Issue
|
||||
|
||||
Users without primaryOrganizationId could not create documents even with system.manage_all permission
|
||||
|
||||
### Fix
|
||||
|
||||
In backend CorrespondenceService.create flow, users without primaryOrganizationId can still create when they have system.manage_all and provide originatorId. Validation now resolves originator organization under that permission instead of immediately throwing 'User must belong to an organization to create documents'. Added regression test in correspondence.service.spec.ts.
|
||||
|
||||
### Extension
|
||||
|
||||
Applied same pattern to RFA, Transmittal, and Circulation create endpoints — they now accept optional originatorId and allow creation for users with system.manage_all even when primaryOrganizationId is null. Added permission-gated impersonation checks in their services to prevent unauthorized cross-organization creation.
|
||||
|
||||
## Playwright E2E Testing Setup
|
||||
|
||||
### Test Stack
|
||||
|
||||
- **Backend**: Jest (Unit + Integration + E2E)
|
||||
- **Frontend**: Vitest (Unit) + Playwright (E2E)
|
||||
|
||||
### MCP Server Setup (Devin)
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"playwright": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@playwright/mcp@latest"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Devin Cascade Tools
|
||||
|
||||
- `browser_navigate` - เปิด URL
|
||||
- `browser_click` - คลิก element
|
||||
- `browser_type` - พิมพ์ข้อความ
|
||||
- `browser_take_screenshot` - ถ่าย screenshot
|
||||
- `browser_evaluate` - รัน JavaScript
|
||||
|
||||
### Run E2E Tests
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
npx playwright test # Run all
|
||||
npx playwright test --ui # Debug mode
|
||||
npx playwright test --headed # See browser
|
||||
npx playwright show-report # Generate report
|
||||
```
|
||||
|
||||
### E2E Script Location
|
||||
|
||||
`frontend/e2e/workflow-adr021.spec.ts`
|
||||
|
||||
## Tag Creation and Contract UUID Fixes
|
||||
|
||||
### Issue 1
|
||||
|
||||
`/admin/doc-control/reference/tags` needed a list-level Project dropdown filter and Tag creation could fail due to TypeORM Tag entity column-name mismatches.
|
||||
|
||||
### Fix
|
||||
|
||||
Added selectedProjectId filter in frontend tags page and mapped backend Tag entity fields to schema names (project_id, tag_name, color_code, created_by, created_at, updated_at, deleted_at).
|
||||
|
||||
### Issue 2
|
||||
|
||||
Frontend contract detail page typecheck failure — `contract.project?.id` vs `contract.project?.publicId`
|
||||
|
||||
### Fix
|
||||
|
||||
In `frontend/app/(admin)/admin/doc-control/contracts/page.tsx`, handleEdit must read nested project UUID from contract.project?.id (not project?.publicId) because Contract.project is typed and returned as { id: string; projectCode; projectName }.
|
||||
@@ -0,0 +1,34 @@
|
||||
# Session 9 — 2026-05-27 (Context-Aware Prompt Templates & Database Typo CC Cleanup)
|
||||
|
||||
## Summary
|
||||
|
||||
ดำเนินการอิมพลีเมนต์ ADR-030 (Context-Aware Prompt Templates สำหรับการสกัดข้อมูลเอกสาร) และทำการแก้ไขบัคช่องว่างประเภทผู้รับ `'CC '` ในฐานข้อมูล
|
||||
|
||||
## Backend Changes (B1-B6)
|
||||
|
||||
- **AiPrompt Entity**: เพิ่มการแมปคอลัมน์ `contextConfig` ไปยัง JSON ฟิลด์ `context_config` ในฐานข้อมูลเพื่อควบคุม master data resolution
|
||||
- **CreateAiPromptDto / Response DTO**: ปรับแต่งให้รองรับการรับและส่งออกคอลัมน์ `contextConfig`
|
||||
- **AiPromptsService**:
|
||||
- อิมพลีเมนต์เมธอด `resolveContext()` สำหรับการดึงข้อมูล Master Data ดำเนินการคัดกรองข้อมูลอ้างอิงโครงการ (Projects, Organizations, Disciplines, CorrespondenceTypes, Tags) สอดคล้องกับ dynamic config filter
|
||||
- ติดตั้ง **Gatekeeper Rule** (ตัวกรองความปลอดภัย) โยน `ForbiddenException` ทันทีเมื่อมีการร้องขอ override project UUID ข้ามอาณาเขตโครงการที่กำหนดใน template เพื่อป้องกัน Cross-project data leak
|
||||
- **AiBatchProcessor**:
|
||||
- ปรับปรุงโครงสร้าง `MigrateDocumentMetadata` interface, sandbox extraction, และ migration process ให้ดึงข้อมูลและแมป master data context-aware
|
||||
- สกัดและจำแนกผู้รับเอกสาร (recipients) ภายใต้โครงสร้าง JSON แบบใหม่ในรูป Object Array: `recipients: Array<{ organizationPublicId: string, recipientType: 'TO' | 'CC' }>` เพื่อความเสถียรและทนทานของข้อมูล
|
||||
- **Unit Tests**:
|
||||
- เพิ่มชุดการทดสอบ `resolveContext` ใน `ai-prompts.service.spec.ts` ครอบคลุมการจำลอง master data resolution, การโยน `NotFoundException` และการล็อคสิทธิ์ความปลอดภัยด้วย `ForbiddenException` เมื่อ override โครงการข้าม boundary
|
||||
- แก้ไข mock dependencies ของ `AiPromptsService` ใน `ai-batch.processor.spec.ts` ป้องกันปัญหา `TypeError: getActive is not a function` ทำให้ผ่าน unit tests 100%
|
||||
|
||||
## Database & Schema Changes (ADR-009)
|
||||
|
||||
- **schema-02-tables.sql**: แก้ไข line 338 ปรับปรุง `ENUM('TO', 'CC ')` เป็น `ENUM('TO', 'CC')`
|
||||
- **SQL Delta**: สร้าง `2026-05-27-add-context-aware-prompts-and-cleanup.sql` ดำเนินการ `UPDATE` ข้อมูลเก่าที่เป็น `'CC '` ให้เป็น `'CC'` เพื่อล้างช่องว่าง จากนั้นสั่ง `ALTER TABLE` ปรับปรุงฟิลด์ enum และ Seed template ภาษาไทยเวอร์ชัน 2
|
||||
- **Rollback SQL**: สร้างไฟล์ย้อนกลับ `2026-05-27-add-context-aware-prompts-and-cleanup.rollback.sql` เรียบร้อย
|
||||
|
||||
## Frontend Changes
|
||||
|
||||
- **detail.tsx**: ตรวจสอบการใช้งาน `normalizeRecipientType` ซึ่งครอบคลุมการล้างช่องว่างและการกรองผู้รับ TO/CC ได้อย่างทนทาน
|
||||
|
||||
## Verification
|
||||
|
||||
- `pnpm --filter backend build` — ✅ Compile ผ่านแบบ Strict Mode
|
||||
- unit tests AI module & backend suites — ✅ ผ่านทั้งหมด 60 suites / 521 tests
|
||||
@@ -0,0 +1,41 @@
|
||||
# Session 8 — 2026-05-30 (OCR Engine Migration — PaddleOCR → Tesseract)
|
||||
|
||||
## ปัญหาที่พบ (Root Cause)
|
||||
|
||||
**Bug 1: PaddleOCR SIGILL (Illegal Instruction)**
|
||||
|
||||
- PaddleOCR 2.6.2 ต้องการ AVX instruction set ซึ่ง CPU บน Desk-5439 ไม่รองรับ
|
||||
- ลองลดรุ่นเป็น 2.5.2 → ยังมี dependency conflict กับ paddleocr 2.7.3
|
||||
- ลองใช้ paddlepaddle-cpu → ยังคงมีปัญหา dependency
|
||||
|
||||
**Bug 2: OCR ภาษาไทยผิด**
|
||||
|
||||
- PaddleOCR ตั้งค่า `lang="en"` ทำให้ข้อความภาษาไทยถูกแปลงเป็นอักษรละตินผิดๆ
|
||||
- เช่น: "10 กุมภาพันธ์ 2568" → "10 qunnwus 2568"
|
||||
|
||||
## การแก้ไข (Fix)
|
||||
|
||||
เปลี่ยนจาก PaddleOCR เป็น Tesseract OCR เพื่อ:
|
||||
|
||||
1. แก้ปัญหา SIGILL บน CPU เก่าที่ไม่รองรับ AVX
|
||||
2. รองรับภาษาไทยด้วย `tha+eng` language code
|
||||
|
||||
| ไฟล์ | การเปลี่ยนแปลย |
|
||||
| ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
|
||||
| `specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/ocr-sidecar/requirements.txt` | ลบ paddlepaddle/paddleocr, เพิ่ม pytesseract, Pillow |
|
||||
| `specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/ocr-sidecar/app.py` | เปลี่ยนใช้ pytesseract, OCR_LANG เป็น `tha+eng`, ลบ PaddleOCR initialization |
|
||||
| `specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/ocr-sidecar/Dockerfile` | ติดตั้ง tesseract-ocr, tesseract-ocr-tha, tesseract-ocr-eng |
|
||||
| `specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/ocr-sidecar/docker-compose.yml` | OCR_LANG เป็น `tha+eng`, ลบ paddleocr_models volume |
|
||||
| `backend/src/modules/ai/services/ocr.service.ts` | เปลี่ยน comment/error message จาก PaddleOCR เป็น Tesseract |
|
||||
| `frontend/components/admin/ai/OcrSandboxPromptManager.tsx` | เปลี่ยน Badge text จาก PaddleOCR เป็น Tesseract |
|
||||
|
||||
## กฎที่ Lock แล้ว
|
||||
|
||||
- Tesseract OCR ไม่ต้องการ AVX instruction set → ทำงานได้บน CPU ทุกรุ่น
|
||||
- Tesseract รองรับภาษาไทยด้วย `tha+eng` language code
|
||||
- API contract ยังเหมือนเดิม (`POST /ocr` คืน `{ text, ocrUsed }`) → backend/frontend ไม่ต้องเปลี่ยน logic
|
||||
|
||||
## Verification ที่ต้องทำ
|
||||
|
||||
- Rebuild container บน Desk-5439: `docker compose down && docker compose up -d --build`
|
||||
- ทดสอบ OCR ภาษาไทย: "10 กุมภาพันธ์ 2568" ควรออกมาถูกต้อง
|
||||
@@ -0,0 +1,67 @@
|
||||
# Session 10 — 2026-05-30 (OCR Sandbox Two-Step Flow)
|
||||
|
||||
## Summary
|
||||
|
||||
แยก OCR Sandbox เป็น 2 steps ตาม spec 231: Step 1 OCR-only → Step 2 AI Extraction เพื่อให้ admin ตรวจคุณภาพ OCR ก่อนทดสอบ AI prompt
|
||||
|
||||
## Backend Changes (B1-B5)
|
||||
|
||||
- **AiBatchJobType**: เพิ่ม `sandbox-ocr-only` และ `sandbox-ai-extract` job types
|
||||
- **AiBatchProcessor**:
|
||||
- เพิ่ม `processSandboxOcrOnly()` — รัน OCR เท่านั้น, cache OCR text ใน Redis key `ai:sandbox:ocr:{idempotencyKey}` (TTL 3600s)
|
||||
- เพิ่ม `processSandboxAiExtract()` — ดึง OCR text จาก cache, resolve prompt version (active หรือ version ที่ระบุ), replace {{ocr_text}} และ {{master_data_context}}, run LLM
|
||||
- **AiPromptsService**: เพิ่ม `findByVersion(promptType, versionNumber)` method สำหรับดึง prompt version ที่ระบุ
|
||||
- **AiController**:
|
||||
- เพิ่ม `POST /ai/admin/sandbox/ocr` — Step 1 endpoint (รับ file multipart/form-data)
|
||||
- เพิ่ม `POST /ai/admin/sandbox/ai-extract` — Step 2 endpoint (รับ requestPublicId + optional promptVersion)
|
||||
- **AiQueueService**: อัปเดต `enqueueSandboxJob()` รองรับ job types ใหม่และ extraPayload สำหรับส่ง promptVersion
|
||||
|
||||
## Frontend Changes (F1-F3)
|
||||
|
||||
- **adminAiService**: เพิ่ม `submitSandboxOcr(file)` และ `submitSandboxAiExtract(requestPublicId, promptVersion)` methods
|
||||
- **OcrSandboxPromptManager.tsx**:
|
||||
- เพิ่ม states: `sandboxStep` ('ocr'|'ai'), `ocrResult` (requestPublicId, ocrText, ocrUsed), `selectedPromptVersion`
|
||||
- เพิ่ม handlers: `handleStep1Ocr()` (poll OCR result), `handleStep2AiExtract()` (poll AI result), `handleResetSandbox()`
|
||||
- Refactor UI: Step 1 (upload + Run OCR button) → Step 2 (prompt version dropdown + Run AI Extraction button + Reset button)
|
||||
- แสดง OCR Raw Text card หลัง Step 1 เสร็จ (สีน้ำเงิน, badge บอก PaddleOCR/Fast Path)
|
||||
- แสดง AI Extraction result หลัง Step 2 เสร็จ (สีเขียว, badge บอก promptVersionUsed)
|
||||
|
||||
## Schema Fix (ADR-009 + ADR-019)
|
||||
|
||||
- **Delta SQL**: สร้าง `2026-05-30-add-ai-prompts-publicId.sql` เพิ่ม `publicId CHAR(36) UNIQUE` column ใน `ai_prompts` table
|
||||
- **Root Cause**: Entity มี `publicId` field แต่ DB table ไม่มี column นี้ → QueryFailedError: "Unknown column 'AiPrompt.publicId' in 'SELECT'"
|
||||
- **Fix**: ใช้ CHAR(36) แทน UUID type (MariaDB compatible), generate UUID สำหรับ existing records ด้วย `UUID()` function
|
||||
|
||||
## Verification
|
||||
|
||||
- Backend TypeScript: ✅ ผ่าน (`npx tsc --noEmit`)
|
||||
- Frontend TypeScript: ✅ ผ่าน (`npx tsc --noEmit`)
|
||||
- ESLint: ✅ ผ่าน (แก้ unused `user` parameter ใน `submitSandboxAiExtract`)
|
||||
|
||||
## Data Flow
|
||||
|
||||
```
|
||||
Step 1: Upload PDF → POST /ai/admin/sandbox/ocr
|
||||
↓
|
||||
BullMQ: sandbox-ocr-only job
|
||||
↓
|
||||
OCR Service → Cache OCR text (ai:sandbox:ocr:{id})
|
||||
↓
|
||||
Frontend displays OCR Raw Text
|
||||
|
||||
Step 2: Select prompt version → POST /ai/admin/sandbox/ai-extract
|
||||
↓
|
||||
BullMQ: sandbox-ai-extract job
|
||||
↓
|
||||
Retrieve OCR text from cache (ai:sandbox:ocr:{id})
|
||||
↓
|
||||
Replace {{ocr_text}} → LLM → JSON result
|
||||
↓
|
||||
Frontend displays AI Extraction result
|
||||
```
|
||||
|
||||
## Pending
|
||||
|
||||
- Run delta SQL `2026-05-30-add-ai-prompts-publicId.sql` ใน production database
|
||||
- Restart backend service หลัง apply delta
|
||||
- Test 2-step flow จริงใน production environment
|
||||
@@ -0,0 +1,30 @@
|
||||
# Session 11 — 2026-05-30 (Typhoon OCR & LLM Integration)
|
||||
|
||||
## Summary
|
||||
|
||||
ออกแบบและพัฒนาการใช้งานโมเดลภาษาไทยผสมอังกฤษ Typhoon OCR-3B ร่วมกับ Tesseract OCR แบบ Dynamic พร้อมระบบ caching 24 ชม., VRAM Monitor ป้องกัน GPU OOM และระบบ fallback 5s เมื่อโมเดลมีปัญหา และการสลับและบริหารจัดการ LLM โมเดลหลักแบบ Dynamic ในระบบ AI Model Management ของ Next.js frontend ตามข้อกำหนด ADR-032
|
||||
|
||||
## Backend Changes (B1-B5)
|
||||
|
||||
- **OcrService**:
|
||||
- เพิ่ม dynamic OCR engine selection (`getOcrEngines()`, `selectOcrEngine()`, `getActiveEngineId()`) จัดเก็บสถานะหลักใน DB `system_settings` (`OCR_ACTIVE_ENGINE`) พร้อม cache ใน Redis 30s ป้องกันคิวรีซ้ำซ้อน
|
||||
- ปรับปรุง `detectAndExtract()` ให้เลือกใช้ engine ที่เหมาะสม หากผู้ใช้เลือก Typhoon OCR-3B จะทำงานผ่าน `processWithTyphoon()` ร่วมกับ `OcrCacheService` (24-hour Redis caching) และ `VramMonitorService` (ตรวจสอบ VRAM capacity > 4GB ก่อนโหลดโมเดล)
|
||||
- พัฒนาระบบ **Graceful Fallback** ไปยัง Tesseract OCR ในเวลา 5 วินาทีหาก Typhoon ขัดข้องหรือ VRAM ไม่เพียงพอ โดยมีการบันทึกรายละเอียดและ error ลง `ai_audit_logs`
|
||||
- **AiService**:
|
||||
- เพิ่ม endpoints สำหรับ AI Model Management: `GET /models`, `POST /models` (Superadmin), `PATCH /models/:modelId/activate` และ `GET /vram/status` (Used/Free VRAM และ Active models บน GPU) ร่วมกับ `AiSettingsService` และ `VramMonitorService`
|
||||
- ตรวจสอบความปลอดภัย VRAM ก่อนอนุญาตให้สลับโมเดลหลัก หากเหลือพื้นที่หน่วยความจำ GPU ไม่พอ จะโยน `BusinessException` แจ้งเตือนภาษาไทยพร้อมบันทึกลง Audit Log และระงับการเปลี่ยนโมเดลทันที
|
||||
- แก้ไขข้อผิดพลาด build error ใน `ai.service.ts` โดยการนำเข้า `OllamaService` และ `AiQdrantService` ที่ขาดหายไปใน constructor
|
||||
|
||||
## Frontend Changes (F1-F3)
|
||||
|
||||
- **admin-ai.service.ts**: เพิ่ม interface `LoadedModelInfo` และ `VramStatusResponse` และเพิ่ม methods `getVramStatus()`, `getAvailableModels()`, `setActiveModel()`, และ `addModel()` โดยใช้ dynamic path ที่อ้างอิง UUIDv7 (`modelId`) และส่ง idempotency headers ตาม ADR-019/ADR-016
|
||||
- **admin/ai/page.tsx**: อัปเดตหน้า AI Admin page โดยเพิ่ม **VRAM GPU Monitor Card** แบบ realtime (ดึงและสลับรีเฟรชผ่าน React Query ทุก 15s) แสดง Free/Used VRAM และ active models บน GPU และปรับปรุง UI ส่วน AI Model Management ให้สลับโมเดลหลักผ่าน UUIDv7 และแสดง VRAM requirements ของแต่ละโมเดลอย่างสวยงามพรีเมียม
|
||||
|
||||
## ADRs Update (ADR-023/023A)
|
||||
|
||||
- อัปเดต `ADR-023-unified-ai-architecture.md` (v1.2) และ `ADR-023A-unified-ai-architecture.md` (v1.3) เพื่อรับรองสถาปัตยกรรม dynamic Thai specialized models (Typhoon OCR & LLM) ภายใต้การควบคุมของ VRAM Monitor
|
||||
|
||||
## Verification
|
||||
|
||||
- Backend NestJS Build: ✅ Compile สำเร็จ 100% ปราศจาก Error (`npm run build` ใน backend)
|
||||
- Frontend Next.js Build: ✅ Compile สำเร็จ 100% ปราศจาก Error (`npm run build` ใน frontend)
|
||||
@@ -0,0 +1,51 @@
|
||||
# Session 15 — 2026-06-05 (Feature 234 RAG Pipeline Enhancements — สมบูรณ์)
|
||||
|
||||
## Summary
|
||||
|
||||
Implement RAG Pipeline Enhancements ตาม Spec 234 / ADR-035 ครบทุก Functional Requirement (FR-001 → FR-015), ผ่าน speckit-analyze → speckit-implement → speckit-tester → speckit-validate; ปิด Gap ทั้ง 2 รายการ
|
||||
|
||||
## งานที่ทำในเซสชั่นนี้
|
||||
|
||||
| งาน | ไฟล์หลัก | สถานะ |
|
||||
|-----|----------|-------|
|
||||
| Sidecar `/embed` (BGE-M3 Dense+Sparse) | `ocr-sidecar/app.py`, `requirements.txt` | ✅ |
|
||||
| Sidecar `/rerank` (BGE-Reranker-Large) | `ocr-sidecar/app.py` | ✅ |
|
||||
| `OcrService.embedViaSidecar()` + `rerankViaSidecar()` | `ocr.service.ts` | ✅ |
|
||||
| Hybrid Qdrant schema (1024 dims, drop+recreate) | `qdrant.service.ts` | ✅ |
|
||||
| Payload indexes (project_public_id tenant, doc_public_id, status_code, doc_type) | `qdrant.service.ts` | ✅ |
|
||||
| `EmbeddingService.embedDocument()` — Semantic Chunking + fallback | `embedding.service.ts` | ✅ |
|
||||
| `semanticChunkTextWithFallback()` → `parseChunkTags()` → `fixedSizeChunk()` | `embedding.service.ts` | ✅ |
|
||||
| `AiBatchProcessor` case `rag-prepare` → `processRagPrepare()` | `ai-batch.processor.ts` | ✅ |
|
||||
| `AiQueueService.enqueueRagPrepare()` + jobId dedup | `ai-queue.service.ts` | ✅ |
|
||||
| `CorrespondenceWorkflowService.syncStatus()` → `triggerRagPrepare()` | `correspondence-workflow.service.ts` | ✅ |
|
||||
| `AiRagService.processQuery()` — Hybrid Search + Reranker | `ai-rag.service.ts` | ✅ |
|
||||
| SQL delta `rag_chunking` prompt | `deltas/2026-06-05-add-rag-chunking-prompt.sql` | ✅ |
|
||||
| Integration test (9 tests) | `ai-rag-pipeline.integration.spec.ts` | ✅ |
|
||||
| Validation report | `specs/200-fullstacks/234-rag-pipeline-enhancements/validation-report.md` | ✅ |
|
||||
|
||||
## Verification
|
||||
|
||||
- `npx jest` (6 suites): **24/24 tests PASS**
|
||||
- `npx tsc --noEmit`: **0 errors**
|
||||
- speckit-validate: **15/15 FR covered, 6/6 SC verifiable, 0 Gaps remaining**
|
||||
|
||||
## Architecture Summary (ADR-035)
|
||||
|
||||
```
|
||||
CorrespondenceWorkflowService.syncStatus()
|
||||
└── triggerRagPrepare() [fire-and-forget]
|
||||
└── AiQueueService.enqueueRagPrepare() [jobId dedup]
|
||||
└── BullMQ ai-batch queue
|
||||
└── AiBatchProcessor.processRagPrepare()
|
||||
├── OcrService.detectAndExtract() [if no cached text]
|
||||
└── EmbeddingService.embedDocument()
|
||||
├── semanticChunkTextWithFallback() → typhoon2.5 / fixed-size fallback
|
||||
├── OcrService.embedViaSidecar() → BGE-M3 [dense 1024 + sparse]
|
||||
└── AiQdrantService.upsert() → lcbp3_vectors [delete-before-upsert]
|
||||
|
||||
AiRagService.processQuery()
|
||||
├── OcrService.embedViaSidecar(question) → BGE-M3
|
||||
├── AiQdrantService.searchByProject(dense, sparse, projectPublicId, 15) → RRF Fusion
|
||||
├── OcrService.rerankViaSidecar(question, chunks) → BGE-Reranker top-5
|
||||
└── Ollama typhoon2.5-np-dms:latest → answer + citations
|
||||
```
|
||||
@@ -0,0 +1,44 @@
|
||||
# Session 14 — 2026-06-05 (RAG Pipeline Enhancements / Spec 234 / ADR-035)
|
||||
|
||||
## Summary
|
||||
|
||||
ปรับโค้ดให้สอดคล้องกับ feature `234-rag-pipeline-enhancements` และ `ADR-035-ai-pipeline-flow-architecture` โดยปิด compile blockers ของ RAG pipeline ใหม่, บังคับ tenant scope ผ่าน `projectPublicId` ใน vector deletion path, ย้าย dashboard ไปใช้ `/ai/rag/*`, และ retire runtime surface ของ legacy `/rag/*`
|
||||
|
||||
## Backend Changes (B1-B6)
|
||||
|
||||
- **Compile blockers fixed (4 จุด):**
|
||||
- ปรับ `ai-batch.processor.ts` ให้ legacy `embed-document` path ส่งข้อมูลตาม signature ใหม่ของ `EmbeddingService.embedDocument(...)`
|
||||
- เพิ่ม `projectPublicId` ใน `AiVectorDeletionJobPayload` และ propagate ผ่าน `AiQueueService` + `vector-deletion.processor.ts`
|
||||
- ปรับ typing ใน `src/modules/ai/qdrant.service.ts` ให้รองรับ hybrid upsert contract ของ Qdrant client
|
||||
- แก้ nullability ใน `correspondence-workflow.service.ts` สำหรับ trigger `enqueueRagPrepare()`
|
||||
- **Legacy delete path hardening:** `backend/src/modules/rag/rag.service.ts` เปลี่ยน `deleteVectors()` ให้ resolve `projectPublicId` จาก `DocumentChunk`/server-side context ก่อน ไม่เชื่อ query param จาก client เป็นหลัก
|
||||
- **Legacy runtime deprecation:** mark `backend/src/modules/rag/rag.controller.ts` และ endpoint summaries เป็น deprecated ชั่วคราวระหว่าง audit
|
||||
- **Legacy runtime removal:** หลัง consumer audit ใน repo ไม่พบ caller ของ `/rag/status`, `/rag/ingest`, `/rag/vectors`, `/rag/admin/init-collection`, จึงถอด `RagModule` ออกจาก `backend/src/app.module.ts` และลบ `backend/src/modules/rag/rag.controller.ts` + `rag.module.ts`
|
||||
|
||||
## Frontend Changes (F1-F2)
|
||||
|
||||
- **Dashboard RAG migration:** `frontend/app/(dashboard)/rag/page.tsx` เปลี่ยนมาใช้ `RagChatWidget` ซึ่งวิ่งผ่าน `POST /ai/rag/query` และ `GET /ai/rag/jobs/:requestPublicId`
|
||||
- **Legacy frontend cleanup:** ลบ `frontend/hooks/use-rag.ts` และ `frontend/components/rag/*` ที่ไม่ถูกใช้งานแล้ว
|
||||
|
||||
## Architecture / Documentation Updates
|
||||
|
||||
- **ADR-035:** เพิ่มและอัปเดต Legacy Compatibility Note ให้สะท้อนสถานะจริงของ migration ไป `/ai/rag/*`
|
||||
- **Current runtime state:** `/rag/*` ไม่ถูก mount ใน `AppModule` แล้ว; flow หลักของระบบใช้ `AiModule` + `/ai/rag/*`
|
||||
|
||||
## Verification
|
||||
|
||||
- `pnpm --filter backend build` — ✅ ผ่าน
|
||||
- `pnpm --filter backend lint:ci` — ✅ ผ่าน
|
||||
- `pnpm --filter backend test -- --runTestsByPath src/modules/ai/processors/ai-batch.processor.spec.ts src/modules/ai/services/embedding.service.spec.ts` — ✅ ผ่าน
|
||||
- `pnpm --filter backend test -- --runTestsByPath src/modules/rag/__tests__/rag.service.spec.ts` — ✅ ผ่าน
|
||||
- `pnpm --filter lcbp3-frontend lint` — ✅ ผ่าน
|
||||
- `pnpm exec tsc --noEmit -p frontend/tsconfig.json` — ✅ ผ่าน
|
||||
|
||||
## Follow-up Completed (Session 14+)
|
||||
|
||||
- ✅ แก้ `backend/src/modules/ai/qdrant.service.ts` — `ensureCollection()` ตรวจ schema ก่อน delete: ถ้าเป็น Hybrid 1024 dims แล้ว skip recreation
|
||||
- ✅ ย้าย `rag-prepare` enqueue ใน `CorrespondenceWorkflowService.syncStatus()` ไปหลัง commit — after-commit pattern ด้วย `triggerRagPrepare()`
|
||||
- ✅ ลบ `backend/src/modules/rag/` ทั้งหมด (audit ไม่พบ import จาก backend/src)
|
||||
- ✅ สร้าง `backend/src/modules/ai/ai-qdrant.service.spec.ts` — regression test สำหรับ `deleteByDocumentPublicId()` (4/4 ผ่าน)
|
||||
- ✅ Code Review Fixes (Session 14+): try-catch after-commit, `createPayloadIndexes()` private, defensive vector size check, `skipRagPrepare` flag
|
||||
- ✅ F5 (Session 15): เพิ่ม `ai-rag-pipeline.integration.spec.ts` — 9 integration tests ครอบคลุม SC-002, SC-003, SC-006, FR-005, jobId dedup
|
||||
Reference in New Issue
Block a user