251202:2300 Prepare 1.5.1

This commit is contained in:
2025-12-03 01:16:27 +07:00
parent 9dcdba0bb3
commit 1817158f25
28 changed files with 7362 additions and 268 deletions

View File

@@ -1,8 +1,8 @@
# Development Tasks
**Project:** LCBP3-DMS (Laem Chabang Port Phase 3 - Document Management System)
**Version:** 1.5.0
**Last Updated:** 2025-12-01
**Version:** 1.5.1
**Last Updated:** 2025-12-02
---
@@ -280,10 +280,17 @@ graph TB
- **Type:** Core Service
- **Key Deliverables:**
- Double-lock mechanism (Redis + DB)
- Template-based generator
- Concurrent-safe implementation
- Double-lock mechanism (Redis Redlock + DB Optimistic Lock)
- Template-based generator (10 token types)
- Concurrent-safe implementation (100+ concurrent requests)
- Comprehensive error handling (4 scenarios)
- Monitoring & alerting (Prometheus + Grafana)
- **Documentation:**
- 📋 [Requirements](../01-requirements/03.11-document-numbering.md)
- 📘 [Implementation Guide](../03-implementation/document-numbering.md)
- 📗 [Operations Guide](../04-operations/document-numbering-operations.md)
- **Related ADR:** [ADR-002](../05-decisions/ADR-002-document-numbering-strategy.md)
- **Task Details:** [TASK-BE-004](./TASK-BE-004-document-numbering.md)
### TASK-BE-006: Workflow Engine
@@ -619,5 +626,5 @@ Add these features when:
---
**Version:** 1.5.0
**Last Updated:** 2025-11-30
**Version:** 1.5.1
**Last Updated:** 2025-12-02

View File

