260322:1648 Correct Coresspondence / Doing RFA / Correct CI
This commit is contained in:
@@ -8,16 +8,19 @@ status: first-draft
|
||||
owner: Nattanin Peancharoen
|
||||
last_updated: 2026-02-23
|
||||
related:
|
||||
- specs/01-requirements/01-objectives.md
|
||||
- specs/03-implementation/03-01-fullftack-js-v1.7.0.md
|
||||
|
||||
- specs/01-requirements/01-objectives.md
|
||||
- specs/03-implementation/03-01-fullftack-js-v1.7.0.md
|
||||
|
||||
---
|
||||
|
||||
## 1. 📋 ภาพรวมระบบ (System Overview)
|
||||
|
||||
ระบบ LCBP3-DMS (Laem Chabang Port Phase 3 - Document Management System) ถูกออกแบบด้วยสถาปัตยกรรมแบบ **Headless/API-First Architecture** โดยทำงานแบบ **On-Premise 100%** บนเครื่องเซอร์ฟเวอร์ QNAP และ ASUSTOR
|
||||
ระบบทั้งหมดทำงานอยู่ภายใต้สภาวะแวดล้อมแบบ **Container Isolation** (ผ่าน Container Station) เพื่อความปลอดภัย, ง่ายต่อการจัดการ, และไม่ยึดติดกับ Hardware (Hardware Agnostic)
|
||||
|
||||
### 1.1 Architecture Principles
|
||||
|
||||
1. **Data Integrity First:** ความถูกต้องของข้อมูลต้องมาก่อนทุกอย่าง
|
||||
2. **Security by Design & Container Isolation:** รักษาความปลอดภัยที่ทุกชั้น และแยกส่วนการทำงานของแต่ละระบบอย่างชัดเจน (Network Segmentation & Containerization)
|
||||
3. **On-Premise First:** ข้อมูลและระบบงานทั้งหมดต้องอยู่ภายในเครือข่ายของโครงการเท่านั้น
|
||||
@@ -27,6 +30,7 @@ related:
|
||||
## 2. 🏢 มาตรฐานการติดตั้ง On-Premise (QNAP/ASUSTOR Installation Standards)
|
||||
|
||||
### 2.1 Hardware Infrastructure
|
||||
|
||||
- **Primary Server (QNAP TS-473A):**
|
||||
- IP: 192.168.10.8 (VLAN 10)
|
||||
- Role: Primary NAS for DMS, Container Host
|
||||
@@ -37,7 +41,9 @@ related:
|
||||
- **Network Interface:** NAS ทั้งสองตัวใช้ LACP bonding แบบ IEEE 802.3ad เพื่อเพิ่ม bandwidth และ redundancy
|
||||
|
||||
### 2.2 Container Isolation & Environment
|
||||
|
||||
อ้างอิงข้อจำกัดและมาตรฐานของระบบ Container Station บน QNAP:
|
||||
|
||||
- **Containerization Engine:** Docker & Docker Compose
|
||||
- **Network Isolation:** ทุกคอนเทนเนอร์ (Frontend, Backend, Database, Redis, Search) จะต้องเชื่อมต่อกันผ่าน Internal Docker Network ชื่อ `lcbp3` เท่านั้น ห้าม Expose Port ออกสู่ภายนอกโดยไม่จำเป็น
|
||||
- **Reverse Proxy:** ใช้ Nginx Proxy Manager (`npm.np-dms.work`) เป็น Gateway (Load Balancer & SSL Termination) รับ Traffic เพียงจุดเดียวบน Port 80/443 และ Map เข้าสู่ Internal Docker Network
|
||||
@@ -51,6 +57,7 @@ related:
|
||||
ระบบจัดแบ่งเครือข่ายออกเป็น VLANs ต่างๆ เพื่อการควบคุมการเข้าถึงตามหลักการ Zero Trust ย่อยๆ โดยใช้อุปกรณ์เครือข่าย (ER7206 Router & SG2428P Core Switch) ในการบังคับใช้ ACL:
|
||||
|
||||
### 3.1 VLAN Configuration
|
||||
|
||||
| VLAN ID | Name | Purpose | Subnet | Gateway | Notes |
|
||||
| ------- | ------ | ------------------ | --------------- | ------------ | ----------------------------------------- |
|
||||
| 10 | SERVER | Server & Storage | 192.168.10.0/24 | 192.168.10.1 | Servers (QNAP, ASUSTOR). Static IPs ONLY. |
|
||||
@@ -62,6 +69,7 @@ related:
|
||||
| 70 | GUEST | Guest Wi-Fi | 192.168.70.0/24 | 192.168.70.1 | Isolated Internet Access only. |
|
||||
|
||||
### 3.2 Network ACL & Isolation Rules
|
||||
|
||||
- **SERVER Isolation:** `VLAN 30 (USER)` สามารถเข้าถึง `VLAN 10 (SERVER)` ได้เฉพาะพอร์ตที่จำเป็น (HTTP/HTTPS/SSH)
|
||||
- **MGMT Restriction:** ไม่อนุญาตให้ `VLAN 30 (USER)` เข้าถึง `VLAN 20 (MGMT)` โดยเด็ดขาด
|
||||
- **Device Isolation:** `CCTV`, `VOICE`, และ `GUEST` แยกขาดออกจากวงอื่นๆ (Deny-All to Internal)
|
||||
@@ -83,6 +91,7 @@ related:
|
||||
| **Search** | - | - | Elasticsearch | Full-text Indexing |
|
||||
|
||||
## 5. 📊 Data Flow & Interactions
|
||||
|
||||
1. **User Request:** ผู้ใช้งานส่ง Request ไปที่โดเมนผ่าน HTTP/HTTPS
|
||||
2. **Reverse Proxy:** Nginx Proxy Manager รับ Request, ตรวจสอบ SSL, และ Forward ไปให้ Frontend หรือ Backend ในวง Docker Network
|
||||
3. **API Processing:** Backend รัน Business Logic, ประมวลผล Authentication (JWT) และ Permissions (RBAC via Redis Cache)
|
||||
@@ -90,6 +99,7 @@ related:
|
||||
5. **Storage Process:** ไฟล์ถูกคัดกรองผ่าน ClamAV (ถ้ามี) และเก็บลง Storage `/share/dms-data` บน QNAP แบบ Two-Phase Storage (Temp -> Permanent) เพื่อป้องกัน Orphan Files
|
||||
|
||||
## 6. 💾 Backup & Disaster Recovery (DR)
|
||||
|
||||
- **Database Backup:** ทำ Automated Backup รายวันด้วย QNAP HBS 3 หรือ mysqldump
|
||||
- **File Backup:** ทำ Snapshot หรือ rsync จาก `/share/dms-data` บนเครื่องหลัก (QNAP) ไปยังเครื่องสำรอง (ASUSTOR) อย่างสม่ำเสมอ
|
||||
- **Recovery Standard:** หาก NAS พัง สามารถ Restore Config ย้ายข้อมูล และรัน `docker-compose up` ขึ้นใหม่บนเครื่อง Backup ได้ทันที เนื่องจาก Architecture ออกแบบแบบ Stateless สำหรับตัวแอพพลิเคชั่น และ Data แยกลง Volume Storage ชัดเจน
|
||||
|
||||
@@ -8,13 +8,15 @@ status: first-draft
|
||||
owner: Nattanin Peancharoen
|
||||
last_updated: 2026-02-23
|
||||
related:
|
||||
- specs/02-Architecture/00-01-system-context.md
|
||||
|
||||
- specs/02-Architecture/00-01-system-context.md
|
||||
|
||||
---
|
||||
|
||||
## 1. 🧱 Backend Module Architecture (NestJS)
|
||||
|
||||
### 1.1 Modular Design
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "Core Modules"
|
||||
@@ -52,21 +54,27 @@ graph TB
|
||||
### 1.2 Key Architectural Patterns
|
||||
|
||||
#### Unified Workflow Engine (DSL-Based)
|
||||
|
||||
ระบบการเดินเอกสาร (Correspondence, RFA, Circulation) ใช้ Engine กลางเดียวกัน ผ่าน **Workflow DSL (JSON Configuration)**
|
||||
|
||||
- **Separation of Concerns:** Modules เก็บเฉพาะข้อมูล (Data) ส่วน Flow/State ถูกจัดการโดย Engine
|
||||
- **Versioning:** อาศัย Workflow Definition Version ป้องกันความขัดแย้งของ State เมื่อมีการแก้ไข Flow
|
||||
|
||||
#### Double-Locking Mechanism (Auto Numbering)
|
||||
|
||||
เพื่อป้องกัน Race Condition ในการขอเลขเอกสารพร้อมกัน:
|
||||
|
||||
- **Layer 1:** Redis Distributed Lock (ล็อคการเข้าถึงในระดับ Server/Network)
|
||||
- **Layer 2:** Optimistic Database Lock ผ่าน `@VersionColumn()` (ป้องกันระดับ Data Record)
|
||||
|
||||
#### Idempotency
|
||||
|
||||
ทุก API ที่แก้ไขสถานะจะต้องส่ง `Idempotency-Key` ป้องกันผู้ใช้กดยืนยันซ้ำสองรอบ
|
||||
|
||||
## 2. 📊 Data Flow & Processes
|
||||
|
||||
### 2.1 Main Request Flow
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as Client
|
||||
@@ -90,7 +98,9 @@ sequenceDiagram
|
||||
```
|
||||
|
||||
### 2.2 File Upload Flow (Two-Phase Storage)
|
||||
|
||||
ใช้แบบ **Two-Phase** เพื่อลดความเสี่ยงเกิดไฟล์ขยะ (Orphan Files):
|
||||
|
||||
1. **[Phase 1]:** Client อัปโหลดไฟล์ -> ตรวจ Virus -> วางไว้ที่โฟลเดอร์ `temp/` -> ส่ง `temp_id` กลับให้ Client
|
||||
2. **[Phase 2]:** Client สั่ง Create Document (แนบ `temp_id`) -> Backend บันทึกฐานข้อมูล -> ย้ายไฟล์จาก `temp/` ไปที่ `permanent/` -> สร้างตาราง Attachment -> Commit Transaction
|
||||
3. **[Cleanup Job]:** ครอนจ็อบตามลบไฟล์ที่ค้างอยู่ใน `temp/` เกิน 24 ชั่วโมง
|
||||
@@ -98,12 +108,14 @@ sequenceDiagram
|
||||
## 3. 🛡️ Security Architecture
|
||||
|
||||
### 3.1 Rate Limiting (Redis-backed)
|
||||
|
||||
- Anonymous: 100 req/hour
|
||||
- File Upload: 50 req/hour
|
||||
- Document Control: 2000 req/hour
|
||||
- Admin: 5000 req/hour
|
||||
|
||||
### 3.2 Authorization checking flow (CASL)
|
||||
|
||||
1. ดึง JWT Token ตรวจสอบความถูกต้อง
|
||||
2. โหลด User Permissions จาก Redis (`user:{user_id}:permissions`)
|
||||
3. ตรวจสอบเงื่อนไขตาม Context:
|
||||
@@ -114,6 +126,7 @@ sequenceDiagram
|
||||
4. พิจารณาอนุญาตหากระดับใดระดับหนึ่งอนุญาต (Most Permissive approach)
|
||||
|
||||
### 3.3 OWASP Top 10 Protections implemented
|
||||
|
||||
- **SQL Injection:** Parameterized Queries via TypeORM
|
||||
- **XSS/CSRF:** Input Sanitization, CSRF Tokens
|
||||
- **Insecure File Upload:** Magic Number Validation (ไม่ใช่แค่ extension), ไวรัสสแกน, สิทธิเข้าถึงไฟล์ถูกห่อหุ้มด้วย Authorization endpoint เสมอ ไม่ปล่อย public link
|
||||
|
||||
@@ -8,8 +8,9 @@ status: first-draft
|
||||
owner: Nattanin Peancharoen
|
||||
last_updated: 2026-02-23
|
||||
related:
|
||||
- specs/02-Architecture/00-01-system-context.md
|
||||
- specs/02-Architecture/02-03-software-architecture.md
|
||||
|
||||
- specs/02-Architecture/00-01-system-context.md
|
||||
- specs/02-Architecture/02-03-software-architecture.md
|
||||
|
||||
---
|
||||
|
||||
@@ -67,8 +68,10 @@ flowchart TB
|
||||
```
|
||||
|
||||
### 2.1 กฎเหล็ก: การเข้าถึงระบบฐานข้อมูล (Database Access Restriction)
|
||||
|
||||
> [!CAUTION]
|
||||
> **MariaDB และ Redis ตั้งอยู่ใน DATA ZONE ภายใต้ Docker Network ภายในชื่อ `lcbp3` เท่านั้น**
|
||||
|
||||
- **ห้าม Expose Port ออกสู่ Host โดยตรง:** `mariadb:3306` และ `redis:6379` จะต้องไม่ถูกเปิดสิทธิออกสู่ภายนอก Container Station
|
||||
- **การเข้าถึงจากระบบอื่น:** เฉพาะ Service ใน **APPLICATION ZONE** (เช่น NestJS Backend) และ Service อื่นบน Network `lcbp3` เท่านั้นที่จะสามารถเรียกใช้งาน Database ได้
|
||||
- **การจัดการโดย Admin:** หากผู้ดูแลระบบต้องการเข้าไปจัดการฐานข้อมูล จะต้องใช้งานผ่าน **phpMyAdmin** (`pma.np-dms.work`) ซึ่งถูกจำกัดสิทธิเข้าถึงผ่าน Nginx Proxy Manager อีกชั้น หรือผ่าน SSH Tunnel เข้าสู่เซิร์ฟเวอร์เท่านั้น
|
||||
@@ -111,6 +114,7 @@ graph TB
|
||||
```
|
||||
|
||||
### 3.1 Switch Profiles & Interfaces
|
||||
|
||||
- **01_CORE_TRUNK:** Router & switch uplinks (Native: 20, Tagged: All)
|
||||
- **02_MGMT_ONLY:** Management only (Native: 20, Untagged: 20)
|
||||
- **03_SERVER_ACCESS:** QNAP / ASUSTOR (Native: 10, Untagged: 10)
|
||||
@@ -120,6 +124,7 @@ graph TB
|
||||
- **07_VOICE_ACCESS:** IP Phones (Native: 30, Tagged: 50, Untagged: 30)
|
||||
|
||||
### 3.2 NAS NIC Bonding Configuration
|
||||
|
||||
| Device | Bonding Mode | Member Ports | VLAN Mode | Tagged VLAN | IP Address | Gateway | Notes |
|
||||
| ------- | ------------------- | ------------ | --------- | ----------- | --------------- | ------------ | ---------------------- |
|
||||
| QNAP | IEEE 802.3ad (LACP) | Adapter 1, 2 | Untagged | 10 (SERVER) | 192.168.10.8/24 | 192.168.10.1 | Primary NAS for DMS |
|
||||
@@ -130,7 +135,9 @@ graph TB
|
||||
กฎของ Firewall จะถูกกำหนดบน Omada Controller และอุปกรณ์ Gateway (ER7206) ตามหลักการอนุญาตแค่สิ่งที่ต้องการ (Default Deny)
|
||||
|
||||
### 4.1 IP Groups & Port Groups (อ้างอิงบ่อย)
|
||||
|
||||
**IP Groups:**
|
||||
|
||||
- `Server`: 192.168.10.8, 192.168.10.9, 192.168.10.111
|
||||
- `Omada-Controller`: 192.168.20.250
|
||||
- `DHCP-Gateways`: 192.168.30.1, 192.168.70.1
|
||||
@@ -139,50 +146,56 @@ graph TB
|
||||
- `Blacklist`: (เพิ่ม IP ประสงค์ร้าย)
|
||||
|
||||
**Port Groups:**
|
||||
|
||||
- `Web`: TCP 443, 8443, 80, 81, 2222
|
||||
- `Omada-Auth`: TCP 443, 8043, 8088, 8843, 29810-29814
|
||||
- `VoIP`: UDP 5060, 5061, 10000-20000 (SIP + RTP)
|
||||
- `DHCP`: UDP 67, 68
|
||||
|
||||
### 4.2 Switch ACL (สำหรับ Omada OC200)
|
||||
|
||||
> ⚠️ **ลำดับความสำคัญ (Priority Level):** (1) Allow rules (DHCP, Auth) -> (2) Isolate/Deny rules -> (3) Allow specific services -> (4) Default Deny
|
||||
|
||||
| ลำดับ | Name | Policy | Source | Destination | Ports |
|
||||
| :--- | :------------------------ | :----- | :---------------- | :---------------------------- | :---------------------------------------- |
|
||||
| 1 | 01 Allow-User-DHCP | Allow | Network → VLAN 30 | IP → 192.168.30.1 | Port Group → DHCP |
|
||||
| 2 | 02 Allow-Guest-DHCP | Allow | Network → VLAN 70 | IP → 192.168.70.1 | Port Group → DHCP |
|
||||
| 3 | 03 Allow-WiFi-Auth | Allow | Network → VLAN 30 | IP Group → Omada-Controller | Port Group → Omada-Auth |
|
||||
| 4 | 04 Allow-Guest-WiFi-Auth | Allow | Network → VLAN 70 | IP Group → Omada-Controller | Port Group → Omada-Auth |
|
||||
| 5 | 05 Isolate-Guests | Deny | Network → VLAN 70 | Network → VLAN 10, 20, 30, 60 | All |
|
||||
| 6 | 06 Isolate-Servers | Deny | Network → VLAN 10 | Network → VLAN 30 (USER) | All |
|
||||
| 7 | 07 Block-User-to-Mgmt | Deny | Network → VLAN 30 | Network → VLAN 20 (MGMT) | All |
|
||||
| 8 | 08 Allow-User-to-Services | Allow | Network → VLAN 30 | IP → QNAP (192.168.10.8) | Port Group → Web (443,8443, 80, 81, 2222) |
|
||||
| 9 | 09 Allow-Voice-to-User | Allow | Network → VLAN 50 | Network → VLAN 30,50 | All |
|
||||
| 10 | 10 Allow-MGMT-to-All | Allow | Network → VLAN 20 | Any | All |
|
||||
| 11 | 11 Allow-Server-Internal | Allow | IP Group : Server | IP Group : Server | All |
|
||||
| 12 | 12 Allow-Server → CCTV | Allow | IP Group : Server | Network → VLAN 40 (CCTV) | All |
|
||||
| 13 | 100 (Default) | Deny | Any | Any | All |
|
||||
| ลำดับ | Name | Policy | Source | Destination | Ports |
|
||||
| :---- | :------------------------ | :----- | :---------------- | :---------------------------- | :---------------------------------------- |
|
||||
| 1 | 01 Allow-User-DHCP | Allow | Network → VLAN 30 | IP → 192.168.30.1 | Port Group → DHCP |
|
||||
| 2 | 02 Allow-Guest-DHCP | Allow | Network → VLAN 70 | IP → 192.168.70.1 | Port Group → DHCP |
|
||||
| 3 | 03 Allow-WiFi-Auth | Allow | Network → VLAN 30 | IP Group → Omada-Controller | Port Group → Omada-Auth |
|
||||
| 4 | 04 Allow-Guest-WiFi-Auth | Allow | Network → VLAN 70 | IP Group → Omada-Controller | Port Group → Omada-Auth |
|
||||
| 5 | 05 Isolate-Guests | Deny | Network → VLAN 70 | Network → VLAN 10, 20, 30, 60 | All |
|
||||
| 6 | 06 Isolate-Servers | Deny | Network → VLAN 10 | Network → VLAN 30 (USER) | All |
|
||||
| 7 | 07 Block-User-to-Mgmt | Deny | Network → VLAN 30 | Network → VLAN 20 (MGMT) | All |
|
||||
| 8 | 08 Allow-User-to-Services | Allow | Network → VLAN 30 | IP → QNAP (192.168.10.8) | Port Group → Web (443,8443, 80, 81, 2222) |
|
||||
| 9 | 09 Allow-Voice-to-User | Allow | Network → VLAN 50 | Network → VLAN 30,50 | All |
|
||||
| 10 | 10 Allow-MGMT-to-All | Allow | Network → VLAN 20 | Any | All |
|
||||
| 11 | 11 Allow-Server-Internal | Allow | IP Group : Server | IP Group : Server | All |
|
||||
| 12 | 12 Allow-Server → CCTV | Allow | IP Group : Server | Network → VLAN 40 (CCTV) | All |
|
||||
| 13 | 100 (Default) | Deny | Any | Any | All |
|
||||
|
||||
### 4.3 Gateway ACL (สำหรับ ER7206)
|
||||
| ลำดับ | Name | Policy | Direction | PROTOCOLS | Source | Destination |
|
||||
| :--- | :---------------------- | :----- | :-------- | :-------- | :------------------- | :--------------------------- |
|
||||
| 1 | 01 Blacklist | Deny | [WAN2] IN | All | IP Group:Blacklist | IP Group:Internal |
|
||||
| 2 | 02 Geo | Permit | [WAN2] IN | All | Location Group:Allow | IP Group:Internal |
|
||||
| 3 | 03 Allow-Voice-Internet | Permit | LAN->WAN | UDP | Network → VLAN 50 | Any |
|
||||
| 4 | 04 Internal → Internet | Permit | LAN->WAN | All | IP Group:Internal | Domain Group:DomainGroup_Any |
|
||||
|
||||
| ลำดับ | Name | Policy | Direction | PROTOCOLS | Source | Destination |
|
||||
| :---- | :---------------------- | :----- | :-------- | :-------- | :------------------- | :--------------------------- |
|
||||
| 1 | 01 Blacklist | Deny | [WAN2] IN | All | IP Group:Blacklist | IP Group:Internal |
|
||||
| 2 | 02 Geo | Permit | [WAN2] IN | All | Location Group:Allow | IP Group:Internal |
|
||||
| 3 | 03 Allow-Voice-Internet | Permit | LAN->WAN | UDP | Network → VLAN 50 | Any |
|
||||
| 4 | 04 Internal → Internet | Permit | LAN->WAN | All | IP Group:Internal | Domain Group:DomainGroup_Any |
|
||||
|
||||
### 4.4 Port Forwarding
|
||||
|
||||
Traffic สาธารณะ (WAN) จะถูกเชื่อมต่อไปยัง Nginx Proxy Manager เพียงจุดเดียว
|
||||
|
||||
- **Allow-NPM-HTTPS:** External Port 443 -> QNAP (192.168.10.8) Port 443 (TCP)
|
||||
- **Allow-NPM-HTTP (สำหรับ Let's Encrypt):** External Port 80 -> QNAP (192.168.10.8) Port 80 (TCP)
|
||||
|
||||
## 5. 📡 EAP ACL (Wireless Data Flow Rules)
|
||||
|
||||
ตั้งค่าสำหรับ Access Points ให้ป้องกันการ Broadcast ลดทอนกันเอง หรือรบกวนโซนอื่นๆ
|
||||
* **SSID: PSLCBP3 (Staff WiFi) - VLAN 30**
|
||||
|
||||
- **SSID: PSLCBP3 (Staff WiFi) - VLAN 30**
|
||||
- อนุญาต DNS, 192.168.10.0/24 (Servers), Printer, Internet
|
||||
- **บล็อค** การเข้าสู่ 192.168.20.0/24 (MGMT), 192.168.40.0/24 (CCTV), และ **Client Isolation (Client-2-Client Deny)**
|
||||
|
||||
* **SSID: GUEST (Guest WiFi) - VLAN 70**
|
||||
- **SSID: GUEST (Guest WiFi) - VLAN 70**
|
||||
- อนุญาต DNS, Internet (HTTP/HTTPS)
|
||||
- **บล็อคเครือข่ายส่วนตัวทั้งหมด (RFC1918):** 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 และสั่ง **Client Isolation**
|
||||
|
||||
@@ -8,9 +8,10 @@
|
||||
**owner:** Nattanin Peancharoen
|
||||
**last_updated:** 2026-02-23
|
||||
**related:**
|
||||
- specs/02-Architecture/00-01-system-context.md
|
||||
- specs/02-Architecture/02-03-software-architecture.md
|
||||
- specs/03-Implementation/03-01-fullstack-js-v1.7.0.md
|
||||
|
||||
- specs/02-Architecture/00-01-system-context.md
|
||||
- specs/02-Architecture/02-03-software-architecture.md
|
||||
- specs/03-Implementation/03-01-fullstack-js-v1.7.0.md
|
||||
|
||||
---
|
||||
|
||||
@@ -21,17 +22,20 @@
|
||||
## 2. 🎯 หลักการออกแบบ API (API Design Principles)
|
||||
|
||||
### 2.1 API-First Approach
|
||||
|
||||
- **ออกแบบ API ก่อนการ Implement:** ทำการออกแบบ API Endpoint และ Data Contract ให้ชัดเจนก่อนเริ่มเขียนโค้ด
|
||||
- **Documentation-Driven:** ใช้ OpenAPI/Swagger เป็นเอกสารอ้างอิงหลัก
|
||||
- **Contract Testing:** ทดสอบ API ตาม Contract ที่กำหนดไว้
|
||||
|
||||
### 2.2 RESTful Principles
|
||||
|
||||
- ใช้ HTTP Methods อย่างถูกต้อง: `GET`, `POST`, `PUT`, `PATCH`, `DELETE`
|
||||
- ใช้ HTTP Status Codes ที่เหมาะสม
|
||||
- Resource-Based URL Design
|
||||
- Stateless Communication
|
||||
|
||||
### 2.3 Consistency & Predictability
|
||||
|
||||
- **Naming Conventions:** ใช้ `kebab-case` สำหรับ URL paths
|
||||
- **Property Naming:** ใช้ `camelCase` สำหรับ JSON properties และ query parameters (สอดคล้องกับ TypeScript/JavaScript conventions)
|
||||
- **Database Columns:** Database ใช้ `snake_case` (mapped via TypeORM decorators)
|
||||
@@ -40,6 +44,7 @@
|
||||
## 3. 🔐 Authentication & Authorization
|
||||
|
||||
### 3.1 Authentication
|
||||
|
||||
- **JWT-Based Authentication:** ใช้ JSON Web Token สำหรับการยืนยันตัวตน
|
||||
- **Token Management:**
|
||||
- Access Token Expiration: 8 ชั่วโมง
|
||||
@@ -48,18 +53,22 @@
|
||||
- Token Revocation: บันทึก Revoked Tokens จนกว่าจะหมดอายุ
|
||||
|
||||
**Endpoints คอร์:**
|
||||
|
||||
```typescript
|
||||
POST /api/v1/auth/login
|
||||
POST /api/v1/auth/logout
|
||||
POST /api/v1/auth/refresh
|
||||
POST /api/v1/auth/change-password
|
||||
POST / api / v1 / auth / login;
|
||||
POST / api / v1 / auth / logout;
|
||||
POST / api / v1 / auth / refresh;
|
||||
POST / api / v1 / auth / change - password;
|
||||
```
|
||||
|
||||
### 3.2 Authorization (RBAC) (CASL)
|
||||
|
||||
ใช้ระบบ 4-Level Permission Hierarchy (Global, Organization, Project, Contract)
|
||||
|
||||
- **Permission Checking:** ใช้ Decorator `@RequirePermission('resource.action')`
|
||||
|
||||
**Example:**
|
||||
|
||||
```typescript
|
||||
@RequirePermission('correspondence.create')
|
||||
@Post('correspondences')
|
||||
@@ -69,29 +78,34 @@ async createCorrespondence(@Body() dto: CreateCorrespondenceDto) {
|
||||
```
|
||||
|
||||
### 3.3 Token Payload Optimization
|
||||
|
||||
- JWT Payload เก็บเฉพาะ `userId` และ `scope` ปัจจุบัน
|
||||
- **Permissions Caching:** เก็บ Permission List ใน Redis และดึงมาตรวจสอบเมื่อมี Request
|
||||
|
||||
## 4. 📡 API Conventions
|
||||
|
||||
### 4.1 Base URL Structure
|
||||
|
||||
```
|
||||
https://backend.np-dms.work/api/v1/{resource}
|
||||
```
|
||||
|
||||
### 4.2 HTTP Methods & Usage
|
||||
| Method | Usage | Idempotent | Example |
|
||||
| :------- | :--------------------------- | :--------- | :----------------------------------- |
|
||||
| `GET` | ดึงข้อมูล (Read) | ✅ Yes | `GET /api/v1/correspondences` |
|
||||
| `POST` | สร้างข้อมูลใหม่ (Create) | ❌ No\* | `POST /api/v1/correspondences` |
|
||||
| `PUT` | อัปเดตทั้งหมด (Full Update) | ✅ Yes | `PUT /api/v1/correspondences/:id` |
|
||||
| `PATCH` | อัปเดตบางส่วน (Partial Update) | ✅ Yes | `PATCH /api/v1/correspondences/:id` |
|
||||
| `DELETE` | ลบข้อมูล (Soft Delete) | ✅ Yes | `DELETE /api/v1/correspondences/:id` |
|
||||
|
||||
* **Note:** `POST` เป็น Idempotent ได้เมื่อใช้ `Idempotency-Key` Header
|
||||
| Method | Usage | Idempotent | Example |
|
||||
| :------- | :----------------------------- | :--------- | :----------------------------------- |
|
||||
| `GET` | ดึงข้อมูล (Read) | ✅ Yes | `GET /api/v1/correspondences` |
|
||||
| `POST` | สร้างข้อมูลใหม่ (Create) | ❌ No\* | `POST /api/v1/correspondences` |
|
||||
| `PUT` | อัปเดตทั้งหมด (Full Update) | ✅ Yes | `PUT /api/v1/correspondences/:id` |
|
||||
| `PATCH` | อัปเดตบางส่วน (Partial Update) | ✅ Yes | `PATCH /api/v1/correspondences/:id` |
|
||||
| `DELETE` | ลบข้อมูล (Soft Delete) | ✅ Yes | `DELETE /api/v1/correspondences/:id` |
|
||||
|
||||
- **Note:** `POST` เป็น Idempotent ได้เมื่อใช้ `Idempotency-Key` Header
|
||||
|
||||
### 4.3 Request Format
|
||||
|
||||
**Request Headers:**
|
||||
|
||||
```http
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer <access_token>
|
||||
@@ -99,6 +113,7 @@ Idempotency-Key: <uuid> # สำหรับ POST/PUT/DELETE
|
||||
```
|
||||
|
||||
### 4.4 HTTP Status Codes
|
||||
|
||||
| Status | Use Case |
|
||||
| ------------------------- | ------------------------------------------- |
|
||||
| 200 OK | Successful GET, PUT, PATCH |
|
||||
@@ -120,6 +135,7 @@ Idempotency-Key: <uuid> # สำหรับ POST/PUT/DELETE
|
||||
### 5.1 Success Response
|
||||
|
||||
**Single Resource:**
|
||||
|
||||
```typescript
|
||||
{
|
||||
"data": {
|
||||
@@ -135,6 +151,7 @@ Idempotency-Key: <uuid> # สำหรับ POST/PUT/DELETE
|
||||
```
|
||||
|
||||
**Collection (Pagination):**
|
||||
|
||||
```typescript
|
||||
{
|
||||
"data": [
|
||||
@@ -154,6 +171,7 @@ Idempotency-Key: <uuid> # สำหรับ POST/PUT/DELETE
|
||||
```
|
||||
|
||||
### 5.2 Error Response Format
|
||||
|
||||
```typescript
|
||||
{
|
||||
"error": {
|
||||
@@ -176,6 +194,7 @@ Idempotency-Key: <uuid> # สำหรับ POST/PUT/DELETE
|
||||
## 6. 🛠️ NestJS Implementation Details
|
||||
|
||||
### 6.1 Global Exception Filter
|
||||
|
||||
คลาสจัดการ Error หลักที่จะจับและดัดแปลง Error ส่งคืน Client อย่างสม่ำเสมอ
|
||||
|
||||
```typescript
|
||||
@@ -225,6 +244,7 @@ export class GlobalExceptionFilter implements ExceptionFilter {
|
||||
```
|
||||
|
||||
### 6.2 Custom Business Exception
|
||||
|
||||
สำหรับจัดการข้อผิดพลาดเชิงความสัมพันธ์ หรือเงื่อนไขธุรกิจ เช่น State Conflict.
|
||||
|
||||
```typescript
|
||||
@@ -242,13 +262,11 @@ export class BusinessException extends HttpException {
|
||||
}
|
||||
|
||||
// Usage Example:
|
||||
throw new BusinessException(
|
||||
'Cannot approve correspondence in current status',
|
||||
'INVALID_WORKFLOW_TRANSITION'
|
||||
);
|
||||
throw new BusinessException('Cannot approve correspondence in current status', 'INVALID_WORKFLOW_TRANSITION');
|
||||
```
|
||||
|
||||
### 6.3 Validation Pipe Configuration
|
||||
|
||||
บังคับ Validation Pipe ก่อนส่งพารามิเตอร์ให้กับ Controller
|
||||
|
||||
```typescript
|
||||
@@ -297,6 +315,7 @@ app.useGlobalPipes(
|
||||
| Authentication | 10 requests/minute | IP |
|
||||
|
||||
### 7.2 File Upload Security
|
||||
|
||||
- **Virus Scanning:** ใช้ ClamAV scan ทุกไฟล์
|
||||
- **File Type Validation:** White-list (PDF, DWG, DOCX, XLSX, ZIP)
|
||||
- **File Size Limit:** 50MB per file
|
||||
@@ -314,21 +333,25 @@ app.useGlobalPipes(
|
||||
## 9. 📈 Optimization & Additional Guidelines
|
||||
|
||||
### 9.1 Caching Strategy
|
||||
|
||||
- Master Data: 1 hour
|
||||
- User Sessions: 30 minutes
|
||||
- Search Results: 15 minutes
|
||||
- File Metadata: 1 hour
|
||||
|
||||
### 9.2 API Versioning
|
||||
|
||||
- **URL-Based Versioning:** `/api/v1/...`, `/api/v2/...`
|
||||
- **Backward Compatibility:** รองรับ API เวอร์ชันเก่าอย่างน้อย 1 เวอร์ชัน
|
||||
- ใช้ Deprecation Headers เมื่อมีการยกเลิก Endpoints
|
||||
|
||||
### 9.3 Documentation
|
||||
|
||||
- **Swagger/OpenAPI:** Auto-generated จาก NestJS Decorators
|
||||
- **URL:** `https://backend.np-dms.work/api/docs`
|
||||
|
||||
## 🎯 สรุป Best Practices
|
||||
|
||||
1. **ใช้ DTOs สำหรับ Validation ทุก Request**
|
||||
2. **ส่ง Idempotency-Key สำหรับ Critical Operations**
|
||||
3. **ใช้ Proper HTTP Status Codes**
|
||||
|
||||
@@ -194,17 +194,17 @@ Layer 6: File Security (Virus Scanning, Access Control)
|
||||
|
||||
### Frontend Stack
|
||||
|
||||
| Component | Technology | Purpose |
|
||||
| -------------------- | -------------------------------- | ---------------------------- |
|
||||
| **Framework** | Next.js 14+ (App Router) | React Framework with SSR |
|
||||
| **Language** | TypeScript (ESM) | Type-safe JavaScript |
|
||||
| **Styling** | Tailwind CSS + PostCSS | Utility-first CSS |
|
||||
| **Components** | shadcn/ui | Accessible Component Library |
|
||||
| **Server State** | TanStack Query | Server State Management |
|
||||
| **Client State** | Zustand | Client State Management |
|
||||
| **Form State** | React Hook Form + Zod | Form State Management |
|
||||
| **Validation** | Zod | Schema Validation |
|
||||
| **Testing** | Vitest + Playwright | Unit + E2E Testing |
|
||||
| Component | Technology | Purpose |
|
||||
| ---------------- | ------------------------ | ---------------------------- |
|
||||
| **Framework** | Next.js 14+ (App Router) | React Framework with SSR |
|
||||
| **Language** | TypeScript (ESM) | Type-safe JavaScript |
|
||||
| **Styling** | Tailwind CSS + PostCSS | Utility-first CSS |
|
||||
| **Components** | shadcn/ui | Accessible Component Library |
|
||||
| **Server State** | TanStack Query | Server State Management |
|
||||
| **Client State** | Zustand | Client State Management |
|
||||
| **Form State** | React Hook Form + Zod | Form State Management |
|
||||
| **Validation** | Zod | Schema Validation |
|
||||
| **Testing** | Vitest + Playwright | Unit + E2E Testing |
|
||||
|
||||
### Backend Stack
|
||||
|
||||
@@ -274,6 +274,7 @@ Layer 6: File Security (Virus Scanning, Access Control)
|
||||
- **Counter Key:** Composite PK (8 columns)
|
||||
|
||||
**Documentation:**
|
||||
|
||||
- 📋 [Requirements](../01-requirements/01-03.11-document-numbering.md)
|
||||
- 📘 [Implementation Guide](../03-implementation/03-04-document-numbering.md)
|
||||
- 📗 [Operations Guide](../04-operations/04-08-document-numbering-operations.md)
|
||||
|
||||
Reference in New Issue
Block a user