# 📋 **แผนการพัฒนา Backend (NestJS) - LCBP3-DMS v1.4.4 (ฉบับปรับปรุง)**

**สถานะ:** FINAL GUIDELINE Rev.04
**วันที่:** 2025-11-26
**อ้างอิง:** Requirements v1.4.3 & FullStackJS Guidelines v1.4.3
**Classification:** Internal Technical Documentation
**การแก้ไข:** เพิ่ม T2.5.1-T2.5.9, T3.1.1-T3.1.8,

---

## 🎯 **ภาพรวมโครงการ**

พัฒนา Backend สำหรับระบบบริหารจัดการเอกสารโครงการ (Document Management System) ที่มีความปลอดภัยสูง รองรับการทำงานพร้อมกัน (Concurrency) ได้อย่างถูกต้องแม่นยำ มีสถาปัตยกรรมที่ยืดหยุ่นต่อการขยายตัว และรองรับการจัดการเอกสารที่ซับซ้อน มีระบบ Workflow การอนุมัติ และการควบคุมสิทธิ์แบบ RBAC 4 ระดับ พร้อมมาตรการความปลอดภัยที่ทันสมัย

---

## 📐 **สถาปัตยกรรมระบบ**

### **Technology Stack (Updated)**

- **Framework:** NestJS (TypeScript, ESM)
- **Database:** MariaDB 10.11 (ใช้ Virtual Columns)
- **ORM:** TypeORM (ใช้ Optimistic Locking)
- **Authentication:** JWT + Passport
- **Authorization:** CASL (RBAC 4-level)
- **File Upload:** Multer + Virus Scanning (ClamAV) + Two-Phase Storage
- **Search:** Elasticsearch
- **Notification:** Nodemailer + n8n (Line Integration) + BullMQ Queue
- **Caching/Locking:** Redis (Redlock) สำหรับ Distributed Locking
- **Queue:** BullMQ (Redis) สำหรับ Notification Batching และ Async Jobs
- **Resilience:** Circuit Breaker, Retry Patterns
- **Security:** Helmet, CSRF Protection, Rate Limiting, Idempotency
- **Monitoring:** Winston, Health Checks, Metrics
- **Scheduling:** @nestjs/schedule (Cron Jobs)
- **Documentation:** Swagger
- **Validation:** Zod / Class-validator

### **โครงสร้างโมดูล (Domain-Driven)**

```
📁backend
├── .editorconfig
├── .env
├── .gitignore
├── .prettierrc
├── docker-compose.override.yml.example
├── docker-compose.yml
├── eslint.config.mjs
├── Infrastructure Setup.yml
├── nest-cli.json
├── package-lock.json
├── package.json
├── pnpm-lock.yaml
├── README.md
├── tsconfig.build.json
├── tsconfig.json
├── 📁scripts
│   ├── debug-db.ts
│   └── verify-workflow.ts
├── 📁test
│   ├── app.e2e-spec.ts
│   ├── jest-e2e.json
│   ├── phase3-workflow.e2e-spec.ts
│   └── simple.e2e-spec.ts
├── 📁uploads
│   └── 📁temp
│       ├── 5a6d4c26-84b2-4c8a-b177-9fa267651a93.pdf
│       └── d60d9807-a22d-4ca0-b99a-5d5d8b81b3e8.pdf
└── 📁src
    ├── app.controller.spec.ts
    ├── app.controller.ts
    ├── app.module.ts
    ├── app.service.ts
    ├── main.ts
    ├── redlock.d.ts
    ├── 📁common
    │   ├── 📁auth
    │   │   ├── 📁dto
    │   │   │   ├── login.dto.ts
    │   │   │   └──  register.dto.ts
    │   │   ├── 📁strategies
    │   │   │   ├── jwt-refresh.strategy.ts
    │   │   │   └──  jwt.strategy.ts
    │   │   ├── auth.controller.spec.ts
    │   │   ├── auth.controller.ts
    │   │   ├── auth.module.ts
    │   │   ├── auth.service.spec.ts
    │   │   └── auth.service.ts
    │   ├── 📁config
    │   │   ├── env.validation.ts
    │   │   └──  redis.config.ts
    │   ├── 📁decorators
    │   │   ├── audit.decorator.ts
    │   │   ├── bypass-maintenance.decorator.ts
    │   │   ├── circuit-breaker.decorator.ts
    │   │   ├── current-user.decorator.ts
    │   │   ├── idempotency.decorator.ts
    │   │   ├── require-permission.decorator.ts
    │   │   └── retry.decorator.ts
    │   ├── 📁entities
    │   │   ├── audit-log.entity.ts
    │   │   └──  base.entity.ts
    │   ├── 📁exceptions
    │   │   └──  http-exception.filter.ts
    │   ├── 📁file-storage
    │   │   ├── 📁entities
    │   │   │   └──  attachment.entity.ts
    │   │   ├── file-cleanup.service.ts
    │   │   ├── file-storage.controller.spec.ts
    │   │   ├── file-storage.controller.ts
    │   │   ├── file-storage.module.ts
    │   │   ├── file-storage.service.spec.ts
    │   │   └──  file-storage.service.ts
    │   ├── 📁guards
    │   │   ├── jwt-auth.guard.ts
    │   │   ├── jwt-refresh.guard.ts
    │   │   ├── maintenance-mode.guard.ts
    │   │   └──  rbac.guard.ts
    │   ├── 📁idempotency
    │   │   ├── idempotency.interceptor.ts
    │   │   └── performance.interceptor.ts
    │   ├── 📁interceptors
    │   │   ├── audit-log.interceptor.ts
    │   │   ├── idempotency.interceptor.ts
    │   │   ├── performance.interceptor.ts
    │   │   └── transform.interceptor.ts
    │   ├── 📁maintenance
    │   ├── 📁resilience
    │   │   └──  resilience.module.ts
    │   └── 📁security
    │       ├── 📁services
    │       │   ├── crypto.service.ts
    │       │   └── request-context.service.ts
    │       └── common.module.ts
    ├── 📁database
    │   ├── 📁migrations
    │   └── 📁seeds
    │       └── workflow-definitions.seed.ts
    └── 📁modules
        ├── 📁circulation
        │   ├── 📁dto
        │   │   ├── create-circulation.dto.ts
        │   │   ├── search-circulation.dto.ts
        │   │   └── update-circulation-routing.dto.ts
        │   ├── 📁entities
        │   │   ├── circulation-routing.entity.ts
        │   │   ├── circulation-status-code.entity.ts
        │   │   └── circulation.entity.ts
        │   ├── circulation.controller.ts
        │   ├── circulation.module.ts
        │   └── circulation.service.ts
        ├── 📁correspondence
        │   ├── 📁dto
        │   │   ├── add-reference.dto.ts
        │   │   ├── create-correspondence.dto.ts
        │   │   ├── search-correspondence.dto.ts
        │   │   ├── submit-correspondence.dto.ts
        │   │   └── workflow-action.dto.ts
        │   ├── 📁entities
        │   │   ├── correspondence-reference.entity.ts
        │   │   ├── correspondence-revision.entity.ts
        │   │   ├── correspondence-routing.entity.ts
        │   │   ├── correspondence-status.entity.ts
        │   │   ├── correspondence-sub-type.entity.ts
        │   │   ├── correspondence-type.entity.ts
        │   │   ├── correspondence.entity.ts
        │   │   ├── routing-template-step.entity.ts
        │   │   └── routing-template.entity.ts
        │   ├── correspondence.controller.spec.ts
        │   ├── correspondence.controller.ts
        │   ├── correspondence.module.ts
        │   ├── correspondence.service.spec.ts
        │   └── correspondence.service.ts
        ├── 📁document-numbering
        │   ├── 📁entities
        │   │   ├── document-number-counter.entity.ts
        │   │   └── document-number-format.entity.ts
        │   ├── 📁interfaces
        │   │   └── document-numbering.interface.ts
        │   ├── document-numbering.module.ts
        │   ├── document-numbering.service.spec.ts
        │   └── document-numbering.service.ts
        ├── 📁drawing
        │   ├── 📁dto
        │   │   ├── create-contract-drawing.dto.ts
        │   │   ├── create-shop-drawing-revision.dto.ts
        │   │   ├── create-shop-drawing.dto.ts
        │   │   ├── search-contract-drawing.dto.ts
        │   │   ├── search-shop-drawing.dto.ts
        │   │   └── update-contract-drawing.dto.ts
        │   ├── 📁entities
        │   │   ├── contract-drawing-sub-category.entity.ts
        │   │   ├── contract-drawing-volume.entity.ts
        │   │   ├── contract-drawing.entity.ts
        │   │   ├── shop-drawing-main-category.entity.ts
        │   │   ├── shop-drawing-revision.entity.ts
        │   │   ├── shop-drawing-sub-category.entity.ts
        │   │   └── shop-drawing.entity.ts
        │   ├── contract-drawing.controller.ts
        │   ├── contract-drawing.service.ts
        │   ├── drawing-master-data.controller.ts
        │   ├── drawing-master-data.service.ts
        │   ├── drawing.module.ts
        │   ├── shop-drawing.controller.ts
        │   └── shop-drawing.service.ts
        ├── 📁json-schema
        │   ├── 📁dto
        │   │   ├── create-json-schema.dto.ts
        │   │   ├── search-json-schema.dto.ts
        │   │   └── update-json-schema.dto.ts
        │   ├── 📁entities
        │   │   └── json-schema.entity.ts
        │   ├── json-schema.controller.spec.ts
        │   ├── json-schema.controller.ts
        │   ├── json-schema.module.ts
        │   ├── json-schema.service.spec.ts
        │   └── json-schema.service.ts
        ├── 📁master
        │   ├── 📁dto
        │   │   ├── create-discipline.dto.ts
        │   │   ├── create-sub-type.dto.ts
        │   │   ├── create-tag.dto.ts
        │   │   ├── save-number-format.dto.ts
        │   │   ├── search-tag.dto.ts
        │   │   └── update-tag.dto.ts
        │   ├── 📁entities
        │   │   ├── discipline.entity.ts
        │   │   └── tag.entity.ts
        │   ├── master.controller.ts
        │   ├── master.module.ts
        │   └── master.service.ts
        ├── 📁monitoring
        │   ├── 📁controllers
        │   │   └── health.controller.ts
        │   ├── 📁dto
        │   │   └── set-maintenance.dto.ts
        │   ├── 📁logger
        │   │   └── winston.config.ts
        │   ├── 📁services
        │   │   └── metrics.service.ts
        │   ├── monitoring.controller.ts
        │   ├── monitoring.module.ts
        │   └── monitoring.service.ts
        ├── 📁notification
        │   ├── 📁dto
        │   │   ├── create-notification.dto.ts
        │   │   └── search-notification.dto.ts
        │   ├── 📁entities
        │   │   └── notification.entity.ts
        │   ├── notification-cleanup.service.ts
        │   ├── notification.controller.ts
        │   ├── notification.gateway.ts
        │   ├── notification.module.ts
        │   ├── notification.processor.ts
        │   └── notification.service.ts
        ├── 📁project
        │   ├── 📁dto
        │   │   ├── create-project.dto.ts
        │   │   ├── search-project.dto.ts
        │   │   └── update-project.dto.ts
        │   ├── 📁entities
        │   │   ├── contract-organization.entity.ts
        │   │   ├── contract.entity.ts
        │   │   ├── organization.entity.ts
        │   │   ├── project-organization.entity.ts
        │   │   └── project.entity.ts
        │   ├── project.controller.spec.ts
        │   ├── project.controller.ts
        │   ├── project.module.ts
        │   ├── project.service.spec.ts
        │   └── project.service.ts
        ├── 📁rfa
        │   ├── 📁dto
        │   │   ├── create-rfa.dto.ts
        │   │   ├── search-rfa.dto.ts
        │   │   └── update-rfa.dto.ts
        │   ├── 📁entities
        │   │   ├── rfa-approve-code.entity.ts
        │   │   ├── rfa-item.entity.ts
        │   │   ├── rfa-revision.entity.ts
        │   │   ├── rfa-status-code.entity.ts
        │   │   ├── rfa-type.entity.ts
        │   │   ├── rfa-workflow-template-step.entity.ts
        │   │   ├── rfa-workflow-template.entity.ts
        │   │   ├── rfa-workflow.entity.ts
        │   │   └── rfa.entity.ts
        │   ├── rfa.controller.ts
        │   ├── rfa.module.ts
        │   └── rfa.service.ts
        ├── 📁search
        │   ├── 📁dto
        │   │   └── search-query.dto.ts
        │   ├── search.controller.ts
        │   ├── search.module.ts
        │   └── search.service.ts
        ├── 📁transmittal
        │   ├── 📁dto
        │   │   ├── create-transmittal.dto.ts
        │   │   ├── search-transmittal.dto.ts
        │   │   └── update-transmittal.dto.ts
        │   ├── 📁entities
        │   │   ├── transmittal-item.entity.ts
        │   │   └── transmittal.entity.ts
        │   ├── transmittal.controller.ts
        │   ├── transmittal.module.ts
        │   └── transmittal.service.ts
        ├── 📁user
        │   ├── 📁dto
        │   │   ├── assign-role.dto.ts
        │   │   ├── create-user.dto.ts
        │   │   ├── update-preference.dto.ts
        │   │   └── update-user.dto.ts
        │   ├── 📁entities
        │   │   ├── permission.entity.ts
        │   │   ├── role.entity.ts
        │   │   ├── user-assignment.entity.ts
        │   │   ├── user-preference.entity.ts
        │   │   └── user.entity.ts
        │   ├── user-assignment.service.ts
        │   ├── user-preference.service.ts
        │   ├── user.controller.ts
        │   ├── user.module.ts
        │   ├── user.service.spec.ts
        │   └── user.service.ts
        └── 📁workflow-engine
            ├── 📁dto
            │   ├── create-workflow-definition.dto.ts
            │   ├── evaluate-workflow.dto.ts
            │   ├── get-available-actions.dto.ts
            │   └── update-workflow-definition.dto.ts
            ├── 📁entities
            │   └── workflow-definition.entity.ts
            ├── 📁interfaces
            │   └── workflow.interface.ts
            ├── workflow-dsl.service.ts
            ├── workflow-engine.controller.ts
            ├── workflow-engine.module.ts
            ├── workflow-engine.service.spec.ts
            └── workflow-engine.service.ts

```

