Files
lcbp3/specs/01-requirements/01-03-modules/01-03-02-correspondence.md
T
admin 7231870e02
CI / CD Pipeline / build (push) Successful in 22m7s
CI / CD Pipeline / deploy (push) Failing after 9m6s
690331:1259 Correspondence Page Refactor by GPT-5.3-Codex Medium #01
2026-03-31 12:59:30 +07:00

211 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 3.2 การจัดการเอกสารโต้ตอบ (Correspondence Management)
---
title: 'Functional Requirements: Correspondence Management'
version: 1.8.3
status: implemented
owner: Nattanin Peancharoen
last_updated: 2026-03-31
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_revision_attachments` | ไฟล์แนบต่อ Revision (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`
### Frontend Routing & Filtering (v1.8.3)
- รายการเอกสารใช้หน้าเดียวที่ `/correspondences`
- กรองประเภทผ่าน query string `?type=<TYPE_CODE>` เช่น `/correspondences?type=RFA`
- เส้นทาง list เดิมของ RFA (`/rfas` และ `/rfa`) redirect มาหน้าเดียวข้างต้น
- หน้า RFA เฉพาะทาง `/rfas/new`, `/rfas/[uuid]`, `/rfas/[uuid]/edit` ยังแยกจาก Correspondence เพื่อรองรับ extension logic
### UX Flow Diagram (v1.8.3)
- หน้า `/correspondences` มีปุ่ม `UX Flow` เพื่อแสดง lifecycle ของ Correspondence
- เนื้อหาครอบคลุม Master-Revision pattern, two-phase attachment, และ RFA extension path
- เอกสารอ้างอิง implementation อยู่ที่ `specs/01-requirements/01-03-modules/01-03-02a-correspondence-rfa-unified-ux-flow.md`
---
## 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_number`: 0-based integer สำหรับ sorting
- `revision_label`: กำหนดตามประเภทเอกสารดังนี้:
| Type | Initial Label | ลำดับถัดไป | Format |
|------|--------------|------------|--------|
| **RFA, RFI** | `A` | B, C, D... | Alphabet |
| **LETTER, MEMO, TRANSMITTAL, EMAIL, INSTRUCTION, NOTICE, MOM, OTHER** | `null` | 1, 2, 3... | Numeric |
**หมายเหตุ:** Shop Drawing และ As-Built Drawing ใช้ revision label แยกตามกฎของ Drawing Module (numeric '0', '1', '2'... หรือ user กำหนดเอง)
---
## 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 56 |
| 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 |