260324:1349 Refactor RFA #01
This commit is contained in:
@@ -3,22 +3,122 @@
|
||||
---
|
||||
|
||||
title: "Functional Requirements: Project Management"
|
||||
version: 1.8.0
|
||||
status: first-draft
|
||||
version: 1.8.1
|
||||
status: updated
|
||||
owner: Nattanin Peancharoen
|
||||
last_updated: 2026-02-23
|
||||
last_updated: 2026-03-24
|
||||
related:
|
||||
|
||||
- specs/01-requirements/01-01-objectives.md
|
||||
- specs/02-architecture/README.md
|
||||
- specs/01-requirements/01-03-modules/01-03-00-index.md
|
||||
- specs/03-Data-and-Storage/03-01-data-dictionary.md
|
||||
- specs/01-requirements/01-02-business-rules/01-02-01-rbac-matrix.md
|
||||
|
||||
---
|
||||
|
||||
## Details (รายละเอียด)
|
||||
## 3.1.1. วัตถุประสงค์
|
||||
|
||||
- 3.1.1. โครงการ (Projects): ระบบต้องสามารถจัดการเอกสารภายในหลายโครงการได้ (ปัจจุบันมี 4 โครงการ และจะเพิ่มขึ้นในอนาคต)
|
||||
- 3.1.2. สัญญา (Contracts): ระบบต้องสามารถจัดการเอกสารภายในแต่ละสัญญาได้ ในแต่ละโครงการ มีได้หลายสัญญา หรืออย่างน้อย 1 สัญญา
|
||||
- 3.1.3. องค์กร (Organizations):
|
||||
- มีหลายองค์กรในโครงการ องค์กรณ์ที่เป็น Owner, Designer และ Consultant สามารถอยู่ในหลายโครงการและหลายสัญญาได้
|
||||
- Contractor จะถือ 1 สัญญา และอยู่ใน 1 โครงการเท่านั้น
|
||||
จัดการโครงสร้างหลักของระบบ ได้แก่ **Project → Contract → Organization → Discipline** — ทุกเอกสารในระบบผูกอยู่กับ Project และ/หรือ Contract เสมอ
|
||||
|
||||
---
|
||||
|
||||
## 3.1.2. โครงสร้างข้อมูล (Database Tables)
|
||||
|
||||
| Table | บทบาท |
|
||||
|---|---|
|
||||
| `projects` | ข้อมูล Master โครงการ: code, name, is_active |
|
||||
| `contracts` | สัญญา ผูกกับ Project (N:1) |
|
||||
| `organizations` | ข้อมูล Master องค์กร: code, name, role |
|
||||
| `organization_roles` | Master: ประเภทองค์กร (OWNER/DESIGNER/ฯลฯ) |
|
||||
| `project_organizations` | M:N: Project ↔ Organization |
|
||||
| `contract_organizations` | M:N: Contract ↔ Organization + role_in_contract |
|
||||
| `disciplines` | สาขางาน ผูกกับ Contract (N:1) |
|
||||
|
||||
### Hierarchy
|
||||
|
||||
```
|
||||
Project (1)
|
||||
└── Contract (N)
|
||||
├── Organization (M:N via contract_organizations)
|
||||
└── Discipline (N)
|
||||
|
||||
Project ↔ Organization (M:N via project_organizations)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3.1.3. Projects
|
||||
|
||||
| Field | Type | หมายเหตุ |
|
||||
|---|---|---|
|
||||
| `project_code` | VARCHAR(50) UNIQUE | รหัสโครงการ |
|
||||
| `project_name` | VARCHAR(255) | ชื่อโครงการ |
|
||||
| `is_active` | TINYINT(1) | 1 = Active |
|
||||
|
||||
- ปัจจุบันมี **4 โครงการ** — รองรับการเพิ่มในอนาคต
|
||||
- จัดการโดย Superadmin เท่านั้น
|
||||
|
||||
---
|
||||
|
||||
## 3.1.4. Contracts
|
||||
|
||||
| Field | Type | หมายเหตุ |
|
||||
|---|---|---|
|
||||
| `project_id` | INT FK | ผูกกับ Project |
|
||||
| `contract_code` | VARCHAR(50) UNIQUE | รหัสสัญญา |
|
||||
| `contract_name` | VARCHAR(255) | ชื่อสัญญา |
|
||||
| `start_date` / `end_date` | DATE | ระยะเวลาสัญญา |
|
||||
| `is_active` | BOOLEAN | สถานะ |
|
||||
|
||||
- 1 Project มีได้หลาย Contract (≥ 1)
|
||||
- Document Number ผูกกับ Contract (ไม่ใช่ Project)
|
||||
|
||||
---
|
||||
|
||||
## 3.1.5. Organizations และ Organization Roles
|
||||
|
||||
### Organization Roles (organization_roles)
|
||||
|
||||
| role_name | ความหมาย | สามารถอยู่ใน |
|
||||
|---|---|---|
|
||||
| `OWNER` | เจ้าของโครงการ | หลาย Project / หลาย Contract |
|
||||
| `DESIGNER` | ผู้ออกแบบ | หลาย Project / หลาย Contract |
|
||||
| `CONSULTANT` | ที่ปรึกษา | หลาย Project / หลาย Contract |
|
||||
| `CONTRACTOR` | ผู้รับเหมา | **1 Contract / 1 Project เท่านั้น** |
|
||||
| `THIRD PARTY` | บุคคลที่สาม | หลาย Project / หลาย Contract |
|
||||
|
||||
### project_organizations (M:N)
|
||||
- ผูก Organization เข้า Project — ไม่มี role_in_contract ระดับ Project
|
||||
|
||||
### contract_organizations (M:N)
|
||||
- ผูก Organization เข้า Contract พร้อม `role_in_contract` (Owner/Designer/Consultant/Contractor)
|
||||
- 1 Organization สามารถมีหลาย role ใน Contract เดียวกันได้
|
||||
|
||||
---
|
||||
|
||||
## 3.1.6. Disciplines (สาขางาน)
|
||||
|
||||
Discipline ผูกกับ **Contract** (ไม่ใช่ Project):
|
||||
|
||||
| Field | หมายเหตุ |
|
||||
|---|---|
|
||||
| `contract_id` | FK → contracts |
|
||||
| `discipline_code` | VARCHAR(10) เช่น GEN, STR, MEP |
|
||||
| `code_name_th` / `code_name_en` | ชื่อภาษาไทย/อังกฤษ |
|
||||
| `is_active` | สถานะ |
|
||||
|
||||
- UNIQUE KEY `(contract_id, discipline_code)` — code ซ้ำได้ระหว่าง Contract
|
||||
- ใช้กรอง RFA Type และ Correspondence ต่อ Contract
|
||||
|
||||
---
|
||||
|
||||
## 3.1.7. การสร้างและสิทธิ์ (RBAC)
|
||||
|
||||
| การกระทำ | Role ที่อนุญาต | Scope |
|
||||
|---|---|---|
|
||||
| สร้าง / แก้ไข Project | Superadmin | Global |
|
||||
| สร้าง / แก้ไข Contract | Superadmin, Org Admin | Project |
|
||||
| สร้าง / แก้ไข Organization | Superadmin | Global |
|
||||
| เพิ่ม Organization เข้า Project/Contract | Superadmin | Global |
|
||||
| จัดการ Disciplines | Superadmin, Org Admin | Contract |
|
||||
| ดู Project / Contract | ทุกคนที่มีสิทธิ์ใน Project | Project |
|
||||
|
||||
@@ -3,37 +3,168 @@
|
||||
---
|
||||
|
||||
title: 'Functional Requirements: Correspondence Management'
|
||||
version: 1.8.0
|
||||
status: first-draft
|
||||
version: 1.8.1
|
||||
status: updated
|
||||
owner: Nattanin Peancharoen
|
||||
last_updated: 2026-02-23
|
||||
last_updated: 2026-03-24
|
||||
related:
|
||||
|
||||
- specs/01-requirements/01-01-objectives.md
|
||||
- specs/02-architecture/README.md
|
||||
- specs/01-requirements/01-03-modules/01-03-00-index.md
|
||||
- specs/01-requirements/01-03-modules/01-03-06-unified-workflow.md
|
||||
- specs/01-requirements/01-03-modules/01-03-08-circulation-sheet.md
|
||||
- specs/01-requirements/01-06-edge-cases-and-rules.md (EC-CORR-001 ถึง EC-CORR-003)
|
||||
- specs/03-Data-and-Storage/03-01-data-dictionary.md
|
||||
- specs/01-requirements/01-02-business-rules/01-02-01-rbac-matrix.md
|
||||
|
||||
---
|
||||
|
||||
## 3.2.1. วัตถุประสงค์:
|
||||
## 3.2.1. วัตถุประสงค์
|
||||
|
||||
- เอกสารโต้ตอบ (Correspondences) ระหว่างองค์กรณ์-องค์กรณ์ ภายใน โครงการ (Projects) และระหว่าง องค์กรณ์-องค์กรณ์ ภายนอก โครงการ (Projects), รองรับ To (ผู้รับหลัก) และ CC (ผู้รับสำเนา) หลายองค์กรณ์
|
||||
เอกสารโต้ตอบ (Correspondence) คือ **โครงสร้างข้อมูลหลัก (Parent)** ของเอกสารทุกประเภทในระบบ — ทั้ง RFA, RFI, Transmittal, Letter ฯลฯ เป็นการสื่อสารระหว่างองค์กร-องค์กร ภายในโครงการ (Project) รองรับผู้รับหลัก (TO) และผู้รับสำเนา (CC) ได้หลายองค์กร
|
||||
|
||||
## 3.2.2. ประเภทเอกสาร:
|
||||
---
|
||||
|
||||
- ระบบต้องรองรับเอกสารรูปแบบ ไฟล์ PDF, ZIP
|
||||
- เอกสารโต้ตอบ (Correspondence) สามารถมีได้หลายประเภท (Types) เช่น จดหมาย (Letter), อีเมล์ (Email), Request for Information (RFI), รวมถึง เอกสารขออนุมัติ (RFA) แต่ละ revision และสามารถเพิ่มประเภทใหม่ได้ในภายหลัง
|
||||
## 3.2.2. โครงสร้างข้อมูล (Database Tables)
|
||||
|
||||
## 3.2.3. การสร้างเอกสาร (Correspondence):
|
||||
| Table | บทบาท |
|
||||
|---|---|
|
||||
| `correspondences` | ข้อมูล Master: เลขเอกสาร, type, project, originator — ไม่เปลี่ยนตาม revision |
|
||||
| `correspondence_revisions` | ประวัติแต่ละ Revision: subject, body, status, due_date |
|
||||
| `correspondence_recipients` | ผู้รับ TO/CC (M:N กับ organizations) |
|
||||
| `correspondence_references` | การอ้างอิงข้ามเอกสาร (M:N) |
|
||||
| `correspondence_tags` | Tags ที่ติดกับเอกสาร (M:N) |
|
||||
| `correspondence_attachments` | ไฟล์แนบ (M:N กับ attachments) |
|
||||
| `correspondence_types` | Master: ประเภทเอกสาร (Global) |
|
||||
| `correspondence_status` | Master: สถานะเอกสาร (Global) |
|
||||
|
||||
- ผู้ใช้ที่มีสิทธิ์ (เช่น Document Control) สามารถสร้างเอกสารรอไว้ในสถานะ ฉบับร่าง" (Draft) ได้ ซึ่งผู้ใช้งานต่างองค์กรจะมองไม่เห็น
|
||||
- เมื่อเอกสารเปลี่ยนสถานะเป็น "Submitted" แล้ว การแก้ไข, ถอนเอกสารกลับไปสถานะ Draft, หรือยกเลิก (Cancel) จะต้องทำโดยผู้ใช้ระดับ Admin ขึ้นไป พร้อมระบุเหตุผล
|
||||
**ข้อสำคัญ:** `correspondence_number` ต้อง UNIQUE ภายใน Project เดียวกัน (`uq_corr_no_per_project`)
|
||||
|
||||
## 3.2.4. การอ้างอิงและจัดกลุ่ม:
|
||||
---
|
||||
|
||||
- เอกสารสามารถอ้างถึง (Reference) เอกสารฉบับก่อนหน้าได้หลายฉบับ
|
||||
- สามารถกำหนด Tag ได้หลาย Tag เพื่อจัดกลุ่มและใช้ในการค้นหาขั้นสูง
|
||||
## 3.2.3. ประเภทเอกสาร (correspondence_types)
|
||||
|
||||
## 3.2.5. Workflow (Unified Workflow):
|
||||
ประเภทเป็น Global Master — จัดการโดย Superadmin เท่านั้น:
|
||||
|
||||
- ระบบต้องรองรับ Workflow ที่เป็นแบบ Unified Workflow
|
||||
| type_code | ชื่อ | มี Extension Table |
|
||||
|---|---|---|
|
||||
| `RFA` | Request for Approval | ✅ `rfas` + `rfa_revisions` |
|
||||
| `RFI` | Request for Information | ❌ (ใช้ `details` JSON) |
|
||||
| `TRANSMITTAL` | Transmittal | ❌ (ใช้ `details` JSON) |
|
||||
| `EMAIL` | Email | ❌ |
|
||||
| `INSTRUCTION` | Instruction | ❌ |
|
||||
| `LETTER` | Letter | ❌ |
|
||||
| `MEMO` | Memorandum | ❌ |
|
||||
| `MOM` | Minutes of Meeting | ❌ |
|
||||
| `NOTICE` | Notice | ❌ |
|
||||
| `OTHER` | Other | ❌ |
|
||||
|
||||
ไฟล์แนบรองรับ **PDF, ZIP**
|
||||
|
||||
---
|
||||
|
||||
## 3.2.4. Fields ที่ต้องกรอกเมื่อสร้าง Correspondence
|
||||
|
||||
| Field | Required | หมายเหตุ |
|
||||
|---|---|---|
|
||||
| Project | ✅ | UUID |
|
||||
| Correspondence Type | ✅ | INT id (Global) |
|
||||
| Subject | ✅ | ขั้นต่ำ 5 ตัวอักษร — เก็บใน `correspondence_revisions` |
|
||||
| To Organization | ✅ | UUID — `recipient_type = 'TO'` (≥ 1) |
|
||||
| CC Organizations | ❌ | UUID[] — `recipient_type = 'CC'` |
|
||||
| Discipline | ❌ | INT — กรองตาม Contract |
|
||||
| Body | ❌ | เนื้อหา — เก็บใน `correspondence_revisions` |
|
||||
| Description | ❌ | คำอธิบาย Revision |
|
||||
| Remarks | ❌ | หมายเหตุ |
|
||||
| Document Date | ❌ | วันที่ในเอกสาร |
|
||||
| Due Date | ❌ | กำหนดส่งคืน |
|
||||
| Tags | ❌ | UUID[] — จัดกลุ่มเพื่อค้นหาขั้นสูง |
|
||||
| References | ❌ | UUID[] — อ้างอิงเอกสารฉบับก่อนหน้า |
|
||||
| Attachments | ❌ | PDF/ZIP — ผ่าน ClamAV scan |
|
||||
| Is Internal | ❌ | `is_internal_communication = 1` → ใช้ Circulation แทน |
|
||||
|
||||
### Document Number Preview
|
||||
|
||||
ระบบแสดง Preview เลขเอกสารแบบ Real-time ก่อน Submit เมื่อกรอกครบ: Project + Type + Discipline + To Organization โดยเรียก `POST /api/correspondences/preview-number`
|
||||
|
||||
---
|
||||
|
||||
## 3.2.5. การสร้างและสิทธิ์ (RBAC)
|
||||
|
||||
| การกระทำ | Role ที่อนุญาต | หมายเหตุ |
|
||||
|---|---|---|
|
||||
| สร้าง Correspondence (Draft) | Document Control, Org Admin, Superadmin | ภายในองค์กรตัวเอง |
|
||||
| Submit Correspondence | Document Control, Org Admin, Superadmin | เปลี่ยนสถานะ DRAFT → SUB* |
|
||||
| แก้ไข/ถอนกลับ/ยกเลิก หลัง Submit | **Org Admin ขึ้นไปเท่านั้น** พร้อมระบุเหตุผล | — |
|
||||
| ดู Correspondence ที่ Draft | เฉพาะคนในองค์กรเดียวกัน | องค์กรอื่นมองไม่เห็น |
|
||||
| ดู Correspondence ที่ Submitted แล้ว | ทุกคนที่มีสิทธิ์ใน Project | รวม TO และ CC org |
|
||||
| จัดการ Correspondence Types (Master) | Superadmin | Global |
|
||||
|
||||
---
|
||||
|
||||
## 3.2.6. Status Codes (correspondence_status)
|
||||
|
||||
สถานะแบ่งตามหมวดและ Actor:
|
||||
|
||||
| หมวด | status_code | ชื่อ |
|
||||
|---|---|---|
|
||||
| **Draft** | `DRAFT` | Draft — มองเห็นเฉพาะ Originator Org |
|
||||
| **Submitted** | `SUBOWN` | Submitted to Owner |
|
||||
| | `SUBDSN` | Submitted to Designer |
|
||||
| | `SUBCSC` | Submitted to CSC |
|
||||
| | `SUBCON` | Submitted to Contractor |
|
||||
| | `SUBOTH` | Submitted to Others |
|
||||
| **Reply** | `REPOWN` | Reply by Owner |
|
||||
| | `REPDSN` | Reply by Designer |
|
||||
| | `REPCSC` | Reply by CSC |
|
||||
| | `REPCON` | Reply by Contractor |
|
||||
| | `REPOTH` | Reply by Others |
|
||||
| **Resubmitted** | `RSBOWN` | Resubmitted by Owner |
|
||||
| | `RSBDSN` | Resubmitted by Designer |
|
||||
| | `RSBCSC` | Resubmitted by CSC |
|
||||
| | `RSBCON` | Resubmitted by Contractor |
|
||||
| **Closed** | `CLBOWN` | Closed by Owner |
|
||||
| | `CLBDSN` | Closed by Designer |
|
||||
| | `CLBCSC` | Closed by CSC |
|
||||
| | `CLBCON` | Closed by Contractor |
|
||||
| **Canceled** | `CCBOWN` | Canceled by Owner |
|
||||
| | `CCBDSN` | Canceled by Designer |
|
||||
| | `CCBCSC` | Canceled by CSC |
|
||||
| | `CCBCON` | Canceled by Contractor |
|
||||
|
||||
---
|
||||
|
||||
## 3.2.7. การอ้างอิงและ Tags
|
||||
|
||||
- **References** (`correspondence_references`): M:N — เอกสารหนึ่งอ้างถึงได้หลายฉบับ ทิศทางเดียว (src → tgt)
|
||||
- **Tags** (`correspondence_tags` + `tags`): M:N — Tag ผูกกับ Project หรือ Global (project_id = NULL)
|
||||
- ทั้งสองอย่างใช้ค้นหาขั้นสูงใน Elasticsearch Index
|
||||
|
||||
---
|
||||
|
||||
## 3.2.8. Revision Model
|
||||
|
||||
- 1 Correspondence Master → หลาย Revision (1:N)
|
||||
- `is_current = TRUE` มีได้เพียง 1 แถวต่อ correspondence (UNIQUE constraint)
|
||||
- `revision_label`: A, B, C, ... (หรือ 1.1, 1.2 แล้วแต่ type)
|
||||
- `revision_number`: 0-based integer สำหรับ sorting
|
||||
|
||||
---
|
||||
|
||||
## 3.2.9. Workflow (Unified Workflow)
|
||||
|
||||
Correspondence ใช้ Unified Workflow Engine — ดูรายละเอียดที่ `01-03-06-unified-workflow.md`
|
||||
|
||||
เมื่อ Correspondence ถูก Submit → ผู้รับ (TO/CC) สามารถสร้าง **Circulation Sheet** เพื่อมอบหมายงานภายในองค์กร (ดู `01-03-08-circulation-sheet.md`)
|
||||
|
||||
---
|
||||
|
||||
## 3.2.10. Business Rules และ Edge Cases
|
||||
|
||||
| รหัส | กฎ | Severity |
|
||||
|---|---|---|
|
||||
| **EC-CORR-001** | Cancel Correspondence ที่มี Circulation เปิดอยู่ → ต้องยืนยันก่อน + Force Close Circulation ทั้งหมด + Audit Log | 🔴 Critical |
|
||||
| **EC-CORR-002** | Reply ต่อ Correspondence ที่ถูก Cancel → ทำได้แต่ UI ต้องแสดง Warning | 🟡 Medium |
|
||||
| **EC-CORR-003** | Originator และ Recipient เป็นองค์กรเดียวกัน → Block (ใช้ Circulation แทน) | 🟡 Medium |
|
||||
|
||||
ดูรายละเอียดครบที่ `01-06-edge-cases-and-rules.md` หมวด "Module 7: Correspondence Edge Cases"
|
||||
|
||||
@@ -1,44 +1,166 @@
|
||||
# 3.3 RFA Management (การจัดการเอกสาขออนุมัติ)
|
||||
# 3.3 RFA Management (การจัดการเอกสารขออนุมัติ)
|
||||
|
||||
---
|
||||
|
||||
title: 'Functional Requirements: RFA Management'
|
||||
version: 1.8.0
|
||||
status: first-draft
|
||||
version: 1.8.1
|
||||
status: updated
|
||||
owner: Nattanin Peancharoen
|
||||
last_updated: 2026-02-23
|
||||
last_updated: 2026-03-24
|
||||
related:
|
||||
|
||||
- specs/01-requirements/01-01-objectives.md
|
||||
- specs/02-architecture/README.md
|
||||
- specs/01-requirements/01-03-modules/01-03-00-index.md
|
||||
- specs/01-requirements/01-03-modules/01-03-02-correspondence.md
|
||||
- specs/01-requirements/01-03-modules/01-03-06-unified-workflow.md
|
||||
- specs/01-requirements/01-06-edge-cases-and-rules.md (EC-RFA-001 ถึง EC-RFA-004)
|
||||
- specs/03-Data-and-Storage/03-01-data-dictionary.md (§4.1–4.6)
|
||||
- specs/01-requirements/01-02-business-rules/01-02-01-rbac-matrix.md
|
||||
|
||||
---
|
||||
|
||||
## 3.3.1. วัตถุประสงค์:
|
||||
## 3.3.1. วัตถุประสงค์
|
||||
|
||||
- เอกสารขออนุมัติ (RFA) ภายใน โครงการ (Projects)
|
||||
เอกสารขออนุมัติ (RFA — Request For Approval) ใช้สำหรับส่งเอกสารหรือสิ่งของเพื่อขออนุมัติจากผู้ว่าจ้างหรือที่ปรึกษา ภายในโครงการ (Project) — **ไม่ได้จำกัดแค่แบบก่อสร้าง** ประเภทของ RFA (RFA Type) เป็นตัวกำหนดว่าต้องแนบ Drawing Revision หรือไฟล์แนบ:
|
||||
|
||||
## 3.3.2. ประเภทเอกสาร:
|
||||
- **ประเภทที่อ้างอิง Drawing** (DDW, SDW, ADW): ผูก Drawing Revision ได้หลายรายการผ่าน `rfa_items`
|
||||
- **ประเภทอื่น** (DOC, MAT, ฯลฯ): แนบได้เพียง 1 ไฟล์ผ่าน `correspondence_attachments`
|
||||
|
||||
- ระบบต้องรองรับเอกสารรูปแบบ ไฟล์ PDF
|
||||
- เอกสารขออนุมัติ (RFA) สามารถมีได้หลาย revision
|
||||
- มีประถทของเอกสาร ได้หลายประเภท (RFA Types) และสามารถเพิ่มประเภทใหม่ได้ในภายหลัง
|
||||
---
|
||||
|
||||
## 3.3.3. การสร้างเอกสาร:
|
||||
## 3.3.2. โครงสร้างข้อมูล (Database Tables)
|
||||
|
||||
- ผู้ใช้ที่มีสิทธิ์ (เช่น Document Control) สามารถสร้างเอกสารขออนุมัติ (RFA) รอไว้ในสถานะ ฉบับร่าง" (Draft) ได้ ซึ่งผู้ใช้งานต่างองค์กรจะมองไม่เห็น
|
||||
- เมื่อเอกสารเปลี่ยนสถานะเป็น "Submitted" แล้ว การแก้ไข, ถอนเอกสารกลับไปสถานะ Draft, หรือยกเลิก (Cancel) จะต้องทำโดยผู้ใช้ระดับ Admin ขึ้นไป พร้อมระบุเหตุผล
|
||||
RFA ใช้ pattern **Correspondence + Extension**:
|
||||
|
||||
## 3.3.4. การอ้างอิงและจัดกลุ่ม:
|
||||
| Table | บทบาท |
|
||||
|---|---|
|
||||
| `correspondences` | ข้อมูลหลัก: เลขเอกสาร, subject, project, originator, recipients |
|
||||
| `rfas` | ข้อมูลเฉพาะ RFA: `rfa_type_id` (FK → `rfa_types`) |
|
||||
| `rfa_revisions` | ประวัติแต่ละ Revision: status, approve code, details JSON |
|
||||
| `rfa_items` | รายการ Drawing Revision ที่อ้างอิงใน Revision นั้น (เฉพาะ type DDW/SDW/ADW) |
|
||||
| `rfa_types` | Master: ประเภท RFA (ผูกกับ Contract) |
|
||||
| `rfa_status_codes` | Master: สถานะ RFA |
|
||||
| `rfa_approve_codes` | Master: ผลการอนุมัติ |
|
||||
|
||||
- RFA สามารถอ้างถึง (Reference) แบบก่อสร้าง (Shop Drawing) ได้หลายฉบับ
|
||||
- การสร้าง RFA ต้องสร้างเอกสารแม่ใน `correspondences` โดยใช้ `correspondence_types.type_code = 'RFA'`
|
||||
- ประเภทย่อยของ RFA ต้องเก็บใน `rfas.rfa_type_id`
|
||||
- ถ้า `rfa_types.type_code` เป็น `DDW` หรือ `SDW` ระบบต้องบังคับให้เลือกอย่างน้อย 1 `shop_drawing_revision`
|
||||
- ถ้า `rfa_types.type_code` เป็น `ADW` ระบบต้องบังคับให้เลือกอย่างน้อย 1 `asbuilt_drawing_revision`
|
||||
- 1 แถวใน `rfa_items` ต้องอ้างอิง Drawing Revision ได้เพียง 1 รายการเท่านั้น โดยเป็น `shop_drawing_revision` หรือ `asbuilt_drawing_revision` อย่างใดอย่างหนึ่ง
|
||||
**ข้อสำคัญ:** `rfas.id` ใช้ FK ชี้ไปที่ `correspondences.id` (ไม่มี AUTO_INCREMENT ของตัวเอง)
|
||||
|
||||
## 3.3.5. Workflow (Unified Workflow):
|
||||
---
|
||||
|
||||
- ระบบต้องรองรับ Workflow ที่เป็นแบบ Unified Workflow
|
||||
## 3.3.3. ประเภทเอกสาร (RFA Types)
|
||||
|
||||
- `rfa_types` เป็น Master ที่ผูกกับ **Contract** (ไม่ใช่ Project) — `contract_id` FK
|
||||
- แต่ละ Contract มี RFA Types ของตัวเอง สามารถเพิ่มใหม่ได้ในภายหลัง
|
||||
- ไฟล์แนบรองรับรูปแบบ **PDF**
|
||||
- RFA สามารถมีได้หลาย Revision (Rev.A, Rev.B, ...)
|
||||
|
||||
### type_code ที่กำหนด drawing requirement:
|
||||
|
||||
| type_code | ชื่อ | Attachment Mechanism | บังคับ |
|
||||
|---|---|---|---|
|
||||
| `DDW` | Drawing for Design | `rfa_items` → Shop Drawing Revision | ≥ 1 |
|
||||
| `SDW` | Shop Drawing | `rfa_items` → Shop Drawing Revision | ≥ 1 |
|
||||
| `ADW` | As-Built Drawing | `rfa_items` → As-Built Drawing Revision | ≥ 1 |
|
||||
| อื่นๆ | เช่น DOC, MAT | `correspondence_attachments` (1 ไฟล์) | ไม่บังคับ |
|
||||
|
||||
---
|
||||
|
||||
## 3.3.4. Fields ที่ต้องกรอกเมื่อสร้าง RFA
|
||||
|
||||
| Field | Required | หมายเหตุ |
|
||||
|---|---|---|
|
||||
| Project | ✅ | UUID — กรองจาก Project ที่ผู้ใช้มีสิทธิ์ |
|
||||
| Contract | ✅ | UUID — filter ตาม Project ที่เลือก |
|
||||
| Discipline | ✅ | INT id — filter ตาม Contract ที่เลือก |
|
||||
| RFA Type | ✅ | INT id — filter ตาม Contract ที่เลือก |
|
||||
| To Organization | ✅ | UUID — ผู้รับหลัก (recipients type = 'TO') |
|
||||
| Subject | ✅ | ขั้นต่ำ 5 ตัวอักษร |
|
||||
| Body | ❌ | เนื้อหาเพิ่มเติม |
|
||||
| Description | ❌ | คำอธิบายสั้น |
|
||||
| Remarks | ❌ | หมายเหตุ |
|
||||
| Due Date | ❌ | กำหนดส่งคืน |
|
||||
| Shop Drawing Revisions | บังคับเมื่อ type = DDW/SDW | UUID[] |
|
||||
| As-Built Drawing Revisions | บังคับเมื่อ type = ADW | UUID[] |
|
||||
|
||||
### Document Number Preview
|
||||
|
||||
ระบบแสดง Preview เลขเอกสารแบบ Real-time ก่อน Submit เมื่อกรอกครบ: Project + Correspondence Type + Discipline + To Organization โดยเรียก `POST /api/correspondences/preview-number`
|
||||
|
||||
---
|
||||
|
||||
## 3.3.5. การสร้างและสิทธิ์ (RBAC)
|
||||
|
||||
| การกระทำ | Role ที่อนุญาต | หมายเหตุ |
|
||||
|---|---|---|
|
||||
| สร้าง RFA (Draft) | Document Control, Org Admin, Superadmin | ภายในองค์กรตัวเอง |
|
||||
| Submit RFA | Document Control, Org Admin, Superadmin | เปลี่ยนสถานะ Draft → FAP/FRE |
|
||||
| แก้ไข/ถอนกลับ/ยกเลิก หลัง Submit | **Org Admin ขึ้นไปเท่านั้น** พร้อมระบุเหตุผล | — |
|
||||
| ดู RFA ที่ Draft | เฉพาะคนในองค์กรเดียวกัน | องค์กรอื่นมองไม่เห็น |
|
||||
| ดู RFA ที่ Submitted แล้ว | ทุกคนที่มีสิทธิ์ใน Project | — |
|
||||
| จัดการ RFA Types (Master) | Superadmin | Global |
|
||||
|
||||
---
|
||||
|
||||
## 3.3.6. การอ้างอิง Drawing Revisions (rfa_items)
|
||||
|
||||
- 1 RFA Revision สามารถอ้างอิง Drawing Revision ได้หลายรายการ
|
||||
- 1 แถวใน `rfa_items` อ้างอิง Drawing Revision ได้ **เพียง 1 รายการเท่านั้น** โดยต้องเป็น `shop_drawing_revision` หรือ `asbuilt_drawing_revision` อย่างใดอย่างหนึ่ง (ไม่ใช่ทั้งคู่)
|
||||
- `item_type` ENUM: `'SHOP'` | `'AS_BUILT'` — กำหนดว่า FK ไหนที่ต้อง NOT NULL
|
||||
- 1 Drawing Revision สามารถถูกอ้างอิงโดยหลาย RFA ได้ (แต่ดู EC-RFA-001)
|
||||
|
||||
### Unique Constraint:
|
||||
- `(rfa_revision_id, shop_drawing_revision_id)` — ห้าม Drawing เดิมซ้ำใน RFA เดียวกัน
|
||||
- `(rfa_revision_id, asbuilt_drawing_revision_id)` — เช่นเดียวกัน
|
||||
|
||||
---
|
||||
|
||||
## 3.3.7. Status Codes (rfa_status_codes)
|
||||
|
||||
| status_code | ชื่อ | ความหมาย |
|
||||
|---|---|---|
|
||||
| `DFT` | Draft | ฉบับร่าง — มองเห็นเฉพาะ Originator Org |
|
||||
| `FAP` | For Approve | ส่งเพื่อขออนุมัติ |
|
||||
| `FRE` | For Review | ส่งเพื่อตรวจสอบ |
|
||||
| `FCO` | For Construction | อนุมัติให้ก่อสร้างได้ |
|
||||
| `ASB` | AS-Built | แบบก่อสร้างจริง |
|
||||
| `OBS` | Obsolete | ไม่ใช้งานแล้ว |
|
||||
| `CC` | Canceled | ยกเลิก |
|
||||
|
||||
---
|
||||
|
||||
## 3.3.8. Approve Codes (rfa_approve_codes)
|
||||
|
||||
ผลการอนุมัติบันทึกใน `rfa_revisions.rfa_approve_code_id`:
|
||||
|
||||
| approve_code | ชื่อ | ความหมาย |
|
||||
|---|---|---|
|
||||
| `1A` | Approved by Authority | อนุมัติโดยหน่วยงานที่มีอำนาจ |
|
||||
| `1C` | Approved by CSC | อนุมัติโดย CSC |
|
||||
| `1N` | Approved As Note | อนุมัติพร้อมบันทึก |
|
||||
| `1R` | Approved with Remarks | อนุมัติพร้อมข้อสังเกต |
|
||||
| `3C` | Consultant Comments | มีความเห็นจากที่ปรึกษา |
|
||||
| `3R` | Revise and Resubmit | ขอให้แก้ไขและส่งใหม่ |
|
||||
| `4X` | Reject | ปฏิเสธ |
|
||||
| `5N` | No Further Action | ไม่ต้องดำเนินการเพิ่มเติม |
|
||||
|
||||
---
|
||||
|
||||
## 3.3.9. Workflow (Unified Workflow)
|
||||
|
||||
RFA ใช้ Unified Workflow Engine — ดูรายละเอียดที่ `01-03-06-unified-workflow.md`
|
||||
|
||||
สถานะการสร้าง Revision ใหม่:
|
||||
- ห้ามมี 2 Active Revision พร้อมกัน (EC-RFA-002)
|
||||
- สร้าง Rev.B ได้ก็ต่อเมื่อ Rev.A มีผลสุดท้ายแล้ว (`3R`, `4X`, หรือ Approved)
|
||||
|
||||
---
|
||||
|
||||
## 3.3.10. Business Rules และ Edge Cases
|
||||
|
||||
| รหัส | กฎ | Severity |
|
||||
|---|---|---|
|
||||
| **EC-RFA-001** | 1 Shop Drawing Revision มี Active RFA ได้สูงสุด 1 ฉบับ (ยกเว้นถูก REJECTED/CANCELLED แล้ว) | 🔴 Critical |
|
||||
| **EC-RFA-002** | ห้ามสร้าง Revision ใหม่ถ้า Revision ก่อนหน้ายังไม่มีคำตอบสุดท้าย | 🟠 High |
|
||||
| **EC-RFA-003** | Discipline ต้องเลือกก่อนเสมอ ไม่มี Auto-detection (AI Classification เป็น Phase 3) | 🟡 Medium |
|
||||
| **EC-RFA-004** | Transmittal ที่มี RFA Submit ได้ก็ต่อเมื่อทุก RFA อยู่ในสถานะ READY (ไม่ใช่ DRAFT) | 🟠 High |
|
||||
|
||||
ดูรายละเอียดครบที่ `01-06-edge-cases-and-rules.md` หมวด "Module 4: RFA & Drawing Edge Cases"
|
||||
|
||||
@@ -3,30 +3,103 @@
|
||||
---
|
||||
|
||||
title: 'Functional Requirements: Contract Drawing Management'
|
||||
version: 1.8.0
|
||||
status: first-draft
|
||||
version: 1.8.1
|
||||
status: updated
|
||||
owner: Nattanin Peancharoen
|
||||
last_updated: 2026-02-23
|
||||
last_updated: 2026-03-24
|
||||
related:
|
||||
|
||||
- specs/01-requirements/01-01-objectives.md
|
||||
- specs/02-architecture/README.md
|
||||
- specs/01-requirements/01-03-modules/01-03-00-index.md
|
||||
- specs/01-requirements/01-03-modules/01-03-05-shop-drawing.md
|
||||
- specs/03-Data-and-Storage/03-01-data-dictionary.md
|
||||
- specs/01-requirements/01-02-business-rules/01-02-01-rbac-matrix.md
|
||||
|
||||
---
|
||||
|
||||
## 3.4.1. วัตถุประสงค์:
|
||||
## 3.4.1. วัตถุประสงค์
|
||||
|
||||
- แบบคู่สัญญา (Contract Drawing) ใช้เพื่ออ้างอิงและใช้ในการตรวจสอบ
|
||||
แบบคู่สัญญา (Contract Drawing) คือแบบที่ได้รับจากสัญญาก่อสร้าง ใช้เป็น **เอกสารอ้างอิงหลัก** สำหรับ Shop Drawing และ As-Built Drawing ภายในโครงการ ไม่มี Revision Model — แต่ละแบบเป็นเอกสาร Master คงที่
|
||||
|
||||
## 3.4.2. ประเภทเอกสาร:
|
||||
> **หมายเหตุการพัฒนา:** ข้อมูล Contract Drawing มาจาก **Seed Data** (นำเข้าจากข้อมูลสัญญาที่มีอยู่แล้ว) ไม่ได้สร้างใหม่ผ่าน UI ระบบอัปโหลดไฟล์ PDF อยู่**ระหว่างการพัฒนา** — ปัจจุบัน record มีอยู่ในระบบแต่ไฟล์แนบยังไม่สมบูรณ์
|
||||
|
||||
- ไฟล์ PDF
|
||||
---
|
||||
|
||||
## 3.4.3. การสร้างเอกสาร:
|
||||
## 3.4.2. โครงสร้างข้อมูล (Database Tables)
|
||||
|
||||
- ผู้ใช้ที่มีสิทธิ์ สามารถสร้างและแก้ไขได้
|
||||
| Table | บทบาท |
|
||||
|---|---|
|
||||
| `contract_drawings` | ข้อมูล Master แบบคู่สัญญา: เลขแบบ, ชื่อ, หมวดหมู่, เล่ม |
|
||||
| `contract_drawing_attachments` | ไฟล์แนบ (M:N กับ `attachments`) รองรับหลายไฟล์ต่อแบบ |
|
||||
| `contract_drawing_volumes` | Master: เล่มของแบบ (ผูกกับ Project) |
|
||||
| `contract_drawing_cats` | Master: หมวดหมู่หลัก (ผูกกับ Project) |
|
||||
| `contract_drawing_sub_cats` | Master: หมวดหมู่ย่อย (ผูกกับ Project) |
|
||||
| `contract_drawing_subcat_cat_maps` | M:N ระหว่าง หมวดหมู่หลัก ↔ หมวดหมู่ย่อย (ผูกกับ Project) |
|
||||
|
||||
## 3.4.4. การอ้างอิงและจัดกลุ่ม:
|
||||
**ข้อสำคัญ:** `condwg_no` ต้อง UNIQUE ภายใน Project เดียวกัน (`ux_condwg_no_project`)
|
||||
|
||||
- ใช้สำหรับอ้างอิง ใน Shop Drawings, มีการจัดหมวดหมู่ของ Contract Drawing
|
||||
---
|
||||
|
||||
## 3.4.3. Fields ที่ต้องกรอกเมื่อสร้าง Contract Drawing
|
||||
|
||||
| Field | Required | หมายเหตุ |
|
||||
|---|---|---|
|
||||
| Project | ✅ | UUID — ผูกกับ `projects` |
|
||||
| Drawing Number (`condwg_no`) | ✅ | VARCHAR(255) — unique per project |
|
||||
| Title | ✅ | VARCHAR(255) |
|
||||
| Category (`map_cat_id`) | ❌ | FK → `contract_drawing_subcat_cat_maps` |
|
||||
| Volume (`volume_id`) | ❌ | FK → `contract_drawing_volumes` |
|
||||
| Volume Page (`volume_page`) | ❌ | INT |
|
||||
| Attachments | ❌ | PDF / DWG / SOURCE / OTHER — ผ่าน ClamAV scan (**อยู่ระหว่างพัฒนาระบบนำเข้า PDF**) |
|
||||
|
||||
---
|
||||
|
||||
## 3.4.4. ไฟล์แนบ (contract_drawing_attachments)
|
||||
|
||||
รองรับหลายไฟล์ต่อ 1 Contract Drawing:
|
||||
|
||||
| file_type | ความหมาย |
|
||||
|---|---|
|
||||
| `PDF` | ไฟล์ PDF แบบดิจิทัล |
|
||||
| `DWG` | ไฟล์ AutoCAD |
|
||||
| `SOURCE` | ไฟล์ต้นฉบับอื่นๆ |
|
||||
| `OTHER` | ประเภทอื่น |
|
||||
|
||||
- `is_main_document = TRUE` ระบุไฟล์หลัก (แสดงเป็น Default สำหรับ Preview)
|
||||
|
||||
> **สถานะ:** ข้อมูล `contract_drawings` ถูก Seed เข้าระบบแล้ว แต่ `contract_drawing_attachments` ยังว่างอยู่ระหว่างรอระบบ PDF Import
|
||||
|
||||
---
|
||||
|
||||
## 3.4.5. โครงสร้างหมวดหมู่ (Category Structure)
|
||||
|
||||
หมวดหมู่ผูกกับ **Project** (ไม่ใช่ Global) — จัดการโดย Project Manager:
|
||||
|
||||
```
|
||||
contract_drawing_volumes (เล่ม — Volume)
|
||||
contract_drawing_cats (หมวดหมู่หลัก — Main Category)
|
||||
contract_drawing_sub_cats (หมวดหมู่ย่อย — Sub Category)
|
||||
contract_drawing_subcat_cat_maps (M:N: Sub Category ↔ Main Category)
|
||||
```
|
||||
|
||||
- `contract_drawings.map_cat_id` FK → `contract_drawing_subcat_cat_maps`
|
||||
- 1 Sub Category สามารถอยู่ใน Main Category ได้หลายหมวด (M:N)
|
||||
|
||||
---
|
||||
|
||||
## 3.4.6. การสร้างและสิทธิ์ (RBAC)
|
||||
|
||||
| การกระทำ | Role ที่อนุญาต | Scope |
|
||||
|---|---|---|
|
||||
| สร้าง / แก้ไข Contract Drawing | Project Manager, Org Admin, Superadmin | Project |
|
||||
| ลบ Contract Drawing | Org Admin, Superadmin | Project |
|
||||
| จัดการ Volume / Category (Master) | Project Manager | Project |
|
||||
| ดู Contract Drawing | ทุกคนที่มีสิทธิ์ใน Project | Project |
|
||||
|
||||
---
|
||||
|
||||
## 3.4.7. ความสัมพันธ์กับ Module อื่น
|
||||
|
||||
- **Shop Drawing** (`shop_drawings`) อ้างอิง `contract_drawing_id` → ใช้ Contract Drawing เป็นแบบต้นฉบับ
|
||||
- Contract Drawing **ไม่มี Revision Model** — ต่างจาก Shop Drawing ที่มี `shop_drawing_revisions`
|
||||
- ไม่มีความสัมพันธ์โดยตรงกับ RFA — RFA อ้างอิง `shop_drawing_revisions` ไม่ใช่ Contract Drawing
|
||||
|
||||
@@ -3,30 +3,132 @@
|
||||
---
|
||||
|
||||
title: 'Functional Requirements: Shop Drawing Management'
|
||||
version: 1.8.0
|
||||
status: first-draft
|
||||
version: 1.8.1
|
||||
status: updated
|
||||
owner: Nattanin Peancharoen
|
||||
last_updated: 2026-02-23
|
||||
last_updated: 2026-03-24
|
||||
related:
|
||||
|
||||
- specs/01-requirements/01-01-objectives.md
|
||||
- specs/02-architecture/README.md
|
||||
- specs/01-requirements/01-03-modules/01-03-00-index.md
|
||||
- specs/01-requirements/01-03-modules/01-03-03-rfa.md
|
||||
- specs/01-requirements/01-03-modules/01-03-04-contract-drawing.md
|
||||
- specs/01-requirements/01-06-edge-cases-and-rules.md (EC-RFA-001, EC-RFA-003)
|
||||
- specs/03-Data-and-Storage/03-01-data-dictionary.md
|
||||
- specs/01-requirements/01-02-business-rules/01-02-01-rbac-matrix.md
|
||||
|
||||
---
|
||||
|
||||
## 3.5.1. วัตถุประสงค์:
|
||||
## 3.5.1. วัตถุประสงค์
|
||||
|
||||
- แบบก่อสร้าง (Shop Drawing) ใช้เในการตรวจสอบ โดยจัดส่งด้วย Request for Approval (RFA)
|
||||
แบบก่อสร้าง (Shop Drawing) คือแบบที่ Contractor จัดทำขึ้นเพื่อขออนุมัติจากผู้ว่าจ้างหรือที่ปรึกษา โดยส่งผ่าน RFA (Request for Approval) — มี Revision Model (Rev.A, Rev.B, ...) และอ้างอิง Contract Drawing ที่เป็นต้นฉบับได้
|
||||
|
||||
## 3.5.2. ประเภทเอกสาร:
|
||||
---
|
||||
|
||||
- ไฟล์ PDF, DWG, ZIP
|
||||
## 3.5.2. โครงสร้างข้อมูล (Database Tables)
|
||||
|
||||
## 3.5.3. การสร้างเอกสาร:
|
||||
| Table | บทบาท |
|
||||
|---|---|
|
||||
| `shop_drawings` | ข้อมูล Master: เลขแบบ, หมวดหมู่หลัก, หมวดหมู่ย่อย, project |
|
||||
| `shop_drawing_revisions` | ประวัติแต่ละ Revision: title, revision_label, is_current, revision_date |
|
||||
| `shop_drawing_revision_contract_refs` | M:N: Revision ↔ Contract Drawing ที่อ้างอิง |
|
||||
| `shop_drawing_revision_attachments` | ไฟล์แนบต่อ Revision (M:N กับ `attachments`) |
|
||||
| `shop_drawing_main_categories` | Master: หมวดหมู่หลัก (ผูกกับ Project) |
|
||||
| `shop_drawing_sub_categories` | Master: หมวดหมู่ย่อย (ผูกกับ Project) |
|
||||
|
||||
- ผู้ใช้ที่มีสิทธิ์ สามารถสร้างและแก้ไขได้ โดยผู้ใช้ที่มีสิทธิ์ (เช่น Document Control) สามารถสร้างเอกสารรอไว้ในสถานะ ฉบับร่าง" (Draft) ได้ ซึ่งผู้ใช้งานต่างองค์กรจะมองไม่เห็น
|
||||
**ข้อสำคัญ:**
|
||||
- `drawing_number` ต้อง UNIQUE ภายใน Project (`ux_shop_dwg_no_project`)
|
||||
- `is_current = TRUE` มีได้เพียง 1 แถวต่อ Shop Drawing (`uq_sd_current`)
|
||||
|
||||
## 3.5.4. การอ้างอิงและจัดกลุ่ม:
|
||||
---
|
||||
|
||||
- ใช้สำหรับอ้างอิง ใน RFA, มีการจัดหมวดหมู่ของ Shop Drawings โดยทุก แบบก่อสร้าง (Shop Drawing) แต่ละ revision ต้องมี RFA ได้เพียง 1 ฉบับ
|
||||
## 3.5.3. Fields ที่ต้องกรอกเมื่อสร้าง Shop Drawing
|
||||
|
||||
### Master (shop_drawings)
|
||||
|
||||
| Field | Required | หมายเหตุ |
|
||||
|---|---|---|
|
||||
| Project | ✅ | UUID |
|
||||
| Drawing Number | ✅ | VARCHAR(100) — unique per project |
|
||||
| Main Category | ✅ | INT id — FK → `shop_drawing_main_categories` |
|
||||
| Sub Category | ✅ | INT id — FK → `shop_drawing_sub_categories` |
|
||||
|
||||
### Revision (shop_drawing_revisions)
|
||||
|
||||
| Field | Required | หมายเหตุ |
|
||||
|---|---|---|
|
||||
| Title | ✅ | VARCHAR(500) — ชื่อแบบใน Revision นี้ |
|
||||
| Revision Label | ❌ | VARCHAR(10) เช่น A, B, 1.1 |
|
||||
| Revision Date | ❌ | DATE |
|
||||
| Description | ❌ | คำอธิบายการแก้ไข |
|
||||
| Legacy Drawing Number | ❌ | VARCHAR(100) — เลขแบบเดิม (สำหรับข้อมูล Migration) |
|
||||
| Contract Drawing Refs | ❌ | UUID[] — อ้างอิง Contract Drawing ต้นฉบับ |
|
||||
| Attachments | ❌ | PDF / DWG / SOURCE / OTHER — ผ่าน ClamAV scan |
|
||||
|
||||
---
|
||||
|
||||
## 3.5.4. ไฟล์แนบ (shop_drawing_revision_attachments)
|
||||
|
||||
ไฟล์แนบผูกกับ **Revision** ไม่ใช่ Master — รองรับหลายไฟล์ต่อ 1 Revision:
|
||||
|
||||
| file_type | ความหมาย |
|
||||
|---|---|
|
||||
| `PDF` | ไฟล์ PDF แบบดิจิทัล |
|
||||
| `DWG` | ไฟล์ AutoCAD |
|
||||
| `SOURCE` | ไฟล์ต้นฉบับอื่นๆ |
|
||||
| `OTHER` | ประเภทอื่น |
|
||||
|
||||
- `is_main_document = TRUE` ระบุไฟล์หลักของ Revision นั้น
|
||||
|
||||
---
|
||||
|
||||
## 3.5.5. โครงสร้างหมวดหมู่ (Category Structure)
|
||||
|
||||
หมวดหมู่ผูกกับ **Project** — จัดการโดย Project Manager:
|
||||
|
||||
```
|
||||
shop_drawing_main_categories (หมวดหมู่หลัก เช่น ARCH, STR, MEP)
|
||||
shop_drawing_sub_categories (หมวดหมู่ย่อย เช่น STR-COLUMN, STR-BEAM)
|
||||
```
|
||||
|
||||
- ต่างจาก Contract Drawing ที่ Main ↔ Sub เป็น M:N — Shop Drawing เป็น **direct FK**: `shop_drawings.main_category_id` และ `shop_drawings.sub_category_id` (1 แบบ = 1 Main + 1 Sub)
|
||||
|
||||
---
|
||||
|
||||
## 3.5.6. Revision Model
|
||||
|
||||
- 1 Shop Drawing Master → หลาย Revision (1:N)
|
||||
- `revision_number`: 0-based integer สำหรับ sorting
|
||||
- `revision_label`: A, B, C, ... — แสดงใน UI
|
||||
- `is_current = TRUE` มีได้เพียง 1 แถว (NULL สำหรับที่ไม่ใช่ปัจจุบัน — ต่างจาก BOOLEAN เพื่อให้ UNIQUE constraint ทำงาน)
|
||||
|
||||
---
|
||||
|
||||
## 3.5.7. การสร้างและสิทธิ์ (RBAC)
|
||||
|
||||
| การกระทำ | Role ที่อนุญาต | Scope |
|
||||
|---|---|---|
|
||||
| สร้าง Shop Drawing + Revision | Document Control, Org Admin, Superadmin | Project |
|
||||
| แก้ไข Shop Drawing | Document Control, Org Admin, Superadmin | Project |
|
||||
| ลบ Shop Drawing | Org Admin, Superadmin | Project |
|
||||
| จัดการ Main/Sub Category (Master) | Project Manager | Project |
|
||||
| ดู Shop Drawing | ทุกคนที่มีสิทธิ์ใน Project | Project |
|
||||
|
||||
---
|
||||
|
||||
## 3.5.8. ความสัมพันธ์กับ Module อื่น
|
||||
|
||||
- **RFA** (`rfa_items`) อ้างอิง `shop_drawing_revision_id` → 1 Revision มี Active RFA ได้สูงสุด 1 ฉบับ (EC-RFA-001)
|
||||
- **Contract Drawing** (`shop_drawing_revision_contract_refs`) — แต่ละ Revision สามารถอ้างอิง Contract Drawing ต้นฉบับได้หลายฉบับ (M:N)
|
||||
- **As-Built Drawing** — ไม่มีความสัมพันธ์โดยตรง (คนละ module)
|
||||
|
||||
---
|
||||
|
||||
## 3.5.9. Business Rules และ Edge Cases
|
||||
|
||||
| รหัส | กฎ | Severity |
|
||||
|---|---|---|
|
||||
| **EC-RFA-001** | 1 Shop Drawing Revision มี Active RFA ได้สูงสุด 1 ฉบับ (ยกเว้น REJECTED/CANCELLED แล้ว) | 🔴 Critical |
|
||||
| **EC-RFA-003** | Discipline และ Category ต้องเลือกก่อน Upload — ไม่มี Auto-detection (Phase 3) | 🟡 Medium |
|
||||
|
||||
ดูรายละเอียดครบที่ `01-06-edge-cases-and-rules.md` หมวด "Module 4: RFA & Drawing Edge Cases"
|
||||
|
||||
@@ -3,41 +3,147 @@
|
||||
---
|
||||
|
||||
title: 'Functional Requirements: Unified Workflow Management'
|
||||
version: 1.8.0
|
||||
status: first-draft
|
||||
version: 1.8.1
|
||||
status: updated
|
||||
owner: Nattanin Peancharoen
|
||||
last_updated: 2026-02-23
|
||||
last_updated: 2026-03-24
|
||||
related:
|
||||
|
||||
- specs/01-requirements/01-01-objectives.md
|
||||
- specs/02-architecture/README.md
|
||||
- specs/01-requirements/01-03-modules/01-03-00-index.md
|
||||
- specs/01-requirements/01-03-modules/01-03-02-correspondence.md
|
||||
- specs/01-requirements/01-03-modules/01-03-03-rfa.md
|
||||
- specs/01-requirements/01-03-modules/01-03-08-circulation-sheet.md
|
||||
- specs/06-Decision-Records/ADR-001-unified-workflow-engine.md
|
||||
- specs/01-requirements/01-02-business-rules/01-02-01-rbac-matrix.md
|
||||
|
||||
---
|
||||
|
||||
## 3.6.1 Workflow Definition:
|
||||
## 3.6.1. วัตถุประสงค์
|
||||
|
||||
- Admin ต้องสามารถกำหนดและสร้าง/แก้ไข Workflow Rule ได้ (DSL)
|
||||
- รองรับการกำหนด State, Transition, Required Role, Condition (JS Expression)
|
||||
Unified Workflow Engine คือ **Engine กลาง** สำหรับจัดการสถานะ (State) และการเปลี่ยนสถานะ (Transition) ของเอกสารทุกประเภทในระบบ ใช้ **JSON-based DSL** เก็บ Workflow Definition ไว้ใน Database ไม่ต้อง Deploy ใหม่เมื่อแก้ Workflow
|
||||
|
||||
## 3.6.2 Workflow Execution:
|
||||
ดูการตัดสินใจเลือก Architecture ได้ที่ `ADR-001-unified-workflow-engine.md`
|
||||
|
||||
- ระบบต้องรองรับการสร้าง Instance ของ Workflow ผูกกับเอกสาร (Polymorphic)
|
||||
- รองรับการเปลี่ยนสถานะ (Action) เช่น Approve, Reject, Comment, Return
|
||||
- Auto-Action: รองรับการเปลี่ยนสถานะอัตโนมัติเมื่อครบเงื่อนไข (เช่น Review ครบทุกคน)
|
||||
---
|
||||
|
||||
## 3.6.3 Flexibility:
|
||||
## 3.6.2. โครงสร้างข้อมูล (Database Tables)
|
||||
|
||||
- รองรับ Parallel Review (ส่งให้หลายคนตรวจพร้อมกัน)
|
||||
- รองรับ Conditional Flow (เช่น ถ้ายอดเงิน > X ให้เพิ่มผู้อนุมัติ)
|
||||
| Table | บทบาท |
|
||||
|---|---|
|
||||
| `workflow_definitions` | นิยาม Workflow (DSL + compiled) — versioned per `workflow_code` |
|
||||
| `workflow_instances` | Instance ผูกกับเอกสาร — เก็บ `current_state` + `context` JSON |
|
||||
| `workflow_histories` | Audit Trail: ทุก transition บันทึก from/to state, action, user, comment |
|
||||
|
||||
## 3.6.4 Workflow การอนุมัติ:
|
||||
### workflow_instances.entity_type ที่รองรับ
|
||||
|
||||
- รองรับกระบวนการอนุมัติที่ซับซ้อนและเป็นลำดับ เช่น ส่งจาก Originator -> Organization 1 -> Organization 2 -> Organization 3 แล้วส่งผลกลับตามลำดับเดิม (โดยถ้า องกรณ์ใดใน Workflow ให้ส่งกลับ ก็สามารถส่งผลกลับตามลำดับเดิมโดยไม่ต้องรอให้ถึง องกรณืในลำดับถัดไป)
|
||||
| entity_type | Module |
|
||||
|---|---|
|
||||
| `rfa_revision` | RFA Revision |
|
||||
| `correspondence_revision` | Correspondence Revision |
|
||||
| `circulation` | Circulation Sheet |
|
||||
|
||||
## 3.6.5 การจัดการ:
|
||||
### workflow_instances.status
|
||||
|
||||
- สามารถกำหนดวันแล้วเสร็จ (Deadline) สำหรับผู้รับผิดชอบของ องกรณ์ ที่อยู่ใน Workflow ได้
|
||||
- มีระบบแจ้งเตือน ให้ผู้รับผิดชอบของ องกรณ์ ที่อยู่ใน Workflow ทราบ เมื่อมี RFA ใหม่ หรือมีการเปลี่ยนสถานะ
|
||||
- สามารถข้ามขั้นตอนได้ในกรณีพิเศษ (โดยผู้มีสิทธิ์)
|
||||
- สามารถส่งกลับขั้นตอนก่อนหน้าได้
|
||||
| status | ความหมาย |
|
||||
|---|---|
|
||||
| `ACTIVE` | กำลังดำเนินการ |
|
||||
| `COMPLETED` | เสร็จสมบูรณ์ (ถึง terminal state) |
|
||||
| `CANCELLED` | ยกเลิกโดยผู้ใช้ |
|
||||
| `TERMINATED` | ถูกยุติโดยระบบ |
|
||||
|
||||
---
|
||||
|
||||
## 3.6.3. Workflow Definition (DSL)
|
||||
|
||||
Workflow Definition เก็บ 2 ฟอร์แมตใน DB:
|
||||
- `dsl` — JSON ต้นฉบับที่ Admin กำหนด
|
||||
- `compiled` — Execution Tree ที่ Engine Compile แล้ว (optimize สำหรับ runtime)
|
||||
|
||||
### DSL Structure (ตัวอย่าง)
|
||||
|
||||
```json
|
||||
{
|
||||
"workflow": "CORRESPONDENCE_ROUTING",
|
||||
"version": 1,
|
||||
"states": [
|
||||
{
|
||||
"name": "DRAFT",
|
||||
"initial": true,
|
||||
"on": {
|
||||
"SUBMIT": {
|
||||
"to": "SUBMITTED",
|
||||
"require": { "role": ["Document Control", "Org Admin"] },
|
||||
"condition": "context.hasRecipient === true",
|
||||
"events": [{ "type": "notify", "target": "recipients" }]
|
||||
}
|
||||
}
|
||||
},
|
||||
{ "name": "SUBMITTED", "on": { "RETURN": { "to": "DRAFT" }, "CLOSE": { "to": "CLOSED" } } },
|
||||
{ "name": "CLOSED", "terminal": true }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### DSL Elements
|
||||
|
||||
| Element | ความหมาย |
|
||||
|---|---|
|
||||
| `states[].initial` | State เริ่มต้นเมื่อสร้าง Instance |
|
||||
| `states[].terminal` | State สุดท้าย — Instance จะ COMPLETED |
|
||||
| `on.<ACTION>.to` | State ปลายทางหลัง transition |
|
||||
| `on.<ACTION>.require.role` | Role ที่ต้องมีจึงจะ trigger action ได้ |
|
||||
| `on.<ACTION>.condition` | JS Expression ประเมินจาก `context` JSON |
|
||||
| `on.<ACTION>.events` | Events ที่ fire หลัง transition (notify, etc.) |
|
||||
|
||||
---
|
||||
|
||||
## 3.6.4. Workflow Execution
|
||||
|
||||
1. **สร้าง Instance** — เมื่อเอกสารถูกสร้าง → `WorkflowEngineService.createInstance(workflowCode, entityType, entityId)`
|
||||
2. **Transition** — `processTransition(instanceId, action, userId, comment)` → validate role + condition → update `current_state` → write `workflow_histories`
|
||||
3. **Auto-Action** — เมื่อ condition ครบ (เช่น Review ครบทุกคน) Engine trigger transition อัตโนมัติ
|
||||
4. **Terminal State** — `instance.status = COMPLETED` เมื่อถึง terminal state
|
||||
|
||||
### Versioning
|
||||
|
||||
- แก้ Workflow ได้โดยเพิ่ม `version` ใหม่ — In-progress instances ยังคงใช้ version เดิม
|
||||
- `UNIQUE KEY (workflow_code, version)` — ป้องกัน version ซ้ำ
|
||||
|
||||
---
|
||||
|
||||
## 3.6.5. Flexibility
|
||||
|
||||
- **Sequential Approval:** Originator → Org1 → Org2 → Org3 → ส่งผลกลับตามลำดับเดิม — องค์กรใด Reject ได้ทันทีโดยไม่รอลำดับถัดไป
|
||||
- **Parallel Review:** ส่งให้หลายคนตรวจพร้อมกัน — รอผลครบก่อน transition
|
||||
- **Conditional Flow:** `condition` expression ประเมิน `context` — เช่น เพิ่ม Approver เมื่อยอดเกิน threshold
|
||||
- **Skip Step:** ผู้มีสิทธิ์ข้ามขั้นตอนได้ (force transition)
|
||||
- **Return:** ส่งกลับ state ก่อนหน้าได้ พร้อม comment บังคับ
|
||||
|
||||
---
|
||||
|
||||
## 3.6.6. Notifications & Deadline
|
||||
|
||||
- **Event:** `"type": "notify"` ใน DSL → fire ผ่าน Notification Module (BullMQ)
|
||||
- **Deadline:** กำหนดได้ต่อ Org ใน Workflow Step
|
||||
- **แจ้งเตือน:** เมื่อมีเอกสารใหม่ หรือสถานะเปลี่ยน → Email / LINE Notify / In-App
|
||||
|
||||
---
|
||||
|
||||
## 3.6.7. RBAC
|
||||
|
||||
| การกระทำ | Role ที่อนุญาต |
|
||||
|---|---|
|
||||
| จัดการ Workflow Definition (สร้าง/แก้ไข DSL) | Superadmin |
|
||||
| Trigger Workflow Action (Submit, Approve, Reject, ฯลฯ) | ขึ้นอยู่กับ `require.role` ใน DSL |
|
||||
| ดู Workflow History | ทุกคนที่มีสิทธิ์ใน Document นั้น |
|
||||
|
||||
---
|
||||
|
||||
## 3.6.8. Audit Trail (workflow_histories)
|
||||
|
||||
ทุก transition บันทึก:
|
||||
- `from_state` / `to_state` / `action`
|
||||
- `action_by_user_id` — ผู้กระทำ
|
||||
- `comment` — ความเห็น (บังคับสำหรับ Return/Reject)
|
||||
- `metadata` JSON — Snapshot ข้อมูล ณ ขณะนั้น
|
||||
|
||||
@@ -3,30 +3,96 @@
|
||||
---
|
||||
|
||||
title: 'Functional Requirements: Transmittals Management'
|
||||
version: 1.8.0
|
||||
status: first-draft
|
||||
version: 1.8.1
|
||||
status: updated
|
||||
owner: Nattanin Peancharoen
|
||||
last_updated: 2026-02-23
|
||||
last_updated: 2026-03-24
|
||||
related:
|
||||
|
||||
- specs/01-requirements/01-01-objectives.md
|
||||
- specs/02-architecture/README.md
|
||||
- specs/01-requirements/01-03-modules/01-03-00-index.md
|
||||
- specs/01-requirements/01-03-modules/01-03-02-correspondence.md
|
||||
- specs/01-requirements/01-03-modules/01-03-03-rfa.md
|
||||
- specs/01-requirements/01-06-edge-cases-and-rules.md (EC-RFA-004)
|
||||
- specs/03-Data-and-Storage/03-01-data-dictionary.md
|
||||
- specs/01-requirements/01-02-business-rules/01-02-01-rbac-matrix.md
|
||||
|
||||
---
|
||||
|
||||
## 3.7.1. วัตถุประสงค์:
|
||||
## 3.7.1. วัตถุประสงค์
|
||||
|
||||
- เอกสารนำส่ง ใช้สำหรับ นำส่ง Request for Approval (RFAS) หลายฉบับ ไปยังองค์กรอื่น
|
||||
เอกสารนำส่ง (Transmittal) ใช้สำหรับรวบรวมเอกสารหลายฉบับ (เช่น RFA) แล้วส่งเป็นชุดไปยังองค์กรอื่นในคราวเดียว เป็น **Correspondence ประเภทหนึ่ง** (`type_code = 'TRANSMITTAL'`) — ใช้ pattern **Correspondence + Extension** เช่นเดียวกับ RFA
|
||||
|
||||
## 3.7.2. ประเภทเอกสาร:
|
||||
---
|
||||
|
||||
- ไฟล์ PDF
|
||||
## 3.7.2. โครงสร้างข้อมูล (Database Tables)
|
||||
|
||||
## 3.7.3. การสร้างเอกสาร:
|
||||
| Table | บทบาท |
|
||||
|---|---|
|
||||
| `correspondences` | ข้อมูลหลัก: เลขเอกสาร, subject, project, originator, recipients |
|
||||
| `transmittals` | ข้อมูลเฉพาะ Transmittal: `purpose`, `remarks` — FK = `correspondences.id` |
|
||||
| `transmittal_items` | รายการเอกสารที่นำส่งใน Transmittal นั้น (M:N กับ `correspondences`) |
|
||||
|
||||
- ผู้ใช้ที่มีสิทธิ์ สามารถสร้างและแก้ไขได้
|
||||
**ข้อสำคัญ:** `transmittals.correspondence_id` คือ PK และ FK ชี้ไปที่ `correspondences.id` (ไม่มี AUTO_INCREMENT ของตัวเอง)
|
||||
|
||||
## 3.7.4. การอ้างอิงและจัดกลุ่ม:
|
||||
---
|
||||
|
||||
- เอกสารนำส่ง เป็นส่วนหนึ่งใน Correspondence
|
||||
## 3.7.3. Fields ที่ต้องกรอกเมื่อสร้าง Transmittal
|
||||
|
||||
| Field | Required | หมายเหตุ |
|
||||
|---|---|---|
|
||||
| Project | ✅ | UUID — เหมือน Correspondence ทั่วไป |
|
||||
| Correspondence Type | ✅ | ต้องเป็น `TRANSMITTAL` |
|
||||
| Subject | ✅ | ขั้นต่ำ 5 ตัวอักษร |
|
||||
| To Organization | ✅ | UUID — `recipient_type = 'TO'` |
|
||||
| Purpose | ❌ | ENUM — วัตถุประสงค์การนำส่ง |
|
||||
| Remarks | ❌ | หมายเหตุ |
|
||||
| Items (เอกสารที่นำส่ง) | ❌ | UUID[] — รายการ Correspondence ที่แนบ |
|
||||
|
||||
### Purpose ENUM (transmittals.purpose)
|
||||
|
||||
| purpose | ความหมาย |
|
||||
|---|---|
|
||||
| `FOR_APPROVAL` | นำส่งเพื่อขออนุมัติ |
|
||||
| `FOR_INFORMATION` | นำส่งเพื่อทราบ |
|
||||
| `FOR_REVIEW` | นำส่งเพื่อตรวจสอบ |
|
||||
| `OTHER` | วัตถุประสงค์อื่น |
|
||||
|
||||
---
|
||||
|
||||
## 3.7.4. transmittal_items
|
||||
|
||||
รายการเอกสารที่แนบใน Transmittal:
|
||||
|
||||
| Field | หมายเหตุ |
|
||||
|---|---|
|
||||
| `transmittal_id` | FK → `transmittals.correspondence_id` |
|
||||
| `item_correspondence_id` | FK → `correspondences.id` — เอกสารที่นำส่ง (เช่น RFA) |
|
||||
| `quantity` | จำนวน (default = 1) |
|
||||
| `remarks` | หมายเหตุสำหรับรายการนี้ |
|
||||
|
||||
- UNIQUE KEY `(transmittal_id, item_correspondence_id)` — ป้องกันเอกสารซ้ำใน Transmittal เดียวกัน
|
||||
- 1 Transmittal รวบรวมเอกสารได้หลายฉบับ
|
||||
- เอกสารที่นำส่งได้ไม่จำกัดประเภท (RFA, Letter, ฯลฯ)
|
||||
|
||||
---
|
||||
|
||||
## 3.7.5. การสร้างและสิทธิ์ (RBAC)
|
||||
|
||||
| การกระทำ | Role ที่อนุญาต | หมายเหตุ |
|
||||
|---|---|---|
|
||||
| สร้าง Transmittal (Draft) | Document Control, Org Admin, Superadmin | ภายในองค์กรตัวเอง |
|
||||
| Submit Transmittal | Document Control, Org Admin, Superadmin | ต้องผ่าน EC-RFA-004 ก่อน |
|
||||
| แก้ไข/ยกเลิก หลัง Submit | **Org Admin ขึ้นไปเท่านั้น** พร้อมระบุเหตุผล | — |
|
||||
| ดู Transmittal ที่ Draft | เฉพาะคนในองค์กรเดียวกัน | — |
|
||||
| ดู Transmittal ที่ Submitted | ทุกคนที่มีสิทธิ์ใน Project | — |
|
||||
|
||||
---
|
||||
|
||||
## 3.7.6. Business Rules และ Edge Cases
|
||||
|
||||
| รหัส | กฎ | Severity |
|
||||
|---|---|---|
|
||||
| **EC-RFA-004** | Transmittal Submit ได้เฉพาะเมื่อ **ทุกเอกสารใน Transmittal** อยู่ในสถานะ READY (ไม่ใช่ DRAFT) — ถ้ามี DRAFT → 422 "RFA [เลข] ยังอยู่ใน Draft กรุณา Submit ก่อน" | 🟠 High |
|
||||
|
||||
ดูรายละเอียดครบที่ `01-06-edge-cases-and-rules.md` หมวด "Module 4: RFA & Drawing Edge Cases"
|
||||
|
||||
@@ -3,39 +3,101 @@
|
||||
---
|
||||
|
||||
title: 'Functional Requirements: Circulation Sheet Management'
|
||||
version: 1.8.0
|
||||
status: first-draft
|
||||
version: 1.8.1
|
||||
status: updated
|
||||
owner: Nattanin Peancharoen
|
||||
last_updated: 2026-02-23
|
||||
last_updated: 2026-03-24
|
||||
related:
|
||||
|
||||
- specs/01-requirements/01-01-objectives.md
|
||||
- specs/02-architecture/README.md
|
||||
- specs/01-requirements/01-03-modules/01-03-00-index.md
|
||||
- specs/01-requirements/01-03-modules/01-03-02-correspondence.md
|
||||
- specs/01-requirements/01-03-modules/01-03-06-unified-workflow.md
|
||||
- specs/01-requirements/01-06-edge-cases-and-rules.md (EC-CIRC-001 ถึง EC-CIRC-003, EC-CORR-001)
|
||||
- specs/03-Data-and-Storage/03-01-data-dictionary.md
|
||||
- specs/01-requirements/01-02-business-rules/01-02-01-rbac-matrix.md
|
||||
|
||||
---
|
||||
|
||||
## 3.8.1. วัตถุประสงค์:
|
||||
## 3.8.1. วัตถุประสงค์
|
||||
|
||||
- การสื่อสาร เอกสาร (Correspondence) ทุกฉบับ จะมีใบเวียนเอกสารเพื่อควบคุมและมอบหมายงานภายในองค์กร (สามารถดูและแก้ไขได้เฉพาะคนในองค์กร)
|
||||
ใบเวียนเอกสาร (Circulation Sheet) ใช้สำหรับ **มอบหมายและติดตามงานภายในองค์กร** เมื่อได้รับ Correspondence จากภายนอก — **มองเห็นและแก้ไขได้เฉพาะคนในองค์กรเดียวกัน** เท่านั้น
|
||||
|
||||
## 3.8.2. ประเภทเอกสาร:
|
||||
---
|
||||
|
||||
- ไฟล์ PDF
|
||||
## 3.8.2. โครงสร้างข้อมูล (Database Tables)
|
||||
|
||||
## 3.8.3. การสร้างเอกสาร:
|
||||
| Table | บทบาท |
|
||||
|---|---|
|
||||
| `circulations` | ข้อมูล Master: เลขใบเวียน, subject, status, organization — ผูก 1:1 กับ `correspondences` |
|
||||
| `circulation_attachments` | ไฟล์แนบเพิ่มเติม (M:N กับ `attachments`) |
|
||||
| `circulation_status_codes` | Master: สถานะใบเวียน |
|
||||
|
||||
- ผู้ใช้ที่มีสิทธิ์ในองค์กรนั้น สามารถสร้างและแก้ไขได้
|
||||
**ข้อสำคัญ:**
|
||||
- `circulations.correspondence_id` UNIQUE — 1 Correspondence มีใบเวียนได้ **1 ฉบับต่อองค์กร**
|
||||
- ใบเวียนผูกกับ `organization_id` — มองเห็นเฉพาะคนในองค์กรนั้น
|
||||
|
||||
## 3.8.4. การอ้างอิงและจัดกลุ่ม:
|
||||
---
|
||||
|
||||
- การระบุผู้รับผิดชอบ:
|
||||
- ผู้รับผิดชอบหลัก (Main): มีได้หลายคน
|
||||
- ผู้ร่วมปฏิบัติงาน (Action): มีได้หลายคน
|
||||
- ผู้ที่ต้องรับทราบ (Information): มีได้หลายคน
|
||||
## 3.8.3. Fields ที่ต้องกรอกเมื่อสร้าง Circulation
|
||||
|
||||
## 3.8.5. การติดตามงาน:
|
||||
| Field | Required | หมายเหตุ |
|
||||
|---|---|---|
|
||||
| Correspondence | ✅ | UUID — เอกสารที่ต้องการเวียน |
|
||||
| Organization | ✅ | UUID — องค์กรเจ้าของใบเวียน (auto จาก current user org) |
|
||||
| Subject (`circulation_subject`) | ✅ | VARCHAR(500) |
|
||||
| Assignees | ✅ | UUID[] — ผู้รับมอบหมาย (จัดการผ่าน Workflow context) |
|
||||
| Deadline | ❌ | สำหรับผู้รับผิดชอบประเภท Main และ Action |
|
||||
| Attachments | ❌ | ไฟล์แนบเพิ่มเติม — ผ่าน ClamAV scan |
|
||||
|
||||
- สามารถกำหนดวันแล้วเสร็จ (Deadline) สำหรับผู้รับผิดชอบประเภท Main และ Action ได้
|
||||
- มีระบบแจ้งเตือนเมื่อมี Circulation ใหม่ และแจ้งเตือนล่วงหน้าก่อนถึงวันแล้วเสร็จ
|
||||
- สามารถปิด Circulation ได้เมื่อดำเนินการตอบกลับไปยังองค์กรผู้ส่ง (Originator) แล้ว หรือ รับทราบแล้ว (For Information)
|
||||
### ประเภทผู้รับมอบหมาย (Assignee Types)
|
||||
|
||||
| ประเภท | ความหมาย | Deadline |
|
||||
|---|---|---|
|
||||
| **Main** | ผู้รับผิดชอบหลัก (มีได้หลายคน) | ✅ บังคับ |
|
||||
| **Action** | ผู้ร่วมปฏิบัติงาน (มีได้หลายคน) | ✅ บังคับ |
|
||||
| **Information** | ผู้ที่ต้องรับทราบ (มีได้หลายคน) | ❌ |
|
||||
|
||||
---
|
||||
|
||||
## 3.8.4. Status Codes (circulation_status_codes)
|
||||
|
||||
| status_code | ความหมาย |
|
||||
|---|---|
|
||||
| `OPEN` | เปิดใบเวียนแล้ว — รอดำเนินการ |
|
||||
| `IN_REVIEW` | กำลังพิจารณา |
|
||||
| `COMPLETED` | ดำเนินการเสร็จสมบูรณ์ |
|
||||
| `CANCELLED` | ยกเลิก / ถอนกลับ |
|
||||
|
||||
---
|
||||
|
||||
## 3.8.5. การสร้างและสิทธิ์ (RBAC)
|
||||
|
||||
| การกระทำ | Role ที่อนุญาต | Scope |
|
||||
|---|---|---|
|
||||
| สร้าง Circulation | Document Control, Org Admin, Superadmin | ภายในองค์กรตัวเอง |
|
||||
| แก้ไข / Re-assign | Document Control, Org Admin | ภายในองค์กรตัวเอง |
|
||||
| Force Close | Document Control, Org Admin | พร้อมระบุเหตุผล (EC-CIRC-002) |
|
||||
| ปิด Circulation (ปกติ) | ผู้ที่ถูก Assign (Main/Action) | เมื่อดำเนินการเสร็จ |
|
||||
| ดู Circulation | เฉพาะคนในองค์กรเดียวกัน | องค์กรอื่นมองไม่เห็น |
|
||||
|
||||
---
|
||||
|
||||
## 3.8.6. Workflow และ Notifications
|
||||
|
||||
- Circulation ใช้ Unified Workflow Engine (`entity_type = 'circulation'`) — ดู `01-03-06-unified-workflow.md`
|
||||
- **แจ้งเตือน:** เมื่อถูก Assign ใหม่, เมื่อใกล้ถึง Deadline, เมื่อ Overdue → Email / LINE Notify / In-App (BullMQ)
|
||||
- **Deadline Rule:** หมดเขตเมื่อ `deadline_date 23:59:59` — Overdue Badge ขึ้นเมื่อ `NOW() > deadline_date + 1 day` (EC-CIRC-003)
|
||||
|
||||
---
|
||||
|
||||
## 3.8.7. Business Rules และ Edge Cases
|
||||
|
||||
| รหัส | กฎ | Severity |
|
||||
|---|---|---|
|
||||
| **EC-CORR-001** | Cancel Correspondence ที่มี Circulation เปิดอยู่ → Force Close Circulation ทั้งหมด + Audit Log | 🔴 Critical |
|
||||
| **EC-CIRC-001** | Assignee ถูก Deactivate ก่อน Respond → Document Control สามารถ Re-assign ได้ | 🟠 High |
|
||||
| **EC-CIRC-002** | Multi-Assignee — บางคนยังไม่ Respond → Document Control Force Close ได้ พร้อมระบุเหตุผล | 🟡 Medium |
|
||||
| **EC-CIRC-003** | Deadline = Today → หมดเขต 23:59:59, Reminder 08:00, Overdue Badge วันถัดไป | 🟡 Medium |
|
||||
|
||||
ดูรายละเอียดครบที่ `01-06-edge-cases-and-rules.md` หมวด "Module 8: Circulation Edge Cases"
|
||||
|
||||
@@ -1,21 +1,116 @@
|
||||
# 3.9 Logs Management (ประวัติการแก้ไข)
|
||||
# 3.9 Logs Management (ประวัติการแก้ไข / Audit Log)
|
||||
|
||||
---
|
||||
|
||||
title: 'Functional Requirements: Logs Management'
|
||||
version: 1.8.0
|
||||
status: first-draft
|
||||
title: 'Functional Requirements: Audit Log Management'
|
||||
version: 1.8.1
|
||||
status: updated
|
||||
owner: Nattanin Peancharoen
|
||||
last_updated: 2026-02-23
|
||||
last_updated: 2026-03-24
|
||||
related:
|
||||
|
||||
- specs/01-requirements/01-01-objectives.md
|
||||
- specs/02-architecture/README.md
|
||||
- specs/01-requirements/01-03-modules/01-03-00-index.md
|
||||
- specs/01-requirements/01-06-edge-cases-and-rules.md
|
||||
- specs/03-Data-and-Storage/03-01-data-dictionary.md
|
||||
- specs/01-requirements/01-02-business-rules/01-02-01-rbac-matrix.md
|
||||
- specs/06-Decision-Records/ADR-010-logging-monitoring.md
|
||||
|
||||
---
|
||||
|
||||
## 3.9.1. วัตถุประสงค์:
|
||||
## 3.9.1. วัตถุประสงค์
|
||||
|
||||
- เพื่อ บันทึกการกระทำ CRUD ของเอกสารทั้งหมด รวมถึงการ เข้าใช้งาน ของ users
|
||||
- admin สามารถดูประวัติการแก้ไขของเอกสารทั้งหมด พร้อม จัดทำรายงายตามข้อกำหนดที่ ต้องการได้
|
||||
Audit Log บันทึก **ทุก action สำคัญ** ในระบบ — ทั้ง CRUD เอกสาร, การ Login/Logout, เหตุการณ์ Security — เพื่อ Traceability, Compliance และการ Debug ในระบบ Production
|
||||
|
||||
---
|
||||
|
||||
## 3.9.2. โครงสร้างข้อมูล (Database Table)
|
||||
|
||||
ใช้ตารางเดียว `audit_logs` ออกแบบสำหรับ **High-Volume Append-Only Write**:
|
||||
|
||||
| Column | Type | หมายเหตุ |
|
||||
|---|---|---|
|
||||
| `audit_id` | BIGINT AUTO_INCREMENT | Primary Key (ร่วมกับ `created_at` เพื่อ Partition) |
|
||||
| `request_id` | VARCHAR(100) | Trace ID เชื่อมกับ Application Log (Distributed Tracing) |
|
||||
| `user_id` | INT | ผู้กระทำ (ไม่มี FK — ป้องกัน Partition constraint) |
|
||||
| `action` | VARCHAR(100) | รหัส action เช่น `rfa.create`, `login.success` |
|
||||
| `severity` | ENUM | `INFO` / `WARN` / `ERROR` / `CRITICAL` |
|
||||
| `entity_type` | VARCHAR(50) | Module/ตาราง เช่น `rfa`, `correspondence` |
|
||||
| `entity_id` | VARCHAR(50) | Primary ID ของ record ที่ได้รับผลกระทบ |
|
||||
| `details_json` | JSON | ข้อมูล Context เพิ่มเติม |
|
||||
| `ip_address` | VARCHAR(45) | IP Address ของผู้กระทำ |
|
||||
| `user_agent` | VARCHAR(255) | Browser/Client ของผู้กระทำ |
|
||||
| `created_at` | DATETIME | เวลาที่กระทำ |
|
||||
|
||||
**Primary Key:** `(audit_id, created_at)` — รวม `created_at` เพื่อรองรับ **Partition Table**
|
||||
**ไม่มี FK** — ใช้ INDEX แทน เพื่อให้ Partition ทำงานได้ (MariaDB constraint)
|
||||
|
||||
---
|
||||
|
||||
## 3.9.3. Action Format
|
||||
|
||||
รูปแบบ: `<module>.<action>` — เช่น:
|
||||
|
||||
| action | ความหมาย |
|
||||
|---|---|
|
||||
| `login.success` / `login.failed` | เข้าสู่ระบบ |
|
||||
| `rfa.create` / `rfa.update` / `rfa.delete` | CRUD RFA |
|
||||
| `correspondence.create` / `correspondence.submit` | สร้าง / Submit Correspondence |
|
||||
| `circulation.create` / `circulation.close` / `circulation.force_close` | Circulation |
|
||||
| `drawing.upload` / `drawing.delete` | อัปโหลด / ลบ Drawing |
|
||||
| `file.virus_detected` | ClamAV พบ Virus |
|
||||
| `file.mime_mismatch` | MIME Type ไม่ตรง |
|
||||
| `user.deactivate` / `user.reactivate` | เปลี่ยนสถานะ User |
|
||||
|
||||
---
|
||||
|
||||
## 3.9.4. Severity
|
||||
|
||||
| severity | ใช้เมื่อ |
|
||||
|---|---|
|
||||
| `INFO` | ทุก CRUD ปกติ, Login สำเร็จ |
|
||||
| `WARN` | Login ล้มเหลว, Re-assign Circulation |
|
||||
| `ERROR` | ระบบ Error, Failed Transaction |
|
||||
| `CRITICAL` | File Virus Detected, Force Close Circulation, Security Event |
|
||||
|
||||
---
|
||||
|
||||
## 3.9.5. Partitioning (Performance)
|
||||
|
||||
`audit_logs` ใช้ **RANGE Partition by YEAR(created_at)**:
|
||||
|
||||
```
|
||||
p_old → ก่อน 2024
|
||||
p2024 → 2024
|
||||
p2025 → 2025
|
||||
...
|
||||
p2030 → 2030
|
||||
p_future → หลัง 2030
|
||||
```
|
||||
|
||||
- Query เฉพาะ Partition ที่เกี่ยวข้อง → ลด I/O อย่างมีนัยสำคัญ
|
||||
- Drop Partition เพื่อ Archive ข้อมูลเก่าได้โดยไม่กระทบ Production
|
||||
|
||||
---
|
||||
|
||||
## 3.9.6. RBAC
|
||||
|
||||
| การกระทำ | Role ที่อนุญาต |
|
||||
|---|---|
|
||||
| ดู Audit Log ทั้งหมด | Superadmin, Org Admin (เฉพาะ org ตัวเอง) |
|
||||
| Export / Report | Superadmin |
|
||||
| ลบ Audit Log | **ห้ามลบ** — Append-Only เสมอ |
|
||||
|
||||
---
|
||||
|
||||
## 3.9.7. กรณีที่บันทึก Audit Log บังคับ
|
||||
|
||||
| กรณี | severity | ระบุใน Edge Case |
|
||||
|---|---|---|
|
||||
| Cancel Correspondence ที่มี Circulation เปิด | `CRITICAL` | EC-CORR-001 |
|
||||
| Force Close Circulation + reason | `CRITICAL` | EC-CIRC-001, EC-CIRC-002 |
|
||||
| Re-assign Circulation (Assignee deactivated) | `WARN` | EC-CIRC-001 |
|
||||
| File Virus Detected (ClamAV) | `CRITICAL` | EC-FILE-001 |
|
||||
| File MIME Type Mismatch | `WARN` | EC-FILE-002 |
|
||||
| ทุก Login / Logout | `INFO` / `WARN` | — |
|
||||
| ทุก CRUD บน Document ทุกประเภท | `INFO` | — |
|
||||
|
||||
@@ -1,97 +1,107 @@
|
||||
# 3.12 JSON Details Management (การจัดการ JSON Details)
|
||||
# 3.10 JSON Details Management (การจัดการ JSON Details)
|
||||
|
||||
---
|
||||
|
||||
title: 'Functional Requirements: JSON Details Management'
|
||||
version: 1.8.0
|
||||
status: first-draft
|
||||
version: 1.8.1
|
||||
status: updated
|
||||
owner: Nattanin Peancharoen
|
||||
last_updated: 2026-02-23
|
||||
last_updated: 2026-03-24
|
||||
related:
|
||||
|
||||
- specs/01-requirements/01-01-objectives.md
|
||||
- specs/02-architecture/README.md
|
||||
- specs/01-requirements/01-03-modules/01-03-00-index.md
|
||||
- specs/01-requirements/01-03-modules/01-03-02-correspondence.md
|
||||
- specs/01-requirements/01-03-modules/01-03-03-rfa.md
|
||||
- specs/01-requirements/01-03-modules/01-03-06-unified-workflow.md
|
||||
- specs/03-Data-and-Storage/03-01-data-dictionary.md
|
||||
- specs/06-Decision-Records/ADR-009-db-strategy.md
|
||||
|
||||
---
|
||||
|
||||
## 3.12.1 วัตถุประสงค์
|
||||
## 3.10.1. วัตถุประสงค์
|
||||
|
||||
- จัดเก็บข้อมูลแบบไดนามิกที่เฉพาะเจาะจงกับแต่ละประเภทของเอกสาร
|
||||
- รองรับการขยายตัวของระบบโดยไม่ต้องเปลี่ยนแปลง database schema
|
||||
- จัดการ metadata และข้อมูลประกอบสำหรับ correspondence, routing, และ workflows
|
||||
ระบบใช้ `JSON` column สำหรับข้อมูลที่มีโครงสร้างแตกต่างกันตามประเภทเอกสาร โดยไม่ต้องเพิ่ม column ใหม่ใน Schema รองรับการขยายตัวโดยไม่กระทบ ADR-009 (No-migration policy)
|
||||
|
||||
## 3.12.2 โครงสร้าง JSON Schema
|
||||
---
|
||||
|
||||
- ระบบต้องมี predefined JSON schemas สำหรับประเภทเอกสารต่างๆ:
|
||||
- 3.12.2.1 Correspondence Types
|
||||
- GENERIC: ข้อมูลพื้นฐานสำหรับเอกสารทั่วไป
|
||||
- RFI: รายละเอียดคำถามและข้อมูลทางเทคนิค
|
||||
- RFA: ข้อมูลการขออนุมัติแบบและวัสดุ
|
||||
- TRANSMITTAL: รายการเอกสารที่ส่งต่อ
|
||||
- LETTER: ข้อมูลจดหมายทางการ
|
||||
- EMAIL: ข้อมูลอีเมล
|
||||
- 3.12.2.2 Rworkflow Types
|
||||
- workflow_definitions: กฎและเงื่อนไขการส่งต่อ
|
||||
- workflow_histories: สถานะและประวัติการส่งต่อ
|
||||
- workflow_instances: การดำเนินการในแต่ละขั้นตอน
|
||||
- 3.12.2.3 Audit Types
|
||||
- AUDIT_LOG: ข้อมูลการตรวจสอบ
|
||||
- SECURITY_SCAN: ผลการตรวจสอบความปลอดภัย
|
||||
## 3.10.2. JSON Columns ในระบบ (ครบทุกตาราง)
|
||||
|
||||
## 3.12.3 Virtual Columns (ปรับปรุง)
|
||||
| ตาราง | Column | วัตถุประสงค์ |
|
||||
|---|---|---|
|
||||
| `correspondence_revisions` | `details` | ข้อมูลเฉพาะตามประเภทเอกสาร (Letter, RFI ฯลฯ) |
|
||||
| `rfa_revisions` | `details` | ข้อมูลเฉพาะ RFA (เช่น drawingCount) |
|
||||
| `workflow_definitions` | `dsl` | นิยาม Workflow ต้นฉบับ (JSON DSL) |
|
||||
| `workflow_definitions` | `compiled` | Execution Tree ที่ Compile แล้ว |
|
||||
| `workflow_instances` | `context` | ตัวแปร Context สำหรับตัดสินใจ Transition |
|
||||
| `workflow_histories` | `metadata` | Snapshot ข้อมูล ณ ขณะ Transition |
|
||||
| `audit_logs` | `details_json` | ข้อมูล Context เพิ่มเติมของ Event |
|
||||
| `document_numbers` | `counter_key` | Counter key (8 fields) สำหรับ Document Numbering |
|
||||
| `document_numbers` | `metadata` | Additional context ของการออกเลข |
|
||||
| `document_number_errors` | `context_data` | Context ของ request ที่เกิด error |
|
||||
| `json_schemas` | `schema_definition` | JSON Schema (AJV Standard) |
|
||||
| `json_schemas` | `ui_schema` | UI Schema สำหรับ Frontend render |
|
||||
| `json_schemas` | `virtual_columns` | Config สำหรับสร้าง Virtual Columns |
|
||||
| `json_schemas` | `migration_script` | Script แปลงข้อมูลระหว่าง versions |
|
||||
|
||||
- สำหรับ Field ใน JSON ที่ต้องใช้ในการค้นหา (Search) หรือจัดเรียง (Sort) บ่อยๆ ต้องสร้าง Generated Column (Virtual Column) ใน Database และทำ Index ไว้ เพื่อประสิทธิภาพสูงสุด
|
||||
- Schema Consistency: Field ที่ถูกกำหนดเป็น Virtual Column ห้าม เปลี่ยนแปลง Key Name หรือ Data Type ใน JSON Schema Version ถัดไป หากจำเป็นต้องเปลี่ยน ต้องมีแผนการ Re-index หรือ Migration ข้อมูลเดิมที่ชัดเจน
|
||||
---
|
||||
|
||||
## 3.12.4 Validation Rules
|
||||
## 3.10.3. JSON Schema Registry (json_schemas)
|
||||
|
||||
- ต้องมี JSON schema validation สำหรับแต่ละประเภท
|
||||
- ต้องรองรับ versioning ของ schema
|
||||
- ต้องมี default values สำหรับ field ที่ไม่บังคับ
|
||||
- ต้องตรวจสอบ data types และ format ให้ถูกต้อง
|
||||
ระบบมีตาราง `json_schemas` เป็น **Centralized Registry** สำหรับ validate และ manage โครงสร้าง JSON:
|
||||
|
||||
## 3.12.5 Performance Requirements
|
||||
| Field | หมายเหตุ |
|
||||
|---|---|
|
||||
| `schema_code` | รหัส Schema เช่น `RFA_DWG`, `CORRESPONDENCE_LETTER` |
|
||||
| `version` | Version ของ Schema (UNIQUE ร่วมกับ `schema_code`) |
|
||||
| `table_name` | ตารางเป้าหมาย เช่น `rfa_revisions` |
|
||||
| `schema_definition` | โครงสร้าง AJV JSON Schema สำหรับ validation |
|
||||
| `ui_schema` | โครงสร้าง UI Schema สำหรับ Frontend render dynamic form |
|
||||
| `virtual_columns` | Config สำหรับสร้าง Generated Columns |
|
||||
| `migration_script` | Script แปลงข้อมูลจาก version ก่อนหน้า |
|
||||
|
||||
- JSON field ต้องมีขนาดไม่เกิน 50KB
|
||||
- ต้องรองรับ indexing สำหรับ field ที่ใช้ค้นหาบ่อย
|
||||
- ต้องมี compression สำหรับ JSON ขนาดใหญ่
|
||||
---
|
||||
|
||||
## 3.12.6 Security Requirements
|
||||
## 3.10.4. Virtual Columns (Generated Columns)
|
||||
|
||||
- ต้อง sanitize JSON input เพื่อป้องกัน injection attacks
|
||||
- ต้อง validate JSON structure ก่อนบันทึก
|
||||
- ต้อง encrypt sensitive data ใน JSON fields
|
||||
JSON field ที่ต้องใช้ใน Query / Search สร้างเป็น **Generated Virtual Column** + Index:
|
||||
|
||||
## 3.12.7 JSON Schema Migration Strategy (เพิ่มเติม)
|
||||
| ตาราง | Virtual Column | JSON Path | ใช้สำหรับ |
|
||||
|---|---|---|---|
|
||||
| `correspondence_revisions` | `v_ref_project_id` | `$.projectId` | Filter by Project |
|
||||
| `correspondence_revisions` | `v_doc_subtype` | `$.subType` | Filter by Sub-type |
|
||||
| `rfa_revisions` | `v_ref_drawing_count` | `$.drawingCount` | Count / Sort |
|
||||
|
||||
- สำหรับ Schema Breaking Changes:
|
||||
- Phase 1 - Add New Column
|
||||
ALTER TABLE correspondence_revisions
|
||||
ADD COLUMN ref_project_id_v2 INT GENERATED ALWAYS AS
|
||||
(JSON_UNQUOTE(JSON_EXTRACT(details, '$.newProjectIdPath'))) VIRTUAL;
|
||||
**กฎสำคัญ:** Field ที่เป็น Virtual Column **ห้ามเปลี่ยน JSON key หรือ data type** ใน version ถัดไป — ต้องมีแผน Re-index / Migration ก่อน
|
||||
|
||||
- Phase 2 - Backfill Old Records
|
||||
- ใช้ background job แปลง JSON format เก่าเป็นใหม่
|
||||
- Update `details` JSON ทีละ batch (1000 records)
|
||||
- Phase 3 - Switch Application Code
|
||||
- Deploy code ที่ใช้ path ใหม่
|
||||
- Phase 4 - Remove Old Column
|
||||
- หลังจาก verify แล้วว่าไม่มี error
|
||||
- Drop old virtual column
|
||||
---
|
||||
|
||||
- สำหรับ Non-Breaking Changes
|
||||
- เพิ่ม optional field ใน schema
|
||||
- Old records ที่ไม่มี field = ใช้ default value
|
||||
## 3.10.5. Validation Rules
|
||||
|
||||
## 3.13. ข้อกำหนดพิเศษ
|
||||
- Backend validate ด้วย `json_schemas.schema_definition` (AJV Standard) ก่อน save ทุกครั้ง
|
||||
- แต่ละ record มี `schema_version` — ใช้เลือก schema ที่ถูกต้องสำหรับ validate
|
||||
- Field ไม่บังคับ → ใช้ `default` value ตามที่กำหนดใน schema
|
||||
- Sanitize JSON input เพื่อป้องกัน injection ก่อน validate
|
||||
|
||||
- ผู้ใช้งานที่มีสิทธิ์ระดับสูง (Global) หรือผู้ได้รับอนุญาตเป็นกรณีพิเศษ
|
||||
- สามารถเลือก สร้างในนามองค์กร (Create on behalf of) ได้ เพื่อให้สามารถออกเลขที่เอกสาร (Running Number) ขององค์กรอื่นได้โดยไม่ต้องล็อกอินใหม่
|
||||
- สามารถทำงานแทนผู้ใช้งานอื่นได้ Routing & Workflow ของ Correspondence, RFA, Circulation Sheet
|
||||
---
|
||||
|
||||
## 3.14. การจัดการข้อมูลหลักขั้นสูง (Master Data Management)
|
||||
## 3.10.6. JSON Schema Migration Strategy
|
||||
|
||||
- 3.14.1. Disciplines Management: Admin ต้องสามารถ เพิ่ม/ลบ/แก้ไข สาขางาน (Disciplines) แยกตามสัญญา (Contract) ได้
|
||||
- 3.14.2. Sub-Type Mapping: Admin ต้องสามารถกำหนด Correspondence Sub-types และ Mapping รหัสตัวเลข (เช่น MAT = 11) ได้
|
||||
- 3.14.3. Numbering Format Configuration: ระบบต้องรองรับการตั้งค่า Format Template ของแต่ละ Project/Type ได้โดยไม่ต้องแก้โค้ด
|
||||
### Breaking Changes (เปลี่ยน key / type)
|
||||
|
||||
1. **Phase 1 — Add New Virtual Column** ด้วย path ใหม่
|
||||
2. **Phase 2 — Backfill Old Records** ด้วย background job (batch 1,000 records)
|
||||
3. **Phase 3 — Deploy Application Code** ที่ใช้ path ใหม่
|
||||
4. **Phase 4 — Drop Old Column** หลัง verify ไม่มี error
|
||||
|
||||
### Non-Breaking Changes (เพิ่ม optional field)
|
||||
|
||||
- เพิ่ม field ใน schema definition — old records ที่ไม่มี field ใช้ `default` value อัตโนมัติ
|
||||
- ไม่ต้อง backfill
|
||||
|
||||
---
|
||||
|
||||
> **หมายเหตุ:** เนื้อหาเดิม §3.13 (Impersonation) และ §3.14 (Master Data Management) ได้ถูกย้ายไปยัง spec ที่เกี่ยวข้องแล้ว:
|
||||
> - Impersonation → `01-02-01-rbac-matrix.md`
|
||||
> - Disciplines Management → `01-03-01-project-management.md` (§3.1.6)
|
||||
> - Numbering Format → Document Numbering spec
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
---
|
||||
|
||||
**Project:** LCBP3-DMS (Laem Chabang Port Phase 3 - Document Management System)
|
||||
**Version:** 1.8.0
|
||||
**Last Updated:** 2025-12-02
|
||||
**Version:** 1.8.4
|
||||
**Last Updated:** 2026-03-24
|
||||
**Owner:** Operations Team
|
||||
**Status:** Active
|
||||
|
||||
@@ -12,15 +12,15 @@
|
||||
|
||||
## 📋 Overview
|
||||
|
||||
This guide provides step-by-step instructions for deploying the LCBP3-DMS system on QNAP Container Station using Docker Compose with Blue-Green deployment strategy.
|
||||
This guide provides step-by-step instructions for deploying the LCBP3-DMS system on QNAP Container Station using Docker Compose.
|
||||
|
||||
### Deployment Strategy
|
||||
|
||||
- **Platform:** QNAP TS-473A with Container Station
|
||||
- **Orchestration:** Docker Compose
|
||||
- **Deployment Method:** Blue-Green Deployment
|
||||
- **Zero Downtime:** Yes
|
||||
- **Rollback Capability:** Instant rollback via NGINX switch
|
||||
- **Deployment Method:** Direct deploy with `--force-recreate` (replaces previous blue-green approach)
|
||||
- **Automation:** Gitea Actions → `appleboy/ssh-action` → `scripts/deploy.sh`
|
||||
- **Rollback:** Re-trigger previous commit via Gitea Actions
|
||||
|
||||
---
|
||||
|
||||
@@ -67,17 +67,14 @@ Create the following directory structure on QNAP:
|
||||
# SSH into QNAP
|
||||
ssh admin@qnap-ip
|
||||
|
||||
# Create base directory
|
||||
mkdir -p /volume1/lcbp3
|
||||
# Create base directories
|
||||
mkdir -p /share/np-dms/app/logs
|
||||
mkdir -p /share/np-dms/app/uploads
|
||||
|
||||
# Create blue-green environments
|
||||
mkdir -p /volume1/lcbp3/blue
|
||||
mkdir -p /volume1/lcbp3/green
|
||||
|
||||
# Create shared directories
|
||||
mkdir -p /volume1/lcbp3/shared/uploads
|
||||
mkdir -p /volume1/lcbp3/shared/logs
|
||||
mkdir -p /volume1/lcbp3/shared/backups
|
||||
# Clone source repository (first time only)
|
||||
mkdir -p /share/np-dms/app/source
|
||||
cd /share/np-dms/app/source
|
||||
git clone https://git.np-dms.work/np-dms/lcbp3.git
|
||||
|
||||
# Create persistent volumes
|
||||
mkdir -p /volume1/lcbp3/volumes/mariadb-data
|
||||
@@ -92,43 +89,23 @@ chmod -R 755 /volume1/lcbp3
|
||||
chown -R admin:administrators /volume1/lcbp3
|
||||
```
|
||||
|
||||
**Final Structure:**
|
||||
**Directory Structure:**
|
||||
|
||||
```
|
||||
/volume1/lcbp3/
|
||||
├── blue/ # Blue environment
|
||||
│ ├── docker-compose.yml
|
||||
│ ├── .env.production
|
||||
│ └── nginx.conf
|
||||
/share/np-dms/app/
|
||||
├── source/
|
||||
│ └── lcbp3/ # Git repository (auto-synced by CI)
|
||||
│ ├── backend/
|
||||
│ ├── frontend/
|
||||
│ ├── scripts/
|
||||
│ │ ├── deploy.sh # Deployment script v2.0
|
||||
│ │ └── rollback.sh
|
||||
│ └── specs/04-Infrastructure-OPS/04-00-docker-compose/
|
||||
│ └── docker-compose-app.yml # Compose file used for deployment
|
||||
│
|
||||
├── green/ # Green environment
|
||||
│ ├── docker-compose.yml
|
||||
│ ├── .env.production
|
||||
│ └── nginx.conf
|
||||
│
|
||||
├── nginx-proxy/ # Main reverse proxy
|
||||
│ ├── docker-compose.yml
|
||||
│ ├── nginx.conf
|
||||
│ └── ssl/
|
||||
│ ├── cert.pem
|
||||
│ └── key.pem
|
||||
│
|
||||
├── shared/ # Shared across blue/green
|
||||
│ ├── uploads/
|
||||
│ ├── logs/
|
||||
│ └── backups/
|
||||
│
|
||||
├── volumes/ # Persistent data
|
||||
│ ├── mariadb-data/
|
||||
│ ├── redis-data/
|
||||
│ └── elastic-data/
|
||||
│
|
||||
├── scripts/ # Deployment scripts
|
||||
│ ├── deploy.sh
|
||||
│ ├── rollback.sh
|
||||
│ └── health-check.sh
|
||||
│
|
||||
└── current # File containing "blue" or "green"
|
||||
├── .env # Single environment config file
|
||||
├── logs/ # Deployment logs
|
||||
└── uploads/ # Persistent file uploads
|
||||
```
|
||||
|
||||
### 2. SSL Certificate Setup
|
||||
@@ -160,10 +137,10 @@ cp /etc/letsencrypt/live/lcbp3-dms.example.com/privkey.pem \
|
||||
|
||||
### 1. Environment Variables (.env.production)
|
||||
|
||||
Create `.env.production` in both `blue/` and `green/` directories:
|
||||
Create `.env` at `/share/np-dms/app/.env`:
|
||||
|
||||
```bash
|
||||
# File: /volume1/lcbp3/blue/.env.production
|
||||
# File: /share/np-dms/app/.env
|
||||
# DO NOT commit this file to Git!
|
||||
|
||||
# Application
|
||||
|
||||
Reference in New Issue
Block a user