---

## 🗓️ **แผนการพัฒนาแบบ Phase-Based**

- _(Dependency Diagram ถูกละไว้เพื่อประหยัดพื้นที่ เนื่องจากมีการอ้างอิงจากแผนเดิม)_

## **Phase 0: Infrastructure & Configuration (สัปดาห์ที่ 1)**

**Milestone:** โครงสร้างพื้นฐานพร้อม รองรับ Secrets ที่ปลอดภัย และ Redis พร้อมใช้งาน

### **Phase 0: Tasks**

- **[ ] T0.1 Secure Configuration Setup**

  - [ ] ปรับปรุง `ConfigModule` ให้รองรับการอ่านค่าจาก Environment Variables
  - [ ] สร้าง Template `docker-compose.override.yml.example` สำหรับ Dev
  - [ ] Validate Config ด้วย Joi/Zod ตอน Start App (Throw error ถ้าขาด Secrets)
  - [ ] **Security:** Setup network segmentation และ firewall rules
  - [ ] **Deliverable:** Configuration Management พร้อมใช้งานอย่างปลอดภัย
  - [ ] **Dependencies:** None (Task เริ่มต้น)

- **[ ] T0.2 Redis & Queue Infrastructure**

  - [ ] Setup Redis Container
  - [ ] Setup BullMQ Module ใน NestJS สำหรับจัดการ Background Jobs
  - [ ] Setup Redis Client สำหรับ Distributed Lock (Redlock)
  - [ ] **Security:** Setup Redis authentication และ encryption
  - [ ] **Deliverable:** Redis และ Queue System พร้อมใช้งาน
  - [ ] **Dependencies:** T0.1

- **[ ] T0.3 Setup Database Connection**

  - [ ] Import SQL Schema v1.4.2 เข้า MariaDB
  - [ ] Run Seed Data (organizations, users, roles, permissions)
  - [ ] Configure TypeORM ใน AppModule
  - [ ] **Security:** Setup database connection encryption
  - [ ] ทดสอบ Connection
  - [ ] **Deliverable:** Database พร้อมใช้งาน, มี Seed Data
  - [ ] **Dependencies:** T0.1

- **[ ] T0.4 Setup Git Repository**

  - [ ] สร้าง Repository ใน Gitea (git.np-dms.work)
  - [ ] Setup .gitignore, README.md, SECURITY.md
  - [ ] Commit Initial Project
  - [ ] **Deliverable:** Code อยู่ใน Version Control
  - [ ] **Dependencies:** T0.1, T0.2, T0.3

---

## **Phase 1: Core Foundation & Security (สัปดาห์ที่ 2-3)**

**Milestone:** ระบบ Authentication, Authorization, Idempotency พื้นฐาน และ Security Baseline

### **Phase 1: Tasks**

- **[ ] T1.1 CommonModule - Base Infrastructure**

  - [ ] สร้าง Base Entity (id, created_at, updated_at, deleted_at)
  - [ ] สร้าง Global Exception Filter (ไม่เปิดเผย sensitive information)
  - [ ] สร้าง Response Transform Interceptor
  - [ ] สร้าง Audit Log Interceptor
  - [ ] **Idempotency Interceptor:** ตรวจสอบ Header `Idempotency-Key` และ Cache Response เดิมใน Redis
  - [ ] **Maintenance Mode Middleware:** ตรวจสอบ Flag ใน **Redis Key** เพื่อ Block API ระหว่างปรับปรุงระบบ **(Admin ใช้ Redis/Admin UI ในการ Toggle สถานะ)**
  - [ ] สร้าง RequestContextService - สำหรับเก็บข้อมูลระหว่าง Request
  - [ ] สร้าง ConfigService - Centralized configuration management
  - [ ] สร้าง CryptoService - สำหรับ encryption/decryption
  - [ ] **Security:** Implement input validation pipeline
  - [ ] **Deliverable:** Common Services พร้อมใช้ รวมถึง Idempotency และ Maintenance Mode
  - [ ] **Dependencies:** T0.2, T0.3

- **[ ] T1.2 AuthModule - JWT Authentication**

  - [ ] สร้าง Entity: User
  - [ ] สร้าง AuthService:
    - [ ] login(username, password) → JWT Token
    - [ ] validateUser(username, password) → User | null
    - [ ] Password Hashing (bcrypt) + salt
  - [ ] สร้าง JWT Strategy (Passport)
  - [ ] สร้าง JwtAuthGuard
  - [ ] สร้าง Controllers:
    - [ ] POST /auth/login → { access_token, refresh_token }
    - [ ] POST /auth/register → Create User (Admin only)
    - [ ] POST /auth/refresh → Refresh token
    - [ ] POST /auth/logout → Revoke token
    - [ ] GET /auth/profile (Protected)
  - [ ] **Security:** Implement rate limiting สำหรับ authentication endpoints
  - [ ] **Deliverable:** ล็อกอิน/ล็อกเอาต์ทำงานได้อย่างปลอดภัย
  - [ ] **Dependencies:** T1.1, T0.3