@@ -10,21 +10,26 @@
## 📋 Overview
สร้าง DocumentNumberingService ที่ใช้ Double-Lock mechanism (Redis + DB Optimistic Lock) สำหรับการสร้างเลขที่เอกสารอัตโนมัติ พร้อม comprehensive error handling, monitoring, และ audit logging
สร้าง DocumentNumberingService ที่ใช้ Double-Lock mechanism (Redis + DB Optimistic Lock) สำหรับการสร้างเลขที่เอกสารอัตโนมัติ ตาม requirements ใน [03.11-document-numbering.md](file:///e:/np-dms/lcbp3/specs/01-requirements/03.11-document-numbering.md)
### เอกสารอ้างอิง
- **Requirements**: [03.11-document-numbering.md](file:///e:/np-dms/lcbp3/specs/01-requirements/03.11-document-numbering.md)
- **Implementation Guide**: [document-numbering.md](file:///e:/np-dms/lcbp3/specs/03-implementation/document-numbering.md)
- **Operations Guide**: [document-numbering-operations.md](file:///e:/np-dms/lcbp3/specs/04-operations/document-numbering-operations.md)
---
## 🎯 Objectives
- ✅ Template-Based Number Generation (รองรับ 9 token types)
- ✅ Double-Lock Protection (Redis + DB Optimistic Lock)
- ✅ Template-Based Number Generation (รองรับ 10 token types)
- ✅ Double-Lock Protection (Redis Redlock + DB Optimistic Lock)
- ✅ Concurrent-Safe (No duplicate numbers, tested with 100+ concurrent requests)
- ✅ Support 4 Document Types (Correspondence, RFA, Transmittal, Drawing)
- ✅ Year-Based Reset (พ.ศ. และ ค.ศ.)
- ✅ Transmittal Special Logic (To Owner vs To Contractor)
- ✅ Support All Document Types (LETTER, RFA, TRANSMITTAL, RFI, MEMO, etc.)
- ✅ Year-Based Auto Reset (ปี ค.ศ.)
- ✅ 4 Error Scenarios with Fallback Strategies
- ✅ Comprehensive Audit Logging
- ✅ Monitoring & Alerting
- ✅ Monitoring & Alerting (Prometheus + Grafana)
- ✅ Rate Limiting & Security
---
@@ -34,42 +39,44 @@
### 1. Number Generation
- ✅ Generate unique sequential numbers
- ✅ Support all 9 token types: `{PROJECT}`, `{ORG}`, `{TYPE}`, `{SUB_TYPE}`, `{DISCIPLINE}`, `{CATEGORY}`, `{SEQ:n}`, `{YEAR:B.E.}`, `{YEAR:A.D}`, `{REV}`
- ✅ Support all 10 token types: `{PROJECT}`, `{ORIGINATOR}`, `{RECIPIENT}`, `{CORR_TYPE}`, `{SUB_TYPE}`, `{RFA_TYPE}`, `{DISCIPLINE}`, `{SEQ:n}`, `{YEAR:B.E.}`, `{YEAR:A.D.}`, `{REV}`
- ✅ No duplicates even with 100+ concurrent requests
- ✅ Performance: <500ms (normal), <2s (p95), <5s (p99)
### 2. Lock Mechanism
- ✅ Redis distributed lock (TTL: 5 seconds)
- ✅ DB optimistic lock with version column
- ✅ Redis Redlock distributed lock (TTL: 5 seconds)
- ✅ DB optimistic lock with `version` column
- ✅ Fallback to DB pessimistic lock when Redis unavailable
- ✅ Retry with exponential backoff (5 retries max for lock, 2 for version conflict, 3 for DB errors)
### 3. Document Types Support
-Correspondence (Letter Type และ Other Types)
- ✅ RFA with Discipline
- ✅ Transmittal (To Owner vs To Contractor with different formats)
- ✅ Drawing with Category
-LETTER / RFI / MEMO / EMAIL / MOM / INSTRUCTION / NOTICE / OTHER
- Counter Key: `(project_id, originator_org_id, recipient_org_id, corr_type_id, 0, 0, 0, year)`
- ✅ TRANSMITTAL
- Counter Key: `(project_id, originator_org_id, recipient_org_id, corr_type_id, sub_type_id, 0, 0, year)`
- ✅ RFA
- Counter Key: `(project_id, originator_org_id, NULL, corr_type_id, 0, rfa_type_id, discipline_id, year)`
### 4. Error Handling
- ✅ Scenario 1: Redis Unavailable → Fallback to DB lock
- ✅ Scenario 1: Redis Unavailable → Fallback to DB pessimistic lock
- ✅ Scenario 2: Lock Timeout → Retry 5x with exponential backoff
- ✅ Scenario 3: Version Conflict → Retry 2x
- ✅ Scenario 4: DB Connection Error → Retry 3x
- ✅ Scenario 3: Version Conflict → Retry 2x immediately
- ✅ Scenario 4: DB Connection Error → Retry 3x with exponential backoff
### 5. Audit & Monitoring
- ✅ Audit log for every generated number
-Track lock wait times, retry counts, errors
-Metrics collection for monitoring dashboard
- ✅ Audit log for every generated number (with performance metrics)
-Error logging with classification (LOCK_TIMEOUT, VERSION_CONFLICT, etc.)
-Prometheus metrics collection
- ✅ Alerting on failures >5%
### 6. Security
- ✅ Rate limiting: 10 req/min per user, 50 req/min per IP
- ✅ Authorization checks
- ✅ Rate limiting: 10 req/min per user, 50 req/min per IP (using @nestjs/throttler)
- ✅ Authorization checks (JWT + Roles)
- ✅ IP address logging
---
@@ -136,37 +143,56 @@ export class DocumentNumberConfig {
import { Entity, PrimaryColumn, Column, UpdateDateColumn, VersionColumn } from 'typeorm';
/**
* ตาราง document_number_counters
* Composite PK: (project_id, originator_organization_id, recipient_organization_id,
* correspondence_type_id, sub_type_id, rfa_type_id, discipline_id, current_year)
*
* References: specs/01-requirements/03.11-document-numbering.md#counter-key-components
*/
@Entity('document_number_counters')
export class DocumentNumberCounter {
@PrimaryColumn()
project_id: number;
@PrimaryColumn({ name: 'project_id' })
projectId: number;
@PrimaryColumn()
doc_type_id: number;
@PrimaryColumn({ name: 'originator_organization_id' })
originatorOrganizationId: number;
@PrimaryColumn({ default: 0 })
sub_type_id: number; // สำหรับ Correspondence types
@PrimaryColumn({ name: 'recipient_organization_id', nullable: true })
recipientOrganizationId: number | null; // NULL for RFA
@PrimaryColumn({ default: 0 })
discipline_id: number; // สำหรับ RFA, Drawing
@PrimaryColumn({ name: 'correspondence_type_id' })
correspondenceTypeId: number;
@PrimaryColumn({ type: 'varchar', length: 20, nullable: true, default: null })
recipient_type: string; // สำหรับ Transmittal: 'OWNER', 'CONTRACTOR', 'CONSULTANT', 'OTHER'
@PrimaryColumn({ name: 'sub_type_id', default: 0 })
subTypeId: number; // for TRANSMITTAL only
@PrimaryColumn()
year: number; // ปี พ.ศ. หรือ ค.ศ.
@PrimaryColumn({ name: 'rfa_type_id', default: 0 })
rfaTypeId: number; // for RFA only
@Column({ default: 0 })
last_number: number;
@PrimaryColumn({ name: 'discipline_id', default: 0 })
disciplineId: number; // for RFA only
@VersionColumn({ comment: 'Optimistic Lock version' })
@PrimaryColumn({ name: 'current_year' })
currentYear: number; // ปี ค.ศ.
@Column({ name: 'last_number', default: 0 })
lastNumber: number;
@VersionColumn({ name: 'version', comment: 'Optimistic Lock version' })
version: number;
@UpdateDateColumn()
updated_at: Date;
@UpdateDateColumn({ name: 'updated_at' })
updatedAt: Date;
}
```
> **⚠️ หมายเหตุ Schema:**
>
> - Primary Key ใช้ `COALESCE(recipient_organization_id, 0)` ในการสร้าง constraint (ดู migration file)
> - `sub_type_id`, `rfa_type_id`, `discipline_id` ใช้ `0` แทน NULL
> - Counter reset อัตโนมัติทุกปี (แยก counter ตาม `current_year`)
#### 1.3 Document Number Audit Entity
```typescript
@@ -1179,6 +1205,7 @@ ensure:
## 📦 Deliverables
### Core Implementation
- [x] DocumentNumberingService with all 4 error scenarios
- [x] DocumentNumberCounter Entity (with sub_type_id, recipient_type)
- [x] DocumentNumberConfig Entity
@@ -1188,12 +1215,14 @@ ensure:
- [x] Retry Logic with Exponential Backoff
### API & Security
- [x] DocumentNumberingController with 4 endpoints
- [x] Rate Limiting Guard (10/min per user, 50/min per IP)
- [x] Authorization Guards
- [x] API Documentation (Swagger)
### Testing
- [x] Unit Tests (targeting 90%+ coverage)
- [x] Concurrent Tests (100+ simultaneous requests)
- [x] Error Scenario Tests (all 4 scenarios)
@@ -1202,6 +1231,7 @@ ensure:
- [x] Load Tests (Artillery config for 50-100 req/sec)
### Monitoring & Documentation
- [x] Metrics Collection Integration
- [x] Audit Logging
- [x] Implementation Documentation
@@ -1225,11 +1255,13 @@ ensure:
## 📌 Implementation Notes
### Performance Targets
- **Normal Operation:** <500ms (no conflicts, Redis available)
- **95th Percentile:** <2 seconds (including retries)
- **99th Percentile:** <5 seconds (worst case scenarios)
### Lock Configuration
- **Redis Lock TTL:** 5 seconds (auto-release)
- **Lock Acquisition Timeout:** 10 seconds
- **Max Retries (Lock):** 5 times with exponential backoff (1s, 2s, 4s, 8s, 16s)
@@ -1237,18 +1269,22 @@ ensure:
- **Max Retries (DB Error):** 3 times with exponential backoff (1s, 2s, 4s)
### Rate Limiting
- **Per User:** 10 requests/minute
- **Per IP:** 50 requests/minute
- **Global:** 5000 requests/minute
### Format Templates
Stored in database (`document_number_configs` table), configurable per:
- Project
- Document Type
- Sub Type (optional, use 0 for fallback)
- Discipline (optional, use 0 for fallback)
### Counter Reset
- Automatic reset per year (based on `{YEAR:B.E.}` or `{YEAR:A.D.}` in template)
- Manual reset available (Super Admin only, with audit log)