Prepare to version 1.5 use spec-kit
This commit is contained in:
58
specs/02-architecture/README.md
Normal file
58
specs/02-architecture/README.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# 📋 Architecture Specification v1.5.0
|
||||
|
||||
## Status: first-draft
|
||||
|
||||
**Date:** 2025-11-30
|
||||
|
||||
---
|
||||
|
||||
## 📑 Table of Contents
|
||||
|
||||
1. [General Philosophy](./01-general-philosophy.md)
|
||||
2. [TypeScript](./02-typescript.md)
|
||||
3. [Functional Requirements](./03-functional-requirements.md)
|
||||
- [3.1 Project & Organization Management](./03.1-project-management.md)
|
||||
- [3.2 Correspondence Management](./03.2-correspondence.md)
|
||||
- [3.3 RFA Management](./03.3-rfa.md)
|
||||
- [3.4 Contract Drawing Management](./03.4-contract-drawing.md)
|
||||
- [3.5 Shop Drawing Management](./03.5-shop-drawing.md)
|
||||
- [3.6 Unified Workflow](./03.6-unified-workflow.md)
|
||||
- [3.7 Transmittals Management](./03.7-transmittals.md)
|
||||
- [3.8 Circulation Sheet Management](./03.8-circulation-sheet.md)
|
||||
- [3.9 Revisions Management](./03.9-revisions.md)
|
||||
- [3.10 File Handling](./03.10-file-handling.md)
|
||||
- [3.11 Document Numbering](./03.11-document-numbering.md)
|
||||
- [3.12 JSON Details](./03.12-json-details.md)
|
||||
4. [Access Control & RBAC](./04-access-control.md)
|
||||
5. [UI/UX Requirements](./05-ui-ux.md)
|
||||
6. [Non-Functional Requirements](./06-non-functional.md)
|
||||
7. [Testing Requirements](./07-testing.md)
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Recent Changes
|
||||
|
||||
See [CHANGELOG.md](../../CHANGELOG.md) for detailed version history.
|
||||
|
||||
### v1.4.5 (2025-11-30)
|
||||
|
||||
- ✅ Added comprehensive security requirements
|
||||
- ✅ Enhanced resilience patterns
|
||||
- ✅ Added performance targets
|
||||
- ⚠️ **Breaking:** Changed document numbering from stored procedure to app-level locking
|
||||
|
||||
---
|
||||
|
||||
## 📊 Compliance Matrix
|
||||
|
||||
| Requirement | Status | Owner | Target Release |
|
||||
| ----------------------------- | ----------- | ------------ | -------------- |
|
||||
| FR-001: Correspondence CRUD | ✅ Done | Backend Team | v1.0 |
|
||||
| FR-002: RFA Workflow | In Progress | Backend Team | v1.1 |
|
||||
| NFR-001: API Response < 200ms | Planned | DevOps | v1.2 |
|
||||
|
||||
---
|
||||
|
||||
## 📬 Feedback
|
||||
|
||||
Found issues? [Open an issue](https://github.com/your-org/lcbp3-dms/issues/new?template=spec-issue.md)
|
||||
551
specs/02-architecture/api-design.md
Normal file
551
specs/02-architecture/api-design.md
Normal file
@@ -0,0 +1,551 @@
|
||||
# 🌐 API Design Specification
|
||||
|
||||
---
|
||||
|
||||
**title:** 'API Design'
|
||||
**version:** 1.5.0
|
||||
**status:** first-draft
|
||||
**owner:** Nattanin Peancharoen
|
||||
**last_updated:** 2025-11-30
|
||||
**related:**
|
||||
|
||||
- specs/01-requirements/02-architecture.md
|
||||
- specs/02-architecture/system-architecture.md
|
||||
- specs/03-implementation/fullftack-js-v1.5.0.md
|
||||
|
||||
---
|
||||
|
||||
## 📋ภาพรวม (Overview)
|
||||
|
||||
เอกสารนี้กำหนดมาตรฐานการออกแบบ API สำหรับระบบ LCBP3-DMS โดยใช้แนวทาง **API-First Design** ที่เน้นความชัดเจน ความสอดคล้อง และความปลอดภัย
|
||||
|
||||
## 🎯 หลักการออกแบบ API (API Design Principles)
|
||||
|
||||
### 1.1 API-First Approach
|
||||
|
||||
- **ออกแบบ API ก่อนการ Implement:** ทำการออกแบบ API Endpoint และ Data Contract ให้ชัดเจนก่อนเริ่มเขียนโค้ด
|
||||
- **Documentation-Driven:** ใช้ OpenAPI/Swagger เป็นเอกสารอ้างอิงหลัก
|
||||
- **Contract Testing:** ทดสอบ API ตาม Contract ที่กำหนดไว้
|
||||
|
||||
### 1.2 RESTful Principles
|
||||
|
||||
- ใช้ HTTP Methods อย่างถูกต้อง: `GET`, `POST`, `PUT`, `PATCH`, `DELETE`
|
||||
- ใช้ HTTP Status Codes ที่เหมาะสม
|
||||
- Resource-Based URL Design
|
||||
- Stateless Communication
|
||||
|
||||
### 1.3 Consistency & Predictability
|
||||
|
||||
- **Naming Conventions:** ใช้ `kebab-case` สำหรับ URL paths
|
||||
- **Property Naming:** ใช้ `snake_case` สำหรับ JSON properties (สอดคล้องกับ Database Schema)
|
||||
- **Versioning:** รองรับการ Version API ผ่าน URL path (`/api/v1/...`)
|
||||
|
||||
## 🔐 Authentication & Authorization
|
||||
|
||||
### 2.1 Authentication
|
||||
|
||||
- **JWT-Based Authentication:** ใช้ JSON Web Token สำหรับการยืนยันตัวตน
|
||||
- **Token Management:**
|
||||
- Access Token Expiration: 8 ชั่วโมง
|
||||
- Refresh Token Expiration: 7 วัน
|
||||
- Token Rotation: รองรับการหมุนเวียน Refresh Token
|
||||
- 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;
|
||||
```
|
||||
|
||||
### 2.2 Authorization (RBAC)
|
||||
|
||||
- **4-Level Permission Hierarchy:**
|
||||
|
||||
1. **Global Level:** System-wide permissions (Superadmin)
|
||||
2. **Organization Level:** Organization-specific permissions
|
||||
3. **Project Level:** Project-specific permissions
|
||||
4. **Contract Level:** Contract-specific permissions
|
||||
|
||||
- **Permission Checking:** ใช้ Decorator `@RequirePermission('resource.action')`
|
||||
|
||||
**Example:**
|
||||
|
||||
```typescript
|
||||
@RequirePermission('correspondence.create')
|
||||
@Post('correspondences')
|
||||
async createCorrespondence(@Body() dto: CreateCorrespondenceDto) {
|
||||
// Implementation
|
||||
}
|
||||
```
|
||||
|
||||
### 2.3 Token Payload Optimization
|
||||
|
||||
- JWT Payload เก็บเฉพาะ `userId` และ `scope` ปัจจุบัน
|
||||
- **Permissions Caching:** เก็บ Permission List ใน Redis และดึงมาตรวจสอบเมื่อมี Request
|
||||
|
||||
## 📡 API Conventions
|
||||
|
||||
### 3.1 Base URL Structure
|
||||
|
||||
```
|
||||
https://backend.np-dms.work/api/v1/{resource}
|
||||
```
|
||||
|
||||
### 3.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
|
||||
|
||||
### 3.3 HTTP Status Codes
|
||||
|
||||
| Status Code | Usage |
|
||||
| :-------------------------- | :------------------------------- |
|
||||
| `200 OK` | Request สำเร็จ (GET, PUT, PATCH) |
|
||||
| `201 Created` | สร้างข้อมูลสำเร็จ (POST) |
|
||||
| `204 No Content` | ลบสำเร็จ (DELETE) |
|
||||
| `400 Bad Request` | ข้อมูล Request ไม่ถูกต้อง |
|
||||
| `401 Unauthorized` | ไม่มี Token หรือ Token หมดอายุ |
|
||||
| `403 Forbidden` | ไม่มีสิทธิ์เข้าถึง |
|
||||
| `404 Not Found` | ไม่พบข้อมูล |
|
||||
| `409 Conflict` | ข้อมูลซ้ำ หรือ State Conflict |
|
||||
| `422 Unprocessable Entity` | Validation Error |
|
||||
| `429 Too Many Requests` | Rate Limit Exceeded |
|
||||
| `500 Internal Server Error` | Server Error |
|
||||
| `503 Service Unavailable` | Maintenance Mode |
|
||||
|
||||
### 3.4 Request & Response Format
|
||||
|
||||
**Request Headers:**
|
||||
|
||||
```http
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer <access_token>
|
||||
Idempotency-Key: <uuid> # สำหรับ POST/PUT/DELETE
|
||||
```
|
||||
|
||||
**Success Response Format:**
|
||||
|
||||
```typescript
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
// Resource data
|
||||
},
|
||||
"message": "Operation completed successfully"
|
||||
}
|
||||
```
|
||||
|
||||
**Error Response Format:**
|
||||
|
||||
```typescript
|
||||
{
|
||||
"success": false,
|
||||
"error": {
|
||||
"code": "VALIDATION_ERROR",
|
||||
"message": "Validation failed",
|
||||
"details": [
|
||||
{
|
||||
"field": "email",
|
||||
"message": "Invalid email format"
|
||||
}
|
||||
]
|
||||
},
|
||||
"timestamp": "2025-11-30T13:48:20Z",
|
||||
"path": "/api/v1/users"
|
||||
}
|
||||
```
|
||||
|
||||
## 🔄 Idempotency
|
||||
|
||||
### 4.1 Implementation
|
||||
|
||||
- **ทุก Critical Operation** (Create, Update, Delete) ต้องรองรับ Idempotency
|
||||
- Client ส่ง Header: `Idempotency-Key: <uuid>`
|
||||
- Server เช็คว่า Key นี้เคยประมวลผลสำเร็จแล้วหรือไม่
|
||||
- ถ้าเคยทำแล้ว: ส่งผลลัพธ์เดิมกลับไป (ไม่ทำซ้ำ)
|
||||
|
||||
**Example:**
|
||||
|
||||
```http
|
||||
POST /api/v1/correspondences
|
||||
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"title": "New Correspondence",
|
||||
"type_id": 1
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 Pagination, Filtering & Sorting
|
||||
|
||||
### 5.1 Pagination (Server-Side)
|
||||
|
||||
**Query Parameters:**
|
||||
|
||||
```
|
||||
GET /api/v1/correspondences?page=1&page_size=20
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```typescript
|
||||
{
|
||||
"success": true,
|
||||
"data": [...],
|
||||
"meta": {
|
||||
"current_page": 1,
|
||||
"page_size": 20,
|
||||
"total_items": 150,
|
||||
"total_pages": 8,
|
||||
"has_next_page": true,
|
||||
"has_previous_page": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 Filtering
|
||||
|
||||
```
|
||||
GET /api/v1/correspondences?project_id=1&status=PENDING
|
||||
```
|
||||
|
||||
### 5.3 Sorting
|
||||
|
||||
```
|
||||
GET /api/v1/correspondences?sort=created_at&order=desc
|
||||
```
|
||||
|
||||
### 5.4 Combined Example
|
||||
|
||||
```
|
||||
GET /api/v1/correspondences?project_id=1&status=PENDING&page=1&page_size=20&sort=created_at&order=desc
|
||||
```
|
||||
|
||||
## 🛡️ Security Features
|
||||
|
||||
### 6.1 Rate Limiting
|
||||
|
||||
| Endpoint Type | Limit | Scope |
|
||||
| :------------------ | :----------------- | :---- |
|
||||
| Anonymous Endpoints | 100 requests/hour | IP |
|
||||
| Viewer | 500 requests/hour | User |
|
||||
| Editor | 1000 requests/hour | User |
|
||||
| Document Control | 2000 requests/hour | User |
|
||||
| Admin/Superadmin | 5000 requests/hour | User |
|
||||
| File Upload | 50 requests/hour | User |
|
||||
| Search | 500 requests/hour | User |
|
||||
| Authentication | 10 requests/minute | IP |
|
||||
|
||||
**Rate Limit Headers:**
|
||||
|
||||
```http
|
||||
X-RateLimit-Limit: 1000
|
||||
X-RateLimit-Remaining: 999
|
||||
X-RateLimit-Reset: 1638360000
|
||||
```
|
||||
|
||||
### 6.2 Input Validation
|
||||
|
||||
- **DTOs with Class Validator:** ทุก Request ต้องผ่าน Validation
|
||||
- **XSS Protection:** Input Sanitization
|
||||
- **SQL Injection Prevention:** ใช้ ORM (TypeORM) Parameterized Queries
|
||||
- **CSRF Protection:** CSRF Tokens สำหรับ State-Changing Operations
|
||||
|
||||
### 6.3 File Upload Security
|
||||
|
||||
**Endpoint:**
|
||||
|
||||
```
|
||||
POST /api/v1/files/upload
|
||||
```
|
||||
|
||||
**Security Measures:**
|
||||
|
||||
- **Virus Scanning:** ใช้ ClamAV scan ทุกไฟล์
|
||||
- **File Type Validation:** White-list (PDF, DWG, DOCX, XLSX, ZIP)
|
||||
- **File Size Limit:** 50MB per file
|
||||
- **Two-Phase Storage:**
|
||||
1. Upload to `temp/` folder
|
||||
2. Commit to `permanent/{YYYY}/{MM}/` when operation succeeds
|
||||
|
||||
**Response:**
|
||||
|
||||
```typescript
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"temp_id": "uuid",
|
||||
"filename": "document.pdf",
|
||||
"size": 1024000,
|
||||
"mime_type": "application/pdf",
|
||||
"scan_status": "CLEAN"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📦 Core Module APIs
|
||||
|
||||
### 7.1 Correspondence Module
|
||||
|
||||
**Base Path:** `/api/v1/correspondences`
|
||||
|
||||
| Method | Endpoint | Permission | Description |
|
||||
| :----- | :--------------------------------- | :---------------------- | :-------------------- |
|
||||
| GET | `/correspondences` | `correspondence.view` | รายการ Correspondence |
|
||||
| GET | `/correspondences/:id` | `correspondence.view` | รายละเอียด |
|
||||
| POST | `/correspondences` | `correspondence.create` | สร้างใหม่ |
|
||||
| PUT | `/correspondences/:id` | `correspondence.update` | อัปเดตทั้งหมด |
|
||||
| PATCH | `/correspondences/:id` | `correspondence.update` | อัปเดตบางส่วน |
|
||||
| DELETE | `/correspondences/:id` | `correspondence.delete` | ลบ (Soft Delete) |
|
||||
| POST | `/correspondences/:id/revisions` | `correspondence.update` | สร้าง Revision ใหม่ |
|
||||
| GET | `/correspondences/:id/revisions` | `correspondence.view` | ดู Revisions ทั้งหมด |
|
||||
| POST | `/correspondences/:id/attachments` | `correspondence.update` | เพิ่มไฟล์แนบ |
|
||||
|
||||
### 7.2 RFA Module
|
||||
|
||||
**Base Path:** `/api/v1/rfas`
|
||||
|
||||
| Method | Endpoint | Permission | Description |
|
||||
| :----- | :-------------------- | :------------- | :----------------- |
|
||||
| GET | `/rfas` | `rfas.view` | รายการ RFA |
|
||||
| GET | `/rfas/:id` | `rfas.view` | รายละเอียด |
|
||||
| POST | `/rfas` | `rfas.create` | สร้างใหม่ |
|
||||
| PUT | `/rfas/:id` | `rfas.update` | อัปเดต |
|
||||
| DELETE | `/rfas/:id` | `rfas.delete` | ลบ |
|
||||
| POST | `/rfas/:id/respond` | `rfas.respond` | ตอบกลับ RFA |
|
||||
| POST | `/rfas/:id/approve` | `rfas.approve` | อนุมัติ RFA |
|
||||
| POST | `/rfas/:id/revisions` | `rfas.update` | สร้าง Revision |
|
||||
| GET | `/rfas/:id/workflow` | `rfas.view` | ดู Workflow Status |
|
||||
|
||||
### 7.3 Drawing Module
|
||||
|
||||
**Base Path:** `/api/v1/drawings`
|
||||
|
||||
**Shop Drawings:**
|
||||
|
||||
| Method | Endpoint | Permission | Description |
|
||||
| :----- | :----------------------------- | :---------------- | :------------------ |
|
||||
| GET | `/shop-drawings` | `drawings.view` | รายการ Shop Drawing |
|
||||
| POST | `/shop-drawings` | `drawings.upload` | อัปโหลดใหม่ |
|
||||
| GET | `/shop-drawings/:id/revisions` | `drawings.view` | ดู Revisions |
|
||||
|
||||
**Contract Drawings:**
|
||||
|
||||
| Method | Endpoint | Permission | Description |
|
||||
| :----- | :------------------- | :---------------- | :---------------------- |
|
||||
| GET | `/contract-drawings` | `drawings.view` | รายการ Contract Drawing |
|
||||
| POST | `/contract-drawings` | `drawings.upload` | อัปโหลดใหม่ |
|
||||
|
||||
### 7.4 Project Module
|
||||
|
||||
**Base Path:** `/api/v1/projects`
|
||||
|
||||
| Method | Endpoint | Permission | Description |
|
||||
| :----- | :------------------------ | :----------------------- | :----------------- |
|
||||
| GET | `/projects` | `projects.view` | รายการโครงการ |
|
||||
| GET | `/projects/:id` | `projects.view` | รายละเอียด |
|
||||
| POST | `/projects` | `projects.create` | สร้างโครงการใหม่ |
|
||||
| PUT | `/projects/:id` | `projects.update` | อัปเดต |
|
||||
| POST | `/projects/:id/contracts` | `contracts.create` | สร้าง Contract |
|
||||
| GET | `/projects/:id/parties` | `projects.view` | ดู Project Parties |
|
||||
| POST | `/projects/:id/parties` | `project_parties.manage` | เพิ่ม Party |
|
||||
|
||||
### 7.5 User & Auth Module
|
||||
|
||||
**Base Path:** `/api/v1/users`, `/api/v1/auth`
|
||||
|
||||
**Authentication:**
|
||||
|
||||
```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 / reset - password;
|
||||
```
|
||||
|
||||
**User Management:**
|
||||
|
||||
```typescript
|
||||
GET /api/v1/users # List users
|
||||
GET /api/v1/users/:id # User details
|
||||
POST /api/v1/users # Create user
|
||||
PUT /api/v1/users/:id # Update user
|
||||
DELETE /api/v1/users/:id # Delete user
|
||||
POST /api/v1/users/:id/roles # Assign roles
|
||||
GET /api/v1/users/me # Current user info
|
||||
GET /api/v1/users/me/permissions # Current user permissions
|
||||
```
|
||||
|
||||
### 7.6 Search Module
|
||||
|
||||
**Base Path:** `/api/v1/search`
|
||||
|
||||
```typescript
|
||||
GET /api/v1/search?q=<query>&type=<correspondence|rfa|drawing>&project_id=<id>
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```typescript
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"results": [...],
|
||||
"aggregations": {
|
||||
"by_type": { "correspondence": 10, "rfa": 5 },
|
||||
"by_status": { "PENDING": 8, "APPROVED": 7 }
|
||||
}
|
||||
},
|
||||
"meta": {
|
||||
"total": 15,
|
||||
"took_ms": 45
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔔 Notification API
|
||||
|
||||
**Base Path:** `/api/v1/notifications`
|
||||
|
||||
```typescript
|
||||
GET /api/v1/notifications # List notifications
|
||||
GET /api/v1/notifications/:id # Notification details
|
||||
PATCH /api/v1/notifications/:id/read # Mark as read
|
||||
DELETE /api/v1/notifications/:id # Delete notification
|
||||
```
|
||||
|
||||
## 📈 Reporting & Export APIs
|
||||
|
||||
**Base Path:** `/api/v1/reports`
|
||||
|
||||
```typescript
|
||||
GET /api/v1/reports/correspondences?format=csv&project_id=1&from=2025-01-01&to=2025-12-31
|
||||
GET /api/v1/reports/rfas?format=excel&project_id=1
|
||||
GET /api/v1/reports/dashboard # Dashboard KPIs
|
||||
```
|
||||
|
||||
**Supported Formats:**
|
||||
|
||||
- `csv` - CSV file
|
||||
- `excel` - Excel file (.xlsx)
|
||||
- `pdf` - PDF file
|
||||
|
||||
## 🔧 Workflow Engine API
|
||||
|
||||
**Base Path:** `/api/v1/workflows`
|
||||
|
||||
```typescript
|
||||
GET /api/v1/workflows/definitions # List workflow definitions
|
||||
GET /api/v1/workflows/definitions/:id # Definition details
|
||||
POST /api/v1/workflows/instances # Create workflow instance
|
||||
GET /api/v1/workflows/instances/:id # Instance details
|
||||
POST /api/v1/workflows/instances/:id/transition # Execute transition
|
||||
GET /api/v1/workflows/instances/:id/history # View history
|
||||
```
|
||||
|
||||
## ⚡ Performance Optimization
|
||||
|
||||
### 11.1 Caching Strategy
|
||||
|
||||
**Cache Headers:**
|
||||
|
||||
```http
|
||||
Cache-Control: max-age=3600, private
|
||||
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
|
||||
```
|
||||
|
||||
**Cache TTL:**
|
||||
|
||||
- Master Data: 1 hour
|
||||
- User Sessions: 30 minutes
|
||||
- Search Results: 15 minutes
|
||||
- File Metadata: 1 hour
|
||||
|
||||
### 11.2 Response Compression
|
||||
|
||||
```http
|
||||
Accept-Encoding: gzip, deflate, br
|
||||
Content-Encoding: gzip
|
||||
```
|
||||
|
||||
## 🧪 Testing & Documentation
|
||||
|
||||
### 12.1 API Documentation
|
||||
|
||||
- **Swagger/OpenAPI:** Auto-generated จาก NestJS Decorators
|
||||
- **URL:** `https://backend.np-dms.work/api/docs`
|
||||
|
||||
### 12.2 Testing Strategy
|
||||
|
||||
- **Unit Tests:** Test individual controllers & services
|
||||
- **Integration Tests:** Test API endpoints with database
|
||||
- **E2E Tests:** Test complete user flows
|
||||
- **Contract Tests:** Verify API contracts
|
||||
|
||||
## 🚦 Health Check & Monitoring
|
||||
|
||||
```typescript
|
||||
GET /health # Health check endpoint
|
||||
GET /health/ready # Readiness probe
|
||||
GET /health/live # Liveness probe
|
||||
GET /metrics # Prometheus metrics
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```typescript
|
||||
{
|
||||
"status": "ok",
|
||||
"uptime": 86400,
|
||||
"checks": {
|
||||
"database": "ok",
|
||||
"redis": "ok",
|
||||
"elasticsearch": "ok"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📝 API Versioning Strategy
|
||||
|
||||
### 14.1 Versioning Approach
|
||||
|
||||
- **URL-Based Versioning:** `/api/v1/...`, `/api/v2/...`
|
||||
- **Backward Compatibility:** รองรับ API เวอร์ชันเก่าอย่างน้อย 1 เวอร์ชัน
|
||||
- **Deprecation Headers:**
|
||||
|
||||
```http
|
||||
X-API-Deprecation-Warning: This endpoint will be deprecated on 2026-01-01
|
||||
X-API-Deprecation-Info: https://docs.np-dms.work/migration/v2
|
||||
```
|
||||
|
||||
## 🎯 Best Practices Summary
|
||||
|
||||
1. **ใช้ DTOs สำหรับ Validation ทุก Request**
|
||||
2. **ส่ง Idempotency-Key สำหรับ Critical Operations**
|
||||
3. **ใช้ Proper HTTP Status Codes**
|
||||
4. **Implement Rate Limiting บน Client Side**
|
||||
5. **Handle Errors Gracefully**
|
||||
6. **Cache Frequently-Accessed Data**
|
||||
7. **Use Pagination สำหรับ Large Datasets**
|
||||
8. **Document ทุก Endpoint ด้วย Swagger**
|
||||
|
||||
---
|
||||
|
||||
**Document Control:**
|
||||
|
||||
- **Version:** 1.5.0
|
||||
- **Status:** First Draft
|
||||
- **Last Updated:** 2025-11-30
|
||||
- **Owner:** Nattanin Peancharoen
|
||||
0
specs/02-architecture/data-model.md
Normal file
0
specs/02-architecture/data-model.md
Normal file
953
specs/02-architecture/system-architecture.md
Normal file
953
specs/02-architecture/system-architecture.md
Normal file
@@ -0,0 +1,953 @@
|
||||
# 🏗️ System Architecture Specification
|
||||
|
||||
---
|
||||
|
||||
**title:** 'System Architecture'
|
||||
**version:** 1.5.0
|
||||
**status:** first-draft
|
||||
**owner:** Nattanin Peancharoen
|
||||
**last_updated:** 2025-11-30
|
||||
**related:**
|
||||
|
||||
- specs/01-requirements/02-architecture.md
|
||||
- specs/01-requirements/06-non-functional.md
|
||||
- specs/03-implementation/fullftack-js-v1.5.0.md
|
||||
|
||||
---
|
||||
|
||||
## 📋 ภาพรวม (Overview)
|
||||
|
||||
เอกสารนี้อธิบายสถาปัตยกรรมระบบ LCBP3-DMS (Laem Chabang Port Phase 3 - Document Management System) ที่ใช้แนวทาง **Headless/API-First Architecture** พร้อมการ Deploy บน QNAP Server ผ่าน Container Station
|
||||
|
||||
## 🎯 Architecture Principles
|
||||
|
||||
### 1.1 Core Principles
|
||||
|
||||
1. **Data Integrity First:** ความถูกต้องของข้อมูลต้องมาก่อนทุกอย่าง
|
||||
2. **Security by Design:** รักษาความปลอดภัยที่ทุกชั้น
|
||||
3. **Scalability:** รองรับการเติบโตในอนาคต
|
||||
4. **Resilience:** ทนทานต่อ Failure และ Recovery ได้รวดเร็ว
|
||||
5. **Observability:** ติดตามและวิเคราะห์สถานะระบบได้ง่าย
|
||||
|
||||
### 1.2 Architecture Style
|
||||
|
||||
- **Headless CMS Architecture:** แยก Frontend และ Backend เป็นอิสระ
|
||||
- **API-First:** Backend เป็น API Server ที่ Frontend หรือ Third-party สามารถเรียกใช้ได้
|
||||
- **Microservices-Ready:** ออกแบบเป็น Modular Architecture พร้อมแยกเป็น Microservices ในอนาคต
|
||||
|
||||
## 🏢 Infrastructure & Deployment
|
||||
|
||||
### 2.1 Server Infrastructure
|
||||
|
||||
- **Server:** QNAP TS-473A
|
||||
- CPU: AMD Ryzen V1500B
|
||||
- RAM: 32GB
|
||||
- Storage: /share/dms-data
|
||||
- **IP Address:** 159.192.126.103
|
||||
- **Domain:** np-dms.work, www.np-dms.work
|
||||
- **Containerization:** Docker & Docker Compose via Container Station
|
||||
- **Development Environment:** VS Code/Cursor on Windows 11
|
||||
|
||||
### 2.2 Network Architecture
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
Internet[Internet] --> NPM[Nginx Proxy Manager<br/>npm.np-dms.work]
|
||||
NPM --> Frontend[Next.js Frontend<br/>lcbp3.np-dms.work]
|
||||
NPM --> Backend[NestJS Backend<br/>backend.np-dms.work]
|
||||
NPM --> PMA[phpMyAdmin<br/>pma.np-dms.work]
|
||||
NPM --> N8N[n8n Workflow<br/>n8n.np-dms.work]
|
||||
NPM --> Gitea[Gitea Git<br/>git.np-dms.work]
|
||||
|
||||
Backend --> MariaDB[(MariaDB 10.11<br/>db.np-dms.work)]
|
||||
Backend --> Redis[(Redis Cache)]
|
||||
Backend --> Elastic[Elasticsearch]
|
||||
Backend --> Storage[File Storage<br/>/share/dms-data]
|
||||
|
||||
N8N --> Line[LINE Notify]
|
||||
Backend --> Email[Email Server]
|
||||
```
|
||||
|
||||
**Docker Network:**
|
||||
|
||||
- Network Name: `lcbp3`
|
||||
- ทุก Service เชื่อมต่อผ่าน Internal Docker Network เพื่อความปลอดภัย
|
||||
|
||||
### 2.3 Configuration Management
|
||||
|
||||
> [!WARNING] > **ข้อจำกัดสำคัญ:** QNAP Container Station ไม่รองรับการใช้ `.env` files ในการกำหนด Environment Variables
|
||||
|
||||
**Configuration Strategy:**
|
||||
|
||||
1. **Production/Staging:**
|
||||
|
||||
- ใช้ `docker-compose.yml` สำหรับกำหนด Environment Variables
|
||||
- ห้ามระบุ Sensitive Secrets (Password, Keys) ใน `docker-compose.yml` หลัก
|
||||
- ใช้ `docker-compose.override.yml` (gitignored) สำหรับ Secrets
|
||||
- พิจารณาใช้ Docker Secrets หรือ Hashicorp Vault
|
||||
|
||||
2. **Development:**
|
||||
|
||||
- ใช้ `docker-compose.override.yml` สำหรับ Local Secrets
|
||||
- ไฟล์หลักใส่ค่า Dummy/Placeholder
|
||||
|
||||
3. **Validation:**
|
||||
- ใช้ Joi/Zod validate Environment Variables ตอน App Start
|
||||
- Throw Error ทันทีหากขาด Variable สำคัญ
|
||||
|
||||
## 🔧 Core Services
|
||||
|
||||
### 3.1 Service Overview
|
||||
|
||||
| Service | Application Name | Domain | Technology | Purpose |
|
||||
| :---------------- | :--------------- | :------------------ | :----------------------- | :-------------------------- |
|
||||
| **Frontend** | lcbp3-frontend | lcbp3.np-dms.work | Next.js 14+ (App Router) | Web Application UI |
|
||||
| **Backend** | lcbp3-backend | backend.np-dms.work | NestJS (TypeScript) | API Server & Business Logic |
|
||||
| **Database** | lcbp3-db | db.np-dms.work | MariaDB 10.11 | Primary Database |
|
||||
| **DB Management** | lcbp3-db | pma.np-dms.work | phpMyAdmin | Database Admin UI |
|
||||
| **Reverse Proxy** | lcbp3-npm | npm.np-dms.work | Nginx Proxy Manager | Reverse Proxy & SSL |
|
||||
| **Workflow** | lcbp3-n8n | n8n.np-dms.work | n8n | Workflow Automation |
|
||||
| **Git** | git | git.np-dms.work | Gitea | Self-hosted Git |
|
||||
| **Cache** | - | - | Redis | Caching & Locking |
|
||||
| **Search** | - | - | Elasticsearch | Full-text Search |
|
||||
|
||||
### 3.2 Frontend (Next.js)
|
||||
|
||||
**Stack:**
|
||||
|
||||
- **Framework:** Next.js 14+ with App Router
|
||||
- **Language:** TypeScript (ESM)
|
||||
- **Styling:** Tailwind CSS + PostCSS
|
||||
- **Components:** shadcn/ui
|
||||
- **State Management:**
|
||||
- Server State: TanStack Query (React Query)
|
||||
- Form State: React Hook Form + Zod
|
||||
- UI State: useState/useReducer
|
||||
|
||||
**Responsibilities:**
|
||||
|
||||
- Render Web UI สำหรับผู้ใช้
|
||||
- จัดการ User Interactions
|
||||
- เรียก Backend API
|
||||
- Client-side Validation
|
||||
- Responsive Design (Desktop + Mobile)
|
||||
|
||||
### 3.3 Backend (NestJS)
|
||||
|
||||
**Stack:**
|
||||
|
||||
- **Framework:** NestJS (Node.js + TypeScript)
|
||||
- **ORM:** TypeORM
|
||||
- **Authentication:** JWT + Passport
|
||||
- **Authorization:** CASL (RBAC)
|
||||
- **Validation:** class-validator + class-transformer
|
||||
- **Documentation:** Swagger/OpenAPI
|
||||
|
||||
**Responsibilities:**
|
||||
|
||||
- ให้บริการ RESTful API
|
||||
- Business Logic Processing
|
||||
- Authentication & Authorization
|
||||
- Data Validation
|
||||
- Database Operations
|
||||
- File Upload Handling (Two-Phase Storage)
|
||||
- Workflow Engine
|
||||
- Background Jobs (Notifications, Cleanup)
|
||||
|
||||
### 3.4 Database (MariaDB 10.11)
|
||||
|
||||
**Features:**
|
||||
|
||||
- **JSON Support:** จัดเก็บ `details` fields (Dynamic Schema)
|
||||
- **Virtual Columns:** Index JSON fields สำหรับ Performance
|
||||
- **Partitioning:** สำหรับ `audit_logs` และ `notifications`
|
||||
- **Optimistic Locking:** ใช้ `@VersionColumn()` ป้องกัน Race Condition
|
||||
|
||||
**Key Tables:**
|
||||
|
||||
- Users & Permissions: `users`, `roles`, `permissions`, `user_roles`
|
||||
- Projects: `projects`, `organizations`, `contracts`, `project_parties`
|
||||
- Documents: `correspondences`, `rfas`, `shop_drawings`, `contract_drawings`
|
||||
- Workflow: `workflow_definitions`, `workflow_instances`, `workflow_history`
|
||||
- Files: `attachments`, `correspondence_attachments`, etc.
|
||||
- Audit: `audit_logs`
|
||||
|
||||
### 3.5 Redis
|
||||
|
||||
**Use Cases:**
|
||||
|
||||
1. **Distributed Locking:** Document Numbering, Critical Operations
|
||||
2. **Session Caching:** User Permissions, Profile Data
|
||||
3. **Master Data Cache:** Roles, Permissions, Organizations (TTL: 1 hour)
|
||||
4. **Queue Management:** BullMQ for Background Jobs
|
||||
5. **Rate Limiting:** Track API Request Counts
|
||||
|
||||
### 3.6 Elasticsearch
|
||||
|
||||
**Use Cases:**
|
||||
|
||||
- **Full-text Search:** Search across Correspondence, RFA, Drawings
|
||||
- **Advanced Filtering:** Multi-criteria Search
|
||||
- **Aggregations:** Statistics และ Dashboard Data
|
||||
|
||||
**Indexing Strategy:**
|
||||
|
||||
- Index อัตโนมัติเมื่อ Create/Update เอกสาร
|
||||
- Async Indexing ผ่าน Queue (ไม่ Block Main Request)
|
||||
|
||||
## 🧱 Backend Module Architecture
|
||||
|
||||
### 4.1 Modular Design
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "Core Modules"
|
||||
Common[CommonModule<br/>Shared Services]
|
||||
Auth[AuthModule<br/>JWT & Guards]
|
||||
User[UserModule<br/>User Management]
|
||||
end
|
||||
|
||||
subgraph "Business Modules"
|
||||
Project[ProjectModule<br/>Projects & Contracts]
|
||||
Corr[CorrespondenceModule<br/>Correspondences]
|
||||
RFA[RfaModule<br/>RFA Management]
|
||||
Drawing[DrawingModule<br/>Shop & Contract Drawings]
|
||||
Circ[CirculationModule<br/>Circulation Sheets]
|
||||
Trans[TransmittalModule<br/>Transmittals]
|
||||
end
|
||||
|
||||
subgraph "Supporting Modules"
|
||||
Workflow[WorkflowEngineModule<br/>Unified Workflow]
|
||||
Numbering[DocumentNumberingModule<br/>Auto Numbering]
|
||||
Search[SearchModule<br/>Elasticsearch]
|
||||
Master[MasterModule<br/>Master Data]
|
||||
JSON[JsonSchemaModule<br/>JSON Validation]
|
||||
end
|
||||
|
||||
Corr --> Workflow
|
||||
RFA --> Workflow
|
||||
Circ --> Workflow
|
||||
|
||||
Corr --> Numbering
|
||||
RFA --> Numbering
|
||||
|
||||
Search --> Corr
|
||||
Search --> RFA
|
||||
Search --> Drawing
|
||||
```
|
||||
|
||||
### 4.2 Module Descriptions
|
||||
|
||||
#### 4.2.1 CommonModule
|
||||
|
||||
**Responsibilities:**
|
||||
|
||||
- Database Configuration
|
||||
- FileStorageService (Two-Phase Upload)
|
||||
- AuditLogService
|
||||
- NotificationService
|
||||
- Shared DTOs, Guards, Interceptors
|
||||
|
||||
#### 4.2.2 AuthModule
|
||||
|
||||
**Responsibilities:**
|
||||
|
||||
- JWT Token Management
|
||||
- Authentication Guards
|
||||
- 4-Level Permission Checking:
|
||||
- Global (Superadmin)
|
||||
- Organization
|
||||
- Project
|
||||
- Contract
|
||||
- Token Refresh & Revocation
|
||||
|
||||
#### 4.2.3 UserModule
|
||||
|
||||
**Responsibilities:**
|
||||
|
||||
- User CRUD Operations
|
||||
- Role Assignment
|
||||
- Permission Management
|
||||
- User Profile Management
|
||||
|
||||
#### 4.2.4 ProjectModule
|
||||
|
||||
**Responsibilities:**
|
||||
|
||||
- Project Management
|
||||
- Contract Management
|
||||
- Organization Management
|
||||
- Project Parties & Contract Parties
|
||||
|
||||
#### 4.2.5 CorrespondenceModule
|
||||
|
||||
**Responsibilities:**
|
||||
|
||||
- Correspondence CRUD
|
||||
- Revision Management
|
||||
- Attachment Handling
|
||||
- Workflow Integration (Routing)
|
||||
|
||||
#### 4.2.6 RfaModule
|
||||
|
||||
**Responsibilities:**
|
||||
|
||||
- RFA CRUD
|
||||
- RFA Item Management
|
||||
- Workflow Integration (Approval Process)
|
||||
- Respond/Approve Actions
|
||||
|
||||
#### 4.2.7 DrawingModule
|
||||
|
||||
**Responsibilities:**
|
||||
|
||||
- Shop Drawing Management
|
||||
- Contract Drawing Management
|
||||
- Drawing Categories
|
||||
- Revision Tracking
|
||||
- Drawing References
|
||||
|
||||
#### 4.2.8 CirculationModule
|
||||
|
||||
**Responsibilities:**
|
||||
|
||||
- Circulation Sheet Management
|
||||
- Circulation Templates
|
||||
- Assignees Management
|
||||
- Workflow Integration (Internal Circulation)
|
||||
|
||||
#### 4.2.9 WorkflowEngineModule (Core)
|
||||
|
||||
> [!IMPORTANT] > **Unified Workflow Engine** - ระบบกลางสำหรับจัดการ Workflow ทั้งหมด
|
||||
|
||||
**Features:**
|
||||
|
||||
- DSL-Based Workflow Definitions (JSON Configuration)
|
||||
- State Machine Management
|
||||
- Workflow Instance Tracking
|
||||
- History & Audit Trail
|
||||
- Workflow Versioning
|
||||
|
||||
**Entities:**
|
||||
|
||||
- `WorkflowDefinition`: กำหนด Workflow Template
|
||||
- `WorkflowInstance`: Instance ที่กำลังรัน
|
||||
- `WorkflowHistory`: ประวัติการเปลี่ยน State
|
||||
|
||||
**Integration:**
|
||||
|
||||
- CorrespondenceModule → Routing Workflow
|
||||
- RfaModule → Approval Workflow
|
||||
- CirculationModule → Internal Circulation Workflow
|
||||
|
||||
#### 4.2.10 DocumentNumberingModule (Internal)
|
||||
|
||||
**Responsibilities:**
|
||||
|
||||
- Auto-generate Document Numbers
|
||||
- Token-Based Generator: `{CONTRACT}-{TYPE}-{DISCIPLINE}-{SEQ:4}`
|
||||
- **Double-Lock Mechanism:**
|
||||
- Layer 1: Redis Distributed Lock
|
||||
- Layer 2: Optimistic Database Lock (`@VersionColumn()`)
|
||||
|
||||
**Algorithm:**
|
||||
|
||||
1. Parse Template → Identify Required Tokens
|
||||
2. Acquire Redis Lock (Key: `project_id:type_id:discipline_id:year`)
|
||||
3. Query `document_number_counters` Table
|
||||
4. Increment Counter (Check Version)
|
||||
5. Generate Final Number
|
||||
6. Release Lock
|
||||
7. Retry on Conflict (Exponential Backoff)
|
||||
|
||||
#### 4.2.11 SearchModule
|
||||
|
||||
**Responsibilities:**
|
||||
|
||||
- Elasticsearch Integration
|
||||
- Full-text Search across Documents
|
||||
- Advanced Filtering
|
||||
- Search Result Aggregation
|
||||
|
||||
#### 4.2.12 JsonSchemaModule (Internal)
|
||||
|
||||
**Responsibilities:**
|
||||
|
||||
- JSON Schema Validation (AJV)
|
||||
- Schema Versioning & Migration
|
||||
- Dynamic Schema Generation
|
||||
- Data Transformation
|
||||
|
||||
## 📊 Data Flow Architecture
|
||||
|
||||
### 5.1 Main Request Flow
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as Client (Browser)
|
||||
participant NPM as Nginx Proxy
|
||||
participant BE as Backend (NestJS)
|
||||
participant Redis as Redis Cache
|
||||
participant DB as MariaDB
|
||||
participant ES as Elasticsearch
|
||||
|
||||
Client->>NPM: HTTP Request + JWT
|
||||
NPM->>BE: Forward Request
|
||||
|
||||
BE->>BE: Rate Limit Check
|
||||
BE->>BE: Validate Input (DTO)
|
||||
BE->>BE: JWT Auth Guard
|
||||
BE->>Redis: Get User Permissions
|
||||
Redis-->>BE: Permission Data
|
||||
BE->>BE: RBAC Guard (Check Permission)
|
||||
|
||||
BE->>DB: Query Data
|
||||
DB-->>BE: Return Data
|
||||
|
||||
BE->>BE: Business Logic Processing
|
||||
BE->>DB: Save Changes (Transaction)
|
||||
BE->>ES: Index for Search
|
||||
BE->>Redis: Invalidate Cache
|
||||
|
||||
BE->>DB: Audit Log
|
||||
BE-->>Client: JSON Response
|
||||
```
|
||||
|
||||
### 5.2 File Upload Flow (Two-Phase Storage)
|
||||
|
||||
> [!IMPORTANT] > **Two-Phase Storage** ป้องกัน Orphan Files และรักษา Data Integrity
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client
|
||||
participant Backend
|
||||
participant ClamAV as Virus Scanner
|
||||
participant TempStorage as Temp Storage
|
||||
participant PermStorage as Permanent Storage
|
||||
participant DB as Database
|
||||
|
||||
Client->>Backend: Upload File
|
||||
Backend->>ClamAV: Scan Virus
|
||||
ClamAV-->>Backend: Scan Result (CLEAN/INFECTED)
|
||||
|
||||
alt File is CLEAN
|
||||
Backend->>TempStorage: Save to temp/
|
||||
Backend-->>Client: Return temp_id
|
||||
|
||||
Client->>Backend: POST Create Document (include temp_id)
|
||||
Backend->>DB: BEGIN Transaction
|
||||
Backend->>DB: Create Document Record
|
||||
Backend->>PermStorage: Move temp/ → permanent/{YYYY}/{MM}/
|
||||
Backend->>DB: Create Attachment Record
|
||||
Backend->>DB: COMMIT Transaction
|
||||
Backend-->>Client: Success Response
|
||||
else File is INFECTED
|
||||
Backend-->>Client: Error: Virus Detected
|
||||
end
|
||||
|
||||
Note over Backend,TempStorage: Cron Job: Delete temp files > 24h
|
||||
```
|
||||
|
||||
### 5.3 Document Numbering Flow
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Service as Correspondence Service
|
||||
participant Numbering as Numbering Service
|
||||
participant Redis
|
||||
participant DB as MariaDB
|
||||
|
||||
Service->>Numbering: generateNextNumber(context)
|
||||
Numbering->>Numbering: Parse Template
|
||||
Numbering->>Redis: ACQUIRE Lock (project:type:year)
|
||||
|
||||
alt Lock Acquired
|
||||
Redis-->>Numbering: Lock Success
|
||||
Numbering->>DB: SELECT counter (with version)
|
||||
DB-->>Numbering: current_number, version
|
||||
Numbering->>DB: UPDATE counter SET last_number = X, version = version + 1 WHERE version = old_version
|
||||
|
||||
alt Update Success
|
||||
DB-->>Numbering: Success
|
||||
Numbering->>Numbering: Generate Final Number
|
||||
Numbering->>Redis: RELEASE Lock
|
||||
Numbering-->>Service: Document Number
|
||||
else Version Conflict (Race Condition)
|
||||
DB-->>Numbering: Update Failed
|
||||
Numbering->>Redis: RELEASE Lock
|
||||
Numbering->>Numbering: Retry (Exponential Backoff)
|
||||
end
|
||||
else Lock Failed
|
||||
Redis-->>Numbering: Lock Timeout
|
||||
Numbering->>Numbering: Retry or Fail
|
||||
end
|
||||
```
|
||||
|
||||
### 5.4 Workflow Execution Flow
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant User
|
||||
participant Module as Correspondence Module
|
||||
participant Engine as Workflow Engine
|
||||
participant DB
|
||||
participant Notify as Notification Service
|
||||
|
||||
User->>Module: Create Correspondence
|
||||
Module->>Engine: createWorkflowInstance(definition_id, entity_id)
|
||||
Engine->>DB: Create workflow_instance
|
||||
Engine->>DB: Set initial state
|
||||
Engine-->>Module: Instance Created
|
||||
Module-->>User: Success
|
||||
|
||||
User->>Module: Execute Action (e.g., "Send")
|
||||
Module->>Engine: executeTransition(instance_id, action)
|
||||
Engine->>DB: Check current state
|
||||
Engine->>Engine: Validate transition (DSL)
|
||||
|
||||
alt Transition Valid
|
||||
Engine->>DB: Update state
|
||||
Engine->>DB: Create workflow_history
|
||||
Engine->>Notify: Trigger Notification
|
||||
Notify->>Notify: Queue Email/Line
|
||||
Engine-->>Module: Transition Success
|
||||
Module-->>User: Action Completed
|
||||
else Invalid Transition
|
||||
Engine-->>Module: Error: Invalid State Transition
|
||||
Module-->>User: Error Response
|
||||
end
|
||||
```
|
||||
|
||||
## 🛡️ Security Architecture
|
||||
|
||||
### 6.1 Security Layers
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "Layer 1: Network Security"
|
||||
SSL[SSL/TLS<br/>Nginx Proxy Manager]
|
||||
Firewall[Firewall Rules<br/>QNAP]
|
||||
end
|
||||
|
||||
subgraph "Layer 2: Application Security"
|
||||
RateLimit[Rate Limiting]
|
||||
CSRF[CSRF Protection]
|
||||
XSS[XSS Prevention]
|
||||
Input[Input Validation]
|
||||
end
|
||||
|
||||
subgraph "Layer 3: Authentication"
|
||||
JWT[JWT Tokens]
|
||||
Refresh[Token Refresh]
|
||||
Revoke[Token Revocation]
|
||||
end
|
||||
|
||||
subgraph "Layer 4: Authorization"
|
||||
RBAC[4-Level RBAC]
|
||||
Guards[Permission Guards]
|
||||
CASL[CASL Rules]
|
||||
end
|
||||
|
||||
subgraph "Layer 5: Data Security"
|
||||
Encrypt[Data Encryption]
|
||||
Audit[Audit Logs]
|
||||
Backup[Backups]
|
||||
end
|
||||
|
||||
subgraph "Layer 6: File Security"
|
||||
Virus[Virus Scanning]
|
||||
FileType[Type Validation]
|
||||
FileAccess[Access Control]
|
||||
end
|
||||
```
|
||||
|
||||
### 6.2 Authentication & Authorization Details
|
||||
|
||||
**JWT Token Structure:**
|
||||
|
||||
```json
|
||||
{
|
||||
"sub": "user_id",
|
||||
"scope": "organization_id|project_id|contract_id",
|
||||
"iat": 1638360000,
|
||||
"exp": 1638388800
|
||||
}
|
||||
```
|
||||
|
||||
**Permission Checking Logic:**
|
||||
|
||||
1. Extract JWT from `Authorization: Bearer <token>`
|
||||
2. Validate Token (Signature, Expiration)
|
||||
3. Get User Permissions from Redis Cache (Key: `user:{user_id}:permissions`)
|
||||
4. Check Permission based on Context:
|
||||
- Global Permission (Superadmin)
|
||||
- Organization Permission
|
||||
- Project Permission (if in project context)
|
||||
- Contract Permission (if in contract context)
|
||||
5. Allow if **any level** grants permission (Most Permissive)
|
||||
|
||||
### 6.3 Rate Limiting
|
||||
|
||||
| Endpoint Category | Limit | Tracking |
|
||||
| :---------------- | :------------ | :--------- |
|
||||
| Anonymous | 100 req/hour | IP Address |
|
||||
| Authentication | 10 req/min | IP Address |
|
||||
| File Upload | 50 req/hour | User ID |
|
||||
| Search | 500 req/hour | User ID |
|
||||
| Viewer | 500 req/hour | User ID |
|
||||
| Editor | 1000 req/hour | User ID |
|
||||
| Document Control | 2000 req/hour | User ID |
|
||||
| Admin | 5000 req/hour | User ID |
|
||||
|
||||
**Implementation:** `rate-limiter-flexible` library with Redis backend
|
||||
|
||||
### 6.4 Input Validation
|
||||
|
||||
**Frontend (Client-Side):**
|
||||
|
||||
- React Hook Form + Zod Schema Validation
|
||||
- Sanitize User Inputs before Display
|
||||
|
||||
**Backend (Server-Side):**
|
||||
|
||||
- class-validator DTOs
|
||||
- Whitelist Validation (`@ValidateIf`, `@IsEnum`, etc.)
|
||||
- Transform Pipes
|
||||
|
||||
**File Upload Validation:**
|
||||
|
||||
1. **File Type Validation:**
|
||||
|
||||
- White-list: PDF, DWG, DOCX, XLSX, ZIP
|
||||
- Magic Number Verification (ไม่ใช่แค่ extension)
|
||||
|
||||
2. **File Size Validation:**
|
||||
|
||||
- Maximum: 50MB per file
|
||||
|
||||
3. **Virus Scanning:**
|
||||
- ClamAV Integration
|
||||
- Scan before saving to temp storage
|
||||
|
||||
### 6.5 OWASP Top 10 Protection
|
||||
|
||||
| Vulnerability | Protection Measure |
|
||||
| :-------------------------------- | :----------------------------------- |
|
||||
| SQL Injection | Parameterized Queries (TypeORM) |
|
||||
| XSS | Input Sanitization + Output Encoding |
|
||||
| CSRF | CSRF Tokens (State-changing ops) |
|
||||
| Broken Auth | JWT + Secure Token Management |
|
||||
| Security Misconfiguration | Security Headers (Helmet.js) |
|
||||
| Sensitive Data Exposure | Encryption + Secure Storage |
|
||||
| Insufficient Logging | Comprehensive Audit Logs |
|
||||
| Insecure Deserialization | Input Validation |
|
||||
| Using Known Vulnerable Components | Regular Dependency Updates |
|
||||
|
||||
## 📈 Performance & Scalability
|
||||
|
||||
### 7.1 Caching Strategy
|
||||
|
||||
| Data Type | Cache Location | TTL | Invalidation |
|
||||
| :--------------- | :------------- | :------ | :------------------------ |
|
||||
| User Permissions | Redis | 30 min | On role/permission change |
|
||||
| Master Data | Redis | 1 hour | On update |
|
||||
| Search Results | Redis | 15 min | Time-based |
|
||||
| File Metadata | Redis | 1 hour | On file update |
|
||||
| Session Data | Redis | 8 hours | On logout |
|
||||
|
||||
### 7.2 Database Optimization
|
||||
|
||||
**Indexes:**
|
||||
|
||||
- Foreign Keys (Auto-indexed)
|
||||
- Search Columns (`idx_cor_project`, `idx_rfa_status`, etc.)
|
||||
- JSON Virtual Columns (for frequently queried JSON fields)
|
||||
|
||||
**Partitioning:**
|
||||
|
||||
- `audit_logs`: Partitioned by Year
|
||||
- `notifications`: Partitioned by Month
|
||||
- Automated Partition Creation (Cron Job)
|
||||
|
||||
**Query Optimization:**
|
||||
|
||||
- Use Views for Complex Queries (`v_current_correspondences`, `v_user_tasks`)
|
||||
- Pagination for Large Datasets
|
||||
- Eager/Lazy Loading Strategy
|
||||
|
||||
### 7.3 Performance Targets
|
||||
|
||||
| Metric | Target | Measurement |
|
||||
| :---------------------------------- | :------ | :------------- |
|
||||
| API Response Time (90th percentile) | < 200ms | Simple CRUD |
|
||||
| Search Query Performance | < 500ms | Complex Search |
|
||||
| File Upload Processing | < 30s | 50MB file |
|
||||
| Concurrent Users | 100+ | Simultaneous |
|
||||
| Cache Hit Ratio | > 80% | Master Data |
|
||||
| Application Startup | < 30s | Cold Start |
|
||||
|
||||
## 🔄 Resilience & Error Handling
|
||||
|
||||
### 8.1 Resilience Patterns
|
||||
|
||||
**Circuit Breaker:**
|
||||
|
||||
- Applied to: Elasticsearch, Email Service, LINE Notify
|
||||
- Threshold: 5 failures in 1 minute
|
||||
- Timeout: 30 seconds
|
||||
- Recovery: Half-open after 1 minute
|
||||
|
||||
**Retry Mechanism:**
|
||||
|
||||
- Strategy: Exponential Backoff
|
||||
- Max Retries: 3
|
||||
- Applied to: External API Calls, Document Numbering
|
||||
|
||||
**Graceful Degradation:**
|
||||
|
||||
- Search Service Down → Return cached results or basic search
|
||||
- Email Service Down → Queue for later retry
|
||||
- LINE Notify Down → Log error, continue operation
|
||||
|
||||
### 8.2 Error Handling
|
||||
|
||||
**Backend:**
|
||||
|
||||
- Global Exception Filter
|
||||
- Structured Error Response Format
|
||||
- Error Logging with Context (Winston)
|
||||
- Don't Expose Internal Details in Error Messages
|
||||
|
||||
**Frontend:**
|
||||
|
||||
- Error Boundaries (React)
|
||||
- Toast Notifications
|
||||
- Fallback UI Components
|
||||
- Retry Mechanisms for Failed Requests
|
||||
|
||||
## 📊 Monitoring & Observability
|
||||
|
||||
### 9.1 Health Checks
|
||||
|
||||
**Endpoints:**
|
||||
|
||||
```
|
||||
GET /health # Overall health
|
||||
GET /health/ready # Readiness probe
|
||||
GET /health/live # Liveness probe
|
||||
```
|
||||
|
||||
**Checks:**
|
||||
|
||||
- Database Connection
|
||||
- Redis Connection
|
||||
- Elasticsearch Connection
|
||||
- Disk Space
|
||||
- Memory Usage
|
||||
|
||||
### 9.2 Metrics Collection
|
||||
|
||||
**Application Metrics:**
|
||||
|
||||
- Request Rate (req/sec)
|
||||
- Response Time (p50, p90, p99)
|
||||
- Error Rate
|
||||
- Active Connections
|
||||
|
||||
**Business Metrics:**
|
||||
|
||||
- Documents Created per Day
|
||||
- Workflow Completion Rate
|
||||
- User Activity
|
||||
- Search Query Performance
|
||||
|
||||
**Infrastructure Metrics:**
|
||||
|
||||
- CPU Usage
|
||||
- Memory Usage
|
||||
- Disk I/O
|
||||
- Network Throughput
|
||||
|
||||
### 9.3 Logging Strategy
|
||||
|
||||
> [!WARNING] > **QNAP Storage Constraints:** ต้องจำกัดปริมาณ Logs
|
||||
|
||||
**Log Levels:**
|
||||
|
||||
- **Production:** WARN and ERROR only
|
||||
- **Staging:** INFO for critical business flows
|
||||
- **Development:** DEBUG allowed
|
||||
|
||||
**Structured Logging:**
|
||||
|
||||
```json
|
||||
{
|
||||
"timestamp": "2025-11-30T13:48:20Z",
|
||||
"level": "INFO",
|
||||
"service": "backend",
|
||||
"module": "CorrespondenceModule",
|
||||
"action": "create",
|
||||
"user_id": 1,
|
||||
"ip_address": "192.168.1.100",
|
||||
"duration_ms": 45,
|
||||
"message": "Correspondence created successfully"
|
||||
}
|
||||
```
|
||||
|
||||
**Log Rotation:**
|
||||
|
||||
- Rotate Daily
|
||||
- Keep 7 days
|
||||
- Compress Old Logs
|
||||
|
||||
### 9.4 Audit Logging
|
||||
|
||||
**Scope:**
|
||||
|
||||
- All CRUD Operations on Critical Data
|
||||
- Permission Changes
|
||||
- Login Attempts (Success/Failure)
|
||||
- File Downloads
|
||||
- Workflow State Changes
|
||||
|
||||
**Audit Log Fields:**
|
||||
|
||||
- `user_id`
|
||||
- `action` (e.g., `correspondence.create`)
|
||||
- `entity_type`, `entity_id`
|
||||
- `old_values`, `new_values` (for updates)
|
||||
- `ip_address`, `user_agent`
|
||||
- `timestamp`
|
||||
|
||||
## 💾 Backup & Disaster Recovery
|
||||
|
||||
### 10.1 Backup Strategy
|
||||
|
||||
**Database Backup:**
|
||||
|
||||
- **Frequency:** Daily (Automated)
|
||||
- **Method:** Full Backup + Transaction Logs
|
||||
- **Retention:** 30 days
|
||||
- **Tool:** QNAP HBS 3 or mysqldump
|
||||
|
||||
**File Storage Backup:**
|
||||
|
||||
- **Frequency:** Daily
|
||||
- **Path:** `/share/dms-data`
|
||||
- **Method:** Incremental Backup
|
||||
- **Retention:** 30 days
|
||||
- **Tool:** QNAP Snapshot or rsync
|
||||
|
||||
### 10.2 Disaster Recovery
|
||||
|
||||
**Recovery Objectives:**
|
||||
|
||||
- **RTO (Recovery Time Objective):** < 4 hours
|
||||
- **RPO (Recovery Point Objective):** < 1 hour
|
||||
|
||||
**Recovery Procedures:**
|
||||
|
||||
1. **Database Restoration:**
|
||||
|
||||
- Restore latest full backup
|
||||
- Apply transaction logs to point-in-time
|
||||
- Verify data integrity
|
||||
|
||||
2. **File Storage Restoration:**
|
||||
|
||||
- Restore from QNAP snapshot
|
||||
- Verify file permissions
|
||||
|
||||
3. **Application Redeployment:**
|
||||
|
||||
- Deploy from known-good Docker images
|
||||
- Verify health checks
|
||||
|
||||
4. **Data Integrity Verification:**
|
||||
- Run consistency checks
|
||||
- Verify critical business data
|
||||
|
||||
## 🏗️ Deployment Architecture
|
||||
|
||||
### 11.1 Container Deployment
|
||||
|
||||
**Docker Compose Services:**
|
||||
|
||||
```yaml
|
||||
services:
|
||||
frontend:
|
||||
image: lcbp3-frontend:latest
|
||||
networks: [lcbp3]
|
||||
depends_on: [backend]
|
||||
|
||||
backend:
|
||||
image: lcbp3-backend:latest
|
||||
networks: [lcbp3]
|
||||
depends_on: [mariadb, redis, elasticsearch]
|
||||
|
||||
mariadb:
|
||||
image: mariadb:10.11
|
||||
networks: [lcbp3]
|
||||
volumes: [/share/dms-data/mysql:/var/lib/mysql]
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
networks: [lcbp3]
|
||||
|
||||
elasticsearch:
|
||||
image: elasticsearch:8.x
|
||||
networks: [lcbp3]
|
||||
|
||||
nginx-proxy-manager:
|
||||
image: jc21/nginx-proxy-manager:latest
|
||||
networks: [lcbp3]
|
||||
ports: [80:80, 443:443]
|
||||
```
|
||||
|
||||
### 11.2 CI/CD Pipeline (Future)
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
Git[Gitea Repository] --> Build[Build & Test]
|
||||
Build --> StagingDeploy[Deploy to Staging]
|
||||
StagingDeploy --> Test[Run E2E Tests]
|
||||
Test --> Manual[Manual Approval]
|
||||
Manual --> ProdDeploy[Deploy to Production]
|
||||
ProdDeploy --> Monitor[Monitor & Alert]
|
||||
```
|
||||
|
||||
## 🎯 Future Enhancements
|
||||
|
||||
### 12.1 Scalability Improvements
|
||||
|
||||
- [ ] Separate into Microservices (when needed)
|
||||
- [ ] Add Load Balancer (HAProxy/Nginx)
|
||||
- [ ] Database Replication (Master-Slave)
|
||||
- [ ] Message Queue (RabbitMQ/Kafka) for async processing
|
||||
|
||||
### 12.2 Advanced Features
|
||||
|
||||
- [ ] AI-Powered Document Classification
|
||||
- [ ] Advanced Analytics & Reporting
|
||||
- [ ] Mobile Native Apps
|
||||
- [ ] Blockchain Integration for Document Integrity
|
||||
|
||||
### 12.3 Infrastructure
|
||||
|
||||
- [ ] Multi-Region Deployment
|
||||
- [ ] CDN for Static Assets
|
||||
- [ ] Automated Failover
|
||||
- [ ] Blue-Green Deployment
|
||||
|
||||
---
|
||||
|
||||
**Document Control:**
|
||||
|
||||
- **Version:** 1.5.0
|
||||
- **Status:** First Draft
|
||||
- **Last Updated:** 2025-11-30
|
||||
- **Owner:** Nattanin Peancharoen
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
Reference in New Issue
Block a user