- **[ ] T1.3 UserModule - User Management**

  - [ ] สร้าง Entities: User, Role, Permission, UserRole, UserAssignment, **UserPreference**
  - [ ] สร้าง UserService CRUD (พร้อม soft delete)
  - [ ] สร้าง RoleService CRUD
  - [ ] สร้าง PermissionService (Read-Only, จาก Seed)
  - [ ] สร้าง UserAssignmentService - สำหรับจัดการ user assignments ตาม scope
  - [ ] สร้าง **UserPreferenceService** - สำหรับจัดการการตั้งค่า Notification และ UI
  - [ ] สร้าง Controllers:
    - [ ] GET /users → List Users (Paginated)
    - [ ] GET /users/:id → User Detail
    - [ ] POST /users → Create User (ต้องบังคับเปลี่ยน password ครั้งแรก)
    - [ ] PUT /users/:id → Update User
    - [ ] DELETE /users/:id → Soft Delete
    - [ ] GET /roles → List Roles
    - [ ] POST /roles → Create Role (Admin)
    - [ ] PUT /roles/:id/permissions → Assign Permissions
  - [ ] **Security:** Implement permission checks สำหรับ user management
  - [ ] **Deliverable:** จัดการผู้ใช้, Role, และ Preferences ได้
  - [ ] **Dependencies:** T1.1, T1.2

- **[ ] T1.4 RBAC Guard - 4-Level Authorization**

  - [ ] สร้าง @RequirePermission() Decorator
  - [ ] สร้าง RbacGuard ที่ตรวจสอบ 4 ระดับ:
    - [ ] Global Permissions
    - [ ] Organization Permissions
    - [ ] Project Permissions
    - [ ] Contract Permissions
  - [ ] Permission Hierarchy Logic
  - [ ] Integration กับ CASL
  - [ ] **Security:** Implement audit logging สำหรับ permission checks
  - [ ] **Deliverable:** ระบบสิทธิ์ทำงานได้ทั้ง 4 ระดับ
  - [ ] **Dependencies:** T1.1, T1.3

- **[ ] T1.5 ProjectModule - Base Structures**

  - [ ] สร้าง Entities:
    - [ ] Organization
    - [ ] Project
    - [ ] Contract
    - [ ] ProjectOrganization (Junction)
    - [ ] ContractOrganization (Junction)
  - [ ] สร้าง Services & Controllers:
    - [ ] GET /organizations → List
    - [ ] POST /projects → Create (Superadmin)
    - [ ] GET /projects/:id/contracts → List Contracts
    - [ ] POST /projects/:id/contracts → Create Contract
  - [ ] **Security:** Implement data isolation ระหว่าง organizations
  - [ ] **Deliverable:** จัดการโครงสร้างโปรเจกต์ได้
  - [ ] **Dependencies:** T1.1, T1.2, T0.3

---

## **Phase 2: High-Integrity Data & File Management (สัปดาห์ที่ 4)**

**Milestone:** Master Data, ระบบจัดการไฟล์แบบ Transactional, Document Numbering ที่ไม่มี Race Condition, JSON details system พร้อมใช้งาน

### **Phase 2: Tasks**

- **[ ] T2.1 Virtual Columns for JSON**

  - [ ] ออกแบบ Migration Script สำหรับตารางที่มี JSON Details
  - [ ] เพิ่ม **Generated Columns (Virtual)** สำหรับฟิลด์ที่ใช้ Search บ่อยๆ (เช่น `project_id`, `type`) พร้อม Index
  - [ ] **Security:** Implement admin-only access สำหรับ master data
  - [ ] **Deliverable:** JSON Data Search Performance ดีขึ้น
  - [ ] **Dependencies:** T0.3, T1.1, T1.5

- **[ ] T2.2 FileStorageService - Two-Phase Storage**

  - [ ] สร้าง Attachment Entity
  - [ ] สร้าง FileStorageService:
    - [ ] **Phase 1 (Upload):** API รับไฟล์ → Scan Virus → Save ลง `temp/` → Return `temp_id`
    - [ ] **Phase 2 (Commit):** Method `commitFiles(tempIds[])` → ย้ายจาก `temp/` ไป `permanent/{YYYY}/{MM}/` → Update DB
    - [ ] File type validation (white-list: PDF, DWG, DOCX, XLSX, PPTX, ZIP)
    - [ ] File size check (max 50MB)
    - [ ] Generate checksum (SHA-256)
    - [ ] **Cleanup Job:** สร้าง Cron Job ลบไฟล์ใน `temp/` ที่ค้างเกิน 24 ชม. **โดยตรวจสอบจากคอลัมน์ `expires_at` ในตาราง `attachments`**
  - [ ] สร้าง Controller:
    - [ ] POST /files/upload → { temp_id } (Protected)
    - [ ] POST /files/commit → { attachment_id, url } (Protected)
    - [ ] GET /files/:id/download → File Stream (Protected + Expiration)
  - [ ] **Security:** Access Control - ตรวจสอบสิทธิ์ผ่าน Junction Table
  - [ ] **Deliverable:** อัปโหลด/ดาวน์โหลดไฟล์ได้อย่างปลอดภัย แบบ Transactional
  - [ ] **Dependencies:** T1.1, T1.4

- **[ ] T2.3 DocumentNumberingModule - Double-Lock Mechanism**

  - [ ] สร้าง Entities:
    - [ ] DocumentNumberFormat
    - [ ] DocumentNumberCounter
  - [ ] สร้าง DocumentNumberingService:
    - [ ] generateNextNumber(projectId, orgId, typeId, year) → string
    - [ ] ใช้ **Double-Lock Mechanism**: 1. Acquire **Redis Lock** (Key: `doc_num:{project}:{type}`) 2. Read DB & Calculate Next Number 3. Update DB with **Optimistic Lock** Check (ใช้ `@VersionColumn()`) 4. Release Redis Lock 5. Retry on Failure ด้วย exponential backoff
    - [ ] Fallback mechanism เมื่อการขอเลขล้มเหลว
    - [ ] Format ตาม Template: {ORG_CODE}-{TYPE_CODE}-{YEAR_SHORT}-{SEQ:4}
  - **ไม่มี Controller** (Internal Service เท่านั้น)
  - [ ] **Security:** Implement audit log ทุกครั้งที่มีการ generate เลขที่
  - [ ] **Deliverable:** Service สร้างเลขที่เอกสารได้ถูกต้องและปลอดภัย ไม่มี Race Condition
  - [ ] **Dependencies:** T1.1, T0.3

* **[ ] T2.3 DocumentNumberingModule - Token-Based & Double-Lock** (Updated)
  - [ ] Update Entity: `DocumentNumberCounter` (Add `discipline_id` to PK)
  - [ ] Implement Token Parser & Replacer Logic (`{DISCIPLINE}`, `{SUBTYPE_NUM}`)
  - [ ] Update `generateNextNumber` to handle optional keys (Discipline/SubType)
  - [ ] **Deliverable:** Flexible Numbering System

- **[ ] T2.4 SecurityModule - Enhanced Security**

  - [ ] สร้าง Input Validation Service:
    - [ ] XSS Prevention
    - [ ] SQL Injection Prevention
    - [ ] CSRF Protection
  - [ ] สร้าง RateLimitGuard:
    - [ ] Implement rate limiting ตาม strategy (anonymous: 100/hr, authenticated: 500-5000/hr)
    - [ ] Different limits สำหรับ endpoints ต่างๆ
  - [ ] สร้าง Security Headers Middleware
  - [ ] **Security:** Implement content security policy (CSP)
  - [ ] **Deliverable:** Security layers ทำงานได้
  - [ ] **Dependencies:** T1.1

- **[ ] T2.5 JSON Details & Schema Management**

  - [ ] T2.5.1 JsonSchemaModule - Schema Management: สร้าง Service สำหรับ Validate, get, register JSON schemas
  - [ ] T2.5.2 DetailsService - Data Processing: สร้าง Service สำหรับ sanitize, transform, compress/decompress JSON
  - [ ] T2.5.3 JSON Security & Validation: Implement security checks และ validation rules
  - [ ] **Deliverable:** JSON schema system ทำงานได้
  - [ ] **Dependencies:** T1.1

### 🚀 **T2.5 JSON Details & Schema Management - Enhanced Implementation Plan**

#### 📋 **Overview**

สร้างระบบจัดการ JSON Schema ที่ครอบคลุมสำหรับ dynamic document details, validation, transformation และ performance optimization

---

#### 🎯 **Enhanced Task Breakdown for T2.5**

##### **[ ] T2.5.1 JSON Schema Registry & Versioning System**

- [ ] **Schema Entity Design** สำหรับเก็บ JSON schemas ทุกประเภท
- [ ] **Version Control System** สำหรับ schema evolution
- [ ] **Migration Strategy** สำหรับ backward-compatible changes
- [ ] **Schema Inheritance** สำหรับ shared field definitions

```typescript
// Schema Entity Design
@Entity()
export class JsonSchema {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  name: string; // 'CORRESPONDENCE_GENERIC', 'RFA_DWG', 'CIRCULATION_INTERNAL'

  @Column()
  entity_type: string; // 'correspondence', 'rfa', 'circulation'

  @Column()
  version: number;

  @Column('json')
  schema_definition: any; // AJV JSON Schema

  @Column('json')
  ui_schema: any; // UI configuration for form generation

  @Column({ default: true })
  is_active: boolean;

  @Column('json', { nullable: true })
  migration_script: any; // Data transformation rules

  @CreateDateColumn()
  created_at: Date;

  @UpdateDateColumn()
  updated_at: Date;

  // Virtual columns configuration for performance
  @Column('json', { nullable: true })
  virtual_columns: VirtualColumnConfig[];
}

interface VirtualColumnConfig {
  json_path: string; // '$.projectId'
  column_name: string; // 'ref_project_id'
  data_type: 'INT' | 'VARCHAR' | 'BOOLEAN' | 'DATE';
  index_type?: 'INDEX' | 'UNIQUE' | 'FULLTEXT';
  is_required: boolean;
}
```

