251118:1300 ปรับปรุง Project requirement

This commit is contained in:
admin
2025-11-18 13:01:23 +07:00
parent 693dd7f074
commit 7c1c5e3c99
20 changed files with 15426 additions and 13926 deletions

View File

@@ -0,0 +1,655 @@
# 📋 แผนการพัฒนา Backend (NestJS) - LCBP3-DMS v1.4.0
## 🎯 ภาพรวมโครงการ
พัฒนา Backend สำหรับระบบบริหารจัดการเอกสารโครงการ (Document Management System) ที่รองรับการจัดการเอกสารที่ซับซ้อน มีระบบ Workflow การอนุมัติ และการควบคุมสิทธิ์แบบ RBAC 3 ระดับ
---
## 📐 สถาปัตยกรรมระบบ
### Technology Stack
- **Framework:** NestJS (TypeScript, ESM)
- **Database:** MariaDB 10.11
- **ORM:** TypeORM
- **Authentication:** JWT + Passport
- **Authorization:** CASL (RBAC)
- **File Upload:** Multer
- **Search:** Elasticsearch
- **Notification:** Nodemailer + n8n (Line Integration)
- **Scheduling:** @nestjs/schedule (Cron Jobs)
- **Documentation:** Swagger
### โครงสร้างโมดูล (Domain-Driven)
```tree
src/
├── common/ # Shared Module
│ ├── auth/ # JWT, Guards
│ ├── config/ # Configuration
│ ├── decorators/ # @RequirePermission
│ ├── entities/ # Base Entities
│ ├── exceptions/ # Global Filters
│ ├── file-storage/ # FileStorageService
│ ├── guards/ # RBAC Guard
│ ├── interceptors/ # Audit, Transform
│ └── services/ # Notification, etc.
├── modules/
│ ├── user/ # Users, Roles, Permissions
│ ├── project/ # Projects, Contracts, Organizations
│ ├── master/ # Master Data
│ ├── correspondence/ # Correspondence Management
│ ├── rfa/ # RFA & Workflows
│ ├── drawing/ # Shop/Contract Drawings
│ ├── circulation/ # Internal Circulation
│ ├── transmittal/ # Transmittals
│ ├── search/ # Elasticsearch
│ └── document-numbering/ # Internal Service
└── database/ # Migrations & Seeds
```
---
## 🗓️ แผนการพัฒนาแบบ Phase-Based
## **Phase 0: Infrastructure Setup (สัปดาห์ที่ 1)**
Milestone: สร้างโครงสร้างพื้นฐานและเชื่อมต่อ Services
### Phase 0: Tasks
- **[✅]T0.1 Setup QNAP Container Station**
- สร้าง Docker Network: `lcbp3`
- Setup docker-compose.yml สำหรับ:
- MariaDB (db.np-dms.work)
- PHPMyAdmin (pma.np-dms.work)
- Backend (backend.np-dms.work)
- Nginx Proxy Manager (npm.np-dms.work)
- กำหนด Environment Variables ใน docker-compose.yml (ไม่ใช้ .env)
- Deliverable: Services ทั้งหมดรันได้และเชื่อมต่อกันผ่าน Network
- **[✅]T0.2 Initialize NestJS Project**
- สร้างโปรเจกต์ใหม่ด้วย Nest CLI
- ติดตั้ง Dependencies:
```bash
npm install @nestjs/typeorm typeorm mysql2
npm install @nestjs/config
npm install class-validator class-transformer
npm install @nestjs/jwt @nestjs/passport passport passport-jwt
npm install casl
npm install @nestjs/platform-express multer
npm install @nestjs/swagger
npm install helmet rate-limiter-flexible
npm install bcrypt
npm install --save-dev @nestjs/testing jest @types/jest @types/passport-jwt @types/multer supertest
npm install @nestjs/cache-manager cache-manager
npm install @nestjs/schedule
npm install @nestjs/config
npm install @nestjs/elasticsearch @elastic/elasticsearch
npm install nodemailer @types/nodemailer
npm install uuid @types/uuid
```
````
- Setup โครงสร้างโฟลเดอร์ตาม Domain-Driven Architecture
- Deliverable: Project Structure พร้อม, แสดง Swagger ที่ `/api`
- **[✅]T0.3 Setup Database Connection**
- Import SQL Schema v1.4.0 เข้า MariaDB
- Run Seed Data (organizations, users, roles, permissions)
- Configure TypeORM ใน AppModule
- ทดสอบ Connection
- Deliverable: Database พร้อมใช้งาน, มี Seed Data
- **[✅]T0.4 Setup Git Repository**
- สร้าง Repository ใน Gitea (git.np-dms.work)
- Setup .gitignore, README.md
- Commit Initial Project
- Deliverable: Code อยู่ใน Version Control
---
## **Phase 1: Core Foundation (สัปดาห์ที่ 2-3)**
Milestone: ระบบ Authentication, Authorization และ Base Entities
### Phase 1: Tasks
- **[ ] T1.1 CommonModule - Base Infrastructure**
- [ ] สร้าง Base Entity (id, created_at, updated_at, deleted_at)
- [ ] สร้าง Global Exception Filter
- [ ] สร้าง Response Transform Interceptor
- [ ] สร้าง Audit Log Interceptor
- [ ] สร้าง RequestContextService - สำหรับเก็บข้อมูลระหว่าง Request
- [ ] สร้าง ConfigService - Centralized configuration management
- [ ] สร้าง CryptoService - สำหรับ encryption/decryption
- [ ] Deliverable: Common Services พร้อมใช้
- **[ ] T1.2 AuthModule - JWT Authentication**
- [ ] สร้าง Entity: User
- [ ] สร้าง AuthService:
- [ ] `login(username, password)` → JWT Token
- [ ] `validateUser(username, password)` → User | null
- [ ] Password Hashing (bcrypt)
- [ ] สร้าง JWT Strategy (Passport)
- [ ] สร้าง JwtAuthGuard
- [ ] สร้าง Controllers:
- [ ] `POST /auth/login` → { access_token }
- [ ] `POST /auth/register` (Admin only)
- [ ] `GET /auth/profile` (Protected)
- [ ] Deliverable: ล็อกอิน/ล็อกเอาต์ทำงานได้
- **[ ] T1.3 UserModule - User Management**
- [ ] สร้าง Entities: User, Role, Permission, UserRole
- [ ] สร้าง UserService CRUD
- [ ] สร้าง RoleService CRUD
- [ ] สร้าง PermissionService (Read-Only, จาก Seed)
- [ ] สร้าง Controllers:
- [ ] `GET /users` → List Users (Paginated)
- [ ] `GET /users/:id` → User Detail
- [ ] `POST /users` → Create User
- [ ] `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
- [ ] Deliverable: จัดการผู้ใช้และ Role ได้
- **[ ] T1.4 RBAC Guard - Authorization**
- [ ] สร้าง `@RequirePermission()` Decorator
- [ ] สร้าง RbacGuard ที่ตรวจสอบ:
- [ ] Global Permissions
- [ ] Organization Permissions
- [ ] Project Permissions
- [ ] Contract Permissions
- [ ] Permission Hierarchy Logic
```bash
// Current: 3-level hierarchy
// Recommended: 4-level hierarchy (Global → Organization → Project → Contract)
@Injectable()
export class RbacGuard implements CanActivate {
async canActivate(context: ExecutionContext): Promise<boolean> {
const requiredPermission = this.getRequiredPermission(context);
const user = this.getUser(context);
// Check permissions in order: Global → Org → Project → Contract
return await this.checkGlobalPermissions(user, requiredPermission) ||
await this.checkOrgPermissions(user, requiredPermission) ||
await this.checkProjectPermissions(user, requiredPermission) ||
await this.checkContractPermissions(user, requiredPermission);
}
}
````
- [ ] Integration กับ CASL
- [ ] Deliverable: ระบบสิทธิ์ทำงานได้ทั้ง 4 ระดับ
- **T1.5 ProjectModule - Base Structures**
- [ ] สร้าง Entities:
- [ ] Organization
- [ ] Project
- [ ] Contract
- [ ] ProjectOrganization (Junction)
- [ ] ContractOrganization (Junction)
- [ ] UserAssignment Entity - สำหรับจัดการ user assignments ตาม scope
- [ ] สร้าง Services & Controllers:
- [ ] `GET /organizations` → List
- [ ] `POST /projects` → Create (Superadmin)
- [ ] `GET /projects/:id/contracts` → List Contracts
- [ ] `POST /projects/:id/contracts` → Create Contract
- [ ] UserAssignment - สำหรับจัดการ user assignments ตาม scope
- [ ] ProjectOrganization - สำหรับจัดการความสัมพันธ์ project-organization
- [ ] ContractOrganization - สำหรับจัดการความสัมพันธ์ contract-organization
- [ ] Deliverable: จัดการโครงสร้างโปรเจกต์ได้
---
## **Phase 2: Master Data & File Management (สัปดาห์ที่ 4)**
Milestone: Master Data และระบบจัดการไฟล์
### Phase 2: Tasks
- **[ ] T2.1 MasterModule - Master Data Management**
- [ ] สร้าง Entities:
- [ ] CorrespondenceType
- [ ] CorrespondenceStatus
- [ ] RfaType
- [ ] RfaStatusCode
- [ ] RfaApproveCode
- [ ] CirculationStatusCode
- [ ] Tag
- [ ] สร้าง Services & Controllers (CRUD):
- [ ] `GET /master/correspondence-types`
- [ ] `POST /master/tags` → Create Tag
- [ ] `GET /master/tags` → List Tags (Autocomplete)
- [ ] Deliverable: Admin จัดการ Master Data ได้
- **[ ] T2.2 FileStorageService - Central File Management**
- [ ] สร้าง Attachment Entity
- [ ] สร้าง FileStorageService: (การจัดเก็บไฟล์ในรูปแบบ centralized storage, ครอบคลุมการจัดการไฟล์แนบทั้งหมด, Security Measures)
- [ ] `uploadFile(file: Express.Multer.File)` → Attachment
- [ ] `getFilePath(attachmentId)` → string
- [ ] `deleteFile(attachmentId)` → boolean
- [ ] จัดเก็บไฟล์ใน `/share/dms-data/uploads/{YYYY}/{MM}/`
- [ ] สร้าง Controller:
- [ ] `POST /files/upload` → { attachment_id, url }
- [ ] `GET /files/:id/download` → File Stream (Protected)
- [ ] Access Control: ตรวจสอบสิทธิ์ผ่าน Junction Table
- [ ] Deliverable: อัปโหลด/ดาวน์โหลดไฟล์ได้อย่างปลอดภัย
- **[ ] T2.3 DocumentNumberingModule - Internal Service**
- [ ] สร้าง Entities:
- [ ] DocumentNumberFormat
- [ ] DocumentNumberCounter
- [ ] สร้าง DocumentNumberingService: รวม Stored Procedure (sp_get_next_document_number), Error Handling และ Retry Logic
- [ ] `generateNextNumber(projectId, orgId, typeId, year)` → string
- [ ] เรียก Stored Procedure: `sp_get_next_document_number`
- [ ] Format ตาม Template: `{ORG_CODE}-{TYPE_CODE}-{YEAR_SHORT}-{SEQ:4}`
- **ไม่มี Controller** (Internal Service เท่านั้น)
- [ ] Deliverable: Service สร้างเลขที่เอกสารได้ถูกต้อง
---
## **Phase 3: Correspondence & RFA Core (สัปดาห์ที่ 5-6)**
Milestone: ระบบเอกสารโต้ตอบและ RFA
### Phase 3: Tasks
- **[ ] T3.1 CorrespondenceModule - Basic CRUD**
- [ ] สร้าง Entities:
- [ ] Correspondence
- [ ] CorrespondenceRevision
- [ ] CorrespondenceRecipient
- [ ] CorrespondenceTag
- [ ] CorrespondenceReference
- [ ] CorrespondenceAttachment
- [ ] สร้าง CorrespondenceService: Complex Business Rules, State Machine สำหรับ Status Transitions
- [ ] `create(dto)` → Correspondence
- [ ] สร้าง Correspondence + Revision แรก (rev 0)
- [ ] เรียก DocumentNumberingService
- [ ] สร้าง Recipients (TO/CC)
- [ ] สร้าง Tags
- [ ] สร้าง Attachments
- [ ] `update(id, dto)` → Correspondence
- [ ] สร้าง Revision ใหม่
- [ ] Update `is_current` flag
- [ ] `findAll(filters)` → Paginated List
- [ ] `findById(id)` → Correspondence with Current Revision
- [ ] สร้าง Controllers:
- [ ] `POST /correspondences` → Create
- [ ] `GET /correspondences` → List (Filter by type, status, org)
- [ ] `GET /correspondences/:id` → Detail
- [ ] `PUT /correspondences/:id` → Update (Create new revision)
- [ ] `DELETE /correspondences/:id` → Soft Delete (Admin only)
- [ ] Deliverable: สร้าง/แก้ไข/ดูเอกสารได้
- **[ ] T3.2 CorrespondenceModule - Advanced Features**
- [ ] Implement Status Transitions:
- [ ] `DRAFT` → `SUBMITTED` (Document Control)
- [ ] `SUBMITTED` → `CLOSED` (Admin)
- [ ] `SUBMITTED` → `CANCELLED` (Admin + Reason)
- [ ] Implement References:
- [ ] `POST /correspondences/:id/references` → Link Documents
- [ ] Implement Search (Basic):
- `GET /correspondences/search?q=...`
- [ ] Deliverable: Workflow พื้นฐานทำงานได้
- **[ ] T3.3 RfaModule - Basic CRUD**
- [ ] สร้าง Entities:
- [ ] Rfa
- [ ] RfaRevision
- [ ] RfaItem (Junction to Shop Drawings)
- [ ] สร้าง RfaService: Complex Business Rules
- [ ] `create(dto)` → Rfa
- [ ] สร้าง Correspondence + Rfa + RfaRevision
- [ ] เชื่อม Shop Drawing Revisions (สำหรับ RFA_DWG)
- [ ] `findAll(filters)` → Paginated List
- [ ] `findById(id)` → Rfa with Items
- [ ] สร้าง Controllers:
- [ ] `POST /rfas` → Create
- [ ] `GET /rfas` → List
- [ ] `GET /rfas/:id` → Detail
- [ ] Deliverable: สร้าง RFA และเชื่อม Shop Drawings ได้
---
## **Phase 4: Drawing Management (สัปดาห์ที่ 7)**
Milestone: ระบบจัดการแบบ
### Phase 4: Tasks
- **[ ] T4.1 DrawingModule - Contract Drawings**
- [ ] สร้าง Entities:
- [ ] ContractDrawing
- [ ] ContractDrawingVolume
- [ ] ContractDrawingCat
- [ ] ContractDrawingSubCat
- [ ] ContractDrawingSubcatCatMap
- [ ] ContractDrawingAttachment
- [ ] สร้าง ContractDrawingService CRUD
- [ ] สร้าง Controllers:
- [ ] `GET /drawings/contract` → List
- [ ] `POST /drawings/contract` → Create (Admin)
- [ ] `GET /drawings/contract/:id` → Detail
- [ ] Deliverable: จัดการ Contract Drawings ได้
- **[ ] T4.2 DrawingModule - Shop Drawings**
- [ ] สร้าง Entities:
- [ ] ShopDrawing
- [ ] ShopDrawingRevision
- [ ] ShopDrawingMainCategory
- [ ] ShopDrawingSubCategory
- [ ] ShopDrawingRevisionContractRef
- [ ] ShopDrawingRevisionAttachment
- [ ] สร้าง ShopDrawingService CRUD
- [ ] สร้าง Controllers:
- [ ] `GET /drawings/shop` → List
- [ ] `POST /drawings/shop` → Create
- [ ] `POST /drawings/shop/:id/revisions` → Create Revision
- [ ] `GET /drawings/shop/:id` → Detail with Revisions
- [ ] Link Shop Drawing Revision → Contract Drawings
- [ ] Deliverable: จัดการ Shop Drawings และ Revisions ได้
---
## **Phase 5: Workflow Systems (สัปดาห์ที่ 8-9)**
Milestone: ระบบ Workflow ทั้งหมด
### Phase 5: Tasks
- **[ ] T5.1 RfaModule - Workflow Implementation**
- [ ] สร้าง Entities:
- [ ] RfaWorkflowTemplate
- [ ] RfaWorkflowTemplateStep
- [ ] RfaWorkflow (Transaction Log)
- [ ] สร้าง RfaWorkflowService: Advanced Workflow Features
- [ ] `initiateWorkflow(rfaId, templateId)` → void
- [ ] สร้าง RfaWorkflow records ตาม Template
- [ ] กำหนด Step 1 เป็น PENDING
- [ ] `completeStep(rfaId, stepNumber, action, comments)` → void
- [ ] Update Status → COMPLETED
- [ ] Set Next Step → PENDING
- [ ] Send Notifications
- [ ] `rejectStep(rfaId, stepNumber, reason)` → void
- [ ] Update Status → REJECTED
- [ ] Send back to Originator
- [ ] สร้าง Controllers:
- [ ] `POST /rfas/:id/workflow/start` → Start Workflow
- [ ] `POST /rfas/:id/workflow/steps/:stepNumber/complete` → Complete Step
- [ ] `GET /rfas/:id/workflow` → Get Workflow Status
- [ ] Deliverable: RFA Workflow ทำงานได้
- **[ ] T5.2 CirculationModule - Internal Routing**
- [ ] สร้าง Entities:
- [ ] Circulation
- [ ] CirculationTemplate
- [ ] CirculationTemplateAssignee
- [ ] CirculationRouting (Transaction Log)
- [ ] CirculationAttachment
- [ ] สร้าง CirculationService:
- [ ] `create(correspondenceId, dto)` → Circulation
- [ ] สร้าง Circulation (1:1 กับ Correspondence)
- [ ] สร้าง Routing ตาม Template
- [ ] `assignUser(circulationId, stepNumber, userId)` → void
- [ ] `completeStep(circulationId, stepNumber, comments)` → void
- [ ] `close(circulationId)` → void (เมื่อตอบกลับองค์กรผู้ส่งแล้ว)
- สร้าง Controllers:
- [ ] `POST /circulations` → Create
- [ ] `GET /circulations/:id` → Detail
- [ ] `POST /circulations/:id/steps/:stepNumber/complete` → Complete
- [ ] `POST /circulations/:id/close` → Close
- [ ] Deliverable: ใบเวียนภายในองค์กรทำงานได้
- **[ ] T5.3 TransmittalModule - Document Forwarding**
- [ ] สร้าง Entities:
- [ ] Transmittal
- [ ] TransmittalItem
- [ ] สร้าง TransmittalService:
- [ ] `create(dto)` → Transmittal
- [ ] สร้าง Correspondence + Transmittal
- [ ] เชื่อม Multiple Correspondences เป็น Items
- [ ] สร้าง Controllers:
- [ ] `POST /transmittals` → Create
- [ ] `GET /transmittals` → List
- [ ] `GET /transmittals/:id` → Detail with Items
- [ ] Deliverable: สร้าง Transmittal ได้
---
## **Phase 6: Advanced Features (สัปดาห์ที่ 10-11)**
Milestone: ฟีเจอร์ขั้นสูง
### Phase 6: Tasks
- **[ ] T6.1 SearchModule - Elasticsearch Integration**
- [ ] Setup Elasticsearch Container ใน docker-compose.yml
- [ ] สร้าง SearchService:
- [ ] `indexDocument(entity)` → void
- [ ] `updateDocument(entity)` → void
- [ ] `deleteDocument(entity)` → void
- [ ] `search(query, filters)` → SearchResult[]
- [ ] Index ทุกครั้งที่ Create/Update:
- [ ] Correspondence
- [ ] RFA
- [ ] Shop Drawing
- [ ] Contract Drawing
- [ ] Circulation
- [ ] Transmittal
- [ ] สร้าง Controllers:
- [ ] `GET /search?q=...&type=...&from=...&to=...` → Results
- [ ] Deliverable: ค้นหาขั้นสูงทำงานได้
- **[ ] T6.2 NotificationModule - Email & Line**
- [ ] สร้าง NotificationService:
- [ ] `sendEmail(to, subject, body)` → void (Nodemailer)
- [ ] `sendLine(userId, message)` → void (ผ่าน n8n Webhook)
- [ ] `createSystemNotification(userId, message, entityType, entityId)` → void
- [ ] Integrate กับ Workflow Events:
- [ ] เมื่อสร้าง Correspondence ใหม่ → แจ้ง Recipients
- [ ] เมื่อสร้าง Circulation → แจ้ง Assignees
- [ ] เมื่อ RFA Workflow ถึง Step → แจ้ง Responsible Org
- [ ] เมื่อใกล้ถึง Deadline → แจ้ง (Optional)
- [ ] สร้าง Controllers:
- [ ] `GET /notifications` → List User's Notifications
- [ ] `PUT /notifications/:id/read` → Mark as Read
- [ ] Deliverable: ระบบแจ้งเตือนทำงานได้
- **[ ] T6.3 Reporting & Analytics**
- [ ] สร้าง ReportService:
- [ ] `getCorrespondenceSummary(projectId, from, to)` → Report
- [ ] `getRfaSummary(projectId, from, to)` → Report
- [ ] `getActivityLog(userId, from, to)` → Report
- [ ] ใช้ Views จาก Database:
- [ ] `v_current_correspondences`
- [ ] `v_current_rfas`
- [ ] `v_user_tasks`
- [ ] `v_audit_log_details`
- [ ] สร้าง Controllers:
- [ ] `GET /reports/correspondence` → Summary (CSV, PDF)
- [ ] `GET /reports/rfa` → Summary
- [ ] `GET /reports/activity` → User Activity
- [ ] Deliverable: สร้างรายงานได้
- **T6.4 Audit Log & Activity Feed**
- [ ] AuditLogInterceptor ทำงานอัตโนมัติแล้ว (Phase 1)
- [ ] สร้าง AuditLogService:
- [ ] `log(userId, action, entityType, entityId, details)` → void
- [ ] `getUserActivity(userId, limit)` → AuditLog[]
- [ ] สร้าง Controllers:
- [ ] `GET /audit-logs` → List (Admin only)
- [ ] `GET /audit-logs/user/:userId` → User's Activity
- [ ] Deliverable: ดู Audit Log ได้
---
## **Phase 7: Testing & Optimization (สัปดาห์ที่ 12-13)**
Milestone: ทดสอบและปรับปรุงประสิทธิภาพ
### Phase 7: Tasks
- **[ ] T7.1 Unit Testing**
- [ ] เขียน Unit Tests สำหรับ Services สำคัญ:
- [ ] AuthService (login, validateUser)
- [ ] RbacGuard (permission checks)
- [ ] DocumentNumberingService (number generation)
- [ ] CorrespondenceService (create, update)
- [ ] RfaWorkflowService (workflow logic)
- [ ] Target: 70% Code Coverage
- [ ] Deliverable: Unit Tests ผ่านทั้งหมด
- **[ ] T7.2 Integration Testing**
- [ ] เขียน Integration Tests:
- [ ] Authentication Flow (login → access protected route)
- [ ] Document Creation Flow (create correspondence → attach files)
- [ ] RFA Workflow Flow (start → step 1 → step 2 → complete)
- [ ] Circulation Flow (create → assign → complete → close)
- [ ] ทดสอบ SQL Views (v_user_all_permissions, v_user_tasks)
- [ ] ใช้ Test Database แยกต่างหาก
- [ ] Deliverable: Integration Tests ผ่าน
- **[ ] T7.3 E2E Testing**
- [ ] เขียน E2E Tests:
- [ ] User Registration & Login
- [ ] Create Correspondence (Full Flow)
- [ ] Create RFA with Shop Drawings
- [ ] Complete RFA Workflow
- [ ] Search Documents
- [ ] Deliverable: E2E Tests ผ่าน
- **[ ] T7.4 Performance Optimization**
- [ ] Implement Caching:
- [ ] Cache Master Data (Roles, Permissions)
- [ ] Cache User Permissions (ใช้ @nestjs/cache-manager)
- [ ] Database Optimization:
- [ ] Review Indexes
- [ ] Optimize Queries (N+1 Problem)
- I[ ] mplement Pagination ทุก List Endpoint
- [ ] Deliverable: Response Time < 200ms (90th percentile)
- **[ ] T7.5 Security Hardening**
- [ ] Implement Rate Limiting (ใช้ rate-limiter-flexible)
- [ ] Setup Helmet (Security Headers)
- [ ] Review CORS Configuration
- [ ] Input Validation (ตรวจสอบ DTOs ทั้งหมด)
- [ ] Deliverable: Security Checklist ผ่าน
---
## **Phase 8: Documentation & Deployment (สัปดาห์ที่ 14)**
Milestone: เอกสารและ Deploy สู่ Production
### Phase 8: Tasks
- **[ ] T8.1 API Documentation**
- [ ] ครบทุก Endpoint ใน Swagger:
- [ ] ใส่ Description, Example Request/Response
- [ ] ระบุ Required Permissions
- [ ] ใส่ Error Responses
- [ ] Export Swagger JSON → Frontend Team
- [ ] Deliverable: Swagger Docs สมบูรณ์
- **[ ] T8.2 Technical Documentation**
- [ ] เขียนเอกสาร:
- [ ] Architecture Overview
- [ ] Module Structure
- [ ] Database Schema Diagram
- [ ] API Design Patterns
- [ ] Deployment Guide
- [ ] Deliverable: Technical Docs พร้อม
- **[ ] T8.3 Deployment Preparation**
- [ ] สร้าง Production docker-compose.yml
- [ ] Setup Environment Variables ใน QNAP
- [ ] Setup Nginx Proxy Manager (SSL Certificate)
- [ ] Setup Backup Scripts (Database + Files)
- [ ] Deliverable: Deployment Guide พร้อม
- **[ ] T8.4 Production Deployment**
- [ ] Deploy Backend ไปยัง backend.np-dms.work
- [ ] ทดสอบ API ผ่าน Postman
- [ ] Monitor Logs (Winston)
- [ ] Setup Health Check Endpoint (`GET /health`)
- [ ] Deliverable: Backend รันบน Production
- **T8.5 Handover to Frontend Team**
- [ ] Demo API ให้ Frontend Team
- [ ] ส่งมอบ Swagger Documentation
- [ ] ส่งมอบ Postman Collection
- [ ] Workshop: วิธีใช้ Authentication & RBAC
- [ ] Deliverable: Frontend เริ่มพัฒนาได้
---
## 📊 สรุป Timeline
| Phase | ระยะเวลา | จำนวนงาน | Output หลัก |
| ------- | -------------- | ------------ | ---------------------------- |
| Phase 0 | 1 สัปดาห์ | 4 | Infrastructure Ready |
| Phase 1 | 2 สัปดาห์ | 5 | Auth & User Management |
| Phase 2 | 1 สัปดาห์ | 3 | Master Data & File Storage |
| Phase 3 | 2 สัปดาห์ | 3 | Correspondence & RFA Core |
| Phase 4 | 1 สัปดาห์ | 2 | Drawing Management |
| Phase 5 | 2 สัปดาห์ | 3 | Workflow Systems |
| Phase 6 | 2 สัปดาห์ | 4 | Advanced Features |
| Phase 7 | 2 สัปดาห์ | 5 | Testing & Optimization |
| Phase 8 | 1 สัปดาห์ | 5 | Documentation & Deploy |
| **รวม** | **14 สัปดาห์** | **34 Tasks** | **Production-Ready Backend** |
---
## 🎯 Critical Success Factors
1. **Database First**: ใช้ Schema v1.4.0 เป็นหลัก ไม่แก้ไข Schema โดยไม่จำเป็น
2. **Emphasizing Soft Delete**: Service ทั้งหมดที่ทำการ Query ข้อมูล (เช่น findAll, findById) ต้อง ใช้ Global Filter หรือ Default Scope ของ TypeORM เพื่อกรอง WHERE deleted_at IS NULL เสมอ
3. **API Contract**: ทุก Endpoint ต้องมี Swagger Documentation สมบูรณ์
4. **Security**: RBAC ต้องทำงานถูกต้อง 100% ก่อน Deploy
5. **Testing**: Code Coverage อย่างน้อย 70% ก่อน Production
6. **Performance**: Response Time < 200ms (90th percentile)
7. **Documentation**: เอกสารต้องครบถ้วนเพื่อ Handover ให้ Frontend Team
---
## 🚀 ขั้นตอนถัดไป
1. **Approve แผนนี้** → ปรับแต่งตาม Feedback
2. **Setup Phase 0** → เริ่มสร้าง Infrastructure
3. **Daily Standup** → รายงานความก้าวหน้าทุกวัน
4. **Weekly Review** → ทบทวนความก้าวหน้าทุกสัปดาห์
5. **Deploy to Production** → Week 14
---
**หมายเหตุ:** แผนนี้สามารถปรับแต่งได้ตามความต้องการและข้อจำกัดของทีม หาก Phase ใดใช้เวลามากกว่าที่คาดการณ์ ควรปรับ Timeline ให้เหมาะสม

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,833 @@
# 📋 แผนการพัฒนา Frontend (NestJS) - LCBP3-DMS v1.4.0
# 📋 แผนการพัฒนา Frontend (Next.js) - LCBP3-DMS v1.4.0
## 🎯 ภาพรวมโครงการ
พัฒนา Frontend สำหรับระบบบริหารจัดการเอกสารโครงการ (Document Management System) ที่ทันสมัย responsive และใช้งานง่าย รองรับการจัดการเอกสารที่ซับซ้อน มี Dashboard แบบ Real-time และระบบ Workflow Visualization
---
## 📐 สถาปัตยกรรมระบบ
### Technology Stack
- **Framework:** Next.js 14+ (App Router, React 18+, TypeScript, ESM)
- **Styling:** Tailwind CSS + PostCSS
- **Component Library:** shadcn/ui (Radix UI)
- **State Management:**
- **Server State:** TanStack Query (React Query)
- **Global Client State:** Zustand
- **Form State:** React Hook Form + Zod
- **Data Fetching:** Axios + TanStack Query
- **Authentication:** NextAuth.js (JWT Strategy)
- **File Upload:** React Dropzone
- **Tables:** TanStack Table
- **Charts:** Recharts
- **Date Picker:** date-fns + shadcn/ui Calendar
- **Icons:** Lucide React
- **Testing:**
- **Unit/Integration:** Vitest + React Testing Library
- **E2E:** Playwright
- **API Mocking:** Mock Service Worker (MSW)
### โครงสร้างโปรเจกต์
```
app/
├── (public)/ # Public routes (Landing, Login)
│ ├── page.tsx # Landing Page
│ └── login/ # Login Page
├── (protected)/ # Protected routes
│ ├── layout.tsx # App Shell (Navbar + Sidebar)
│ ├── dashboard/ # Dashboard
│ ├── correspondences/ # Correspondence Management
│ ├── rfas/ # RFA Management
│ ├── drawings/ # Drawing Management
│ ├── circulations/ # Circulation Management
│ ├── transmittals/ # Transmittal Management
│ ├── search/ # Advanced Search
│ ├── reports/ # Reports
│ ├── admin/ # Admin Panel
│ └── profile/ # User Profile
├── api/ # API Routes (if needed)
components/
├── ui/ # shadcn/ui components
├── features/ # Feature-specific components
│ ├── auth/
│ ├── correspondence/
│ ├── rfa/
│ ├── drawing/
│ ├── circulation/
│ └── common/
└── layouts/ # Layout components
lib/
├── api/ # API client & hooks
├── stores/ # Zustand stores
├── utils/ # Utility functions
├── hooks/ # Custom hooks
└── types/ # TypeScript types
public/
├── images/
└── fonts/
```
---
## 🗓️ แผนการพัฒนาแบบ Phase-Based
## **Phase 0: Setup & Infrastructure (สัปดาห์ที่ 1)**
### Milestone: สร้างโครงสร้างพื้นฐานและ Development Environment
#### Tasks:
**T0.1 Initialize Next.js Project**
- สร้างโปรเจกต์ด้วย `create-next-app`:
```bash
npx create-next-app@latest lcbp3-frontend --typescript --tailwind --app --src-dir=false
```
- เลือก Options:
- ✅ TypeScript
- ✅ ESLint
- ✅ Tailwind CSS
- ✅ App Router
- ✅ Import alias (@/\*)
- Setup .gitignore, README.md
- Deliverable: ✅ โปรเจกต์เริ่มต้นพร้อม
**T0.2 Install Core Dependencies**
```bash
# State Management & Data Fetching
npm install @tanstack/react-query zustand
npm install axios
npm install react-hook-form @hookform/resolvers zod
# UI Components & Styling
npm install clsx tailwind-merge
npm install lucide-react
npm install date-fns
# File Upload
npm install react-dropzone
# Authentication
npm install next-auth
# Development Tools
npm install -D @types/node
```
- Deliverable: ✅ Dependencies ติดตั้งสมบูรณ์
**T0.3 Setup shadcn/ui**
```bash
npx shadcn-ui@latest init
```
- เลือก Style: Default
- เลือก Base Color: Slate
- ติดตั้ง Components เบื้องต้น:
```bash
npx shadcn-ui@latest add button input label card table dropdown-menu
npx shadcn-ui@latest add dialog sheet toast alert
npx shadcn-ui@latest add form select textarea checkbox
npx shadcn-ui@latest add calendar popover
```
- Deliverable: ✅ shadcn/ui พร้อมใช้งาน
**T0.4 Configure Tailwind CSS**
- แก้ไข `tailwind.config.ts`:
- เพิ่ม Custom Colors (ตาม Brand)
- เพิ่ม Custom Fonts (ภาษาไทย: Noto Sans Thai)
- Configure Container, Spacing
- สร้าง `app/globals.css` พร้อม Custom Styles
- Deliverable: ✅ Tailwind พร้อมใช้
**T0.5 Setup Development Environment**
- สร้าง `.env.local`:
```
NEXT_PUBLIC_API_URL=http://backend.np-dms.work/api
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=...
```
- Setup ESLint Rules (ไทย Comments OK)
- Setup Prettier
- Setup VS Code Settings
- Deliverable: ✅ Dev Environment พร้อม
**T0.6 Setup Git & Docker**
- Push โปรเจกต์ไปยัง Gitea (git.np-dms.work)
- สร้าง Dockerfile สำหรับ Next.js:
```dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]
```
- สร้าง docker-compose.yml (เชื่อม Network `lcbp3`)
- Deliverable: ✅ Project อยู่ใน Git + Docker พร้อม
---
## **Phase 1: Authentication & App Shell (สัปดาห์ที่ 2-3)**
### Milestone: ระบบ Login และ Layout หลัก
#### Tasks:
**T1.1 Setup API Client**
- สร้าง `lib/api/client.ts`:
```typescript
import axios from "axios";
export const apiClient = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_URL,
headers: {
"Content-Type": "application/json",
},
});
// Request Interceptor (Add JWT Token)
apiClient.interceptors.request.use((config) => {
const token = localStorage.getItem("access_token");
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
// Response Interceptor (Handle Errors)
apiClient.interceptors.response.use(
(response) => response,
(error) => {
if (error.response?.status === 401) {
// Redirect to login
window.location.href = "/login";
}
return Promise.reject(error);
}
);
```
- Deliverable: ✅ API Client พร้อมใช้
**T1.2 Setup TanStack Query**
- สร้าง `app/providers.tsx`:
```typescript
"use client";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { useState } from "react";
export function Providers({ children }: { children: React.ReactNode }) {
const [queryClient] = useState(
() =>
new QueryClient({
defaultOptions: {
queries: {
staleTime: 60 * 1000, // 1 minute
refetchOnWindowFocus: false,
},
},
})
);
return (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
);
}
```
- Wrap ใน `app/layout.tsx`
- Deliverable: ✅ React Query พร้อม
**T1.3 Create Auth Store (Zustand)**
- สร้าง `lib/stores/auth-store.ts`:
```typescript
import { create } from "zustand";
import { persist } from "zustand/middleware";
interface User {
user_id: number;
username: string;
email: string;
first_name: string;
last_name: string;
primary_organization_id: number;
permissions: string[];
}
interface AuthStore {
user: User | null;
token: string | null;
setAuth: (user: User, token: string) => void;
clearAuth: () => void;
hasPermission: (permission: string) => boolean;
}
export const useAuthStore = create<AuthStore>()(
persist(
(set, get) => ({
user: null,
token: null,
setAuth: (user, token) => {
set({ user, token });
localStorage.setItem("access_token", token);
},
clearAuth: () => {
set({ user: null, token: null });
localStorage.removeItem("access_token");
},
hasPermission: (permission) => {
const user = get().user;
return user?.permissions.includes(permission) || false;
},
}),
{
name: "auth-storage",
}
)
);
```
- Deliverable: ✅ Auth Store พร้อม
**T1.4 Create Login Page**
- สร้าง `app/(public)/login/page.tsx`:
```typescript
"use client";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import * as z from "zod";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { useRouter } from "next/navigation";
import { useAuthStore } from "@/lib/stores/auth-store";
import { apiClient } from "@/lib/api/client";
const loginSchema = z.object({
username: z.string().min(1, "กรุณากรอกชื่อผู้ใช้"),
password: z.string().min(1, "กรุณากรอกรหัสผ่าน"),
});
export default function LoginPage() {
const router = useRouter();
const setAuth = useAuthStore((state) => state.setAuth);
const form = useForm({
resolver: zodResolver(loginSchema),
});
const handleLogin = async (data: z.infer<typeof loginSchema>) => {
try {
const response = await apiClient.post("/auth/login", data);
const { access_token, user } = response.data;
setAuth(user, access_token);
router.push("/dashboard");
} catch (error) {
console.error("Login failed:", error);
// แสดง Toast Error
}
};
return (
<div className="flex min-h-screen items-center justify-center">
<form onSubmit={form.handleSubmit(handleLogin)} className="w-96">
{/* Form Fields */}
</form>
</div>
);
}
```
- Deliverable: ✅ หน้า Login พร้อม
**T1.5 Create Landing Page**
- สร้าง `app/(public)/page.tsx`:
- Hero Section พร้อมข้อมูลโครงการ
- Feature Highlights
- CTA Button → Login
- ใช้ Tailwind + Animations
- Deliverable: ✅ Landing Page สวยงาม
**T1.6 Create Protected Layout (App Shell)**
- สร้าง `app/(protected)/layout.tsx`:
```typescript
"use client";
import { useEffect } from "react";
import { useRouter } from "next/navigation";
import { useAuthStore } from "@/lib/stores/auth-store";
import Navbar from "@/components/layouts/navbar";
import Sidebar from "@/components/layouts/sidebar";
export default function ProtectedLayout({
children,
}: {
children: React.ReactNode;
}) {
const router = useRouter();
const user = useAuthStore((state) => state.user);
useEffect(() => {
if (!user) {
router.push("/login");
}
}, [user, router]);
if (!user) return null;
return (
<div className="flex h-screen">
<Sidebar />
<div className="flex flex-1 flex-col">
<Navbar />
<main className="flex-1 overflow-y-auto p-6">{children}</main>
</div>
</div>
);
}
```
- Deliverable: ✅ App Shell พร้อม
**T1.7 Create Navbar Component**
- สร้าง `components/layouts/navbar.tsx`:
- แสดงชื่อระบบ
- แสดงชื่อผู้ใช้ + Avatar
- Dropdown Menu:
- Profile
- Settings
- Logout
- Responsive (Mobile Hamburger Menu)
- Deliverable: ✅ Navbar พร้อม
**T1.8 Create Sidebar Component**
- สร้าง `components/layouts/sidebar.tsx`:
- เมนูหลัก:
- Dashboard
- Correspondences
- RFAs
- Drawings (Shop & Contract)
- Circulations
- Transmittals
- Search
- Reports
- เมนู Admin (แสดงตามสิทธิ์):
- Users
- Roles & Permissions
- Master Data
- Document Numbering
- Collapsible Sidebar
- Active State Highlighting
- Deliverable: ✅ Sidebar พร้อม
---
## **Phase 2: Dashboard & Common Components (สัปดาห์ที่ 4)**
### Milestone: Dashboard และ Reusable Components
#### Tasks:
**T2.1 Create Reusable Components**
- `components/features/common/data-table.tsx`:
- ใช้ TanStack Table
- รองรับ Pagination, Sorting, Filtering
- Responsive
- `components/features/common/file-upload.tsx`:
- ใช้ React Dropzone
- รองรับ Multi-file Upload
- Drag & Drop
- Progress Bar
- `components/features/common/status-badge.tsx`:
- แสดง Status แบบสีสัน (Draft, Submitted, Approved)
- `components/features/common/permission-guard.tsx`:
- ซ่อน/แสดง Component ตามสิทธิ์
- Deliverable: ✅ Reusable Components พร้อม
**T2.2 Create Dashboard Page**
- สร้าง `app/(protected)/dashboard/page.tsx`:
- **KPI Cards Section**:
- จำนวนเอกสารทั้งหมด
- งานที่รอดำเนินการ
- เอกสารที่เกินกำหนด
- RFA ที่รออนุมัติ
- **My Tasks Table**:
- ดึงข้อมูลจาก `/api/circulations/my-tasks` (ใช้ `v_user_tasks`)
- แสดงรายการงานที่ต้องทำ (Pending, In Progress)
- Columns: Document Number, Title, Type, Status, Deadline, Actions
- คลิกแถวแล้วไปยังหน้า Detail
- **Recent Activity Feed**:
- ดึงข้อมูลจาก `/api/audit-logs/user/:userId`
- แสดง 10 รายการล่าสุด
- Deliverable: ✅ Dashboard ครบถ้วน
**T2.3 Create API Hooks**
- สร้าง `lib/api/hooks/use-my-tasks.ts`:
```typescript
import { useQuery } from "@tanstack/react-query";
import { apiClient } from "../client";
export function useMyTasks() {
return useQuery({
queryKey: ["my-tasks"],
queryFn: async () => {
const response = await apiClient.get("/circulations/my-tasks");
return response.data;
},
});
}
```
- สร้าง Hooks เพิ่มเติม:
- `use-dashboard-stats.ts`
- `use-recent-activity.ts`
- Deliverable: ✅ API Hooks พร้อม
---
## **Phase 3: Correspondence Management (สัปดาห์ที่ 5-6)**
### Milestone: ระบบจัดการเอกสารโต้ตอบ
#### Tasks:
**T3.1 Create Correspondence List Page**
- สร้าง `app/(protected)/correspondences/page.tsx`:
- Data Table แสดงรายการเอกสาร
- Columns:
- Document Number (คลิกไปยัง Detail)
- Title
- Type
- Status (Badge)
- Originator
- Date
- Actions (View, Edit, Delete)
- Filters:
- ประเภทเอกสาร (Dropdown)
- สถานะ (Dropdown)
- วันที่ (Date Range Picker)
- องค์กร (Dropdown)
- Pagination (Server-side)
- Search Box
- Create Button (ตรวจสิทธิ์)
- Deliverable: ✅ หน้ารายการเอกสาร
**T3.2 Create Correspondence Detail Page**
- สร้าง `app/(protected)/correspondences/[id]/page.tsx`:
- **Header Section**:
- Document Number (ใหญ่)
- Status Badge
- Action Buttons: Edit, Delete, Export PDF
- **Metadata Section**:
- Title, Description
- Document Date, Issued Date, Received Date
- Originator, Recipients (TO/CC)
- Due Date (ถ้ามี)
- **Revision History**:
- แสดง Revisions ทั้งหมดเป็น Timeline
- แต่ละ Revision แสดง: Revision Number, Date, Changes, User
- **Attachments**:
- แสดงไฟล์แนบทั้งหมด
- กำหนดไฟล์หลัก (Main Document) ด้วยไอคอน
- ปุ่ม Download
- **References**:
- แสดงเอกสารที่อ้างถึง (Links)
- **Tags**:
- แสดง Tags แบบ Chips
- **Activity Log**:
- แสดง Audit Log ของเอกสารนี้
- Deliverable: ✅ หน้า Detail ครบถ้วน
**T3.3 Create Correspondence Form (Create/Edit)**
- สร้าง `app/(protected)/correspondences/create/page.tsx`:
- สร้าง `app/(protected)/correspondences/[id]/edit/page.tsx`:
- Form Fields:
- **Basic Info**:
- Correspondence Type (Dropdown)
- Title (Text)
- Description (Textarea)
- Document Date (Date Picker)
- **Recipients**:
- TO: Multi-select Organizations
- CC: Multi-select Organizations
- **References**:
- Search & Select เอกสารอื่นๆ
- **Tags**:
- Autocomplete Tag Input
- **Attachments**:
- File Upload (Multi-file)
- กำหนด Main Document (Radio)
- **Deadline**:
- Due Date (Date Picker)
- Validation ด้วย Zod
- Submit → API → Redirect to Detail
- Deliverable: ✅ ฟอร์มสร้าง/แก้ไข
**T3.4 Create Status Management**
- ใน Detail Page เพิ่มปุ่ม Status Actions:
- **Draft → Submit** (Document Control)
- **Submit → Close** (Admin)
- **Submit → Cancel** (Admin + Dialog ให้กรอกเหตุผล)
- แสดง Confirmation Dialog ก่อนเปลี่ยนสถานะ
- Deliverable: ✅ เปลี่ยนสถานะได้
---
## **Phase 4: RFA & Workflow Visualization (สัปดาห์ที่ 7-8)**
### Milestone: ระบบ RFA และ Workflow
#### Tasks:
**T4.1 Create RFA List Page**
- สร้าง `app/(protected)/rfas/page.tsx`:
- คล้าย Correspondence List
- Columns เพิ่มเติม:
- RFA Type (DWG, DOC, MAT)
- Approval Status (Badge)
- Approval Code (1A, 3R, etc.)
- Filters:
- RFA Type
- Status
- Approval Code
- Deliverable: ✅ หน้ารายการ RFA
**T4.2 Create RFA Detail Page**
- สร้าง `app/(protected)/rfas/[id]/page.tsx`:
- คล้าย Correspondence Detail
- เพิ่ม Section:
- **Shop Drawings** (สำหรับ RFA_DWG):
- แสดงรายการ Shop Drawings ที่เชื่อมโยง
- แสดง Revision ของแต่ละแบบ
- Link ไปยัง Shop Drawing Detail
- **Workflow Visualization** (ดูรายละเอียดใน T4.3)
- Deliverable: ✅ หน้า Detail RFA
**T4.3 Create Workflow Visualization Component**
- สร้าง `components/features/rfa/workflow-visualizer.tsx`:
- **Layout**: Steps แนวนอน (Timeline)
- **Step States**:
- ✅ **Completed**: สีเขียว, ไอคอน Check
- ⏳ **Active**: สีฟ้า, ปุ่ม Action เปิดใช้งาน
- ⏸️ **Pending**: สีเทา, ปุ่ม disabled
- ❌ **Rejected**: สีแดง
- **Step Info Card** (เมื่อคลิก):
- Organization
- Assigned User
- Action Type (Review, Approve)
- Status
- Comments
- Completed Date
- **Actions** (สำหรับ Active Step):
- ปุ่ม "อนุมัติ" (Approve)
- ปุ่ม "ปฏิเสธ" (Reject)
- Dialog ให้กรอก Comments
- **Admin Override**:
- ปุ่ม "ไปยังขั้นตอนต่อไป" (Skip Step)
- ปุ่ม "ย้อนกลับ" (Previous Step)
- Deliverable: ✅ Workflow Component พร้อม
**T4.4 Create RFA Form (Create/Edit)**
- สร้าง `app/(protected)/rfas/create/page.tsx`:
- Form Fields:
- RFA Type (Dropdown)
- Title, Description
- Document Date
- **Shop Drawings Section** (สำหรับ RFA_DWG):
- Search & Select Shop Drawings
- แสดง Revisions ที่มี (Dropdown)
- เพิ่มได้หลายแบบ
- Attachments
- Workflow Template (Dropdown)
- Submit → สร้าง RFA + Start Workflow
- Deliverable: ✅ ฟอร์ม RFA พร้อม
**T4.5 Implement Workflow Actions API**
- สร้าง `lib/api/hooks/use-rfa-workflow.ts`:
```typescript
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { apiClient } from "../client";
export function useCompleteWorkflowStep() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ rfaId, stepNumber, action, comments }) => {
const response = await apiClient.post(
`/rfas/${rfaId}/workflow/steps/${stepNumber}/complete`,
{ action, comments }
);
return response.data;
},
onSuccess: (_, variables) => {
queryClient.invalidateQueries(["rfa", variables.rfaId]);
queryClient.invalidateQueries(["my-tasks"]);
},
});
}
```
- Hooks เพิ่มเติม:
- `use-reject-workflow-step.ts`
- `use-start-workflow.ts`
- Deliverable: ✅ Workflow Actions ทำงานได้
---
## **Phase 5: Drawing Management (สัปดาห์ที่ 9)**
### Milestone: ระบบจัดการแบบ
#### Tasks:
**T5.1 Create Shop Drawing List Page**
- สร้าง `app/(protected)/drawings/shop/page.tsx`:
- Data Table:
- Drawing Number
- Title
- Main Category
- Sub Category
- Current Revision
- Actions
- Filters:
- Category (Dropdown)
- Sub Category (Dropdown)
- Create Button
- Deliverable: ✅ หน้ารายการ Shop Drawings
**T5.2 Create Shop Drawing Detail Page**
- สร้าง `app/(protected)/drawings/shop/[id]/page.tsx`:
- **Header**: Drawing Number, Title
- **Current Revision Info**:
- Revision Number, Date
- Description
- Attachments (PDF, DWG)
- **Contract Drawing References**:
- แสดง Contract Drawings ที่อ้างถึง
- Links ไปยัง Contract Drawing Detail
- **Revision History**:
- แสดง Revisions ทั้งหมดเป็น Timeline
- **Related RFAs**:
- แสดง RFAs ที่เชื่อมโยงกับแบบนี้
- Deliverable: ✅ หน้า Detail Shop Drawing
**T5.3 Create Shop Drawing Form**
- สร้าง `app/(protected)/drawings/shop/create/page.tsx`:
- Form Fields:
- Drawing Number (Auto-generate หรือ Manual)
- Title
- Main Category (Dropdown)
- Sub Category (Dropdown, dependent on Main)
- **Contract Drawing References**:
- Search & Select Contract Drawings (Multi-select)
- **Revision Info**:
- Revision Number (Auto)
- Revision Label (A, B, C)
- Description
- **Attachments**:
- Upload PDF (Main)
- Upload DWG (Optional)
- Upload Other Files
- Deliverable: ✅ ฟอร์ม Shop Drawing
**T5.4 Create Contract Drawing List & Detail**
- สร้าง `app/(protected)/drawings/contract/page.tsx`:
- Data Table:
- Drawing Number
- Title
- Volume
- Category
- Sub Category
- Filters:
- Volume (Dropdown)
- Category (Dropdown)
- สร้าง `app/(protected)/drawings/contract/[id]/page.tsx`:
- แสดง Metadata
- Attachments
- **Referenced By**:
- แสดง Shop Drawings ที่อ้างถึงแบบนี้
- Deliverable: ✅ Contract Drawing Pages
---
## **Phase 6: Circulation & Transmittal (สัปดาห์ที่ 10)**
### Milestone: ระบบใบเวียนและเอกสารนำส่ง
#### Tasks:
**T6.1 Create Circulation List Page**
- สร้าง `app/(protected)/circulations/page.tsx`:
- Data Table:
- Circulation Number
- Subject
- Status (Badge)
- Created By
- Created Date
- Filters:
- Status
- Date Range
- Deliverable: ✅ หน้ารายการใบเวียน
**T6.2 Create Circulation Detail & Workflow**
- สร้าง `app/(protected)/circulations/[id]/page.tsx`:
- **Header**: Circulation Number, Subject, Status
- **Linked Correspondence**:
- Link ไปยังเอกสารต้นทาง
- **Workflow Visualization**:
- คล้าย RFA Workflow
- แสดง Steps:
- Organization
- Assigned Users (Main, Action, Information)
- Status
- Comments
- Deadline
- **Actions** (สำหรับ Assigned User):
- ปุ่ม "ดำเนินการเสร็จสิ้น" (Complete)
- Dialog ให้กรอก Comments
- **Close Circulation** (Document Control):
- ปุ่ม "ปิดใบเวียน" (เมื่อตอบกลับองค์กรผู้ส่งแล้ว)
- Deliverable: ✅ หน้า Detail ใบเวียน

