diff --git a/.agent/rules/00-project-specs.md b/.agent/rules/00-project-specs.md index e2569bb..e4caa1b 100644 --- a/.agent/rules/00-project-specs.md +++ b/.agent/rules/00-project-specs.md @@ -9,70 +9,80 @@ Globs: \* --- -## Agent Role +## 🧠 Role & Persona -You are a Principal Engineer and Architect strictly bound by the project's documentation. You do not improvise outside of the defined specifications. +Act as a **Senior Full Stack Developer** specialized in: -## The Context Loading Protocol +- NestJS, Next.js, TypeScript +- Document Management Systems (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**. + +## 🧭 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-018) +- Forbidden patterns: `any`, `console.log`, UUID misuse + +### 🟡 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 + +### 🟢 Tier 3 — GUIDELINES + +Best practice — follow when possible: + +- Code style / formatting (Prettier handles) +- Comment completeness +- Minor optimizations + +## 📖 The Context Loading Protocol Before generating code or planning a solution, you MUST conceptually load the context in this specific order: -1. **📖 PROJECT CONTEXT (`specs/00-Overview/`)** - - _Action:_ Align with the high-level goals and domain language described here. +1. **📖 PROJECT CONTEXT (`specs/00-Overview/`)** + - _Action:_ Align with the high-level goals and domain language described here. +2. **✅ REQUIREMENTS (`specs/01-Requirements/`)** + - _Action:_ Verify that your plan satisfies the functional requirements and user stories. +3. **🏗 ARCHITECTURE & DECISIONS (`specs/02-Architecture/` & `specs/06-Decision-Records/`)** + - _Action:_ Adhere to the defined system design. + - _Crucial:_ Check `specs/06-Decision-Records/` (ADRs) to ensure you do not violate previously agreed-upon technical decisions. +4. **💾 DATABASE & SCHEMA (`specs/03-Data-and-Storage/`)** + - _Action:_ Read schema SQL files and data dictionary. Use only defined names. +5. **⚙️ IMPLEMENTATION DETAILS (`specs/05-Engineering-Guidelines/`)** + - _Action:_ Follow Tech Stack, Naming Conventions, and Code Patterns. +6. **🚀 OPERATIONS & INFRASTRUCTURE (`specs/04-Infrastructure-OPS/`)** + - _Action:_ Ensure deployability and configuration compliance. -2. **✅ REQUIREMENTS (`specs/01-Requirements/`)** - - _Action:_ Verify that your plan satisfies the functional requirements and user stories. - - _Constraint:_ If a requirement is ambiguous, stop and ask. +### 🗂️ Key Spec Files (Priority: ADRs > Engineering Guidelines > others) -3. **🏗 ARCHITECTURE & DECISIONS (`specs/02-Architecture/` & `specs/06-Decision-Records/`)** - - _Action:_ Adhere to the defined system design. - - _Crucial:_ Check `specs/06-Decision-Records/` (ADRs) to ensure you do not violate previously agreed-upon technical decisions. - -4. **💾 DATABASE & SCHEMA (`specs/03-Data-and-Storage/`)** - - _Action:_ - - **Read `specs/03-Data-and-Storage/lcbp3-v1.8.0-schema-02-tables.sql`** for exact table structures and constraints. (Schema split: `01-drop`, `02-tables`, `03-views-indexes`) - - **Consult `specs/03-Data-and-Storage/03-01-data-dictionary.md`** for field meanings and business rules. - - **Check `specs/03-Data-and-Storage/lcbp3-v1.8.0-seed-basic.sql`** to understand initial data states. - - **Check `specs/03-Data-and-Storage/lcbp3-v1.8.0-seed-permissions.sql`** to understand initial permissions states. - - **Check `specs/03-Data-and-Storage/03-04-legacy-data-migration.md`** for migration context (ADR-017). - - **Check `specs/03-Data-and-Storage/03-05-n8n-migration-setup-guide.md`** for n8n workflow setup. - - _Constraint:_ NEVER invent table names or columns. Use ONLY what is defined here. - -5. **⚙️ IMPLEMENTATION DETAILS (`specs/05-Engineering-Guidelines/`)** - - _Action:_ Follow Tech Stack, Naming Conventions, and Code Patterns. - -6. **🚀 OPERATIONS & INFRASTRUCTURE (`specs/04-Infrastructure-OPS/`)** - - _Action:_ Ensure deployability and configuration compliance. - - _Constraint:_ Ensure deployment paths, port mappings, and volume mounts are consistent with this documentation. - -## Execution Rules - -### 1. Citation Requirement - -When proposing a change or writing code, you must explicitly reference the source of truth: - -> "Implementing feature X per `specs/01-Requirements/` using pattern defined in `specs/05-Engineering-Guidelines/`." - -### 2. Conflict Resolution - -- **Spec vs. Training Data:** The `specs/` folder ALWAYS supersedes your general training data. -- **Spec vs. User Prompt:** If a user prompt contradicts `specs/06-Decision-Records/`, warn the user before proceeding. - -### 3. File Generation - -- Do not create new files outside of the established project structure: - - Backend: `backend/src/modules//`, `backend/src/common/` - - Frontend: `frontend/app/`, `frontend/components/`, `frontend/hooks/`, `frontend/lib/` - - Specs: `specs/` subdirectories only -- Keep the code style consistent with `specs/05-Engineering-Guidelines/`. -- New modules MUST follow the workflow in `.agents/workflows/create-backend-module.md` or `.agents/workflows/create-frontend-page.md`. - -### 4. Schema Changes - -- **DO NOT** create or run TypeORM migration files. -- Modify the schema directly in `specs/03-Data-and-Storage/lcbp3-v1.8.0-schema-02-tables.sql` (or `01-drop`/`03-views-indexes` as appropriate). -- Update `specs/03-Data-and-Storage/03-01-data-dictionary.md` if adding/changing columns. -- Notify the user so they can apply the SQL change to the live database manually. -- **AI Isolation (ADR-018):** Ollama runs on ASUSTOR only. AI has NO direct DB access, NO write access to uploads. All writes go through DMS API. - ---- +| Document | Path | Use When | +| ----------------------- | ----------------------------------------------------------------- | ------------------------------- | +| **Glossary** | `specs/00-overview/00-02-glossary.md` | Verify domain terminology | +| **Schema Tables** | `specs/03-Data-and-Storage/lcbp3-v1.8.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 | +| **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 | diff --git a/.agent/rules/01-code-execution.md b/.agent/rules/01-code-execution.md index e2d0624..b26de74 100644 --- a/.agent/rules/01-code-execution.md +++ b/.agent/rules/01-code-execution.md @@ -21,6 +21,9 @@ denyAuto: - 'DROP TABLE' - 'TRUNCATE' - 'DELETE FROM' + - 'pnpm migration:*' + - 'npm run migration:*' + - 'npx auth secret' alwaysReview: true scopes: - 'backend/src/**' diff --git a/.agent/rules/02-identifier-strategy.md b/.agent/rules/02-identifier-strategy.md new file mode 100644 index 0000000..144e4ee --- /dev/null +++ b/.agent/rules/02-identifier-strategy.md @@ -0,0 +1,18 @@ +--- +trigger: always_on +--- + +# 🆔 Identifier Strategy (ADR-019) — CRITICAL + +| 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) | + +**CRITICAL RULES:** + +- **NEVER** use `parseInt`, `Number()`, or `+` on UUID values. +- **NEVER** use `id ?? ''` fallback for identifiers in the frontend. +- Use `publicId` only in frontend and public API responses. +- `INT id` has `@Exclude()` on the backend — it must never appear in API responses. diff --git a/.agent/rules/03-security-rules.md b/.agent/rules/03-security-rules.md new file mode 100644 index 0000000..16a77e9 --- /dev/null +++ b/.agent/rules/03-security-rules.md @@ -0,0 +1,23 @@ +--- +trigger: always_on +--- + +# 🛡️ Security Rules (Non-Negotiable) + +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. **AI Isolation (ADR-018):** Ollama on Admin Desktop ONLY — NO direct DB/storage access + +## 🚫 Forbidden Actions + +| ❌ Forbidden | ✅ Correct Approach | +| ----------------------------------------------- | --------------------------------------------- | +| SQL Triggers for business logic | NestJS Service methods | +| TypeORM migration files | Edit schema SQL directly (ADR-009) | +| `any` TypeScript type | Proper types / generics | +| `console.log` in committed code | NestJS Logger (backend) / remove (frontend) | +| Direct file operations bypassing StorageService | `StorageService` for all file moves | +| Inline email/notification sending | BullMQ queue job | +| `parseInt()` on UUID values | Use UUID string directly (ADR-019) | diff --git a/.agent/rules/04-development-standards.md b/.agent/rules/04-development-standards.md new file mode 100644 index 0000000..8f676ab --- /dev/null +++ b/.agent/rules/04-development-standards.md @@ -0,0 +1,24 @@ +--- +trigger: always_on +--- + +# 📐 TypeScript Rules + +- **Strict Mode** — all strict checks enforced +- **ZERO `any` types** — use proper types or `unknown` + narrowing +- **ZERO `console.log`** — NestJS `Logger` (backend); remove before commit (frontend) + +## 🏷️ Domain Terminology (Thai Comments, English Code) + +| ✅ Use | ❌ Don't Use | +| ------------------ | ------------------------------------- | +| Correspondence | Letter, Communication, Document | +| RFA | Approval Request, Submit for Approval | +| Workflow Engine | Approval Flow, Process Engine | +| Document Numbering | Document ID, Auto Number | + +## 🔄 Development Flow (Tiered) + +- **🔴 Critical (DB/API/Security):** MUST follow all Context Protocol steps. +- **🟡 Normal (UI/Feature):** Follow existing patterns, check spec for relevant module. +- **🟢 Quick Fix:** Fix directly, check forbidden patterns before commit. diff --git a/.agent/rules/05-precommit-checklist.md b/.agent/rules/05-precommit-checklist.md new file mode 100644 index 0000000..af21df2 --- /dev/null +++ b/.agent/rules/05-precommit-checklist.md @@ -0,0 +1,13 @@ +--- +trigger: always_on +--- + +# ✅ Quick Reference Checklist (Before Every Commit) + +- [ ] 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) +- [ ] Relevant ADRs checked (ADR-009, ADR-018, ADR-019) +- [ ] i18n keys used instead of hardcode text diff --git a/package.json b/package.json index c26c129..da57ea7 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,9 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start:mcp": "node ./scripts/start-mcp.js", + "dev:backend": "pnpm --filter backend start:dev", + "dev:frontend": "pnpm --filter lcbp3-frontend dev", + "dev": "pnpm run --parallel /dev|start:dev/", "prepare": "husky", "lint": "eslint .", "lint:fix": "eslint . --fix"