##### **[ ] T2.5.2 Schema Validation & Transformation Engine**

- [ ] **AJV Integration** สำหรับ high-performance JSON validation
- [ ] **Custom Validators** สำหรับ business rule validation
- [ ] **Data Transformation** สำหรับ schema version migration
- [ ] **Sanitization Service** สำหรับ data cleansing

```typescript
@Injectable()
export class JsonSchemaService {
  private ajv: Ajv;

  constructor() {
    this.ajv = new Ajv({
      allErrors: true,
      coerceTypes: true,
      useDefaults: true,
      removeAdditional: true,
      formats: {
        'date-time': true,
        email: true,
        uri: true,
        'document-number': this.documentNumberFormat,
      },
    });

    // Register custom formats and keywords
    this.registerCustomValidators();
  }

  async validateData(
    schemaName: string,
    data: any,
    options: ValidationOptions = {}
  ): Promise<ValidationResult> {
    const schema = await this.getSchema(schemaName);
    const validate = this.ajv.compile(schema);

    const isValid = validate(data);

    if (!isValid) {
      return {
        isValid: false,
        errors: validate.errors,
        sanitizedData: null,
      };
    }

    // Apply data transformation if needed
    const sanitizedData = await this.sanitizeData(data, schema, options);

    return {
      isValid: true,
      errors: [],
      sanitizedData,
    };
  }

  private async sanitizeData(
    data: any,
    schema: any,
    options: ValidationOptions
  ): Promise<any> {
    const sanitized = { ...data };

    // Remove unknown properties if not allowed
    if (options.removeAdditional !== false) {
      const allowedProperties = this.extractPropertyNames(schema);
      Object.keys(sanitized).forEach((key) => {
        if (!allowedProperties.includes(key)) {
          delete sanitized[key];
        }
      });
    }

    // Apply custom sanitizers based on field type
    await this.applyFieldSanitizers(sanitized, schema);

    return sanitized;
  }

  private registerCustomValidators(): void {
    // Custom format for document numbers
    this.ajv.addFormat('document-number', {
      type: 'string',
      validate: (value: string) => {
        return /^[A-Z]{3,5}-[A-Z]{2,4}-\d{4}-\d{3,5}$/.test(value);
      },
    });

    // Custom keyword for role-based access
    this.ajv.addKeyword({
      keyword: 'requiredRole',
      type: 'string',
      compile: (requiredRole: string) => {
        return (data: any, dataPath: string, parentData: any) => {
          // Check if user has required role for this field
          const userContext = this.getUserContext();
          return userContext.roles.includes(requiredRole);
        };
      },
    });
  }
}
```

##### **[ ] T2.5.3 Virtual Columns & Performance Optimization**

- [ ] **Virtual Column Generator** สำหรับ JSON field indexing
- [ ] **Migration Scripts** สำหรับสร้าง generated columns
- [ ] **Query Optimizer** สำหรับใช้ virtual columns ใน search
- [ ] **Performance Monitoring** สำหรับ JSON query performance

```typescript
@Injectable()
export class VirtualColumnService {
  constructor(
    private dataSource: DataSource,
    private configService: ConfigService
  ) {}

  async setupVirtualColumns(
    tableName: string,
    schemaConfig: VirtualColumnConfig[]
  ): Promise<void> {
    const connection = this.dataSource.manager.connection;

    for (const config of schemaConfig) {
      await this.createVirtualColumn(tableName, config);
    }
  }

  private async createVirtualColumn(
    tableName: string,
    config: VirtualColumnConfig
  ): Promise<void> {
    const columnDefinition = this.generateColumnDefinition(config);

    const sql = `
      ALTER TABLE ${tableName}
      ADD COLUMN ${config.column_name} ${columnDefinition}
    `;

    await this.dataSource.query(sql);

    // Create index if specified
    if (config.index_type) {
      await this.createIndex(tableName, config);
    }
  }

  private generateColumnDefinition(config: VirtualColumnConfig): string {
    const dataType = this.mapDataType(config.data_type);
    const jsonPath = this.escapeJsonPath(config.json_path);

    return `${dataType} GENERATED ALWAYS AS (JSON_UNQUOTE(JSON_EXTRACT(details, '${jsonPath}'))) VIRTUAL`;
  }

  private async createIndex(
    tableName: string,
    config: VirtualColumnConfig
  ): Promise<void> {
    const indexName = `idx_${tableName}_${config.column_name}`;
    const sql = `
      CREATE ${config.index_type} INDEX ${indexName}
      ON ${tableName} (${config.column_name})
    `;

    await this.dataSource.query(sql);
  }
}

// Example virtual column configuration for correspondence
const correspondenceVirtualColumns: VirtualColumnConfig[] = [
  {
    json_path: '$.projectId',
    column_name: 'ref_project_id',
    data_type: 'INT',
    index_type: 'INDEX',
    is_required: true,
  },
  {
    json_path: '$.priority',
    column_name: 'ref_priority',
    data_type: 'VARCHAR',
    index_type: 'INDEX',
    is_required: false,
  },
  {
    json_path: '$.dueDate',
    column_name: 'ref_due_date',
    data_type: 'DATE',
    index_type: 'INDEX',
    is_required: false,
  },
];
```

##### **[ ] T2.5.4 Dynamic Form Schema Management**

- [ ] **UI Schema Definition** สำหรับ frontend form generation
- [ ] **Field Dependency System** สำหรับ conditional fields
- [ ] **Validation Rule Sync** ระหว่าง backend-frontend
- [ ] **Form Template Registry** สำหรับ reusable form patterns

```typescript
interface UiSchema {
  type: 'object';
  properties: {
    [key: string]: UiSchemaField;
  };
  required?: string[];
  layout?: {
    type: 'tabs' | 'sections' | 'steps';
    groups: LayoutGroup[];
  };
}

interface UiSchemaField {
  type: 'string' | 'number' | 'boolean' | 'array' | 'object';
  widget?: 'text' | 'textarea' | 'select' | 'radio' | 'checkbox' | 'date';
  title: string;
  description?: string;
  placeholder?: string;
  enum?: string[];
  enumNames?: string[];
  dependencies?: FieldDependency[];
  conditions?: FieldCondition[];
  properties?: { [key: string]: UiSchemaField }; // for nested objects
  items?: UiSchemaField; // for arrays
}

interface FieldDependency {
  field: string;
  condition: {
    operator: 'equals' | 'notEquals' | 'contains' | 'greaterThan';
    value: any;
  };
  actions: {
    visibility?: boolean;
    required?: boolean;
    options?: string[];
  };
}

// Example: RFA Drawing Schema
const rfaDwgSchema: UiSchema = {
  type: 'object',
  layout: {
    type: 'tabs',
    groups: [
      {
        title: 'Basic Information',
        fields: ['title', 'description', 'discipline'],
      },
      {
        title: 'Drawing Details',
        fields: ['drawingReferences', 'revision', 'approvalType'],
      },
      {
        title: 'Technical Specifications',
        fields: ['materials', 'dimensions', 'tolerances'],
      },
    ],
  },
  properties: {
    title: {
      type: 'string',
      widget: 'text',
      title: 'Drawing Title',
      placeholder: 'Enter drawing title...',
      required: true,
    },
    discipline: {
      type: 'string',
      widget: 'select',
      title: 'Discipline',
      enum: ['CIVIL', 'STRUCTURAL', 'MECHANICAL', 'ELECTRICAL', 'PLUMBING'],
      enumNames: [
        'Civil',
        'Structural',
        'Mechanical',
        'Electrical',
        'Plumbing',
      ],
    },
    drawingReferences: {
      type: 'array',
      title: 'Related Contract Drawings',
      items: {
        type: 'string',
        widget: 'select',
        title: 'Drawing Number',
      },
    },
    approvalType: {
      type: 'string',
      widget: 'radio',
      title: 'Approval Type',
      enum: ['FULL_APPROVAL', 'PARTIAL_APPROVAL', 'COMMENTS_ONLY'],
      enumNames: ['Full Approval', 'Partial Approval', 'Comments Only'],
    },
  },
  required: ['title', 'discipline', 'approvalType'],
};
```

##### **[ ] T2.5.5 Data Migration & Version Compatibility**

- [ ] **Schema Migration Service** สำหรับอัพเกรด data ระหว่าง versions
- [ ] **Data Transformation Pipeline** สำหรับ backward compatibility
- [ ] **Version Rollback Mechanism** สำหรับ emergency situations
- [ ] **Migration Testing Framework** สำหรับ 确保 data integrity

