# Document Numbering Requirements

**Version**: 1.6.1
**Last Updated**: 2025-01-16
**Status**: draft
**Related ADRs**: ADR-018-document-numbering-strategy

---

## 1. Overview

### 1.1 Purpose
ระบบ Document Numbering สำหรับสร้างเลขที่เอกสารอัตโนมัติที่มีความเป็นเอกลักษณ์ (unique) และสามารถติดตามได้ (traceable) สำหรับเอกสารทุกประเภทในระบบ LCBP3-DMS

### 1.2 Scope
- Auto-generation ของเลขที่เอกสารตามรูปแบบที่กำหนด
- Manual override สำหรับการ import เอกสารเก่า
- Cancelled number handling (ไม่ reuse)
- Void & Replace pattern สำหรับการแทนที่เอกสาร
- Distributed locking เพื่อป้องกัน race condition
- Complete audit trail สำหรับทุก operation

### 1.3 Document Types Supported
- Correspondences (COR)
- Request for Approvals (RFA)
- Contract Drawings (CD)
- Shop Drawings (SD)
- Transmittals (TRN)
- Circulation Sheets (CIR)

---

## 2. Functional Requirements

### 2.1 Auto Number Generation

#### FR-DN-001: Generate Sequential Number
**Priority**: CRITICAL
**Status**: Required

**Description**:
ระบบต้องสามารถสร้างเลขที่เอกสารอัตโนมัติตามลำดับ (sequential) โดยไม่ซ้ำกัน

**Acceptance Criteria**:
- เลขที่เอกสารต้องเป็น unique ใน scope ที่กำหนด
- ต้องเพิ่มขึ้นทีละ 1 (increment by 1)
- ต้องรองรับ concurrent requests โดยไม่มีเลขที่ซ้ำ
- Response time < 100ms (p95)

**Example**:
```
COR-00001-2025
COR-00002-2025
COR-00003-2025
```

---

#### FR-DN-002: Configurable Number Format
**Priority**: HIGH
**Status**: Required

**Description**:
ระบบต้องรองรับการกำหนดรูปแบบเลขที่เอกสารที่หลากหลาย

**Format Tokens**:
- `{PREFIX}` - คำนำหน้าตามประเภทเอกสาร (e.g., COR, RFA)
- `{YYYY}` - ปี 4 หลัก (e.g., 2025)
- `{YY}` - ปี 2 หลัก (e.g., 25)
- `{MM}` - เดือน 2 หลัก (e.g., 01-12)
- `{SEQ:n}` - sequence number ความยาว n หลัก (e.g., {SEQ:5} = 00001)
- `{PROJECT}` - รหัสโครงการ
- `{CONTRACT}` - รหัสสัญญา

**Acceptance Criteria**:
- รองรับ format tokens ที่ระบุ
- Admin สามารถกำหนด format ผ่าน UI ได้
- Validate format ก่อน save
- แสดง preview ของเลขที่ที่จะถูกสร้าง

**Examples**:
```typescript
// Correspondence format
"COR-{YYYY}-{SEQ:5}"
→ COR-2025-00001

// RFA format with project
"RFA-{PROJECT}-{YYYY}{MM}-{SEQ:4}"
→ RFA-LCBP3-202501-0001

// Drawing format
"{CONTRACT}-CD-{SEQ:6}"
→ C001-CD-000001
```

---

#### FR-DN-003: Scope-based Sequences
**Priority**: HIGH
**Status**: Required

**Description**:
ระบบต้องรองรับการสร้าง sequence ที่แยกตาม scope ที่ต่างกัน

**Scopes**:
1. **Global**: Sequence ระดับระบบทั้งหมด
2. **Project**: Sequence แยกตามโครงการ
3. **Contract**: Sequence แยกตามสัญญา
4. **Yearly**: Sequence reset ทุกปี
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

