192 lines
9.8 KiB
Markdown
192 lines
9.8 KiB
Markdown
# 3.2 การจัดการเอกสารโต้ตอบ (Correspondence Management)
|
||
|
||
---
|
||
|
||
title: 'Functional Requirements: Correspondence Management'
|
||
version: 1.8.2
|
||
status: implemented
|
||
owner: Nattanin Peancharoen
|
||
last_updated: 2026-03-24
|
||
related:
|
||
|
||
- specs/01-requirements/01-01-objectives.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. วัตถุประสงค์
|
||
|
||
เอกสารโต้ตอบ (Correspondence) คือ **โครงสร้างข้อมูลหลัก (Parent)** ของเอกสารทุกประเภทในระบบ — ทั้ง RFA, RFI, Transmittal, Letter ฯลฯ เป็นการสื่อสารระหว่างองค์กร-องค์กร ภายในโครงการ (Project) รองรับผู้รับหลัก (TO) และผู้รับสำเนา (CC) ได้หลายองค์กร
|
||
|
||
---
|
||
|
||
## 3.2.2. โครงสร้างข้อมูล (Database Tables)
|
||
|
||
| 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) |
|
||
|
||
**ข้อสำคัญ:** `correspondence_number` ต้อง UNIQUE ภายใน Project เดียวกัน (`uq_corr_no_per_project`)
|
||
|
||
---
|
||
|
||
## 3.2.3. ประเภทเอกสาร (correspondence_types)
|
||
|
||
ประเภทเป็น Global Master — จัดการโดย Superadmin เท่านั้น:
|
||
|
||
| 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"
|
||
|
||
---
|
||
|
||
## 3.2.11. Implementation Status (v1.8.2)
|
||
|
||
| Feature | Status | หมายเหตุ |
|
||
|---|---|---|
|
||
| Create/Update/List/Detail Correspondence | ✅ Done | Phase 1 |
|
||
| File Attachments (two-phase upload) | ✅ Done | Phase 2 |
|
||
| Recipients (TO/CC), Submit Workflow | ✅ Done | Phase 3 |
|
||
| Elasticsearch Indexing | ✅ Done | Phase 4 |
|
||
| Cancel + In-App Notifications (cancel/submit) | ✅ Done | Phase 4 |
|
||
| Reference Selector (outgoing/incoming) | ✅ Done | Phase 5 |
|
||
| Tag Manager (assign/remove tags) | ✅ Done | Phase 5–6 |
|
||
| Search `/search` — status filter + pagination | ✅ Done | Phase 6.1 |
|
||
| Circulation Status Card in detail sidebar | ✅ Done | Phase 6.2 |
|
||
| Revision History UI (timeline) | ✅ Done | Phase 6.3 |
|
||
| Due Date Reminder (`@Cron` daily at 08:00) | ✅ Done | Phase 6.4 |
|
||
| Email notification via Nodemailer/BullMQ | ✅ Done | Phase 7.1 — type `'EMAIL'` → NotificationProcessor sends Nodemailer |
|
||
| Unit tests (service layer ≥ 80%) | ✅ Done | Phase 7.2 — 8 backend + 5 frontend tests |
|
||
| Bulk operations (bulk cancel/export) | ✅ Done | Phase 7.3 — `POST /bulk-cancel`, `GET /export-csv`, CSV button |
|