View File

@@ -0,0 +1,480 @@
# **Documents Management Sytem Version 1.4.0: แนวทางการพัฒนา FullStackJS**
## **🧠 ปรัชญาทั่วไป**
แนวทางปฏิบัติที่ดีที่สุดแบบครบวงจรสำหรับการพัฒนา NestJS Backend, NextJS Frontend และ Tailwind-based UI/UX ในสภาพแวดล้อม TypeScript มุ่งเน้นที่ ความชัดเจน (clarity), ความง่ายในการบำรุงรักษา (maintainability), ความสอดคล้องกัน (consistency) และ การเข้าถึงได้ (accessibility) ตลอดทั้งสแต็ก
## **⚙️ แนวทางทั่วไปสำหรับ TypeScript**
### **หลักการพื้นฐาน**
* ใช้ **ภาษาอังกฤษ** สำหรับโค้ด
* ใช้ **ภาษาไทย** สำหรับ comment และเอกสารทั้งหมด
* กำหนดไทป์ (type) อย่างชัดเจนสำหรับตัวแปร, พารามิเตอร์ และค่าที่ส่งกลับ (return values) ทั้งหมด
* หลีกเลี่ยงการใช้ any; ให้สร้างไทป์ (types) หรืออินเทอร์เฟซ (interfaces) ที่กำหนดเอง
* ใช้ **JSDoc** สำหรับคลาส (classes) และเมธอด (methods) ที่เป็น public
* ส่งออก (Export) **สัญลักษณ์หลัก (main symbol) เพียงหนึ่งเดียว** ต่อไฟล์
* หลีกเลี่ยงบรรทัดว่างภายในฟังก์ชัน
* ระบุ // File: path/filename ในบรรทัดแรกของทุกไฟล์
* ระบุ // บันทึกการแก้ไข, หากมีการแก้ไขเพิ่มในอนาคต ให้เพิ่มบันทึก
### **ข้อตกลงในการตั้งชื่อ (Naming Conventions)**
| Entity (สิ่งที่ตั้งชื่อ) | Convention (รูปแบบ) | Example (ตัวอย่าง) |
| :---- | :---- | :---- |
| Classes | PascalCase | UserService |
| Property | snake_sase | user_id |
| Variables & Functions | camelCase | getUserInfo |
| Files & Folders | kebab-case | user-service.ts |
| Environment Variables | UPPERCASE | DATABASE\URL |
| Booleans | Verb \+ Noun | isActive, canDelete, hasPermission |
ใช้คำเต็ม — ไม่ใช้อักษรย่อ — ยกเว้นคำมาตรฐาน (เช่น API, URL, req, res, err, ctx)
## **🧩 ฟังก์ชัน (Functions)**
* เขียนฟังก์ชันให้สั้น และทำ **หน้าที่เพียงอย่างเดียว** (single-purpose) (\< 20 บรรทัด)
* ใช้ **early returns** เพื่อลดการซ้อน (nesting) ของโค้ด
* ใช้ **map**, **filter**, **reduce** แทนการใช้ loops เมื่อเหมาะสม
* ควรใช้ **arrow functions** สำหรับตรรกะสั้นๆ, และใช้ **named functions** ในกรณีอื่น
* ใช้ **default parameters** แทนการตรวจสอบค่า null
* จัดกลุ่มพารามิเตอร์หลายตัวให้เป็นอ็อบเจกต์เดียว (RO-RO pattern)
* ส่งค่ากลับ (Return) เป็นอ็อบเจกต์ที่มีไทป์กำหนด (typed objects) ไม่ใช่ค่าพื้นฐาน (primitives)
* รักษาระดับของสิ่งที่เป็นนามธรรม (abstraction level) ให้เป็นระดับเดียวในแต่ละฟังก์ชัน
## **🧱 การจัดการข้อมูล (Data Handling)**
* ห่อหุ้มข้อมูล (Encapsulate) ในไทป์แบบผสม (composite types)
* ใช้ **immutability** (การไม่เปลี่ยนแปลงค่า) ด้วย readonly และ as const
* ทำการตรวจสอบความถูกต้องของข้อมูล (Validations) ในคลาสหรือ DTOs ไม่ใช่ภายในฟังก์ชันทางธุรกิจ
* ตรวจสอบความถูกต้องของข้อมูลโดยใช้ DTOs ที่มีไทป์กำหนดเสมอ
## **🧰 คลาส (Classes)**
* ปฏิบัติตามหลักการ **SOLID**
* ควรใช้ **composition มากกว่า inheritance** (Prefer composition over inheritance)
* กำหนด **interfaces** สำหรับสัญญา (contracts)
* ให้คลาสมุ่งเน้นการทำงานเฉพาะอย่างและมีขนาดเล็ก (\< 200 บรรทัด, \< 10 เมธอด, \< 10 properties)
## **🚨 การจัดการข้อผิดพลาด (Error Handling)**
* ใช้ Exceptions สำหรับข้อผิดพลาดที่ไม่คาดคิด
* ดักจับ (Catch) ข้อผิดพลาดเพื่อแก้ไขหรือเพิ่มบริบท (context) เท่านั้น; หากไม่เช่นนั้น ให้ใช้ global error handlers
* ระบุข้อความข้อผิดพลาด (error messages) ที่มีความหมายเสมอ
## **🧪 การทดสอบ (ทั่วไป) (Testing (General))**
* ใช้รูปแบบ **ArrangeActAssert**
* ใช้ชื่อตัวแปรในการทดสอบที่สื่อความหมาย (inputData, expectedOutput)
* เขียน **unit tests** สำหรับ public methods ทั้งหมด
* จำลอง (Mock) การพึ่งพาภายนอก (external dependencies)
* เพิ่ม **acceptance tests** ต่อโมดูลโดยใช้รูปแบบ GivenWhen-Then
## **🏗️ แบ็กเอนด์ (NestJS) (Backend (NestJS))**
### **หลักการ**
* **สถาปัตยกรรมแบบโมดูลาร์ (Modular architecture)**:
* หนึ่งโมดูลต่อหนึ่งโดเมน
* โครงสร้างแบบ Controller → Service → Repository (Model)
* API-First: มุ่งเน้นการสร้าง API ที่มีคุณภาพสูง มีเอกสารประกอบ (Swagger) ที่ชัดเจนสำหรับ Frontend Team
* DTOs ที่ตรวจสอบความถูกต้องด้วย **class-validator**
* ใช้ **MikroORM** (หรือ TypeORM/Prisma) สำหรับการคงอยู่ของข้อมูล (persistence) ซึ่งสอดคล้องกับสคีมา MariaDB
* ห่อหุ้มโค้ดที่ใช้ซ้ำได้ไว้ใน **common module** (@app/common):
* Configs, decorators, DTOs, guards, interceptors, notifications, shared services, types, validators
### **ฟังก์ชันหลัก (Core Functionalities)**
* Global **filters** สำหรับการจัดการ exception
* **Middlewares** สำหรับการจัดการ request
* **Guards** สำหรับการอนุญาต (permissions) และ RBAC
* **Interceptors** สำหรับการแปลงข้อมูล response และการบันทึก log
### **ข้อจำกัดในการ Deploy (QNAP Container Station)**
* **ห้ามใช้ไฟล์ .env** ในการตั้งค่า Environment Variables [cite: 2.1]
* การตั้งค่าทั้งหมด (เช่น Database connection string, JWT secret) **จะต้องถูกกำหนดผ่าน Environment Variable ใน docker-compose.yml โดยตรง** [cite: 6.5] ซึ่งจะจัดการผ่าน UI ของ QNAP Container Station [cite: 2.1]
### **โครงสร้างโมดูลตามโดเมน (Domain-Driven Module Structure)**
เพื่อให้สอดคล้องกับสคีมา SQL (LCBP3-DMS) เราจะใช้โครงสร้างโมดูลแบบ **Domain-Driven (แบ่งตามขอบเขตธุรกิจ)** แทนการแบ่งตามฟังก์ชัน:
1. **CommonModule:**
* เก็บ Services ที่ใช้ร่วมกัน เช่น DatabaseModule, FileStorageService (จัดการไฟล์ใน QNAP), AuditLogService, NotificationService
* จัดการ audit_logs
* NotificationService ต้องรองรับ Triggers ที่ระบุใน Requirement 6.7 [cite: 6.7]
2. **AuthModule:**
* จัดการะการยืนยันตัวตน (JWT, Guards)
* **(สำคัญ)** ต้องรับผิดชอบการตรวจสอบสิทธิ์ **4 ระดับ** [cite: 4.2]: สิทธิ์ระดับระบบ (Global Role), สิทธิ์ระดับองกรณ์ (Organization Role), สิทธิ์ระดับโปรเจกต์ (Project Role), และ สิทธิ์ระดับสัญญา (Contract Role)
* **(สำคัญ)** ต้องมี API สำหรับ **Admin Panel** เพื่อ:
* สร้างและจัดการ Role และการจับคู่ Permission แบบไดนามิก [cite: 4.3]
* ให้ Superadmin สร้าง Organizations และกำหนด Org Admin ได้ [cite: 4.6]
* ให้ Superadmin/Admin จัดการ document_number_formats (รูปแบบเลขที่เอกสาร), document_number_counters (Running Number) [cite: 3.10]
3. **UserModule:**
* จัดการ users, roles, permissions, global_default_roles, role_permissions, user_roles, user_project_roles
* **(สำคัญ)** ต้องมี API สำหรับ **Admin Panel** เพื่อ:
* สร้างและจัดการ Role และการจับคู่ Permission แบบไดนามิก [cite: 4.3]
4. **ProjectModule:**
* จัดการ projects, organizations, contracts, project_parties, contract_parties
5. **MasterModule:**
* จัดการ master data (correspondence_types, rfa_types, rfa_status_codes, rfa_approve_codes, circulation_status_codes, correspondence_types, correspondence_status, tags) [cite: 4.5]
6. **CorrespondenceModule (โมดูลศูนย์กลาง):**
* จัดการ correspondences, correspondence_revisions, correspondence_tags
* **(สำคัญ)** Service นี้ต้อง Inject DocumentNumberingService เพื่อขอเลขที่เอกสารใหม่ก่อนการสร้าง
* **(สำคัญ)** ตรรกะการสร้าง/อัปเดต Revision จะอยู่ใน Service นี้
* จัดการ correspondence_attachments (ตารางเชื่อมไฟล์แนบ)
* รับผิดชอบ Routing **Correspondence Routing** (correspondence_routings, correspondence_routing_template_steps, correspondence_routing_templates, correspondence_status_transitions) สำหรับการส่งต่อเอกสารทั่วไประหว่างองค์กร
7. **RfaModule:**
* จัดการ rfas, rfa_revisions, rfa_items
* รับผิดชอบเวิร์กโฟลว์ **"RFA Workflows"** (rfa_workflows, rfa_workflow_templates, rfa_workflow_template_steps, rfa_status_transitions) สำหรับการอนุมัติเอกสารทางเทคนิค
8. **DrawingModule:**
* จัดการ shop_drawings, shop_drawing_revisions, contract_drawings, contract_drawing_volumes, contract_drawing_cats, contract_drawing_sub_cats, shop_drawing_main_categories, shop_drawing_sub_categories, contract_drawing_subcat_cat_maps, shop_drawing_revision_contract_refs
* จัดการ shop_drawing_revision_attachments และ contract_drawing_attachments(ตารางเชื่อมไฟล์แนบ)
9. **CirculationModule:**
* จัดการ circulations, circulation_templates, circulation_assignees
* จัดการ circulation_attachments (ตารางเชื่อมไฟล์แนบ)
* รับผิดชอบเวิร์กโฟลว์ **"Circulations"** (circulation_status_transitions, circulation_template_assignees, circulation_assignees, circulation_recipients, circulation_actions, circulation_action_documents)สำหรับการเวียนเอกสาร **ภายในองค์กร**
10. **TransmittalModule:**
* จัดการ transmittals และ transmittal_items
11. **SearchModule:**
* ให้บริการค้นหาขั้นสูง (Advanced Search) [cite: 6.2] โดยใช้ **Elasticsearch** เพื่อรองรับการค้นหาแบบ Full-text จากชื่อเรื่อง, รายละเอียด, เลขที่เอกสาร, ประเภท, วันที่, และ Tags
* ระบบจะใช้ Elasticsearch Engine ในการจัดทำดัชนีเพื่อการค้นหาข้อมูลเชิงลึกจากเนื้อหาของเอกสาร โดยข้อมูลจะถูกส่งไปทำดัชนีจาก Backend (NestJS) ทุกครั้งที่มีการสร้างหรือแก้ไขเอกสาร
12. **DocumentNumberingModule:**
* **สถานะ:** เป็น Module ภายใน (Internal Module) ไม่เปิด API สู่ภายนอก
* **หน้าที่:** ให้บริการ DocumentNumberingService ที่ Module อื่น (เช่น CorrespondenceModule) จะ Inject ไปใช้งาน
* **ตรรกะ:** รับผิดชอบการสร้างเลขที่เอกสาร โดยการเรียกใช้ Stored Procedure *sp_get_next_document_number** เพื่อป้องกัน Race Condition
### **สถาปัตยกรรมระบบ (System Architecture)**
โครงสร้างโมดูล (Module Structure)
```bash
📁 src
├── 📄 app.module.ts
├── 📄 main.ts
├── 📁 common # @app/common (โมดูลส่วนกลาง)
│ ├── 📁 auth # AuthModule (JWT, Guards)
│ ├── 📁 config # Configuration
│ ├── 📁 decorators # Custom Decorators (เช่น @RequirePermission)
│ ├── 📁 entities # Shared Entities (User, Role, Permission)
│ ├── 📁 exceptions # Global Exception Filters
│ ├── 📁 file-storage # FileStorageService
│ ├── 📁 guards # Custom Guards (RBAC Guard)
│ ├── 📁 interceptors # Interceptors (Audit Log, Transform)
│ └── 📁 services # Shared Services (NotificationService)
├── 📁 modules
│ ├── 📁 user # UserModule (จัดการ Users, Roles, Permissions)
│ ├── 📁 project # ProjectModule (จัดการ Projects, Organizations, Contracts)
│ ├── 📁 correspondence # CorrespondenceModule (จัดการเอกสารโต้ตอบ)
│ ├── 📁 rfa # RfaModule (จัดการเอกสารขออนุมัติ)
│ ├── 📁 drawing # DrawingModule (จัดการแบบแปลน)
│ ├── 📁 circulation # CirculationModule (จัดการใบเวียน)
│ ├── 📁 transmittal # TransmittalModule (จัดการเอกสารนำส่ง)
│ ├── 📁 search # SearchModule (ค้นหาขั้นสูงด้วย Elasticsearch)
│ └── 📁 document-numbering # DocumentNumberingModule (Internal Module)
└── 📁 database # Database Migration & Seeding Scripts
```
### **เเทคโนโลยีที่ใช้ (Technology Stack)**
| ส่วน | Library/Tool | หมายเหตุ |
|---|---|---|
| **Framework** | `@nestjs/core`, `@nestjs/common` | Core Framework |
| **Language** | `TypeScript` | ใช้ TypeScript ทั้งระบบ |
| **Database** | `MariaDB 10.11` | ฐานข้อมูลหลัก |
| **ORM** | `@nestjs/typeorm`, `typeorm` | 🗃️จัดการการเชื่อมต่อและ Query ฐานข้อมูล |
| **Validation** | `class-validator`, `class-transformer` | 📦ตรวจสอบและแปลงข้อมูลใน DTO |
| **Auth** | `@nestjs/jwt`, `@nestjs/passport`, `passport-jwt` | 🔐การยืนยันตัวตนด้วย JWT |
|**Authorization** | `casl` | 🔐จัดการสิทธิ์แบบ RBAC |
| **File Upload** | `multer` | 📁จัดการการอัปโหลดไฟล์ |
| **Search** | `@nestjs/elasticsearch` | 🔍สำหรับการค้นหาขั้นสูง |
| **Notification** | `nodemailer` | 📬ส่งอีเมลแจ้งเตือน |
| **Scheduling** | `@nestjs/schedule` | 📬สำหรับ Cron Jobs (เช่น แจ้งเตือน Deadline) |
| **Logging** | `winston` | 📊บันทึก Log ที่มีประสิทธิภาพ |
| **Testing** | `@nestjs/testing`, `jest`, `supertest` | 🧪ทดสอบ Unit, Integration และ E2E |
| **Documentation** | `@nestjs/swagger` | 🌐สร้าง API Documentation อัตโนมัติ |
| **Security** | `helmet`, `rate-limiter-flexible` | 🛡️เพิ่มความปลอดภัยให้ API |
เราจะแบ่งการทดสอบเป็น 3 ระดับ โดยใช้ **Jest** และ @nestjs/testing:
* **Unit Tests (การทดสอบหน่วยย่อย):**
* **เป้าหมาย:** ทดสอบ Logic ภายใน Service, Guard, หรือ Pipe โดยจำลอง (Mock) Dependencies ทั้งหมด
* **สิ่งที่ต้องทดสอบ:** Business Logic (เช่น การเปลี่ยนสถานะ Workflow, การตรวจสอบ Deadline) [cite: 2.9.1], ตรรกะการตรวจสอบสิทธิ์ (Auth Guard) ทั้ง 4 ระดับ
* **Integration Tests (การทดสอบการบูรณาการ):**
* **เป้าหมาย:** ทดสอบการทำงานร่วมกันของ Controller -> Service -> Repository (Database)
* **เทคนิค:** ใช้ **Test Database แยกต่างหาก** (ห้ามใช้ Dev DB) และใช้ supertest เพื่อยิง HTTP Request จริงไปยัง App
* **สิ่งที่ต้องทดสอบ:** การเรียก sp\get\next\document\number [cite: 2.9.3] และการทำงานของ Views (เช่น v_user_tasks)
* **E2E (End-to-End) Tests:**
* **เป้าหมาย:** ทดสอบ API Contract ว่า Response Body Shape ตรงตามเอกสาร Swagger เพื่อรับประกันทีม Frontend
### **🗄️ Backend State Management**
Backend (NestJS) ควรเป็น **Stateless** (ไม่เก็บสถานะ) "State" ทั้งหมดจะถูกจัดเก็บใน MariaDB
* **Request-Scoped State (สถานะภายใน Request เดียว):**
* **ปัญหา:** จะส่งต่อข้อมูล (เช่น User ที่ล็อกอิน) ระหว่าง Guard และ Service ใน Request เดียวกันได้อย่างไร?
* **วิธีแก้:** ใช้ **Request-Scoped Providers** ของ NestJS (เช่น AuthContextService) เพื่อเก็บข้อมูล User ปัจจุบันที่ได้จาก AuthGuard และให้ Service อื่น Inject ไปใช้
* **Application-Scoped State (การ Caching):**
* **ปัญหา:** ข้อมูล Master (เช่น roles, permissions, organizations) ถูกเรียกใช้บ่อย
* **วิธีแก้:** ใช้ **Caching** (เช่น @nestjs/cache-manager) เพื่อ Caching ข้อมูลเหล่านี้ และลดภาระ Database
### **การไหลของข้อมูล (Data Flow)**
1. Request: ผ่าน Nginx Proxy Manager -> NestJS Controller
2. Authentication: JWT Guard ตรวจสอบ Token และดึงข้อมูล User
3. Authorization: RBAC Guard (ใช้ CASL) ตรวจสอบสิทธิ์จาก Decorators (@RequirePermission)
4. Validation: Validation Pipe (ใช้ class-validator) ตรวจสอบ DTO
5. Business Logic: Service Layer ประมวลผลตรรกะทางธุรกิจ
6. Data Access: Repository Layer (ใช้ TypeORM) ติดต่อกับฐานข้อมูล MariaDB
7. Response: ส่งกลับไปยัง Frontend พร้อมสถานะและข้อมูลที่เหมาะสม
# **🖥️ ฟรอนต์เอนด์ (NextJS / React / UI) (Frontend (NextJS / React / UI))**
### **โปรไฟล์นักพัฒนา (Developer Profile)**
วิศวกร TypeScript + React/NextJS ระดับ Senior
เชี่ยวชาญ TailwindCSS, Shadcn/UI, และ Radix สำหรับการพัฒนา UI
### **แนวทางการพัฒนาโค้ด (Code Implementation Guidelines)**
* ใช้ **early returns** เพื่อความชัดเจน
* ใช้คลาสของ **TailwindCSS** ในการกำหนดสไตล์เสมอ
* ควรใช้ class: syntax แบบมีเงื่อนไข (หรือ utility clsx) มากกว่าการใช้ ternary operators ใน class strings
* ใช้ **const arrow functions** สำหรับ components และ handlers
* Event handlers ให้ขึ้นต้นด้วย handle... (เช่น handleClick, handleSubmit)
* รวมแอตทริบิวต์สำหรับการเข้าถึง (accessibility) ด้วย:
tabIndex="0", aria-label, onKeyDown, ฯลฯ
* ตรวจสอบให้แน่ใจว่าโค้ดทั้งหมด **สมบูรณ์**, **ผ่านการทดสอบ**, และ **ไม่ซ้ำซ้อน (DRY)**
* ต้อง import โมดูลที่จำเป็นต้องใช้อย่างชัดเจนเสมอ
### **UI/UX ด้วย React**
* ใช้ **semantic HTML**
* ใช้คลาสของ **Tailwind** ที่รองรับ responsive (sm:, md:, lg:)
* รักษาลำดับชั้นของการมองเห็น (visual hierarchy) ด้วยการใช้ typography และ spacing
* ใช้ **Shadcn** components (Button, Input, Card, ฯลฯ) เพื่อ UI ที่สอดคล้องกัน
* ทำให้ components มีขนาดเล็กและมุ่งเน้นการทำงานเฉพาะอย่าง
* ใช้ utility classes สำหรับการจัดสไตล์อย่างรวดเร็ว (spacing, colors, text, ฯลฯ)
* ตรวจสอบให้แน่ใจว่าสอดคล้องกับ **ARIA** และใช้ semantic markup
### **การตรวจสอบฟอร์มและข้อผิดพลาด (Form Validation & Errors)**
* ใช้ไลบรารีฝั่ง client เช่น zod และ react-hook-form
* แสดงข้อผิดพลาดด้วย **alert components** หรือข้อความ inline
* ต้องมี labels, placeholders, และข้อความ feedback
### **🧪 Frontend Testing**
เราจะใช้ **React Testing Library (RTL)** สำหรับการทดสอบ Component และ **Playwright** สำหรับ E2E:
* **Unit Tests (การทดสอบหน่วยย่อย):**
* **เครื่องมือ:** Vitest + RTL
* **เป้าหมาย:** ทดสอบ Component ขนาดเล็ก (เช่น Buttons, Inputs) หรือ Utility functions
* **Integration Tests (การทดสอบการบูรณาการ):**
* **เครื่องมือ:** RTL + **Mock Service Worker (MSW)**
* **เป้าหมาย:** ทดสอบว่า Component หรือ Page ทำงานกับ API (ที่จำลองขึ้น) ได้ถูกต้อง
* **เทคนิค:** ใช้ MSW เพื่อจำลอง NestJS API และทดสอบว่า Component แสดงผลข้อมูลจำลองได้ถูกต้องหรือไม่ (เช่น ทดสอบหน้า Dashboard [cite: 5.3] ที่ดึงข้อมูลจาก v_user_tasks)
* **E2E (End-to-End) Tests:**
* **เครื่องมือ:** **Playwright**
* **เป้าหมาย:** ทดสอบ User Flow ทั้งระบบโดยอัตโนมัติ (เช่น ล็อกอิน -> สร้าง RFA -> ตรวจสอบ Workflow Visualization [cite: 5.6])
### **🗄️ Frontend State Management**
สำหรับ Next.js App Router เราจะแบ่ง State เป็น 4 ระดับ:
1. **Local UI State (สถานะ UI ชั่วคราว):**
* **เครื่องมือ:** useState, useReducer
* **ใช้เมื่อ:** จัดการสถานะเล็กๆ ที่จบใน Component เดียว (เช่น Modal เปิด/ปิด, ค่าใน Input)
2. **Server State (สถานะข้อมูลจากเซิร์ฟเวอร์):**
* **เครื่องมือ:** **React Query (TanStack Query)** หรือ SWR
* **ใช้เมื่อ:** จัดการข้อมูลที่ดึงมาจาก NestJS API (เช่น รายการ correspondences, rfas, drawings)
* **ทำไม:** React Query เป็น "Cache" ที่จัดการ Caching, Re-fetching, และ Invalidation ให้โดยอัตโนมัติ
3. **Global Client State (สถานะส่วนกลางฝั่ง Client):**
* **เครื่องมือ:** **Zustand** (แนะนำ) หรือ Context API
* **ใช้เมื่อ:** จัดการข้อมูลที่ต้องใช้ร่วมกันทั่วทั้งแอป และ *ไม่ใช่* ข้อมูลจากเซิร์ฟเวอร์ (เช่น ข้อมูล User ที่ล็อกอิน, สิทธิ์ Permissions)
4. **Form State (สถานะของฟอร์ม):**
* **เครื่องมือ:** **React Hook Form** + **Zod**
* **ใช้เมื่อ:** จัดการฟอร์มที่ซับซ้อน (เช่น ฟอร์มสร้าง RFA, ฟอร์ม Circulation [cite: 3.7])
# **🔗 แนวทางการบูรณาการ Full Stack (Full Stack Integration Guidelines)**
| Aspect (แง่มุม) | Backend (NestJS) | Frontend (NextJS) | UI Layer (Tailwind/Shadcn) |
| :---- | :---- | :---- | :---- |
| API | REST / GraphQL Controllers | API hooks ผ่าน fetch/axios/SWR | Components ที่รับข้อมูล |
| Validation (การตรวจสอบ) | class-validator DTOs | zod / react-hook-form | สถานะของฟอร์ม/input ใน Shadcn |
| Auth (การยืนยันตัวตน) | Guards, JWT | NextAuth / cookies | สถานะ UI ของ Auth (loading, signed in) |
| Errors (ข้อผิดพลาด) | Global filters | Toasts / modals | Alerts / ข้อความ feedback |
| Testing (การทดสอบ) | Jest (unit/e2e) | Vitest / Playwright | Visual regression |
| Styles (สไตล์) | Scoped modules (ถ้าจำเป็น) | Tailwind / Shadcn | Tailwind utilities |
| Accessibility (การเข้าถึง) | Guards + filters | ARIA attributes | Semantic HTML |
## **🗂️ ข้อตกลงเฉพาะสำหรับ DMS (LCBP3-DMS)**
ส่วนนี้ขยายแนวทาง FullStackJS ทั่วไปสำหรับโปรเจกต์ **LCBP3-DMS** โดยมุ่งเน้นไปที่เวิร์กโฟลว์การอนุมัติเอกสาร (Correspondence, RFA, Drawing, Contract, Transmittal, Circulation)
### **🧩 RBAC และการควบคุมสิทธิ์ (RBAC & Permission Control)**
ใช้ Decorators เพื่อบังคับใช้สิทธิ์การเข้าถึง โดยอ้างอิงสิทธิ์จากตาราง permissions
@RequirePermission('rfas.respond') // ต้องตรงกับ 'permission\code'
@Put(':id')
updateRFA(@Param('id') id: string) {
return this.rfaService.update(id);
}
### **Roles (บทบาท)**
* **Superadmin**: ไม่มีข้อจำกัดใดๆ [cite: 4.3]
* **Admin**: มีสิทธิ์เต็มที่ในองค์กร [cite: 4.3]
* **Document Control**: เพิ่ม/แก้ไข/ลบ เอกสารในองค์กร [cite: 4.3]
* **Editor**: สามารถ เพิ่ม/แก้ไข เอกสารที่กำหนด [cite: 4.3]
* **Viewer**: สามารถดู เอกสาร [cite: 4.3]
### **ตัวอย่าง Permissions (จากตาราง permissions)**
* rfas.view, rfas.create, rfas.respond, rfas.delete
* drawings.view, drawings.upload, drawings.delete
* corr.view, corr.manage
* transmittals.manage
* cirs.manage
* project\parties.manage
การจับคู่ระหว่าง roles และ permissions **เริ่มต้น** จะถูก seed ผ่านสคริปต์ (ดังที่เห็นในไฟล์ SQL)**อย่างไรก็ตาม AuthModule/UserModule ต้องมี API สำหรับ Admin เพื่อสร้าง Role ใหม่และกำหนดสิทธิ์ (Permissions) เพิ่มเติมได้ในภายหลัง** [cite: 4.3]
## **🧾 มาตรฐาน AuditLog (AuditLog Standard)**
บันทึกการดำเนินการ CRUD และการจับคู่ทั้งหมดลงในตาราง audit_logs
| Field (ฟิลด์) | Type (จาก SQL) | Description (คำอธิบาย) |
| :---- | :---- | :---- |
| audit_id | BIGINT | Primary Key |
| user_id | INT | ผู้ใช้ที่ดำเนินการ (FK -> users) |
| action | VARCHAR(100) | rfa.create, correspondence.update, login.success |
| entity_type | VARCHAR(50) | ชื่อตาราง/โมดูล เช่น 'rfa', 'correspondence' |
| entity_id | VARCHAR(50) | Primary ID ของระเบียนที่ได้รับผลกระทบ |
| details_json | JSON | ข้อมูลบริบท (เช่น ฟิลด์ที่มีการเปลี่ยนแปลง) |
| ip_address | VARCHAR(45) | IP address ของผู้ดำเนินการ |
| user_agent | VARCHAR(255) | User Agent ของผู้ดำเนินการ |
| created_at | TIMESTAMP | Timestamp (UTC) |
## **📂 การจัดการไฟล์ (File Handling) (ปรับปรุงใหม่)**
### **มาตรฐานการอัปโหลดไฟล์ (File Upload Standard)**
* **ตรรกะใหม่:** การอัปโหลดไฟล์ทั้งหมดจะถูกจัดการโดย FileStorageService และบันทึกข้อมูลไฟล์ลงในตาราง attachments (ตารางกลาง)
* ไฟล์จะถูกเชื่อมโยงไปยัง Entity ที่ถูกต้องผ่าน **ตารางเชื่อม (Junction Tables)** เท่านั้น:
* correspondence_attachments (เชื่อม Correspondence กับ Attachments)
* circulation_attachments (เชื่อม Circulation กับ Attachments)
* shop_drawing_revision_attachments (เชื่อม Shop Drawing Revision กับ Attachments)
* contract_drawing_attachments (เชื่อม Contract Drawing กับ Attachments)
* เส้นทางจัดเก็บไฟล์ (Upload path): อ้างอิงจาก Requirement 2.1 คือ /share/dms-data [cite: 2.1] โดย FileStorageService จะสร้างโฟลเดอร์ย่อยแบบรวมศูนย์ (เช่น /share/dms-data/uploads/{YYYY}/{MM}/[stored\filename])
* ประเภทไฟล์ที่อนุญาต: pdf, dwg, docx, xlsx, zip
* ขนาดสูงสุด: **50 MB**
* จัดเก็บนอก webroot
* ให้บริการไฟล์ผ่าน endpoint ที่ปลอดภัย /files/:attachment_id/download
### **การควบคุมการเข้าถึง (Access Control)**
การเข้าถึงไฟล์ไม่ใช่การเข้าถึงโดยตรง endpoint /files/:attachment_id/download จะต้อง:
1. ค้นหาระเบียน attachment
2. ตรวจสอบว่า attachment_id นี้ เชื่อมโยงกับ Entity ใด (เช่น correspondence, circulation, shop_drawing_revision, contract_drawing) ผ่านตารางเชื่อม
3. ตรวจสอบว่าผู้ใช้มีสิทธิ์ (permission) ในการดู Entity ต้นทางนั้นๆ หรือไม่
## **🔟 การจัดการเลขที่เอกสาร (Document Numbering) [cite: 3.10]**
* **เป้าหมาย:** สร้างเลขที่เอกสาร (เช่น correspondence\number) โดยอัตโนมัติ ตามรูปแบบที่กำหนด
* **ตรรกะการนับ:** การนับ Running number (SEQ) จะนับแยกตาม Key: **Project + Originator Organization + Document Type + Year**
* **ตาราง SQL:**
* document_number_formats: Admin ใช้กำหนด "รูปแบบ" (Template) ของเลขที่ (เช่น {ORG\CODE}-{TYPE\CODE}-{YEAR\SHORT}-{SEQ:4}) โดยกำหนดตาม **Project** และ **Document Type** [cite: 4.5]
* document_number_counters: ระบบใช้เก็บ "ตัวนับ" ล่าสุดของ Key (Project+Org+Type+Year)
* **การทำงาน (Backend):**
* DocumentNumberingModule จะให้บริการ DocumentNumberingService
* เมื่อ CorrespondenceModule ต้องการสร้างเอกสารใหม่, มันจะเรียก documentNumberingService.generateNextNumber(...)
* Service นี้จะเรียกใช้ Stored Procedure **sp_get_next_document_number** [cite: 2.9.3] ซึ่ง Procedure นี้จะจัดการ Database Transaction และ Row Lock (FOR UPDATE) ภายใน DB เพื่อรับประกันการป้องกัน Race Condition
## **📊 การรายงานและการส่งออก (Reporting & Exports)**
### **วิวสำหรับการรายงาน (Reporting Views) (จาก SQL)**
การรายงานควรสร้างขึ้นจาก Views ที่กำหนดไว้ล่วงหน้าในฐานข้อมูลเป็นหลัก:
* v_current_correspondences: สำหรับ revision ปัจจุบันทั้งหมดของเอกสารที่ไม่ใช่ RFA
* v_current_rfas: สำหรับ revision ปัจจุบันทั้งหมดของ RFA และข้อมูล master
* v_contract_parties_all: สำหรับการตรวจสอบความสัมพันธ์ของ project/contract/organization
* v_user_tasks: สำหรับ Dashboard "งานของฉัน"
* v_audit_log_details: สำหรับ Activity Feed
Views เหล่านี้ทำหน้าที่เป็นแหล่งข้อมูลหลักสำหรับการรายงานฝั่งเซิร์ฟเวอร์และการส่งออกข้อมูล
### **กฎการส่งออก (Export Rules)**
* Export formats: CSV, Excel, PDF.
* จัดเตรียมมุมมองสำหรับพิมพ์ (Print view).
* รวมลิงก์ไปยังต้นทาง (เช่น /rfas/:id).
## **🧮 ฟรอนต์เอนด์: รูปแบบ DataTable และฟอร์ม (Frontend: DataTable & Form Patterns)**
### **DataTable (ServerSide)**
* Endpoint: /api/{module}?page=1\&pageSize=20\&sort=...\&filter=...
* ต้องรองรับ: การแบ่งหน้า (pagination), การเรียงลำดับ (sorting), การค้นหา (search), การกรอง (filters)
* แสดง revision ล่าสุดแบบ inline เสมอ (สำหรับ RFA/Drawing)
### **มาตรฐานฟอร์ม (Form Standards)**
* ต้องมีการใช้งาน Dropdowns แบบขึ้นต่อกัน (Dependent dropdowns) (ตามที่สคีมารองรับ):
* Project → Contract Drawing Volumes
* Contract Drawing Category → Sub-Category
* RFA (ประเภท Shop Drawing) → Shop Drawing Revisions ที่เชื่อมโยงได้
* **(ใหม่)** การอัปโหลดไฟล์: ต้องรองรับ **Multi-file upload (Drag-and-Drop)** [cite: 5.7]
* **(ใหม่)** UI ต้องอนุญาตให้ผู้ใช้กำหนดว่าไฟล์ใดเป็น **"เอกสารหลัก"** หรือ "เอกสารแนบประกอบ" [cite: 5.7]
* ส่ง (Submit) ผ่าน API พร้อม feedback แบบ toast
### **ข้อกำหนด Component เฉพาะ (Specific UI Requirements)**
* **Dashboard \- My Tasks:** ต้องพัฒนา Component ตาราง "งานของฉัน" (My Tasks)ซึ่งดึงข้อมูลงานที่ผู้ใช้ล็อกอินอยู่ต้องรับผิดชอบ (Main/Action) จาก v\user\tasks [cite: 5.3]
* **Workflow Visualization:** ต้องพัฒนา Component สำหรับแสดงผล Workflow (โดยเฉพาะ RFA)ที่แสดงขั้นตอนทั้งหมดเป็นลำดับ โดยขั้นตอนปัจจุบัน (active) เท่านั้นที่ดำเนินการได้ และขั้นตอนอื่นเป็น disabled [cite: 5.6] ต้องมีตรรกะสำหรับ Admin ในการ override หรือย้อนกลับขั้นตอนได้ [cite: 5.6]
* ** Admin Panel:** ต้องมีหน้า UI สำหรับ Superadmin/Admin เพื่อจัดการข้อมูลหลัก (Master Data [cite: 4.5]), การเริ่มต้นใช้งาน (Onboarding [cite: 4.6]), และ **รูปแบบเลขที่เอกสาร (Numbering Formats [cite: 3.10])**
## **🧭 แดชบอร์ดและฟีดกิจกรรม (Dashboard & Activity Feed)**
### **การ์ดบนแดชบอร์ด (Dashboard Cards)**
* แสดง Correspondences, RFAs, Circulations, Shop Drawing Revision ล่าสุด
* รวมสรุป KPI (เช่น "RFAs ที่รอการอนุมัติ", "Shop Drawing ที่รอการอนุมัติ") [cite: 5.3]
* รวมลิงก์ด่วนไปยังโมดูลต่างๆ
### **ฟีดกิจกรรม (Activity Feed)**
* แสดงรายการ v\audit\log\details ล่าสุด (10 รายการ) ที่เกี่ยวข้องกับผู้ใช้
// ตัวอย่าง API response
[
{ user: 'editor01', action: 'Updated RFA (LCBP3-RFA-001)', time: '2025-11-04T09:30Z' }
]
## **🛡️ ข้อกำหนดที่ไม่ใช่ฟังก์ชันการทำงาน (Non-Functional Requirements)**
ส่วนนี้สรุปข้อกำหนด Non-Functional จาก requirements.md เพื่อให้ทีมพัฒนาทราบ
* **Audit Log [cite: 6.1]:** ทุกการกระทำที่สำคัญ (C/U/D) ต้องถูกบันทึกใน audit_logs
* **Performance [cite: 6.4]:** ต้องใช้ Caching สำหรับข้อมูลที่เรียกบ่อย และใช้ Pagination
* **Security [cite: 6.5]:** ต้องมี Rate Limiting และจัดการ Secret ผ่าน docker-compose.yml (ไม่ใช่ .env)
* **(ใหม่) Backup & Recovery [cite: 6.6]:** ต้องมีแผนสำรองข้อมูลทั้ง Database (MariaDB) และ File Storage (/share/dms-data) อย่างน้อยวันละ 1 ครั้ง
* **(ใหม่) Notification Strategy [cite: 6.7]:** ระบบแจ้งเตือน (Email/Line) ต้องถูก Trigger เมื่อมีเอกสารใหม่ส่งถึง, มีการมอบหมายงานใหม่ (Circulation), หรือ (ทางเลือก) เมื่องานเสร็จ/ใกล้ถึงกำหนด
## **✅ มาตรฐานที่นำไปใช้แล้ว (จาก SQL v1.1.0) (Implemented Standards (from SQL v1.1.0))**
ส่วนนี้ยืนยันว่าแนวทางปฏิบัติที่ดีที่สุดต่อไปนี้เป็นส่วนหนึ่งของการออกแบบฐานข้อมูลอยู่แล้ว และควรถูกนำไปใช้ประโยชน์ ไม่ใช่สร้างขึ้นใหม่
***Soft Delete:** นำไปใช้แล้วผ่านคอลัมน์ deleted_at ในตารางสำคัญ (เช่น correspondences, rfas, project_parties) ตรรกะการดึงข้อมูลต้องกรอง deleted_at IS NULL
***Database Indexes:** สคีมาได้มีการทำ index ไว้อย่างหนักหน่วงบน foreign keys และคอลัมน์ที่ใช้ค้นหาบ่อย (เช่น idx_rr_rfa, idx_cor_project, idx_cr_is_current) เพื่อประสิทธิภาพ
***โครงสร้าง RBAC:** มีระบบ users, roles, permissions, user_roles, และ user_project_roles ที่ครอบคลุมอยู่แล้ว
***Data Seeding:** ข้อมูล Master (roles, permissions, organization_roles, initial users, project parties) ถูกรวมอยู่ในสคริปต์สคีมาแล้ว
## **🧩 การปรับปรุงที่แนะนำ (สำหรับอนาคต) (Recommended Enhancements (Future))**
* ✅ สร้าง Background job (โดยใช้ **n8n** เพื่อเชื่อมต่อกับ **Line** [cite: 2.7] และ/หรือใช้สำหรับการแจ้งเตือน RFA ที่ใกล้ถึงกำหนด due_date [cite: 6.7])
* ✅ เพิ่ม job ล้างข้อมูลเป็นระยะสำหรับ attachments ที่ไม่ถูกเชื่อมโยงกับ Entity ใดๆ เลย (ไฟล์กำพร้า)