Yearly Reset:
COR-2024-00999 (Dec 2024)
COR-2025-00001 (Jan 2025)
```

---

### 2.2 Manual Override

#### FR-DN-004: Manual Number Assignment
**Priority**: HIGH
**Status**: Required

**Description**:
ระบบต้องรองรับการกำหนดเลขที่เอกสารด้วยตนเอง (manual override)

**Use Cases**:
1. Import เอกสารเก่าจากระบบเดิม
2. External documents จาก client/consultant
3. Correction หลังพบความผิดพลาด

**Acceptance Criteria**:
- ตรวจสอบ duplicate ก่อน save
- Validate format ตามรูปแบบที่กำหนด
- Auto-update sequence counter ถ้าเลขที่สูงกว่า current
- บันทึก audit log ว่าเป็น manual override
- ต้องมีสิทธิ์ Admin ขึ้นไปเท่านั้น

**Validation Rules**:
```typescript
interface ManualNumberValidation {
  format_match: boolean;       // ตรง format หรือไม่
  not_duplicate: boolean;      // ไม่ซ้ำ
  in_valid_range: boolean;     // อยู่ในช่วงที่กำหนด
  permission_granted: boolean; // มีสิทธิ์
}
```

---

#### FR-DN-005: Bulk Import Support
**Priority**: MEDIUM
**Status**: Required

**Description**:
ระบบต้องรองรับการ import เอกสารหลายรายการพร้อมกัน

**Acceptance Criteria**:
- รองรับไฟล์ CSV/Excel
- Validate ทุกรายการก่อน import
- แสดง preview ก่อน confirm
- Rollback ทั้งหมดถ้ามีรายการใดผิดพลาด (transactional)
- Auto-update sequence counters หลัง import
- Generate import report

**CSV Format**:
```csv
document_type,document_number,created_at,metadata
COR,COR-2024-00001,2024-01-01,{"imported":true}
COR,COR-2024-00002,2024-01-05,{"imported":true}
```

---

### 2.3 Cancelled & Void Handling

#### FR-DN-006: Skip Cancelled Numbers
**Priority**: HIGH
**Status**: Required

**Description**:
เลขที่เอกสารที่ถูกยกเลิกต้องไม่ถูก 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)
2025-00003 ✅ ACTIVE   (created 2025-01-04)
```

---

#### FR-DN-007: Void and Replace
**Priority**: HIGH
**Status**: Required

**Description**:
ระบบต้องรองรับการ void เอกสารและสร้างเอกสารใหม่แทน

**Workflow**:
1. User เลือกเอกสารที่ต้องการ void
2. ระบุเหตุผล (required)
3. ระบบเปลี่ยน status เอกสารเดิมเป็น VOID
4. สร้างเอกสารใหม่ด้วยเลขที่ใหม่
5. Link เอกสารใหม่กับเดิม (voided_from_id)

**Acceptance Criteria**:
- เอกสารเดิม status = VOID (ไม่ลบ)
- เอกสารใหม่ได้เลขที่ต่อเนื่องจาก sequence
- มี reference link ระหว่างเอกสาร
- บันทึก void reason
- แสดง void history chain (A→B→C)

**Database Relationship**:
```sql
-- Original document
id: 100
document_number: COR-2025-00005
status: VOID
void_reason: "ข้อมูลผิด"
voided_at: 2025-01-10

-- Replacement document
id: 101
document_number: COR-2025-00006
status: ACTIVE
voided_from_id: 100
```

---

### 2.4 Concurrency & Performance

#### FR-DN-008: Prevent Race Conditions
**Priority**: CRITICAL
**Status**: Required

**Description**:
ระบบต้องป้องกันการสร้างเลขที่ซ้ำเมื่อมีการ 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
requests_per_second: 500
test_duration: 5 minutes
expected_duplicates: 0
```

---

#### FR-DN-009: Two-Phase Commit
**Priority**: HIGH
**Status**: Required

**Description**:
ใช้ 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
});

// Do some work...

// Phase 2
await confirmReservation(token);
// OR
await cancelReservation(token);
```

---

### 2.5 Monitoring & Audit

#### FR-DN-010: Complete Audit Trail
**Priority**: HIGH
**Status**: Required

**Description**:
บันทึกทุก operation ที่เกิดขึ้นกับเลขที่เอกสาร

**Events to Log**:
- Number reserved
- Number confirmed
- Number cancelled
- Manual override
- Void document
- Sequence adjusted
- Format changed

**Audit Fields**:
```typescript
interface AuditLog {
  id: number;
  operation: string;
  document_type: string;
  document_number: string;
  old_value?: any;
  new_value?: any;
  user_id: number;
  ip_address: string;
  user_agent: string;
  timestamp: Date;
  metadata: Record<string, any>;
}
```

**Acceptance Criteria**:
- Log ทุก operation
- Searchable by user, date, type
- Export to CSV
- Retain for 7 years

---