```typescript
@Injectable()
export class SchemaMigrationService {
  async migrateData(
    entityType: string,
    entityId: string,
    targetVersion: number
  ): Promise<MigrationResult> {
    const currentData = await this.getCurrentData(entityType, entityId);
    const currentVersion = await this.getCurrentSchemaVersion(
      entityType,
      entityId
    );

    const migrationPath = await this.findMigrationPath(
      currentVersion,
      targetVersion
    );

    let migratedData = currentData;

    for (const migrationStep of migrationPath) {
      migratedData = await this.applyMigrationStep(migrationStep, migratedData);
    }

    // Validate migrated data against target schema
    const validationResult = await this.validateAgainstSchema(
      migratedData,
      targetVersion
    );

    if (!validationResult.isValid) {
      throw new MigrationError(
        'MIGRATION_VALIDATION_FAILED',
        validationResult.errors
      );
    }

    await this.saveMigratedData(
      entityType,
      entityId,
      migratedData,
      targetVersion
    );

    return {
      success: true,
      fromVersion: currentVersion,
      toVersion: targetVersion,
      migratedFields: this.getMigratedFields(currentData, migratedData),
    };
  }

  private async applyMigrationStep(
    step: MigrationStep,
    data: any
  ): Promise<any> {
    switch (step.type) {
      case 'FIELD_RENAME':
        return this.renameField(data, step.config);
      case 'FIELD_TRANSFORM':
        return this.transformField(data, step.config);
      case 'FIELD_ADD':
        return this.addField(data, step.config);
      case 'FIELD_REMOVE':
        return this.removeField(data, step.config);
      case 'STRUCTURE_CHANGE':
        return this.restructureData(data, step.config);
      default:
        throw new MigrationError('UNKNOWN_MIGRATION_TYPE');
    }
  }
}

// Example migration configuration
const migrationSteps = [
  {
    from_version: 1,
    to_version: 2,
    type: 'FIELD_RENAME',
    config: {
      old_field: 'project_id',
      new_field: 'ref_project_id',
    },
  },
  {
    from_version: 2,
    to_version: 3,
    type: 'FIELD_TRANSFORM',
    config: {
      field: 'priority',
      transform: 'MAP_VALUES',
      mapping: {
        HIGH: 'URGENT',
        MEDIUM: 'NORMAL',
        LOW: 'LOW',
      },
    },
  },
];
```

##### **[ ] T2.5.6 Security & Access Control for JSON Data**

- [ ] **Field-level Security** 基于 user roles
- [ ] **Data Encryption** สำหรับ sensitive fields
- [ ] **Audit Logging** สำหรับ JSON data changes
- [ ] **Input Sanitization** สำหรับป้องกัน XSS และ injection

```typescript
@Injectable()
export class JsonSecurityService {
  async applyFieldLevelSecurity(
    data: any,
    schema: any,
    userContext: UserContext
  ): Promise<any> {
    const securedData = { ...data };
    const securityRules = await this.getSecurityRules(schema.name);

    for (const [fieldPath, fieldConfig] of Object.entries(schema.properties)) {
      const fieldRules = securityRules[fieldPath];

      if (fieldRules && !this.hasFieldAccess(fieldRules, userContext)) {
        // Remove or mask field based on security rules
        if (fieldRules.on_deny === 'REMOVE') {
          this.deleteField(securedData, fieldPath);
        } else if (fieldRules.on_deny === 'MASK') {
          this.maskField(securedData, fieldPath, fieldRules.mask_pattern);
        }
      }
    }

    return securedData;
  }

  async encryptSensitiveFields(data: any, schema: any): Promise<any> {
    const encryptedData = { ...data };
    const sensitiveFields = this.getSensitiveFields(schema);

    for (const fieldPath of sensitiveFields) {
      const fieldValue = this.getFieldValue(data, fieldPath);
      if (fieldValue) {
        const encrypted = await this.cryptoService.encrypt(
          fieldValue,
          'field-level'
        );
        this.setFieldValue(encryptedData, fieldPath, encrypted);
      }
    }

    return encryptedData;
  }

  private getSensitiveFields(schema: any): string[] {
    const sensitiveFields: string[] = [];

    const traverseSchema = (obj: any, path: string = '') => {
      if (obj.properties) {
        for (const [key, value] of Object.entries(obj.properties)) {
          const currentPath = path ? `${path}.${key}` : key;

          if (value.sensitive) {
            sensitiveFields.push(currentPath);
          }

          if (value.properties || value.items) {
            traverseSchema(value, currentPath);
          }
        }
      }
    };

    traverseSchema(schema);
    return sensitiveFields;
  }
}
```

##### **[ ] T2.5.7 API Design & Integration**

- [ ] **Schema Management API** สำหรับ CRUD operations
- [ ] **Validation API** สำหรับ validate data against schemas
- [ ] **Migration API** สำหรับ manage data migrations
- [ ] **Integration Hooks** สำหรับ other modules

```typescript
@Controller('json-schema')
export class JsonSchemaController {
  @Post('validate/:schemaName')
  @RequirePermission('schema.validate')
  async validateData(
    @Param('schemaName') schemaName: string,
    @Body() dto: ValidateDataDto
  ): Promise<ValidationResult> {
    return this.jsonSchemaService.validateData(
      schemaName,
      dto.data,
      dto.options
    );
  }

  @Post('schemas')
  @RequirePermission('schema.manage')
  async createSchema(@Body() dto: CreateSchemaDto): Promise<JsonSchema> {
    return this.jsonSchemaService.createSchema(dto);
  }

  @Post('migrate/:entityType/:entityId')
  @RequirePermission('data.migrate')
  async migrateData(
    @Param('entityType') entityType: string,
    @Param('entityId') entityId: string,
    @Body() dto: MigrateDataDto
  ): Promise<MigrationResult> {
    return this.migrationService.migrateData(
      entityType,
      entityId,
      dto.targetVersion
    );
  }

  @Get('ui-schema/:schemaName')
  @RequirePermission('schema.view')
  async getUiSchema(
    @Param('schemaName') schemaName: string
  ): Promise<UiSchema> {
    return this.schemaService.getUiSchema(schemaName);
  }
}
```

### **[ ] T2.5.8 Integration with Document Modules**

- [ ] **Correspondence Module Integration**
- [ ] **RFA Module Integration**
- [ ] **Circulation Module Integration**
- [ ] **Drawing Module Integration**

```typescript
// Example: Correspondence Service Integration
@Injectable()
export class CorrespondenceService {
  constructor(
    private jsonSchemaService: JsonSchemaService,
    private detailsService: DetailsService
  ) {}

  async createCorrespondence(
    dto: CreateCorrespondenceDto
  ): Promise<Correspondence> {
    // 1. Validate details against schema
    const validationResult = await this.jsonSchemaService.validateData(
      `CORRESPONDENCE_${dto.type}`,
      dto.details
    );

    if (!validationResult.isValid) {
      throw new ValidationError('INVALID_DETAILS', validationResult.errors);
    }

    // 2. Apply security and sanitization
    const secureDetails = await this.detailsService.sanitizeDetails(
      validationResult.sanitizedData,
      dto.type
    );

    // 3. Create correspondence entity
    const correspondence = this.correspondenceRepository.create({
      ...dto,
      details: secureDetails,
      schema_version: await this.getCurrentSchemaVersion(
        `CORRESPONDENCE_${dto.type}`
      ),
    });

    // 4. Setup virtual columns for performance
    await this.setupVirtualColumns(correspondence);

    return this.correspondenceRepository.save(correspondence);
  }

  async searchCorrespondences(
    filters: SearchFilters
  ): Promise<Correspondence[]> {
    // Use virtual columns for efficient filtering
    const query = this.correspondenceRepository.createQueryBuilder('c');

    if (filters.projectId) {
      query.andWhere('c.ref_project_id = :projectId', {
        projectId: filters.projectId,
      });
    }

    if (filters.priority) {
      query.andWhere('c.ref_priority = :priority', {
        priority: filters.priority,
      });
    }

    return query.getMany();
  }
}
```

##### **[ ] T2.5.9 Testing Strategy**

- [ ] **Unit Tests** สำหรับ schema validation และ transformation
- [ ] **Integration Tests** สำหรับ end-to-end data flow
- [ ] **Performance Tests** สำหรับ virtual columns และ large datasets
- [ ] **Security Tests** สำหรับ field-level security

```typescript
describe('JsonSchemaService', () => {
  describe('validateData', () => {
    it('should validate correct RFA_DWG data successfully', async () => {
      const testData = {
        title: 'Structural Beam Details',
        discipline: 'STRUCTURAL',
        drawingReferences: ['CD-STR-001', 'CD-STR-002'],
        approvalType: 'FULL_APPROVAL',
        materials: ['STEEL_A36', 'CONCRETE_40MPA'],
      };

      const result = await jsonSchemaService.validateData('RFA_DWG', testData);

      expect(result.isValid).toBe(true);
      expect(result.errors).toHaveLength(0);
    });

    it('should reject invalid discipline value', async () => {
      const testData = {
        title: 'Test Drawing',
        discipline: 'INVALID_DISCIPLINE', // Not in enum
        approvalType: 'FULL_APPROVAL',
      };

      const result = await jsonSchemaService.validateData('RFA_DWG', testData);

      expect(result.isValid).toBe(false);
      expect(result.errors[0].message).toContain('discipline');
    });
  });
});

describe('VirtualColumnService', () => {
  it('should improve search performance with virtual columns', async () => {
    // Create test data with JSON details
    await createTestCorrespondences(1000);

    // Search without virtual column (JSON_EXTRACT)
    const startTime1 = Date.now();
    const result1 = await correspondenceRepository
      .createQueryBuilder('c')
      .where("JSON_EXTRACT(c.details, '$.projectId') = :projectId", {
        projectId: 123,
      })
      .getMany();
    const time1 = Date.now() - startTime1;

    // Search with virtual column
    const startTime2 = Date.now();
    const result2 = await correspondenceRepository
      .createQueryBuilder('c')
      .where('c.ref_project_id = :projectId', { projectId: 123 })
      .getMany();
    const time2 = Date.now() - startTime2;

    expect(time2).toBeLessThan(time1 * 0.5); // At least 2x faster
    expect(result1.length).toEqual(result2.length);
  });
});
```

#### 🔗 **Critical Dependencies**

- **T1.1** (Common Module) - สำหรับ base entities และ shared services
- **T1.4** (RBAC Guard) - สำหรับ field-level security
- **T0.3** (Database) - สำหรับ virtual columns implementation
- **T3.2** (Correspondence) - สำหรับ integration testing

