Prepare to version 1.5 use spec-kit
This commit is contained in:
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
|
||||
Reference in New Issue
Block a user