#### FR-DN-011: Metrics & Alerting
**Priority**: MEDIUM
**Status**: Required

**Description**:
แสดงสถิติและส่ง alert เมื่อเกิดปัญหา

**Metrics**:
- Sequence utilization (% of max)
- Average lock wait time
- Failed lock attempts
- Numbers generated per day
- Manual overrides per day

**Alerts**:
- Sequence >90% used (WARNING)
- Sequence >95% used (CRITICAL)
- Lock wait time >1s (WARNING)
- Redis unavailable (CRITICAL)
- High error rate (WARNING)

**Acceptance Criteria**:
- Real-time dashboard (Grafana)
- Email/LINE notifications
- Alert history tracking
- Configurable thresholds

---

## 3. Non-Functional Requirements

### 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

### 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)

### 3.4 Scalability

#### NFR-DN-007: Capacity Planning
- Support 10,000 documents/day
- Store 10M+ historical numbers
- Archive old audit logs (>2 years)

### 3.5 Maintainability

#### NFR-DN-008: Code Quality
- Unit test coverage: >70%
- Integration test coverage: >50%
- E2E test coverage: >20 critical paths
- Documentation: Complete API docs

---

## 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)
- Replacement is optional

---

## 5. Data Model

### 5.1 Numbering Configuration
```sql
CREATE TABLE document_numbering_configs (
  id INT PRIMARY KEY AUTO_INCREMENT,
  document_type VARCHAR(50) NOT NULL,
  format VARCHAR(200) NOT NULL,
  scope ENUM('GLOBAL','PROJECT','CONTRACT','YEARLY','MONTHLY'),
  allow_manual_override BOOLEAN DEFAULT FALSE,
  max_value INT DEFAULT 999999,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  UNIQUE KEY (document_type, scope)
);
```

### 5.2 Sequence Counter
```sql
CREATE TABLE document_numbering_sequences (
  id INT PRIMARY KEY AUTO_INCREMENT,
  config_id INT NOT NULL,
  scope_value VARCHAR(50),  -- project_id, contract_id, year, etc.
  current_value INT DEFAULT 0,
  last_used_at TIMESTAMP NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (config_id) REFERENCES document_numbering_configs(id),
  UNIQUE KEY (config_id, scope_value)
);
```

### 5.3 Audit Log
```sql
CREATE TABLE document_numbering_audit_logs (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  operation VARCHAR(50) NOT NULL,
  document_type VARCHAR(50),
  document_number VARCHAR(50),
  old_value TEXT,
  new_value TEXT,
  user_id INT NOT NULL,
  ip_address VARCHAR(45),
  user_agent VARCHAR(500),
  timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  metadata JSON,
  INDEX idx_document_number (document_number),
  INDEX idx_user_id (user_id),
  INDEX idx_timestamp (timestamp)
);
```

---

## 6. API Specifications

### 6.1 Reserve Number
```http
POST /api/document-numbering/reserve
Content-Type: application/json

{
  "document_type": "COR",
  "project_id": 1,
  "contract_id": null,
  "metadata": {}
}

Response 201:
{
  "token": "uuid-v4",
  "document_number": "COR-2025-00042",
  "expires_at": "2025-01-16T10:30:00Z"
}
```

### 6.2 Confirm Reservation
```http
POST /api/document-numbering/confirm
Content-Type: application/json

{
  "token": "uuid-v4"
}

Response 200:
{
  "document_number": "COR-2025-00042",
  "confirmed_at": "2025-01-16T10:25:00Z"
}
```

### 6.3 Manual Override
```http
POST /api/document-numbering/manual
Content-Type: application/json
Authorization: Bearer <admin-token>

{
  "document_type": "COR",
  "document_number": "COR-2024-99999",
  "reason": "Import from legacy system",
  "skip_validation": false
}

Response 201:
{
  "document_number": "COR-2024-99999",
  "is_manual": true,
  "created_at": "2025-01-16T10:25:00Z"
}
```

---

## 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
- Admin configuration UI

---

## 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
4. Update sequence counters to max values
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
- Week 5+: Monitor and optimize

---

## 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
- ✅ System stability >99.9%

---

## 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/)

---

**Approval Sign-off**:

| Role | Name | Date | Signature |
|------|------|------|-----------|
| Product Owner | ___________ | _______ | _________ |
| Tech Lead | ___________ | _______ | _________ |
| QA Lead | ___________ | _______ | _________ |
