690603:2041 ADR-034-134 #01
CI / CD Pipeline / build (push) Failing after 4m28s
CI / CD Pipeline / deploy (push) Has been skipped

This commit is contained in:
2026-06-03 20:41:42 +07:00
parent 754d609399
commit 3274dede7a
197 changed files with 1575 additions and 42 deletions
+168
View File
@@ -0,0 +1,168 @@
---
trigger: always_on
---
# NAP-DMS Project Context & Rules
- For: Windsurf Cascade (and compatible: Codex CLI, opencode, Amp, Antigravity, AGENTS.md tools)
- Version: 1.9.6 | Last synced from repo: 2026-05-22
- Repo: [https://git.np-dms.work/np-dms/lcbp3](https://git.np-dms.work/np-dms/lcbp3)
- Skill pack: `.agents/skills/` (v1.9.0, 21 skills) — see [`skills/README.md`](./.agents/skills/README.md) + [`skills/_LCBP3-CONTEXT.md`](./.agents/skills/_LCBP3-CONTEXT.md)
## 🧠 Role & Persona
Act as **Senior Full Stack Developer** specialized in NestJS, Next.js, TypeScript, DMS. Focus: Data Integrity, Security, Maintainability, Performance.
You are a **Document Intelligence Engine** — not a general chatbot. Every response must be **precise**, **spec-compliant**, and **production-ready**.
---
## 🧩 Thought & Planning Protocol (Powered by Everything-Claude-Code)
Before writing any code or taking any action in Tier 1 and Tier 2, the AI must demonstrate the following thinking process:
### 1. Analysis Phase (Explore & Analyze)
Problem Understanding: Restate what the user wants in clear, unambiguous terms.
Context Search: Identify the relevant Spec files or ADRs from the "Key Spec Files" table that must be read before starting.
Constraints Identification: Identify key constraints (e.g. Security rules, UUID patterns, or Domain terminology).
### 2. Planning Phase (Plan)
Alternative Exploration: Present at least 2 solution approaches (where possible) with pros/cons analysis.
Step-by-Step Roadmap: Write a file-by-file plan of changes before executing.
Verification Plan: Specify how to verify the work is complete (e.g. "which unit tests to write" or "which file to check the schema in").
### 3. Execution & Refinement (Execute & Refine)
Follow the plan step by step, and pause to ask if any uncertainty arises.
If significant logic changes are made, summarize what was done for the user after completion.
---
## ⚙️ DMS Workflow Engine Protocol
กฎนี้ใช้คุม Logic การไหลของเอกสาร (RFA, Transmittal, Correspondence) เพื่อป้องกัน Race Condition และรักษาความถูกต้องของสถานะ:
- **State Management:** ตรวจสอบสถานะปัจจุบันจาก DB ก่อนเสมอ เพื่อป้องกันการอนุมัติซ้ำซ้อน (ดู `05-06-code-snippets.md` `[workflow-transition]`)
- **Concurrency Control:** การจอนเลขที่เอกสารต้องใช้ **Redis Redlock** หรือ **TypeORM `@VersionColumn`** เท่านั้น (ADR-002)
- **Background Jobs:** งานนานหรือการแจ้งเตือนต้องส่งไปทำที่ **BullMQ** ห้ามเขียนแบบ Inline (ADR-008)
- **Term Consistency:** ห้ามใช้ "Approval Flow" ให้ใช้ **"Workflow Engine"** และห้ามใช้ "Letter" ให้ใช้ **"Correspondence"** (หมายเหตุ: "จดหมาย" ในคอมเมนต์ภาษาไทย = Correspondence ที่ครอบคลุมทุกประเภท)
---
## 🛡️ Security & Integrity Audit Protocol
กฎนี้ให้ AI เป็น Gatekeeper ก่อน Commit โดยเน้น **Tier 1 — CRITICAL**:
- **UUID Validation:** ตรวจสอบว่าเป็น **UUIDv7** และห้ามใช้ `parseInt()` บน UUID (ADR-019)
- **RBAC Check:** API ใหม่ต้องมี **CASL Guard** และตรวจสอบ 4-Level RBAC Matrix (ADR-016)
- **Data Isolation:** AI ต้องรันผ่าน **Ollama บน Admin Desktop** เท่านั้น ห้ามเข้าถึง DB/storage โดยตรง (ADR-023)
- **Input Sanitization:** ไฟล์อัปโหลดต้องผ่าน **Two-Phase** (Temp → Commit) และสแกนด้วย **ClamAV** (ADR-016)
---
## 🧭 Rule Enforcement Tiers
### 🔴 Tier 1 — CRITICAL (CI BLOCKER)
Build fails หากละเมิด:
- Security (Auth, RBAC, Validation)
- UUID Strategy (ADR-019) — no `parseInt` / `Number` / `+` on UUID
- Database correctness — verify schema before writing queries
- File upload security (ClamAV + whitelist)
- AI validation boundary (ADR-023)
- Error handling strategy (ADR-007)
- Forbidden patterns: `any`, `console.log`, UUID misuse, `id ?? ''` fallback
### 🟡 Tier 2 — IMPORTANT (CODE REVIEW)
Must fix ก่อน merge:
- Architecture patterns (thin controller, business logic in service)
- Test coverage (80%+ business logic, 70%+ backend overall)
- Cache invalidation
- Naming conventions
- **TypeScript Standards:** Missing JSDoc, explicit types, or file headers
### 🟢 Tier 3 — SPECIALIZED WORK
Requires domain-specific knowledge:
- **ADR-021 Integration:** Workflow Engine & Context implementation
- **AI Infrastructure:** ADR-023/023A boundary enforcement and pipeline usage
- **AI Runtime Layer:** ADR-024 Intent Classification, ADR-025 Tool Layer, ADR-026 Chat UI, ADR-027 Admin Console
- **Migration Pipeline:** ADR-028 Staging Queue & post-migration cleanup
- **Complex Business Logic:** Multi-step workflows with state management
- **Performance Optimization:** Database queries, caching strategies, bulk operations
### 🔵 Tier 4 — GUIDELINES
Best practice — follow when possible:
- Code style / formatting (Prettier handles)
- Comment completeness
- Minor optimizations
---
## 📐 TypeScript Rules & Coding Standards
### 📝 Core Standards
- **Strict Mode** — all strict checks enforced.
- **ZERO `any` types** — use proper types or `unknown` + narrowing.
- **ZERO `console.log`** — use NestJS `Logger` (backend) or remove (frontend).
- **English for Code** — use English for all code identifiers, variables, and logic.
- **Thai for Comments** — use Thai for comments, documentation, and JSDoc.
- **Explicit Typing** — explicitly define types for all variables, parameters, and return values.
- **JSDoc** — use JSDoc for all public classes and methods.
### 🏗️ File & Function Structure
- **File Headers** — every file MUST start with `// File: path/filename` on the first line.
- **Change Log** — include `// Change Log` at the top of the file to track modifications.
- **Single Export** — export **only one main symbol** per file.
- **Function Style** — avoid unnecessary blank lines inside functions.
---
## 🚫 Forbidden Actions
| ❌ Forbidden | ✅ Correct Approach | ⚠️ Why |
| ----------------------------------------------- | ------------------------------------------------------- | ---------------------------------------------------- |
| SQL Triggers for business logic | NestJS Service methods | Untestable; bypasses audit log |
| `.env` files in production | `docker-compose.yml` environment section | Secrets exposed in version control |
| TypeORM migration files | Edit schema SQL directly (ADR-009) | Migration drift risk; schema managed via SQL delta |
| Inventing table/column names | Verify against `schema-02-tables.sql` | Schema mismatch causes silent runtime errors |
| `any` TypeScript type | Proper types / generics | Defeats strict mode; hides runtime type errors |
| `console.log` in committed code | NestJS Logger (backend) / remove (frontend) | Log flooding in production; risk of data leakage |
| `req: any` in controllers | `RequestWithUser` typed interface | Type safety lost; auth context unreachable |
| `parseInt()` on UUID values | Use UUID string directly (ADR-019) | `"0195…"` parsed to integer `19` — silently wrong |
| Exposing INT PK in API responses | UUIDv7 `publicId` (ADR-019) | Leaks row count; enables DB enumeration attacks |
| AI accessing DB/storage directly | AI → DMS API → DB (ADR-023/023A) | Bypasses RBAC, audit trail, and validation layer |
| Direct file operations bypassing StorageService | `StorageService` for all file moves | Orphaned files; broken ClamAV scan; no audit trail |
| Inline email/notification sending | BullMQ queue job (ADR-008) | Blocks request thread; no retry on transient failure |
| Deploying without Release Gates | Complete `04-08-release-management-policy.md` | Unverified deploy risks data loss in production |
| AI direct cloud API calls | On-premises Ollama only (ADR-023/023A) | Data privacy violation; no audit control |
| AI outputs without human validation | Human-in-the-loop validation required (ADR-023/023A) | Unvalidated AI metadata corrupts document records |
| n8n calling Ollama/Qdrant directly | n8n → DMS API → BullMQ → Ollama (ADR-023A) | Bypasses audit log, RBAC, and error handling layer |
| Qdrant query without `projectPublicId` filter | `QdrantService.search(projectPublicId, ...)` (ADR-023A) | Cross-project data leak via vector search |
---
## 🚧 Out of Scope — Never Do Without Explicit Approval
| ❌ Never Do Autonomously | ⚠️ Why Approval Is Required |
| --------------------------------------------------------------- | ---------------------------------------------------------------- |
| `DROP` or `RENAME` a column / table | Irreversible data loss — requires DBA + PM sign-off |
| Push directly to `main` / `master` branch | Bypasses CI, code review, and release gates |
| Generate or insert seed data into production database | May corrupt live data or violate business state invariants |
| Delete files from permanent storage | Files may be referenced in active documents or audit trails |
| Modify RBAC permission matrix without security team approval | Defines access control for all users — security boundary change |
| Upgrade major library versions (NestJS, Next.js, TypeORM, etc.) | Breaking changes require full regression test cycle |
| Disable or modify authentication / authorization guards | Creates unguarded endpoints — immediate security risk |
| Change Redis lock TTL or disable Redlock | Risk of document number race condition (ADR-002) |
| Create or supersede an ADR unilaterally | Architecture decisions require team consensus and review process |
| Add new columns to production tables without schema review | Must update Data Dictionary + downstream queries simultaneously |
+71
View File
@@ -0,0 +1,71 @@
---
trigger: always_on
---
# ADR-019 UUID Strategy
## CRITICAL RULES
- **NEVER** use `parseInt()` on UUID values
- **NEVER** use `Number()` on UUID values
- **NEVER** use `+` operator on UUID values
- **ALWAYS** use `publicId` (string UUID) for API responses
- **NEVER** expose internal INT `id` in API responses (use `@Exclude()`)
## Identifier Types
| Context | Type | Notes |
| ---------------- | ------------------------- | ------------------------------------------- |
| Internal / DB FK | `INT AUTO_INCREMENT` | Never exposed in API |
| Public API / URL | `UUIDv7` (MariaDB native) | Stored as BINARY(16), no transformer needed |
| Entity Property | `publicId: string` | Exposed directly in API (no transformation) |
| API Response | `publicId: string` (UUID) | INT `id` has `@Exclude()` — never appears |
## Backend Pattern (NestJS/TypeORM)
```typescript
// Entity
@Entity()
class Project extends UuidBaseEntity {
@Column({ type: 'uuid' })
publicId: string; // UUID string, no transformation needed
@PrimaryKey()
@Exclude()
id: number; // Internal INT, never exposed
}
// API Response → { id: "019505a1-7c3e-7000-8000-abc123def456" }
// Uses publicId directly, no @Expose({ name: 'id' }) needed
```
## Frontend Pattern (Next.js)
```typescript
// ✅ CORRECT — Use publicId only
type ProjectOption = {
publicId?: string; // No uuid, no id fallback
projectName?: string;
};
// ❌ WRONG — Multiple identifiers cause confusion
type ProjectOption = {
publicId?: string;
uuid?: string; // Don't do this
id?: number; // Don't do this
};
// ❌ NEVER use parseInt on UUID
parseInt(projectId); // "0195..." → 19 (WRONG!)
// ❌ NEVER use id ?? '' fallback
const value = c.publicId ?? c.id ?? ''; // Wrong!
// ✅ CORRECT — Use publicId only
const value = c.publicId; // "019505a1-7c3e-7000-8000-abc123def456"
```
## Related Documents
- `specs/06-Decision-Records/ADR-019-hybrid-identifier-strategy.md`
- `specs/05-Engineering-Guidelines/05-07-hybrid-uuid-implementation-plan.md`
+38
View File
@@ -0,0 +1,38 @@
---
trigger: always_on
---
# Security Rules (Non-Negotiable)
## Mandatory Security Requirements
1. **Idempotency:** All critical `POST`/`PUT`/`PATCH` MUST validate `Idempotency-Key` header
2. **Two-Phase File Upload:** Upload → Temp → Commit → Permanent
3. **Race Conditions:** Redis Redlock + TypeORM `@VersionColumn` for Document Numbering
4. **Validation:** Zod (frontend) + class-validator (backend DTO)
5. **Password:** bcrypt 12 salt rounds, min 8 chars, rotate every 90 days
6. **Rate Limiting:** `ThrottlerGuard` on all auth endpoints
7. **File Upload:** Whitelist PDF/DWG/DOCX/XLSX/ZIP, max 50MB, ClamAV scan
8. **AI Isolation (ADR-023/023A):** Ollama on Admin Desktop ONLY — NO direct DB/storage access; 2-model stack `gemma4:e4b Q8_0` + `nomic-embed-text`; all inference via BullMQ (`ai-realtime` / `ai-batch`)
9. **Error Handling (ADR-007):** Use layered error classification with user-friendly messages
10. **AI Integration (ADR-023/023A):** RFA-First approach; n8n orchestrates Migration Phase only via DMS API — never calls Ollama directly; `QdrantService.search()` requires `projectPublicId` as mandatory param
11. **AI Audit Trail:** Log all AI interactions and human validations
12. **Rate Limiting:** Apply to AI endpoints to prevent abuse
## Full Documentation
`specs/06-Decision-Records/ADR-016-security-authentication.md`
## Security Checklist (Before Every Commit)
- [ ] Input validation implemented (Zod/class-validator)
- [ ] RBAC/CASL permissions checked
- [ ] No SQL injection vulnerabilities
- [ ] File upload validation (whitelist + ClamAV)
- [ ] Rate limiting applied to auth endpoints
- [ ] AI boundary enforcement (ADR-023/023A) - no direct DB/storage access
- [ ] AI audit logging implemented for AI interactions
- [ ] AI outputs validated before use (human-in-the-loop)
- [ ] Error handling follows ADR-007 layered classification
- [ ] Cache invalidation when data modified
- [ ] OWASP Top 10 review passed
+48
View File
@@ -0,0 +1,48 @@
---
trigger: always_on
---
# TypeScript Rules
## Core Standards
- **Strict Mode** — all strict checks enforced.
- **ZERO `any` types** — use proper types or `unknown` + narrowing.
- **ZERO `console.log`** — use NestJS `Logger` (backend) or remove before commit (frontend).
- **English for Code** — use English for all code identifiers, variables, and logic.
- **Thai for Comments** — use Thai for comments, documentation, and JSDoc.
- **Explicit Typing** — explicitly define types for all variables, parameters, and return values.
- **JSDoc** — use JSDoc for all public classes and methods (in **Thai**).
## File & Function Structure
- **File Headers** — every file MUST start with `// File: path/filename` on the first line.
- Use **absolute path** from project root (e.g., `// File: backend/src/modules/correspondence/correspondence.service.ts`)
- Do NOT use relative path (e.g., `// File: src/example.service.ts`)
- **Change Log** — include `// Change Log` at the top of the file.
- **Single Export** — export **only one main symbol** per file.
- **Function Style** — avoid unnecessary blank lines inside functions.
## i18n Guidelines
- **No Hardcoded Text:** Use i18n keys for all user-facing text
- **Reference:** `specs/05-Engineering-Guidelines/05-08-i18n-guidelines.md`
- **Pattern:** Use `t('key.path')` from i18n hook instead of hardcoded strings
## Patterns
```typescript
// ✅ CORRECT
// File: src/example.service.ts
// Change Log:
// - 2026-05-13: Initial creation
/**
* บริการตัวอย่างสำหรับ LCBP3
*/
export class ExampleService {
public doSomething(data: string): boolean {
return data.length > 0;
}
}
```
+45
View File
@@ -0,0 +1,45 @@
---
trigger: always_on
---
# Domain Terminology
## DMS Glossary
| ✅ Use | ❌ Don't Use | คำอธิบายเพิ่มเติม |
| ------------------ | ------------------------------------- | ------------------------------------------------ |
| Correspondence | Letter, Communication, Document | ครอบคลุมทุกประเภท: Letter, RFA, Memo, ฯลฯ |
| RFA | Approval Request, Submit for Approval | เอกสารขออนุมัติ (ชนิดหนึ่งของ Correspondence) |
| Transmittal | Delivery Note, Cover Letter | เอกสารนำส่ง (ชนิดหนึ่งของ Correspondence) |
| Circulation | Distribution, Routing | ใบเวียนเอกสารภายใน (ชนิดหนึ่งของ Correspondence) |
| Shop Drawing | Construction Drawing | แบบก่อสร้าง |
| Contract Drawing | Design Drawing, Blueprint | แบบคู่สัญญา |
| Workflow Engine | Approval Flow, Process Engine | เครื่องมือจัดการลำดับงาน |
| Document Numbering | Document ID, Auto Number | ระบบจัดการเลขที่เอกสาร |
| RBAC | Permission System (generic) | การควบคุมสิทธิ์ตามบทบาท |
## Full Glossary
`specs/00-overview/00-02-glossary.md`
## Key Spec Files Priority
Spec priority: **`06-Decision-Records`** > **`05-Engineering-Guidelines`** > others
| Document | Path | Use When |
| ------------------------------ | --------------------------------------------------------------------------- | --------------------------------- |
| **Glossary** | `specs/00-overview/00-02-glossary.md` | Verify domain terminology |
| **Schema Tables** | `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql` | Before writing any query |
| **Data Dictionary** | `specs/03-Data-and-Storage/03-01-data-dictionary.md` | Field meanings + business rules |
| **Edge Cases** | `specs/01-Requirements/01-06-edge-cases-and-rules.md` | Prevent bugs in flows |
| **ADR-019 UUID** | `specs/06-Decision-Records/ADR-019-hybrid-identifier-strategy.md` | UUID-related work |
| **ADR-023 AI** | `specs/06-Decision-Records/ADR-023-unified-ai-architecture.md` | AI integration work |
| **ADR-023A AI Model** | `specs/06-Decision-Records/ADR-023A-unified-ai-architecture.md` | 2-model stack, BullMQ 2-queue |
| **ADR-024 Intent Class.** | `specs/06-Decision-Records/ADR-024-intent-classification-strategy.md` | Pattern→LLM Fallback; Redis cache |
| **ADR-025 AI Tool Layer** | `specs/06-Decision-Records/ADR-025-ai-tool-layer-architecture.md` | Tool Registry; CASL-guarded |
| **ADR-026 Chat UI** | `specs/06-Decision-Records/ADR-026-document-chat-ui-pattern.md` | Side-panel; streaming SSE |
| **ADR-027 AI Admin Console** | `specs/06-Decision-Records/ADR-027-ai-admin-console-and-dynamic-control.md` | Dynamic control; admin-only |
| **ADR-028 Migration Refactor** | `specs/06-Decision-Records/ADR-028-migration-architecture-refactor.md` | Staging Queue; cleanup |
| **Backend Guidelines** | `specs/05-Engineering-Guidelines/05-02-backend-guidelines.md` | NestJS patterns |
| **Frontend Guidelines** | `specs/05-Engineering-Guidelines/05-03-frontend-guidelines.md` | Next.js patterns |
| **Testing Strategy** | `specs/05-Engineering-Guidelines/05-04-testing-strategy.md` | Coverage goals |
+43
View File
@@ -0,0 +1,43 @@
---
trigger: always_on
---
# Forbidden Actions
## ❌ Never Do This
| ❌ Forbidden | ✅ Correct Approach | ⚠️ Why |
| ----------------------------------------------- | ------------------------------------------------------- | ---------------------------------------------------- |
| SQL Triggers for business logic | NestJS Service methods | Untestable; bypasses audit log |
| `.env` files in production | `docker-compose.yml` environment section | Secrets exposed in version control |
| TypeORM migration files | Edit schema SQL directly (ADR-009) | Migration drift risk; schema managed via SQL delta |
| Inventing table/column names | Verify against `schema-02-tables.sql` | Schema mismatch causes silent runtime errors |
| `any` TypeScript type | Proper types / generics | Defeats strict mode; hides runtime type errors |
| `console.log` in committed code | NestJS Logger (backend) / remove (frontend) | Log flooding in production; risk of data leakage |
| `req: any` in controllers | `RequestWithUser` typed interface | Type safety lost; auth context unreachable |
| `parseInt()` on UUID values | Use UUID string directly (ADR-019) | `"0195…"` parsed to integer `19` — silently wrong |
| Exposing INT PK in API responses | UUIDv7 `publicId` (ADR-019) | Leaks row count; enables DB enumeration attacks |
| AI accessing DB/storage directly | AI → DMS API → DB (ADR-023/023A) | Bypasses RBAC, audit trail, and validation layer |
| Direct file operations bypassing StorageService | `StorageService` for all file moves | Orphaned files; broken ClamAV scan; no audit trail |
| Inline email/notification sending | BullMQ queue job (ADR-008) | Blocks request thread; no retry on transient failure |
| Deploying without Release Gates | Complete `04-08-release-management-policy.md` | Unverified deploy risks data loss in production |
| AI direct cloud API calls | On-premises Ollama only (ADR-023/023A) | Data privacy violation; no audit control |
| AI outputs without human validation | Human-in-the-loop validation required (ADR-023/023A) | Unvalidated AI metadata corrupts document records |
| n8n calling Ollama/Qdrant directly | n8n → DMS API → BullMQ → Ollama (ADR-023A) | Bypasses audit log, RBAC, and error handling layer |
| Qdrant query without `projectPublicId` filter | `QdrantService.search(projectPublicId, ...)` (ADR-023A) | Cross-project data leak via vector search |
## Schema Changes (ADR-009)
- **NO TypeORM migrations** — edit SQL schema directly
- Always check `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql` before writing queries
- Update Data Dictionary when changing fields
## UUID Handling
See `01-adr-019-uuid.md` for complete UUID rules.
Quick reminder:
-`parseInt(uuid)` → NEVER
-`Number(uuid)` → NEVER
- ✅ Use UUID string directly
+63
View File
@@ -0,0 +1,63 @@
---
trigger: glob
globs:
- 'backend/**/*.service.ts'
- 'backend/**/*.controller.ts'
- 'backend/**/*.dto.ts'
- 'backend/**/*.entity.ts'
---
# Backend Patterns (NestJS)
## Architecture
- **Thin Controller** — business logic in Service layer
- **DTO Validation** — class-validator + class-transformer
- **RBAC** — CASL for authorization
- **Error Handling** — Logger + HttpException
## UUID Resolution Pattern
```typescript
// Controller - accept UUID in DTO
@Post()
async create(@Body() dto: CreateCorrespondenceDto) {
// Resolve UUID to internal ID
const contract = await this.contractService.findOneByUuid(dto.contractUuid);
const contractId = contract.id; // Internal INT for DB queries
return this.service.create(dto, contractId);
}
// Service - use internal ID for DB operations
async create(dto: CreateCorrespondenceDto, contractId: number) {
// Use contractId (INT) for database queries
const correspondence = this.repo.create({
contractId, // FK is INT
// ... other fields
});
return this.repo.save(correspondence);
}
```
## API Response Pattern
```typescript
// Entity
@Entity()
class Contract extends UuidBaseEntity {
@Column({ type: 'uuid' })
publicId: string;
@PrimaryGeneratedColumn()
@Exclude()
id: number;
}
// Response automatically includes publicId as 'id'
// { id: "019505a1-7c3e-7000-8000-abc123def456", ... }
```
## Full Guidelines
`specs/05-Engineering-Guidelines/05-02-backend-guidelines.md`
+54
View File
@@ -0,0 +1,54 @@
---
trigger: glob
globs:
- "frontend/**/*.tsx"
- "frontend/**/*.ts"
- "frontend/**/*.css"
---
# Frontend Patterns (Next.js)
## Form Handling
- **RHF** (React Hook Form) for form management
- **Zod** for validation schema
- **TanStack Query** for server state
## UUID Handling
```typescript
// ✅ CORRECT - Use publicId only
interface ProjectOption {
publicId?: string;
projectName?: string;
}
// Select options
const options = contracts.map(c => ({
label: `${c.contractName} (${c.contractCode})`,
value: c.publicId!, // Use publicId, no fallback to id
}));
// ❌ WRONG - Never use these patterns
const value = c.publicId ?? c.id ?? ''; // Wrong!
const id = parseInt(projectId); // Wrong - parseInt on UUID!
```
## API Client Pattern
```typescript
// Use publicId directly in API calls
const contract = await contractService.getById(publicId);
// Form submission with UUID
const onSubmit = async (data: FormData) => {
await correspondenceService.create({
contractUuid: selectedContract.publicId!, // UUID string
// ... other fields
});
};
```
## Full Guidelines
`specs/05-Engineering-Guidelines/05-03-frontend-guidelines.md`
+118
View File
@@ -0,0 +1,118 @@
---
trigger: always_on
---
# Development Flow
## 🔴 Critical Work — DB / API / Security / Workflow Engine
**MUST complete all steps:**
1. **Glossary check** — verify domain terms in `00-02-glossary.md`
2. **Read the spec** — select from Key Spec Files table
3. **Check schema** — verify table/column in `lcbp3-v1.9.0-schema-02-tables.sql`
4. **Check data dictionary** — confirm field meanings + business rules
5. **Scan edge cases**`01-06-edge-cases-and-rules.md`
6. **Check ADRs** — verify decisions align (ADR-009, ADR-019, ADR-023)
7. **Write code** — TypeScript strict, no `any`, no `console.log`
## 🟡 Normal Work — UI / Feature / Integration
- Follow existing patterns in codebase.
- Check spec for relevant module only.
- **Hybrid Specs Organization:**
- Place new Infrastructure tasks in `specs/100-Infrastructures/`
- Place new Feature/Workflow tasks in `specs/200-fullstacks/`
- Place Documentation/Research in `specs/300-others/`
- Ensure no forbidden patterns (`any`, `console.log`, UUID misuse) are introduced.
## 🟢 Quick Fix — Bug Fix / Typo / Style
- Fix directly
- Add minimal test if logic changed
- Check forbidden patterns before commit
### 🟢 Specialized Work — ADR-021, AI Runtime Layer, Complex Logic
**MUST complete:**
1. **Domain Knowledge Check** - Read relevant ADRs (ADR-021, ADR-023/023A, ADR-024~028)
2. **Pattern Verification** - Check existing implementations in codebase
3. **Specialized Requirements** - Follow domain-specific patterns
4. **Complex Logic Testing** - Multi-scenario test coverage
5. **Performance Validation** - Load testing if applicable
**For ADR-021 Integration:**
- Read ADR-021 - Integrated workflow & step attachments
- Check ADR-001 - Unified workflow engine patterns
- Verify WorkflowEngineService - Polymorphic instance handling
- Add workflow fields - Expose workflowInstanceId, workflowState, availableActions
- Include IntegratedBanner - Frontend workflow lifecycle display
- Test workflow transitions - State changes and action validation
**For AI Infrastructure (ADR-023/023A):**
- Verify AI boundary enforcement - No direct DB/storage access
- Check BullMQ 2-queue setup - ai-realtime + ai-batch
- Validate Qdrant multi-tenancy - projectPublicId filter required
- Test human-in-the-loop validation workflows
- Audit AI interaction logging to ai_audit_logs
**For AI Runtime Layer (ADR-024/025/026/027):**
- ADR-024: Pattern Layer first (ai_intent_patterns DB + Redis cache 5 min) → LLM Fallback (gemma4:e4b, semaphore max=3)
- ADR-025: Tool Registry dispatch — AI Gateway → Tool → Business Service; ToolResult DTO must use publicId only
- ADR-026: useAiChat() hook + side-panel UI; streaming response via SSE; TanStack Query cache
- ADR-027: Admin Console — dynamic model/prompt/intent control; CASL-guarded admin-only endpoints
**For Migration Pipeline (ADR-028):**
- Use Staging Queue pattern — never write directly to production tables
- Post-migration cleanup process required after each batch
- Migration Validation Gates must pass before promoting to production
**Expected output:**
- Backend services expose specialized context fields
- Frontend components use domain-specific patterns
- Complex state management with proper validation
- Performance metrics within acceptable thresholds
- Comprehensive test coverage for edge cases
---
## Context-Aware Triggers
| Request | Files to Check | Expected Response |
| --------------------------- | ------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| "สร้าง API ใหม่" | `05-02-backend-guidelines.md`, `lcbp3-v1.9.0-schema-02-tables.sql` | NestJS Controller + Service + DTO + CASL Guard |
| "แก้ฟอร์ม frontend" | `05-03-frontend-guidelines.md`, `01-06-edge-cases-and-rules.md` | RHF+Zod + TanStack Query + Thai comments |
| "เพิ่ม field ใหม่" | `ADR-009`, `03-01-data-dictionary.md`, `lcbp3-v1.9.0-schema-02-tables.sql` | Edit SQL directly + update Data Dictionary + Entity |
| "ตรวจสอบ UUID" | `ADR-019`, `05-07-hybrid-uuid-implementation-plan.md` | UUIDv7 MariaDB native UUID + TransformInterceptor |
| "สร้าง migration" | `ADR-009`, `03-06-migration-business-scope.md` | Edit SQL schema directly + n8n workflow |
| "ตรวจสอบ permission" | `lcbp3-v1.9.0-seed-permissions.sql`, `ADR-016` | CASL 4-Level RBAC matrix |
| "deploy production" | `04-08-release-management-policy.md`, `ADR-015` | Release Gates + Blue-Green strategy |
| "เพิ่ม test" | `05-04-testing-strategy.md` | Coverage goals + test patterns |
| "AI integration" | `ADR-023`, `ADR-023A`, `ADR-024`, `ADR-025` | AI boundary + 2-model stack + BullMQ queue policy + Intent/Tool Layer |
| "Error handling" | `ADR-007` | Layered error classification + recovery |
| "File upload" | `ADR-016`, `05-02-backend-guidelines.md`, `03-Data-and-Storage/03-03-file-storage.md` | Two-phase upload → temp → commit; ClamAV + whitelist |
| "Notifications / Queue" | `ADR-008`, `05-02-backend-guidelines.md` | BullMQ job — never inline; check retry + dead-letter |
| "Add i18n / translate" | `05-08-i18n-guidelines.md` | i18n keys only — no hardcoded text |
| "Workflow / DSL" | `ADR-001`, `01-03-modules/01-03-06-unified-workflow.md` | DSL state machine + WorkflowEngineService |
| "Document numbering" | `ADR-002`, `01-02-business-rules/01-02-02-doc-numbering-rules.md` | Redis Redlock + DB optimistic lock (double-lock) |
| "ตรวจสอบ Workflow" | `01-06-edge-cases-and-rules.md`, `05-02-backend-guidelines.md`, `ADR-001`, `ADR-002` | เช็คการเปลี่ยน State, คิว BullMQ และการล็อกเลขที่เอกสาร |
| "Transmittal submit" | `ADR-021`, `specs/200-fullstacks/201-transmittals-circulation/` | submit() with EC-RFA-004 validation |
| "Circulation reassign" | `ADR-021`, `specs/200-fullstacks/201-transmittals-circulation/` | reassignRouting() with EC-CIRC-001 |
| "สร้าง workflow ใหม่" | `ADR-001`, `ADR-021`, `specs/200-fullstacks/203-unified-workflow-engine/` | DSL workflow definition + WorkflowEngineService setup |
| "ตรวจสอบ AI boundary" | `ADR-023`, `ADR-023A` | Verify Ollama isolation + BullMQ queues + Qdrant projectPublicId filter |
| "Intent classification" | `ADR-024`, `specs/200-fullstacks/224-intent-classification/` | Pattern Layer → LLM Fallback; ai_intent_patterns; Redis cache 5 min |
| "AI Tool Layer" | `ADR-025`, `specs/200-fullstacks/225-ai-tool-layer-architecture/` | Tool Registry; CASL-guarded dispatch; ToolResult publicId only |
| "Document Chat UI" | `ADR-026`, `specs/200-fullstacks/226-document-chat-ui-pattern/` | Side-panel; useAiChat() hook; streaming SSE; TanStack Query cache |
| "AI Admin Console" | `ADR-027`, `specs/200-fullstacks/227-ai-admin-console/` | Dynamic model/prompt/intent control; admin-only CASL endpoints |
| "Migration refactor" | `ADR-028`, `specs/200-fullstacks/228-migration-arch-refactor/` | Staging Queue; post-migration cleanup; validation gates |
| "จัดการ document numbering" | `ADR-002`, `specs/03-Data-and-Storage/03-04-document-numbering.md` | Redis Redlock + template system + preview/override workflows |
| "Audit ความปลอดภัย" | `ADR-016`, `ADR-019`, `ADR-023`, `ADR-023A` | ตรวจสอบ UUID pattern, CASL Guard, AI Boundary และ Qdrant multi-tenancy |
| "แก้ bug / bugfix" | `.agents/workflows/bugfix.md`, `error-catalog.md` | ใช้ bugfix workflow สำหรับเคสที่สาเหตุชัดเจน |
| "ตรวจแอปจริง" | `.windsurf/workflows/check-real-app.md` | ตรวจ endpoint/UI/console หลัง build pass — No Fake Evidence |
| "งานค้าง / resume" | `.windsurf/workflows/resume-pending-work.md` | อ่าน checkpoint เดิม → ตรวจ build → วางแผนต่อโดยไม่ทำงานซ้ำ |
+36
View File
@@ -0,0 +1,36 @@
---
trigger: always_on
---
# Commit Checklist
## Pre-Commit Verification
- [ ] UUID pattern verified (no parseInt on UUID)
- [ ] No `any` types in TypeScript
- [ ] No `console.log` in committed code
- [ ] Comments in Thai
- [ ] Code identifiers in English
- [ ] Schema changes via SQL directly (not migration)
- [ ] Test coverage meets targets (Backend 70%+, Business Logic 80%+)
- [ ] Relevant ADRs checked (ADR-009, ADR-018, ADR-019)
- [ ] Glossary terms used correctly
- [ ] Error handling complete (Logger + HttpException)
- [ ] i18n keys used instead of hardcode text
- [ ] Cache invalidation when data modified
- [ ] Security checklist passed (OWASP Top 10)
## Commit Message Format
```
type(scope): description
[optional body]
```
Types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`
Examples:
- `feat(correspondence): add originator organization validation`
- `fix(uuid): correct parseInt usage to string comparison`
- `spec(agents): bump to v1.8.5 - refactor structure`
+78
View File
@@ -0,0 +1,78 @@
---
trigger: always_on
---
# ADR-007 Error Handling Strategy
## CRITICAL RULES
- **ALWAYS** use layered error classification (Validation, Business, System)
- **NEVER** expose technical details to end users
- **ALWAYS** provide user-friendly error messages with recovery guidance
- **ALWAYS** log technical details for debugging
- **NEVER** use generic error messages without context
## Error Classification
| Error Type | Description | User Message | Technical Log |
|------------|-------------|--------------|---------------|
| **Validation** | Input validation failures | Clear field-level errors | Full validation details |
| **Business** | Business rule violations | Actionable guidance | Business context + user ID |
| **System** | Infrastructure failures | Generic "try again" | Full stack trace + metrics |
## Backend Pattern (NestJS)
```typescript
// Custom Exception Hierarchy
export class BusinessException extends HttpException {
constructor(
message: string,
userMessage: string,
recoveryAction?: string,
errorCode?: string
) {
super({ message, userMessage, recoveryAction, errorCode }, 400);
}
}
// Global Exception Filter
@Catch()
export class GlobalExceptionFilter implements ExceptionFilter {
catch(exception: unknown, host: ArgumentsHost) {
// Classify error and provide appropriate response
// Log technical details
// Return user-friendly message
}
}
```
## Frontend Pattern (Next.js)
```typescript
// Error Display Component
const ErrorDisplay = ({ error, onRetry }) => {
const userMessage = error.userMessage || 'เกิดข้อผิดพลาด';
const recoveryAction = error.recoveryAction;
return (
<div>
<p>{userMessage}</p>
{recoveryAction && <p>{recoveryAction}</p>}
{onRetry && <button onClick={onRetry}></button>}
</div>
);
};
```
## Required Implementation
- [ ] Global Exception Filter with layered classification
- [ ] Custom exception hierarchy (Validation, Business, System)
- [ ] Standardized error response DTOs
- [ ] Frontend error display components
- [ ] Error recovery mechanisms where applicable
## Related Documents
- `specs/06-Decision-Records/ADR-007-error-handling-strategy.md`
- `specs/06-Decision-Records/ADR-010-logging-monitoring-strategy.md`
+149
View File
@@ -0,0 +1,149 @@
---
trigger: always_on
---
# ADR-023/023A AI Integration Architecture
## CRITICAL RULES
- **ALWAYS** follow ADR-023 AI boundary policy (isolation on Admin Desktop)
- **ALWAYS** use ADR-023A 2-model stack (gemma4:e2b + nomic-embed-text)
- **ALWAYS** use BullMQ 2-queue (ai-realtime + ai-batch) for GPU overload prevention
- **NEVER** allow AI direct database/storage access
- **ALWAYS** implement human-in-the-loop validation
- **NEVER** send sensitive data to cloud AI services
- **ALWAYS** enforce Qdrant projectPublicId filter (compile-time enforcement)
- **NEVER** allow n8n to call Ollama/Qdrant directly (must go through DMS API → BullMQ)
## AI Integration Patterns
### Architecture Overview
```
Frontend → AI Gateway API → BullMQ → Admin Desktop (Ollama) → Backend Validation
n8n (Migration) → DMS API → BullMQ → Admin Desktop (Ollama) → Backend Validation
```
### Key Components
| Component | Location | Purpose |
| ----------------- | ------------------------- | ------------------------------------------------------------------------ |
| **AI Gateway** | Backend (NestJS) | API endpoints, validation, audit logging |
| **BullMQ Queues** | Backend (NestJS) | ai-realtime (RAG/Suggest), ai-batch (OCR/Extract/Embed) |
| **Ollama Engine** | Admin Desktop (Desk-5439) | gemma4:e2b (LLM) + nomic-embed-text (Embedding) |
| **OCR Engine** | Admin Desktop (Desk-5439) | PaddleOCR + PyThaiNLP (Thai/English text extraction) |
| **Orchestrator** | QNAP NAS (n8n) | Migration Phase orchestrator only (calls DMS API, never Ollama directly) |
## Backend Implementation (NestJS)
```typescript
// AI Module with boundary enforcement
@Module({
controllers: [AiController],
providers: [AiService, AiGateway, QdrantService],
exports: [AiService],
})
export class AiModule {
constructor() {
// Enforce ADR-023 boundaries
}
}
// QdrantService with compile-time projectPublicId enforcement
@Injectable()
export class QdrantService {
async search(
projectPublicId: string, // required — compile-time enforcement
vector: number[],
topK: number = 5,
): Promise<QdrantSearchResult[]> {
return this.client.search('documents', {
vector,
limit: topK,
filter: {
must: [{ key: 'project_public_id', match: { value: projectPublicId } }],
},
});
}
async upsert(
projectPublicId: string, // required
chunks: DocumentChunk[],
): Promise<void> { ... }
// ❌ NEVER expose rawSearch() or method without projectPublicId filter
}
// AI Service with validation
@Injectable()
export class AiService {
async extractMetadata(documentId: string): Promise<AIMetadata> {
// 1. Validate permissions
// 2. Queue job to BullMQ (ai-batch or ai-realtime)
// 3. Worker sends to Admin Desktop AI (gemma4:e2b)
// 4. Validate AI response
// 5. Log audit trail to ai_audit_logs
// 6. Return validated results
}
}
```
## Frontend Pattern (Next.js)
```typescript
// Document Review Form (reusable component)
const DocumentReviewForm = ({ document, aiSuggestions }) => {
return (
<form>
<Field label="Document Type" suggestions={aiSuggestions.documentType} />
<Field label="Project Code" suggestions={aiSuggestions.projectCode} />
<Field label="Discipline" suggestions={aiSuggestions.discipline} />
<ConfidenceScore score={aiSuggestions.confidence} />
<HumanValidationActions />
</form>
);
};
```
## Security Requirements
- **AI Isolation:** All AI processing on Admin Desktop only (Desk-5439)
- **Data Privacy:** No cloud AI services, on-premises only
- **Audit Trail:** Log all AI interactions and human validations to ai_audit_logs
- **Rate Limiting:** Prevent AI abuse and resource exhaustion
- **Validation:** All AI outputs must be validated before use
- **Multi-tenant Isolation:** Qdrant queries MUST include projectPublicId filter (compile-time enforcement)
- **n8n Boundary:** n8n MUST call DMS API → BullMQ, NEVER Ollama/Qdrant directly
- **GPU Overload Prevention:** BullMQ 2-queue (ai-realtime + ai-batch) with concurrency=1
## ADR-023A Specific Rules
- **2-Model Stack:** gemma4:e2b + nomic-embed-text
- **PDF 3-Page Limit:** Classification/Tagging uses first 3 pages only (NOT RAG embedding)
- **RAG Embedding:** Full document chunked at 512 tokens/64 tokens overlap
- **OCR Auto-Detect:** PyMuPDF chars > 100 → Fast path, else PaddleOCR
- **Embed Auto-Trigger:** AUTO after commit (parallel), gap covered by DB search
- **Threshold Recalibration:** After 100-500 docs, based on ai_audit_logs analysis
## Required Implementation
- [ ] AiModule with ADR-023 boundary enforcement
- [ ] AI Gateway API endpoints with validation
- [ ] BullMQ 2-queue setup (ai-realtime + ai-batch)
- [ ] QdrantService with projectPublicId enforcement
- [ ] DocumentReviewForm reusable component
- [ ] Admin Desktop Ollama (gemma4:e2b + nomic-embed-text) + PaddleOCR setup
- [ ] n8n workflow orchestration (Migration Phase only)
- [ ] AI audit logging and monitoring (ai_audit_logs)
- [ ] Human-in-the-loop validation workflows
## Related Documents
- `specs/06-Decision-Records/ADR-023-unified-ai-architecture.md` (Base architecture)
- `specs/06-Decision-Records/ADR-023A-unified-ai-architecture.md` (Model revision - current)
- `specs/06-Decision-Records/ADR-024-intent-classification-strategy.md` (Pattern→LLM Fallback)
- `specs/06-Decision-Records/ADR-025-ai-tool-layer-architecture.md` (Tool Registry)
- `specs/06-Decision-Records/ADR-026-document-chat-ui-pattern.md` (Chat UI)
- `specs/06-Decision-Records/ADR-027-ai-admin-console-and-dynamic-control.md` (Admin Console)
- `specs/06-Decision-Records/ADR-028-migration-architecture-refactor.md` (Migration Pipeline)
+141
View File
@@ -0,0 +1,141 @@
---
trigger: always_on
---
# LCBP3 Agent Rules
Critical rules and guidelines for AI agents working on LCBP3-DMS.
## Version
- **Current:** v1.9.6
- **Last Updated:** 2026-05-22
- **Synced with:** `AGENTS.md` (v1.9.6)
## Purpose
This directory contains rule files that define:
- Project context and role expectations
- Critical Tier 1 rules (CI blockers)
- Coding standards and patterns
- Domain terminology and glossary
- Development workflows
- Security requirements
- AI integration architecture (ADR-023/023A)
## Rule Enforcement Tiers
### 🔴 Tier 1 — CRITICAL (CI BLOCKER)
Build fails immediately if violated:
- Security (Auth, RBAC, Validation)
- UUID Strategy (ADR-019) — no `parseInt` / `Number` / `+` on UUID
- Database correctness — verify schema before writing queries
- File upload security (ClamAV + whitelist)
- AI validation boundary (ADR-023)
- Error handling strategy (ADR-007)
- Forbidden patterns: `any`, `console.log`, UUID misuse, `id ?? ''` fallback
### 🟡 Tier 2 — IMPORTANT (CODE REVIEW)
Must fix before merge:
- Architecture patterns (thin controller, business logic in service)
- Test coverage (80%+ business logic, 70%+ backend overall)
- Cache invalidation
- Naming conventions
- TypeScript Standards: Missing JSDoc, explicit types, or file headers
### 🟢 Tier 3 — SPECIALIZED WORK
Requires domain-specific knowledge:
- **ADR-021 Integration:** Workflow Engine & Context implementation
- **AI Infrastructure:** ADR-023/023A boundary enforcement and pipeline usage
- **AI Runtime Layer:** ADR-024 Intent Classification, ADR-025 Tool Layer, ADR-026 Chat UI, ADR-027 Admin Console
- **Migration Pipeline:** ADR-028 Staging Queue & post-migration cleanup
- **Complex Business Logic:** Multi-step workflows with state management
- **Performance Optimization:** Database queries, caching strategies, bulk operations
### 🔵 Tier 4 — GUIDELINES
Best practice — follow when possible:
- Code style / formatting (Prettier handles)
- Comment completeness
- Minor optimizations
## Rule Files
### Core Rules (Tier 1 - CRITICAL)
| File | Purpose |
| ----------------------- | ------------------------------------------------------------------------------- |
| `00-project-context.md` | Project context, role & persona, tier classification, specs folder organization |
| `01-adr-019-uuid.md` | UUID handling strategy — no parseInt, use publicId only |
| `02-security.md` | Security requirements, checklist, ADR-023/023A AI boundaries |
### Coding Standards
| File | Purpose |
| ------------------------- | ------------------------------------------------------- |
| `03-typescript.md` | TypeScript rules, file headers, i18n guidelines |
| `06-backend-patterns.md` | NestJS patterns, UUID resolution, API response patterns |
| `07-frontend-patterns.md` | Next.js patterns, RHF+Zod+TanStack Query, UUID handling |
### Domain & Workflow
| File | Purpose |
| -------------------------- | ------------------------------------------------------------- |
| `04-domain-terminology.md` | DMS glossary, key spec files priority table |
| `08-development-flow.md` | Development workflow by work type (Critical/Normal/Quick Fix) |
### Compliance & Architecture
| File | Purpose |
| ------------------------- | -------------------------------------------------------------- |
| `05-forbidden-actions.md` | Actions that must never be done, schema changes, UUID handling |
| `09-commit-checklist.md` | Pre-commit verification, commit message format |
| `10-error-handling.md` | ADR-007 error handling strategy, layered classification |
| `11-ai-integration.md` | ADR-023/023A AI architecture, 2-model stack, BullMQ 2-queue |
## Key Spec Files Priority
Spec priority: **`06-Decision-Records`** > **`05-Engineering-Guidelines`** > others
| Document | Path | Use When |
| ------------------------------ | --------------------------------------------------------------------------- | --------------------------------- |
| **Glossary** | `specs/00-overview/00-02-glossary.md` | Verify domain terminology |
| **Schema Tables** | `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql` | Before writing any query |
| **Data Dictionary** | `specs/03-Data-and-Storage/03-01-data-dictionary.md` | Field meanings + business rules |
| **Edge Cases** | `specs/01-Requirements/01-06-edge-cases-and-rules.md` | Prevent bugs in flows |
| **ADR-019 UUID** | `specs/06-Decision-Records/ADR-019-hybrid-identifier-strategy.md` | UUID-related work |
| **ADR-023 AI** | `specs/06-Decision-Records/ADR-023-unified-ai-architecture.md` | AI integration work |
| **ADR-023A AI Model** | `specs/06-Decision-Records/ADR-023A-unified-ai-architecture.md` | 2-model stack, BullMQ 2-queue |
| **ADR-024 Intent Class.** | `specs/06-Decision-Records/ADR-024-intent-classification-strategy.md` | Pattern→LLM Fallback; Redis cache |
| **ADR-025 AI Tool Layer** | `specs/06-Decision-Records/ADR-025-ai-tool-layer-architecture.md` | Tool Registry; CASL-guarded |
| **ADR-026 Chat UI** | `specs/06-Decision-Records/ADR-026-document-chat-ui-pattern.md` | Side-panel; streaming SSE |
| **ADR-027 AI Admin Console** | `specs/06-Decision-Records/ADR-027-ai-admin-console-and-dynamic-control.md` | Dynamic control; admin-only |
| **ADR-028 Migration Refactor** | `specs/06-Decision-Records/ADR-028-migration-architecture-refactor.md` | Staging Queue; cleanup |
| **Backend Guidelines** | `specs/05-Engineering-Guidelines/05-02-backend-guidelines.md` | NestJS patterns |
| **Frontend Guidelines** | `specs/05-Engineering-Guidelines/05-03-frontend-guidelines.md` | Next.js patterns |
| **Testing Strategy** | `specs/05-Engineering-Guidelines/05-04-testing-strategy.md` | Coverage goals |
## Maintenance
When updating rules:
1. **Check AGENTS.md version** — Ensure rule files are synced
2. **Update version numbers** — Bump version in `00-project-context.md` only (03-typescript.md no longer has version)
3. **Review ADR references** — Ensure all ADR references are current (ADR-023, ADR-023A, ADR-024~028)
4. **Add new forbidden actions** — When new patterns are identified as violations
5. **Update key spec files table** — When new ADRs or guidelines are added
6. **Update Tier 3 SPECIALIZED WORK** — When new domain-specific workflows are added
## Related Documents
- `AGENTS.md` — Master agent configuration and context
- `specs/06-Decision-Records/` — All Architecture Decision Records
- `specs/05-Engineering-Guidelines/` — Backend, frontend, and testing guidelines
+30
View File
@@ -0,0 +1,30 @@
# lcbp3 Development Guidelines
Auto-generated from all feature plans. Last updated: 2026-05-30
## Active Technologies
- TypeScript 5.x (NestJS 11 backend, Next.js 16 frontend), Python 3.11 (OCR sidecar)
+ Ollama (AI runtime), BullMQ (job queues), TypeORM (ORM), Redis (caching/locks), MariaDB 11.8 (database)
(232-typhoon-ocr-integration)
## Project Structure
```text
backend/
frontend/
tests/
```
## Commands
cd src [ONLY COMMANDS FOR ACTIVE TECHNOLOGIES][ONLY COMMANDS FOR ACTIVE TECHNOLOGIES] pytest [ONLY COMMANDS FOR ACTIVE TECHNOLOGIES][ONLY COMMANDS FOR ACTIVE TECHNOLOGIES] ruff check .
## Code Style
TypeScript 5.x (NestJS 11 backend, Next.js 16 frontend), Python 3.11 (OCR sidecar)
: Follow standard conventions
## Recent Changes
- 232-typhoon-ocr-integration: Added TypeScript 5.x (NestJS 11 backend, Next.js 16 frontend), Python 3.11 (OCR sidecar)