#### 🎯 **Success Metrics**

- ✅ JSON validation performance: < 10ms ต่อ request
- ✅ Virtual columns improve search performance 5x+
- ✅ Support schema evolution without data loss
- ✅ Field-level security enforced across all modules
- ✅ 100% test coverage สำหรับ core validation logic

* **[ ] T2.6 MasterModule - Advanced Data (Req 6B)** (New)
  - [ ] Update Entities: `Discipline`, `CorrespondenceSubType`
  - [ ] Create Services/Controllers for CRUD Operations (Admin Panel Support)
  - [ ] Implement Seeding Logic for initial 6B data
  - [ ] **Deliverable:** API for managing Disciplines and Sub-types
  - [ ] **Dependencies:** T1.1, T0.3

---

## **Phase 3: Unified Workflow Engine (สัปดาห์ที่ 5-6)**

**Milestone:** ระบบ Workflow กลางที่รองรับทั้ง Routing ปกติ และ RFA

### **Phase 3: Tasks**

- **[ ] T3.1 WorkflowEngineModule (New)**

  - [ ] ออกแบบ Generic Schema สำหรับ Workflow State Machine
  - [ ] Implement Service: `initializeWorkflow()`, `processAction()`, `getNextStep()`
  - [ ] รองรับ Logic การ "ข้ามขั้นตอน" และ "ส่งกลับ" ภายใน Engine เดียว
  - [ ] **Security:** Implement audit logging สำหรับ workflow actions
  - [ ] **Deliverable:** Unified Workflow Engine พร้อมใช้งาน
  - [ ] **Dependencies:** T1.1

- **[ ] T3.1.1 Workflow DSL Specification & Grammar**
  - [ ] Define EBNF Grammar สำหรับ Workflow DSL
  - [ ] Create YAML Schema สำหรับ human-friendly workflow definitions
  - [ ] Design JSON Schema สำหรับ compiled workflow representations

```yaml
# ตัวอย่าง DSL Structure

workflow: RFA_APPROVAL
version: 1.0
description: "RFA Approval Workflow with Parallel Reviews"

states:

- name: DRAFT
  initial: true
  metadata:
  color: "gray"
  icon: "draft"
  on:
  SUBMIT:
  to: TECHNICAL_REVIEW
  conditions: - expression: "user.hasRole('ENGINEER')"
  requirements: - role: "ENGINEER"
  events: - type: "notify"
  target: "reviewers"
  template: "NEW_RFA_SUBMITTED" - type: "assign"
  target: "technical_lead"

- name: TECHNICAL_REVIEW
  metadata:
  color: "blue"
  icon: "review"
  on:
  APPROVE:
  to: MANAGERIAL_REVIEW
  conditions: - expression: "user.department === context.document.department"
  REQUEST_CHANGES:
  to: DRAFT
  events: - type: "notify"
  target: "creator"
  template: "CHANGES_REQUESTED"
  ESCALATE:
  to: ESCALATED_REVIEW
  conditions: - expression: "document.priority === 'HIGH'"

- name: PARALLEL_APPROVAL
  parallel: true
  branches:

  - MANAGERIAL_REVIEW
  - FINANCIAL_REVIEW
    on:
    ALL_APPROVED:
    to: APPROVED
    ANY_REJECTED:
    to: REJECTED

- name: APPROVED
  terminal: true
  metadata:
  color: "green"
  icon: "approved"
  Versioning Strategy สำหรับ workflow definitions
```

- **[ ] T3.1.2 Workflow Core Entities & Database Schema**

  - [ ] WorkflowDefinition Entity
  - [ ] WorkflowInstance Entity
  - [ ] WorkflowHistory Entity
  - [ ] WorkflowTransition Entity

```typescript
// Core Entities Design
@Entity()
export class WorkflowDefinition {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  name: string;

  @Column()
  version: number;

  @Column('json')
  dsl_raw: any; // YAML/JSON DSL

  @Column('json')
  compiled_schema: any; // Normalized JSON

  @Column({ default: true })
  is_active: boolean;

  @CreateDateColumn()
  created_at: Date;

  @VersionColumn()
  version: number;
}

@Entity()
export class WorkflowInstance {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @ManyToOne(() => WorkflowDefinition)
  definition: WorkflowDefinition;

  @Column()
  entity_type: string; // 'correspondence', 'rfa', 'circulation'

  @Column()
  entity_id: string;

  @Column()
  current_state: string;

  @Column('json')
  context: any; // Workflow-specific data

  @Column('json')
  history: any[]; // State transition history

  @CreateDateColumn()
  created_at: Date;

  @UpdateDateColumn()
  updated_at: Date;
}
```

- **[ ] T3.1.3 DSL Parser & Compiler Service**

  - [ ] YAML Parser สำหรับอ่าน DSL definitions
  - [ ] Syntax Validator สำหรับ compile-time validation
  - [ ] Schema Compiler สำหรับแปลง DSL → Normalized JSON
  - [ ] Version Migration สำหรับอัพเกรด workflow definitions

```typescript
@Injectable()
export class WorkflowDslService {
  async parseAndValidate(dslContent: string): Promise<CompiledWorkflow> {
    // 1. Parse YAML
    const rawDefinition = yaml.parse(dslContent);

    // 2. Validate Syntax
    await this.validateSyntax(rawDefinition);

    // 3. Compile to Normalized JSON
    const compiled = await this.compileDefinition(rawDefinition);

    // 4. Validate Business Rules
    await this.validateBusinessRules(compiled);

    return compiled;
  }

  private async validateSyntax(definition: any): Promise<void> {
    const rules = [
      // ต้องมีอย่างน้อย 1 initial state
      () => definition.states.some((s) => s.initial),
      // Terminal states ต้องไม่มี transitions
      () => !definition.states.filter((s) => s.terminal).some((s) => s.on),
      // State names must be unique
      () =>
        new Set(definition.states.map((s) => s.name)).size ===
        definition.states.length,
      // Transition targets must exist
      () => this.validateTransitionTargets(definition),
    ];

    for (const rule of rules) {
      if (!rule()) {
        throw new WorkflowValidationError('DSL_VALIDATION_FAILED');
      }
    }
  }
}
```

- **[ ] T3.1.4 Workflow Runtime Engine**
  - [ ] State Machine Engine สำหรับจัดการ state transitions
  - [ ] Condition Evaluator สำหรับประเมิน conditional transitions
  - [ ] Permission Checker สำหรับตรวจสอบสิทธิ์ในการเปลี่ยนสถานะ
  - [ ] Event Dispatcher สำหรับจัดการ workflow events

```typescript
****@Injectable()
export class WorkflowEngineService {
  async processTransition(
    instanceId: string,
    action: string,
    context: WorkflowContext
  ): Promise<TransitionResult> {
    // 1. Load Workflow Instance
    const instance = await this.findInstance(instanceId);
    const definition = await this.getCompiledDefinition(instance.definition_id);

    // 2. Validate Current State & Action
    const currentState = definition.states[instance.current_state];
    const transition = currentState.transitions[action];

    if (!transition) {
      throw new WorkflowError('INVALID_TRANSITION');
    }

    // 3. Check Permissions & Conditions
    await this.validatePermissions(transition, context);
    await this.validateConditions(transition, context);

    // 4. Execute Pre-Transition Hooks
    await this.executeHooks('pre_transition', instance, transition, context);

    // 5. Perform State Transition
    const previousState = instance.current_state;
    instance.current_state = transition.to;

    // 6. Record History
    await this.recordTransitionHistory(instance, {
      from: previousState,
      to: transition.to,
      action,
      user: context.userId,
      timestamp: new Date(),
      metadata: context.metadata
    });

    // 7. Execute Post-Transition Events
    await this.executeEvents(transition.events, instance, context);

    // 8. Execute Post-Transition Hooks
    await this.executeHooks('post_transition', instance, transition, context);

    // 9. Save Instance
    await this.saveInstance(instance);

    return {
      success: true,
      previousState,
      newState: transition.to,
      instanceId: instance.id
    };
  }

  async getAvailableActions(
    instanceId: string,
    context: WorkflowContext
  ): Promise<string[]> {
    const instance = await this.findInstance(instanceId);
    const definition = await this.getCompiledDefinition(instance.definition_id);
    const currentState = definition.states[instance.current_state];

    return Object.keys(currentState.transitions).filter(action => {
      const transition = currentState.transitions[action];
      return this.isActionAvailable(transition, context);
    });
  }
}
```

- **[ ] T3.1.5 Advanced Feature Implementation**
  - [ ] Parallel Approval Flows สำหรับ multi-department approvals
  - [ ] Conditional Transitions ด้วย expression evaluation
  - [ ] Timeout & Escalation สำหรับขั้นตอนที่เกินกำหนด
  - [ ] Rollback & Compensation สำหรับย้อนกลับสถานะ

```typescript
// Parallel Workflow Support
interface ParallelState {
  parallel: true;
  branches: string[];
  completion_policy: 'ALL' | 'ANY' | 'MAJORITY';
  on: {
    [completionType: string]: {
      to: string;
      conditions?: Condition[];
    };
  };
}

// Conditional Transition Support
interface ConditionalTransition {
  to: string;
  conditions: Array<{
    expression: string; // "user.role === 'MANAGER' && document.value > 10000"
    evaluator?: 'javascript' | 'jsonlogic';
  }>;
  requirements?: PermissionRequirement[];
}

// Timeout & Escalation
interface StateWithTimeout {
  timeout_seconds: number;
  on_timeout: {
    action: string;
    escalate_to?: string;
    notify?: string[];
  };
}
```

