# 3.11 Document Numbering Management (การจัดการเลขที่เอกสาร)

---

title: 'Functional Requirements: Document Numbering Management'
version: 1.5.0
status: first-draft
owner: Nattanin Peancharoen
last_updated: 2025-11-30
related:

- specs/01-requirements/01-objectives.md
- specs/01-requirements/02-architecture.md
- specs/01-requirements/03-functional-requirements.md

---

## 3.11.1. วัตถุประสงค์

- ระบบต้องสามารถสร้างเลขที่เอกสาร (Running Number) ได้โดยอัตโนมัติและยืดหยุ่นสูง
- ระบต้องสามารถกำหนด รูปแบบ(template) เลขที่เอกสารได้ สำหรับแต่ละโครงการ, ชนิดเอกสาร, ประเภทเอกสาร

## 3.11.2. Logic การนับเลข (Counter Logic)

- การนับเลขจะต้องรองรับการแยกตาม Key ที่ซับซ้อนขึ้น ตามแต่ละ รูปแบบ(template) ได้

## 3.11.3. Format Template

- รองรับการกำหนดรูปแบบด้วย Token Replacement
  - transmittal to owner:
    - {ORG}-{ORG}-{TYPE}-{SEQ:4}-{YEAR B.D.} -> คคง.-สคฉ.3-03-21-0117-2568
  - other transmittal:
    - {ORG}-{ORG}-{TYPE}-{SEQ:4}-{YEAR B.D.} -> ผรม.2-คคง.-0117-2568
  - RFA:
    - {PROJECT}-{ORG}-{TYPE}-{DISCIPLINE}-{SEQ:4}-{REV} -> LCBP3-C2-RFI-ROW-0029-A
  - Correspondence type LETTER:
    - {ORG}-{ORG}-{TYPE}-{SEQ:4}-{YEAR B.D.} -> คคง.-สคฉ.3-0985-2568
  - Correspondence รองรับ Token: {ORG}-{ORG}-{TYPE}-{SEQ:4}-{YEAR B.D.} -> คคง.-สคฉ.3-STR-0001-2568
  - RFA รองรับ Token: {PROJECT}-{ORG}-{TYPE}-{DISCIPLINE}-{SEQ:4}-{REV} -> TEAM-RFA-STR-0001-A
  - Transmittal รองรับ Token: {PROJECT}-{ORG}-{TYPE}-{DISCIPLINE}-{SEQ:4}-{REV} -> TEAM-TR-STR-0001-A

## 3.11.4. Transmittal Logic

- รองรับเงื่อนไขพิเศษสำหรับ Transmittal ที่เลขอาจเปลี่ยนตามผู้รับ (To Owner vs To Contractor)

## 3.11.5. กลไกความปลอดภัย

- ยังคงใช้ Redis Distributed Lock และ Optimistic Locking เพื่อป้องกันเลขซ้ำหรือข้าม

## 3.11.6. ต้องมี retry mechanism และ fallback strategy เมื่อการ generate เลขที่เอกสารล้มเหลว

## 3.11.7. Fallback Logic (เพิ่ม)

- กรณีที่เอกสารประเภทนั้นไม่มี discipline_id หรือ sub_type_id (เป็นค่า NULL หรือไม่ระบุ) ให้ระบบใช้ค่า Default (เช่น 0) ในการจัดกลุ่ม Counter เพื่อป้องกัน Error และรับประกันความถูกต้องของ Running Number (Uniqueness Guarantee)
- Scenario 1: Redis Unavailable
  - Fallback เป็น database-only locking (pessimistic lock)
  - Log warning และแจ้ง ops team
  - ระบบยังใช้งานได้แต่ performance ลดลง
- Scenario 2: Lock Acquisition Timeout
  - Retry 5 ครั้งด้วย exponential backoff (1s, 2s, 4s, 8s, 16s)
  - หลัง 5 ครั้ง: Return error 503 "Service Temporarily Unavailable"
  - Frontend แสดง user-friendly message: "ระบบกำลังยุ่ง กรุณาลองใหม่ภายหลัง"
- Scenario 3: Version Conflict After Lock
  - Retry transaction อีก 2 ครั้ง
  - หากยังล้มเหลว: Log error พร้อม context และ return 409 Conflict
  - Frontend แสดง user-friendly message: "เลขที่เอกสารถูกเปลี่ยน กรุณาลองใหม่"
- Monitoring:
  - Alert ถ้า lock acquisition failures > 5% ใน 5 นาที
  - Dashboard แสดง lock wait time percentiles