View File

@@ -0,0 +1,245 @@
# **📝 Documents Management Sytem Version 1.4.0: Application Requirements Specification**
## **📌 1. วัตถุประสงค์**
สร้างเว็บแอปพลิเคชั่นสำหรับระบบบริหารจัดการเอกสารโครงการ (Document Management System)ที่สามารถจัดการและควบคุม การสื่อสารด้วยเอกสารที่ซับซ้อน อย่างมีประสิทธิภาพ
- มีฟังก์ชันหลักในการอัปโหลด จัดเก็บ ค้นหา แชร์ และควบคุมสิทธิ์การเข้าถึงเอกสาร
- ช่วยลดการใช้เอกสารกระดาษ เพิ่มความปลอดภัยในการจัดเก็บข้อมูล
- เพิ่มความสะดวกในการทำงานร่วมกันระหว่างองกรณ์
## **🛠️ 2. สถาปัตยกรรมและเทคโนโลยี (System Architecture & Technology Stack)**
ใช้สถาปัตยกรรมแบบ Headless/API-First ที่ทันสมัย ทำงานทั้งหมดบน QNAP Server ผ่าน Container Station เพื่อความสะดวกในการจัดการและบำรุงรักษา, Domain: np-dms.work, มี fix ip, รัน docker command ใน application ของ Container Station ได้โดยตรง, ประกอบด้วย
- **2.1. Infrastructure & Environment:**
- Server: QNAP (Model: TS-473A, RAM: 32GB, CPU: AMD Ryzen V1500B)
- Containerization: Container Station (Docker & Docker Compose) ใช้ UI ของ Container Station เป็นหลัก ในการ configuration และการรัน docker command
- Development Environment: VS Code on Windows 11
- Domain: np-dms.work, www.np-dms.work
- ip: 159.192.126.103
- Docker Network: ทุก Service จะเชื่อมต่อผ่านเครือข่ายกลางชื่อ lcbp3 เพื่อให้สามารถสื่อสารกันได้
- Data Storage: /share/dms-data บน QNAP
- ข้อจำกัด: ไม่สามารถใช้ .env ในการกำหนดตัวแปรภายนอกได้ ต้องกำหนดใน docker-compose.yml เท่านั้น
- **2.2. Code Hosting:**
- Application name: git
- Service: Gitea (Self-hosted on QNAP)
- Service name: gitea
- Domain: git.np-dms.work
- หน้าที่: เป็นศูนย์กลางในการเก็บและจัดการเวอร์ชันของโค้ด (Source Code) สำหรับทุกส่วน
- **2.3. Backend / Data Platform:**
- Application name: lcbp3-backend
- Service: NestJS
- Service name: backend
- Domain: backend.np-dms.work
- Framework: NestJS (Node.js, TypeScript, ESM)
- หน้าที่: จัดการโครงสร้างข้อมูล (Data Models), สร้าง API, จัดการสิทธิ์ผู้ใช้ (Roles & Permissions), และสร้าง Workflow ทั้งหมดของระบบ
- **2.4. Database:**
- Application name: lcbp3-db
- Service: mariadb:10.11
- Service name: mariadb
- Domain: db.np-dms.work
- หน้าที่: ฐานข้อมูลหลักสำหรับเก็บข้อมูลทั้งหมด
- Tooling: DBeaver (Community Edition), phpmyadmin สำหรับการออกแบบและจัดการฐานข้อมูล
- **2.5. Database management:**
- Application name: lcbp3-db
- Service: phpmyadmin:5-apache
- Service name: pma
- Domain: pma.np-dms.work
- หน้าที่: จัดการฐานข้อมูล mariadb ผ่าน Web UI
- **2.6. Frontend:**
- Application name: lcbp3-frontend
- Service: next.js
- Service name: frontend
- Domain: lcbp3.np-dms.work
- Framework: Next.js (App Router, React, TypeScript, ESM)
- Styling: Tailwind CSS + PostCSS
- Component Library: shadcn/ui
- หน้าที่: สร้างหน้าตาเว็บแอปพลิเคชันสำหรับให้ผู้ใช้งานเข้ามาดู Dashboard, จัดการเอกสาร, และติดตามงาน โดยจะสื่อสารกับ Backend ผ่าน API
- **2.7. Workflow automation:**
- Application name: lcbp3-n8n
- Service: n8nio/n8n:latest
- Service name: n8n
- Domain: n8n.np-dms.work
- หน้าที่: จัดการ workflow ระหว่าง Backend และ Line
- **2.8. Reverse Proxy:**
- Application name: lcbp3-npm
- Service: Nginx Proxy Manager (nginx-proxy-manage: latest)
- Service name: npm
- Domain: npm.np-dms.work
- หน้าที่: เป็นด่านหน้าในการรับ-ส่งข้อมูล จัดการโดเมนทั้งหมด, ทำหน้าที่เป็น Proxy ชี้ไปยัง Service ที่ถูกต้อง, และจัดการ SSL Certificate (HTTPS) ให้อัตโนมัติ
- **2.9. การจัดการตรรกะทางธุรกิจ (Business Logic Implementation):**
- 2.9.1. ตรรกะทางธุรกิจที่ซับซ้อนทั้งหมด (เช่น การเปลี่ยนสถานะ Workflow [cite: 3.5.4, 3.6.5], การบังคับใช้สิทธิ์ [cite: 4.4], การตรวจสอบ Deadline [cite: 3.2.5]) **จะถูกจัดการในฝั่ง Backend (NestJS)** [cite: 2.3] เพื่อให้สามารถบำรุงรักษาและทดสอบได้ง่าย (Testability)
- 2.9.2. **จะไม่มีการใช้ SQL Triggers** เพื่อป้องกันตรรกะซ่อนเร้น (Hidden Logic) และความซับซ้อนในการดีบัก
- 2.9.3. **ข้อยกเว้น:** ตรรกะเดียวที่จะอยู่ในฐานข้อมูลคือ **Stored Procedure** สำหรับการสร้างเลขที่เอกสาร (Document Numbering) [cite: 3.10] เพื่อป้องกันการซ้ำซ้อนของข้อมูล (Race Condition)
## **📦 3. ข้อกำหนดด้านฟังก์ชันการทำงาน (Functional Requirements)**
- **3.1. การจัดการโครงสร้างโครงการและองค์กร**
- 3.1.1. โครงการ (Projects): ระบบต้องสามารถจัดการเอกสารภายในหลายโครงการได้ (ปัจจุบันมี 4 โครงการ และจะเพิ่มขึ้นในอนาคต)
- 3.1.2. สัญญา (Contracts): ระบบต้องสามารถจัดการเอกสารภายในแต่ละสัญญาได้ ในแต่ละโครงการ มีได้หลายสัญญา หรืออย่างน้อย 1 สัญญา
- 3.1.3. องค์กร (Organizations):
- มีหลายองค์กรในโครงการ องค์กรณ์ที่เป็น Owner, Designer และ Consultant สามารถอยู่ในหลายโครงการและหลายสัญญาได้
- Contractor จะถือ 1 สัญญา และอยู่ใน 1 โครงการเท่านั้น
- **3.2. การจัดการเอกสารโต้ตอบ (Correspondence Management)**
- 3.2.1. วัตถุประสงค์: เอกสารโต้ตอบ (correspondences) ระหว่างองกรณื-องกรณ์ ภายใน โครงการ (Projects) และระหว่าง องค์กร-องค์กร ภายนอก โครงการ (Projects), รองรับ To (ผู้รับหลัก) และ CC (ผู้รับสำเนา) หลายองค์กร
- 3.2.2. ประเภทเอกสาร: ระบบต้องรองรับเอกสารรูปแบบ ไฟล์ PDF หลายประเภท (Types) เช่น จดหมาย (Letter), อีเมล์ (Email), Request for Information (RFI), และสามารถเพิ่มประเภทใหม่ได้ในภายหลัง
- 3.2.3. การสร้างเอกสาร (Correspondence):
- ผู้ใช้ที่มีสิทธิ์ (เช่น Document Control) สามารถสร้างเอกสารรอไว้ในสถานะ ฉบับร่าง" (Draft) ได้ ซึ่งผู้ใช้งานต่างองค์กรจะมองไม่เห็น
- เมื่อกด "Submitted" แล้ว การแก้ไข, ถอนเอกสารกลับไปสถานะ Draft, หรือยกเลิก (Cancel) จะต้องทำโดยผู้ใช้ระดับ Admin ขึ้นไป พร้อมระบุเหตุผล
- 3.2.4. การอ้างอิงและจัดกลุ่ม:
- เอกสารสามารถอ้างถึง (Reference) เอกสารฉบับก่อนหน้าได้หลายฉบับ
- สามารถกำหนด Tag ได้หลาย Tag เพื่อจัดกลุ่มและใช้ในการค้นหาขั้นสูง
- 3.2.5. Routings : ต้องรองรับกระบวนการส่งต่อเอกสาร (Routing) ตามลำดับ เช่น
- ส่งจาก Originator -> Organization 1 -> Organization 2 -> Organization 3 แล้วส่งผลกลับตามลำดับเดิม (โดยถ้า องกรณ์ใดใน Wouting ให้ส่งกลับ ก็สามารถส่งผลกลับตามลำดับเดิมโดยไม่ต้องรอให้ถึง องกรณืในลำดับถัดไป)
- 3.2.6. การจัดการ: มีการจัดการอย่างน้อยดังนี้
- สามารถกำหนดวันแล้วเสร็จ (Deadline) สำหรับผู้รับผิดชอบของ องกรณ์ ที่เป็นผู้รับได้
- มีระบบแจ้งเตือน ให้ผู้รับผิดชอบขององกรณ์ที่เป็น ผู้รับ/ผู้ส่ง ทราบ เมื่อมีเอกสารใหม่ หรือมีการเปลี่ยนสถานะ
- **3.3. การจัดกาแบบคู่สัญญา (Contract Drawing)**
- 3.3.1. วัตถุประสงค์: แบบคู่สัญญา (Contract Drawing) ใช้เพื่ออ้างอิงและใช้ในการตรวจสอบ
- 3.3.2. ประเภทเอกสาร: ไฟล์ PDF
- 3.3.3. การสร้างเอกสาร: ผู้ใช้ที่มีสิทธิ์ สามารถสร้างและแก้ไขได้
- 3.3.4. การอ้างอิงและจัดกลุ่ม: ใช้สำหรับอ้างอิง ใน Shop Drawings, มีการจัดหมวดหมู่ของ Contract Drawing
- **3.4. การจัดกาแบบก่อสร้าง (Shop Drawing)**
- 3.4.1. วัตถุประสงค์: แบบก่อสร้าง (Shop Drawing) ใช้เในการตรวจสอบ โดยจัดส่งด้วย Request for Approval (RFA)
- 3.4.2. ประเภทเอกสาร: ไฟล์ PDF
- 3.4.3. การสร้างเอกสาร: ผู้ใช้ที่มีสิทธิ์ สามารถสร้างและแก้ไขได้
- 3.4.4. การอ้างอิงและจัดกลุ่ม: ช้สำหรับอ้างอิง ใน Shop Drawings, มีการจัดหมวดหมู่ของ Shop Drawings
- **3.5. การจัดการเอกสารขออนุมัติ (Request for Approval & Workflow)**
- 3.5.1. วัตถุประสงค์: เอกสารขออนุมัติ (Request for Approval) ใช้ในการส่งเอกสารเพิอขออนุมัติ
- 3.5.2. ประเภทเอกสาร: Request for Approval (RFA) เป็นชนิดหนึ่งของ Correspondence ที่มีลักษณะเฉพาะที่ต้องได้รับการอนุมัติ มีประเภทดังนี้:
- Request for Drawing Approval (RFA_DWG)
- Request for Document Approval (RFA_DOC)
- Request for Method statement Approval (RFA_MES)
- Request for Material Approval (RFA_MAT)
- 3.5.2. การสร้างเอกสาร: ผู้ใช้ที่มีสิทธิ์ สามารถสร้างและแก้ไขได้
- 3.5.4. การอ้างอิงและจัดกลุ่ม: การจัดการ Drawing (RFA_DWG):
- เอกสาร RFA_DWG จะประกอบไปด้วย Shop Drawing (shop_drawings) หลายแผ่น ซึ่งแต่ละแผ่นมี Revision ของตัวเอง
- Shop Drawing แต่ละ Revision สามารถอ้างอิงถึง Contract Drawing (Ccontract_drawings) หลายแผ่น หรือไม่อ้างถึงก็ได้
- ระบบต้องมีส่วนสำหรับจัดการข้อมูล Master Data ของทั้ง Shop Drawing และ Contract Drawing แยกจากกัน
- 3.6.5. Workflow การอนุมัติ: ต้องรองรับกระบวนการอนุมัติที่ซับซ้อนและเป็นลำดับ เช่น
- ส่งจาก Originator -> Organization 1 -> Organization 2 -> Organization 3 แล้วส่งผลกลับตามลำดับเดิม (โดยถ้า องกรณ์ใดใน Workflow ให้ส่งกลับ ก็สามารถส่งผลกลับตามลำดับเดิมโดยไม่ต้องรอให้ถึง องกรณืในลำดับถัดไป)
- 3.6.6. การจัดการ: มีการจัดการอย่างน้อยดังนี้
- สามารถกำหนดวันแล้วเสร็จ (Deadline) สำหรับผู้รับผิดชอบของ องกรณ์ ที่อยู่ใน Workflow ได้
- มีระบบแจ้งเตือน ให้ผู้รับผิดชอบของ องกรณ์ ที่อยู่ใน Workflow ทราบ เมื่อมี RFA ใหม่ หรือมีการเปลี่ยนสถานะ
- **3.6.การจัดการเอกสารนำส่ง (Transmittals)**
- 3.6.1. วัตถุประสงค์: เอกสารนำส่ง ใช้สำหรับ นำส่ง Request for Approval (RFAS) หลายฉบับ ไปยังองค์กรอื่น
- 3.6.2. ประเภทเอกสาร: ไฟล์ PDF
- 3.6.3. การสร้างเอกสาร: ผู้ใช้ที่มีสิทธิ์ สามารถสร้างและแก้ไขได้
- 3.6.4. การอ้างอิงและจัดกลุ่ม: เอกสารนำส่ง เป็นส่วนหนึ่งใน Correspondence
- **3.7. ใบเวียนเอกสาร (Circulation Sheet)**
- 3.7.1. วัตถุประสงค์: การสื่อสาร เอกสาร (Correspondence) ทุกฉบับ จะมีใบเวียนเอกสารเพื่อควบคุมและมอบหมายงานภายในองค์กร (สามารถดูและแก้ไขได้เฉพาะคนในองค์กร)
- 3.7.2. ประเภทเอกสาร: ไฟล์ PDF
- 3.7.3. การสร้างเอกสาร: ผู้ใช้ที่มีสิทธิ์ในองค์กรนั้น สามารถสร้างและแก้ไขได้
- 3.7.4. การอ้างอิงและจัดกลุ่ม: การระบุผู้รับผิดชอบ:
- ผู้รับผิดชอบหลัก (Main): มีได้หลายคน
- ผู้ร่วมปฏิบัติงาน (Action): มีได้หลายคน
- ผู้ที่ต้องรับทราบ (Information): มีได้หลายคน
- 3.7.5. การติดตามงาน:
- สามารถกำหนดวันแล้วเสร็จ (Deadline) สำหรับผู้รับผิดชอบประเภท Main และ Action ได้
- มีระบบแจ้งเตือนเมื่อมี Circulation ใหม่ และแจ้งเตือนล่วงหน้าก่อนถึงวันแล้วเสร็จ
- สามารถปิด Circulation ได้เมื่อดำเนินการตอบกลับไปยังองค์กรผู้ส่ง (Originator) แล้ว หรือ รับทราบแล้ว (For Information)
- **3.8. ประวัติการแก้ไข (Revisions):** ระบบจะเก็บประวัติการสร้างและแก้ไข เอกสารทั้งหมด
- **3.9. การจัดเก็บ: (ปรับปรุงตามสถาปัตยกรรมใหม่)**
- เอกสารและไฟล์แนบทั้งหมดจะถูกจัดเก็บในโฟลเดอร์บน Server (/share/dms-data/) [cite: 2.1]
- ข้อมูล Metadata ของไฟล์ (เช่น ชื่อไฟล์, ขนาด, path) จะถูกเก็บในตาราง attachments (ตารางกลาง)
- ไฟล์จะถูกเชื่อมโยงกับเอกสารประเภทต่างๆ ผ่านตารางเชื่อม (Junction tables) เช่น correspondence_attachments, circulation_attachments, shop_drawing_revision_attachments ,และ contracy_drawing_attachments
- สถาปัตยกรรมแบบรวมศูนย์นี้ _แทนที่_ แนวคิดเดิมที่จะแยกโฟลเดอร์ตามประเภทเอกสาร เพื่อรองรับการขยายระบบที่ดีกว่า
- **3.10. การจัดการเลขที่เอกสาร (Document Numbering):**
- 3.10.1. ระบบต้องสามารถสร้างเลขที่เอกสาร (เช่น correspondence_number) ได้โดยอัตโนมัติ
- 3.10.2. การนับเลข Running Number (SEQ) จะต้องนับแยกตาม Key ดังนี้: **โครงการ (Project)**, **องค์กรผู้ส่ง (Originator Organization)**, **ประเภทเอกสาร (Document Type)** และ **ปีปัจจุบัน (Year)**
- 3.10.3. ผู้ดูแลระบบ (Admin) ต้องสามารถกำหนด "รูปแบบ" (Format Template) ของเลขที่เอกสารได้ (เช่น {ORG_CODE}-{TYPE_CODE}-{YEAR_SHORT}-{SEQ:4}) โดยกำหนดแยกตามโครงการและประเภทเอกสาร
## **🔐 4. ข้อกำหนดด้านสิทธิ์และการเข้าถึง (Access Control Requirements)**
- **4.1. ภาพรวม:** ผู้ใช้และองค์กรสามารถดูและแก้ไขเอกสารได้ตามสิทธิ์ที่ได้รับ โดยระบบสิทธิ์จะเป็นแบบ Role-Based Access Control (RBAC)
- **4.2. ลำดับชั้นของสิทธิ์ (Permission Hierarchy)**
- Global: สิทธิ์สูงสุดของระบบ
- Organization: สิทธิ์ภายในองค์กร เป็นสิทธิ์พื้นฐานของผู้ใช้
- Project: สิทธิ์เฉพาะในโครงการ จะถูกพิจารณาเมื่อผู้ใช้อยู่ในโครงการนั้น
- Contract: สิทธิ์เฉพาะในสัญญา จะถูกพิจารณาเมื่อผู้ใช้อยู่ในสัญญานั้น (สัญญาเป็นส่วนหนึ่งของโครงการ)
กฎการบังคับใช้: เมื่อตรวจสอบสิทธิ์ ระบบจะพิจารณาสิทธิ์จากทุกระดับที่ผู้ใช้มี และใช้ สิทธิ์ที่มากที่สุด (Most Permissive) เป็นตัวตัดสิน
ตัวอย่าง: ผู้ใช้ A เป็น Viewer ในองค์กร แต่ถูกมอบหมายเป็น Editor ในโครงการ X เมื่ออยู่ในโครงการ X ผู้ใช้ A จะมีสิทธิ์แก้ไขได้
- **4.3. การกำหนดบทบาท (Roles) และขอบเขต (Scope)**
| บทบาท (Role) | ขอบเขต (Scope) | คำอธิบาย | สิทธิ์หลัก (Key Permissions) |
| :------------------- | :------------- | :---------------------- | :------------------------------------------------------------------------------------- |
| **Superadmin** | Global | ผู้ดูแลระบบสูงสุด | ทำทุกอย่างในระบบ, จัดการองค์กร, จัดการข้อมูลหลักระดับ Global |
| **Org Admin** | Organization | ผู้ดูแลองค์กร | จัดการผู้ใช้ในองค์กร, จัดการบทบาท/สิทธิ์ภายในองค์กร, ดูรายงานขององค์กร |
| **Document Control** | Organization | ควบคุมเอกสารขององค์กร | เพิ่ม/แก้ไข/ลบเอกสาร, กำหนดสิทธิ์เอกสารภายในองค์กร |
| **Editor** | Organization | ผู้แก้ไขเอกสารขององค์กร | เพิ่ม/แก้ไขเอกสารที่ได้รับมอบหมาย |
| **Viewer** | Organization | ผู้ดูเอกสารขององค์กร | ดูเอกสารที่มีสิทธิ์เข้าถึง |
| **Project Manager** | Project | ผู้จัดการโครงการ | จัดการสมาชิกในโครงการ (เพิ่ม/ลบ/มอบบทบาท), สร้าง/จัดการสัญญาในโครงการ, ดูรายงานโครงการ |
| **Contract Admin** | Contract | ผู้ดูแลสัญญา | จัดการสมาชิกในสัญญา, สร้าง/จัดการข้อมูลหลักเฉพาะสัญญา (ถ้ามี), อนุมัติเอกสารในสัญญา |
- **4.4. กระบวนการเริ่มต้นใช้งาน (Onboarding Workflow) ที่สมบูรณ์**
- 4.1. **สร้างองค์กร (Organization)**
- **Superadmin** สร้างองค์กรใหม่ (เช่น บริษัท A)
- **Superadmin** แต่งตั้งผู้ใช้อย่างน้อย 1 คนให้เป็น **Org Admin** หรือ **Document Control** ของบริษัท A
- 4.2. **เพิ่มผู้ใช้ในองค์กร**
- **Org Admin** ของบริษัท A เพิ่มผู้ใช้อื่นๆ (Editor, Viewer) เข้ามาในองค์กรของตน
- 4.3. **มอบหมายผู้ใช้ให้กับโครงการ (Project)**
- **Project Manager** ของโครงการ X (ซึ่งอาจมาจากบริษัท A หรือบริษัทอื่น) ทำการ "เชิญ" หรือ "มอบหมาย" ผู้ใช้จากองค์กรต่างๆ ที่เกี่ยวข้องเข้ามาในโครงการ X
- ในขั้นตอนนี้ **Project Manager** จะกำหนด **บทบาทระดับโครงการ** (เช่น Project Member, หรืออาจไม่มีบทบาทพิเศษ ให้ใช้สิทธิ์จากระดับองค์กรไปก่อน)
- 4.4. **เมอบหมายผู้ใช้ให้กับสัญญา (Contract)**
- **Contract Admin** ของสัญญา Y (ซึ่งเป็นส่วนหนึ่งของโครงการ X) ทำการเลือกผู้ใช้ที่อยู่ในโครงการ X แล้ว มอบหมายให้เข้ามาในสัญญา Y
- ในขั้นตอนนี้ **Contract Admin** จะกำหนด **บทบาทระดับสัญญา** (เช่น Contract Member) และสิทธิ์เฉพาะที่จำเป็น
- **4.5. การจัดการข้อมูลหลัก (Master Data Management) ที่แบ่งตามระดับ**
| ข้อมูลหลัก | ผู้มีสิทธิ์จัดการ | ระดับ |
| :---------------------------------- | :------------------------------ | :--------------------------------- |
| ประเภทเอกสาร (Correspondence, RFA) | **Superadmin** | Global |
| สถานะเอกสาร (Draft, Approved, etc.) | **Superadmin** | Global |
| หมวดหมู่แบบ (Shop Drawing) | **Project Manager** | Project (สร้างใหม่ได้ภายในโครงการ) |
| Tags | **Org Admin / Project Manager** | Organization / Project |
| บทบาทและสิทธิ์ (Custom Roles) | **Superadmin / Org Admin** | Global / Organization |
## **👥 5. ข้อกำหนดด้านผู้ใช้งาน (User Interface & Experience)**
- **5.1. Layout หลัก:** หน้าเว็บใช้รูปแบบ App Shell ที่ประกอบด้วย:
- Navbar (ส่วนบน): แสดงชื่อระบบ, เมนูผู้ใช้ (Profile), เมนูสำหรับ Document Control/เมนูสำหรับ Admin/Superadmin (จัดการผู้ใช้, จัดการสิทธิ์), และปุ่ม Login/Logout
- Sidebar (ด้านข้าง): เป็นเมนูหลักสำหรับเข้าถึงส่วนที่เกี่ยวกับเอกสารทั้งหมด เช่น Dashboard, Correspondences, RFA, Drawings
- Main Content Area: พื้นที่สำหรับแสดงเนื้อหาหลักของหน้าที่เลือก
- **5.2. หน้า Landing Page:** เป็นหน้าแรกที่แสดงข้อมูลบางส่วนของโครงการสำหรับผู้ใช้ที่ยังไม่ได้ล็อกอิน
- **5.3. หน้า Dashboard:** เป็นหน้าแรกหลังจากล็อกอิน ประกอบด้วย:
- การ์ดสรุปภาพรวม (KPI Cards): แสดงข้อมูลสรุปที่สำคัญขององค์กร เช่น จำนวนเอกสาร, งานที่เกินกำหนด
- ตาราง "งานของฉัน" (My Tasks Table): แสดงรายการงานทั้งหมดจาก Circulation ที่ผู้ใช้ต้องดำเนินการ
- **5.4. การติดตามสถานะ:** องค์กรสามารถติดตามสถานะเอกสารทั้งของตนเอง (Originator) และสถานะเอกสารที่ส่งมาถึงตนเอง (Recipient)
- **5.5. การจัดการข้อมูลส่วนตัว (Profile Page):** ผู้ใช้สามารถจัดการข้อมูลส่วนตัวและเปลี่ยนรหัสผ่านของตนเองได้
- **5.6. การจัดการเอกสารทางเทคนิค (RFA & Workflow):** ผู้ใช้สามารถดู RFA ในรูปแบบ Workflow ทั้งหมดได้ในหน้าเดียว, ขั้นตอนที่ยังไม่ถึงหรือผ่านไปแล้วจะเป็นรูปแบบ diable, สามารถดำเนินการได้เฉพาะในขั้นตอนที่ได้รับมอบหมายงาน (active) เช่น ตรวจสอบแล้ว เพื่อไปยังขั้นตอนต่อไป, สิทธิ์ Document Control ขึ้นไป สามรถกด ไปยังขั้นตอนต่อไป ได้ทุกขั้นตอน, การย้อนกลับ ไปขั้นตอนก่อนหน้า สามารถทำได้โดย สิทธิ์ Document Control ขึ้นไป
- **5.7. การจัดการใบเวียนเอกสาร (Circulation):** ผู้ใช้สามารถดู Circulation ในรูปแบบ Workflow ทั้งหมดได้ในหน้าเดียว,ขั้นตอนที่ยังไม่ถึงหรือผ่านไปแล้วจะเป็นรูปแบบ diable, สามารถดำเนินการได้เฉพาะในขั้นตอนที่ได้รับมอบหมายงาน (active) เช่น ตรวจสอบแล้ว เพื่อไปยังขั้นตอนต่อไป, สิทธิ์ Document Control ขึ้นไป สามรถกด ไปยังขั้นตอนต่อไป ได้ทุกขั้นตอน, การย้อนกลับ ไปขั้นตอนก่อนหน้า สามารถทำได้โดย สิทธิ์ Document Control ขึ้นไป
- **5.8. การจัดการเอกสารนำส่ง (Transmittals):** ผู้ใช้สามารถดู Transmittals ในรูปแบบรายการทั้งหมดได้ในหน้าเดียว
- **5.9. ข้อกำหนด UI/UX การแนบไฟล์ (File Attachment UX):**
- ระบบต้องรองรับการอัปโหลดไฟล์หลายไฟล์พร้อมกัน (Multi-file upload) เช่น การลากและวาง (Drag-and-Drop)
- ในหน้าอัปโหลด (เช่น สร้าง RFA หรือ Correspondence) ผู้ใช้ต้องสามารถกำหนดได้ว่าไฟล์ใดเป็น "เอกสารหลัก" (Main Document เช่น PDF) และไฟล์ใดเป็น "เอกสารแนบประกอบ" (Supporting Attachments เช่น .dwg, .docx, .zip)
## **6. ข้อกำหนดที่ไม่ใช่ฟังก์ชันการทำงาน (Non-Functional Requirements)**
- **6.1. การบันทึกการกระทำ (Audit Log):** ทุกการกระทำที่สำคัญของผู้ใช้ (สร้าง, แก้ไข, ลบ, ส่ง) จะถูกบันทึกไว้ใน audit_logs เพื่อการตรวจสอบย้อนหลัง
- **6.2. การค้นหา (Search):** ระบบต้องมีฟังก์ชันการค้นหาขั้นสูง ที่สามารถค้นหาเอกสาร **correspondence**, **rfa**, **shop_drawing**, **contract-drawing**, **transmittal** และ **ใบเวียน (Circulations)** จากหลายเงื่อนไขพร้อมกันได้ เช่น ค้นหาจากชื่อเรื่อง, ประเภท, วันที่, และ Tag
- **6.3. การทำรายงาน (Reporting):** สามารถจัดทำรายงานสรุปแยกประเภทของ Correspondence ประจำวัน, สัปดาห์, เดือน, และปีได้
- **6.4. ประสิทธิภาพ (Performance):** มีการใช้ Caching กับข้อมูลที่เรียกใช้บ่อย และใช้ Pagination ในตารางข้อมูลเพื่อจัดการข้อมูลจำนวนมาก
- **6.5. ความปลอดภัย (Security):**
- มีระบบ Rate Limiting เพื่อป้องกันการโจมตีแบบ Brute-force
- การจัดการ Secret (เช่น รหัสผ่าน DB, JWT Secret) จะต้องทำผ่าน Environment Variable ของ Docker เพื่อความปลอดภัยสูงสุด
- **6.6. การสำรองข้อมูลและการกู้คืน (Backup & Recovery):**
- ระบบจะต้องมีกลไกการสำรองข้อมูลอัตโนมัติสำหรับฐานข้อมูล MariaDB [cite: 2.4] และไฟล์เอกสารทั้งหมดใน /share/dms-data [cite: 2.1] (เช่น ใช้ HBS 3 ของ QNAP หรือสคริปต์สำรองข้อมูล) อย่างน้อยวันละ 1 ครั้ง
- ต้องมีแผนการกู้คืนระบบ (Disaster Recovery Plan) ในกรณีที่ Server หลัก (QNAP) ใช้งานไม่ได้
- **6.7. กลยุทธ์การแจ้งเตือน (Notification Strategy):**
- ระบบจะส่งการแจ้งเตือน (ผ่าน Email หรือ Line [cite: 2.7]) เมื่อมีการกระทำที่สำคัญ ดังนี้:
1. เมื่อมีเอกสารใหม่ (Correspondence, RFA) ถูกส่งมาถึงองค์กรณ์ของเรา
2. เมื่อมีใบเวียน (Circulation) ใหม่ มอบหมายงานมาที่เรา
3. (ทางเลือก) เมื่อเอกสารที่เราส่งไป ถูกดำเนินการ (เช่น อนุมัติ/ปฏิเสธ)
4. (ทางเลือก) เมื่อใกล้ถึงวันครบกำหนด (Deadline) [cite: 3.2.5, 3.6.6, 3.7.5]