- **[ ] T3.1.6 Event System & Integration**
  - [ ] Event Types (notify, assign, webhook, auto_action)
  - [ ] Template Engine สำหรับ dynamic messages
  - [ ] Webhook Support สำหรับ external integrations
  - [ ] Notification Service Integration

```typescript
@Injectable()
export class WorkflowEventService {
  async executeEvents(
    events: WorkflowEvent[],
    instance: WorkflowInstance,
    context: WorkflowContext
  ): Promise<void> {
    for (const event of events) {
      switch (event.type) {
        case 'notify':
          await this.handleNotifyEvent(event, instance, context);
          break;
        case 'assign':
          await this.handleAssignEvent(event, instance, context);
          break;
        case 'webhook':
          await this.handleWebhookEvent(event, instance, context);
          break;
        case 'auto_action':
          await this.handleAutoActionEvent(event, instance, context);
          break;
      }
    }
  }

  private async handleNotifyEvent(
    event: NotifyEvent,
    instance: WorkflowInstance,
    context: WorkflowContext
  ): Promise<void> {
    const recipients = await this.resolveRecipients(
      event.target,
      instance,
      context
    );
    const message = await this.renderTemplate(
      event.template,
      instance,
      context
    );

    await this.notificationService.send({
      type: 'workflow',
      recipients,
      subject: message.subject,
      body: message.body,
      metadata: {
        workflow_instance_id: instance.id,
        state: instance.current_state,
        action: context.action,
      },
    });
  }
}
```

- **[ ] T3.1.7 API Design & Controllers**
  - [ ] REST API Endpoints สำหรับ workflow management
  - [ ] WebSocket Support สำหรับ real-time updates
  - [ ] Admin API สำหรับ workflow definition management
  - [ ] Integration Hooks สำหรับ external systems

```typescript
@Controller('workflow')
export class WorkflowEngineController {
  @Post('instances/:id/transition')
  @RequirePermission('workflow.execute')
  async processTransition(
    @Param('id') instanceId: string,
    @Body() dto: WorkflowTransitionDto
  ): Promise<TransitionResult> {
    return this.workflowEngine.processTransition(
      instanceId,
      dto.action,
      dto.context
    );
  }

  @Get('instances/:id/actions')
  @RequirePermission('workflow.view')
  async getAvailableActions(
    @Param('id') instanceId: string,
    @Query() context: WorkflowContext
  ): Promise<string[]> {
    return this.workflowEngine.getAvailableActions(instanceId, context);
  }

  @Post('definitions')
  @RequirePermission('workflow.manage')
  async createWorkflowDefinition(
    @Body() dto: CreateWorkflowDefinitionDto
  ): Promise<WorkflowDefinition> {
    return this.workflowDslService.compileAndSave(dto.dslContent);
  }

  @Get('instances/:id/history')
  @RequirePermission('workflow.view')
  async getWorkflowHistory(
    @Param('id') instanceId: string
  ): Promise<WorkflowHistory[]> {
    return this.workflowHistoryService.getHistory(instanceId);
  }
}
```

- **[ ] T3.1.8 Integration with Existing Modules**
  - [ ] Correspondence Module Integration
  - [ ] RFA Module Integration
  - [ ] Circulation Module Integration
  - [ ] Notification Module Integration

```typescript
// Correspondence Integration Example
@Injectable()
export class CorrespondenceWorkflowService {
  constructor(
    private workflowEngine: WorkflowEngineService,
    private correspondenceService: CorrespondenceService
  ) {}

  async submitCorrespondence(
    correspondenceId: string,
    userId: string
  ): Promise<void> {
    const correspondence = await this.correspondenceService.findById(
      correspondenceId
    );

    // Create workflow instance
    const instance = await this.workflowEngine.createInstance({
      definition: 'CORRESPONDENCE_ROUTING',
      entity_type: 'correspondence',
      entity_id: correspondenceId,
      context: {
        document: correspondence,
        user: userId,
      },
    });

    // Process initial transition
    await this.workflowEngine.processTransition(instance.id, 'SUBMIT', {
      userId,
      metadata: { correspondenceId },
    });
  }
}
```

- **[ ] T3.1.9 Testing Strategy**
  - [ ] Unit Tests สำหรับ DSL parser และ state machine
  - [ ] Integration Tests สำหรับ end-to-end workflow execution
  - [ ] Performance Tests สำหรับ high-concurrency scenarios
  - [ ] Security Tests สำหรับ permission validation.

```typescript
describe('WorkflowEngineService', () => {
  describe('processTransition', () => {
    it('should successfully transition state with valid permissions', async () => {
      // Arrange
      const instance = await createTestInstance();
      const context = { userId: 'user1', roles: ['APPROVER'] };

      // Act
      const result = await workflowEngine.processTransition(
        instance.id,
        'APPROVE',
        context
      );

      // Assert
      expect(result.success).toBe(true);
      expect(result.newState).toBe('APPROVED');
    });

    it('should reject transition without required permissions', async () => {
      // Arrange
      const instance = await createTestInstance();
      const context = { userId: 'user2', roles: ['VIEWER'] };

      // Act & Assert
      await expect(
        workflowEngine.processTransition(instance.id, 'APPROVE', context)
      ).rejects.toThrow(WorkflowError);
    });
  });
});
```

- **🔗 Critical Dependencies of T3.1.1-T3.1.8**

  - T1.1 (Common Module) - สำหรับ base entities และ shared services
  - T1.4 (RBAC Guard) - สำหรับ permission checking
  - T2.5 (JSON Schema) - สำหรับ DSL validation
  - T6.2 (Notification) - สำหรับ event handling

- **🎯 Success Metrics**

  - ✅ Support ทั้ง Correspondence Routing และ RFA Workflow
  - ✅ DSL ที่ human-readable และ editable โดยไม่ต้องแก้โค้ด
  - ✅ Performance: < 50ms ต่อ state transition
  - ✅ 100% test coverage สำหรับ core workflow logic
  - ✅ Complete audit trail สำหรับทุก workflow instance

- **[ ] T3.2 CorrespondenceModule - Basic CRUD**

  - [ ] สร้าง Entities (Correspondence, Revision, Recipient, Tag, Reference, Attachment)
  - [ ] สร้าง CorrespondenceService (Create with Document Numbering, Update with new Revision, Soft Delete)
  - [ ] สร้าง Controllers (POST/GET/PUT/DELETE /correspondences)
  - [ ] Implement Impersonation Logic: ตรวจสอบ originatorId ใน DTO หากมีการส่งมา ต้องเช็คว่า User ปัจจุบันมีสิทธิ์กระทำการแทนหรือไม่ (Superadmin)
  - [ ] **Security:** Implement permission checks สำหรับ document access
  - [ ] **Deliverable:** สร้าง/แก้ไข/ดูเอกสารได้
  - [ ] **Dependencies:** T1.1, T1.2, T1.3, T1.4, T1.5, T2.3, T2.2, T2.5

- **[ ] T3.3 CorrespondenceModule - Advanced Features**

  - [ ] Implement Status Transitions (DRAFT → SUBMITTED)
  - [ ] Implement References (Link Documents)
  - [ ] Implement Search (Basic)
  - [ ] **Security:** Implement state transition validation
  - [ ] **Deliverable:** Workflow พื้นฐานทำงานได้
  - [ ] **Dependencies:** T3.2

- **[ ] T3.4 Correspondence Integration with Workflow**

  - [ ] เชื่อมต่อ `CorrespondenceService` เข้ากับ `WorkflowEngineModule`
  - [ ] ย้าย Logic การ Routing เดิมมาใช้ Engine ใหม่
  - [ ] สร้าง API endpoints สำหรับ Frontend (Templates, Pending Tasks, Bulk Action)
  - [ ] **Security:** Implement permission checks สำหรับ workflow operations
  - [ ] **Deliverable:** ระบบส่งต่อเอกสารทำงานได้สมบูรณ์ด้วย Unified Engine
  - [ ] **Dependencies:** T3.1, T3.2

---

## **Phase 4: Drawing & Advanced Workflows (สัปดาห์ที่ 7-8)**

**Milestone:** การจัดการแบบและ RFA โดยใช้ Unified Engine

### **Phase 4: Tasks**

- **[ ] T4.1 DrawingModule - Contract Drawings**

  - [ ] สร้าง Entities (ContractDrawing, Volume, Category, SubCategory, Attachment)
  - [ ] สร้าง ContractDrawingService CRUD
  - [ ] สร้าง Controllers (GET/POST /drawings/contract)
  - [ ] **Security:** Implement access control สำหรับ contract drawings
  - [ ] **Deliverable:** จัดการ Contract Drawings ได้
  - [ ] **Dependencies:** T1.1, T1.2, T1.4, T1.5, T2.2

- **[ ] T4.2 DrawingModule - Shop Drawings**

  - [ ] สร้าง Entities (ShopDrawing, Revision, Main/SubCategory, ContractRef, RevisionAttachment)
  - [ ] สร้าง ShopDrawingService CRUD (รวมการสร้าง Revision)
  - [ ] สร้าง Controllers (GET/POST /drawings/shop, /drawings/shop/:id/revisions)
  - [ ] Link Shop Drawing Revision → Contract Drawings
  - [ ] **Security:** Implement virus scanning สำหรับ drawing files
  - [ ] **Deliverable:** จัดการ Shop Drawings และ Revisions ได้
  - [ ] **Dependencies:** T4.1

