260322:1648 Correct Coresspondence / Doing RFA / Correct CI
This commit is contained in:
@@ -1,25 +1,29 @@
|
||||
# 4. Access Control & RBAC Matrix (V1.8.0)
|
||||
|
||||
---
|
||||
|
||||
title: 'Access Control & RBAC Matrix'
|
||||
version: 1.8.0
|
||||
status: APPROVED
|
||||
owner: Nattanin Peancharoen / Development Team
|
||||
last_updated: 2026-02-23
|
||||
related:
|
||||
- specs/02-architecture/02-01-system-architecture.md
|
||||
- specs/03-implementation/03-02-backend-guidelines.md
|
||||
- specs/07-database/07-01-data-dictionary-v1.8.0.md
|
||||
- specs/05-decisions/ADR-005-redis-usage-strategy.md
|
||||
- specs/05-decisions/ADR-001-unified-workflow-engine.md
|
||||
references:
|
||||
- [RBAC Implementation](../../99-archives/ADR-004-rbac-implementation.md)
|
||||
- [Access Control](../../99-archives/01-04-access-control.md)
|
||||
|
||||
- specs/02-architecture/02-01-system-architecture.md
|
||||
- specs/03-implementation/03-02-backend-guidelines.md
|
||||
- specs/07-database/07-01-data-dictionary-v1.8.0.md
|
||||
- specs/05-decisions/ADR-005-redis-usage-strategy.md
|
||||
- specs/05-decisions/ADR-001-unified-workflow-engine.md
|
||||
references:
|
||||
- [RBAC Implementation](../../99-archives/ADR-004-rbac-implementation.md)
|
||||
- [Access Control](../../99-archives/01-04-access-control.md)
|
||||
|
||||
---
|
||||
|
||||
## 4.1. Overview and Problem Statement
|
||||
|
||||
LCBP3-DMS จัดการสิทธิ์การเข้าถึงข้อมูลที่ซับซ้อน ได้แก่:
|
||||
|
||||
- **Multi-Organization**: หลายองค์กรใช้ระบบร่วมกัน แต่ต้องแยกข้อมูลตามบริบท
|
||||
- **Project-Based**: โครงการสามารถมีหลายสัญญาย่อย (Contracts)
|
||||
- **Hierarchical Permissions**: สิทธิ์ระดับบนสามารถครอบคลุมระดับล่าง
|
||||
@@ -28,6 +32,7 @@ LCBP3-DMS จัดการสิทธิ์การเข้าถึงข
|
||||
Users และ Organizations สามารถเข้าดูหรือแก้ไขเอกสารได้จากสิทธิ์ที่ได้รับ ระบบออกแบบด้วย **4-Level Hierarchical Role-Based Access Control (RBAC)** ដើម្បីรองรับความซับซ้อนนี้.
|
||||
|
||||
### Key Requirements
|
||||
|
||||
1. User หนึ่งคนสามารถมีหลาย Roles ในหลาย Scopes
|
||||
2. Permission Inheritance (Global → Organization → Project → Contract)
|
||||
3. Fine-grained Access Control (เช่น "อนุญาตให้ดู Correspondence เฉพาะใน Project A รวมถึง Contract ภายใต้ Project A เท่านั้น")
|
||||
@@ -56,8 +61,9 @@ Global (ทั้งระบบ)
|
||||
```
|
||||
|
||||
**Permission Enforcement:**
|
||||
|
||||
- เมื่อตรวจสอบสิทธิ์ ระบบจะพิจารณาสิทธิ์จากทุก Level ที่ผู้ใช้มี และใช้สิทธิ์ที่ **"ครอบคลุมที่สุด (Most Permissive)"** ในบริบท (Context) นั้นมาเป็นเกณฑ์.
|
||||
- *Example*: User A เป็น `Viewer` ในองค์กร (ระดับ Organization Level) แต่มอบหมายหน้าที่ให้เป็น `Editor` ในตำแหน่งของ Project X. เมื่อ User A ดำเนินการในบริบท Context ของ Project X (หรือ Contract ที่อยู่ใต้ Project X), User A จะสามารถทำงานด้วยสิทธิ์ `Editor` ทันที.
|
||||
- _Example_: User A เป็น `Viewer` ในองค์กร (ระดับ Organization Level) แต่มอบหมายหน้าที่ให้เป็น `Editor` ในตำแหน่งของ Project X. เมื่อ User A ดำเนินการในบริบท Context ของ Project X (หรือ Contract ที่อยู่ใต้ Project X), User A จะสามารถทำงานด้วยสิทธิ์ `Editor` ทันที.
|
||||
|
||||
---
|
||||
|
||||
@@ -75,14 +81,14 @@ Global (ทั้งระบบ)
|
||||
|
||||
### Master Data Management Authority
|
||||
|
||||
| Master Data | Manager | Scope |
|
||||
| :-------------------------------------- | :------------------------------ | :------------------------------ |
|
||||
| Document Type (Correspondence, RFA) | **Superadmin** | Global |
|
||||
| Document Status (Draft, Approved, etc.) | **Superadmin** | Global |
|
||||
| Master Data | Manager | Scope |
|
||||
| :-------------------------------------- | :------------------------------ | :--------------------------------- |
|
||||
| Document Type (Correspondence, RFA) | **Superadmin** | Global |
|
||||
| Document Status (Draft, Approved, etc.) | **Superadmin** | Global |
|
||||
| Shop Drawing Category | **Project Manager** | Project (สร้างใหม่ได้ภายในโครงการ) |
|
||||
| Tags | **Org Admin / Project Manager** | Organization / Project |
|
||||
| Custom Roles | **Superadmin / Org Admin** | Global / Organization |
|
||||
| Document Numbering Formats | **Superadmin / Admin** | Global / Organization |
|
||||
| Tags | **Org Admin / Project Manager** | Organization / Project |
|
||||
| Custom Roles | **Superadmin / Org Admin** | Global / Organization |
|
||||
| Document Numbering Formats | **Superadmin / Admin** | Global / Organization |
|
||||
|
||||
---
|
||||
|
||||
@@ -272,13 +278,11 @@ Controller Example Usage:
|
||||
@Controller('correspondences')
|
||||
@UseGuards(JwtAuthGuard, PermissionGuard)
|
||||
export class CorrespondenceController {
|
||||
|
||||
@Post()
|
||||
@RequirePermission('correspondence.create')
|
||||
async create(@Body() dto: CreateCorrespondenceDto) {
|
||||
// Accessible only when CASL Evaluate "correspondence.create" successfully fits the parameters limits (Project/Contract scope check)
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
@@ -299,15 +303,21 @@ export class CorrespondenceController {
|
||||
ส่วนอ้างอิงและประวัติศาสตร์การตัดสินใจพิจารณาในอดีต (Reference) ก่อนการนำมาปรับใช้ร่าง Architecture ฉบับ V1.8.0.
|
||||
|
||||
### Considered Options Before Version 1.5.0
|
||||
|
||||
1. **Option 1**: Simple Role-Based (No Scope)
|
||||
- *Pros*: Very simple implementation, Easy to understand
|
||||
- *Cons*: ไม่รองรับ Multi-organization, Superadmin เห็นข้อมูลองค์กรอื่นมั่วข้ามกลุ่ม
|
||||
|
||||
- _Pros_: Very simple implementation, Easy to understand
|
||||
- _Cons_: ไม่รองรับ Multi-organization, Superadmin เห็นข้อมูลองค์กรอื่นมั่วข้ามกลุ่ม
|
||||
|
||||
2. **Option 2**: Organization-Only Scope
|
||||
- *Pros*: แยกข้อมูลระหว่าง Organizations ได้ชัดเจน
|
||||
- *Cons*: ไม่รองรับระดับ Sub-level Permissions (Project/Contract) ไม่เพียงพอกับ Business Rule.
|
||||
|
||||
- _Pros_: แยกข้อมูลระหว่าง Organizations ได้ชัดเจน
|
||||
- _Cons_: ไม่รองรับระดับ Sub-level Permissions (Project/Contract) ไม่เพียงพอกับ Business Rule.
|
||||
|
||||
3. **Option 3**: **4-Level Hierarchical RBAC (Selected)**
|
||||
- *Pros*: ครอบคลุม Use Case สูงสุด (Maximum Flexibility), รองรับ Hierarchy สืบทอดสิทธิ์ (Inheritance), ขอบเขตจำกัดข้อมูลอย่างรัดกุมระดับ Contract (Data Isolation).
|
||||
- *Cons*: Complexity ทางด้านการ Implement, Invalidate Caching หางานให้ฝั่ง Operations, Developer Learning Curve.
|
||||
|
||||
- _Pros_: ครอบคลุม Use Case สูงสุด (Maximum Flexibility), รองรับ Hierarchy สืบทอดสิทธิ์ (Inheritance), ขอบเขตจำกัดข้อมูลอย่างรัดกุมระดับ Contract (Data Isolation).
|
||||
- _Cons_: Complexity ทางด้านการ Implement, Invalidate Caching หางานให้ฝั่ง Operations, Developer Learning Curve.
|
||||
|
||||
**Decision Rationale:**
|
||||
เลือกแนวทางที่ 3 รองรับความต้องการของ Construction Projects ที่มีการแบ่งกลุ่มรับเหมาช่วงย่อยระดับ Contracts ต่อเนื่อง (Future proof). แก้ไขปัญหา Performance Cons ด้วยแนวคิดการประจุ Redis Caching ข้ามขั้ว และล้าง Invalidation เฉพาะเมื่อ Triggering Database Updates (อ้างอิงหัวข้อ 4.6).
|
||||
|
||||
@@ -1,26 +1,29 @@
|
||||
# 3.11 Document Numbering Management & Implementation (V1.8.0)
|
||||
|
||||
---
|
||||
|
||||
title: 'Specifications & Implementation Guide: Document Numbering System'
|
||||
version: 1.8.0
|
||||
status: draft
|
||||
owner: Nattanin Peancharoen / Development Team
|
||||
last_updated: 2026-02-23
|
||||
related:
|
||||
- specs/01-requirements/01-01-objectives.md
|
||||
- specs/02-architecture/README.md
|
||||
- specs/03-implementation/03-02-backend-guidelines.md
|
||||
- specs/04-operations/04-08-document-numbering-operations.md
|
||||
- specs/07-database/07-01-data-dictionary-v1.8.0.md
|
||||
- specs/05-decisions/ADR-002-document-numbering-strategy.md
|
||||
Clean Version v1.8.0 – Scope of Changes:
|
||||
- รวม Functional Requirements เข้ากับ Implementation Guide
|
||||
- เลือกใช้ Single Numbering System (Option A) `document_number_counters` เป็น Authoritative Counter
|
||||
- เพิ่ม Idempotency Key, Reservation (Two-Phase Commit)
|
||||
- Number State Machine, Pattern Validate UTF-8, Cancellation Rule (Void/Replace)
|
||||
references:
|
||||
- [Document Numbering](../../99-archives/01-03.11-document-numbering.md)
|
||||
- [Document Numbering](../../99-archives/03-04-document-numbering.md)
|
||||
|
||||
- specs/01-requirements/01-01-objectives.md
|
||||
- specs/02-architecture/README.md
|
||||
- specs/03-implementation/03-02-backend-guidelines.md
|
||||
- specs/04-operations/04-08-document-numbering-operations.md
|
||||
- specs/07-database/07-01-data-dictionary-v1.8.0.md
|
||||
- specs/05-decisions/ADR-002-document-numbering-strategy.md
|
||||
Clean Version v1.8.0 – Scope of Changes:
|
||||
- รวม Functional Requirements เข้ากับ Implementation Guide
|
||||
- เลือกใช้ Single Numbering System (Option A) `document_number_counters` เป็น Authoritative Counter
|
||||
- เพิ่ม Idempotency Key, Reservation (Two-Phase Commit)
|
||||
- Number State Machine, Pattern Validate UTF-8, Cancellation Rule (Void/Replace)
|
||||
references:
|
||||
- [Document Numbering](../../99-archives/01-03.11-document-numbering.md)
|
||||
- [Document Numbering](../../99-archives/03-04-document-numbering.md)
|
||||
|
||||
---
|
||||
|
||||
> **📖 เอกสารฉบับนี้เป็นการรวมรายละเอียดจาก `01-03.11-document-numbering.md` และ `03-04-document-numbering.md` ให้อยู่ในฉบับเดียวสำหรับใช้อ้างอิงการออกแบบเชิง Functional และการพัฒนา Technology Component**
|
||||
@@ -32,6 +35,7 @@ references:
|
||||
ระบบ Document Numbering สำหรับสร้างเลขที่เอกสารอัตโนมัติที่มีความเป็นเอกลักษณ์ (unique) และสามารถติดตามได้ (traceable) สำหรับเอกสารทุกประเภทในระบบ LCBP3-DMS
|
||||
|
||||
### 1.1 Requirements Summary & Scope
|
||||
|
||||
- **Auto-generation**: สร้างเลขที่อัตโนมัติ ไม่ซ้ำ (Unique) ยืดหยุ่น
|
||||
- **Configurable Templates**: รองรับแบบฟอร์มกำหนดค่า สำหรับโปรเจกต์ ประเภทเอกสาร ฯลฯ
|
||||
- **Uniqueness Guarantee**: การันตี Uniqueness ใน Concurrent Environment (Race Conditions)
|
||||
@@ -40,6 +44,7 @@ references:
|
||||
- **Audit Logging**: บันทึกเหตุการณ์ Operation ทั้งหมดอย่างละเอียดครบถ้วน 7 ปี
|
||||
|
||||
### 1.2 Technology Stack
|
||||
|
||||
| Component | Technology |
|
||||
| ----------------- | -------------------- |
|
||||
| Backend Framework | NestJS 10.x |
|
||||
@@ -50,7 +55,9 @@ references:
|
||||
| Monitoring | Prometheus + Grafana |
|
||||
|
||||
### 1.3 Architectural Decision (AD-DN-001)
|
||||
|
||||
ระบบเลือกใช้ **Option A**:
|
||||
|
||||
- `document_number_counters` เป็น Core / Authoritative Counter System.
|
||||
- `document_numbering_configs` (หรือ `document_number_formats`) ใช้เฉพาะกำหนดระเบียบเลข (Template format) และ Permission.
|
||||
- เหตุผล: ลดความซ้ำซ้อน, ป้องกัน Counter Mismatch, Debug ง่าย, Ops เคลียร์.
|
||||
@@ -62,30 +69,33 @@ references:
|
||||
### 2.1 Counter Logic & Reset Policy
|
||||
|
||||
การนับเลขจะแยกตาม **Counter Key** ที่ประกอบด้วยหลายส่วน ซึ่งขึ้นกับประเภทเอกสาร
|
||||
* `(project_id, originator_organization_id, recipient_organization_id, correspondence_type_id, sub_type_id, rfa_type_id, discipline_id, reset_scope)`
|
||||
|
||||
- `(project_id, originator_organization_id, recipient_organization_id, correspondence_type_id, sub_type_id, rfa_type_id, discipline_id, reset_scope)`
|
||||
|
||||
| Document Type | Reset Policy | Counter Key Format / Details |
|
||||
| ---------------------------------- | ------------------ | ------------------------------------------------------------------------------ |
|
||||
| Correspondence (LETTER, MEMO, RFI) | Yearly reset | `(project_id, originator, recipient, type_id, 0, 0, 0, 'YEAR_2025')` |
|
||||
| Transmittal | Yearly reset | `(project_id, originator, recipient, type_id, sub_type_id, 0, 0, 'YEAR_2025')` |
|
||||
| RFA | No reset | `(project_id, originator, 0, type_id, 0, rfa_type_id, discipline_id, 'NONE')` |
|
||||
| Drawing | Separate Namespace | `DRAWING::<project>::<contract>` (ไม่ได้ใช้ counter rules เดียวกัน) |
|
||||
| Drawing | Separate Namespace | `DRAWING::<project>::<contract>` (ไม่ได้ใช้ counter rules เดียวกัน) |
|
||||
|
||||
### 2.2 Format Templates & Supported Tokens
|
||||
|
||||
**Supported Token Types**:
|
||||
* `{PROJECT}`: รหัสโครงการ (เช่น `LCBP3`)
|
||||
* `{ORIGINATOR}`: รหัสองค์กรส่ง (เช่น `คคง.`)
|
||||
* `{RECIPIENT}`: รหัสองค์กรรับหลัก (เช่น `สคฉ.3`) *ไม่ใช้กับ RFA
|
||||
* `{CORR_TYPE}`: รหัสประเภทเอกสาร (เช่น `RFA`, `LETTER`)
|
||||
* `{SUB_TYPE}`: ประเภทย่อย (สำหรับ Transmittal)
|
||||
* `{RFA_TYPE}`: รหัสประเภท RFA (เช่น `SDW`, `RPT`)
|
||||
* `{DISCIPLINE}`: รหัสสาขาวิชา (เช่น `STR`, `CV`)
|
||||
* `{SEQ:n}`: Running Number ตามจำนวนหลัก `n` ลบด้วยศูนย์นำหน้า
|
||||
* `{YEAR:B.E.}`, `{YEAR:A.D.}`, `{YYYY}`, `{YY}`, `{MM}`: สัญลักษณ์บอกเวลาและปฏิทิน.
|
||||
* `{REV}`: Revision Code (เช่น `A`, `B`)
|
||||
|
||||
- `{PROJECT}`: รหัสโครงการ (เช่น `LCBP3`)
|
||||
- `{ORIGINATOR}`: รหัสองค์กรส่ง (เช่น `คคง.`)
|
||||
- `{RECIPIENT}`: รหัสองค์กรรับหลัก (เช่น `สคฉ.3`) \*ไม่ใช้กับ RFA
|
||||
- `{CORR_TYPE}`: รหัสประเภทเอกสาร (เช่น `RFA`, `LETTER`)
|
||||
- `{SUB_TYPE}`: ประเภทย่อย (สำหรับ Transmittal)
|
||||
- `{RFA_TYPE}`: รหัสประเภท RFA (เช่น `SDW`, `RPT`)
|
||||
- `{DISCIPLINE}`: รหัสสาขาวิชา (เช่น `STR`, `CV`)
|
||||
- `{SEQ:n}`: Running Number ตามจำนวนหลัก `n` ลบด้วยศูนย์นำหน้า
|
||||
- `{YEAR:B.E.}`, `{YEAR:A.D.}`, `{YYYY}`, `{YY}`, `{MM}`: สัญลักษณ์บอกเวลาและปฏิทิน.
|
||||
- `{REV}`: Revision Code (เช่น `A`, `B`)
|
||||
|
||||
**Token Validation Grammar**
|
||||
|
||||
```ebnf
|
||||
TEMPLATE := TOKEN ("-" TOKEN)*
|
||||
TOKEN := SIMPLE | PARAM
|
||||
@@ -95,11 +105,13 @@ DIGIT := "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
|
||||
```
|
||||
|
||||
### 2.3 Character & Format Rules (BR-DN-002, BR-DN-003)
|
||||
|
||||
- Document number **must be printable UTF‑8** (Thai, English, Numbers, `-`, `_`, `.`). ไม่อนุญาต Control characters, newlines.
|
||||
- ต้องยาวระหว่าง 10 ถึง 50 ตัวอักษร
|
||||
- ต้องกำหนด Token `{SEQ:n}` ลำดับที่ exactly once. ห้ามเป็น Unknown token ใดๆ.
|
||||
|
||||
### 2.4 Number State Machine & Idempotency
|
||||
|
||||
1. **States Lifecycle**: `RESERVED` (TTL 5 mins) → `CONFIRMED` → `VOID` / `CANCELLED`. Document ที่ Confirmed แล้วสามารถมีพฤติกรรม VOID ในอนาคตเพื่อแทนที่ด้วยเอกสารใหม่ได้ การ Request จะได้ Document ชุดใหม่ทดแทนต่อเนื่องทันที. ห้าม Reuse เลขเดิมโดยสิ้นเชิง.
|
||||
2. **Idempotency Key Support**: ทุก API ในการ Generator จำเป็นต้องระบุ HTTP Header `Idempotency-Key` ป้องกันระบบสร้างเลขเบิ้ล (Double Submission). ถ้าระบบได้รับคู่ Request + Key ชุดเดิม จะ Response เลขที่เอกสารเดิม.
|
||||
|
||||
@@ -107,22 +119,23 @@ DIGIT := "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
|
||||
|
||||
## 3. Functional Requirements
|
||||
|
||||
* **FR-DN-001 (Sequential Auto-generation)**: ระบบตอบกลับความรวดเร็วที่ระดับ < 100ms โดยที่ทน Concurrent ได้ ทนต่อปัญหา Duplicate
|
||||
* **FR-DN-002 (Configurable)**: สามารถเปลี่ยนรูปแบบเทมเพลตผ่านระบบ Admin ได้ด้วยการ Validation ก่อน حفظ
|
||||
* **FR-DN-003 (Scope-based sequences)**: รองรับ Scope แยกระดับเอกสาร
|
||||
* **FR-DN-004 (Manual Override)**: ระบบรองรับการตั้งเลขด้วยตนเองสำหรับ Admin Level พร้อมระบุเหตุผลผ่าน Audit Trails เป็นหลักฐานสำคัญ (Import Legacy, Correction)
|
||||
* **FR-DN-005 (Bulk Import)**: รับเข้าระบบจากไฟล์ Excel/CSV และแก้ไข Counters Sequence ต่อเนื่องพร้อมเช็ค Duplicates.
|
||||
* **FR-DN-006 (Skip Cancelled)**: ไม่ให้สิทธิ์ดึงเอกสารยกเลิกใช้งานซ้ำ. คงรักษาสภาพ Audit ต่อไป.
|
||||
* **FR-DN-007 (Void & Replace)**: เปลี่ยน Status เลขเป็น VOID ไม่มีการ Delete. Reference Link เอกสารใหม่ที่เกิดขึ้นทดแทนอิงตาม `voided_from_id`.
|
||||
* **FR-DN-008 (Race Condition Prevention)**: จัดการ Race Condition (RedLock + Database Pessimistic Locking) เพื่อ Guarantee zero duplicate numbers ที่ Load 1000 req/s.
|
||||
* **FR-DN-009 (Two-phase Commit)**: แบ่งการออกเลขเป็นช่วง Reserve 5 นาที แล้วค่อยเรียก Confirm หลังจากได้เอกสารที่ Submit เรียบร้อย (ลดอาการเลขหาย/เลขฟันหลอที่ยังไม่ถูกใช้).
|
||||
* **FR-DN-010/011 (Audit / Metrics Alerting)**: Audit ทุกๆ Step / Transaction ไว้ใน DB ให้เสิร์ชได้เกิน 7 ปี. ส่งแจ้งเตือนถ้า Sequence เริ่มเต็ม (เกิน 90%) หรือ Rate error เริ่มสูง.
|
||||
- **FR-DN-001 (Sequential Auto-generation)**: ระบบตอบกลับความรวดเร็วที่ระดับ < 100ms โดยที่ทน Concurrent ได้ ทนต่อปัญหา Duplicate
|
||||
- **FR-DN-002 (Configurable)**: สามารถเปลี่ยนรูปแบบเทมเพลตผ่านระบบ Admin ได้ด้วยการ Validation ก่อน حفظ
|
||||
- **FR-DN-003 (Scope-based sequences)**: รองรับ Scope แยกระดับเอกสาร
|
||||
- **FR-DN-004 (Manual Override)**: ระบบรองรับการตั้งเลขด้วยตนเองสำหรับ Admin Level พร้อมระบุเหตุผลผ่าน Audit Trails เป็นหลักฐานสำคัญ (Import Legacy, Correction)
|
||||
- **FR-DN-005 (Bulk Import)**: รับเข้าระบบจากไฟล์ Excel/CSV และแก้ไข Counters Sequence ต่อเนื่องพร้อมเช็ค Duplicates.
|
||||
- **FR-DN-006 (Skip Cancelled)**: ไม่ให้สิทธิ์ดึงเอกสารยกเลิกใช้งานซ้ำ. คงรักษาสภาพ Audit ต่อไป.
|
||||
- **FR-DN-007 (Void & Replace)**: เปลี่ยน Status เลขเป็น VOID ไม่มีการ Delete. Reference Link เอกสารใหม่ที่เกิดขึ้นทดแทนอิงตาม `voided_from_id`.
|
||||
- **FR-DN-008 (Race Condition Prevention)**: จัดการ Race Condition (RedLock + Database Pessimistic Locking) เพื่อ Guarantee zero duplicate numbers ที่ Load 1000 req/s.
|
||||
- **FR-DN-009 (Two-phase Commit)**: แบ่งการออกเลขเป็นช่วง Reserve 5 นาที แล้วค่อยเรียก Confirm หลังจากได้เอกสารที่ Submit เรียบร้อย (ลดอาการเลขหาย/เลขฟันหลอที่ยังไม่ถูกใช้).
|
||||
- **FR-DN-010/011 (Audit / Metrics Alerting)**: Audit ทุกๆ Step / Transaction ไว้ใน DB ให้เสิร์ชได้เกิน 7 ปี. ส่งแจ้งเตือนถ้า Sequence เริ่มเต็ม (เกิน 90%) หรือ Rate error เริ่มสูง.
|
||||
|
||||
---
|
||||
|
||||
## 4. Module System & Code Architecture
|
||||
|
||||
### 4.1 Folder Structure
|
||||
|
||||
```
|
||||
backend/src/modules/document-numbering/
|
||||
├── document-numbering.module.ts
|
||||
@@ -138,6 +151,7 @@ backend/src/modules/document-numbering/
|
||||
### 4.2 Sequence Process Architecture
|
||||
|
||||
**1. Number Generation Process Diagram**
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant C as Client
|
||||
@@ -166,6 +180,7 @@ sequenceDiagram
|
||||
```
|
||||
|
||||
**2. Two-Phase Commit Pattern (Reserve / Confirm)**
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant C as Client
|
||||
@@ -189,6 +204,7 @@ sequenceDiagram
|
||||
```
|
||||
|
||||
### 4.3 Lock Service (Redis Redlock Example)
|
||||
|
||||
```typescript
|
||||
@Injectable()
|
||||
export class DocumentNumberingLockService {
|
||||
@@ -204,6 +220,7 @@ export class DocumentNumberingLockService {
|
||||
```
|
||||
|
||||
### 4.4 Counter Service & Transaction Strategy (Optimistic Example)
|
||||
|
||||
```typescript
|
||||
async incrementCounter(counterKey: CounterKey): Promise<number> {
|
||||
const MAX_RETRIES = 2;
|
||||
@@ -231,6 +248,7 @@ async incrementCounter(counterKey: CounterKey): Promise<number> {
|
||||
## 5. Database Schema Details
|
||||
|
||||
### 5.1 Format Storage & Counters
|
||||
|
||||
```sql
|
||||
-- Format Template Configuration
|
||||
CREATE TABLE document_number_formats (
|
||||
@@ -261,6 +279,7 @@ CREATE TABLE document_number_counters (
|
||||
```
|
||||
|
||||
### 5.2 Two-Phase Commit Reservations
|
||||
|
||||
```sql
|
||||
CREATE TABLE document_number_reservations (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
@@ -274,6 +293,7 @@ CREATE TABLE document_number_reservations (
|
||||
```
|
||||
|
||||
### 5.3 Audit Trails & Error Logs
|
||||
|
||||
```sql
|
||||
CREATE TABLE document_number_audit (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
@@ -313,23 +333,26 @@ CREATE TABLE document_number_errors (
|
||||
## 7. Security, Error Handling & Concurrency Checklists
|
||||
|
||||
**Fallback Strategy for Database Lock Failures**:
|
||||
|
||||
1. System attempt to acquire `Redlock`.
|
||||
2. Redis Down? → **Fallback DB-only Lock** Transaction Layer.
|
||||
3. Redis Online but Timeout `>3 Times`? → Return HTTP 503 (Exponential Backoff).
|
||||
4. Save Failed via TypeORM Version Confilct? → Retry Loop `2 Times`, otherwise Return 409 Conflict.
|
||||
|
||||
**Rate Limiting Profiles**:
|
||||
* Single User Threshold: `10 requests/minute`.
|
||||
* Specific Request IP: `50 requests/minute`.
|
||||
|
||||
- Single User Threshold: `10 requests/minute`.
|
||||
- Specific Request IP: `50 requests/minute`.
|
||||
|
||||
**Authorization Policies**:
|
||||
* `Super Admin` เท่านั้นที่บังคับสั่ง `Reset Counter` ให้เริ่มนับศูนย์ได้เมื่อฉุกเฉิน.
|
||||
* กฎ Audit Log System ระบุชัดเจนว่าต้อง Retain Information ไม่ต่ำกว่า 7 ปี.
|
||||
|
||||
- `Super Admin` เท่านั้นที่บังคับสั่ง `Reset Counter` ให้เริ่มนับศูนย์ได้เมื่อฉุกเฉิน.
|
||||
- กฎ Audit Log System ระบุชัดเจนว่าต้อง Retain Information ไม่ต่ำกว่า 7 ปี.
|
||||
|
||||
## 8. Monitoring / Observability (Prometheus + Grafana)
|
||||
|
||||
| Condition Event | Prometheus Counter Target | Severity Reaction |
|
||||
| ---------------------- | -------------------------------- | ----------------------------------------------------------------- |
|
||||
| Condition Event | Prometheus Counter Target | Severity Reaction |
|
||||
| ---------------------- | -------------------------------- | ------------------------------------------------------------------ |
|
||||
| Utilization `>95%` | `numbering_sequence_utilization` | 🔴 **CRITICAL** (PagerDuty/Slack). Limit Maximum sequence reached. |
|
||||
| Redis Downtime `>1M` | Health System | 🔴 **CRITICAL** (PagerDuty/Slack) |
|
||||
| Lock Latency p95 `>1s` | `numbering_lock_wait_seconds` | 🟡 **WARNING** (Slack). Redis connection struggling. |
|
||||
@@ -340,11 +363,13 @@ CREATE TABLE document_number_errors (
|
||||
## 9. Testing & Rollout Migration Strategies
|
||||
|
||||
### 9.1 Test Approach Requirements
|
||||
* **Unit Tests**: Template Tokens Validations, Error handling retry, Optimistic locking checks.
|
||||
* **Concurrency Integration Test**: Assert >1000 requests without double generating numbers simultaneously per `project_id`.
|
||||
* **E2E Load Sequence Flow**: Mocking bulk API loads over 500 requests per seconds via CI/CD load pipeline.
|
||||
|
||||
- **Unit Tests**: Template Tokens Validations, Error handling retry, Optimistic locking checks.
|
||||
- **Concurrency Integration Test**: Assert >1000 requests without double generating numbers simultaneously per `project_id`.
|
||||
- **E2E Load Sequence Flow**: Mocking bulk API loads over 500 requests per seconds via CI/CD load pipeline.
|
||||
|
||||
### 9.2 Data Rollout Plan (Legacy Legacy Import)
|
||||
|
||||
1. Dump out existing Sequence numbers (Extracted Document Strings).
|
||||
2. Write validation script for Sequence Max Counts.
|
||||
3. Import to Table `document_number_counters` as Manual Override API Method context (`FR-DN-004`).
|
||||
@@ -353,6 +378,7 @@ CREATE TABLE document_number_errors (
|
||||
---
|
||||
|
||||
**Best Practices Checklist**
|
||||
|
||||
- ✅ **DO**: Two-Phase Commit (`Reserve` + `Confirm`) ให้เป็น Routine System Concept.
|
||||
- ✅ **DO**: DB Fallback เมื่อ Redis ดาวน์. ให้ Availability สูงสุด ไม่หยุดทำงาน.
|
||||
- ✅ **DO**: ข้ามเลขที่ยกเลิกทั้งหมดห้ามมีการ Re-Use เด็ดขาด ไม่ว่าเจตนาใดๆ.
|
||||
@@ -361,11 +387,11 @@ CREATE TABLE document_number_errors (
|
||||
- ❌ **DON'T**: ลืมเขียน Idempotency-Key สำหรับ Request.
|
||||
|
||||
---
|
||||
|
||||
**Document Version**: 1.8.0
|
||||
**Created By**: Development Team
|
||||
**End of Document**
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 10. Operations & Infrastructure Guidelines
|
||||
@@ -374,18 +400,18 @@ CREATE TABLE document_number_errors (
|
||||
|
||||
### 1.1. Response Time Targets
|
||||
|
||||
| Metric | Target | Measurement |
|
||||
| ---------------- | -------- | ------------------------ |
|
||||
| Metric | Target | Measurement |
|
||||
| ---------------- | ---------- | ---------------------------- |
|
||||
| 95th percentile | ≤ 2 วินาที | ตั้งแต่ request ถึง response |
|
||||
| 99th percentile | ≤ 5 วินาที | ตั้งแต่ request ถึง response |
|
||||
| Normal operation | ≤ 500ms | ไม่มี retry |
|
||||
| Normal operation | ≤ 500ms | ไม่มี retry |
|
||||
|
||||
### 1.2. Throughput Targets
|
||||
|
||||
| Load Level | Target | Notes |
|
||||
| -------------- | ----------- | ------------------------ |
|
||||
| Normal load | ≥ 50 req/s | ใช้งานปกติ |
|
||||
| Peak load | ≥ 100 req/s | ช่วงเร่งงาน |
|
||||
| Normal load | ≥ 50 req/s | ใช้งานปกติ |
|
||||
| Peak load | ≥ 100 req/s | ช่วงเร่งงาน |
|
||||
| Burst capacity | ≥ 200 req/s | Short duration (< 1 min) |
|
||||
|
||||
### 1.3. Availability SLA
|
||||
@@ -395,7 +421,6 @@ CREATE TABLE document_number_errors (
|
||||
- **Recovery Time Objective (RTO)**: ≤ 30 นาที
|
||||
- **Recovery Point Objective (RPO)**: ≤ 5 นาที
|
||||
|
||||
|
||||
### 2. Infrastructure Setup
|
||||
|
||||
### 2.1. Database Configuration
|
||||
@@ -567,12 +592,12 @@ services:
|
||||
- backend
|
||||
```
|
||||
|
||||
|
||||
### 4. Troubleshooting Runbooks
|
||||
|
||||
### 4.1. Scenario: Redis Unavailable
|
||||
|
||||
**Symptoms:**
|
||||
|
||||
- Alert: `RedisUnavailable`
|
||||
- System falls back to DB-only locking
|
||||
- Performance degraded 30-50%
|
||||
@@ -580,22 +605,26 @@ services:
|
||||
**Action Steps:**
|
||||
|
||||
1. **Check Redis status:**
|
||||
|
||||
```bash
|
||||
docker exec lcbp3-redis redis-cli ping
|
||||
# Expected: PONG
|
||||
```
|
||||
|
||||
2. **Check Redis logs:**
|
||||
|
||||
```bash
|
||||
docker logs lcbp3-redis --tail=100
|
||||
```
|
||||
|
||||
3. **Restart Redis (if needed):**
|
||||
|
||||
```bash
|
||||
docker restart lcbp3-redis
|
||||
```
|
||||
|
||||
4. **Verify failover (if using Sentinel):**
|
||||
|
||||
```bash
|
||||
docker exec lcbp3-redis-sentinel redis-cli -p 26379 SENTINEL masters
|
||||
```
|
||||
@@ -607,29 +636,34 @@ services:
|
||||
### 4.2. Scenario: High Lock Failure Rate
|
||||
|
||||
**Symptoms:**
|
||||
|
||||
- Alert: `HighLockFailureRate` (> 10%)
|
||||
- Users report "ระบบกำลังยุ่ง" errors
|
||||
|
||||
**Action Steps:**
|
||||
|
||||
1. **Check concurrent load:**
|
||||
|
||||
```bash
|
||||
# Check current request rate
|
||||
curl http://prometheus:9090/api/v1/query?query=rate(docnum_generation_duration_ms_count[1m])
|
||||
```
|
||||
|
||||
2. **Check database connections:**
|
||||
|
||||
```sql
|
||||
SHOW PROCESSLIST;
|
||||
-- Look for waiting/locked queries
|
||||
```
|
||||
|
||||
3. **Check Redis memory:**
|
||||
|
||||
```bash
|
||||
docker exec lcbp3-redis redis-cli INFO memory
|
||||
```
|
||||
|
||||
4. **Scale up if needed:**
|
||||
|
||||
```bash
|
||||
# Increase backend replicas
|
||||
docker-compose up -d --scale backend=5
|
||||
@@ -644,12 +678,14 @@ services:
|
||||
### 4.3. Scenario: Slow Performance
|
||||
|
||||
**Symptoms:**
|
||||
|
||||
- Alert: `SlowDocumentNumberGeneration`
|
||||
- P95 > 2 seconds
|
||||
|
||||
**Action Steps:**
|
||||
|
||||
1. **Check database query performance:**
|
||||
|
||||
```sql
|
||||
SELECT * FROM document_number_counters USE INDEX (idx_counter_lookup)
|
||||
WHERE project_id = 2 AND correspondence_type_id = 6 AND current_year = 2025;
|
||||
@@ -659,16 +695,19 @@ services:
|
||||
```
|
||||
|
||||
2. **Check for missing indexes:**
|
||||
|
||||
```sql
|
||||
SHOW INDEX FROM document_number_counters;
|
||||
```
|
||||
|
||||
3. **Check Redis latency:**
|
||||
|
||||
```bash
|
||||
docker exec lcbp3-redis redis-cli --latency
|
||||
```
|
||||
|
||||
4. **Check network latency:**
|
||||
|
||||
```bash
|
||||
ping mariadb-master
|
||||
ping redis-master
|
||||
@@ -682,12 +721,14 @@ services:
|
||||
### 4.4. Scenario: Version Conflicts
|
||||
|
||||
**Symptoms:**
|
||||
|
||||
- High retry count
|
||||
- Users report "เลขที่เอกสารถูกเปลี่ยน" errors
|
||||
|
||||
**Action Steps:**
|
||||
|
||||
1. **Check concurrent requests to same counter:**
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
project_id,
|
||||
@@ -701,6 +742,7 @@ services:
|
||||
```
|
||||
|
||||
2. **Investigate specific counter:**
|
||||
|
||||
```sql
|
||||
SELECT * FROM document_number_counters
|
||||
WHERE project_id = X AND correspondence_type_id = Y;
|
||||
@@ -720,7 +762,6 @@ services:
|
||||
- Increase retry count in application config
|
||||
- Consider manual counter adjustment (last resort)
|
||||
|
||||
|
||||
### 5. Maintenance Procedures
|
||||
|
||||
### 5.1. Counter Reset (Manual)
|
||||
@@ -730,6 +771,7 @@ services:
|
||||
**Steps:**
|
||||
|
||||
1. **Request approval via API:**
|
||||
|
||||
```bash
|
||||
POST /api/v1/document-numbering/configs/{configId}/reset-counter
|
||||
{
|
||||
@@ -757,6 +799,7 @@ services:
|
||||
4. Template changes do NOT affect existing documents
|
||||
|
||||
**API Call:**
|
||||
|
||||
```bash
|
||||
PUT /api/v1/document-numbering/configs/{configId}
|
||||
{
|
||||
@@ -768,6 +811,7 @@ PUT /api/v1/document-numbering/configs/{configId}
|
||||
### 5.3. Database Maintenance
|
||||
|
||||
**Weekly Tasks:**
|
||||
|
||||
- Check slow query log
|
||||
- Optimize tables if needed:
|
||||
```sql
|
||||
@@ -776,11 +820,10 @@ PUT /api/v1/document-numbering/configs/{configId}
|
||||
```
|
||||
|
||||
**Monthly Tasks:**
|
||||
|
||||
- Review and archive old audit logs (> 2 years)
|
||||
- Check index usage:
|
||||
```sql
|
||||
SELECT * FROM sys.schema_unused_indexes
|
||||
WHERE object_schema = 'lcbp3_db';
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -54,7 +54,6 @@ related:
|
||||
- มีการใช้ Caching กับข้อมูลที่เรียกใช้บ่อย และใช้ Pagination ในตารางข้อมูลเพื่อจัดการข้อมูลจำนวนมาก
|
||||
|
||||
- ตัวชี้วัดประสิทธิภาพ:
|
||||
|
||||
- **API Response Time:** < 200ms (90th percentile) สำหรับ operation ทั่วไป
|
||||
- **Search Query Performance:** < 500ms สำหรับการค้นหาขั้นสูง
|
||||
- **File Upload Performance:** < 30 seconds สำหรับไฟล์ขนาด 50MB
|
||||
@@ -64,7 +63,6 @@ related:
|
||||
- **Application Startup Time:** < 30 seconds
|
||||
|
||||
- Caching Strategy:
|
||||
|
||||
- **Master Data Cache:** Roles, Permissions, Organizations, Project metadata (TTL: 1 hour)
|
||||
- **User Session Cache:** User permissions และ profile data (TTL: 30 minutes)
|
||||
- **Search Result Cache:** Frequently searched queries (TTL: 15 minutes)
|
||||
|
||||
Reference in New Issue
Block a user