260322:1648 Correct Coresspondence / Doing RFA / Correct CI
CI Pipeline / build (push) Failing after 12m41s
Build and Deploy / deploy (push) Failing after 2m44s

This commit is contained in:
admin
2026-03-22 16:48:12 +07:00
parent e5deedb42e
commit 11984bfa29
683 changed files with 105251 additions and 29068 deletions
@@ -10,9 +10,11 @@
## 1. Overview
### 1.1 Purpose
ระบบ Document Numbering สำหรับสร้างเลขที่เอกสารอัตโนมัติที่มีความเป็นเอกลักษณ์ (unique) และสามารถติดตามได้ (traceable) สำหรับเอกสารทุกประเภทในระบบ LCBP3-DMS
### 1.2 Scope
- Auto-generation ของเลขที่เอกสารตามรูปแบบที่กำหนด
- Manual override สำหรับการ import เอกสารเก่า
- Cancelled number handling (ไม่ reuse)
@@ -21,6 +23,7 @@
- Complete audit trail สำหรับทุก operation
### 1.3 Document Types Supported
- Correspondences (COR)
- Request for Approvals (RFA)
- Contract Drawings (CD)
@@ -35,6 +38,7 @@
### 2.1 Auto Number Generation
#### FR-DN-001: Generate Sequential Number
**Priority**: CRITICAL
**Status**: Required
@@ -42,12 +46,14 @@
ระบบต้องสามารถสร้างเลขที่เอกสารอัตโนมัติตามลำดับ (sequential) โดยไม่ซ้ำกัน
**Acceptance Criteria**:
- เลขที่เอกสารต้องเป็น unique ใน scope ที่กำหนด
- ต้องเพิ่มขึ้นทีละ 1 (increment by 1)
- ต้องรองรับ concurrent requests โดยไม่มีเลขที่ซ้ำ
- Response time < 100ms (p95)
**Example**:
```
COR-00001-2025
COR-00002-2025
@@ -57,6 +63,7 @@ COR-00003-2025
---
#### FR-DN-002: Configurable Number Format
**Priority**: HIGH
**Status**: Required
@@ -64,6 +71,7 @@ COR-00003-2025
ระบบต้องรองรับการกำหนดรูปแบบเลขที่เอกสารที่หลากหลาย
**Format Tokens**:
- `{PREFIX}` - คำนำหน้าตามประเภทเอกสาร (e.g., COR, RFA)
- `{YYYY}` - ปี 4 หลัก (e.g., 2025)
- `{YY}` - ปี 2 หลัก (e.g., 25)
@@ -73,12 +81,14 @@ COR-00003-2025
- `{CONTRACT}` - รหัสสัญญา
**Acceptance Criteria**:
- รองรับ format tokens ที่ระบุ
- Admin สามารถกำหนด format ผ่าน UI ได้
- Validate format ก่อน save
- แสดง preview ของเลขที่ที่จะถูกสร้าง
**Examples**:
```typescript
// Correspondence format
"COR-{YYYY}-{SEQ:5}"
@@ -96,6 +106,7 @@ COR-00003-2025
---
#### FR-DN-003: Scope-based Sequences
**Priority**: HIGH
**Status**: Required
@@ -103,6 +114,7 @@ COR-00003-2025
ระบบต้องรองรับการสร้าง sequence ที่แยกตาม scope ที่ต่างกัน
**Scopes**:
1. **Global**: Sequence ระดับระบบทั้งหมด
2. **Project**: Sequence แยกตามโครงการ
3. **Contract**: Sequence แยกตามสัญญา
@@ -110,11 +122,13 @@ COR-00003-2025
5. **Monthly**: Sequence reset ทุกเดือน
**Acceptance Criteria**:
- เลขที่ไม่ซ้ำภายใน scope เดียวกัน
- Scope ที่ต่างกันสามารถมีเลขที่เดียวกันได้
- Support multiple active scopes
**Example**:
```
Project A: COR-A-2025-00001, COR-A-2025-00002
Project B: COR-B-2025-00001, COR-B-2025-00002
@@ -129,6 +143,7 @@ COR-2025-00001 (Jan 2025)
### 2.2 Manual Override
#### FR-DN-004: Manual Number Assignment
**Priority**: HIGH
**Status**: Required
@@ -136,11 +151,13 @@ COR-2025-00001 (Jan 2025)
ระบบต้องรองรับการกำหนดเลขที่เอกสารด้วยตนเอง (manual override)
**Use Cases**:
1. Import เอกสารเก่าจากระบบเดิม
2. External documents จาก client/consultant
3. Correction หลังพบความผิดพลาด
**Acceptance Criteria**:
- ตรวจสอบ duplicate ก่อน save
- Validate format ตามรูปแบบที่กำหนด
- Auto-update sequence counter ถ้าเลขที่สูงกว่า current
@@ -148,11 +165,12 @@ COR-2025-00001 (Jan 2025)
- ต้องมีสิทธิ์ Admin ขึ้นไปเท่านั้น
**Validation Rules**:
```typescript
interface ManualNumberValidation {
format_match: boolean; // ตรง format หรือไม่
not_duplicate: boolean; // ไม่ซ้ำ
in_valid_range: boolean; // อยู่ในช่วงที่กำหนด
format_match: boolean; // ตรง format หรือไม่
not_duplicate: boolean; // ไม่ซ้ำ
in_valid_range: boolean; // อยู่ในช่วงที่กำหนด
permission_granted: boolean; // มีสิทธิ์
}
```
@@ -160,6 +178,7 @@ interface ManualNumberValidation {
---
#### FR-DN-005: Bulk Import Support
**Priority**: MEDIUM
**Status**: Required
@@ -167,6 +186,7 @@ interface ManualNumberValidation {
ระบบต้องรองรับการ import เอกสารหลายรายการพร้อมกัน
**Acceptance Criteria**:
- รองรับไฟล์ CSV/Excel
- Validate ทุกรายการก่อน import
- แสดง preview ก่อน confirm
@@ -175,6 +195,7 @@ interface ManualNumberValidation {
- Generate import report
**CSV Format**:
```csv
document_type,document_number,created_at,metadata
COR,COR-2024-00001,2024-01-01,{"imported":true}
@@ -186,6 +207,7 @@ COR,COR-2024-00002,2024-01-05,{"imported":true}
### 2.3 Cancelled & Void Handling
#### FR-DN-006: Skip Cancelled Numbers
**Priority**: HIGH
**Status**: Required
@@ -193,17 +215,20 @@ COR,COR-2024-00002,2024-01-05,{"imported":true}
เลขที่เอกสารที่ถูกยกเลิกต้องไม่ถูก reuse
**Rationale**:
- รักษา audit trail ที่ชัดเจน
- ป้องกันความสับสน
- Legal compliance
**Acceptance Criteria**:
- Cancelled number ยังคงอยู่ในฐานข้อมูลพร้อม status
- ระบบข้าม (skip) cancelled number เมื่อสร้างเลขที่ใหม่
- บันทึกเหตุผลการยกเลิก
- แสดง cancelled numbers ใน audit trail
**Example Timeline**:
```
2025-00001 ✅ ACTIVE (created 2025-01-01)
2025-00002 ❌ CANCELLED (created 2025-01-02, cancelled 2025-01-03)
@@ -213,6 +238,7 @@ COR,COR-2024-00002,2024-01-05,{"imported":true}
---
#### FR-DN-007: Void and Replace
**Priority**: HIGH
**Status**: Required
@@ -220,6 +246,7 @@ COR,COR-2024-00002,2024-01-05,{"imported":true}
ระบบต้องรองรับการ void เอกสารและสร้างเอกสารใหม่แทน
**Workflow**:
1. User เลือกเอกสารที่ต้องการ void
2. ระบุเหตุผล (required)
3. ระบบเปลี่ยน status เอกสารเดิมเป็น VOID
@@ -227,6 +254,7 @@ COR,COR-2024-00002,2024-01-05,{"imported":true}
5. Link เอกสารใหม่กับเดิม (voided_from_id)
**Acceptance Criteria**:
- เอกสารเดิม status = VOID (ไม่ลบ)
- เอกสารใหม่ได้เลขที่ต่อเนื่องจาก sequence
- มี reference link ระหว่างเอกสาร
@@ -234,6 +262,7 @@ COR,COR-2024-00002,2024-01-05,{"imported":true}
- แสดง void history chain (A→B→C)
**Database Relationship**:
```sql
-- Original document
id: 100
@@ -254,6 +283,7 @@ voided_from_id: 100
### 2.4 Concurrency & Performance
#### FR-DN-008: Prevent Race Conditions
**Priority**: CRITICAL
**Status**: Required
@@ -261,17 +291,20 @@ voided_from_id: 100
ระบบต้องป้องกันการสร้างเลขที่ซ้ำเมื่อมีการ request พร้อมกัน
**Solution**:
- Distributed locking (Redlock)
- Database pessimistic locking
- Two-phase commit pattern
**Acceptance Criteria**:
- Zero duplicate numbers ภายใต้ concurrent load (1000 req/s)
- Lock acquisition time < 50ms (avg)
- Automatic retry on lock failure (max 3 times)
- Timeout handling (30 seconds)
**Load Test Requirements**:
```bash
# Must pass without duplicates
concurrent_users: 100
@@ -283,6 +316,7 @@ expected_duplicates: 0
---
#### FR-DN-009: Two-Phase Commit
**Priority**: HIGH
**Status**: Required
@@ -290,26 +324,30 @@ expected_duplicates: 0
ใช้ Two-phase commit pattern เพื่อความสมบูรณ์ของข้อมูล
**Phase 1: Reserve**
- ล็อกเลขที่และ reserve ไว้ชั่วคราว
- Set TTL 5 นาที
- Return reservation token
**Phase 2: Confirm or Cancel**
- Confirm: บันทึกลงฐานข้อมูลถาวร
- Cancel: คืน lock และ reservation
**Acceptance Criteria**:
- Reservation ต้อง expire หลัง 5 นาที
- Auto-cleanup expired reservations
- Support explicit cancel
- Idempotent confirmation
**API Flow**:
```typescript
// Phase 1
const { token, number } = await reserveNumber({
document_type: 'COR',
project_id: 1
project_id: 1,
});
// Do some work...
@@ -325,6 +363,7 @@ await cancelReservation(token);
### 2.5 Monitoring & Audit
#### FR-DN-010: Complete Audit Trail
**Priority**: HIGH
**Status**: Required
@@ -332,6 +371,7 @@ await cancelReservation(token);
บันทึกทุก operation ที่เกิดขึ้นกับเลขที่เอกสาร
**Events to Log**:
- Number reserved
- Number confirmed
- Number cancelled
@@ -341,6 +381,7 @@ await cancelReservation(token);
- Format changed
**Audit Fields**:
```typescript
interface AuditLog {
id: number;
@@ -358,6 +399,7 @@ interface AuditLog {
```
**Acceptance Criteria**:
- Log ทุก operation
- Searchable by user, date, type
- Export to CSV
@@ -366,6 +408,7 @@ interface AuditLog {
---
#### FR-DN-011: Metrics & Alerting
**Priority**: MEDIUM
**Status**: Required
@@ -373,6 +416,7 @@ interface AuditLog {
แสดงสถิติและส่ง alert เมื่อเกิดปัญหา
**Metrics**:
- Sequence utilization (% of max)
- Average lock wait time
- Failed lock attempts
@@ -380,6 +424,7 @@ interface AuditLog {
- Manual overrides per day
**Alerts**:
- Sequence >90% used (WARNING)
- Sequence >95% used (CRITICAL)
- Lock wait time >1s (WARNING)
@@ -387,6 +432,7 @@ interface AuditLog {
- High error rate (WARNING)
**Acceptance Criteria**:
- Real-time dashboard (Grafana)
- Email/LINE notifications
- Alert history tracking
@@ -399,22 +445,26 @@ interface AuditLog {
### 3.1 Performance
#### NFR-DN-001: Response Time
- Number generation: <100ms (p95)
- Lock acquisition: <50ms (avg)
- Bulk import: <5s per 100 records
#### NFR-DN-002: Throughput
- Support >500 req/s
- Scale horizontally (add Redis nodes)
### 3.2 Reliability
#### NFR-DN-003: Availability
- System uptime: 99.9%
- Graceful degradation (fallback to DB-only)
- Auto-recovery from Redis failure
#### NFR-DN-004: Data Integrity
- Zero duplicate numbers (100% guarantee)
- ACID transactions
- Backup & restore procedures
@@ -422,12 +472,14 @@ interface AuditLog {
### 3.3 Security
#### NFR-DN-005: Access Control
- Admin only: Format configuration, sequence adjustment
- Manager+: Manual override, void document
- User: Auto-generate only
- Audit all operations
#### NFR-DN-006: Data Protection
- Encrypt sensitive data (audit logs)
- Secure Redis connections (TLS)
- Rate limiting (100 req/min per user)
@@ -435,6 +487,7 @@ interface AuditLog {
### 3.4 Scalability
#### NFR-DN-007: Capacity Planning
- Support 10,000 documents/day
- Store 10M+ historical numbers
- Archive old audit logs (>2 years)
@@ -442,6 +495,7 @@ interface AuditLog {
### 3.5 Maintainability
#### NFR-DN-008: Code Quality
- Unit test coverage: >70%
- Integration test coverage: >50%
- E2E test coverage: >20 critical paths
@@ -452,24 +506,28 @@ interface AuditLog {
## 4. Business Rules
### BR-DN-001: Sequence Scope Rules
- Correspondence: Project-level + Yearly reset
- RFA: Contract-level + Yearly reset
- Drawings: Contract-level + No reset
- Transmittal: Project-level + Monthly reset
### BR-DN-002: Number Format Rules
- Min length: 10 characters
- Max length: 50 characters
- Must include {SEQ} token
- Must be ASCII only (no Thai/Chinese)
### BR-DN-003: Manual Override Rules
- Only for document_types with allow_manual_override=true
- Must validate format
- Must check duplicate
- Requires Admin permission
### BR-DN-004: Void Rules
- Can only void ACTIVE documents
- Cannot void already-VOID documents
- Must provide reason (min 10 chars)
@@ -480,6 +538,7 @@ interface AuditLog {
## 5. Data Model
### 5.1 Numbering Configuration
```sql
CREATE TABLE document_numbering_configs (
id INT PRIMARY KEY AUTO_INCREMENT,
@@ -495,6 +554,7 @@ CREATE TABLE document_numbering_configs (
```
### 5.2 Sequence Counter
```sql
CREATE TABLE document_numbering_sequences (
id INT PRIMARY KEY AUTO_INCREMENT,
@@ -509,6 +569,7 @@ CREATE TABLE document_numbering_sequences (
```
### 5.3 Audit Log
```sql
CREATE TABLE document_numbering_audit_logs (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
@@ -533,6 +594,7 @@ CREATE TABLE document_numbering_audit_logs (
## 6. API Specifications
### 6.1 Reserve Number
```http
POST /api/document-numbering/reserve
Content-Type: application/json
@@ -553,6 +615,7 @@ Response 201:
```
### 6.2 Confirm Reservation
```http
POST /api/document-numbering/confirm
Content-Type: application/json
@@ -569,6 +632,7 @@ Response 200:
```
### 6.3 Manual Override
```http
POST /api/document-numbering/manual
Content-Type: application/json
@@ -594,24 +658,28 @@ Response 201:
## 7. Testing Requirements
### 7.1 Unit Tests
- Format parsing and validation
- Sequence increment logic
- Manual override validation
- Scope resolution
### 7.2 Integration Tests
- Redis locking mechanism
- Database transactions
- Two-phase commit flow
- Bulk import
### 7.3 Load Tests
- Concurrent number generation (1000 req/s)
- Lock contention under load
- Redis failover scenarios
- Database connection pool exhaustion
### 7.4 E2E Tests
- Complete document creation flow
- Void and replace workflow
- Bulk import with validation
@@ -622,6 +690,7 @@ Response 201:
## 8. Migration Plan
### 8.1 Legacy Data Import
1. Export existing document numbers from old system
2. Validate format and detect duplicates
3. Bulk import using manual override API
@@ -629,6 +698,7 @@ Response 201:
5. Verify data integrity
### 8.2 Rollout Strategy
- Week 1-2: Deploy to staging, test with dummy data
- Week 3: Deploy to production, enable for test project
- Week 4: Enable for all projects
@@ -639,18 +709,21 @@ Response 201:
## 9. Success Criteria
### 9.1 Functional Success
- ✅ All FRs implemented and tested
- ✅ Zero duplicate numbers in production
- ✅ Migration of 50,000+ legacy documents
- ✅ UAT approved by stakeholders
### 9.2 Performance Success
- ✅ Response time <100ms (p95)
- ✅ Throughput >500 req/s
- ✅ Lock acquisition <50ms (avg)
- ✅ Zero downtime during deployment
### 9.3 Business Success
- ✅ Document creation speed +30%
- ✅ Manual numbering errors -80%
- ✅ User satisfaction >4.5/5
@@ -661,12 +734,14 @@ Response 201:
## 10. Appendix
### 10.1 Glossary
- **Sequence**: ลำดับตัวเลขที่เพิ่มขึ้นอัตโนมัติ
- **Scope**: ขอบเขตที่ sequence แยกตาม (project, contract, etc.)
- **Token**: Format placeholder (e.g., {YYYY}, {SEQ})
- **Redlock**: Distributed locking algorithm สำหรับ Redis
### 10.2 References
- [ADR-018: Document Numbering Strategy](../05-decisions/adr-018-document-numbering.md)
- [Two-Phase Commit Pattern](https://en.wikipedia.org/wiki/Two-phase_commit_protocol)
- [Redlock Algorithm](https://redis.io/docs/manual/patterns/distributed-locks/)
@@ -675,8 +750,8 @@ Response 201:
**Approval Sign-off**:
| Role | Name | Date | Signature |
|------|------|------|-----------|
| Product Owner | ___________ | _______ | _________ |
| Tech Lead | ___________ | _______ | _________ |
| QA Lead | ___________ | _______ | _________ |
| Role | Name | Date | Signature |
| ------------- | -------------- | ---------- | ---------- |
| Product Owner | ****\_\_\_**** | **\_\_\_** | ****\_**** |
| Tech Lead | ****\_\_\_**** | **\_\_\_** | ****\_**** |
| QA Lead | ****\_\_\_**** | **\_\_\_** | ****\_**** |