- **[ ] T5.1 RfaModule with Unified Workflow**

  - [ ] สร้าง Entities (Rfa, RfaRevision, RfaItem, RfaWorkflowTemplate/Step)
  - [ ] สร้าง RfaService (Create RFA, Link Shop Drawings)
  - [ ] Implement RFA Workflow โดยใช้ Configuration ของ `WorkflowEngineModule`
  - [ ] สร้าง Controllers (POST/GET /rfas, POST /rfas/:id/workflow/...)
  - [ ] **Resilience:** Implement circuit breaker สำหรับ notification services
  - [ ] **Deliverable:** RFA Workflow ทำงานได้ด้วย Unified Engine
  - [ ] **Dependencies:** T3.2, T4.2, T2.5, T6.2

---

## **Phase 5: Workflow Systems & Resilience (สัปดาห์ที่ 8-9)**

**Milestone:** ระบบ Workflow ทั้งหมดพร้อม Resilience Patterns

### **Phase 5: Tasks**

- **[ ] T5.2 CirculationModule - Internal Routing**

  - [ ] สร้าง Entities (Circulation, Template, Routing, Attachment)
  - [ ] สร้าง CirculationService (Create 1:1 with Correspondence, Assign User, Complete/Close Step)
  - [ ] สร้าง Controllers (POST/GET /circulations, POST /circulations/:id/steps/...)
  - [ ] **Resilience:** Implement retry mechanism สำหรับ assignment notifications
  - [ ] **Deliverable:** ใบเวียนภายในองค์กรทำงานได้
  - [ ] **Dependencies:** T3.2, T2.5, T6.2

- **[ ] T5.3 TransmittalModule - Document Forwarding**

  - [ ] สร้าง Entities (Transmittal, TransmittalItem)
  - [ ] สร้าง TransmittalService (Create Correspondence + Transmittal, Link Multiple Correspondences)
  - [ ] สร้าง Controllers (POST/GET /transmittals)
  - [ ] **Security:** Implement access control สำหรับ transmittal items
  - [ ] **Deliverable:** สร้าง Transmittal ได้
  - [ ] **Dependencies:** T3.2

---

## **Phase 6: Notification & Resilience (สัปดาห์ที่ 9)**

**Milestone:** ระบบแจ้งเตือนแบบ Digest และการจัดการข้อมูลขนาดใหญ่

### **Phase 6: Tasks**

- **[ ] T6.1 SearchModule - Elasticsearch Integration**

  - [ ] Setup Elasticsearch Container
  - [ ] สร้าง SearchService (index/update/delete documents, search)
  - [ ] Index ทุก Document Type
  - [ ] สร้าง Controllers (GET /search)
  - [ ] **Resilience:** Implement circuit breaker สำหรับ Elasticsearch
  - [ ] **Deliverable:** ค้นหาขั้นสูงทำงานได้
  - [ ] **Dependencies:** T3.2, T5.1, T4.2, T5.2, T5.3

- **[ ] T6.2 Notification Queue & Digest**

  - [ ] สร้าง NotificationService (sendEmail/Line/System)
  - [ ] **Producer:** Push Event ลง BullMQ Queue
  - [ ] **Consumer:** จัดกลุ่ม Notification (Digest Message) และส่งผ่าน Email/Line
  - [ ] Integrate กับ Workflow Events (แจ้ง Recipients, Assignees, Deadline)
  - [ ] สร้าง Controllers (GET /notifications, PUT /notifications/:id/read)
  - [ ] **Resilience:** Implement retry mechanism ด้วย exponential backoff
  - [ ] **Deliverable:** ระบบแจ้งเตือนทำงานได้แบบ Digest
  - [ ] **Dependencies:** T1.1, T6.4

- **[ ] T6.3 MonitoringModule - Observability**

  - [ ] สร้าง Health Check Controller (GET /health)
  - [ ] สร้าง Metrics Service (API response times, Error rates)
  - [ ] สร้าง Performance Interceptor (Track request duration)
  - [ ] สร้าง Logging Service (Structured logging)
  - [ ] **Deliverable:** Monitoring system ทำงานได้
  - [ ] **Dependencies:** T1.1

- **[ ] T6.4 ResilienceModule - Circuit Breaker & Retry**

  - [ ] สร้าง Circuit Breaker Service (@CircuitBreaker() decorator)
  - [ ] สร้าง Retry Service (@Retry() decorator)
  - [ ] สร้าง Fallback Strategies
  - [ ] Implement สำหรับ Email, LINE, Elasticsearch, Virus Scanning
  - [ ] **Deliverable:** Resilience patterns ทำงานได้
  - [ ] **Dependencies:** T1.1

- **[ ] T6.5 Data Partitioning Strategy**

  - [ ] ออกแบบ Table Partitioning สำหรับ `audit_logs` และ `notifications` (แบ่งตาม Range: Year)
  - [ ] เขียน Raw SQL Migration สำหรับสร้าง Partition Table
  - [ ] **Deliverable:** Database Performance และ Scalability ดีขึ้น
  - [ ] **Dependencies:** T0.3

---

## **Phase 7: Testing & Hardening (สัปดาห์ที่ 10-12)**

**Milestone:** ทดสอบความทนทานต่อ Race Condition, Security, และ Performance

### **Phase 7: Tasks**

- **[ ] T7.1 Concurrency Testing**

  - [ ] เขียน Test Scenarios ยิง Request ขอเลขที่เอกสารพร้อมกัน 100 Request (ต้องไม่ซ้ำและไม่ข้าม)
  - [ ] ทดสอบ Optimistic Lock ทำงานถูกต้องเมื่อ Redis ถูกปิด
  - [ ] ทดสอบ File Upload พร้อมกันหลายไฟล์
  - [ ] **Deliverable:** ระบบทนทานต่อ Concurrency Issues

- **[ ] T7.2 Transaction Integrity Testing**

  - [ ] ทดสอบ Upload ไฟล์แล้ว Kill Process ก่อน Commit
  - [ ] ทดสอบ Two-Phase File Storage ทำงานถูกต้อง
  - [ ] ทดสอบ Database Transaction Rollback Scenarios
  - [ ] **Deliverable:** Data Integrity รับประกันได้

- **[ ] T7.3 Security & Idempotency Test**

  - [ ] ทดสอบ Replay Attack โดยใช้ `Idempotency-Key` ซ้ำ
  - [ ] ทดสอบ Maintenance Mode Block API ได้จริง
  - [ ] ทดสอบ RBAC 4-Level ทำงานถูกต้อง 100%
  - [ ] **Deliverable:** Security และ Idempotency ทำงานได้ตาม 设计要求

- **[ ] T7.4 Unit Testing (80% Coverage)**

- **[ ] T7.5 Integration Testing**

- **[ ] T7.6 E2E Testing**

- **[ ] T7.7 Performance Testing**

  - [ ] Load Testing: 100 concurrent users
  - [ ] **(สำคัญ)** การจูนและทดสอบ Load Test จะต้องทำในสภาพแวดล้อมที่จำลอง Spec ของ QNAP Server (TS-473A, AMD Ryzen V1500B) เพื่อให้ได้ค่า Response Time และ Connection Pool ที่เที่ยงตรง
  - [ ] Stress Testing
  - [ ] Endurance Testing
  - [ ] **Deliverable:** Performance targets บรรลุ

- **[ ] T7.8 Security Testing**

  - [ ] Penetration Testing (OWASP Top 10)
  - [ ] Security Audit (Code review, Dependency scanning)
  - [ ] File Upload Security Testing
  - [ ] **Deliverable:** Security tests ผ่าน

- **[ ] T7.9 Performance Optimization**

  - [ ] Implement Caching (Master Data, User Permissions, Search Results)
  - [ ] Database Optimization (Review Indexes, Query Optimization, Pagination)
  - [ ] **Deliverable:** Response Time < 200ms (90th percentile)

---

## **Phase 8: Documentation & Deployment (สัปดาห์ที่ 14)**

**Milestone:** เอกสารและ Deploy สู่ Production พร้อม Security Hardening

### **Phase 8: Tasks**

- **[ ] T8.1 API Documentation (Swagger)**
- **[ ] T8.2 Technical Documentation**
- **[ ] T8.3 Security Hardening**
- **[ ] T8.4 Deployment Preparation (QNAP Setup, Nginx Proxy Manager)**
- **[ ] T8.5 Production Deployment**
- **[ ] T8.6 Handover to Frontend Team**

---

## 📊 **สรุป Timeline**

| Phase   | ระยะเวลา       | จำนวนงาน     | Output หลัก                                    |
| :------ | :------------- | :----------- | :--------------------------------------------- |
| Phase 0 | 1 สัปดาห์      | 4            | Infrastructure Ready + Security Base           |
| Phase 1 | 2 สัปดาห์      | 5            | Auth & User Management + RBAC + Idempotency    |
| Phase 2 | 1 สัปดาห์      | 5            | High-Integrity Data & File Management          |
| Phase 3 | 2 สัปดาห์      | 4            | Unified Workflow Engine + Correspondence       |
| Phase 4 | 2 สัปดาห์      | 3            | Drawing Management + RFA with Unified Workflow |
| Phase 5 | 2 สัปดาห์      | 2            | Workflow Systems + Resilience                  |
| Phase 6 | 1 สัปดาห์      | 5            | Notification & Resilience + Data Partitioning  |
| Phase 7 | 3 สัปดาห์      | 9            | Testing & Hardening                            |
| Phase 8 | 1 สัปดาห์      | 6            | Documentation & Deploy                         |
| **รวม** | **15 สัปดาห์** | **39 Tasks** | **Production-Ready Backend v1.4.2**            |

## **Document Control:**

- **Document:** Backend Development Plan v1.4.4
- **Version:** 1.4
- **Date:** 2025-11-28
- **Author:** NAP LCBP3-DMS & Gemini
- **Status:** FINAL-Rev.04
- **Classification:** Internal Technical Documentation
- **Approved By:** Nattanin

---

`End of Backend Development Plan v1.4.4`

```

```

```

```
