diff --git a/01_lcbp3_v1_4_1.sql b/01_lcbp3_v1_4_1.sql index 3193fda..1897531 100644 --- a/01_lcbp3_v1_4_1.sql +++ b/01_lcbp3_v1_4_1.sql @@ -1856,7 +1856,6 @@ CREATE INDEX idx_notifications_created_at ON notifications(created_at); -- Indexes for search_indices CREATE INDEX idx_search_indices_entity ON search_indices(entity_type, entity_id); CREATE INDEX idx_search_indices_indexed_at ON search_indices(indexed_at); -CREATE FULLTEXT INDEX idx_search_indices_content ON search_indices(content); -- Indexes for backup_logs CREATE INDEX idx_backup_logs_type ON backup_logs(backup_type); CREATE INDEX idx_backup_logs_status ON backup_logs(status); diff --git a/Documnets/0.html b/Documnets/0.html new file mode 100644 index 0000000..c873072 --- /dev/null +++ b/Documnets/0.html @@ -0,0 +1,483 @@ + + + + + + LCBP3-DMS V1.4.1 Project Infographic + + + + + + + +
+ +
+ +
+ +
+
+

Project Overview: LCBP3 Document Management System (V1.4.1)

+
+
+

+ นี่คือภาพรวมของระบบบริหารจัดการเอกสารโครงการ (DMS) V1.4.1 + ที่กำลังพัฒนาสำหรับโครงการแหลมฉบังเฟส 3 (LCBP3) + เป้าหมายหลักคือการสร้างเว็บแอปพลิเคชั่นที่ทันสมัย ปลอดภัย + และมีประสิทธิภาพสูงเพื่อจัดการและควบคุมการสื่อสารด้วยเอกสารที่ซับซ้อน + ลดการใช้กระดาษ และเพิ่มความสะดวกในการทำงานร่วมกันระหว่างองค์กร +

+
+
+ +
+

Key Performance Indicators (KPIs)

+
+
+

API Response Time

+

< 200ms

+

(90th Percentile)

+
+
+

Search Performance

+

< 500ms

+

(Elasticsearch)

+
+
+

File Upload (50MB)

+

< 30s

+

(Inc. Virus Scan)

+
+
+

Cache Hit Ratio

+

> 80%

+

(Redis)

+
+
+
+ +
+
+

System Architecture & Technology Stack

+
+
+

+ สถาปัตยกรรมระบบเป็นแบบ API-First ที่ทำงานบน QNAP Container Station (Docker) + โดยมีการแบ่งส่วนบริการ (Services) อย่างชัดเจน + เพื่อความสะดวกในการจัดการและบำรุงรักษา +

+ +
+
+
Internet User
+ +
+
QNAP (WAN)
+ +
+
Nginx Proxy Manager
+
+ +
+ +
+
+

Public Facing Services (ผ่าน NPM)

+
+
Frontend (Next.js)
+
Backend (NestJS)
+
Gitea (Git)
+
n8n (Automation)
+
+
+ +
+

Internal Services (Backend เรียกใช้)

+
+
MariaDB (Database)
+
Redis (Cache)
+
Elasticsearch (Search)
+
ClamAV (Virus Scan)
+
+
+
+
+
+
+ +
+
+
+

Development Roadmap

+
+
+

+ แผนการพัฒนาถูกแบ่งออกเป็น Phase (Backend) และ Sprints (Frontend) + เพื่อให้สามารถส่งมอบงานได้อย่างต่อเนื่องและเป็นระบบ +

+
+
+

Backend (NestJS)

+
+
+
+

Phase 0-1: Setup & Core

+

Infrastructure, DB Schema, ORM

+
+
+
+

Phase 2-3: Auth & RBAC

+

JWT, Passport, CASL 4-Level

+
+
+
+

Phase 4-5: Core Features

+

Document Upload, RFA Workflow

+
+
+
+

Phase 6-8: Integration & Deploy

+

Search, Cache, Notification, Deploy

+
+
+
+
+

Frontend (Next.js)

+
+
+
+

Sprint 1-2: Setup & Auth

+

shadcn/ui, NextAuth, Layout

+
+
+
+

Sprint 3: Dashboard

+

Charts (Recharts), KPIs

+
+
+
+

Sprint 4-5: Document Module

+

TanStack Table, Upload, Search

+
+
+
+

Sprint 6-7: Workflow & Deploy

+

RFA Forms, Testing, Deploy

+
+
+
+
+
+
+ +
+
+

Feature Focus: 4-Level RBAC

+
+
+

+ ระบบควบคุมสิทธิ์ (RBAC) เป็นหัวใจสำคัญของความปลอดภัย + โดยใช้สถาปัตยกรรม 4 ระดับ (4-Level) เพื่อการควบคุมที่ละเอียดสูงสุด +

+
+ 🌍 Level 1: Global +

(Super Admin, System Settings)

+ +
+ 🏢 Level 2: Organization +

(Org Admin, Manage Users & Projects)

+ +
+ 🏗️ Level 3: Project +

(Project Manager, View All Project Docs)

+ +
+ 📄 Level 4: Contract +

(Contractor, Access Own Contract Docs Only)

+
+
+
+
+
+
+
+ +
+
+

Document Statistics (Mockup Data)

+
+
+

+ Dashboard จะแสดงสถิติเอกสารแบบ Real-time + (อ้างอิงจาก View: `v_document_statistics` ในฐานข้อมูล) + เพื่อช่วยในการติดตามและบริหารจัดการโครงการ +

+
+
+

เอกสารตามประเภท (By Type)

+

+ แสดงจำนวนเอกสารทั้งหมดโดยแบ่งตามประเภทหลัก + ช่วยให้เห็นภาพรวมของเอกสารในระบบ +

+
+ +
+
+
+

สถานะเอกสาร (By Status)

+

+ แสดงสัดส่วนของสถานะเอกสารในปัจจุบัน + (เช่น ร่าง, รออนุมัติ, อนุมัติแล้ว) เพื่อติดตาม Workflow +

+
+ +
+
+
+
+
+ +
+ + + + + + \ No newline at end of file diff --git a/Documnets/Git_command.md b/Documnets/Git_command.md new file mode 100644 index 0000000..4b27f25 --- /dev/null +++ b/Documnets/Git_command.md @@ -0,0 +1,220 @@ +# **คำสั่งตั้งค่า Gitea ใหม่ทั้งหมด + คำสั่งใช้งานประจำวัน / แก้ปัญหา / branch”** + +--- + +📘 Git + Gitea (QNAP / Container Station) – Cheat Sheet +คู่มือนี้รวบรวม: + +- คำสั่งตั้งค่า Gitea ใหม่ทั้งหมด +- คำสั่งใช้งาน Git ประจำวัน +- การแก้ไขปัญหา repository +- การทำงานกับ branch +- การ reset / clone / merge / rebase + +--- + +## 🧩 SECTION 1 – การตั้งค่า Gitea ใหม่ทั้งหมด + +🔹 1) เคลียร์ host key เดิม ใช้เมื่อ Gitea ถูก reset ใหม่ หรือ IP / key เปลี่ยน + +```bash +ssh-keygen -R "[git.np-dms.work]:2222" +``` + +🔹 2) เชื่อมต่อครั้งแรก (จะมีคำถาม fingerprint) + +```bash +ssh -T git@git.np-dms.work -p 2222 +``` + +🔹 3) แสดง SSH public key เพื่อเพิ่มใน Gitea + +```bash +cat /root/.ssh/id_ed25519.pub +cat /root/.ssh/id_rsa.pub +``` + +🔹 4) เพิ่ม remote ใหม่ (หากยังไม่ได้เพิ่ม) + +```bash +git remote add origin ssh://git@git.np-dms.work:2222/np-dms/lcbp3.git +``` + +🔹 5) ลบ remote เดิมหากผิด + +```bash +git remote remove origin +``` + +🔹 6) Push ครั้งแรกหลังตั้งค่า + +```bash +git push -u origin main +``` + +🔹 7) Clone repo ใหม่ทั้งหมด + +```bash +git clone ssh://git@git.np-dms.work:2222/np-dms/lcbp3.git +``` + +--- + +## 🧩 SECTION 2 – คำสั่ง Git ใช้งานประจำวัน + +🟦 ตรวจสอบสถานะงาน + +```bash +git status +``` + +🟦 ดูว่าแก้ไฟล์อะไรไป + +```bash +git diff +``` + +🟦 เพิ่มไฟล์ทั้งหมด + +```bash +git add . +``` + +🟦 Commit การแก้ไข + +```bash +git commit -m "message" +``` + +🟦 Push + +```bash +git push +``` + +🟦 Pull (ดึงงานล่าสุด) + +```bash +git pull +``` + +--- +## 🧩 SECTION 3 – ทำงานกับ Branch + +### ดู branch ทั้งหมด + +```bash +git branch +``` + +### สร้าง branch ใหม่ + +```bash +git checkout -b feature/login-page +``` + +### สลับ branch + +```bash +git checkout main +``` + +### ส่ง branch ขึ้น Gitea + +```bash +git push -u origin feature/login-page +``` + +### ลบ branch ในเครื่อง + +```bash +git branch -d feature/login-page +``` + +### ลบ branch บน Gitea + +```bash +git push origin --delete feature/login-page +``` + +### Merge branch → main + +```bash +git checkout main +git pull +git merge feature/login-page +git push +``` + +### Rebase เพื่อให้ history สวย + +```bash +git checkout feature/login-page +git rebase main +git checkout main +git merge feature/login-page +git push +``` + +--- + +## 🧩 SECTION 4 – แก้ไขปัญหา Repo + +🔴 (1) Reset repo ทั้งหมดให้เหมือน remote + +⚠ ใช้เมื่อไฟล์ในเครื่องพัง หรือแก้จนเละ + +```bash +git fetch --all +git reset --hard origin/main +``` + +🔴 (2) แก้ปัญหา conflict ตอน pull + +```bash +git pull --rebase +``` + +🔴 (3) ดู remote ว่าชี้ไปทางไหน + +```bash +git remote -v +``` + +🔴 (4) เปลี่ยน remote ใหม่ + +```bash +git remote remove origin +git remote add origin ssh://git@git.np-dms.work:2222/np-dms/lcbp3.git +``` + +🔴 (5) Commit message ผิด แก้ใหม่ + +```bash +git commit --amend +``` + +🔴 (6) ย้อน commit ล่าสุด (ไม่ลบไฟล์) + +```bash +git reset --soft HEAD~1 +``` + +🔴 (7) ดู log แบบสรุป + +```bash +git log --oneline --graph +``` + +🔴 (8) Clone repo ใหม่ทั้งหมด (เมื่อพังหนัก) + +```bash +rm -rf lcbp3 +git clone ssh://git@git.np-dms.work:2222/np-dms/lcbp3.git +``` + +--- + +## 📌 END + +``` diff --git a/Documnets/Gitea_setting.md b/Documnets/Gitea_setting.md new file mode 100644 index 0000000..6791bab --- /dev/null +++ b/Documnets/Gitea_setting.md @@ -0,0 +1,91 @@ +# การติดตั้ง Gitea ใน Docker + +* user id ของ gites: + + * uid=1000(git) gid=1000(git) groups=1000(git) + +## กำหนดสิทธิ + +```bash +chown -R 1000:1000 /share/Container/gitea/ +[/share/Container/git] # ls -l /share/Container/gitea/etc/app.ini +[/share/Container/git] # setfacl -R -m u:1000:rwx /share/Container/gitea/ +[/share/Container/git] # setfacl -R -m u:70:rwx /share/Container/git/postgres/ +getfacl /share/Container/git/etc/app.ini +chown -R 1000:1000 /share/Container/gitea/ +ล้าง +setfacl -R -b /share/Container/gitea/ + +chgrp -R administrators /share/Container/gitea/ +chown -R 1000:1000 /share/Container/gitea/etc /share/Container/gitea/lib /share/Container/gitea/backup +setfacl -m u:1000:rwx -m g:1000:rwx /share/Container/gitea/etc /share/Container/gitea/lib /share/Container/gitea/backup +``` + +## Docker file + +```yml +# File: share/Container/git/docker-compose.yml +# DMS Container v1_4_1 : แยก service และ folder, Application name: git, Servive:gitea +networks: + lcbp3: + external: true + giteanet: + external: true + name: gitnet + +services: + gitea: + image: gitea/gitea:latest-rootless + container_name: gitea + restart: always + stdin_open: true + tty: true + environment: + # ---- File ownership in QNAP ---- + USER_UID: "1000" + USER_GID: "1000" + TZ: Asia/Bangkok + # ---- Server / Reverse proxy (NPM) ---- + GITEA__server__ROOT_URL: https://git.np-dms.work/ + GITEA__server__DOMAIN: git.np-dms.work + GITEA__server__SSH_DOMAIN: git.np-dms.work + GITEA__server__START_SSH_SERVER: "true" + GITEA__server__SSH_PORT: "22" + GITEA__server__SSH_LISTEN_PORT: "22" + GITEA__server__LFS_START_SERVER: "true" + GITEA__server__HTTP_ADDR: "0.0.0.0" + GITEA__server__HTTP_PORT: "3000" + GITEA__server__TRUSTED_PROXIES: "127.0.0.1/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16" + # --- การตั้งค่าฐานข้อมูล + GITEA__database__DB_TYPE: mysql + GITEA__database__HOST: mariadb:3306 + GITEA__database__NAME: "gitea" + GITEA__database__USER: "gitea" + GITEA__database__PASSWD: "Center#2025" + # --- repos + GITEA__repository__ROOT: /var/lib/gitea/git/repositories + DISABLE_HTTP_GIT: "false" + ENABLE_BASIC_AUTHENTICATION: "true" + # --- Enable Package Registry --- + GITEA__packages__ENABLED: "true" + GITEA__packages__REGISTRY__ENABLED: "true" + GITEA__packages__REGISTRY__STORAGE_TYPE: local + GITEA__packages__REGISTRY__STORAGE_PATH: /data/registry + # Optional: lock install after setup (เปลี่ยนเป็น true เมื่อจบ onboarding) + GITEA__security__INSTALL_LOCK: "true" + volumes: + - /share/Container/gitea/backup:/backup + - /share/Container/gitea/etc:/etc/gitea + - /share/Container/gitea/lib:/var/lib/gitea + # ให้ repo root ใช้จาก /share/dms-data/gitea_repos + - /share/dms-data/gitea_repos:/var/lib/gitea/git/repositories + - /share/dms-data/gitea_registry:/data/registry + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + ports: + - "3003:3000" # HTTP (ไปหลัง NPM) + - "2222:22" # SSH สำหรับ git clone/push + networks: + - lcbp3 + - giteanet +``` diff --git a/Documnets/MariaDB_setting.md b/Documnets/MariaDB_setting.md new file mode 100644 index 0000000..4c5babe --- /dev/null +++ b/Documnets/MariaDB_setting.md @@ -0,0 +1,138 @@ +# การติดตั้ง MAriaDB และ PHPMyAdmin ใน Docker + +* user id ของ mariadb: + + * uid=0(root) gid=0(root) groups=0(root) + +## กำหนดสิทธิ + +```bash +chown -R 999:999 /share/Container/mariadb/init +chmod 755 /share/Container/mariadb/init +setfacl -R -m u:999:r-x /share/Container/mariadb/init +setfacl -R -d -m u:999:r-x /share/Container/mariadb/init + +chown -R 33:33 /share/Container/pma/tmp +chmod 755 /share/Container/pma/tmp +setfacl -R -m u:33:rwx /share/Container/pma/tmp +setfacl -R -d -m u:33:rwx /share/Container/pma/tmp + +chown -R 33:33 /share/dms-data/logs/pma +chmod 755 /share/dms-data/logs/pma +setfacl -R -m u:33:rwx /share/dms-data/logs/pma +setfacl -R -d -m u:33:rwx /share/dms-data/logs/pma + +setfacl -R -m u:1000:rwx /share/Container/gitea +setfacl -R -m u:1000:rwx /share/dms-data/gitea_repos +setfacl -R -m u:1000:rwx /share/dms-data/gitea_registry +``` + +## เพิ่ม database & user สำหรับ Nginx Proxy Manager (NPM) + +```bash +docker exec -it mariadb mysql -u root -p + CREATE DATABASE npm; + CREATE USER 'npm'@'%' IDENTIFIED BY 'npm'; + GRANT ALL PRIVILEGES ON npm.* TO 'npm'@'%'; + FLUSH PRIVILEGES; +``` + +## เพิ่ม database & user สำหรับ Gitea + +```bash +docker exec -it mariadb mysql -u root -p + CREATE DATABASE gitea CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_unicode_ci'; + CREATE USER 'gitea'@'%' IDENTIFIED BY 'Center#2025'; + GRANT ALL PRIVILEGES ON gitea.* TO 'gitea'@'%'; + FLUSH PRIVILEGES; +``` + +## Docker file + +```yml +# File: share/Container/mariadb/docker-compose.yml +# DMS Container v1_4_1 : แยก service และ folder,Application name: lcbp3-db, Servive: mariadb, pma +x-restart: &restart_policy + restart: unless-stopped + +x-logging: &default_logging + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "5" + +services: + mariadb: + <<: [*restart_policy, *default_logging] + image: mariadb:11.8 + container_name: mariadb + stdin_open: true + tty: true + deploy: + resources: + limits: + cpus: "2.0" + memory: 4G + reservations: + cpus: "0.5" + memory: 1G + environment: + MYSQL_ROOT_PASSWORD: "Center#2025" + MYSQL_DATABASE: "lcbp3" + MYSQL_USER: "center" + MYSQL_PASSWORD: "Center#2025" + TZ: "Asia/Bangkok" + ports: + - "3306:3306" + volumes: + - "/share/Container/mariadb/data:/var/lib/mysql" + - "/share/Container/mariadb/my.cnf:/etc/mysql/conf.d/my.cnf:ro" + - "/share/Container/mariadb/init:/docker-entrypoint-initdb.d:ro" + - "/share/dms-data/mariadb/backup:/backup" + healthcheck: + test: + ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -pCenter#2025 || exit 1"] + interval: 10s + timeout: 5s + retries: 15 + networks: + lcbp3: {} + + pma: + <<: [*restart_policy, *default_logging] + image: phpmyadmin:5-apache + container_name: pma + stdin_open: true + tty: true + deploy: + resources: + limits: + cpus: "0.25" + memory: 256M + environment: + TZ: "Asia/Bangkok" + PMA_HOST: "mariadb" + PMA_PORT: "3306" + PMA_ABSOLUTE_URI: "https://pma.np-dms.work/" + UPLOAD_LIMIT: "1G" + MEMORY_LIMIT: "512M" + ports: + - "89:80" + # expose: + # - "80" + volumes: + - "/share/Container/pma/config.user.inc.php:/etc/phpmyadmin/config.user.inc.php:ro" + - "/share/Container/pma/zzz-custom.ini:/usr/local/etc/php/conf.d/zzz-custom.ini:ro" + - "/share/Container/pma/tmp:/var/lib/phpmyadmin/tmp:rw" + - "/share/dms-data/logs/pma:/var/log/apache2" + depends_on: + mariadb: + condition: service_healthy + networks: + lcbp3: {} + +networks: + lcbp3: + external: true +``` diff --git a/Documnets/NPM_setting.md b/Documnets/NPM_setting.md new file mode 100644 index 0000000..8aa05ab --- /dev/null +++ b/Documnets/NPM_setting.md @@ -0,0 +1,99 @@ +# การติดตั้ง Nginx Proxy Manager (NPM) ใน Docker + +* ค่าเริ่มต้นคือ:Email: [admin@example.com] Password: changeme + +* user id ของ NPM: + + * uid=0(root) gid=0(root) groups=0(root) + +--- + +## กำหนดสิทธิ + +```bash +# ตรวจสอบ user id ของ NPM +docker exec -it npm id +chown -R 0:0 /share/Container/npm +setfacl -R -m u:0:rwx /share/Container/npm +``` + +## Note: Configurations + +| Domain Names | Forward Hostname | IP Forward Port | Cache Assets | Block Common Exploits | Websockets | Force SSL | HTTP/2 | SupportHSTS Enabled | +| :----------------------------- | :--------------- | :-------------- | :----------- | :-------------------- | :--------- | :-------- | :----- | :------------------ | +| backend.np-dms.work | backend | 3000 | [ ] | [x] | [ ] | [x] | [x] | [ ] | +| lcbp3.np-dms.work | frontend | 3000 | [x] | [x] | [x] | [x] | [x] | [ ] | +| db.np-dms.work | mariadb | 3306 | [x] | [x] | [x] | [x] | [x] | [ ] | +| git.np-dms.work | gitea | 3000 | [x] | [x] | [x] | [x] | [x] | [ ] | +| n8n.np-dms.work | n8n | 5678 | [x] | [x] | [x] | [x] | [x] | [ ] | +| npm.np-dms.work | npm | 81 | [ ] | [x] | [x] | [x] | [x] | [ ] | +| pma.np-dms.work | pma | 80 | [x] | [x] | [ ] | [x] | [x] | [ ] | +| np-dms.work, [www.np-dms.work] | localhost | 80 | [x] | [x] | [ ] | [x] | [x] | [ ] | + +## Docker file + +```yml +# File: share/Container/npm/docker-compose-npm.yml +# DMS Container v1_4_1 แยก service และ folder, Application name: lcbp3-npm, Servive:npm +x-restart: &restart_policy + restart: unless-stopped + +x-logging: &default_logging + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "5" +services: + npm: + <<: [*restart_policy, *default_logging] + image: jc21/nginx-proxy-manager:latest + container_name: npm + stdin_open: true + tty: true + deploy: + resources: + limits: + cpus: "1.0" # 50% CPU + memory: 512M + ports: + - "80:80" # HTTP + - "443:443" # HTTPS + - "81:81" # NPM Admin UI + environment: + TZ: "Asia/Bangkok" + DB_MYSQL_HOST: "mariadb" + DB_MYSQL_PORT: 3306 + DB_MYSQL_USER: "npm" + DB_MYSQL_PASSWORD: "npm" + DB_MYSQL_NAME: "npm" + # Uncomment this if IPv6 is not enabled on your host + DISABLE_IPV6: "true" + networks: + - lcbp3 + - giteanet + volumes: + - "/share/Container/npm/data:/data" + - "/share/dms-data/logs/npm:/data/logs" # <-- เพิ่ม logging volume + - "/share/Container/npm/letsencrypt:/etc/letsencrypt" + - "/share/Container/npm/custom:/data/nginx/custom" # <-- สำคัญสำหรับ http_top.conf + # - "/share/Container/lcbp3/npm/landing:/data/landing:ro" + landing: + image: nginx:1.27-alpine + container_name: landing + restart: unless-stopped + volumes: + - "/share/Container/npm/landing:/usr/share/nginx/html:ro" + networks: + - lcbp3 +networks: + lcbp3: + external: true + giteanet: + external: true + name: gitnet + + + + +``` diff --git a/docs/LCBP3-DMS_V1_4_1_Backend_Development_Plan.md b/Documnets/Project/LCBP3-DMS_V1_4_1_Backend_Development_Plan.md similarity index 96% rename from docs/LCBP3-DMS_V1_4_1_Backend_Development_Plan.md rename to Documnets/Project/LCBP3-DMS_V1_4_1_Backend_Development_Plan.md index 630a142..3b53f51 100644 --- a/docs/LCBP3-DMS_V1_4_1_Backend_Development_Plan.md +++ b/Documnets/Project/LCBP3-DMS_V1_4_1_Backend_Development_Plan.md @@ -1,1323 +1,1324 @@ -# 📋 **แผนการพัฒนา Backend (NestJS) - LCBP3-DMS v1.4.1 (ปรับปรุงโดย deepseek)** - -**ปรับปรุงตาม Requirements v1.4.0 ที่อัปเดตแล้ว* -**Routing และ รูปแบบ JSON details** - ---- - -## 🎯 **ภาพรวมโครงการ** - -พัฒนา Backend สำหรับระบบบริหารจัดการเอกสารโครงการ (Document Management System) ที่รองรับการจัดการเอกสารที่ซับซ้อน มีระบบ Workflow การอนุมัติ และการควบคุมสิทธิ์แบบ RBAC 4 ระดับ พร้อมมาตรการความปลอดภัยที่ทันสมัย - ---- - -## 📐 **สถาปัตยกรรมระบบ** - -### **Technology Stack** - -- **Framework:** NestJS (TypeScript, ESM) -- **Database:** MariaDB 10.11 -- **ORM:** TypeORM -- **Authentication:** JWT + Passport -- **Authorization:** CASL (RBAC 4-level) -- **File Upload:** Multer + Virus Scanning (ClamAV) -- **Search:** Elasticsearch -- **Notification:** Nodemailer + n8n (Line Integration) -- **Caching:** Redis -- **Resilience:** Circuit Breaker, Retry Patterns -- **Security:** Helmet, CSRF Protection, Rate Limiting -- **Monitoring:** Winston, Health Checks, Metrics -- **Scheduling:** @nestjs/schedule (Cron Jobs) -- **Documentation:** Swagger - -### **โครงสร้างโมดูล (Domain-Driven)** - -```tree -src/ -├── common/ # Shared Module -│ ├── auth/ # JWT, Guards, RBAC -│ ├── config/ # Configuration Management -│ ├── decorators/ # @RequirePermission, @RateLimit -│ ├── entities/ # Base Entities -│ ├── exceptions/ # Global Filters -│ ├── file-storage/ # FileStorageService (Virus Scanning) -│ ├── guards/ # RBAC Guard, RateLimitGuard -│ ├── interceptors/ # Audit, Transform, Performance -│ ├── resilience/ # Circuit Breaker, Retry Patterns -│ ├── security/ # Input Validation, XSS Protection -│ └── services/ # Notification, Caching, Monitoring -├── modules/ -│ ├── user/ # Users, Roles, Permissions -│ ├── project/ # Projects, Contracts, Organizations -│ ├── master/ # Master Data Management -│ ├── correspondence/ # Correspondence Management -│ ├── rfa/ # RFA & Workflows -│ ├── drawing/ # Shop/Contract Drawings -│ ├── circulation/ # Internal Circulation -│ ├── transmittal/ # Transmittals -│ ├── search/ # Elasticsearch -│ ├── monitoring/ # Metrics, Health Checks -│ └── document-numbering/ # Internal Service (Redis Locking) -└── database/ # Migrations & Seeds -``` - ---- - -## 🗓️ **แผนการพัฒนาแบบ Phase-Based** - -### **Dependency Diagram (ภาพรวม)** - - ```mermaid - %% Phase 0: Infrastructure - subgraph Phase 0 [Phase 0: Infrastructure Setup] - T0_1[T0.1: Setup QNAP Container Station] - T0_2[T0.2: Initialize NestJS Project] - T0_3[T0.3: Setup Database Connection] - T0_4[T0.4: Setup Git Repository] - end - - %% Phase 1: Core Foundation - subgraph Phase 1 [Phase 1: Core Foundation & Security] - T1_1[T1.1: CommonModule - Base Infrastructure] - T1_2[T1.2: AuthModule - JWT Authentication] - T1_3[T1.3: UserModule - User Management] - T1_4[T1.4: RBAC Guard - 4-Level Authorization] - T1_5[T1.5: ProjectModule - Base Structures] - end - - %% Phase 2: Security & File Management - subgraph Phase 2 [Phase 2: Security & File Management] - T2_1[T2.1: MasterModule - Master Data Management] - T2_2[T2.2: FileStorageService - Secure File Management] - T2_3[T2.3: DocumentNumberingModule - App-Level Locking] - T2_4[T2.4: SecurityModule - Enhanced Security] - T2_5[T2.5: JSON Details & Schema Management] - end - - %% Phase 3: Correspondence & RFA Core - subgraph Phase 3 [Phase 3: Correspondence & RFA Core] - T3_1[T3.1: CorrespondenceModule - Basic CRUD] - T3_2[T3.2: CorrespondenceModule - Advanced Features] - T3_3[T3.3: RfaModule - Basic CRUD] - T3_4[T3.4: Correspondence Routing] - end - - %% Phase 4: Drawing Management - subgraph Phase 4 [Phase 4: Drawing Management] - T4_1[T4.1: DrawingModule - Contract Drawings] - T4_2[T4.2: DrawingModule - Shop Drawings] - end - - %% Phase 5: Workflow Systems & Resilience - subgraph Phase 5 [Phase 5: Workflow Systems & Resilience] - T5_1[T5.1: RfaModule - Workflow Implementation] - T5_2[T5.2: CirculationModule - Internal Routing] - T5_3[T5.3: TransmittalModule - Document Forwarding] - end - - %% Phase 6: Advanced Features & Monitoring - subgraph Phase 6 [Phase 6: Advanced Features & Monitoring] - T6_1[T6.1: SearchModule - Elasticsearch Integration] - T6_2[T6.2: NotificationModule - Email & Line] - T6_3[T6.3: MonitoringModule - Observability] - T6_4[T6.4: ResilienceModule - Circuit Breaker & Retry] - end - - %% Phase 7: Testing & Optimization - subgraph Phase 7 [Phase 7: Testing & Optimization] - T7_1[T7.1: Unit Testing] - T7_2[T7.2: Integration Testing] - T7_3[T7.3: E2E Testing] - T7_4[T7.4: Performance Testing] - T7_5[T7.5: Security Testing] - T7_6[T7.6: Performance Optimization] - end - - %% Phase 8: Documentation & Deployment - subgraph Phase 8 [Phase 8: Documentation & Deployment] - T8_1[T8.1: API Documentation] - T8_2[T8.2: Technical Documentation] - T8_3[T8.3: Security Hardening] - T8_4[T8.4: Deployment Preparation] - T8_5[T8.5: Production Deployment] - T8_6[T8.6: Handover to Frontend Team] - end - - %% Dependencies - T0_1 --> T0_2 - T0_2 --> T0_3 - T0_3 --> T0_4 - - T0_2 --> T1_1 - T0_3 --> T1_1 - T1_1 --> T1_2 - T1_1 --> T1_3 - T1_1 --> T1_4 - T1_1 --> T1_5 - T1_2 --> T1_3 - T1_3 --> T1_4 - - T0_3 --> T2_1 - T1_1 --> T2_1 - T1_5 --> T2_1 - T1_1 --> T2_2 - T1_4 --> T2_2 - T1_1 --> T2_3 - T1_1 --> T2_4 - T1_1 --> T2_5 - - T1_1 --> T3_1 - T1_2 --> T3_1 - T1_3 --> T3_1 - T1_4 --> T3_1 - T1_5 --> T3_1 - T2_3 --> T3_1 - T2_2 --> T3_1 - T2_5 --> T3_1 - T3_1 --> T3_2 - T3_1 --> T3_3 - T1_5 --> T3_3 - T3_1 --> T3_4 - T2_5 --> T3_4 - - T1_1 --> T4_1 - T1_2 --> T4_1 - T1_4 --> T4_1 - T1_5 --> T4_1 - T2_2 --> T4_1 - T4_1 --> T4_2 - - T3_3 --> T5_1 - T4_2 --> T5_1 - T2_5 --> T5_1 - T3_1 --> T5_2 - T2_5 --> T5_2 - T3_1 --> T5_3 - - T3_1 --> T6_1 - T3_3 --> T6_1 - T4_2 --> T6_1 - T5_2 --> T6_1 - T5_3 --> T6_1 - T1_1 --> T6_2 - T6_4 --> T6_2 - T1_1 --> T6_3 - T1_1 --> T6_4 - - %% All development phases must be complete before testing - T1_5 --> T7_1 - T2_5 --> T7_1 - T3_4 --> T7_1 - T4_2 --> T7_1 - T5_3 --> T7_1 - T6_4 --> T7_1 - T7_1 --> T7_2 - T7_2 --> T7_3 - T7_3 --> T7_4 - T7_4 --> T7_5 - T7_5 --> T7_6 - - %% Testing must be complete before deployment - T7_6 --> T8_1 - T8_1 --> T8_2 - T8_2 --> T8_3 - T8_3 --> T8_4 - T8_4 --> T8_5 - T8_5 --> T8_6 - ``` - -## **Phase 0: Infrastructure Setup (สัปดาห์ที่ 1)** - -**Milestone:** สร้างโครงสร้างพื้นฐานและเชื่อมต่อ Services พร้อม Security Baseline - -### **Phase 0: Tasks** - -- **[✅] T0.1 Setup QNAP Container Station** - - [✅]สร้าง Docker Network: `lcbp3` - - [✅]Setup docker-compose.yml สำหรับ: - - [✅]MariaDB (db.np-dms.work) - - [✅]PHPMyAdmin (pma.np-dms.work) - - [ ]Redis (cache.np-dms.work) - - [ ]Elasticsearch (search.np-dms.work) - - [✅]Backend (backend.np-dms.work) - - [✅]Nginx Proxy Manager (npm.np-dms.work) - - กำหนด Environment Variables ใน docker-compose.yml (ไม่ใช้ .env) - - **Security:** Setup network segmentation และ firewall rules - - [ ] **Deliverable:** Services ทั้งหมดรันได้และเชื่อมต่อกันผ่าน Network - - **Dependencies:** None (Task เริ่มต้น) - -- **[✅] T0.2 Initialize NestJS Project** - - สร้างโปรเจกต์ใหม่ด้วย Nest CLI - - ติดตั้ง Dependencies: - - ```bash - # Core - npm install @nestjs/core @nestjs/common @nestjs/platform-express - npm install @nestjs/typeorm typeorm mysql2 - npm install @nestjs/config class-validator class-transformer - - # Auth & Security - npm install @nestjs/jwt @nestjs/passport passport passport-jwt - npm install casl helmet csurf rate-limiter-flexible bcrypt crypto - - # File & Search - npm install multer @nestjs/elasticsearch @elastic/elasticsearch - npm install clamscan @types/multer - - # Resilience & Caching - npm install @nestjs/cache-manager cache-manager cache-manager-redis-store - npm install @nestjs/circuit-breaker - - # Monitoring & Scheduling - npm install @nestjs/schedule @nestjs/monitoring winston - - # Documentation - npm install @nestjs/swagger - - # Development - npm install --save-dev @nestjs/testing jest @types/jest supertest - npm install --save-dev @types/passport-jwt @types/bcrypt @types/crypto - ``` - - - Setup โครงสร้างโฟลเดอร์ตาม Domain-Driven Architecture - - **Security:** Initialize security headers และ CORS configuration - - [ ] **Deliverable:** Project Structure พร้อม, แสดง Swagger ที่ `/api` - - **Dependencies:** T0.1 (ต้องมี Docker Network และ Environment พร้อมก่อนสร้าง Project) - -- **[✅] T0.3 Setup Database Connection** - - - Import SQL Schema v1.4.0 เข้า MariaDB - - Run Seed Data (organizations, users, roles, permissions) - - Configure TypeORM ใน AppModule - - **Security:** Setup database connection encryption - - ทดสอบ Connection - - [ ] **Deliverable:** Database พร้อมใช้งาน, มี Seed Data - - **Dependencies:** T0.1 (ต้องมี MariaDB Container รันแล้ว), T0.2 (ต้องมี NestJS Project พร้อมสำหรับตั้งค่า TypeORM) - -- **[✅] T0.4 Setup Git Repository** - - สร้าง Repository ใน Gitea (git.np-dms.work) - - Setup .gitignore, README.md, SECURITY.md - - Commit Initial Project - - [ ] **Deliverable:** Code อยู่ใน Version Control - - **Dependencies:** T0.2 (ต้องมี Project และโครงสร้างพื้นฐานก่อนจะ Commit) - -### **Phase 0: Testing - Infrastructure Validation** - -#### **T0.T1 Database Connectivity Tests** - -- [ ] **Unit Tests:** - - [ ] Test database connection configuration - - [ ] Test connection pooling settings - - [ ] Test connection error handling -- [ ] **Integration Tests:** - - [ ] Test actual database connection - - [ ] Test database migrations - - [ ] Test seed data loading - - [ ] Test backup/restore procedures -- [ ] **Performance Tests:** - - [ ] Test connection acquisition time < 100ms - - [ ] Test concurrent connections handling -- **Exit Criteria:** Database tests 100% passed - -#### **T0.T2 Service Connectivity Tests** - -- [ ] **Integration Tests:** - - [ ] Test Docker network connectivity - - [ ] Test inter-service communication - - [ ] Test Nginx proxy configuration - - [ ] Test SSL certificate setup -- [ ] **Security Tests:** - - [ ] Test firewall rules - - [ ] Test port exposure - - [ ] Test environment variables security -- **Exit Criteria:** All services can communicate securely - -#### **T0.T3 Project Setup Tests** - -- [ ] **Unit Tests:** - - [ ] Test NestJS project structure - - [ ] Test dependency configurations - - [ ] Test build process -- [ ] **Integration Tests:** - - [ ] Test Swagger documentation generation - - [ ] Test health check endpoints - - [ ] Test error handling setup -- **Exit Criteria:** Project setup verified and documented - ---- - -## **Phase 1: Core Foundation & Security (สัปดาห์ที่ 2-3)** - -**Milestone:** ระบบ Authentication, Authorization, Security Baseline และ Base Entities - -### **Phase 1: Tasks** - -- **[ ] T1.1 CommonModule - Base Infrastructure** - - [ ] สร้าง Base Entity (id, created_at, updated_at, deleted_at) - - [ ] สร้าง Global Exception Filter (ไม่เปิดเผย sensitive information) - - [ ] สร้าง Response Transform Interceptor - - [ ] สร้าง Audit Log Interceptor - - [ ] สร้าง RequestContextService - สำหรับเก็บข้อมูลระหว่าง Request - - [ ] สร้าง ConfigService - Centralized configuration management - - [ ] สร้าง CryptoService - สำหรับ encryption/decryption - - [ ] **Security:** Implement input validation pipeline - - [ ] **Deliverable:** Common Services พร้อมใช้ - - [ ] **Dependencies:** T0.2, T0.3 (ต้องมี Project และ Database Connection พร้อมสำหรับสร้าง Base Entity และ Services) - -- **[ ] T1.2 AuthModule - JWT Authentication** - - [ ] สร้าง Entity: User - - [ ] สร้าง AuthService: - - [ ] login(username, password) → JWT Token - - [ ] validateUser(username, password) → User | null - - [ ] Password Hashing (bcrypt) + salt - - [ ] สร้าง JWT Strategy (Passport) - - [ ] สร้าง JwtAuthGuard - - [ ] สร้าง Controllers: - - [ ] POST /auth/login → { access_token, refresh_token } - - [ ] POST /auth/register → Create User (Admin only) - - [ ] POST /auth/refresh → Refresh token - - [ ] POST /auth/logout → Revoke token - - [ ] GET /auth/profile (Protected) - - [ ] **Security:** Implement rate limiting สำหรับ authentication endpoints - - [ ] **Deliverable:** ล็อกอิน/ล็อกเอาต์ทำงานได้อย่างปลอดภัย - - [ ] **Dependencies:** T1.1 (ต้องใช้ Base Entity, ConfigService, CryptoService), T0.3 (ต้องเชื่อมต่อกับ User table) - -- **[ ] T1.3 UserModule - User Management** - - [ ] สร้าง Entities: User, Role, Permission, UserRole, UserAssignment - - [ ] สร้าง UserService CRUD (พร้อม soft delete) - - [ ] สร้าง RoleService CRUD - - [ ] สร้าง PermissionService (Read-Only, จาก Seed) - - [ ] สร้าง UserAssignmentService - สำหรับจัดการ user assignments ตาม scope - - [ ] สร้าง Controllers: - - [ ] GET /users → List Users (Paginated) - - [ ] GET /users/:id → User Detail - - [ ] POST /users → Create User (ต้องบังคับเปลี่ยน password ครั้งแรก) - - [ ] PUT /users/:id → Update User - - [ ] DELETE /users/:id → Soft Delete - - [ ] GET /roles → List Roles - - [ ] POST /roles → Create Role (Admin) - - [ ] PUT /roles/:id/permissions → Assign Permissions - - [ ] **Security:** Implement permission checks สำหรับ user management - - [ ] **Deliverable:** จัดการผู้ใช้และ Role ได้ - - [ ] **Dependencies:** T1.1 (Base Entity, Global Exception Filter), T1.2 (สำหรับ Authentication และ Authorization) - -- **[ ] T1.4 RBAC Guard - 4-Level Authorization** - - [ ] สร้าง @RequirePermission() Decorator - - [ ] สร้าง RbacGuard ที่ตรวจสอบ 4 ระดับ: - - [ ] Global Permissions - - [ ] Organization Permissions - - [ ] Project Permissions - - [ ] Contract Permissions - - [ ] Permission Hierarchy Logic: - - [ ] Integration กับ CASL - - [ ] **Security:** Implement audit logging สำหรับ permission checks - - [ ] **Deliverable:** ระบบสิทธิ์ทำงานได้ทั้ง 4 ระดับ - - [ ] **Dependencies:** T1.1 (Decorators, RequestContextService), T1.3 (ต้องมีโครงสร้าง User, Role, Permission ที่สมบูรณ์) - -- **[ ] T1.5 ProjectModule - Base Structures** - - [ ] สร้าง Entities: - - [ ] Organization - - [ ] Project - - [ ] Contract - - [ ] ProjectOrganization (Junction) - - [ ] ContractOrganization (Junction) - - [ ] สร้าง Services & Controllers: - - [ ] GET /organizations → List - - [ ] POST /projects → Create (Superadmin) - - [ ] GET /projects/:id/contracts → List Contracts - - [ ] POST /projects/:id/contracts → Create Contract - - [ ] **Security:** Implement data isolation ระหว่าง organizations - - [ ] **Deliverable:** จัดการโครงสร้างโปรเจกต์ได้ - - [ ] **Dependencies:** T1.1 (Base Entity, Security), T1.2 (สำหรับการป้องกันการเข้าถึง), T0.3 (ต้องเชื่อมต่อกับ project/organization tables) - -### **Phase 1: Testing - Core Foundation** - -#### **T1.T1 Authentication Test Suite** - -- [ ] **Unit Tests (25+ test cases):** - - [ ] AuthService.authenticate() - success and failure cases - - [ ] AuthService.validateUser() - various user states - - [ ] JWT token generation and validation - - [ ] Password hashing and verification - - [ ] Token refresh mechanism -- [ ] **Integration Tests (15+ test cases):** - - [ ] Complete login/logout flow - - [ ] Token expiration handling - - [ ] Concurrent session management - - [ ] Rate limiting on auth endpoints -- [ ] **Security Tests (10+ test cases):** - - [ ] SQL injection attempts on login - - [ ] Brute force attack simulation - - [ ] Token tampering attempts - - [ ] Session fixation tests -- [ ] **Performance Tests:** - - [ ] Login response time < 500ms under load - - [ ] Token validation < 50ms -- **Exit Criteria:** Authentication system secure and performant - -#### **T1.T2 RBAC Test Suite** - -- [ ] **Unit Tests (30+ test cases):** - - [ ] RbacGuard - all 4 permission levels - - [ ] Permission hierarchy logic - - [ ] Role-permission mappings - - [ ] Scope-based access control -- [ ] **Integration Tests (20+ test cases):** - - [ ] End-to-end permission checks - - [ ] Multi-organization access control - - [ ] Project/contract scope isolation - - [ ] Permission escalation attempts -- [ ] **Security Tests (15+ test cases):** - - [ ] Unauthorized access attempts - - [ ] Privilege escalation attempts - - [ ] Role manipulation attempts -- **Exit Criteria:** RBAC system working correctly for all scenarios - -#### **T1.T3 User Management Test Suite** - -- [ ] **Unit Tests (20+ test cases):** - - [ ] User CRUD operations - - [ ] Role assignment logic - - [ ] Soft delete functionality - - [ ] User search and filtering -- [ ] **Integration Tests (15+ test cases):** - - [ ] User creation with role assignment - - [ ] User deactivation workflow - - [ ] Bulk user operations - - [ ] User permission inheritance -- **Exit Criteria:** User management complete and secure - ---- - -## **Phase 2: Security & File Management (สัปดาห์ที่ 4)** - -**Milestone:** Master Data, ระบบจัดการไฟล์ที่มีความปลอดภัย, Document Numbering, JSON details system พร้อมใช้งาน พร้อม validation และ security - -### **Phase 2: Tasks** - -- **[ ] T2.1 MasterModule - Master Data Management** - - [ ] สร้าง Entities: - - [ ] CorrespondenceType - - [ ] CorrespondenceStatus - - [ ] RfaType - - [ ] RfaStatusCode - - [ ] RfaApproveCode - - [ ] CirculationStatusCode - - [ ] Tag - - [ ] สร้าง Services & Controllers (CRUD): - - [ ] GET /master/correspondence-types - - [ ] POST /master/tags → Create Tag - - [ ] GET /master/tags → List Tags (Autocomplete) - - [ ] **Security:** Implement admin-only access สำหรับ master data - - [ ] **Deliverable:** Admin จัดการ Master Data ได้ - - [ ] **Dependencies:** T0.3 (ต้องเชื่อมต่อกับ master tables), T1.1 (Security patterns), T1.5 (Project context สำหรับ master data บางอย่าง) - -- **[ ] T2.2 FileStorageService - Secure File Management** - - [ ] สร้าง Attachment Entity - - [ ] สร้าง FileStorageService: - - [ ] uploadFile(file: Express.Multer.File, userId: number)` → Attachment - - [ ] Virus scanning ด้วย ClamAV - - [ ] File type validation (white-list: PDF, DWG, DOCX, XLSX, PPTX, ZIP) - - [ ] File size check (max 50MB) - - [ ] Generate checksum (SHA-256) - - [ ] getFilePath(attachmentId)` → string - - [ ] deleteFile(attachmentId)` → boolean - - [ ] จัดเก็บไฟล์ใน /share/dms-data/uploads/{YYYY}/{MM}/ - - [ ] สร้าง Controller: - - [ ] POST /files/upload → { attachment_id, url } (Protected) - - [ ] GET /files/:id/download → File Stream (Protected + Expiration) - - [ ] **Security:** Access Control - ตรวจสอบสิทธิ์ผ่าน Junction Table - - [ ] **Deliverable:** อัปโหลด/ดาวน์โหลดไฟล์ได้อย่างปลอดภัย - - [ ] **Dependencies:** T1.1 (Base Entity สำหรับ Attachment, CryptoService สำหรับ checksum), T1.4 (RBAC Guard สำหรับการควบคุมการเข้าถึงไฟล์) - -- **[ ] T2.3 DocumentNumberingModule - Application-Level Locking** - - [ ] สร้าง Entities: - - [ ] DocumentNumberFormat - - [ ] DocumentNumberCounter - - [ ] สร้าง DocumentNumberingService: - - [ ] generateNextNumber(projectId, orgId, typeId, year) → string - - [ ] ใช้ **Redis distributed locking** แทน stored procedure - - [ ] Retry mechanism ด้วย exponential backoff - - [ ] Fallback mechanism เมื่อการขอเลขล้มเหลว - - [ ] Format ตาม Template: {ORG_CODE}-{TYPE_CODE}-{YEAR_SHORT}-{SEQ:4} - - **ไม่มี Controller** (Internal Service เท่านั้น) - - [ ] **Security:** Implement audit log ทุกครั้งที่มีการ generate เลขที่ - - [ ] **Deliverable:** Service สร้างเลขที่เอกสารได้ถูกต้องและปลอดภัย - - [ ] **Dependencies:** T1.1 (Base patterns, Audit Log), T0.3 (ต้องเชื่อมต่อกับ document_number_formats/counters) - -- **[ ] T2.4 SecurityModule - Enhanced Security** - - [ ] สร้าง Input Validation Service: - - [ ] XSS Prevention - - [ ] SQL Injection Prevention - - [ ] CSRF Protection - - [ ] สร้าง RateLimitGuard: - - [ ] Implement rate limiting ตาม strategy (anonymous: 100/hr, authenticated: 500-5000/hr) - - [ ] Different limits สำหรับ endpoints ต่างๆ - - [ ] สร้าง Security Headers Middleware - - [ ] **Security:** Implement content security policy (CSP) - - [ ] **Deliverable:** Security layers ทำงานได้ - - [ ] **Dependencies:** T1.1 (Input Validation Pipeline) - -### **Phase 2.5: JSON Details & Schema Management (สัปดาห์ที่ 4)** - -- [ ]Dependencies: T1.1 (Validation patterns, Security) -- **[ ] T2.5.1 JsonSchemaModule - Schema Management** - - [ ] สร้าง JsonSchemaService: - - [ ] validate(schemaId: string, data: any): ValidationResult - - [ ] getSchema(schemaId: string, version?: string): object - - [ ] registerSchema(schemaId: string, schema: object): void - - [ ] migrateData(data: any, fromVersion: string, toVersion: string): any - - [ ] สร้าง predefined schemas สำหรับ: - - [ ] Correspondence types (RFI, RFA, TRANSMITTAL, etc.) - - [ ] Routing types (TEMPLATE, INSTANCE, ACTION) - - [ ] Audit types (AUDIT_LOG, SECURITY_SCAN) - - [ ] Implement schema versioning และ compatibility - - [ ] **Deliverable:** JSON schema system ทำงานได้ - -- **[ ] T2.5.2 DetailsService - Data Processing** - - [ ] สร้าง DetailsService: - - [ ] processDetails(type: string, input: any): ProcessedDetails - - [ ] sanitize(input: any): any (XSS prevention, SQL injection protection) - - [ ] compress(data: any): string (JSON compression) - - [ ] decompress(compressed: string): any - - [ ] Implement data transformation pipelines: - - [ ] Input validation และ sanitization - - [ ] Data normalization - - [ ] Default value population - - [ ] **Deliverable:** Data processing service ทำงานได้ - -- **[ ] T2.5.3 JSON Security & Validation** - - [ ] สร้าง SecurityService สำหรับ JSON: - - [ ] sanitizeJson(input: any): any (Remove dangerous properties) - - [ ] validateSize(data: any): boolean (Max 50KB check) - - [ ] encryptSensitiveFields(data: any): any - - [ ] Implement validation rules: - - [ ] Type validation - - [ ] Format validation (email, date, URL) - - [ ] Custom validation rules - - [ ] **Deliverable:** JSON security measures ทำงานได้ - -- **T2.5.4 Integration with Existing Modules** - - [ ] Integrate กับ CorrespondenceModule: - - [ ] Auto-validate details ก่อน save - - [ ] Auto-populate default values - - [ ] Handle version migration - - [ ] Integrate กับ RoutingModule: - - [ ] Validate routing configuration details - - [ ] Process step action details - - [ ] Integrate กับ AuditModule: - - [ ] Validate audit log details - - [ ] Compress large audit data - - [ ] **Deliverable:** JSON details integrated กับทุก modules - -### **Phase 2: Testing - Security & File Management** - -#### **T2.T1 File Upload Security Test Suite** - -- [ ] **Unit Tests (15+ test cases):** - - [ ] File type validation (white-list) - - [ ] File size validation - - [ ] Virus scanning integration - - [ ] Checksum generation -- [ ] **Integration Tests (10+ test cases):** - - [ ] Complete file upload flow - - [ ] File download with access control - - [ ] Concurrent file operations - - [ ] File cleanup procedures -- [ ] **Security Tests (20+ test cases):** - - [ ] Malicious file upload attempts - - [ ] Path traversal attacks - - [ ] File type spoofing - - [ ] Access control bypass attempts -- [ ] **Performance Tests:** - - [ ] File upload < 30s for 50MB files - - [ ] Concurrent upload handling -- **Exit Criteria:** File system secure and performant - -#### **T2.T2 JSON Schema Test Suite** - -- [ ] **Unit Tests (25+ test cases):** - - [ ] JSON schema validation - - [ ] Schema versioning - - [ ] Data transformation - - [ ] Default value population -- [ ] **Integration Tests (15+ test cases):** - - [ ] End-to-end JSON processing - - [ ] Schema migration scenarios - - [ ] Error handling and recovery - - [ ] Backward compatibility -- [ ] **Security Tests (10+ test cases):** - - [ ] JSON injection attempts - - [ ] Schema manipulation - - [ ] Large payload attacks -- **Exit Criteria:** JSON system robust and secure - -#### **T2.T3 Document Numbering Test Suite** - -- [ ] **Unit Tests (10+ test cases):** - - [ ] Redis locking mechanism - - [ ] Number generation logic - - [ ] Retry mechanism - - [ ] Error scenarios -- [ ] **Integration Tests (8+ test cases):** - - [ ] Concurrent number generation - - [ ] Database transaction handling - - [ ] Failure recovery -- [ ] **Performance Tests:** - - [ ] Number generation < 100ms under load - - [ ] Concurrent request handling -- **Exit Criteria:** Document numbering system race-condition free - ---- - -## **Phase 3: Correspondence & RFA Core (สัปดาห์ที่ 5-6)** - -**Milestone:** ระบบเอกสารโต้ตอบและ RFA พร้อม Security และ Audit, ระบบส่งต่อเอกสารระหว่างองค์กรทำงานได้ - -### **Phase 3A: Tasks (สัปดาห์ที่ 5)** - -- **[ ] T3.1 CorrespondenceModule - Basic CRUD** - - [ ] สร้าง Entities: - - [ ] Correspondence - - [ ] CorrespondenceRevision - - [ ] CorrespondenceRecipient - - [ ] CorrespondenceTag - - [ ] CorrespondenceReference - - [ ] CorrespondenceAttachment - - [ ] สร้าง CorrespondenceService: - - [ ] create(dto) → Correspondence - - [ ] สร้าง Correspondence + Revision แรก (rev 0) - - [ ] เรียก DocumentNumberingService (Redis locking) - - [ ] สร้าง Recipients (TO/CC) - - [ ] สร้าง Tags - - [ ] สร้าง Attachments (ผ่าน FileStorageService) - - [ ] update(id, dto) → Correspondence - - [ ] สร้าง Revision ใหม่ - - [ ] Update is_current flag - - [ ] findAll(filters) → Paginated List - - [ ] findById(id) → Correspondence with Current Revision - - [ ] สร้าง Controllers: - - [ ] POST /correspondences → Create - - [ ] GET /correspondences → List (Filter by type, status, org) - - [ ] GET /correspondences/:id → Detail - - [ ] PUT /correspondences/:id → Update (Create new revision) - - [ ] DELETE /correspondences/:id → Soft Delete (Admin only) - - [ ] **Security:** Implement permission checks สำหรับ document access - - [ ] **Deliverable:** สร้าง/แก้ไข/ดูเอกสารได้ - - [ ] **Dependencies:** T1.1 (Base Entity, Audit, Transform), T1.2 (Authentication), T1.3 (User context), T1.4 (RBAC), T1.5 (Project/Organization context), T2.3 (DocumentNumberingService), T2.2 (FileStorageService), T2.5 (JSON Details Validation) - -- **[ ] T3.2 CorrespondenceModule - Advanced Features** - - [ ] Implement Status Transitions: - - [ ] DRAFT → SUBMITTED (Document Control) - - [ ] SUBMITTED → CLOSED (Admin) - - [ ] SUBMITTED → CANCELLED (Admin + Reason) - - [ ] Implement References: - - [ ] POST /correspondences/:id/references → Link Documents - - [ ] Implement Search (Basic): - - [ ] GET /correspondences/search?q=... - - [ ] **Security:** Implement state transition validation - - [ ] **Deliverable:** Workflow พื้นฐานทำงานได้ - - [ ] **Dependencies:** T3.1 (ต้องมี Basic CRUD ก่อน) - -- **[ ] T3.3 RfaModule - Basic CRUD** - - [ ] สร้าง Entities: - - [ ] Rfa - - [ ] RfaRevision - - [ ] RfaItem (Junction to Shop Drawings) - - [ ] สร้าง RfaService: - - [ ] create(dto) → Rfa - - [ ] สร้าง Correspondence + Rfa + RfaRevision - - [ ] เชื่อม Shop Drawing Revisions (สำหรับ RFA_DWG) - - [ ] findAll(filters) → Paginated List - - [ ] findById(id) → Rfa with Items - - [ ] สร้าง Controllers: - - [ ] POST /rfas → Create - - [ ] GET /rfas → List - - [ ] GET /rfas/:id → Detail - - [ ] **Security:** Implement permission checks สำหรับ RFA operations - - [ ] **Deliverable:** สร้าง RFA และเชื่อม Shop Drawings ได้ - - [ ] **Dependencies:** T3.1 (RFA คือ Correspondence ประเภทหนึ่ง), T1.5 (Project context), T4.2 (สำหรับการเชื่อมโยงกับ Shop Drawings) - -### **Phase 3B: Correspondence Routing (สัปดาห์ที่ 6)** - -- [ ] **Dependencies:** T3.1 (ต้องมี Correspondence ก่อนจะส่งต่อได้), T2.5 (สำหรับ JSON Details ของ Routing) - -- **[ ] T3.4.1 CorrespondenceRoutingModule - Template Management** - - [ ] สร้าง Entities: - - [ ] CorrespondenceRoutingTemplate - - [ ] CorrespondenceRoutingTemplateStep - - [ ] สร้าง Services: - - [ ] createTemplate(dto) → Create routing template - - [ ] addStep(templateId, stepDto) → Add step to template - - [ ] getTemplates(projectId) → List available templates - - [ ] สร้าง Controllers: - - [ ] POST /routing/templates → Create template (Admin only) - - [ ] GET /routing/templates → List templates - - [ ] POST /routing/templates/:id/steps → Add step - -- **[ ] T3.4.2 CorrespondenceRoutingModule - Routing Execution** - - [ ] สร้าง Entity: CorrespondenceRouting - - [ ] สร้าง RoutingService: - - [ ] initiateRouting(correspondenceId, templateId) → void - - [ ] สร้าง routing instances ตาม template steps - - [ ] คำนวณ due dates จาก expected_days - - [ ] ส่ง notifications ไปยังองค์กรแรก - - [ ] processStep(routingId, action, comments) → void - - [ ] อัพเดทสถานะขั้นตอนปัจจุบัน - - [ ] ส่ง notification ไปยังขั้นตอนต่อไป - - [ ] อัพเดท due dates สำหรับขั้นตอนต่อไป - - [ ] สร้าง Controllers: - - [ ] POST /correspondences/:id/routing/start → Start routing - - [ ] POST /routing/:id/process → Process routing step - - [ ] GET /correspondences/:id/routing → Get routing status - - [ ] ตัวอย่าง Implementation Details - -- **[ ] T3.4.3 WorkflowEngineModule - State Management** - - [ ] สร้าง WorkflowEngineService: - - [ ] validateTransition(currentStatus, targetStatus) → boolean - - [ ] getAllowedTransitions(status) → string[] - - [ ] autoAdvanceStatus(correspondenceId) → void - - [ ] สร้าง DeadlineService: - - [ ] checkDeadlines() → void (Cron job) - - [ ] sendReminder(routingId) → void - - [ ] escalateOverdue(routingId) → void - -- **[ ] T3.4.4 Routing UI Integration** - - [ ] สร้าง API endpoints สำหรับ frontend: - - [ ] GET /routing/available-templates → Templates for current project - - [ ] GET /routing/my-pending → Pending routing steps for current user - - [ ] POST /routing/bulk-action → Process multiple routing steps - - [ ] **Security:** Implement permission checks สำหรับ routing operations - - [ ] **Deliverable:** ระบบส่งต่อเอกสารทำงานได้สมบูรณ์ - -### **Phase 3: Testing - Correspondence & Routing** - -#### **T3.T1 Correspondence Test Suite** - -- [ ] **Unit Tests (30+ test cases):** - - [ ] Correspondence creation with auto-numbering - - [ ] Revision management - - [ ] Status transitions - - [ ] Recipient management -- [ ] **Integration Tests (25+ test cases):** - - [ ] Complete correspondence lifecycle - - [ ] File attachment handling - - [ ] Reference management - - [ ] Search and filtering -- [ ] **Business Logic Tests (20+ test cases):** - - [ ] Workflow state validation - - [ ] Permission-based access - - [ ] Data validation rules - - [ ] Business rule enforcement -- **Exit Criteria:** Correspondence system handles all business scenarios - -#### **T3.T2 Routing Test Suite** - -- [ ] **Unit Tests (25+ test cases):** - - [ ] Template management - - [ ] Step sequencing - - [ ] Due date calculation - - [ ] Status transitions -- [ ] **Integration Tests (20+ test cases):** - - [ ] Complete routing workflow - - [ ] Multi-organization routing - - [ ] Deadline management - - [ ] Notification triggers -- [ ] **Edge Case Tests (15+ test cases):** - - [ ] Parallel processing scenarios - - [ ] Step skipping conditions - - [ ] Escalation procedures - - [ ] Error recovery -- **Exit Criteria:** Routing system handles complex workflows - -#### **T3.T3 JSON Details Integration Test Suite** - -- [ ] **Integration Tests (15+ test cases):** - - [ ] RFI details validation and processing - - [ ] RFA details for different types - - [ ] Transmittal details management - - [ ] Routing details in workflows -- [ ] **Data Migration Tests (10+ test cases):** - - [ ] Schema version upgrades - - [ ] Data transformation scenarios - - [ ] Backward compatibility -民主- **Exit Criteria:** JSON details integrated across all modules - ---- - -## **Phase 4: Drawing Management (สัปดาห์ที่ 7)** - -**Milestone:** ระบบจัดการแบบพร้อม File Security - -### **Phase 4: Tasks** - -- **[ ] T4.1 DrawingModule - Contract Drawings** - - [ ] สร้าง Entities: - - [ ] ContractDrawing - - [ ] ContractDrawingVolume - - [ ] ContractDrawingCat - - [ ] ContractDrawingSubCat - - [ ] ContractDrawingSubcatCatMap - - [ ] ContractDrawingAttachment - - [ ] สร้าง ContractDrawingService CRUD - - [ ] สร้าง Controllers: - - [ ] GET /drawings/contract → List - - [ ] POST /drawings/contract → Create (Admin) - - [ ] GET /drawings/contract/:id → Detail - - [ ] **Security:** Implement access control สำหรับ contract drawings - - [ ] **Deliverable:** จัดการ Contract Drawings ได้ - - [ ] **Dependencies:** T1.1 (Base Entity, Security), T1.2 (Authentication), T1.4 (RBAC), T1.5 (Project context), T2.2 (FileStorageService) - -- **[ ] T4.2 DrawingModule - Shop Drawings** - - [ ] สร้าง Entities: - - [ ] ShopDrawing - - [ ] ShopDrawingRevision - - [ ] ShopDrawingMainCategory - - [ ] ShopDrawingSubCategory - - [ ] ShopDrawingRevisionContractRef - - [ ] ShopDrawingRevisionAttachment - - [ ] สร้าง ShopDrawingService CRUD - - [ ] สร้าง Controllers: - - [ ] GET /drawings/shop → List - - [ ] POST /drawings/shop → Create - - [ ] POST /drawings/shop/:id/revisions → Create Revision - - [ ] GET /drawings/shop/:id → Detail with Revisions - - [ ] Link Shop Drawing Revision → Contract Drawings - - [ ] **Security:** Implement virus scanning สำหรับ drawing files - - [ ] **Deliverable:** จัดการ Shop Drawings และ Revisions ได้ - - [ ] ependencies: T4.1 (Shop Drawings อ้างอิงถึง Contract Drawings) - ---- - -## **Phase 5: Workflow Systems & Resilience (สัปดาห์ที่ 8-9)** - -**Milestone:** ระบบ Workflow ทั้งหมดพร้อม Resilience Patterns - -### **Phase 5: Tasks** - -- **[ ] T5.1 RfaModule - Workflow Implementation** - - [ ] สร้าง Entities: - - [ ] RfaWorkflowTemplate - - [ ] RfaWorkflowTemplateStep - - [ ] RfaWorkflow (Transaction Log) - - [ ] สร้าง RfaWorkflowService: - - [ ] initiateWorkflow(rfaId, templateId) → void - - [ ] สร้าง RfaWorkflow records ตาม Template - - [ ] กำหนด Step 1 เป็น PENDING - - [ ] completeStep(rfaId, stepNumber, action, comments) → void - - [ ] Update Status → COMPLETED - - [ ] Set Next Step → PENDING - - [ ] Send Notifications - - [ ] rejectStep(rfaId, stepNumber, reason) → void - - [ ] Update Status → REJECTED - - [ ] Send back to Originator - - [ ] สร้าง Controllers: - - [ ] POST /rfas/:id/workflow/start → Start Workflow - - [ ] POST /rfas/:id/workflow/steps/:stepNumber/complete → Complete Step - - [ ] GET /rfas/:id/workflow → Get Workflow Status - - [ ] **Resilience:** Implement circuit breaker สำหรับ notification services - - [ ] **Deliverable:** RFA Workflow ทำงานได้ - - [ ] **Dependencies:** T3.3 (ต้องมี RFA Basic CRUD ก่อน), T4.2 (RFA_DWG ต้องเชื่อมโยงกับ Shop Drawings), T2.5 (JSON Details สำหรับ Workflow), T6.2 (NotificationService สำหรับแจ้งเตือน) - -- **[ ] T5.2 CirculationModule - Internal Routing** - - [ ] สร้าง Entities: - - [ ] Circulation - - [ ] CirculationTemplate - - [ ] CirculationTemplateAssignee - - [ ] CirculationRouting (Transaction Log) - - [ ] CirculationAttachment - - [ ] สร้าง CirculationService: - - [ ] create(correspondenceId, dto) → Circulation - - [ ] สร้าง Circulation (1:1 กับ Correspondence) - - [ ] สร้าง Routing ตาม Template - - [ ] assignUser(circulationId, stepNumber, userId) → void - - [ ] completeStep(circulationId, stepNumber, comments) → void - - [ ] close(circulationId) → void (เมื่อตอบกลับองค์กรผู้ส่งแล้ว) - - สร้าง Controllers: - - [ ] POST /circulations → Create - - [ ] GET /circulations/:id → Detail - - [ ] POST /circulations/:id/steps/:stepNumber/complete → Complete - - [ ] POST /circulations/:id/close → Close - - [ ] **Resilience:** Implement retry mechanism สำหรับ assignment notifications - - [ ] **Deliverable:** ใบเวียนภายในองค์กรทำงานได้ - - [ ] **Dependencies:** T3.1 (Circulation คือ Correspondence ประเภทหนึ่ง), T2.5 (JSON Details), T6.2 (NotificationService) - -- **[ ] T5.3 TransmittalModule - Document Forwarding** - - [ ] สร้าง Entities: - - [ ] Transmittal - - [ ] TransmittalItem - - [ ] สร้าง TransmittalService: - - [ ] create(dto) → Transmittal - - [ ] สร้าง Correspondence + Transmittal - - [ ] เชื่อม Multiple Correspondences เป็น Items - - [ ] สร้าง Controllers: - - [ ] POST /transmittals → Create - - [ ] GET /transmittals → List - - [ ] GET /transmittals/:id → Detail with Items - - [ ] **Security:** Implement access control สำหรับ transmittal items - - [ ] **Deliverable:** สร้าง Transmittal ได้ - - [ ] **Dependencies:** T3.1 (Transmittal คือ Correspondence ประเภทหนึ่ง) - ---- - -## **Phase 6: Advanced Features & Monitoring (สัปดาห์ที่ 10-11)** - -**Milestone:** ฟีเจอร์ขั้นสูงพร้อม Monitoring และ Observability - -### **Phase 6: Tasks** - -- **[ ] T6.1 SearchModule - Elasticsearch Integration** - - [ ] Setup Elasticsearch Container ใน docker-compose.yml - - [ ] สร้าง SearchService: - - [ ] indexDocument(entity) → void - - [ ] updateDocument(entity) → void - - [ ] deleteDocument(entity) → void - - [ ] search(query, filters) → SearchResult[] - - [ ] Index ทุกครั้งที่ Create/Update: - - [ ] Correspondence - - [ ] RFA - - [ ] Shop Drawing - - [ ] Contract Drawing - - [ ] Circulation - - [ ] Transmittal - - [ ] สร้าง Controllers: - - [ ] GET /search?q=...&type=...&from=...&to=... → Results - - [ ] **Resilience:** Implement circuit breaker สำหรับ Elasticsearch - - [ ] **Deliverable:** ค้นหาขั้นสูงทำงานได้ - - [ ] **Dependencies:** T3.1, T3.3, T4.2, T5.2, T5.3 (ต้องมีข้อมูลจาก Modules หลักเหล่านี้ให้ทำการ Index) - -- **[ ] T6.2 NotificationModule - Email & Line** - - [ ] สร้าง NotificationService: - - [ ] sendEmail(to, subject, body) → void (Nodemailer) - - [ ] sendLine(userId, message) → void (ผ่าน n8n Webhook) - - [ ] createSystemNotification(userId, message, entityType, entityId) → void - - [ ] Integrate กับ Workflow Events: - - [ ] เมื่อสร้าง Correspondence ใหม่ → แจ้ง Recipients - - [ ] เมื่อสร้าง Circulation → แจ้ง Assignees - - [ ] เมื่อ RFA Workflow ถึง Step → แจ้ง Responsible Org - - [ ] เมื่อใกล้ถึง Deadline → แจ้ง (Optional) - - [ ] สร้าง Controllers: - - [ ] GET /notifications → List User's Notifications - - [ ] PUT /notifications/:id/read → Mark as Read - - [ ] **Resilience:** Implement retry mechanism ด้วย exponential backoff - - [ ] **Deliverable:** ระบบแจ้งเตือนทำงานได้ - - [ ] **Dependencies:** T1.1 (ConfigService สำหรับ Email credentials), T6.4 (Resilience patterns สำหรับการส่งภายนอก) - -- **[ ] T6.3 MonitoringModule - Observability** - - [ ] สร้าง Health Check Controller: - - [ ] GET /health → Database, Redis, Elasticsearch status - - [ ] สร้าง Metrics Service: - - [ ] API response times - - [ ] Error rates - - [ ] Cache hit ratios - - [ ] Business metrics (documents created, workflow completion) - - [ ] สร้าง Performance Interceptor: - - [ ] Track request duration - - [ ] Alert if response time > 200ms - - [ ] สร้าง Logging Service: - - [ ] Structured logging (JSON format) - - [ ] Log aggregation - - [ ] **Deliverable:** Monitoring system ทำงานได้ - - [ ] **Dependencies:** T1.1 (Base patterns) - -- **[ ] T6.4 ResilienceModule - Circuit Breaker & Retry** - - [ ] สร้าง Circuit Breaker Service: - - [ ] @CircuitBreaker() decorator สำหรับ external calls - - [ ] Configurable timeout และ error thresholds - - [ ] สร้าง Retry Service: - - [ ] @Retry() decorator ด้วย exponential backoff - - [ ] สร้าง Fallback Strategies: - - [ ] Graceful degradation สำหรับ non-critical features - - [ ] Implement สำหรับ: - - [ ] Email notifications - - [ ] LINE notifications - - [ ] Elasticsearch queries - - [ ] File virus scanning - - [ ] **Deliverable:** Resilience patterns ทำงานได้ - - [ ] **Dependencies:** T1.1 (Base patterns) - ---- - -## **Phase 7: Testing & Optimization (สัปดาห์ที่ 12-13)** - -**Milestone:** ทดสอบและปรับปรุงประสิทธิภาพพร้อม Security Audit - -### **Phase 7: Tasks- Testing Automation & CI/CD** - -- [ ] **Setup Test Environment:** - - [ ] Dockerized test database - - [ ] Test Redis instance - - [ ] Mock external services - - [ ] Test data management -- [ ] **CI/CD Pipeline:** - - [ ] GitHub Actions workflow - - [ ] Automated test execution - - [ ] Test reporting and metrics - - [ ] Quality gates - -- **Test Quality Gates** - -```yaml -# GitHub Actions Quality Gates -quality_gates: - unit_tests: - coverage: 80% - required: true - integration_tests: - scenarios: all_core - required: true - security_tests: - vulnerabilities: 0 - required: true - performance_tests: - response_time: 200ms - required: true -``` - -- **[ ] T7.1 Unit Testing** - - [ ] เขียน Unit Tests สำหรับ Services สำคัญ: - - [ ] AuthService (login, validateUser) - - [ ] RbacGuard (permission checks ทั้ง 4 ระดับ) - - [ ] DocumentNumberingService (Redis locking) - - [ ] FileStorageService (virus scanning, validation) - - [ ] CorrespondenceService (create, update, status transitions) - - [ ] RfaWorkflowService (workflow logic) - - [ ] **Security:** ทดสอบ security scenarios (SQL injection, XSS attempts) - - [ ] Target: 80% Code Coverage - - [ ] **Deliverable:** Unit Tests ผ่านทั้งหมด - - [ ] **Dependencies:** ทุก Development Tasks ใน Phase 1-6 ต้องเสร็จสิ้นก่อนเริ่มเขียน Tests อย่างจริงจัง (โดยเฉพาะ T1.4, T2.3, T3.1, T5.1) - -- **[ ] T7.2 Integration Testing** - - [ ] เขียน Integration Tests: - - [ ] Authentication Flow (login → access protected route) - - [ ] Document Creation Flow (create correspondence → attach files → virus scan) - - [ ] RFA Workflow Flow (start → step 1 → step 2 → complete) - - [ ] Circulation Flow (create → assign → complete → close) - - [ ] ทดสอบ SQL Views (v_user_all_permissions, v_user_tasks) - - [ ] ใช้ Test Database แยกต่างหาก - - [ ] **Security:** ทดสอบ rate limiting และ permission enforcement - - [ ] **Deliverable:** Integration Tests ผ่าน - - [ ] **Dependencies:** T7.1 (Unit Tests ควรผ่านก่อน) - -- **[ ] T7.3 E2E Testing** - - [ ] เขียน E2E Tests: - - [ ] User Registration & Login - - [ ] Create Correspondence (Full Flow) - - [ ] Create RFA with Shop Drawings - - [ ] Complete RFA Workflow - - [ ] Search Documents - - [ ] **Security:** ทดสอบ file upload security - - [ ] **Deliverable:** E2E Tests ผ่าน - - [ ] **Dependencies:** T7.2 (Integration Tests ควรผ่านก่อน) - -- **[ ] T7.4 Performance Testing** - - [ ] Load Testing: - - [ ] 100 concurrent users - - [ ] API response time < 200ms (90th percentile) - - [ ] Search performance < 500ms - - [ ] Stress Testing: - - [ ] Find breaking points - - [ ] Database connection limits - - [ ] Endurance Testing: - - [ ] 24-hour continuous operation - - [ ] **Deliverable:** Performance targets บรรลุ - - [ ] **Dependencies:** T7.3 (E2E Tests ควรผ่านก่อน) - -- **[ ] T7.5 Security Testing** - - [ ] Penetration Testing: - - [ ] OWASP Top 10 vulnerabilities - - [ ] SQL Injection attempts - - [ ] XSS attempts - - [ ] CSRF attempts - - [ ] Security Audit: - - [ ] Code review สำหรับ security flaws - - [ ] Dependency vulnerability scanning - - [ ] File Upload Security Testing: - - [ ] Virus scanning effectiveness - - [ ] File type bypass attempts - - [ ] **Deliverable:** Security tests ผ่าน - - [ ] **Dependencies:** T7.4 (Performance Tests ควรผ่านก่อน) - -- **[ ] T7.6 Performance Optimization** - - [ ] Implement Caching: - - [ ] Cache Master Data (Roles, Permissions, Organizations) - - [ ] Cache User Permissions - - [ ] Cache Search Results - - [ ] Database Optimization: - - [ ] Review Indexes - - [ ] Optimize Queries (N+1 Problem) - - [ ] Implement Pagination ทุก List Endpoint - - [ ] **Deliverable:** Response Time < 200ms (90th percentile) - - [ ] **Dependencies:** T7.4 (ผลจาก Performance Testing จะบอกว่าจุดไหนต้อง Optimization) - -### 📊 **Testing Metrics & Exit Criteria** - - **แต่ละ Phase ต้องผ่าน Metrics เหล่านี้:** - -#### **Phase Completion Metrics** - -- [ ] **Code Quality Metrics** - - [ ] Unit test coverage: ≥ 80% - - [ ] Integration test coverage: 100% core scenarios - - [ ] Static analysis: 0 critical issues - - [ ] Code duplication: < 5% - -- [ ] **Performance Metrics** - - [ ] API response time: < 200ms (90th percentile) - - [ ] Database query performance: < 100ms - - [ ] Memory usage: Within limits - - [ ] Concurrent users: Meets targets - -- [ ] **Security Metrics** - - [ ] Security vulnerabilities: 0 - - [ ] Authentication tests: 100% passed - - [ ] Authorization tests: 100% passed - - [ ] Data validation tests: 100% passed - -- [ ] **Business Metrics** - - [ ] Core workflows: 100% tested - - [ ] Edge cases: Covered - - [ ] Error scenarios: Handled appropriately - - [ ] User acceptance: Meets requirements - ---- - -## **Phase 8: Documentation & Deployment (สัปดาห์ที่ 14)** - -**Milestone:** เอกสารและ Deploy สู่ Production พร้อม Security Hardening - -### **Phase 8: Tasks** - -- **[ ] T8.1 API Documentation** - - [ ] ครบทุก Endpoint ใน Swagger: - - [ ] ใส่ Description, Example Request/Response - - [ ] ระบุ Required Permissions - - [ ] ใส่ Error Responses - - [ ] Export Swagger JSON → Frontend Team - - [ ] **Security:** เอกสารต้องไม่เปิดเผย sensitive information - - [ ] **Deliverable:** Swagger Docs สมบูรณ์ - - [ ] **Dependencies:** ทุก Development Tasks ต้องเสร็จสิ้น - -- **[ ] T8.2 Technical Documentation** - - [ ] เขียนเอกสาร: - - [ ] Architecture Overview - - [ ] Module Structure - - [ ] Database Schema Diagram - - [ ] API Design Patterns - - [ ] Security Implementation Guide - - [ ] Deployment Guide - - [ ] Disaster Recovery Procedures - - [ ] **Deliverable:** Technical Docs พร้อม - - [ ] **Dependencies:** T8.1 - -- **[ ] T8.3 Security Hardening** - - [ ] Final Security Review: - - [ ] Environment variables security - - [ ] Database encryption - - [ ] File storage security - - [ ] API security headers - - [ ] Implement Security Monitoring: - - [ ] Failed login attempts tracking - - [ ] Suspicious activity alerts - - [ ] Rate limiting monitoring - - [ ] **Deliverable:** Security checklist ผ่าน - - [ ] **Dependencies:** T7.5 (Security Testing ต้องผ่าน) - -- **[ ] T8.4 Deployment Preparation** - - [ ] สร้าง Production docker-compose.yml - - [ ] Setup Environment Variables ใน QNAP - - [ ] Setup Nginx Proxy Manager (SSL Certificate) - - [ ] Setup Backup Scripts (Database + Files) - - [ ] Setup Monitoring และ Alerting - - [ ] **Deliverable:** Deployment Guide พร้อม - - [ ] **Dependencies:** T8.2, T8.3 - -- **[ ] T8.5 Production Deployment** - - [ ] Deploy Backend ไปยัง backend.np-dms.work - - [ ] ทดสอบ API ผ่าน Postman - - [ ] Monitor Logs (Winston) - - [ ] Setup Health Check Endpoint (GET /health) - - [ ] Verify Security Measures: - - [ ] HTTPS enforcement - - [ ] Security headers - - [ ] Rate limiting - - [ ] Virus scanning - - [ ] **Deliverable:** Backend รันบน Production - - [ ] **Dependencies:** T8.4 - -- **[ ] T8.6 Handover to Frontend Team** - - [ ] Demo API ให้ Frontend Team - - [ ] ส่งมอบ Swagger Documentation - - [ ] ส่งมอบ Postman Collection - - [ ] Workshop: วิธีใช้ Authentication & RBAC - - [ ] **Deliverable:** Frontend เริ่มพัฒนาได้ - - [ ] **Dependencies:** T8.5 - ---- - -## 📊 **สรุป Timeline** - -| Phase | ระยะเวลา | จำนวนงาน | Output หลัก | -| ------- | -------------- | ------------ | ------------------------------------ | -| Phase 0 | 1 สัปดาห์ | 4 | Infrastructure Ready + Security Base | -| Phase 1 | 2 สัปดาห์ | 5 | Auth & User Management + RBAC | -| Phase 2 | 1 สัปดาห์ | 4 | Security & File Management | -| Phase 3 | 2 สัปดาห์ | 3 | Correspondence & RFA Core | -| Phase 4 | 1 สัปดาห์ | 2 | Drawing Management | -| Phase 5 | 2 สัปดาห์ | 3 | Workflow Systems + Resilience | -| Phase 6 | 2 สัปดาห์ | 4 | Advanced Features + Monitoring | -| Phase 7 | 2 สัปดาห์ | 6 | Testing & Optimization | -| Phase 8 | 1 สัปดาห์ | 6 | Documentation & Deploy | -| **รวม** | **14 สัปดาห์** | **37 Tasks** | **Production-Ready Backend** | - ---- - -## 🎯 **Critical Success Factors** - -1. **Security First:** ทุก Task ต้องพิจารณาด้านความปลอดภัยเป็นหลัก -2. **Database Integrity:** ใช้ Schema v1.4.1 เป็นหลัก ไม่แก้ไข Schema โดยไม่จำเป็น -3. **Soft Delete:** Service ทั้งหมดต้องใช้ Global Filter กรอง WHERE deleted_at IS NULL -4. **API Contract:** ทุก Endpoint ต้องมี Swagger Documentation สมบูรณ์ -5. **Security Compliance:** RBAC ต้องทำงานถูกต้อง 100% ก่อน Deploy -6. **Testing Coverage:** Code Coverage อย่างน้อย 80% ก่อน Production -7. **Performance Targets:** Response Time < 200ms (90th percentile) -8. **Resilience:** ระบบต้องทนทานต่อ failures ของ external services -9. **Monitoring:** ต้องมี comprehensive monitoring และ alerting -10. **Documentation:** เอกสารต้องครบถ้วนเพื่อ Handover ให้ Frontend Team - ---- - -## 🚀 **ขั้นตอนถัดไป** - -1. **Approve แผนนี้** → ปรับแต่งตาม Feedback -2. **Setup Phase 0** → เริ่มสร้าง Infrastructure -3. **Daily Standup** → รายงานความก้าวหน้าทุกวัน -4. **Weekly Review** → ทบทวนความก้าวหน้าทุกสัปดาห์ -5. **Security Review** → ทุก Phase ต้องผ่าน security review -6. **Deploy to Production** → Week 14 - ---- - -## 📋 **Security Checklist ทุก Phase** - -- **Phase 1-2: Foundation Security** - - [ ] Input validation implemented - - [ ] XSS protection enabled - - [ ] CSRF protection implemented - - [ ] Rate limiting configured - - [ ] Secure password hashing (bcrypt) - -- **Phase 3-5: Application Security** - - [ ] RBAC 4-level working correctly - - [ ] File upload security (virus scanning, type validation) - - [ ] Audit logging for critical operations - - [ ] SQL injection prevention - -- **Phase 6-8: Production Security** - - [ ] HTTPS enforcement - - [ ] Security headers configured - - [ ] Environment variables secured - - [ ] Monitoring and alerting active - - [ ] Backup and recovery tested - -## **หมายเหตุ:** แผนนี้สามารถปรับแต่งได้ตามความต้องการและข้อจำกัดของทีม หาก Phase ใดใช้เวลามากกว่าที่คาดการณ์ ควรปรับ Timeline ให้เหมาะสม โดยให้ความสำคัญกับ Security และ Quality +# 📋 **แผนการพัฒนา Backend (NestJS) - LCBP3-DMS v1.4.1 (ปรับปรุงโดย deepseek)** + +**ปรับปรุงตาม Requirements v1.4.0 ที่อัปเดตแล้ว* +**Routing และ รูปแบบ JSON details** + +--- + +## 🎯 **ภาพรวมโครงการ** + +พัฒนา Backend สำหรับระบบบริหารจัดการเอกสารโครงการ (Document Management System) ที่รองรับการจัดการเอกสารที่ซับซ้อน มีระบบ Workflow การอนุมัติ และการควบคุมสิทธิ์แบบ RBAC 4 ระดับ พร้อมมาตรการความปลอดภัยที่ทันสมัย + +--- + +## 📐 **สถาปัตยกรรมระบบ** + +### **Technology Stack** + +- **Framework:** NestJS (TypeScript, ESM) +- **Database:** MariaDB 10.11 +- **ORM:** TypeORM +- **Authentication:** JWT + Passport +- **Authorization:** CASL (RBAC 4-level) +- **File Upload:** Multer + Virus Scanning (ClamAV) +- **Search:** Elasticsearch +- **Notification:** Nodemailer + n8n (Line Integration) +- **Caching:** Redis +- **Resilience:** Circuit Breaker, Retry Patterns +- **Security:** Helmet, CSRF Protection, Rate Limiting +- **Monitoring:** Winston, Health Checks, Metrics +- **Scheduling:** @nestjs/schedule (Cron Jobs) +- **Documentation:** Swagger + +### **โครงสร้างโมดูล (Domain-Driven)** + +```tree +src/ +├── common/ # Shared Module +│ ├── auth/ # JWT, Guards, RBAC +│ ├── config/ # Configuration Management +│ ├── decorators/ # @RequirePermission, @RateLimit +│ ├── entities/ # Base Entities +│ ├── exceptions/ # Global Filters +│ ├── file-storage/ # FileStorageService (Virus Scanning) +│ ├── guards/ # RBAC Guard, RateLimitGuard +│ ├── interceptors/ # Audit, Transform, Performance +│ ├── resilience/ # Circuit Breaker, Retry Patterns +│ ├── security/ # Input Validation, XSS Protection +│ └── services/ # Notification, Caching, Monitoring +├── modules/ +│ ├── user/ # Users, Roles, Permissions +│ ├── project/ # Projects, Contracts, Organizations +│ ├── master/ # Master Data Management +│ ├── correspondence/ # Correspondence Management +│ ├── rfa/ # RFA & Workflows +│ ├── drawing/ # Shop/Contract Drawings +│ ├── circulation/ # Internal Circulation +│ ├── transmittal/ # Transmittals +│ ├── search/ # Elasticsearch +│ ├── monitoring/ # Metrics, Health Checks +│ └── document-numbering/ # Internal Service (Redis Locking) +└── database/ # Migrations & Seeds +``` + +--- + +## 🗓️ **แผนการพัฒนาแบบ Phase-Based** + +### **Dependency Diagram (ภาพรวม)** + + ```mermaid + %% Phase 0: Infrastructure + subgraph Phase 0 [Phase 0: Infrastructure Setup] + T0_1[T0.1: Setup QNAP Container Station] + T0_2[T0.2: Initialize NestJS Project] + T0_3[T0.3: Setup Database Connection] + T0_4[T0.4: Setup Git Repository] + end + + %% Phase 1: Core Foundation + subgraph Phase 1 [Phase 1: Core Foundation & Security] + T1_1[T1.1: CommonModule - Base Infrastructure] + T1_2[T1.2: AuthModule - JWT Authentication] + T1_3[T1.3: UserModule - User Management] + T1_4[T1.4: RBAC Guard - 4-Level Authorization] + T1_5[T1.5: ProjectModule - Base Structures] + end + + %% Phase 2: Security & File Management + subgraph Phase 2 [Phase 2: Security & File Management] + T2_1[T2.1: MasterModule - Master Data Management] + T2_2[T2.2: FileStorageService - Secure File Management] + T2_3[T2.3: DocumentNumberingModule - App-Level Locking] + T2_4[T2.4: SecurityModule - Enhanced Security] + T2_5[T2.5: JSON Details & Schema Management] + end + + %% Phase 3: Correspondence & RFA Core + subgraph Phase 3 [Phase 3: Correspondence & RFA Core] + T3_1[T3.1: CorrespondenceModule - Basic CRUD] + T3_2[T3.2: CorrespondenceModule - Advanced Features] + T3_3[T3.3: RfaModule - Basic CRUD] + T3_4[T3.4: Correspondence Routing] + end + + %% Phase 4: Drawing Management + subgraph Phase 4 [Phase 4: Drawing Management] + T4_1[T4.1: DrawingModule - Contract Drawings] + T4_2[T4.2: DrawingModule - Shop Drawings] + end + + %% Phase 5: Workflow Systems & Resilience + subgraph Phase 5 [Phase 5: Workflow Systems & Resilience] + T5_1[T5.1: RfaModule - Workflow Implementation] + T5_2[T5.2: CirculationModule - Internal Routing] + T5_3[T5.3: TransmittalModule - Document Forwarding] + end + + %% Phase 6: Advanced Features & Monitoring + subgraph Phase 6 [Phase 6: Advanced Features & Monitoring] + T6_1[T6.1: SearchModule - Elasticsearch Integration] + T6_2[T6.2: NotificationModule - Email & Line] + T6_3[T6.3: MonitoringModule - Observability] + T6_4[T6.4: ResilienceModule - Circuit Breaker & Retry] + end + + %% Phase 7: Testing & Optimization + subgraph Phase 7 [Phase 7: Testing & Optimization] + T7_1[T7.1: Unit Testing] + T7_2[T7.2: Integration Testing] + T7_3[T7.3: E2E Testing] + T7_4[T7.4: Performance Testing] + T7_5[T7.5: Security Testing] + T7_6[T7.6: Performance Optimization] + end + + %% Phase 8: Documentation & Deployment + subgraph Phase 8 [Phase 8: Documentation & Deployment] + T8_1[T8.1: API Documentation] + T8_2[T8.2: Technical Documentation] + T8_3[T8.3: Security Hardening] + T8_4[T8.4: Deployment Preparation] + T8_5[T8.5: Production Deployment] + T8_6[T8.6: Handover to Frontend Team] + end + + %% Dependencies + T0_1 --> T0_2 + T0_2 --> T0_3 + T0_3 --> T0_4 + + T0_2 --> T1_1 + T0_3 --> T1_1 + T1_1 --> T1_2 + T1_1 --> T1_3 + T1_1 --> T1_4 + T1_1 --> T1_5 + T1_2 --> T1_3 + T1_3 --> T1_4 + + T0_3 --> T2_1 + T1_1 --> T2_1 + T1_5 --> T2_1 + T1_1 --> T2_2 + T1_4 --> T2_2 + T1_1 --> T2_3 + T1_1 --> T2_4 + T1_1 --> T2_5 + + T1_1 --> T3_1 + T1_2 --> T3_1 + T1_3 --> T3_1 + T1_4 --> T3_1 + T1_5 --> T3_1 + T2_3 --> T3_1 + T2_2 --> T3_1 + T2_5 --> T3_1 + T3_1 --> T3_2 + T3_1 --> T3_3 + T1_5 --> T3_3 + T3_1 --> T3_4 + T2_5 --> T3_4 + + T1_1 --> T4_1 + T1_2 --> T4_1 + T1_4 --> T4_1 + T1_5 --> T4_1 + T2_2 --> T4_1 + T4_1 --> T4_2 + + T3_3 --> T5_1 + T4_2 --> T5_1 + T2_5 --> T5_1 + T3_1 --> T5_2 + T2_5 --> T5_2 + T3_1 --> T5_3 + + T3_1 --> T6_1 + T3_3 --> T6_1 + T4_2 --> T6_1 + T5_2 --> T6_1 + T5_3 --> T6_1 + T1_1 --> T6_2 + T6_4 --> T6_2 + T1_1 --> T6_3 + T1_1 --> T6_4 + + %% All development phases must be complete before testing + T1_5 --> T7_1 + T2_5 --> T7_1 + T3_4 --> T7_1 + T4_2 --> T7_1 + T5_3 --> T7_1 + T6_4 --> T7_1 + T7_1 --> T7_2 + T7_2 --> T7_3 + T7_3 --> T7_4 + T7_4 --> T7_5 + T7_5 --> T7_6 + + %% Testing must be complete before deployment + T7_6 --> T8_1 + T8_1 --> T8_2 + T8_2 --> T8_3 + T8_3 --> T8_4 + T8_4 --> T8_5 + T8_5 --> T8_6 + ``` + +## **Phase 0: Infrastructure Setup (สัปดาห์ที่ 1)** + +**Milestone:** สร้างโครงสร้างพื้นฐานและเชื่อมต่อ Services พร้อม Security Baseline + +### **Phase 0: Tasks** + +- **[✅] T0.1 Setup QNAP Container Station** + - [✅]สร้าง Docker Network: `lcbp3` + - [✅]Setup docker-compose.yml สำหรับ: + - [✅]MariaDB (db.np-dms.work) -> MariaDB_setting.md + - [✅]PHPMyAdmin (pma.np-dms.work) -> MariaDB_setting.md + - [✅]Gitea (git.np-dms.work) -> Gitea_setting.md + - [✅]Nginx Proxy Manager (npm.np-dms.work) -> NPM_setting.md + - [✅]Backend (backend.np-dms.work) + - [✅]Redis + - [✅]Elasticsearch + - กำหนด Environment Variables ใน docker-compose.yml (ไม่ใช้ .env) + - **Security:** Setup network segmentation และ firewall rules + - [✅] **Deliverable:** Services ทั้งหมดรันได้และเชื่อมต่อกันผ่าน Network + - **Dependencies:** None (Task เริ่มต้น) + +- **[✅] T0.2 Initialize NestJS Project** + - [ ] สร้างโปรเจกต์ใหม่ด้วย Nest CLI + - [ ] ติดตั้ง Dependencies: + + ```bash + # Core + npm install @nestjs/core @nestjs/common @nestjs/platform-express + npm install @nestjs/typeorm typeorm mysql2 + npm install @nestjs/config class-validator class-transformer + + # Auth & Security + npm install @nestjs/jwt @nestjs/passport passport passport-jwt + npm install casl helmet csurf rate-limiter-flexible bcrypt crypto + + # File & Search + npm install multer @nestjs/elasticsearch @elastic/elasticsearch + npm install clamscan @types/multer + + # Resilience & Caching + npm install @nestjs/cache-manager cache-manager cache-manager-redis-store + npm install @nestjs/circuit-breaker + + # Monitoring & Scheduling + npm install @nestjs/schedule @nestjs/monitoring winston + + # Documentation + npm install @nestjs/swagger + + # Development + npm install --save-dev @nestjs/testing jest @types/jest supertest + npm install --save-dev @types/passport-jwt @types/bcrypt @types/crypto + ``` + + - Setup โครงสร้างโฟลเดอร์ตาม Domain-Driven Architecture + - **Security:** Initialize security headers และ CORS configuration + - [ ] **Deliverable:** Project Structure พร้อม, แสดง Swagger ที่ `/api` + - **Dependencies:** T0.1 (ต้องมี Docker Network และ Environment พร้อมก่อนสร้าง Project) + +- **[✅] T0.3 Setup Database Connection** + + - Import SQL Schema v1.4.0 เข้า MariaDB + - Run Seed Data (organizations, users, roles, permissions) + - Configure TypeORM ใน AppModule + - **Security:** Setup database connection encryption + - ทดสอบ Connection + - [ ] **Deliverable:** Database พร้อมใช้งาน, มี Seed Data + - **Dependencies:** T0.1 (ต้องมี MariaDB Container รันแล้ว), T0.2 (ต้องมี NestJS Project พร้อมสำหรับตั้งค่า TypeORM) + +- **[✅] T0.4 Setup Git Repository** + - สร้าง Repository ใน Gitea (git.np-dms.work) + - Setup .gitignore, README.md, SECURITY.md + - Commit Initial Project + - [ ] **Deliverable:** Code อยู่ใน Version Control + - **Dependencies:** T0.2 (ต้องมี Project และโครงสร้างพื้นฐานก่อนจะ Commit) + +### **Phase 0: Testing - Infrastructure Validation** + +#### **T0.T1 Database Connectivity Tests** + +- [ ] **Unit Tests:** + - [ ] Test database connection configuration + - [ ] Test connection pooling settings + - [ ] Test connection error handling +- [ ] **Integration Tests:** + - [ ] Test actual database connection + - [ ] Test database migrations + - [ ] Test seed data loading + - [ ] Test backup/restore procedures +- [ ] **Performance Tests:** + - [ ] Test connection acquisition time < 100ms + - [ ] Test concurrent connections handling +- **Exit Criteria:** Database tests 100% passed + +#### **T0.T2 Service Connectivity Tests** + +- [ ] **Integration Tests:** + - [ ] Test Docker network connectivity + - [ ] Test inter-service communication + - [ ] Test Nginx proxy configuration + - [ ] Test SSL certificate setup +- [ ] **Security Tests:** + - [ ] Test firewall rules + - [ ] Test port exposure + - [ ] Test environment variables security +- **Exit Criteria:** All services can communicate securely + +#### **T0.T3 Project Setup Tests** + +- [ ] **Unit Tests:** + - [ ] Test NestJS project structure + - [ ] Test dependency configurations + - [ ] Test build process +- [ ] **Integration Tests:** + - [ ] Test Swagger documentation generation + - [ ] Test health check endpoints + - [ ] Test error handling setup +- **Exit Criteria:** Project setup verified and documented + +--- + +## **Phase 1: Core Foundation & Security (สัปดาห์ที่ 2-3)** + +**Milestone:** ระบบ Authentication, Authorization, Security Baseline และ Base Entities + +### **Phase 1: Tasks** + +- **[ ] T1.1 CommonModule - Base Infrastructure** + - [ ] สร้าง Base Entity (id, created_at, updated_at, deleted_at) + - [ ] สร้าง Global Exception Filter (ไม่เปิดเผย sensitive information) + - [ ] สร้าง Response Transform Interceptor + - [ ] สร้าง Audit Log Interceptor + - [ ] สร้าง RequestContextService - สำหรับเก็บข้อมูลระหว่าง Request + - [ ] สร้าง ConfigService - Centralized configuration management + - [ ] สร้าง CryptoService - สำหรับ encryption/decryption + - [ ] **Security:** Implement input validation pipeline + - [ ] **Deliverable:** Common Services พร้อมใช้ + - [ ] **Dependencies:** T0.2, T0.3 (ต้องมี Project และ Database Connection พร้อมสำหรับสร้าง Base Entity และ Services) + +- **[ ] T1.2 AuthModule - JWT Authentication** + - [ ] สร้าง Entity: User + - [ ] สร้าง AuthService: + - [ ] login(username, password) → JWT Token + - [ ] validateUser(username, password) → User | null + - [ ] Password Hashing (bcrypt) + salt + - [ ] สร้าง JWT Strategy (Passport) + - [ ] สร้าง JwtAuthGuard + - [ ] สร้าง Controllers: + - [ ] POST /auth/login → { access_token, refresh_token } + - [ ] POST /auth/register → Create User (Admin only) + - [ ] POST /auth/refresh → Refresh token + - [ ] POST /auth/logout → Revoke token + - [ ] GET /auth/profile (Protected) + - [ ] **Security:** Implement rate limiting สำหรับ authentication endpoints + - [ ] **Deliverable:** ล็อกอิน/ล็อกเอาต์ทำงานได้อย่างปลอดภัย + - [ ] **Dependencies:** T1.1 (ต้องใช้ Base Entity, ConfigService, CryptoService), T0.3 (ต้องเชื่อมต่อกับ User table) + +- **[ ] T1.3 UserModule - User Management** + - [ ] สร้าง Entities: User, Role, Permission, UserRole, UserAssignment + - [ ] สร้าง UserService CRUD (พร้อม soft delete) + - [ ] สร้าง RoleService CRUD + - [ ] สร้าง PermissionService (Read-Only, จาก Seed) + - [ ] สร้าง UserAssignmentService - สำหรับจัดการ user assignments ตาม scope + - [ ] สร้าง Controllers: + - [ ] GET /users → List Users (Paginated) + - [ ] GET /users/:id → User Detail + - [ ] POST /users → Create User (ต้องบังคับเปลี่ยน password ครั้งแรก) + - [ ] PUT /users/:id → Update User + - [ ] DELETE /users/:id → Soft Delete + - [ ] GET /roles → List Roles + - [ ] POST /roles → Create Role (Admin) + - [ ] PUT /roles/:id/permissions → Assign Permissions + - [ ] **Security:** Implement permission checks สำหรับ user management + - [ ] **Deliverable:** จัดการผู้ใช้และ Role ได้ + - [ ] **Dependencies:** T1.1 (Base Entity, Global Exception Filter), T1.2 (สำหรับ Authentication และ Authorization) + +- **[ ] T1.4 RBAC Guard - 4-Level Authorization** + - [ ] สร้าง @RequirePermission() Decorator + - [ ] สร้าง RbacGuard ที่ตรวจสอบ 4 ระดับ: + - [ ] Global Permissions + - [ ] Organization Permissions + - [ ] Project Permissions + - [ ] Contract Permissions + - [ ] Permission Hierarchy Logic: + - [ ] Integration กับ CASL + - [ ] **Security:** Implement audit logging สำหรับ permission checks + - [ ] **Deliverable:** ระบบสิทธิ์ทำงานได้ทั้ง 4 ระดับ + - [ ] **Dependencies:** T1.1 (Decorators, RequestContextService), T1.3 (ต้องมีโครงสร้าง User, Role, Permission ที่สมบูรณ์) + +- **[ ] T1.5 ProjectModule - Base Structures** + - [ ] สร้าง Entities: + - [ ] Organization + - [ ] Project + - [ ] Contract + - [ ] ProjectOrganization (Junction) + - [ ] ContractOrganization (Junction) + - [ ] สร้าง Services & Controllers: + - [ ] GET /organizations → List + - [ ] POST /projects → Create (Superadmin) + - [ ] GET /projects/:id/contracts → List Contracts + - [ ] POST /projects/:id/contracts → Create Contract + - [ ] **Security:** Implement data isolation ระหว่าง organizations + - [ ] **Deliverable:** จัดการโครงสร้างโปรเจกต์ได้ + - [ ] **Dependencies:** T1.1 (Base Entity, Security), T1.2 (สำหรับการป้องกันการเข้าถึง), T0.3 (ต้องเชื่อมต่อกับ project/organization tables) + +### **Phase 1: Testing - Core Foundation** + +#### **T1.T1 Authentication Test Suite** + +- [ ] **Unit Tests (25+ test cases):** + - [ ] AuthService.authenticate() - success and failure cases + - [ ] AuthService.validateUser() - various user states + - [ ] JWT token generation and validation + - [ ] Password hashing and verification + - [ ] Token refresh mechanism +- [ ] **Integration Tests (15+ test cases):** + - [ ] Complete login/logout flow + - [ ] Token expiration handling + - [ ] Concurrent session management + - [ ] Rate limiting on auth endpoints +- [ ] **Security Tests (10+ test cases):** + - [ ] SQL injection attempts on login + - [ ] Brute force attack simulation + - [ ] Token tampering attempts + - [ ] Session fixation tests +- [ ] **Performance Tests:** + - [ ] Login response time < 500ms under load + - [ ] Token validation < 50ms +- **Exit Criteria:** Authentication system secure and performant + +#### **T1.T2 RBAC Test Suite** + +- [ ] **Unit Tests (30+ test cases):** + - [ ] RbacGuard - all 4 permission levels + - [ ] Permission hierarchy logic + - [ ] Role-permission mappings + - [ ] Scope-based access control +- [ ] **Integration Tests (20+ test cases):** + - [ ] End-to-end permission checks + - [ ] Multi-organization access control + - [ ] Project/contract scope isolation + - [ ] Permission escalation attempts +- [ ] **Security Tests (15+ test cases):** + - [ ] Unauthorized access attempts + - [ ] Privilege escalation attempts + - [ ] Role manipulation attempts +- **Exit Criteria:** RBAC system working correctly for all scenarios + +#### **T1.T3 User Management Test Suite** + +- [ ] **Unit Tests (20+ test cases):** + - [ ] User CRUD operations + - [ ] Role assignment logic + - [ ] Soft delete functionality + - [ ] User search and filtering +- [ ] **Integration Tests (15+ test cases):** + - [ ] User creation with role assignment + - [ ] User deactivation workflow + - [ ] Bulk user operations + - [ ] User permission inheritance +- **Exit Criteria:** User management complete and secure + +--- + +## **Phase 2: Security & File Management (สัปดาห์ที่ 4)** + +**Milestone:** Master Data, ระบบจัดการไฟล์ที่มีความปลอดภัย, Document Numbering, JSON details system พร้อมใช้งาน พร้อม validation และ security + +### **Phase 2: Tasks** + +- **[ ] T2.1 MasterModule - Master Data Management** + - [ ] สร้าง Entities: + - [ ] CorrespondenceType + - [ ] CorrespondenceStatus + - [ ] RfaType + - [ ] RfaStatusCode + - [ ] RfaApproveCode + - [ ] CirculationStatusCode + - [ ] Tag + - [ ] สร้าง Services & Controllers (CRUD): + - [ ] GET /master/correspondence-types + - [ ] POST /master/tags → Create Tag + - [ ] GET /master/tags → List Tags (Autocomplete) + - [ ] **Security:** Implement admin-only access สำหรับ master data + - [ ] **Deliverable:** Admin จัดการ Master Data ได้ + - [ ] **Dependencies:** T0.3 (ต้องเชื่อมต่อกับ master tables), T1.1 (Security patterns), T1.5 (Project context สำหรับ master data บางอย่าง) + +- **[ ] T2.2 FileStorageService - Secure File Management** + - [ ] สร้าง Attachment Entity + - [ ] สร้าง FileStorageService: + - [ ] uploadFile(file: Express.Multer.File, userId: number)` → Attachment + - [ ] Virus scanning ด้วย ClamAV + - [ ] File type validation (white-list: PDF, DWG, DOCX, XLSX, PPTX, ZIP) + - [ ] File size check (max 50MB) + - [ ] Generate checksum (SHA-256) + - [ ] getFilePath(attachmentId)` → string + - [ ] deleteFile(attachmentId)` → boolean + - [ ] จัดเก็บไฟล์ใน /share/dms-data/uploads/{YYYY}/{MM}/ + - [ ] สร้าง Controller: + - [ ] POST /files/upload → { attachment_id, url } (Protected) + - [ ] GET /files/:id/download → File Stream (Protected + Expiration) + - [ ] **Security:** Access Control - ตรวจสอบสิทธิ์ผ่าน Junction Table + - [ ] **Deliverable:** อัปโหลด/ดาวน์โหลดไฟล์ได้อย่างปลอดภัย + - [ ] **Dependencies:** T1.1 (Base Entity สำหรับ Attachment, CryptoService สำหรับ checksum), T1.4 (RBAC Guard สำหรับการควบคุมการเข้าถึงไฟล์) + +- **[ ] T2.3 DocumentNumberingModule - Application-Level Locking** + - [ ] สร้าง Entities: + - [ ] DocumentNumberFormat + - [ ] DocumentNumberCounter + - [ ] สร้าง DocumentNumberingService: + - [ ] generateNextNumber(projectId, orgId, typeId, year) → string + - [ ] ใช้ **Redis distributed locking** แทน stored procedure + - [ ] Retry mechanism ด้วย exponential backoff + - [ ] Fallback mechanism เมื่อการขอเลขล้มเหลว + - [ ] Format ตาม Template: {ORG_CODE}-{TYPE_CODE}-{YEAR_SHORT}-{SEQ:4} + - **ไม่มี Controller** (Internal Service เท่านั้น) + - [ ] **Security:** Implement audit log ทุกครั้งที่มีการ generate เลขที่ + - [ ] **Deliverable:** Service สร้างเลขที่เอกสารได้ถูกต้องและปลอดภัย + - [ ] **Dependencies:** T1.1 (Base patterns, Audit Log), T0.3 (ต้องเชื่อมต่อกับ document_number_formats/counters) + +- **[ ] T2.4 SecurityModule - Enhanced Security** + - [ ] สร้าง Input Validation Service: + - [ ] XSS Prevention + - [ ] SQL Injection Prevention + - [ ] CSRF Protection + - [ ] สร้าง RateLimitGuard: + - [ ] Implement rate limiting ตาม strategy (anonymous: 100/hr, authenticated: 500-5000/hr) + - [ ] Different limits สำหรับ endpoints ต่างๆ + - [ ] สร้าง Security Headers Middleware + - [ ] **Security:** Implement content security policy (CSP) + - [ ] **Deliverable:** Security layers ทำงานได้ + - [ ] **Dependencies:** T1.1 (Input Validation Pipeline) + +### **Phase 2.5: JSON Details & Schema Management (สัปดาห์ที่ 4)** + +- [ ]Dependencies: T1.1 (Validation patterns, Security) +- **[ ] T2.5.1 JsonSchemaModule - Schema Management** + - [ ] สร้าง JsonSchemaService: + - [ ] validate(schemaId: string, data: any): ValidationResult + - [ ] getSchema(schemaId: string, version?: string): object + - [ ] registerSchema(schemaId: string, schema: object): void + - [ ] migrateData(data: any, fromVersion: string, toVersion: string): any + - [ ] สร้าง predefined schemas สำหรับ: + - [ ] Correspondence types (RFI, RFA, TRANSMITTAL, etc.) + - [ ] Routing types (TEMPLATE, INSTANCE, ACTION) + - [ ] Audit types (AUDIT_LOG, SECURITY_SCAN) + - [ ] Implement schema versioning และ compatibility + - [ ] **Deliverable:** JSON schema system ทำงานได้ + +- **[ ] T2.5.2 DetailsService - Data Processing** + - [ ] สร้าง DetailsService: + - [ ] processDetails(type: string, input: any): ProcessedDetails + - [ ] sanitize(input: any): any (XSS prevention, SQL injection protection) + - [ ] compress(data: any): string (JSON compression) + - [ ] decompress(compressed: string): any + - [ ] Implement data transformation pipelines: + - [ ] Input validation และ sanitization + - [ ] Data normalization + - [ ] Default value population + - [ ] **Deliverable:** Data processing service ทำงานได้ + +- **[ ] T2.5.3 JSON Security & Validation** + - [ ] สร้าง SecurityService สำหรับ JSON: + - [ ] sanitizeJson(input: any): any (Remove dangerous properties) + - [ ] validateSize(data: any): boolean (Max 50KB check) + - [ ] encryptSensitiveFields(data: any): any + - [ ] Implement validation rules: + - [ ] Type validation + - [ ] Format validation (email, date, URL) + - [ ] Custom validation rules + - [ ] **Deliverable:** JSON security measures ทำงานได้ + +- **T2.5.4 Integration with Existing Modules** + - [ ] Integrate กับ CorrespondenceModule: + - [ ] Auto-validate details ก่อน save + - [ ] Auto-populate default values + - [ ] Handle version migration + - [ ] Integrate กับ RoutingModule: + - [ ] Validate routing configuration details + - [ ] Process step action details + - [ ] Integrate กับ AuditModule: + - [ ] Validate audit log details + - [ ] Compress large audit data + - [ ] **Deliverable:** JSON details integrated กับทุก modules + +### **Phase 2: Testing - Security & File Management** + +#### **T2.T1 File Upload Security Test Suite** + +- [ ] **Unit Tests (15+ test cases):** + - [ ] File type validation (white-list) + - [ ] File size validation + - [ ] Virus scanning integration + - [ ] Checksum generation +- [ ] **Integration Tests (10+ test cases):** + - [ ] Complete file upload flow + - [ ] File download with access control + - [ ] Concurrent file operations + - [ ] File cleanup procedures +- [ ] **Security Tests (20+ test cases):** + - [ ] Malicious file upload attempts + - [ ] Path traversal attacks + - [ ] File type spoofing + - [ ] Access control bypass attempts +- [ ] **Performance Tests:** + - [ ] File upload < 30s for 50MB files + - [ ] Concurrent upload handling +- **Exit Criteria:** File system secure and performant + +#### **T2.T2 JSON Schema Test Suite** + +- [ ] **Unit Tests (25+ test cases):** + - [ ] JSON schema validation + - [ ] Schema versioning + - [ ] Data transformation + - [ ] Default value population +- [ ] **Integration Tests (15+ test cases):** + - [ ] End-to-end JSON processing + - [ ] Schema migration scenarios + - [ ] Error handling and recovery + - [ ] Backward compatibility +- [ ] **Security Tests (10+ test cases):** + - [ ] JSON injection attempts + - [ ] Schema manipulation + - [ ] Large payload attacks +- **Exit Criteria:** JSON system robust and secure + +#### **T2.T3 Document Numbering Test Suite** + +- [ ] **Unit Tests (10+ test cases):** + - [ ] Redis locking mechanism + - [ ] Number generation logic + - [ ] Retry mechanism + - [ ] Error scenarios +- [ ] **Integration Tests (8+ test cases):** + - [ ] Concurrent number generation + - [ ] Database transaction handling + - [ ] Failure recovery +- [ ] **Performance Tests:** + - [ ] Number generation < 100ms under load + - [ ] Concurrent request handling +- **Exit Criteria:** Document numbering system race-condition free + +--- + +## **Phase 3: Correspondence & RFA Core (สัปดาห์ที่ 5-6)** + +**Milestone:** ระบบเอกสารโต้ตอบและ RFA พร้อม Security และ Audit, ระบบส่งต่อเอกสารระหว่างองค์กรทำงานได้ + +### **Phase 3A: Tasks (สัปดาห์ที่ 5)** + +- **[ ] T3.1 CorrespondenceModule - Basic CRUD** + - [ ] สร้าง Entities: + - [ ] Correspondence + - [ ] CorrespondenceRevision + - [ ] CorrespondenceRecipient + - [ ] CorrespondenceTag + - [ ] CorrespondenceReference + - [ ] CorrespondenceAttachment + - [ ] สร้าง CorrespondenceService: + - [ ] create(dto) → Correspondence + - [ ] สร้าง Correspondence + Revision แรก (rev 0) + - [ ] เรียก DocumentNumberingService (Redis locking) + - [ ] สร้าง Recipients (TO/CC) + - [ ] สร้าง Tags + - [ ] สร้าง Attachments (ผ่าน FileStorageService) + - [ ] update(id, dto) → Correspondence + - [ ] สร้าง Revision ใหม่ + - [ ] Update is_current flag + - [ ] findAll(filters) → Paginated List + - [ ] findById(id) → Correspondence with Current Revision + - [ ] สร้าง Controllers: + - [ ] POST /correspondences → Create + - [ ] GET /correspondences → List (Filter by type, status, org) + - [ ] GET /correspondences/:id → Detail + - [ ] PUT /correspondences/:id → Update (Create new revision) + - [ ] DELETE /correspondences/:id → Soft Delete (Admin only) + - [ ] **Security:** Implement permission checks สำหรับ document access + - [ ] **Deliverable:** สร้าง/แก้ไข/ดูเอกสารได้ + - [ ] **Dependencies:** T1.1 (Base Entity, Audit, Transform), T1.2 (Authentication), T1.3 (User context), T1.4 (RBAC), T1.5 (Project/Organization context), T2.3 (DocumentNumberingService), T2.2 (FileStorageService), T2.5 (JSON Details Validation) + +- **[ ] T3.2 CorrespondenceModule - Advanced Features** + - [ ] Implement Status Transitions: + - [ ] DRAFT → SUBMITTED (Document Control) + - [ ] SUBMITTED → CLOSED (Admin) + - [ ] SUBMITTED → CANCELLED (Admin + Reason) + - [ ] Implement References: + - [ ] POST /correspondences/:id/references → Link Documents + - [ ] Implement Search (Basic): + - [ ] GET /correspondences/search?q=... + - [ ] **Security:** Implement state transition validation + - [ ] **Deliverable:** Workflow พื้นฐานทำงานได้ + - [ ] **Dependencies:** T3.1 (ต้องมี Basic CRUD ก่อน) + +- **[ ] T3.3 RfaModule - Basic CRUD** + - [ ] สร้าง Entities: + - [ ] Rfa + - [ ] RfaRevision + - [ ] RfaItem (Junction to Shop Drawings) + - [ ] สร้าง RfaService: + - [ ] create(dto) → Rfa + - [ ] สร้าง Correspondence + Rfa + RfaRevision + - [ ] เชื่อม Shop Drawing Revisions (สำหรับ RFA_DWG) + - [ ] findAll(filters) → Paginated List + - [ ] findById(id) → Rfa with Items + - [ ] สร้าง Controllers: + - [ ] POST /rfas → Create + - [ ] GET /rfas → List + - [ ] GET /rfas/:id → Detail + - [ ] **Security:** Implement permission checks สำหรับ RFA operations + - [ ] **Deliverable:** สร้าง RFA และเชื่อม Shop Drawings ได้ + - [ ] **Dependencies:** T3.1 (RFA คือ Correspondence ประเภทหนึ่ง), T1.5 (Project context), T4.2 (สำหรับการเชื่อมโยงกับ Shop Drawings) + +### **Phase 3B: Correspondence Routing (สัปดาห์ที่ 6)** + +- [ ] **Dependencies:** T3.1 (ต้องมี Correspondence ก่อนจะส่งต่อได้), T2.5 (สำหรับ JSON Details ของ Routing) + +- **[ ] T3.4.1 CorrespondenceRoutingModule - Template Management** + - [ ] สร้าง Entities: + - [ ] CorrespondenceRoutingTemplate + - [ ] CorrespondenceRoutingTemplateStep + - [ ] สร้าง Services: + - [ ] createTemplate(dto) → Create routing template + - [ ] addStep(templateId, stepDto) → Add step to template + - [ ] getTemplates(projectId) → List available templates + - [ ] สร้าง Controllers: + - [ ] POST /routing/templates → Create template (Admin only) + - [ ] GET /routing/templates → List templates + - [ ] POST /routing/templates/:id/steps → Add step + +- **[ ] T3.4.2 CorrespondenceRoutingModule - Routing Execution** + - [ ] สร้าง Entity: CorrespondenceRouting + - [ ] สร้าง RoutingService: + - [ ] initiateRouting(correspondenceId, templateId) → void + - [ ] สร้าง routing instances ตาม template steps + - [ ] คำนวณ due dates จาก expected_days + - [ ] ส่ง notifications ไปยังองค์กรแรก + - [ ] processStep(routingId, action, comments) → void + - [ ] อัพเดทสถานะขั้นตอนปัจจุบัน + - [ ] ส่ง notification ไปยังขั้นตอนต่อไป + - [ ] อัพเดท due dates สำหรับขั้นตอนต่อไป + - [ ] สร้าง Controllers: + - [ ] POST /correspondences/:id/routing/start → Start routing + - [ ] POST /routing/:id/process → Process routing step + - [ ] GET /correspondences/:id/routing → Get routing status + - [ ] ตัวอย่าง Implementation Details + +- **[ ] T3.4.3 WorkflowEngineModule - State Management** + - [ ] สร้าง WorkflowEngineService: + - [ ] validateTransition(currentStatus, targetStatus) → boolean + - [ ] getAllowedTransitions(status) → string[] + - [ ] autoAdvanceStatus(correspondenceId) → void + - [ ] สร้าง DeadlineService: + - [ ] checkDeadlines() → void (Cron job) + - [ ] sendReminder(routingId) → void + - [ ] escalateOverdue(routingId) → void + +- **[ ] T3.4.4 Routing UI Integration** + - [ ] สร้าง API endpoints สำหรับ frontend: + - [ ] GET /routing/available-templates → Templates for current project + - [ ] GET /routing/my-pending → Pending routing steps for current user + - [ ] POST /routing/bulk-action → Process multiple routing steps + - [ ] **Security:** Implement permission checks สำหรับ routing operations + - [ ] **Deliverable:** ระบบส่งต่อเอกสารทำงานได้สมบูรณ์ + +### **Phase 3: Testing - Correspondence & Routing** + +#### **T3.T1 Correspondence Test Suite** + +- [ ] **Unit Tests (30+ test cases):** + - [ ] Correspondence creation with auto-numbering + - [ ] Revision management + - [ ] Status transitions + - [ ] Recipient management +- [ ] **Integration Tests (25+ test cases):** + - [ ] Complete correspondence lifecycle + - [ ] File attachment handling + - [ ] Reference management + - [ ] Search and filtering +- [ ] **Business Logic Tests (20+ test cases):** + - [ ] Workflow state validation + - [ ] Permission-based access + - [ ] Data validation rules + - [ ] Business rule enforcement +- **Exit Criteria:** Correspondence system handles all business scenarios + +#### **T3.T2 Routing Test Suite** + +- [ ] **Unit Tests (25+ test cases):** + - [ ] Template management + - [ ] Step sequencing + - [ ] Due date calculation + - [ ] Status transitions +- [ ] **Integration Tests (20+ test cases):** + - [ ] Complete routing workflow + - [ ] Multi-organization routing + - [ ] Deadline management + - [ ] Notification triggers +- [ ] **Edge Case Tests (15+ test cases):** + - [ ] Parallel processing scenarios + - [ ] Step skipping conditions + - [ ] Escalation procedures + - [ ] Error recovery +- **Exit Criteria:** Routing system handles complex workflows + +#### **T3.T3 JSON Details Integration Test Suite** + +- [ ] **Integration Tests (15+ test cases):** + - [ ] RFI details validation and processing + - [ ] RFA details for different types + - [ ] Transmittal details management + - [ ] Routing details in workflows +- [ ] **Data Migration Tests (10+ test cases):** + - [ ] Schema version upgrades + - [ ] Data transformation scenarios + - [ ] Backward compatibility +民主- **Exit Criteria:** JSON details integrated across all modules + +--- + +## **Phase 4: Drawing Management (สัปดาห์ที่ 7)** + +**Milestone:** ระบบจัดการแบบพร้อม File Security + +### **Phase 4: Tasks** + +- **[ ] T4.1 DrawingModule - Contract Drawings** + - [ ] สร้าง Entities: + - [ ] ContractDrawing + - [ ] ContractDrawingVolume + - [ ] ContractDrawingCat + - [ ] ContractDrawingSubCat + - [ ] ContractDrawingSubcatCatMap + - [ ] ContractDrawingAttachment + - [ ] สร้าง ContractDrawingService CRUD + - [ ] สร้าง Controllers: + - [ ] GET /drawings/contract → List + - [ ] POST /drawings/contract → Create (Admin) + - [ ] GET /drawings/contract/:id → Detail + - [ ] **Security:** Implement access control สำหรับ contract drawings + - [ ] **Deliverable:** จัดการ Contract Drawings ได้ + - [ ] **Dependencies:** T1.1 (Base Entity, Security), T1.2 (Authentication), T1.4 (RBAC), T1.5 (Project context), T2.2 (FileStorageService) + +- **[ ] T4.2 DrawingModule - Shop Drawings** + - [ ] สร้าง Entities: + - [ ] ShopDrawing + - [ ] ShopDrawingRevision + - [ ] ShopDrawingMainCategory + - [ ] ShopDrawingSubCategory + - [ ] ShopDrawingRevisionContractRef + - [ ] ShopDrawingRevisionAttachment + - [ ] สร้าง ShopDrawingService CRUD + - [ ] สร้าง Controllers: + - [ ] GET /drawings/shop → List + - [ ] POST /drawings/shop → Create + - [ ] POST /drawings/shop/:id/revisions → Create Revision + - [ ] GET /drawings/shop/:id → Detail with Revisions + - [ ] Link Shop Drawing Revision → Contract Drawings + - [ ] **Security:** Implement virus scanning สำหรับ drawing files + - [ ] **Deliverable:** จัดการ Shop Drawings และ Revisions ได้ + - [ ] ependencies: T4.1 (Shop Drawings อ้างอิงถึง Contract Drawings) + +--- + +## **Phase 5: Workflow Systems & Resilience (สัปดาห์ที่ 8-9)** + +**Milestone:** ระบบ Workflow ทั้งหมดพร้อม Resilience Patterns + +### **Phase 5: Tasks** + +- **[ ] T5.1 RfaModule - Workflow Implementation** + - [ ] สร้าง Entities: + - [ ] RfaWorkflowTemplate + - [ ] RfaWorkflowTemplateStep + - [ ] RfaWorkflow (Transaction Log) + - [ ] สร้าง RfaWorkflowService: + - [ ] initiateWorkflow(rfaId, templateId) → void + - [ ] สร้าง RfaWorkflow records ตาม Template + - [ ] กำหนด Step 1 เป็น PENDING + - [ ] completeStep(rfaId, stepNumber, action, comments) → void + - [ ] Update Status → COMPLETED + - [ ] Set Next Step → PENDING + - [ ] Send Notifications + - [ ] rejectStep(rfaId, stepNumber, reason) → void + - [ ] Update Status → REJECTED + - [ ] Send back to Originator + - [ ] สร้าง Controllers: + - [ ] POST /rfas/:id/workflow/start → Start Workflow + - [ ] POST /rfas/:id/workflow/steps/:stepNumber/complete → Complete Step + - [ ] GET /rfas/:id/workflow → Get Workflow Status + - [ ] **Resilience:** Implement circuit breaker สำหรับ notification services + - [ ] **Deliverable:** RFA Workflow ทำงานได้ + - [ ] **Dependencies:** T3.3 (ต้องมี RFA Basic CRUD ก่อน), T4.2 (RFA_DWG ต้องเชื่อมโยงกับ Shop Drawings), T2.5 (JSON Details สำหรับ Workflow), T6.2 (NotificationService สำหรับแจ้งเตือน) + +- **[ ] T5.2 CirculationModule - Internal Routing** + - [ ] สร้าง Entities: + - [ ] Circulation + - [ ] CirculationTemplate + - [ ] CirculationTemplateAssignee + - [ ] CirculationRouting (Transaction Log) + - [ ] CirculationAttachment + - [ ] สร้าง CirculationService: + - [ ] create(correspondenceId, dto) → Circulation + - [ ] สร้าง Circulation (1:1 กับ Correspondence) + - [ ] สร้าง Routing ตาม Template + - [ ] assignUser(circulationId, stepNumber, userId) → void + - [ ] completeStep(circulationId, stepNumber, comments) → void + - [ ] close(circulationId) → void (เมื่อตอบกลับองค์กรผู้ส่งแล้ว) + - สร้าง Controllers: + - [ ] POST /circulations → Create + - [ ] GET /circulations/:id → Detail + - [ ] POST /circulations/:id/steps/:stepNumber/complete → Complete + - [ ] POST /circulations/:id/close → Close + - [ ] **Resilience:** Implement retry mechanism สำหรับ assignment notifications + - [ ] **Deliverable:** ใบเวียนภายในองค์กรทำงานได้ + - [ ] **Dependencies:** T3.1 (Circulation คือ Correspondence ประเภทหนึ่ง), T2.5 (JSON Details), T6.2 (NotificationService) + +- **[ ] T5.3 TransmittalModule - Document Forwarding** + - [ ] สร้าง Entities: + - [ ] Transmittal + - [ ] TransmittalItem + - [ ] สร้าง TransmittalService: + - [ ] create(dto) → Transmittal + - [ ] สร้าง Correspondence + Transmittal + - [ ] เชื่อม Multiple Correspondences เป็น Items + - [ ] สร้าง Controllers: + - [ ] POST /transmittals → Create + - [ ] GET /transmittals → List + - [ ] GET /transmittals/:id → Detail with Items + - [ ] **Security:** Implement access control สำหรับ transmittal items + - [ ] **Deliverable:** สร้าง Transmittal ได้ + - [ ] **Dependencies:** T3.1 (Transmittal คือ Correspondence ประเภทหนึ่ง) + +--- + +## **Phase 6: Advanced Features & Monitoring (สัปดาห์ที่ 10-11)** + +**Milestone:** ฟีเจอร์ขั้นสูงพร้อม Monitoring และ Observability + +### **Phase 6: Tasks** + +- **[ ] T6.1 SearchModule - Elasticsearch Integration** + - [ ] Setup Elasticsearch Container ใน docker-compose.yml + - [ ] สร้าง SearchService: + - [ ] indexDocument(entity) → void + - [ ] updateDocument(entity) → void + - [ ] deleteDocument(entity) → void + - [ ] search(query, filters) → SearchResult[] + - [ ] Index ทุกครั้งที่ Create/Update: + - [ ] Correspondence + - [ ] RFA + - [ ] Shop Drawing + - [ ] Contract Drawing + - [ ] Circulation + - [ ] Transmittal + - [ ] สร้าง Controllers: + - [ ] GET /search?q=...&type=...&from=...&to=... → Results + - [ ] **Resilience:** Implement circuit breaker สำหรับ Elasticsearch + - [ ] **Deliverable:** ค้นหาขั้นสูงทำงานได้ + - [ ] **Dependencies:** T3.1, T3.3, T4.2, T5.2, T5.3 (ต้องมีข้อมูลจาก Modules หลักเหล่านี้ให้ทำการ Index) + +- **[ ] T6.2 NotificationModule - Email & Line** + - [ ] สร้าง NotificationService: + - [ ] sendEmail(to, subject, body) → void (Nodemailer) + - [ ] sendLine(userId, message) → void (ผ่าน n8n Webhook) + - [ ] createSystemNotification(userId, message, entityType, entityId) → void + - [ ] Integrate กับ Workflow Events: + - [ ] เมื่อสร้าง Correspondence ใหม่ → แจ้ง Recipients + - [ ] เมื่อสร้าง Circulation → แจ้ง Assignees + - [ ] เมื่อ RFA Workflow ถึง Step → แจ้ง Responsible Org + - [ ] เมื่อใกล้ถึง Deadline → แจ้ง (Optional) + - [ ] สร้าง Controllers: + - [ ] GET /notifications → List User's Notifications + - [ ] PUT /notifications/:id/read → Mark as Read + - [ ] **Resilience:** Implement retry mechanism ด้วย exponential backoff + - [ ] **Deliverable:** ระบบแจ้งเตือนทำงานได้ + - [ ] **Dependencies:** T1.1 (ConfigService สำหรับ Email credentials), T6.4 (Resilience patterns สำหรับการส่งภายนอก) + +- **[ ] T6.3 MonitoringModule - Observability** + - [ ] สร้าง Health Check Controller: + - [ ] GET /health → Database, Redis, Elasticsearch status + - [ ] สร้าง Metrics Service: + - [ ] API response times + - [ ] Error rates + - [ ] Cache hit ratios + - [ ] Business metrics (documents created, workflow completion) + - [ ] สร้าง Performance Interceptor: + - [ ] Track request duration + - [ ] Alert if response time > 200ms + - [ ] สร้าง Logging Service: + - [ ] Structured logging (JSON format) + - [ ] Log aggregation + - [ ] **Deliverable:** Monitoring system ทำงานได้ + - [ ] **Dependencies:** T1.1 (Base patterns) + +- **[ ] T6.4 ResilienceModule - Circuit Breaker & Retry** + - [ ] สร้าง Circuit Breaker Service: + - [ ] @CircuitBreaker() decorator สำหรับ external calls + - [ ] Configurable timeout และ error thresholds + - [ ] สร้าง Retry Service: + - [ ] @Retry() decorator ด้วย exponential backoff + - [ ] สร้าง Fallback Strategies: + - [ ] Graceful degradation สำหรับ non-critical features + - [ ] Implement สำหรับ: + - [ ] Email notifications + - [ ] LINE notifications + - [ ] Elasticsearch queries + - [ ] File virus scanning + - [ ] **Deliverable:** Resilience patterns ทำงานได้ + - [ ] **Dependencies:** T1.1 (Base patterns) + +--- + +## **Phase 7: Testing & Optimization (สัปดาห์ที่ 12-13)** + +**Milestone:** ทดสอบและปรับปรุงประสิทธิภาพพร้อม Security Audit + +### **Phase 7: Tasks- Testing Automation & CI/CD** + +- [ ] **Setup Test Environment:** + - [ ] Dockerized test database + - [ ] Test Redis instance + - [ ] Mock external services + - [ ] Test data management +- [ ] **CI/CD Pipeline:** + - [ ] GitHub Actions workflow + - [ ] Automated test execution + - [ ] Test reporting and metrics + - [ ] Quality gates + +- **Test Quality Gates** + +```yaml +# GitHub Actions Quality Gates +quality_gates: + unit_tests: + coverage: 80% + required: true + integration_tests: + scenarios: all_core + required: true + security_tests: + vulnerabilities: 0 + required: true + performance_tests: + response_time: 200ms + required: true +``` + +- **[ ] T7.1 Unit Testing** + - [ ] เขียน Unit Tests สำหรับ Services สำคัญ: + - [ ] AuthService (login, validateUser) + - [ ] RbacGuard (permission checks ทั้ง 4 ระดับ) + - [ ] DocumentNumberingService (Redis locking) + - [ ] FileStorageService (virus scanning, validation) + - [ ] CorrespondenceService (create, update, status transitions) + - [ ] RfaWorkflowService (workflow logic) + - [ ] **Security:** ทดสอบ security scenarios (SQL injection, XSS attempts) + - [ ] Target: 80% Code Coverage + - [ ] **Deliverable:** Unit Tests ผ่านทั้งหมด + - [ ] **Dependencies:** ทุก Development Tasks ใน Phase 1-6 ต้องเสร็จสิ้นก่อนเริ่มเขียน Tests อย่างจริงจัง (โดยเฉพาะ T1.4, T2.3, T3.1, T5.1) + +- **[ ] T7.2 Integration Testing** + - [ ] เขียน Integration Tests: + - [ ] Authentication Flow (login → access protected route) + - [ ] Document Creation Flow (create correspondence → attach files → virus scan) + - [ ] RFA Workflow Flow (start → step 1 → step 2 → complete) + - [ ] Circulation Flow (create → assign → complete → close) + - [ ] ทดสอบ SQL Views (v_user_all_permissions, v_user_tasks) + - [ ] ใช้ Test Database แยกต่างหาก + - [ ] **Security:** ทดสอบ rate limiting และ permission enforcement + - [ ] **Deliverable:** Integration Tests ผ่าน + - [ ] **Dependencies:** T7.1 (Unit Tests ควรผ่านก่อน) + +- **[ ] T7.3 E2E Testing** + - [ ] เขียน E2E Tests: + - [ ] User Registration & Login + - [ ] Create Correspondence (Full Flow) + - [ ] Create RFA with Shop Drawings + - [ ] Complete RFA Workflow + - [ ] Search Documents + - [ ] **Security:** ทดสอบ file upload security + - [ ] **Deliverable:** E2E Tests ผ่าน + - [ ] **Dependencies:** T7.2 (Integration Tests ควรผ่านก่อน) + +- **[ ] T7.4 Performance Testing** + - [ ] Load Testing: + - [ ] 100 concurrent users + - [ ] API response time < 200ms (90th percentile) + - [ ] Search performance < 500ms + - [ ] Stress Testing: + - [ ] Find breaking points + - [ ] Database connection limits + - [ ] Endurance Testing: + - [ ] 24-hour continuous operation + - [ ] **Deliverable:** Performance targets บรรลุ + - [ ] **Dependencies:** T7.3 (E2E Tests ควรผ่านก่อน) + +- **[ ] T7.5 Security Testing** + - [ ] Penetration Testing: + - [ ] OWASP Top 10 vulnerabilities + - [ ] SQL Injection attempts + - [ ] XSS attempts + - [ ] CSRF attempts + - [ ] Security Audit: + - [ ] Code review สำหรับ security flaws + - [ ] Dependency vulnerability scanning + - [ ] File Upload Security Testing: + - [ ] Virus scanning effectiveness + - [ ] File type bypass attempts + - [ ] **Deliverable:** Security tests ผ่าน + - [ ] **Dependencies:** T7.4 (Performance Tests ควรผ่านก่อน) + +- **[ ] T7.6 Performance Optimization** + - [ ] Implement Caching: + - [ ] Cache Master Data (Roles, Permissions, Organizations) + - [ ] Cache User Permissions + - [ ] Cache Search Results + - [ ] Database Optimization: + - [ ] Review Indexes + - [ ] Optimize Queries (N+1 Problem) + - [ ] Implement Pagination ทุก List Endpoint + - [ ] **Deliverable:** Response Time < 200ms (90th percentile) + - [ ] **Dependencies:** T7.4 (ผลจาก Performance Testing จะบอกว่าจุดไหนต้อง Optimization) + +### 📊 **Testing Metrics & Exit Criteria** + + **แต่ละ Phase ต้องผ่าน Metrics เหล่านี้:** + +#### **Phase Completion Metrics** + +- [ ] **Code Quality Metrics** + - [ ] Unit test coverage: ≥ 80% + - [ ] Integration test coverage: 100% core scenarios + - [ ] Static analysis: 0 critical issues + - [ ] Code duplication: < 5% + +- [ ] **Performance Metrics** + - [ ] API response time: < 200ms (90th percentile) + - [ ] Database query performance: < 100ms + - [ ] Memory usage: Within limits + - [ ] Concurrent users: Meets targets + +- [ ] **Security Metrics** + - [ ] Security vulnerabilities: 0 + - [ ] Authentication tests: 100% passed + - [ ] Authorization tests: 100% passed + - [ ] Data validation tests: 100% passed + +- [ ] **Business Metrics** + - [ ] Core workflows: 100% tested + - [ ] Edge cases: Covered + - [ ] Error scenarios: Handled appropriately + - [ ] User acceptance: Meets requirements + +--- + +## **Phase 8: Documentation & Deployment (สัปดาห์ที่ 14)** + +**Milestone:** เอกสารและ Deploy สู่ Production พร้อม Security Hardening + +### **Phase 8: Tasks** + +- **[ ] T8.1 API Documentation** + - [ ] ครบทุก Endpoint ใน Swagger: + - [ ] ใส่ Description, Example Request/Response + - [ ] ระบุ Required Permissions + - [ ] ใส่ Error Responses + - [ ] Export Swagger JSON → Frontend Team + - [ ] **Security:** เอกสารต้องไม่เปิดเผย sensitive information + - [ ] **Deliverable:** Swagger Docs สมบูรณ์ + - [ ] **Dependencies:** ทุก Development Tasks ต้องเสร็จสิ้น + +- **[ ] T8.2 Technical Documentation** + - [ ] เขียนเอกสาร: + - [ ] Architecture Overview + - [ ] Module Structure + - [ ] Database Schema Diagram + - [ ] API Design Patterns + - [ ] Security Implementation Guide + - [ ] Deployment Guide + - [ ] Disaster Recovery Procedures + - [ ] **Deliverable:** Technical Docs พร้อม + - [ ] **Dependencies:** T8.1 + +- **[ ] T8.3 Security Hardening** + - [ ] Final Security Review: + - [ ] Environment variables security + - [ ] Database encryption + - [ ] File storage security + - [ ] API security headers + - [ ] Implement Security Monitoring: + - [ ] Failed login attempts tracking + - [ ] Suspicious activity alerts + - [ ] Rate limiting monitoring + - [ ] **Deliverable:** Security checklist ผ่าน + - [ ] **Dependencies:** T7.5 (Security Testing ต้องผ่าน) + +- **[ ] T8.4 Deployment Preparation** + - [ ] สร้าง Production docker-compose.yml + - [ ] Setup Environment Variables ใน QNAP + - [ ] Setup Nginx Proxy Manager (SSL Certificate) + - [ ] Setup Backup Scripts (Database + Files) + - [ ] Setup Monitoring และ Alerting + - [ ] **Deliverable:** Deployment Guide พร้อม + - [ ] **Dependencies:** T8.2, T8.3 + +- **[ ] T8.5 Production Deployment** + - [ ] Deploy Backend ไปยัง backend.np-dms.work + - [ ] ทดสอบ API ผ่าน Postman + - [ ] Monitor Logs (Winston) + - [ ] Setup Health Check Endpoint (GET /health) + - [ ] Verify Security Measures: + - [ ] HTTPS enforcement + - [ ] Security headers + - [ ] Rate limiting + - [ ] Virus scanning + - [ ] **Deliverable:** Backend รันบน Production + - [ ] **Dependencies:** T8.4 + +- **[ ] T8.6 Handover to Frontend Team** + - [ ] Demo API ให้ Frontend Team + - [ ] ส่งมอบ Swagger Documentation + - [ ] ส่งมอบ Postman Collection + - [ ] Workshop: วิธีใช้ Authentication & RBAC + - [ ] **Deliverable:** Frontend เริ่มพัฒนาได้ + - [ ] **Dependencies:** T8.5 + +--- + +## 📊 **สรุป Timeline** + +| Phase | ระยะเวลา | จำนวนงาน | Output หลัก | +| ------- | ------------ | ------------ | ------------------------------------ | +| Phase 0 | 1 สัปดาห์ | 4 | Infrastructure Ready + Security Base | +| Phase 1 | 2 สัปดาห์ | 5 | Auth & User Management + RBAC | +| Phase 2 | 1 สัปดาห์ | 4 | Security & File Management | +| Phase 3 | 2 สัปดาห์ | 3 | Correspondence & RFA Core | +| Phase 4 | 1 สัปดาห์ | 2 | Drawing Management | +| Phase 5 | 2 สัปดาห์ | 3 | Workflow Systems + Resilience | +| Phase 6 | 2 สัปดาห์ | 4 | Advanced Features + Monitoring | +| Phase 7 | 2 สัปดาห์ | 6 | Testing & Optimization | +| Phase 8 | 1 สัปดาห์ | 6 | Documentation & Deploy | +| **รวม** | **14 สัปดาห์** | **37 Tasks** | **Production-Ready Backend** | + +--- + +## 🎯 **Critical Success Factors** + +1. **Security First:** ทุก Task ต้องพิจารณาด้านความปลอดภัยเป็นหลัก +2. **Database Integrity:** ใช้ Schema v1.4.1 เป็นหลัก ไม่แก้ไข Schema โดยไม่จำเป็น +3. **Soft Delete:** Service ทั้งหมดต้องใช้ Global Filter กรอง WHERE deleted_at IS NULL +4. **API Contract:** ทุก Endpoint ต้องมี Swagger Documentation สมบูรณ์ +5. **Security Compliance:** RBAC ต้องทำงานถูกต้อง 100% ก่อน Deploy +6. **Testing Coverage:** Code Coverage อย่างน้อย 80% ก่อน Production +7. **Performance Targets:** Response Time < 200ms (90th percentile) +8. **Resilience:** ระบบต้องทนทานต่อ failures ของ external services +9. **Monitoring:** ต้องมี comprehensive monitoring และ alerting +10. **Documentation:** เอกสารต้องครบถ้วนเพื่อ Handover ให้ Frontend Team + +--- + +## 🚀 **ขั้นตอนถัดไป** + +1. **Approve แผนนี้** → ปรับแต่งตาม Feedback +2. **Setup Phase 0** → เริ่มสร้าง Infrastructure +3. **Daily Standup** → รายงานความก้าวหน้าทุกวัน +4. **Weekly Review** → ทบทวนความก้าวหน้าทุกสัปดาห์ +5. **Security Review** → ทุก Phase ต้องผ่าน security review +6. **Deploy to Production** → Week 14 + +--- + +## 📋 **Security Checklist ทุก Phase** + +- **Phase 1-2: Foundation Security** + - [ ] Input validation implemented + - [ ] XSS protection enabled + - [ ] CSRF protection implemented + - [ ] Rate limiting configured + - [ ] Secure password hashing (bcrypt) + +- **Phase 3-5: Application Security** + - [ ] RBAC 4-level working correctly + - [ ] File upload security (virus scanning, type validation) + - [ ] Audit logging for critical operations + - [ ] SQL injection prevention + +- **Phase 6-8: Production Security** + - [ ] HTTPS enforcement + - [ ] Security headers configured + - [ ] Environment variables secured + - [ ] Monitoring and alerting active + - [ ] Backup and recovery tested + +## **หมายเหตุ:** แผนนี้สามารถปรับแต่งได้ตามความต้องการและข้อจำกัดของทีม หาก Phase ใดใช้เวลามากกว่าที่คาดการณ์ ควรปรับ Timeline ให้เหมาะสม โดยให้ความสำคัญกับ Security และ Quality diff --git a/docs/LCBP3-DMS_V1_4_1_Data_Dictionary.md b/Documnets/Project/LCBP3-DMS_V1_4_1_Data_Dictionary.md similarity index 92% rename from docs/LCBP3-DMS_V1_4_1_Data_Dictionary.md rename to Documnets/Project/LCBP3-DMS_V1_4_1_Data_Dictionary.md index 5a10755..b0c30cc 100644 --- a/docs/LCBP3-DMS_V1_4_1_Data_Dictionary.md +++ b/Documnets/Project/LCBP3-DMS_V1_4_1_Data_Dictionary.md @@ -1,2837 +1,2833 @@ -# **ตารางฐานข้อมูล (Data Dictionary) - LCBP3-DMS (V1.4.1)** - -เอกสารนี้สรุปโครงสร้างตาราง, Foreign Keys (FK), และ Constraints ที่สำคัญทั้งหมดในฐานข้อมูล LCBP3-DMS (v1.4.0) เพื่อใช้เป็นเอกสารอ้างอิงสำหรับทีมพัฒนา Backend (NestJS) และ Frontend (Next.js) โดยอิงจาก Requirements และ SQL Script ล่าสุด [GLM-4.6] - ---- - -## **1. 🏢 Core & Master Data Tables (องค์กร, โครงการ, สัญญา)** - -### 1.1 organization_roles - -**Purpose**: Master table for organization role types in the system - -| Column Name | Data Type | Constraints | Description | -| ----------- | ----------- | --------------------------- | ---------------------------------------------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier for organization role | -| role_name | VARCHAR(20) | NOT NULL, UNIQUE | Role name (OWNER, DESIGNER, CONSULTANT, CONTRACTOR, THIRD PARTY) | - -**Indexes**: - -- PRIMARY KEY (id) -- UNIQUE (role_name) - -**Business Rules**: - -- Predefined system roles for organization types -- Cannot be deleted if referenced by organizations - ---- - -### 1.2 organizations - -**Purpose**: Master table storing all organizations involved in the system - -| Column Name | Data Type | Constraints | Description | -| ----------------- | ------------ | ----------------------------------- | ---------------------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier for organization | -| organization_code | VARCHAR(20) | NOT NULL, UNIQUE | Organization code (e.g., 'กทท.', 'TEAM') | -| organization_name | VARCHAR(255) | NOT NULL | Full organization name | -| is_active | BOOLEAN | DEFAULT TRUE | Active status (1=active, 0=inactive) | -| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | -| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | - -**Indexes**: - -- PRIMARY KEY (id) -- UNIQUE (organization_code) -- INDEX (is_active) - -**Relationships**: - -- Referenced by: users, project_organizations, contract_organizations, correspondences, circulations - -**Seed Data**: Pre-populated with 15 organizations including: - -- Port Authority of Thailand (กทท.) -- Project supervision consultants (สค©.3-xx) -- Design consultants (TEAM) -- Construction supervisors (คคง.) -- Contractors (ผรม.1-4) -- Third parties (EN, CAR) - ---- - -### 1.3 projects - -**Purpose**: Master table for all projects in the system - -| Column Name | Data Type | Constraints | Description | -| ------------ | ------------ | --------------------------- | ----------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier for project | -| project_code | VARCHAR(50) | NOT NULL, UNIQUE | Project code (e.g., 'LCBP3') | -| project_name | VARCHAR(255) | NOT NULL | Full project name | -| is_active | TINYINT(1) | DEFAULT 1 | Active status | - -**Indexes**: - -- PRIMARY KEY (id) -- UNIQUE (project_code) -- INDEX (is_active) - -**Relationships**: - -- Referenced by: contracts, correspondences, document_number_formats, drawings - -**Seed Data**: 5 projects for Laem Chabang Port Phase 3 (LCBP3) including main project and 4 sub-contracts - ---- - -### 1.4 contracts - -**Purpose**: Master table for contracts within projects - -| Column Name | Data Type | Constraints | Description | -| ------------- | ------------ | ----------------------------------- | ------------------------------ | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier for contract | -| project_id | INT | NOT NULL, FK | Reference to projects table | -| contract_code | VARCHAR(50) | NOT NULL, UNIQUE | Contract code | -| contract_name | VARCHAR(255) | NOT NULL | Full contract name | -| description | TEXT | NULL | Contract description | -| start_date | DATE | NULL | Contract start date | -| end_date | DATE | NULL | Contract end date | -| is_active | BOOLEAN | DEFAULT TRUE | Active status | -| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | -| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | - -**Indexes**: - -- PRIMARY KEY (id) -- UNIQUE (contract_code) -- FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE -- INDEX (project_id, is_active) - -**Relationships**: - -- Parent: projects -- Referenced by: contract_organizations, user_assignments - -**Seed Data**: 7 contracts including design, supervision, construction, and environmental monitoring - ---- - -## **2. 👥 Users & RBAC Tables (ผู้ใช้, สิทธิ์, บทบาท)** - -### 2.1 users - -**Purpose**: Master table storing all system users - -| Column Name | Data Type | Constraints | Description | -| ----------------------- | ------------ | ----------------------------------- | -------------------------------- | -| user_id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier for user | -| username | VARCHAR(50) | NOT NULL, UNIQUE | Login username | -| password_hash | VARCHAR(255) | NOT NULL | Hashed password (bcrypt) | -| first_name | VARCHAR(50) | NULL | User's first name | -| last_name | VARCHAR(50) | NULL | User's last name | -| email | VARCHAR(100) | NOT NULL, UNIQUE | Email address | -| line_id | VARCHAR(100) | NULL | LINE messenger ID | -| primary_organization_id | INT | NULL, FK | Primary organization affiliation | -| is_active | TINYINT(1) | DEFAULT 1 | Active status | -| failed_attempts | INT | DEFAULT 0 | Failed login attempts counter | -| locked_until | DATETIME | NULL | Account lock expiration time | -| last_login_at | TIMESTAMP | NULL | Last successful login timestamp | -| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | -| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | - -**Indexes**: - -- PRIMARY KEY (user_id) -- UNIQUE (username) -- UNIQUE (email) -- FOREIGN KEY (primary_organization_id) REFERENCES organizations(id) ON DELETE SET NULL -- INDEX (is_active) -- INDEX (email) - -**Relationships**: - -- Parent: organizations (primary_organization_id) -- Referenced by: user_assignments, audit_logs, notifications, circulation_routings - -**Security Features**: - -- Password stored as bcrypt hash -- Account locking after failed attempts -- Last login tracking - -**Seed Data**: 3 initial users (superadmin, editor01, viewer01) - ---- - -### 2.2 roles - -**Purpose**: Master table defining system roles with scope levels - -| Column Name | Data Type | Constraints | Description | -| ----------- | ------------ | --------------------------- | ---------------------------------------------------- | -| role_id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier for role | -| role_name | VARCHAR(100) | NOT NULL | Role name (e.g., 'Superadmin', 'Document Control') | -| scope | ENUM | NOT NULL | Scope level: Global, Organization, Project, Contract | -| description | TEXT | NULL | Role description | -| is_system | BOOLEAN | DEFAULT FALSE | System role flag (cannot be deleted) | - -**Indexes**: - -- PRIMARY KEY (role_id) -- INDEX (scope) - -**Relationships**: - -- Referenced by: role_permissions, user_assignments - -**Seed Data**: 7 predefined roles - -1. Superadmin (Global) - Full system access -2. Org Admin (Organization) - Organization management -3. Document Control (Organization) - Document lifecycle management -4. Editor (Organization) - Document creation and editing -5. Viewer (Organization) - Read-only access -6. Project Manager (Project) - Project-level management -7. Contract Admin (Contract) - Contract-specific administration - ---- - -### 2.3 permissions - -**Purpose**: Master table defining all system permissions - -| Column Name | Data Type | Constraints | Description | -| --------------- | ------------ | --------------------------- | ------------------------------------------------------ | -| permission_id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier for permission | -| permission_name | VARCHAR(100) | NOT NULL, UNIQUE | Permission code (e.g., 'rfas.create', 'document.view') | -| description | TEXT | NULL | Permission description | -| module | VARCHAR(50) | NULL | Related module name | -| scope_level | ENUM | NULL | Scope: GLOBAL, ORG, PROJECT | -| is_active | TINYINT(1) | DEFAULT 1 | Active status | - -**Indexes**: - -- PRIMARY KEY (permission_id) -- UNIQUE (permission_name) -- INDEX (module) -- INDEX (scope_level) -- INDEX (is_active) - -**Relationships**: - -- Referenced by: role_permissions - -**Permission Categories**: - -1. **System Management** (1): system.manage_all -2. **Organization Management** (2-5): create, edit, delete, view -3. **Project Management** (6-9, 23-26): create, edit, delete, view, manage members/contracts/reports -4. **Role & Permission Management** (10-13): create, edit, delete roles, assign permissions -5. **Master Data Management** (14-17): document types, statuses, categories, tags -6. **User Management** (18-22): create, edit, delete, view, assign organization -7. **Contract Management** (27-28): manage members, view -8. **Document Management** (29-44): CRUD operations, workflows, circulation -9. **Search & Reporting** (48-49): advanced search, generate reports - -**Total Permissions**: 49 - ---- - -### 2.4 role_permissions - -**Purpose**: Junction table mapping roles to permissions (M:N) - -| Column Name | Data Type | Constraints | Description | -| ------------- | --------- | --------------- | ------------------------------ | -| role_id | INT | PRIMARY KEY, FK | Reference to roles table | -| permission_id | INT | PRIMARY KEY, FK | Reference to permissions table | - -**Indexes**: - -- PRIMARY KEY (role_id, permission_id) -- FOREIGN KEY (role_id) REFERENCES roles(role_id) ON DELETE CASCADE -- FOREIGN KEY (permission_id) REFERENCES permissions(permission_id) ON DELETE CASCADE -- INDEX (permission_id) - -**Relationships**: - -- Parent: roles, permissions - -**Seed Data**: Complete permission mappings for all 7 roles - -- Superadmin: All 49 permissions -- Org Admin: 15 permissions (user/org/tag management, view access) -- Document Control: 26 permissions (full document lifecycle) -- Editor: 12 permissions (document CRUD without admin powers) -- Viewer: 2 permissions (view and search only) -- Project Manager: 23 permissions (project management + document CRUD) -- Contract Admin: 15 permissions (contract management + document CRUD) - ---- - -### 2.5 user_assignments - -**Purpose**: Junction table assigning users to roles with scope context - -| Column Name | Data Type | Constraints | Description | -| ------------------- | --------- | --------------------------- | ---------------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier | -| user_id | INT | NOT NULL, FK | Reference to users table | -| role_id | INT | NOT NULL, FK | Reference to roles table | -| organization_id | INT | NULL, FK | Organization scope (if applicable) | -| project_id | INT | NULL, FK | Project scope (if applicable) | -| contract_id | INT | NULL, FK | Contract scope (if applicable) | -| assigned_by_user_id | INT | NULL, FK | User who made the assignment | -| assigned_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Assignment timestamp | - -**Indexes**: - -- PRIMARY KEY (id) -- FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE -- FOREIGN KEY (role_id) REFERENCES roles(role_id) ON DELETE CASCADE -- FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE -- FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE -- FOREIGN KEY (contract_id) REFERENCES contracts(id) ON DELETE CASCADE -- FOREIGN KEY (assigned_by_user_id) REFERENCES users(user_id) -- INDEX (user_id, role_id) -- INDEX (organization_id) -- INDEX (project_id) -- INDEX (contract_id) - -**Constraints**: - -- CHECK: Only one scope field (organization_id, project_id, contract_id) can be NOT NULL, or all NULL for Global scope - -**Relationships**: - -- Parent: users, roles, organizations, projects, contracts - -**Business Rules**: - -- User can have multiple role assignments with different scopes -- Scope inheritance: Contract → Project → Organization → Global -- Global scope: all scope fields are NULL - ---- - -### 2.6 project_organizations - -**Purpose**: Junction table linking projects to participating organizations (M:N) - -| Column Name | Data Type | Constraints | Description | -| --------------- | --------- | --------------- | -------------------------------- | -| project_id | INT | PRIMARY KEY, FK | Reference to projects table | -| organization_id | INT | PRIMARY KEY, FK | Reference to organizations table | - -**Indexes**: - -- PRIMARY KEY (project_id, organization_id) -- FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE -- FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE -- INDEX (organization_id) - -**Relationships**: - -- Parent: projects, organizations - -**Seed Data**: Pre-populated with project-organization relationships - ---- - -### 2.7 contract_organizations - -**Purpose**: Junction table linking contracts to participating organizations with roles (M:N) - -| Column Name | Data Type | Constraints | Description | -| ---------------- | ------------ | --------------- | ------------------------------------------------------------------------- | -| contract_id | INT | PRIMARY KEY, FK | Reference to contracts table | -| organization_id | INT | PRIMARY KEY, FK | Reference to organizations table | -| role_in_contract | VARCHAR(100) | NULL | Organization's role in contract (Owner, Designer, Consultant, Contractor) | - -**Indexes**: - -- PRIMARY KEY (contract_id, organization_id) -- FOREIGN KEY (contract_id) REFERENCES contracts(id) ON DELETE CASCADE -- FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE -- INDEX (organization_id) -- INDEX (role_in_contract) - -**Relationships**: - -- Parent: contracts, organizations - -**Seed Data**: Pre-populated with contract-organization-role relationships - ---- - -## **3. ✉️ Correspondences Tables (เอกสารหลัก, Revisions, Workflows)** - -### 3.1 correspondence_types - -**Purpose**: Master table for correspondence document types - -| Column Name | Data Type | Constraints | Description | -| ----------- | ------------ | --------------------------- | --------------------------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier | -| type_code | VARCHAR(50) | NOT NULL, UNIQUE | Type code (e.g., 'RFA', 'RFI', 'TRANSMITTAL') | -| type_name | VARCHAR(255) | NOT NULL | Full type name | -| sort_order | INT | DEFAULT 0 | Display order | -| is_active | TINYINT(1) | DEFAULT 1 | Active status | - -**Indexes**: - -- PRIMARY KEY (id) -- UNIQUE (type_code) -- INDEX (is_active) -- INDEX (sort_order) - -**Relationships**: - -- Referenced by: correspondences, document_number_formats, document_number_counters - -**Seed Data**: 10 correspondence types including RFA, RFI, TRANSMITTAL, EMAIL, INSTRUCTION, LETTER, MEMO, MOM, NOTICE, OTHER - ---- - -### 3.2 correspondence_status - -**Purpose**: Master table for correspondence status codes - -| Column Name | Data Type | Constraints | Description | -| ----------- | ------------ | --------------------------- | ------------------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier | -| status_code | VARCHAR(50) | NOT NULL, UNIQUE | Status code (e.g., 'DRAFT', 'SUBOWN') | -| status_name | VARCHAR(255) | NOT NULL | Full status name | -| sort_order | INT | DEFAULT 0 | Display order | -| is_active | TINYINT(1) | DEFAULT 1 | Active status | - -**Indexes**: - -- PRIMARY KEY (id) -- UNIQUE (status_code) -- INDEX (is_active) -- INDEX (sort_order) - -**Relationships**: - -- Referenced by: correspondence_revisions - -**Seed Data**: 23 status codes covering draft, submission, reply, resubmission, closure, and cancellation states by different parties (Owner, Designer, CSC, Contractor) - ---- - -### 3.3 correspondences - -**Purpose**: Master table for correspondence documents (non-revisioned data) - -| Column Name | Data Type | Constraints | Description | -| ------------------------- | ------------ | --------------------------- | ------------------------------------------ | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Master correspondence ID | -| correspondence_number | VARCHAR(100) | NOT NULL | Document number (from numbering system) | -| correspondence_type_id | INT | NOT NULL, FK | Reference to correspondence_types | -| is_internal_communication | TINYINT(1) | DEFAULT 0 | Internal (1) or external (0) communication | -| project_id | INT | NOT NULL, FK | Reference to projects table | -| originator_id | INT | NULL, FK | Originating organization | -| created_at | DATETIME | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | -| created_by | INT | NULL, FK | User who created the record | -| deleted_at | DATETIME | NULL | Soft delete timestamp | - -**Indexes**: - -- PRIMARY KEY (id) -- FOREIGN KEY (correspondence_type_id) REFERENCES correspondence_types(id) ON DELETE RESTRICT -- FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE -- FOREIGN KEY (originator_id) REFERENCES organizations(id) ON DELETE SET NULL -- FOREIGN KEY (created_by) REFERENCES users(user_id) ON DELETE SET NULL -- UNIQUE KEY (project_id, correspondence_number) -- INDEX (correspondence_type_id) -- INDEX (originator_id) -- INDEX (deleted_at) - -**Relationships**: - -- Parent: correspondence_types, projects, organizations, users -- Children: correspondence_revisions, correspondence_recipients, correspondence_tags, correspondence_references, correspondence_attachments, circulations, transmittals - -**Business Rules**: - -- One correspondence can have multiple revisions -- Correspondence number must be unique within a project -- Soft delete preserves history - ---- - -### 3.4 correspondence_revisions - -**Purpose**: Child table storing revision history of correspondences (1:N) - -| Column Name | Data Type | Constraints | Description | -| ------------------------ | ------------ | --------------------------- | ------------------------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique revision ID | -| correspondence_id | INT | NOT NULL, FK | Master correspondence ID | -| revision_number | INT | NOT NULL | Revision sequence (0, 1, 2...) | -| revision_label | VARCHAR(10) | NULL | Display revision (A, B, 1.1...) | -| is_current | BOOLEAN | DEFAULT FALSE | Current revision flag | -| correspondence_status_id | INT | NOT NULL, FK | Current status of this revision | -| title | VARCHAR(255) | NOT NULL | Document title | -| document_date | DATE | NULL | Document date | -| issued_date | DATETIME | NULL | Issue date | -| received_date | DATETIME | NULL | Received date | -| due_date | DATETIME | NULL | Due date for response | -| description | TEXT | NULL | Revision description | -| details | JSON | NULL | Type-specific details (e.g., RFI questions) | -| created_at | DATETIME | DEFAULT CURRENT_TIMESTAMP | Revision creation timestamp | -| created_by | INT | NULL, FK | User who created revision | -| updated_by | INT | NULL, FK | User who last updated | - -**Indexes**: - -- PRIMARY KEY (id) -- FOREIGN KEY (correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE -- FOREIGN KEY (correspondence_status_id) REFERENCES correspondence_status(id) ON DELETE RESTRICT -- FOREIGN KEY (created_by) REFERENCES users(user_id) ON DELETE SET NULL -- FOREIGN KEY (updated_by) REFERENCES users(user_id) ON DELETE SET NULL -- UNIQUE KEY (correspondence_id, revision_number) -- UNIQUE KEY (correspondence_id, is_current) - Only one current revision per correspondence -- INDEX (correspondence_status_id) -- INDEX (is_current) -- INDEX (document_date) -- INDEX (issued_date) - -**Relationships**: - -- Parent: correspondences, correspondence_status, users - -**Business Rules**: - -- Only one revision can be marked as current (is_current=TRUE) per correspondence -- Revision numbers are sequential starting from 0 -- JSON details field allows type-specific data storage - ---- - -### 3.5 correspondence_recipients - -**Purpose**: Junction table for correspondence recipients (TO/CC) (M:N) - -| Column Name | Data Type | Constraints | Description | -| ------------------------- | ---------------- | --------------- | ---------------------------- | -| correspondence_id | INT | PRIMARY KEY, FK | Reference to correspondences | -| recipient_organization_id | INT | PRIMARY KEY, FK | Recipient organization | -| recipient_type | ENUM('TO', 'CC') | PRIMARY KEY | Recipient type | - -**Indexes**: - -- PRIMARY KEY (correspondence_id, recipient_organization_id, recipient_type) -- FOREIGN KEY (correspondence_id) REFERENCES correspondence_revisions(correspondence_id) ON DELETE CASCADE -- FOREIGN KEY (recipient_organization_id) REFERENCES organizations(id) ON DELETE RESTRICT -- INDEX (recipient_organization_id) -- INDEX (recipient_type) - -**Relationships**: - -- Parent: correspondences, organizations - -**Business Rules**: - -- One organization can be both TO and CC recipient -- Cascade delete when correspondence is deleted - ---- - -### 3.6 tags - -**Purpose**: Master table for document tagging system - -| Column Name | Data Type | Constraints | Description | -| ----------- | ------------ | ----------------------------------- | ------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique tag ID | -| tag_name | VARCHAR(100) | NOT NULL, UNIQUE | Tag name | -| description | TEXT | NULL | Tag description | -| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | -| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | - -**Indexes**: - -- PRIMARY KEY (id) -- UNIQUE (tag_name) -- INDEX (tag_name) - For autocomplete - -**Relationships**: - -- Referenced by: correspondence_tags - ---- - -### 3.7 correspondence_tags - -**Purpose**: Junction table linking correspondences to tags (M:N) - -| Column Name | Data Type | Constraints | Description | -| ----------------- | --------- | --------------- | ---------------------------- | -| correspondence_id | INT | PRIMARY KEY, FK | Reference to correspondences | -| tag_id | INT | PRIMARY KEY, FK | Reference to tags | - -**Indexes**: - -- PRIMARY KEY (correspondence_id, tag_id) -- FOREIGN KEY (correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE -- FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE -- INDEX (tag_id) - -**Relationships**: - -- Parent: correspondences, tags - ---- - -### 3.8 correspondence_references - -**Purpose**: Junction table for cross-referencing correspondences (M:N) - -| Column Name | Data Type | Constraints | Description | -| --------------------- | --------- | --------------- | ------------------------------------- | -| src_correspondence_id | INT | PRIMARY KEY, FK | Source correspondence ID | -| tgt_correspondence_id | INT | PRIMARY KEY, FK | Target (referenced) correspondence ID | - -**Indexes**: - -- PRIMARY KEY (src_correspondence_id, tgt_correspondence_id) -- FOREIGN KEY (src_correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE -- FOREIGN KEY (tgt_correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE -- INDEX (tgt_correspondence_id) - -**Relationships**: - -- Parent: correspondences (both sides) - -**Business Rules**: - -- Allows tracing document relationships -- Bi-directional references should be created as separate records - -### 3.9 ตาราง correspondence_routing_templates - -**Purpose**: เก็บข้อมูลแม่แบบ (Template) ของสายงานการส่งต่อเอกสารเพื่อขออนุมัติ ทำให้ไม่ต้องกำหนดขั้นตอนซ้ำทุกครั้ง สามารถสร้างเป็นแม่แบบทั่วไป หรือเฉพาะสำหรับโครงการใดโครงการหนึ่งได้ - -| Column Name | Data Type | Constraints | Description | -| ------------- | --------- | --------------------------- | -------------------------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | ID หลัก (Primary Key) ของแม่แบบ รันค่าอัตโนมัติ | -| template_name | VARCHAR(255) | NOT NULL | ชื่อของแม่แบบ เช่น "เสนอโครงการ", "ขออนุมัติจัดซื้อ" | -| description | TEXT | NULL | คำอธิบายรายละเอียดเกี่ยวกับแม่แบบนี้ | -| project_id | INT | NULL | ID ของโครงการที่แม่แบบนี้สังกัดอยู่ (ถ้ามี) **ค่า NULL หมายถึง** เป็น "แม่แบบทั่วไป" ที่สามารถใช้กับทุกโครงการได้ | -| created_at | TIMESTAMP | NOT NULL, DEFAULT CURRENT_TIMESTAMP | วันที่และเวลาที่สร้างแม่แบบนี้ | -| updated_at | TIMESTAMP | NOT NULL,`DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP | วันที่และเวลาที่แก้ไขข้อมูลในแม่แบบนี้ล่าสุด | -| is_active | BOOLEAN | DEFAULT TRUE| สถานะใช้งาน | - -**Indexes**: - -- ux_routing_template_name_project (template_name, project_id): ดัชนีแบบ UNIQUE ป้องกันการมีชื่อแม่แบบซ้ำกันในแต่ละโครงการ หรือในส่วนของแม่แบบทั่วไป (ที่ project_id เป็น NULL) - -**ความสัมพันธ์ Foreign Key:** - -- fk_crt_project: อ้างอิงไปยัง projects(id) -- ON DELETE CASCAD`: ถ้าโครงการ (projects) ถูกลบ แม่แบบที่เกี่ยวข้องกับโครงการนั้นๆ จะถูกลบไปด้วยทั้งหมด - ---- - -### 3.10 ตาราง correspondence_routing_template_steps - -**Purpose**: เก็บรายละเอียดของแต่ละขั้นตอน (Steps) ภายในแม่แบบสายงาน (correspondence_routing_templates) กำหนดว่าจะส่งไปที่องค์กรไหน ลำดับเป็นเท่าไร และเพื่อวัตถุประสงค์อะไร - -| Column Name | Data Type | Constraints | Description | -| :----- |----- | ----- | ---- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | ID หลักของขั้นตอน | -| template_id | INT | NOT NULL | ID ของแม่แบบที่ขั้นตอนนี้สังกัดอยู่ | -| sequence | INT | NOT NULL | ลำดับของขั้นตอน (1, 2, 3, ...) | -| to_organization_id | INT | NOT NULL | ID ขององค์กรที่เป็นผู้รับในขั้นตอนนี้ | -| step_purpose | ENUM | NOT NULL,DEFAULT FOR_REVIEW | วัตถุประสงค์ของการส่งต่อในขั้นตอนนี้ **ค่าที่เป็นไปได้:** [FOR_APPROVAL: เพื่ออนุมัติ, FOR_REVIEW: เพื่อตรวจสอบ/พิจารณา, FOR_INFORMATION: เพื่อทราบ] | -| expected_days | INT | NULL | วันที่คาดหวัง | - -**Indexes**: - -- ux_cor_template_sequence (template_id, sequence): ดัชนีแบบ UNIQUE ป้องกันการมีลำดับขั้นตอนซ้ำกันภายในแม่แบบเดียวกัน - -**ความสัมพันธ์ Foreign Key:** - -- fk_cwts_template: อ้างอิงไปยัง correspondence_routing_templates(id) -- ON DELETE CASCADE: ถ้าแม่แบบถูกลบ ขั้นตอนทั้งหมดภายในแม่แบบนั้นจะถูกลบไปด้วย -- fk_cwts_org: อ้างอิงไปยัง organizations(id) -- ON DELETE CASCADE: ถ้าองค์กรถูกลบ ขั้นตอนที่ชี้ไปยังองค์กรนั้นจะถูกลบ - ---- - -### 3.11 ตาราง correspondence_routings - -**Purpose**: เป็นตารางที่เก็บข้อมูลการส่งต่อเอกสารจริง (Instance/Run-time) ติดตามประวัติการเคลื่อนย้ายของแต่ละเอกสาร ว่าผ่านใครมาบ้าง อยู่ที่ใคร และสถานะปัจจุบันคืออะไร - -| Column Name | Data Type | Constraints | Description | -| --- | --- | --- | --- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | ID หลักของรายการส่งต่อ | -| correspondence_id | INT | NOT NUL | ID ของเอกสาร (FK ไปยัง correspondence_revisions) | -| template_id | INT | NULL | ID ของแม่แบบที่ใช้สร้างสายงานนี้ (เก็บไว้เป็นข้อมูลอ้างอิง) | -| sequence | INT | NOT NULL | ลำดับของขั้นตอนการส่งต่อจริง | -| from_organization_id | INT | NOT NULL | ID ขององค์กรผู้ส่ง | -| to_organization_id| INT | NOT NULL | ID ขององค์กรผู้รับ | -| step_purpose | ENUM | NOT NULL, DEFAULT FOR_REVIEW | วัตถุประสงค์ของการส่งต่อในขั้นตอนนี้จริง **ค่าที่เป็นไปได้:** [FOR_APPROVAL: เพื่ออนุมัติ, FOR_REVIEW: เพื่อตรวจสอบ/พิจารณา, FOR_INFORMATION: เพื่อทราบ, FOR_ACTION: เพื่อดำเนินการ] | -| status | ENUM | NOT NULL, DEFAULT SENT | [ACTIONED: ดำเนินการแล้ว, FORWARDED: ส่งต่อแล้ว, REPLIE: ตอบกลับแล้ว] | -| comments | TEXT | NULL | หมายเหตุหรือความคิดเห็นในการส่งต่อ | -| due_date | DATETIME | NULL | วันที่ครบกำหนดที่ต้องดำเนินการในขั้นตอนนี้ | -| processed_by_user_id | INT |NULL | ID ของผู้ใช้ที่ดำเนินการในขั้นตอนนี้จริงๆ | -| processed_at | TIMESTAMP | NULL | เวลาที่ผู้ใช้ดำเนินการเสร็จสิ้น | -| created_at | TIMESTAMP | NOT NULL, DEFAULT CURRENT_TIMESTAMP | เวลาที่สร้างรายการส่งต่อนี้ | - -**Indexes**: - -- ux_cor_routing_sequence (correspondence_id, sequence): ดัชนีแบบ UNIQUE ทำให้มั่นใจได้ว่าแต่ละเอกสารจะมีขั้นตอนการส่งต่อตามลำดับได้เพียงชุดเดียว - -**ความสัมพันธ์ Foreign Key:** - -- fk_crs_correspondence: อ้างอิงไปยัง correspondence_revisions(correspondence_id) -- ON DELETE CASCADE`: ถ้าเอกสาร (revision) ถูกลบ ประวัติการส่งต่อทั้งหมดจะถูกลบไปด้วย -- fk_crs_template: อ้างอิงไปยัง correspondence_routing_templates(id) -- ON DELETE SET NULL: ถ้าแม่แบบถูกลบ ค่า template_id ในตารางนี้จะถูกเปลี่ยนเป็น NULL เพื่อรักษาประวัติการส่งต่อไว้ -- fk_crs_from_org: อ้างอิงไปยัง organizations(id) -- ON DELETE CASCADE: ถ้าองค์กรผู้ส่งถูกลบ รายการส่งต่อนี้จะถูกลบ -- fk_crs_to_org: อ้างอิงไปยัง organizations(id) -- ON DELETE CASCADE: ถ้าองค์กรผู้รับถูกลบ รายการส่งต่อนี้จะถูกลบ -- fk_crs_processed_by_user: อ้างอิงไปยัง users(user_id) -- ON DELETE SET NULL: ถ้าผู้ใช้ถูกลบ ค่า processed_by_user_id จะถูกเปลี่ยนเป็น NULL เพื่อรักษาประวัติการดำเนินการไว้ - ---- - -### 3.12 ตาราง correspondence_status_transitions - -**Purpose**: ตารางนี้ใช้กำหนดกฎ (State Machine) ว่าสถานะใดสามารถเปลี่ยนไปเป็นสถานะใดได้บ้าง โดยขึ้นอยู่กับประเภทของหนังสือ เพื่อควบคุมการไหลของสถานะให้ถูกต้องตามข้อบังคับ - -| Column Name | Data Type | Constraints | Description | -| -------------- | --------- | ----------- | ------------------------------------------------- | -| type_id | INT | PRIMARY KEY | ID ของประเภทหนังสือ (เช่น หนังสือภายใน, หนังสือภายนอก) | -| from_status_id | INT | PRIMARY KEY | ID ของสถานะต้นทาง (เช่น ร่าง) | -| to_status_id | INT | PRIMARY KEY | ID ของสถานะปลายทาง (เช่น รออนุมัติ) | - -**คีย์หลัก (Primary Key):** - -- (type_id, from_status_id, to_status_id)`: คีย์หลักแบบประกอบ ทำให้แน่ใจว่าแต่ละประเภทหนังสือ การเปลี่ยนจากสถานะหนึ่งไปอีกสถานะหนึ่งจะซ้ำกันไม่ได้ - -**ความสัมพันธ์ Foreign Key:** - -- fk_cst_type : อ้างอิงไปยัง correspondence_types(id) -- fk_cst_from : อ้างอิงไปยัง correspondence_status(id) -- fk_cst_to : อ้างอิงไปยัง correspondence_status(id) -- ไม่มีการกำหนด ON DELETE จึงเป็นค่าเริ่มต้น RESTRICT หมายความว่า จะลบประเภทหนังสือหรือสถานะไม่ได้ ถ้ายังมีการใช้งานอยู่ในตารางนี้ - ---- - -## **4. 📐 approval: RFA Tables (เอกสารขออนุมัติ, Workflows)** - -### 4.1 rfa_types - -**Purpose**: Master table for RFA (Request for Approval) types - -| Column Name | Data Type | Constraints | Description | -| ----------- | ------------ | --------------------------- | ------------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier | -| type_code | VARCHAR(20) | NOT NULL, UNIQUE | Type code (DWG, DOC, MAT, etc.) | -| type_name | VARCHAR(100) | NOT NULL | Full type name | -| description | TEXT | NULL | Type description | -| sort_order | INT | DEFAULT 0 | Display order | -| is_active | TINYINT(1) | DEFAULT 1 | Active status | - -**Indexes**: - -- PRIMARY KEY (id) -- UNIQUE (type_code) -- INDEX (is_active) -- INDEX (sort_order) - -**Relationships**: - -- Referenced by: rfas - -**Seed Data**: 11 RFA types including Shop Drawing (DWG), Document (DOC), Specification (SPC), Calculation (CAL), Test Report (TRP), Survey Report (SRY), QA/QC Document, Method Statement (MES), Material (MAT), As-Built (ASB), Other (OTH) - ---- - -### 4.2 rfa_status_codes - -**Purpose**: Master table for RFA status codes - -| Column Name | Data Type | Constraints | Description | -| ----------- | ------------ | --------------------------- | --------------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier | -| status_code | VARCHAR(20) | NOT NULL, UNIQUE | Status code (DFT, FAP, FRE, etc.) | -| status_name | VARCHAR(100) | NOT NULL | Full status name | -| description | TEXT | NULL | Status description | -| sort_order | INT | DEFAULT 0 | Display order | -| is_active | TINYINT(1) | DEFAULT 1 | Active status | - -**Indexes**: - -- PRIMARY KEY (id) -- UNIQUE (status_code) -- INDEX (is_active) -- INDEX (sort_order) - -**Relationships**: - -- Referenced by: rfa_revisions - -**Seed Data**: 7 status codes - -- DFT: Draft -- FAP: For Approve -- FRE: For Review -- FCO: For Construction -- ASB: AS-Built -- OBS: Obsolete -- CC: Canceled - ---- - -### 4.3 rfa_approve_codes - -**Purpose**: Master table for RFA approval result codes - -| Column Name | Data Type | Constraints | Description | -| ------------ | ------------ | --------------------------- | -------------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier | -| approve_code | VARCHAR(20) | NOT NULL, UNIQUE | Approval code (1A, 1C, 3R, etc.) | -| approve_name | VARCHAR(100) | NOT NULL | Full approval name | -| description | TEXT | NULL | Code description | -| sort_order | INT | DEFAULT 0 | Display order | -| is_active | TINYINT(1) | DEFAULT 1 | Active status | - -**Indexes**: - -- PRIMARY KEY (id) -- UNIQUE (approve_code) -- INDEX (is_active) -- INDEX (sort_order) - -**Relationships**: - -- Referenced by: rfa_revisions - -**Seed Data**: 8 approval codes - -- 1A: Approved by Authority -- 1C: Approved by CSC -- 1N: Approved As Note -- 1R: Approved with Remarks -- 3C: Consultant Comments -- 3R: Revise and Resubmit -- 4X: Reject -- 5N: No Further Action - ---- - -### 4.4 rfas - -**Purpose**: Master table for RFA documents (non-revisioned data) - -| Column Name | Data Type | Constraints | Description | -| ----------- | --------- | --------------------------- | --------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Master RFA ID | -| rfa_type_id | INT | NOT NULL, FK | Reference to rfa_types | -| created_at | DATETIME | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | -| created_by | INT | NULL, FK | User who created the record | -| deleted_at | DATETIME | NULL | Soft delete timestamp | - -**Indexes**: - -- PRIMARY KEY (id) -- FOREIGN KEY (rfa_type_id) REFERENCES rfa_types(id) -- FOREIGN KEY (created_by) REFERENCES users(user_id) ON DELETE SET NULL -- INDEX (rfa_type_id) -- INDEX (deleted_at) - -**Relationships**: - -- Parent: rfa_types, users -- Children: rfa_revisions - -**Business Rules**: - -- One RFA can have multiple revisions -- Soft delete preserves history - ---- - -### 4.5 rfa_revisions - -**Purpose**: Child table storing revision history of RFAs (1:N) - -| Column Name | Data Type | Constraints | Description | -| ------------------- | ------------ | --------------------------- | ---------------------------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique revision ID | -| correspondence_id | INT | NOT NULL, FK | Link to correspondence (RFA as correspondence) | -| rfa_id | INT | NOT NULL, FK | Master RFA ID | -| revision_number | INT | NOT NULL | Revision sequence (0, 1, 2...) | -| revision_label | VARCHAR(10) | NULL | Display revision (A, B, 1.1...) | -| is_current | BOOLEAN | DEFAULT FALSE | Current revision flag | -| rfa_status_code_id | INT | NOT NULL, FK | Current RFA status | -| rfa_approve_code_id | INT | NULL, FK | Approval result code | -| title | VARCHAR(255) | NOT NULL | RFA title | -| document_date | DATE | NULL | Document date | -| issued_date | DATE | NULL | Issue date for approval | -| received_date | DATETIME | NULL | Received date | -| approved_date | DATE | NULL | Approval date | -| description | TEXT | NULL | Revision description | -| created_at | DATETIME | DEFAULT CURRENT_TIMESTAMP | Revision creation timestamp | -| created_by | INT | NULL, FK | User who created revision | -| updated_by | INT | NULL, FK | User who last updated | - -**Indexes**: - -- PRIMARY KEY (id) -- FOREIGN KEY (correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE -- FOREIGN KEY (rfa_id) REFERENCES rfas(id) ON DELETE CASCADE -- FOREIGN KEY (rfa_status_code_id) REFERENCES rfa_status_codes(id) -- FOREIGN KEY (rfa_approve_code_id) REFERENCES rfa_approve_codes(id) ON DELETE SET NULL -- FOREIGN KEY (created_by) REFERENCES users(user_id) ON DELETE SET NULL -- FOREIGN KEY (updated_by) REFERENCES users(user_id) ON DELETE SET NULL -- UNIQUE KEY (rfa_id, revision_number) -- UNIQUE KEY (rfa_id, is_current) -- INDEX (rfa_status_code_id) -- INDEX (rfa_approve_code_id) -- INDEX (is_current) - -**Relationships**: - -- Parent: correspondences, rfas, rfa_status_codes, rfa_approve_codes, users -- Children: rfa_items, rfa_workflows - -**Business Rules**: - -- RFA is a specialized type of correspondence -- Only one revision can be current per RFA -- Links to shop drawings through rfa_items - ---- - -### 4.6 rfa_items - -**Purpose**: Junction table linking RFA revisions to shop drawing revisions (M:N) - -| Column Name | Data Type | Constraints | Description | -| ------------------------ | --------- | --------------- | ------------------------------ | -| rfarev_correspondence_id | INT | PRIMARY KEY, FK | RFA revision correspondence ID | -| shop_drawing_revision_id | INT | PRIMARY KEY, FK | Shop drawing revision ID | - -**Indexes**: - -- PRIMARY KEY (rfarev_correspondence_id, shop_drawing_revision_id) -- FOREIGN KEY (rfarev_correspondence_id) REFERENCES rfa_revisions(correspondence_id) ON DELETE CASCADE -- FOREIGN KEY (shop_drawing_revision_id) REFERENCES shop_drawing_revisions(id) ON DELETE CASCADE -- INDEX (shop_drawing_revision_id) - -**Relationships**: - -- Parent: rfa_revisions, shop_drawing_revisions - -**Business Rules**: - -- Used primarily for RFA type = 'DWG' (Shop Drawing) -- One RFA can contain multiple shop drawings -- One shop drawing can be referenced by multiple RFAs - ---- - -### 4.7 rfa_workflow_templates - -**Purpose**: Master table for RFA approval workflow templates - -| Column Name | Data Type | Constraints | Description | -| ------------- | ------------ | ----------------------------------- | ------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique template ID | -| template_name | VARCHAR(100) | NOT NULL | Template name | -| description | TEXT | NULL | Template description | -| is_active | TINYINT(1) | DEFAULT 1 | Active status | -| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | -| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | - -**Indexes**: - -- PRIMARY KEY (id) -- INDEX (is_active) -- INDEX (template_name) - -**Relationships**: - -- Children: rfa_workflow_template_steps - -**Business Rules**: - -- Defines reusable approval workflows for RFAs -- Can be assigned to specific RFA types or organizations - ---- - -### 4.8 rfa_workflow_template_steps - -**Purpose**: Child table defining steps in workflow templates - -| Column Name | Data Type | Constraints | Description | -| --------------- | --------- | --------------------------- | ----------------------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique step ID | -| template_id | INT | NOT NULL, FK | Reference to workflow template | -| step_number | INT | NOT NULL | Step sequence order | -| organization_id | INT | NOT NULL, FK | Organization responsible for step | -| role_id | INT | NULL, FK | Required role for this step | -| action_type | ENUM | NULL | Action type: REVIEW, APPROVE, ACKNOWLEDGE | -| duration_days | INT | NULL | Expected duration in days | -| is_optional | BOOLEAN | DEFAULT FALSE | Optional step flag | - -**Indexes**: - -- PRIMARY KEY (id) -- FOREIGN KEY (template_id) REFERENCES rfa_workflow_templates(id) ON DELETE CASCADE -- FOREIGN KEY (organization_id) REFERENCES organizations(id) -- FOREIGN KEY (role_id) REFERENCES roles(role_id) -- INDEX (template_id, step_number) -- INDEX (organization_id) - -**Relationships**: - -- Parent: rfa_workflow_templates, organizations, roles - -**Business Rules**: - -- Steps are executed in step_number order -- Optional steps can be skipped -- Duration used for deadline calculation - ---- - -### 4.9 rfa_workflows - -**Purpose**: Transaction log table tracking actual RFA approval workflow execution - -| Column Name | Data Type | Constraints | Description | -| --------------- | --------- | ----------------------------------- | ------------------------------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique workflow log ID | -| rfa_revision_id | INT | NOT NULL, FK | Reference to RFA revision | -| step_number | INT | NOT NULL | Current step number | -| organization_id | INT | NOT NULL, FK | Organization responsible | -| assigned_to | INT | NULL, FK | Assigned user ID | -| action_type | ENUM | NULL | Action type: REVIEW, APPROVE, ACKNOWLEDGE | -| status | ENUM | NULL | Status: PENDING, IN_PROGRESS, COMPLETED, REJECTED | -| comments | TEXT | NULL | Comments/remarks | -| completed_at | DATETIME | NULL | Completion timestamp | -| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | -| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | - -**Indexes**: - -- PRIMARY KEY (id) -- FOREIGN KEY (rfa_revision_id) REFERENCES rfa_revisions(id) ON DELETE CASCADE -- FOREIGN KEY (organization_id) REFERENCES organizations(id) -- FOREIGN KEY (assigned_to) REFERENCES users(user_id) -- INDEX (rfa_revision_id, step_number) -- INDEX (assigned_to, status) -- INDEX (status) - -**Relationships**: - -- Parent: rfa_revisions, organizations, users - -**Business Rules**: - -- Records actual workflow execution history -- Tracks who did what and when -- Multiple records per RFA revision (one per step) -- Status changes tracked via updated_at - ---- - -## **5. 📐 Drawings Tables (แบบ, หมวดหมู่)** - -### 5.1 contract_drawing_volumes - -**Purpose**: Master table for contract drawing volume classification - -| Column Name | Data Type | Constraints | Description | -| ----------- | ------------ | ----------------------------------- | ------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique volume ID | -| project_id | INT | NOT NULL, FK | Reference to projects | -| volume_code | VARCHAR(50) | NOT NULL | Volume code | -| volume_name | VARCHAR(255) | NOT NULL | Volume name | -| description | TEXT | NULL | Volume description | -| sort_order | INT | DEFAULT 0 | Display order | -| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | -| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | - -**Indexes**: - -- PRIMARY KEY (id) -- FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE -- UNIQUE KEY (project_id, volume_code) -- INDEX (sort_order) - -**Relationships**: - -- Parent: projects -- Referenced by: contract_drawings - -**Business Rules**: - -- Volume codes must be unique within a project -- Used for organizing large sets of contract drawings - ---- - -### 5.2 contract_drawing_cats - -**Purpose**: Master table for contract drawing main categories - -| Column Name | Data Type | Constraints | Description | -| ----------- | ------------ | ----------------------------------- | ------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique category ID | -| project_id | INT | NOT NULL, FK | Reference to projects | -| cat_code | VARCHAR(50) | NOT NULL | Category code | -| cat_name | VARCHAR(255) | NOT NULL | Category name | -| description | TEXT | NULL | Category description | -| sort_order | INT | DEFAULT 0 | Display order | -| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | -| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | - -**Indexes**: - -- PRIMARY KEY (id) -- FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE -- UNIQUE KEY (project_id, cat_code) -- INDEX (sort_order) - -**Relationships**: - -- Parent: projects -- Referenced by: contract_drawing_subcat_cat_maps - -**Business Rules**: - -- Category codes must be unique within a project -- Hierarchical relationship with sub-categories via mapping table - ---- - -### 5.3 contract_drawing_sub_cats - -**Purpose**: Master table for contract drawing sub-categories - -| Column Name | Data Type | Constraints | Description | -| ------------ | ------------ | ----------------------------------- | ------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique sub-category ID | -| project_id | INT | NOT NULL, FK | Reference to projects | -| sub_cat_code | VARCHAR(50) | NOT NULL | Sub-category code | -| sub_cat_name | VARCHAR(255) | NOT NULL | Sub-category name | -| description | TEXT | NULL | Sub-category description | -| sort_order | INT | DEFAULT 0 | Display order | -| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | -| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | - -**Indexes**: - -- PRIMARY KEY (id) -- FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE -- UNIQUE KEY (project_id, sub_cat_code) -- INDEX (sort_order) - -**Relationships**: - -- Parent: projects -- Referenced by: contract_drawings, contract_drawing_subcat_cat_maps - -**Business Rules**: - -- Sub-category codes must be unique within a project -- Can be mapped to multiple main categories via mapping table - ---- - -### 5.4 contract_drawing_subcat_cat_maps - -**Purpose**: Junction table mapping sub-categories to main categories (M:N) - -| Column Name | Data Type | Constraints | Description | -| ----------- | --------- | --------------- | -------------------------- | -| project_id | INT | PRIMARY KEY, FK | Reference to projects | -| sub_cat_id | INT | PRIMARY KEY, FK | Reference to sub-category | -| cat_id | INT | PRIMARY KEY, FK | Reference to main category | - -**Indexes**: - -- PRIMARY KEY (project_id, sub_cat_id, cat_id) -- FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE -- FOREIGN KEY (sub_cat_id) REFERENCES contract_drawing_sub_cats(id) ON DELETE CASCADE -- FOREIGN KEY (cat_id) REFERENCES contract_drawing_cats(id) ON DELETE CASCADE -- INDEX (sub_cat_id) -- INDEX (cat_id) - -**Relationships**: - -- Parent: projects, contract_drawing_sub_cats, contract_drawing_cats - -**Business Rules**: - -- Allows flexible categorization -- One sub-category can belong to multiple main categories -- All three fields required for uniqueness - ---- - -### 5.5 contract_drawings - -**Purpose**: Master table for contract drawings (from contract specifications) - -| Column Name | Data Type | Constraints | Description | -| ----------- | ------------ | ----------------------------------- | ------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique drawing ID | -| project_id | INT | NOT NULL, FK | Reference to projects | -| condwg_no | VARCHAR(255) | NOT NULL | Contract drawing number | -| title | VARCHAR(255) | NOT NULL | Drawing title | -| sub_cat_id | INT | NULL, FK | Reference to sub-category | -| volume_id | INT | NULL, FK | Reference to volume | -| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | -| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | -| deleted_at | DATETIME | NULL | Soft delete timestamp | -| updated_by | INT | NULL, FK | User who last updated | - -**Indexes**: - -- PRIMARY KEY (id) -- FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE -- FOREIGN KEY (sub_cat_id) REFERENCES contract_drawing_sub_cats(id) ON DELETE RESTRICT -- FOREIGN KEY (volume_id) REFERENCES contract_drawing_volumes(id) ON DELETE RESTRICT -- FOREIGN KEY (updated_by) REFERENCES users(user_id) -- UNIQUE KEY (project_id, condwg_no) -- INDEX (sub_cat_id) -- INDEX (volume_id) -- INDEX (deleted_at) - -**Relationships**: - -- Parent: projects, contract_drawing_sub_cats, contract_drawing_volumes, users -- Referenced by: shop_drawing_revision_contract_refs, contract_drawing_attachments - -**Business Rules**: - -- Drawing numbers must be unique within a project -- Represents baseline/contract drawings -- Referenced by shop drawings for compliance tracking -- Soft delete preserves history - ---- - -### 5.6 shop_drawing_main_categories - -**Purpose**: Master table for shop drawing main categories (discipline-level) - -| Column Name | Data Type | Constraints | Description | -| ------------------ | ------------ | ----------------------------------- | ------------------------------------ | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique category ID | -| main_category_code | VARCHAR(50) | NOT NULL, UNIQUE | Category code (ARCH, STR, MEP, etc.) | -| main_category_name | VARCHAR(255) | NOT NULL | Category name | -| description | TEXT | NULL | Category description | -| sort_order | INT | DEFAULT 0 | Display order | -| is_active | TINYINT(1) | DEFAULT 1 | Active status | -| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | -| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | - -**Indexes**: - -- PRIMARY KEY (id) -- UNIQUE (main_category_code) -- INDEX (is_active) -- INDEX (sort_order) - -**Relationships**: - -- Referenced by: shop_drawing_sub_categories, shop_drawings - -**Business Rules**: - -- Global categories (not project-specific) -- Typically represents engineering disciplines - ---- - -### 5.7 shop_drawing_sub_categories - -**Purpose**: Master table for shop drawing sub-categories (component-level) - -| Column Name | Data Type | Constraints | Description | -| ----------------- | ------------ | ----------------------------------- | ----------------------------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique sub-category ID | -| sub_category_code | VARCHAR(50) | NOT NULL, UNIQUE | Sub-category code (STR-COLUMN, ARCH-DOOR, etc.) | -| sub_category_name | VARCHAR(255) | NOT NULL | Sub-category name | -| main_category_id | INT | NOT NULL, FK | Reference to main category | -| description | TEXT | NULL | Sub-category description | -| sort_order | INT | DEFAULT 0 | Display order | -| is_active | TINYINT(1) | DEFAULT 1 | Active status | -| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | -| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | - -**Indexes**: - -- PRIMARY KEY (id) -- UNIQUE (sub_category_code) -- FOREIGN KEY (main_category_id) REFERENCES shop_drawing_main_categories(id) -- INDEX (main_category_id) -- INDEX (is_active) -- INDEX (sort_order) - -**Relationships**: - -- Parent: shop_drawing_main_categories -- Referenced by: shop_drawings - -**Business Rules**: - -- Global sub-categories (not project-specific) -- Hierarchical under main categories -- Represents specific drawing types or components - ---- - -### 5.8 shop_drawings - -**Purpose**: Master table for shop drawings (contractor-submitted) - -| Column Name | Data Type | Constraints | Description | -| ---------------- | ------------ | ----------------------------------- | -------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique drawing ID | -| project_id | INT | NOT NULL, FK | Reference to projects | -| drawing_number | VARCHAR(100) | NOT NULL, UNIQUE | Shop drawing number | -| title | VARCHAR(500) | NOT NULL | Drawing title | -| main_category_id | INT | NOT NULL, FK | Reference to main category | -| sub_category_id | INT | NOT NULL, FK | Reference to sub-category | -| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | -| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | -| deleted_at | DATETIME | NULL | Soft delete timestamp | -| updated_by | INT | NULL, FK | User who last updated | - -**Indexes**: - -- PRIMARY KEY (id) -- UNIQUE (drawing_number) -- FOREIGN KEY (project_id) REFERENCES projects(id) -- FOREIGN KEY (main_category_id) REFERENCES shop_drawing_main_categories(id) -- FOREIGN KEY (sub_category_id) REFERENCES shop_drawing_sub_categories(id) -- FOREIGN KEY (updated_by) REFERENCES users(user_id) -- INDEX (project_id) -- INDEX (main_category_id) -- INDEX (sub_category_id) -- INDEX (deleted_at) - -**Relationships**: - -- Parent: projects, shop_drawing_main_categories, shop_drawing_sub_categories, users -- Children: shop_drawing_revisions - -**Business Rules**: - -- Drawing numbers are globally unique across all projects -- Represents contractor shop drawings -- Can have multiple revisions -- Soft delete preserves history - ---- - -### 5.9 shop_drawing_revisions - -**Purpose**: Child table storing revision history of shop drawings (1:N) - -| Column Name | Data Type | Constraints | Description | -| --------------- | ----------- | --------------------------- | ------------------------------ | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique revision ID | -| shop_drawing_id | INT | NOT NULL, FK | Master shop drawing ID | -| revision_number | INT | NOT NULL | Revision sequence (0, 1, 2...) | -| revision_label | VARCHAR(10) | NULL | Display revision (A, B, C...) | -| revision_date | DATE | NULL | Revision date | -| description | TEXT | NULL | Revision description/changes | -| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Revision creation timestamp | - -**Indexes**: - -- PRIMARY KEY (id) -- FOREIGN KEY (shop_drawing_id) REFERENCES shop_drawings(id) ON DELETE CASCADE -- UNIQUE KEY (shop_drawing_id, revision_number) -- INDEX (revision_date) - -**Relationships**: - -- Parent: shop_drawings -- Referenced by: rfa_items, shop_drawing_revision_contract_refs, shop_drawing_revision_attachments - -**Business Rules**: - -- Revision numbers are sequential starting from 0 -- Each revision can reference multiple contract drawings -- Each revision can have multiple file attachments -- Linked to RFAs for approval tracking - ---- - -### 5.10 shop_drawing_revision_contract_refs - -**Purpose**: Junction table linking shop drawing revisions to referenced contract drawings (M:N) - -| Column Name | Data Type | Constraints | Description | -| ------------------------ | --------- | --------------- | ---------------------------------- | -| shop_drawing_revision_id | INT | PRIMARY KEY, FK | Reference to shop drawing revision | -| contract_drawing_id | INT | PRIMARY KEY, FK | Reference to contract drawing | - -**Indexes**: - -- PRIMARY KEY (shop_drawing_revision_id, contract_drawing_id) -- FOREIGN KEY (shop_drawing_revision_id) REFERENCES shop_drawing_revisions(id) ON DELETE CASCADE -- FOREIGN KEY (contract_drawing_id) REFERENCES contract_drawings(id) ON DELETE CASCADE -- INDEX (contract_drawing_id) - -**Relationships**: - -- Parent: shop_drawing_revisions, contract_drawings - -**Business Rules**: - -- Tracks which contract drawings each shop drawing revision is based on -- Ensures compliance with contract specifications -- One shop drawing revision can reference multiple contract drawings - ---- - -## **6. 🔄 Circulations Tables (ใบเวียนภายใน)** - -### 6.1 circulation_status_codes - -**Purpose**: Master table for circulation workflow status codes - -| Column Name | Data Type | Constraints | Description | -| ----------- | ----------- | --------------------------- | --------------------------------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique status ID | -| code | VARCHAR(20) | NOT NULL, UNIQUE | Status code (OPEN, IN_REVIEW, COMPLETED, CANCELLED) | -| description | VARCHAR(50) | NOT NULL | Status description | -| sort_order | INT | DEFAULT 0 | Display order | -| is_active | TINYINT(1) | DEFAULT 1 | Active status | - -**Indexes**: - -- PRIMARY KEY (id) -- UNIQUE (code) -- INDEX (is_active) -- INDEX (sort_order) - -**Relationships**: - -- Referenced by: circulations - -**Seed Data**: 4 status codes - -- OPEN: Initial status when created -- IN_REVIEW: Under review by recipients -- COMPLETED: All recipients have responded -- CANCELLED: Withdrawn/cancelled - ---- - -### 6.2 circulations - -**Purpose**: Master table for internal circulation sheets (document routing) - -| Column Name | Data Type | Constraints | Description | -| ----------------------- | ------------ | ----------------------------------- | ----------------------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique circulation ID | -| correspondence_id | INT | UNIQUE, FK | Link to correspondence (1:1 relationship) | -| organization_id | INT | NOT NULL, FK | Organization that owns this circulation | -| circulation_no | VARCHAR(100) | NOT NULL | Circulation sheet number | -| circulation_subject | VARCHAR(500) | NOT NULL | Subject/title | -| circulation_status_code | VARCHAR(20) | NOT NULL, FK | Current status code | -| created_by_user_id | INT | NOT NULL, FK | User who created circulation | -| submitted_at | TIMESTAMP | NULL | Submission timestamp | -| closed_at | TIMESTAMP | NULL | Closure timestamp | -| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | -| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | - -**Indexes**: - -- PRIMARY KEY (id) -- UNIQUE (correspondence_id) -- FOREIGN KEY (correspondence_id) REFERENCES correspondences(id) -- FOREIGN KEY (organization_id) REFERENCES organizations(id) -- FOREIGN KEY (circulation_status_code) REFERENCES circulation_status_codes(code) -- FOREIGN KEY (created_by_user_id) REFERENCES users(user_id) -- INDEX (organization_id) -- INDEX (circulation_status_code) -- INDEX (created_by_user_id) - -**Relationships**: - -- Parent: correspondences, organizations, circulation_status_codes, users -- Children: circulation_routings, circulation_attachments - -**Business Rules**: - -- Internal document routing within organization -- One-to-one relationship with correspondences -- Tracks document review/approval workflow -- Status progression: OPEN → IN_REVIEW → COMPLETED/CANCELLED - ---- - -### 6.3 circulation_templates - -**Purpose**: Master table for circulation workflow templates - -| Column Name | Data Type | Constraints | Description | -| --------------- | ------------ | ----------------------------------- | --------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique template ID | -| template_name | VARCHAR(100) | NOT NULL | Template name | -| description | TEXT | NULL | Template description | -| organization_id | INT | NOT NULL, FK | Template owner organization | -| is_active | TINYINT(1) | DEFAULT 1 | Active status | -| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | -| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | - -**Indexes**: - -- PRIMARY KEY (id) -- FOREIGN KEY (organization_id) REFERENCES organizations(id) -- INDEX (organization_id) -- INDEX (is_active) - -**Relationships**: - -- Parent: organizations -- Children: circulation_template_assignees - -**Business Rules**: - -- Organization-specific templates -- Defines reusable routing workflows - ---- - -### 6.4 circulation_template_assignees - -**Purpose**: Child table defining steps in circulation templates - -| Column Name | Data Type | Constraints | Description | -| --------------- | --------- | --------------------------- | --------------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique step ID | -| template_id | INT | NOT NULL, FK | Reference to template | -| step_number | INT | NOT NULL | Step sequence order | -| organization_id | INT | NOT NULL, FK | Organization responsible for step | -| role_id | INT | NULL, FK | Required role for this step | -| duration_days | INT | NULL | Expected duration in days | -| is_optional | BOOLEAN | DEFAULT FALSE | Optional step flag | - -**Indexes**: - -- PRIMARY KEY (id) -- FOREIGN KEY (template_id) REFERENCES circulation_templates(id) ON DELETE CASCADE -- FOREIGN KEY (organization_id) REFERENCES organizations(id) -- FOREIGN KEY (role_id) REFERENCES roles(role_id) -- INDEX (template_id, step_number) -- INDEX (organization_id) - -**Relationships**: - -- Parent: circulation_templates, organizations, roles - -**Business Rules**: - -- Steps executed in step_number order -- Optional steps can be skipped -- Duration used for deadline calculation - ---- - -### 6.5 circulation_routings - -**Purpose**: Transaction log table tracking actual circulation routing execution - -| Column Name | Data Type | Constraints | Description | -| --------------- | --------- | ----------------------------------- | ------------------------------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique routing log ID | -| circulation_id | INT | NOT NULL, FK | Reference to circulation | -| step_number | INT | NOT NULL | Current step number | -| organization_id | INT | NOT NULL, FK | Organization responsible | -| assigned_to | INT | NULL, FK | Assigned user ID | -| status | ENUM | NULL | Status: PENDING, IN_PROGRESS, COMPLETED, REJECTED | -| comments | TEXT | NULL | Comments/remarks | -| completed_at | DATETIME | NULL | Completion timestamp | -| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | -| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | - -**Indexes**: - -- PRIMARY KEY (id) -- FOREIGN KEY (circulation_id) REFERENCES circulations(id) ON DELETE CASCADE -- FOREIGN KEY (organization_id) REFERENCES organizations(id) -- FOREIGN KEY (assigned_to) REFERENCES users(user_id) -- INDEX (circulation_id, step_number) -- INDEX (assigned_to, status) -- INDEX (status) - -**Relationships**: - -- Parent: circulations, organizations, users - -**Business Rules**: - -- Records actual routing history -- Multiple records per circulation (one per step) -- Tracks who reviewed/approved and when -- Used in v_user_tasks view for pending items - ---- - -## **7. 📤 Transmittals Tables (เอกสารนำส่ง)** - -### 7.1 transmittals - -**Purpose**: Child table for transmittal-specific data (1:1 with correspondences) - -| Column Name | Data Type | Constraints | Description | -| ----------------- | --------- | --------------- | --------------------------------------------------------- | -| correspondence_id | INT | PRIMARY KEY, FK | Reference to correspondences (1:1) | -| purpose | ENUM | NULL | Purpose: FOR_APPROVAL, FOR_INFORMATION, FOR_REVIEW, OTHER | -| remarks | TEXT | NULL | Additional remarks | - -**Indexes**: - -- PRIMARY KEY (correspondence_id) -- FOREIGN KEY (correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE -- INDEX (purpose) - -**Relationships**: - -- Parent: correspondences -- Children: transmittal_items - -**Business Rules**: - -- One-to-one relationship with correspondences -- Transmittal is a correspondence type for forwarding documents -- Contains metadata about the transmission - ---- - -### 7.2 transmittal_items - -**Purpose**: Junction table listing documents included in transmittal (M:N) - -| Column Name | Data Type | Constraints | Description | -| ---------------------- | ------------ | --------------------------- | --------------------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique item ID | -| transmittal_id | INT | NOT NULL, FK | Reference to transmittal | -| item_correspondence_id | INT | NOT NULL, FK | Reference to document being transmitted | -| quantity | INT | DEFAULT 1 | Number of copies | -| remarks | VARCHAR(255) | NULL | Item-specific remarks | - -**Indexes**: - -- PRIMARY KEY (id) -- FOREIGN KEY (transmittal_id) REFERENCES transmittals(correspondence_id) ON DELETE CASCADE -- FOREIGN KEY (item_correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE -- UNIQUE KEY (transmittal_id, item_correspondence_id) -- INDEX (item_correspondence_id) - -**Relationships**: - -- Parent: transmittals, correspondences - -**Business Rules**: - -- One transmittal can contain multiple documents -- Tracks quantity of physical copies (if applicable) -- Links to any type of correspondence document - ---- - -## **8. 📎 File Management Tables (ไฟล์แนบ)** - -### 8.1 attachments - -**Purpose**: Central repository for all file attachments in the system - -| Column Name | Data Type | Constraints | Description | -| ------------------- | ------------ | --------------------------- | --------------------------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique attachment ID | -| original_filename | VARCHAR(255) | NOT NULL | Original filename from upload | -| stored_filename | VARCHAR(255) | NOT NULL | System-generated unique filename | -| file_path | VARCHAR(500) | NOT NULL | Full file path on server (/share/dms-data/) | -| mime_type | VARCHAR(100) | NOT NULL | MIME type (application/pdf, image/jpeg, etc.) | -| file_size | INT | NOT NULL | File size in bytes | -| uploaded_by_user_id | INT | NOT NULL, FK | User who uploaded file | -| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Upload timestamp | - -**Indexes**: - -- PRIMARY KEY (id) -- FOREIGN KEY (uploaded_by_user_id) REFERENCES users(user_id) ON DELETE CASCADE -- INDEX (stored_filename) -- INDEX (mime_type) -- INDEX (uploaded_by_user_id) -- INDEX (created_at) - -**Relationships**: - -- Parent: users -- Referenced by: correspondence_attachments, circulation_attachments, shop_drawing_revision_attachments, contract_drawing_attachments - -**Business Rules**: - -- Central storage prevents file duplication -- Stored filename prevents naming conflicts -- File path points to QNAP NAS storage -- Original filename preserved for download -- One file record can be linked to multiple documents - ---- - -### 8.2 correspondence_attachments - -**Purpose**: Junction table linking correspondences to file attachments (M:N) - -| Column Name | Data Type | Constraints | Description | -| ----------------- | --------- | --------------- | ---------------------------- | -| correspondence_id | INT | PRIMARY KEY, FK | Reference to correspondences | -| attachment_id | INT | PRIMARY KEY, FK | Reference to attachments | -| is_main_document | BOOLEAN | DEFAULT FALSE | Main/primary document flag | - -**Indexes**: - -- PRIMARY KEY (correspondence_id, attachment_id) -- FOREIGN KEY (correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE -- FOREIGN KEY (attachment_id) REFERENCES attachments(id) ON DELETE CASCADE -- INDEX (attachment_id) -- INDEX (is_main_document) - -**Relationships**: - -- Parent: correspondences, attachments - -**Business Rules**: - -- One correspondence can have multiple attachments -- One attachment can be linked to multiple correspondences -- is_main_document identifies primary file (typically PDF) - ---- - -### 8.3 circulation_attachments - -**Purpose**: Junction table linking circulations to file attachments (M:N) - -| Column Name | Data Type | Constraints | Description | -| ---------------- | --------- | --------------- | -------------------------- | -| circulation_id | INT | PRIMARY KEY, FK | Reference to circulations | -| attachment_id | INT | PRIMARY KEY, FK | Reference to attachments | -| is_main_document | BOOLEAN | DEFAULT FALSE | Main/primary document flag | - -**Indexes**: - -- PRIMARY KEY (circulation_id, attachment_id) -- FOREIGN KEY (circulation_id) REFERENCES circulations(id) ON DELETE CASCADE -- FOREIGN KEY (attachment_id) REFERENCES attachments(id) ON DELETE CASCADE -- INDEX (attachment_id) -- INDEX (is_main_document) - -**Relationships**: - -- Parent: circulations, attachments - ---- - -### 8.4 shop_drawing_revision_attachments - -**Purpose**: Junction table linking shop drawing revisions to file attachments (M:N) - -| Column Name | Data Type | Constraints | Description | -| ------------------------ | --------- | --------------- | ---------------------------------- | -| shop_drawing_revision_id | INT | PRIMARY KEY, FK | Reference to shop drawing revision | -| attachment_id | INT | PRIMARY KEY, FK | Reference to attachments | -| file_type | ENUM | NULL | File type: PDF, DWG, SOURCE, OTHER | -| is_main_document | BOOLEAN | DEFAULT FALSE | Main/primary document flag | - -**Indexes**: - -- PRIMARY KEY (shop_drawing_revision_id, attachment_id) -- FOREIGN KEY (shop_drawing_revision_id) REFERENCES shop_drawing_revisions(id) ON DELETE CASCADE -- FOREIGN KEY (attachment_id) REFERENCES attachments(id) ON DELETE CASCADE -- INDEX (attachment_id) -- INDEX (file_type) -- INDEX (is_main_document) - -**Relationships**: - -- Parent: shop_drawing_revisions, attachments - -**Business Rules**: - -- file_type categorizes drawing file formats -- Typically includes PDF for viewing and DWG for editing -- SOURCE may include native CAD files - ---- - -### 8.5 contract_drawing_attachments - -**Purpose**: Junction table linking contract drawings to file attachments (M:N) - -| Column Name | Data Type | Constraints | Description | -| ------------------- | --------- | --------------- | ---------------------------------- | -| contract_drawing_id | INT | PRIMARY KEY, FK | Reference to contract drawing | -| attachment_id | INT | PRIMARY KEY, FK | Reference to attachments | -| file_type | ENUM | NULL | File type: PDF, DWG, SOURCE, OTHER | -| is_main_document | BOOLEAN | DEFAULT FALSE | Main/primary document flag | - -**Indexes**: - -- PRIMARY KEY (contract_drawing_id, attachment_id) -- FOREIGN KEY (contract_drawing_id) REFERENCES contract_drawings(id) ON DELETE CASCADE -- FOREIGN KEY (attachment_id) REFERENCES attachments(id) ON DELETE CASCADE -- INDEX (attachment_id) -- INDEX (file_type) -- INDEX (is_main_document) - -**Relationships**: - -- Parent: contract_drawings, attachments - ---- - -## **9. 🔢 Document Numbering Tables (การสร้างเลขที่เอกสาร)** - -### 9.1 document_number_formats - -**Purpose**: Master table defining document numbering templates per project and type - -| Column Name | Data Type | Constraints | Description | -| ---------------------- | ------------ | ----------------------------------- | -------------------------------------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique format ID | -| project_id | INT | NOT NULL, FK | Reference to projects | -| correspondence_type_id | INT | NOT NULL, FK | Reference to correspondence types | -| format_template | VARCHAR(255) | NOT NULL | Template string (e.g., '{ORG_CODE}-{TYPE_CODE}-{SEQ:4}') | -| description | TEXT | NULL | Format description | -| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | -| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | - -**Indexes**: - -- PRIMARY KEY (id) -- FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE -- FOREIGN KEY (correspondence_type_id) REFERENCES correspondence_types(id) ON DELETE CASCADE -- UNIQUE KEY (project_id, correspondence_type_id) -- INDEX (project_id) -- INDEX (correspondence_type_id) - -**Relationships**: - -- Parent: projects, correspondence_types - -**Business Rules**: - -- One format template per project per correspondence type combination -- Template placeholders: {ORG_CODE}, {TYPE_CODE}, {YEAR}, {SEQ:n} where n is zero-padding length -- Used by document numbering module to generate unique document numbers - ---- - -### 9.2 document_number_counters - -**Purpose**: Transaction table maintaining running sequence numbers for document numbering - -| Column Name | Data Type | Constraints | Description | -| -------------------------- | --------- | --------------- | --------------------------------- | -| project_id | INT | PRIMARY KEY, FK | Reference to projects | -| originator_organization_id | INT | PRIMARY KEY, FK | Originating organization | -| correspondence_type_id | INT | PRIMARY KEY, FK | Reference to correspondence types | -| current_year | INT | PRIMARY KEY | Year (Buddhist calendar) | -| last_number | INT | DEFAULT 0 | Last assigned sequence number | - -**Indexes**: - -- PRIMARY KEY (project_id, originator_organization_id, correspondence_type_id, current_year) -- FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE -- FOREIGN KEY (originator_organization_id) REFERENCES organizations(id) ON DELETE CASCADE -- FOREIGN KEY (correspondence_type_id) REFERENCES correspondence_types(id) ON DELETE CASCADE -- INDEX (project_id) -- INDEX (originator_organization_id) -- INDEX (correspondence_type_id) -- INDEX (current_year) - -**Relationships**: - -- Parent: projects, organizations, correspondence_types - -**Business Rules**: - -- Composite primary key ensures unique counters per project/organization/type/year -- Counter resets each year -- Thread-safe increments handled by stored procedure sp_get_next_document_number -- last_number tracks highest assigned number -- Used with document_number_formats to generate complete document numbers - ---- - -## **10. ⚙️ System & Logs Tables (ระบบและ Log)** - -### 10.1 audit_logs - -**Purpose**: Comprehensive audit trail for all significant system actions - -| Column Name | Data Type | Constraints | Description | -| ------------ | ------------ | --------------------------- | ------------------------------------------------------ | -| audit_id | BIGINT | PRIMARY KEY, AUTO_INCREMENT | Unique audit log ID | -| user_id | INT | NULL, FK | User who performed action | -| action | VARCHAR(100) | NOT NULL | Action code (e.g., 'rfa.create', 'login.success') | -| entity_type | VARCHAR(50) | NULL | Entity/module affected (e.g., 'rfa', 'correspondence') | -| entity_id | VARCHAR(50) | NULL | Primary ID of affected record | -| details_json | JSON | NULL | Additional context/details in JSON format | -| ip_address | VARCHAR(45) | NULL | Client IP address (supports IPv6) | -| user_agent | VARCHAR(255) | NULL | Browser user agent string | -| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Action timestamp | - -**Indexes**: - -- PRIMARY KEY (audit_id) -- FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE SET NULL -- INDEX (user_id) -- INDEX (action) -- INDEX (entity_type, entity_id) -- INDEX (created_at) -- INDEX (ip_address) - -**Relationships**: - -- Parent: users - -**Business Rules**: - -- Immutable records (no updates/deletes) -- Captures all CRUD operations on sensitive data -- Includes authentication events (login, logout, failed attempts) -- JSON details field for flexible data storage -- Retention policy: typically 7 years for compliance -- Used for security audits, compliance reporting, and troubleshooting - -**Common Actions**: - -- Authentication: login.success, login.failed, logout -- Documents: correspondence.create, correspondence.update, rfa.submit -- Users: user.create, user.deactivate, role.assign -- Workflow: rfa.approve, rfa.reject, circulation.complete - ---- - -### 10.2 notifications - -**Purpose**: User notification queue for email, LINE, and in-system alerts - -| Column Name | Data Type | Constraints | Description | -| ----------------- | ------------ | --------------------------- | ------------------------------------------------ | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique notification ID | -| user_id | INT | NOT NULL, FK | Recipient user ID | -| title | VARCHAR(255) | NOT NULL | Notification title/subject | -| message | TEXT | NOT NULL | Notification message body | -| notification_type | ENUM | NOT NULL | Type: EMAIL, LINE, SYSTEM | -| is_read | BOOLEAN | DEFAULT FALSE | Read status flag | -| entity_type | VARCHAR(50) | NULL | Related entity type (e.g., 'rfa', 'circulation') | -| entity_id | INT | NULL | Related entity ID | -| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Notification creation timestamp | - -**Indexes**: - -- PRIMARY KEY (id) -- FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE -- INDEX (user_id) -- INDEX (notification_type) -- INDEX (is_read) -- INDEX (entity_type, entity_id) -- INDEX (created_at) -- COMPOSITE INDEX (user_id, is_read, created_at) - For user notification listing - -**Relationships**: - -- Parent: users - -**Business Rules**: - -- EMAIL: Sent via SMTP to user's email address -- LINE: Sent via LINE Notify API to user's LINE ID -- SYSTEM: In-app notifications displayed in user interface -- Same notification can trigger multiple types (EMAIL + SYSTEM) -- entity_type/entity_id allow deep-linking to related records -- is_read flag only applicable for SYSTEM notifications -- Auto-cleanup: delete read notifications older than 30 days - -**Common Notification Triggers**: - -- Task assignment (circulation routing, RFA workflow) -- Document status changes (submitted, approved, rejected) -- Approaching deadlines -- System announcements -- Mention in comments - ---- - -### 10.3 search_indices - -**Purpose**: Full-text search index for document content - -| Column Name | Data Type | Constraints | Description | -| ----------- | ----------- | --------------------------- | ------------------------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique index ID | -| entity_type | VARCHAR(50) | NOT NULL | Entity type (e.g., 'correspondence', 'rfa') | -| entity_id | INT | NOT NULL | Entity primary ID | -| content | TEXT | NOT NULL | Searchable text content | -| indexed_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Last indexing timestamp | - -**Indexes**: - -- PRIMARY KEY (id) -- INDEX (entity_type, entity_id) -- INDEX (indexed_at) -- FULLTEXT INDEX (content) - Enables full-text searching - -**Business Rules**: - -- Automatically populated/updated when documents change -- Content includes: title, description, document number, metadata -- May include OCR text from PDF attachments (future enhancement) -- Used by advanced search functionality -- Periodic re-indexing to catch missed updates -- Supports Boolean operators, phrase searching - -**Search Features**: - -- Natural language queries -- Wildcard support (\*, ?) -- Boolean operators (AND, OR, NOT) -- Phrase matching with quotes -- Result ranking by relevance - ---- - -### 10.4 backup_logs - -**Purpose**: Log table tracking database and file backup operations - -| Column Name | Data Type | Constraints | Description | -| ------------- | ------------ | --------------------------- | ---------------------------------- | -| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique backup log ID | -| backup_type | ENUM | NOT NULL | Type: DATABASE, FILES, FULL | -| backup_path | VARCHAR(500) | NOT NULL | Path to backup file/directory | -| file_size | BIGINT | NULL | Backup file size in bytes | -| status | ENUM | NOT NULL | Status: STARTED, COMPLETED, FAILED | -| started_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Backup start timestamp | -| completed_at | TIMESTAMP | NULL | Backup completion timestamp | -| error_message | TEXT | NULL | Error details if failed | - -**Indexes**: - -- PRIMARY KEY (id) -- INDEX (backup_type) -- INDEX (status) -- INDEX (started_at) -- INDEX (completed_at) - -**Business Rules**: - -- DATABASE: MariaDB dump of database schema and data -- FILES: Backup of attachment files from QNAP storage -- FULL: Complete system backup (database + files) -- Triggered by n8n cron jobs -- Backup retention policy defined in backup strategy -- Failed backups trigger alert notifications -- completed_at - started_at = backup duration - -**Monitoring**: - -- Alert if no successful backup in 24 hours -- Track backup size trends over time -- Verify backup integrity with test restores - ---- - -## **11. 📊 Views & Procedures (วิว และ โปรซีเดอร์)** - -### 11.1 v_current_correspondences - -**Purpose**: View showing current revision of all non-RFA correspondences - -**Columns**: - -- correspondence_id, correspondence_number, correspondence_type_id/code/name -- project_id, project_code, project_iname -- organization_id, organization_code, organization_name -- revision_id, revision_number, revision_label -- title, document_date, issued_date, received_date, due_date -- correspondence_status_id, correspondence_status_code, correspondence_status_name -- created_by, created_by_username, revision_created_at - -**Filters**: - -- is_current = TRUE (only latest revision) -- correspondence_type NOT IN ('RFA') (excludes RFAs) -- deleted_at IS NULL (excludes soft-deleted records) - -**Business Rules**: - -- Provides flattened view of current correspondence state -- Joins correspondence_revisions with is_current flag -- Used by dashboard, document listing screens -- Excludes RFAs (they have separate view) - ---- - -### 11.2 v_current_rfas - -**Purpose**: View showing current revision of all RFA documents - -**Columns**: - -- rfa_id, rfa_type_id, rfa_type_code, rfa_type_name -- correspondence_id, correspondence_number -- project_id, project_code, project_iname -- organization_id, organization_name -- revision_id, revision_number, revision_label -- title, document_date, issued_date, received_date, approved_date -- rfa_status_code_id, rfa_status_code, rfa_status_name -- rfa_approve_code_id, rfa_approve_code, rfa_approve_code_name -- created_by, created_by_username, revision_created_at - -**Filters**: - -- is_current = TRUE -- deleted_at IS NULL (both rfas and correspondences) - -**Business Rules**: - -- Specialized view for RFA documents -- Includes RFA-specific fields (approval codes, approved date) -- Joins across rfas → rfa_revisions → correspondences -- Used by RFA management screens - ---- - -### 11.3 v_contract_parties_all - -**Purpose**: View showing all organization relationships across contracts and projects - -**Columns**: - -- contract_id, contract_code, contract_name -- project_id, project_code, project_iname -- organization_id, organization_code, organization_name -- role_in_contract - -**Business Rules**: - -- Joins contracts → projects → contract_organizations → organizations -- Shows only active contracts (is_active = TRUE) -- Used for permission checks and document routing -- Supports multi-organization projects/contracts - ---- - -### 11.4 v_user_tasks - -**Purpose**: View showing pending tasks assigned to users (action items) - -**Columns**: - -- routing_id, circulation_id, circulation_no, circulation_subject -- correspondence_id, correspondence_number -- project_id, project_code, project_name -- user_id, username, first_name, last_name -- organization_id, organization_name -- step_number, task_status, comments -- completed_at, assigned_at, circulation_created_at - -**Filters**: - -- status IN ('PENDING', 'IN_PROGRESS') -- assigned_to IS NOT NULL - -**Business Rules**: - -- Shows circulation routings requiring user action -- Used for "My Tasks" / "Inbox" functionality -- Excludes completed/cancelled tasks -- Ordered by creation date (oldest first) - ---- - -### 11.5 v_audit_log_details - -**Purpose**: View enriching audit logs with user information - -**Columns**: - -- audit_id, user_id, username, email, first_name, last_name -- action, entity_type, entity_id -- details_json, ip_address, user_agent -- created_at - -**Business Rules**: - -- Joins audit_logs with users table -- Used for audit trail reports -- Includes user details even if user later deleted (LEFT JOIN) - ---- - -### 11.6 v_user_all_permissions - -**Purpose**: View showing all effective permissions for users across all scopes - -**Columns**: - -- user_id, role_id, role_name -- permission_id, permission_name -- module, scope_level -- organization_id, project_id, contract_id -- permission_scope (GLOBAL, ORGANIZATION, PROJECT, CONTRACT) - -**Business Rules**: - -- UNION of permissions from Global, Organization, Project, and Contract scopes -- Used for authorization checks -- Considers role-permission mappings at all levels -- Only shows active permissions (is_active = 1) -- One row per user-permission-scope combination - -**Usage Example**: - -```sql -SELECT permission_name -FROM v_user_all_permissions -WHERE user_id = ? - AND project_id = ? - AND permission_name = 'document.edit'; -``` - ---- - -### 11.7 v_documents_with_attachments - -**Purpose**: View showing all documents and their attachment counts - -**Columns**: - -- document_type (CORRESPONDENCE, CIRCULATION, SHOP_DRAWING, CONTRACT_DRAWING) -- document_id, document_number -- project_id, project_code, project_name -- attachment_count, latest_attachment_date - -**Business Rules**: - -- UNION of all document types with attachments -- Used for document listing with file indicators -- Helps identify documents missing attachments -- Aggregates count per document - ---- - -### 11.8 v_document_statistics - -**Purpose**: View providing aggregated document statistics by project, type, and status - -**Columns**: - -- project_id, project_code, project_name -- correspondence_type_id, correspondence_type_code, correspondence_type_name -- status_id, status_code, status_name -- document_count, revision_count - -**Business Rules**: - -- CROSS JOIN creates all possible combinations -- LEFT JOIN shows zeros for combinations with no documents -- Only includes active projects, types, and statuses -- Used for dashboard charts and reports -- Groups by project → type → status - ---- - -### 11.9 sp_get_next_document_number - -**Purpose**: Stored procedure to safely generate next sequential document number - -**Parameters**: - -- IN p_project_id INT -- IN p_originator_organization_id INT -- IN p_correspondence_type_id INT -- IN p_current_year INT -- OUT p_next_number INT - -**Logic**: - -1. Start transaction -2. SELECT last_number FOR UPDATE (locks row) -3. If record doesn't exist, INSERT with last_number = 1 -4. Else UPDATE last_number = last_number + 1 -5. Return new number via OUT parameter -6. COMMIT transaction - -**Business Rules**: - -- Thread-safe counter increment -- FOR UPDATE lock prevents race conditions -- Handles first-time counter initialization -- Rolls back on any error -- Must be called within document creation transaction -- Used in conjunction with document_number_formats template - -**Usage Example**: - -```sql -CALL sp_get_next_document_number( - 1, -- project_id - 10, -- organization_id - 1, -- type_id (RFA) - 2568, -- Buddhist year - @next_number -); --- @next_number now contains next sequence -``` - ---- - -## Database Indexes Summary - -### Performance Optimization Indexes - -**Primary Indexes** (automatic with PRIMARY KEY): - -- All tables have PRIMARY KEY with AUTO_INCREMENT - -**Foreign Key Indexes** (automatic with FOREIGN KEY): - -- All FK relationships automatically indexed - -**Additional Performance Indexes**: - -1. **Correspondence Tables**: - - - `idx_correspondences_type_project` on (correspondence_type_id, project_id) - - `idx_corr_revisions_current_status` on (is_current, correspondence_status_id) - - `idx_corr_revisions_correspondence_current` on (correspondence_id, is_current) - - `idx_correspondences_project_type` on (project_id, correspondence_type_id) - -2. **RFA Tables**: - - - `idx_rfa_revisions_current_status` on (is_current, rfa_status_code_id) - - `idx_rfa_revisions_rfa_current` on (rfa_id, is_current) - -3. **Circulation Tables**: - - - `idx_circulation_routings_status_assigned` on (status, assigned_to) - - `idx_circulation_routings_circulation_status` on (circulation_id, status) - -4. **Document Numbering**: - - - `idx_doc_counter_composite` on (project_id, originator_organization_id, correspondence_type_id, current_year) - -5. **Audit & Notifications**: - - - `idx_audit_logs_reporting` on (created_at, entity_type, action) - - `idx_notifications_user_unread` on (user_id, is_read, created_at) - -6. **Search**: - - `FULLTEXT idx_search_indices_content` on (content) - ---- - -## Data Integrity Constraints - -### Foreign Key Constraints - -**Cascade Delete**: - -- Parent-child relationships where child should be deleted with parent -- Examples: correspondence_revisions, shop_drawing_revisions, project/contract relationships - -**Restrict Delete**: - -- Prevents deletion if references exist -- Examples: correspondence_types, rfa_status_codes, organizations (when referenced) - -**Set NULL**: - -- Preserves record but removes reference -- Examples: originator_id, created_by, updated_by - -### Unique Constraints - -1. **Globally Unique**: - - - usernames, emails - - shop_drawing.drawing_number - -2. **Unique Within Scope**: - - - (project_id, correspondence_number) - - (project_id, condwg_no) - - (correspondence_id, revision_number) - - (rfa_id, revision_number) - -3. **Composite Unique**: - - (correspondence_id, is_current) - ensures only one current revision - - (project_id, correspondence_type_id) - in document_number_formats - -### Check Constraints - -1. **user_assignments.chk_scope**: - - Ensures only one scope field (organization_id, project_id, contract_id) is NOT NULL - - OR all are NULL for Global scope - -### Business Rule Constraints - -1. **Soft Delete Pattern**: - - - deleted_at timestamp instead of hard delete - - Preserves audit trail and relationships - - Applied to: correspondences, rfas, shop_drawings, contract_drawings - -2. **Current Revision Pattern**: - - - is_current flag with UNIQUE constraint - - Ensures only one current revision per document - -3. **Sequential Numbering**: - - revision_number starts at 0, increments by 1 - - Enforced by application logic + stored procedure - ---- - -## Security & Permissions Model - -### Access Control Hierarchy - -```tree -Global Scope (Superadmin) - └── Organization Scope (Org Admin, Document Control) - └── Project Scope (Project Manager) - └── Contract Scope (Contract Admin) -``` - -### Permission Inheritance - -- Users can have multiple role assignments at different scopes -- More specific scopes inherit access from broader scopes -- Permission checks evaluate all applicable scopes -- View v_user_all_permissions aggregates effective permissions - -### Role-Based Access Control (RBAC) - -**7 Predefined Roles**: - -1. Superadmin (Global) - Full system access -2. Org Admin (Organization) - Organization management -3. Document Control (Organization) - Document lifecycle + admin powers -4. Editor (Organization) - Document CRUD -5. Viewer (Organization) - Read-only -6. Project Manager (Project) - Project + document management -7. Contract Admin (Contract) - Contract-specific management - -### Permission Categories (49 total) - -1. **System Management** (1): Full system control -2. **Organization Management** (4): CRUD on organizations -3. **Project Management** (8): CRUD + member/contract management -4. **Role & Permission Management** (4): RBAC administration -5. **Master Data Management** (4): Document types, categories, tags -6. **User Management** (5): User CRUD + organization assignment -7. **Contract Management** (2): Contract administration -8. **Document Management** (16): Full document lifecycle -9. **Workflow Management** (3): Approval workflow control -10. **Search & Reporting** (2): Advanced search, report generation - ---- - -## Data Migration & Seeding - -### Pre-populated Master Data - -1. **organization_roles**: Not used in current implementation -2. **organizations**: 15 organizations (Owner, Consultants, Contractors, Third parties) -3. **projects**: 5 projects (LCBP3 + 4 sub-contracts) -4. **contracts**: 7 contracts -5. **users**: 3 initial users (superadmin, editor01, viewer01) -6. **roles**: 7 predefined roles -7. **permissions**: 49 system permissions -8. **role_permissions**: Complete permission mappings -9. **project_organizations**: Project-organization relationships -10. **contract_organizations**: Contract-organization-role relationships -11. **correspondence_types**: 10 types -12. **correspondence_status**: 23 status codes -13. **rfa_types**: 11 types -14. **rfa_status_codes**: 7 statuses -15. **rfa_approve_codes**: 8 approval codes -16. **circulation_status_codes**: 4 statuses - -### Initial Passwords - -All seed users have password: `password123` - -- Hashed as: `$2y$10$0kjBMxWq7E4G7P.dc8r5i.cjiPBiup553AsFpDfxUt31gKg9h/udq` -- **Must be changed on first login in production** - ---- - -## Backup & Recovery Strategy - -### Database Backup - -**Strategy**: - -- Daily full database backups -- Hourly incremental backups (transaction logs) -- Retention: 30 days online, 7 years archived - -**Backup Method**: - -- MariaDB mysqldump for logical backups -- MariaDB Backup (Mariabackup) for physical backups -- Automated via n8n cron workflows - -### File Backup - -**Strategy**: - -- Daily backup of /share/dms-data/ directory -- QNAP snapshot every 4 hours -- Offsite replication to secondary NAS - -**File Organization**: - -```tree -/share/dms-data/ - ├── attachments/ - │ ├── 2025/ - │ │ ├── 01/ - │ │ │ └── {uuid}-{filename} - │ │ └── 02/ - │ └── 2024/ - └── temp/ -``` - -### Recovery Procedures - -1. **Point-in-Time Recovery**: Using transaction logs -2. **Full Restore**: From latest full backup -3. **Selective Restore**: Individual tables or records -4. **File Recovery**: From QNAP snapshots or backup - ---- - -## Performance Optimization - -### Query Optimization - -1. **Use Indexed Columns**: WHERE, JOIN, ORDER BY clauses -2. **Avoid SELECT**: Specify needed columns -3. **Use Views**: For complex, frequently-used queries -4. **Limit Result Sets**: Use LIMIT and pagination -5. **Analyze Slow Queries**: Enable slow query log - -### Index Maintenance - -```sql --- Check index usage -SELECT * FROM information_schema.STATISTICS -WHERE TABLE_SCHEMA = 'lcbp3'; - --- Optimize tables -OPTIMIZE TABLE correspondences; - --- Analyze tables -ANALYZE TABLE correspondences; -``` - -### Connection Pooling - -- Backend uses connection pool (NestJS TypeORM) -- Min pool size: 5 -- Max pool size: 20 -- Idle timeout: 10 minutes - ---- - -## Data Validation Rules - -### Required Fields Validation - -**At Application Level**: - -- Email format validation -- Date range validation (start_date < end_date) -- File size limits (5MB per attachment) -- File type restrictions (PDF, DWG, DOC, XLS, images) - -**At Database Level**: - -- NOT NULL constraints -- UNIQUE constraints -- Foreign key constraints -- Check constraints (user_assignments scope) - -### Business Logic Validation - -1. **Document Workflow**: - - - Cannot edit submitted documents (unless Document Control) - - Cannot skip workflow steps (unless forced) - - Must provide approval comments - -2. **User Management**: - - - Cannot delete users with active assignments - - Cannot deactivate own account - - Must have valid organization for non-Global roles - -3. **File Management**: - - Original filename preserved for audit - - Unique stored filename prevents conflicts - - File path must exist and be accessible - ---- - -## Change Log & Versioning - -### Database Version: v1.4.0 - -**Changes from v1.3.0**: - -- Added comprehensive RBAC system (roles, permissions, user_assignments) -- Refactored organization-project-contract relationships -- Added junction tables for M:N relationships -- Implemented soft delete pattern -- Added full-text search support -- Enhanced audit logging with JSON details -- Added circulation workflow templates -- Improved document numbering with stored procedure -- Added comprehensive views for common queries -- Optimized indexes for performance - -**Migration Path**: - -- v1.3.0 → v1.4.0: Run migration script (not provided in this excerpt) -- Backup database before migration -- Test migration on staging environment first - ---- - -## Technical Specifications - -### Database Configuration - -**MariaDB Server**: - -- Version: 10.11 -- Character Set: utf8mb4 -- Collation: utf8mb4_general_ci -- Time Zone: +07:00 (Bangkok/Asia) -- SQL Mode: STRICT_TRANS_TABLES, NO_ENGINE_SUBSTITUTION - -**Connection Settings**: - -- Host: Container on QNAP TS-473A -- Port: 3306 (default) -- Max Connections: 100 -- Max Packet Size: 64MB - -### Table Engine - -**InnoDB Features Used**: - -- ACID compliance -- Foreign key constraints -- Row-level locking -- Crash recovery -- Transaction support - -### Storage Requirements - -**Estimated Initial Size**: - -- Database: ~50 MB (with seed data) -- Indexes: ~20 MB -- Total: ~70 MB - -**Growth Estimates**: - -- 1,000 documents/month: +100 MB/month (database) -- 10 attachments/document @ 2MB avg: +20 GB/month (files) -- Plan for 1TB+ storage within first year - ---- - -## Application Integration - -### Backend (NestJS) - -**TypeORM Entities**: - -- One entity class per table -- Decorators for columns, relationships -- DTOs for data transfer -- Repositories for data access - -**Key Modules**: - -- AuthModule: Authentication, authorization -- DocumentsModule: Correspondence, RFA management -- DrawingsModule: Shop drawing, contract drawing -- WorkflowModule: Circulation, approval workflows -- FilesModule: Attachment management -- UsersModule: User, role, permission management - -### Frontend (Next.js) - -**Key Features**: - -- Document listing/search -- Document creation wizards -- Workflow approval interface -- File upload/download -- User management console -- Dashboard analytics - -### Integration Points - -1. **Document Numbering**: - - - Call sp_get_next_document_number - - Format with template from document_number_formats - - Store in correspondences.correspondence_number - -2. **File Upload**: - - - Upload to QNAP /share/dms-data/ - - Create attachment record - - Link via junction table - -3. **Workflow Execution**: - - - Check rfa_workflow_templates - - Create rfa_workflows records - - Update status as steps complete - - Send notifications - -4. **Permission Checks**: - - Query v_user_all_permissions - - Cache results per session - - Re-check on sensitive operations - ---- - -## Monitoring & Maintenance - -### Health Checks - -```sql --- Database size -SELECT - table_schema, - SUM(data_length + index_length) / 1024 / 1024 AS size_mb -FROM information_schema.TABLES -WHERE table_schema = 'dms_db' -GROUP BY table_schema; - --- Table sizes -SELECT - table_name, - (data_length + index_length) / 1024 / 1024 AS size_mb, - table_rows -FROM information_schema.TABLES -WHERE table_schema = 'dms_db' -ORDER BY (data_length + index_length) DESC; - --- Active connections -SHOW PROCESSLIST; - --- Lock wait statistics -SELECT * FROM information_schema.INNODB_LOCK_WAITS; -``` - -### Scheduled Maintenance - -**Daily**: - -- Full database backup -- Check backup log for failures -- Monitor disk space - -**Weekly**: - -- OPTIMIZE tables -- ANALYZE tables -- Review slow query log -- Check for deadlocks - -**Monthly**: - -- Review audit logs -- Clean up old notifications (30+ days) -- Archive old audit logs (7+ years) -- Verify backup integrity (test restore) - -**Quarterly**: - -- Review and optimize indexes -- Update database statistics -- Capacity planning review - ---- - -## Glossary - -**Terms**: - -- **Correspondence**: Any formal document exchanged between parties -- **RFA**: Request for Approval - formal submittal for review/approval -- **Circulation**: Internal document routing workflow -- **Transmittal**: Cover sheet for forwarding multiple documents -- **Shop Drawing**: Detailed construction drawing from contractor -- **Contract Drawing**: Baseline drawing from contract specifications -- **Revision**: Version of a document -- **Originator**: Organization that creates/sends a document -- **Recipient**: Organization that receives a document (TO or CC) -- **Scope**: Level of permission application (Global, Organization, Project, Contract) - -**Acronyms**: - -- **DMS**: Document Management System -- **LCBP3**: Laem Chabang Port Phase 3 -- **RBAC**: Role-Based Access Control -- **RFA**: Request for Approval -- **RFI**: Request for Information -- **CSC**: Construction Supervision Consultant -- **TO**: Primary recipient (action required) -- **CC**: Carbon copy (for information) -- **QNAP**: Network Attached Storage device manufacturer - ---- - -**Document Control**: - -- Document: Data Dictionary - DMS v1.4.0 -- Version: 1.0 -- Date: 2025-01-XX -- Author: System Architecture Team -- Status: FINAL -- Classification: Internal Technical Documentation - ---- - -_End of Data Dictionary +# **ตารางฐานข้อมูล (Data Dictionary) - LCBP3-DMS (V1.4.1)** + +เอกสารนี้สรุปโครงสร้างตาราง, Foreign Keys (FK), และ Constraints ที่สำคัญทั้งหมดในฐานข้อมูล LCBP3-DMS (v1.4.0) เพื่อใช้เป็นเอกสารอ้างอิงสำหรับทีมพัฒนา Backend (NestJS) และ Frontend (Next.js) โดยอิงจาก Requirements และ SQL Script ล่าสุด [GLM-4.6] + +--- + +## **1. 🏢 Core & Master Data Tables (องค์กร, โครงการ, สัญญา)** + +### 1.1 organization_roles + +**Purpose**: Master table for organization role types in the system + +| Column Name | Data Type | Constraints | Description | +| ----------- | ----------- | --------------------------- | ---------------------------------------------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier for organization role | +| role_name | VARCHAR(20) | NOT NULL, UNIQUE | Role name (OWNER, DESIGNER, CONSULTANT, CONTRACTOR, THIRD PARTY) | + +**Indexes**: + +- PRIMARY KEY (id) +- UNIQUE (role_name) + +**Business Rules**: + +- Predefined system roles for organization types +- Cannot be deleted if referenced by organizations + +--- + +### 1.2 organizations + +**Purpose**: Master table storing all organizations involved in the system + +| Column Name | Data Type | Constraints | Description | +| ----------------- | ------------ | ----------------------------------- | ---------------------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier for organization | +| organization_code | VARCHAR(20) | NOT NULL, UNIQUE | Organization code (e.g., 'กทท.', 'TEAM') | +| organization_name | VARCHAR(255) | NOT NULL | Full organization name | +| is_active | BOOLEAN | DEFAULT TRUE | Active status (1=active, 0=inactive) | +| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | +| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | + +**Indexes**: + +- PRIMARY KEY (id) +- UNIQUE (organization_code) +- INDEX (is_active) + +**Relationships**: + +- Referenced by: users, project_organizations, contract_organizations, correspondences, circulations + +**Seed Data**: Pre-populated with 15 organizations including: + +- Port Authority of Thailand (กทท.) +- Project supervision consultants (สค©.3-xx) +- Design consultants (TEAM) +- Construction supervisors (คคง.) +- Contractors (ผรม.1-4) +- Third parties (EN, CAR) + +--- + +### 1.3 projects + +**Purpose**: Master table for all projects in the system + +| Column Name | Data Type | Constraints | Description | +| ------------ | ------------ | --------------------------- | ----------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier for project | +| project_code | VARCHAR(50) | NOT NULL, UNIQUE | Project code (e.g., 'LCBP3') | +| project_name | VARCHAR(255) | NOT NULL | Full project name | +| is_active | TINYINT(1) | DEFAULT 1 | Active status | + +**Indexes**: + +- PRIMARY KEY (id) +- UNIQUE (project_code) +- INDEX (is_active) + +**Relationships**: + +- Referenced by: contracts, correspondences, document_number_formats, drawings + +**Seed Data**: 5 projects for Laem Chabang Port Phase 3 (LCBP3) including main project and 4 sub-contracts + +--- + +### 1.4 contracts + +**Purpose**: Master table for contracts within projects + +| Column Name | Data Type | Constraints | Description | +| ------------- | ------------ | ----------------------------------- | ------------------------------ | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier for contract | +| project_id | INT | NOT NULL, FK | Reference to projects table | +| contract_code | VARCHAR(50) | NOT NULL, UNIQUE | Contract code | +| contract_name | VARCHAR(255) | NOT NULL | Full contract name | +| description | TEXT | NULL | Contract description | +| start_date | DATE | NULL | Contract start date | +| end_date | DATE | NULL | Contract end date | +| is_active | BOOLEAN | DEFAULT TRUE | Active status | +| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | +| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | + +**Indexes**: + +- PRIMARY KEY (id) +- UNIQUE (contract_code) +- FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE +- INDEX (project_id, is_active) + +**Relationships**: + +- Parent: projects +- Referenced by: contract_organizations, user_assignments + +**Seed Data**: 7 contracts including design, supervision, construction, and environmental monitoring + +--- + +## **2. 👥 Users & RBAC Tables (ผู้ใช้, สิทธิ์, บทบาท)** + +### 2.1 users + +**Purpose**: Master table storing all system users + +| Column Name | Data Type | Constraints | Description | +| ----------------------- | ------------ | ----------------------------------- | -------------------------------- | +| user_id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier for user | +| username | VARCHAR(50) | NOT NULL, UNIQUE | Login username | +| password_hash | VARCHAR(255) | NOT NULL | Hashed password (bcrypt) | +| first_name | VARCHAR(50) | NULL | User's first name | +| last_name | VARCHAR(50) | NULL | User's last name | +| email | VARCHAR(100) | NOT NULL, UNIQUE | Email address | +| line_id | VARCHAR(100) | NULL | LINE messenger ID | +| primary_organization_id | INT | NULL, FK | Primary organization affiliation | +| is_active | TINYINT(1) | DEFAULT 1 | Active status | +| failed_attempts | INT | DEFAULT 0 | Failed login attempts counter | +| locked_until | DATETIME | NULL | Account lock expiration time | +| last_login_at | TIMESTAMP | NULL | Last successful login timestamp | +| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | +| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | + +**Indexes**: + +- PRIMARY KEY (user_id) +- UNIQUE (username) +- UNIQUE (email) +- FOREIGN KEY (primary_organization_id) REFERENCES organizations(id) ON DELETE SET NULL +- INDEX (is_active) +- INDEX (email) + +**Relationships**: + +- Parent: organizations (primary_organization_id) +- Referenced by: user_assignments, audit_logs, notifications, circulation_routings + +**Security Features**: + +- Password stored as bcrypt hash +- Account locking after failed attempts +- Last login tracking + +**Seed Data**: 3 initial users (superadmin, editor01, viewer01) + +--- + +### 2.2 roles + +**Purpose**: Master table defining system roles with scope levels + +| Column Name | Data Type | Constraints | Description | +| ----------- | ------------ | --------------------------- | ---------------------------------------------------- | +| role_id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier for role | +| role_name | VARCHAR(100) | NOT NULL | Role name (e.g., 'Superadmin', 'Document Control') | +| scope | ENUM | NOT NULL | Scope level: Global, Organization, Project, Contract | +| description | TEXT | NULL | Role description | +| is_system | BOOLEAN | DEFAULT FALSE | System role flag (cannot be deleted) | + +**Indexes**: + +- PRIMARY KEY (role_id) +- INDEX (scope) + +**Relationships**: + +- Referenced by: role_permissions, user_assignments + +**Seed Data**: 7 predefined roles + +1. Superadmin (Global) - Full system access +2. Org Admin (Organization) - Organization management +3. Document Control (Organization) - Document lifecycle management +4. Editor (Organization) - Document creation and editing +5. Viewer (Organization) - Read-only access +6. Project Manager (Project) - Project-level management +7. Contract Admin (Contract) - Contract-specific administration + +--- + +### 2.3 permissions + +**Purpose**: Master table defining all system permissions + +| Column Name | Data Type | Constraints | Description | +| --------------- | ------------ | --------------------------- | ------------------------------------------------------ | +| permission_id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier for permission | +| permission_name | VARCHAR(100) | NOT NULL, UNIQUE | Permission code (e.g., 'rfas.create', 'document.view') | +| description | TEXT | NULL | Permission description | +| module | VARCHAR(50) | NULL | Related module name | +| scope_level | ENUM | NULL | Scope: GLOBAL, ORG, PROJECT | +| is_active | TINYINT(1) | DEFAULT 1 | Active status | + +**Indexes**: + +- PRIMARY KEY (permission_id) +- UNIQUE (permission_name) +- INDEX (module) +- INDEX (scope_level) +- INDEX (is_active) + +**Relationships**: + +- Referenced by: role_permissions + +**Permission Categories**: + +1. **System Management** (1): system.manage_all +2. **Organization Management** (2-5): create, edit, delete, view +3. **Project Management** (6-9, 23-26): create, edit, delete, view, manage members/contracts/reports +4. **Role & Permission Management** (10-13): create, edit, delete roles, assign permissions +5. **Master Data Management** (14-17): document types, statuses, categories, tags +6. **User Management** (18-22): create, edit, delete, view, assign organization +7. **Contract Management** (27-28): manage members, view +8. **Document Management** (29-44): CRUD operations, workflows, circulation +9. **Search & Reporting** (48-49): advanced search, generate reports + +**Total Permissions**: 49 + +--- + +### 2.4 role_permissions + +**Purpose**: Junction table mapping roles to permissions (M:N) + +| Column Name | Data Type | Constraints | Description | +| ------------- | --------- | --------------- | ------------------------------ | +| role_id | INT | PRIMARY KEY, FK | Reference to roles table | +| permission_id | INT | PRIMARY KEY, FK | Reference to permissions table | + +**Indexes**: + +- PRIMARY KEY (role_id, permission_id) +- FOREIGN KEY (role_id) REFERENCES roles(role_id) ON DELETE CASCADE +- FOREIGN KEY (permission_id) REFERENCES permissions(permission_id) ON DELETE CASCADE +- INDEX (permission_id) + +**Relationships**: + +- Parent: roles, permissions + +**Seed Data**: Complete permission mappings for all 7 roles + +- Superadmin: All 49 permissions +- Org Admin: 15 permissions (user/org/tag management, view access) +- Document Control: 26 permissions (full document lifecycle) +- Editor: 12 permissions (document CRUD without admin powers) +- Viewer: 2 permissions (view and search only) +- Project Manager: 23 permissions (project management + document CRUD) +- Contract Admin: 15 permissions (contract management + document CRUD) + +--- + +### 2.5 user_assignments + +**Purpose**: Junction table assigning users to roles with scope context + +| Column Name | Data Type | Constraints | Description | +| ------------------- | --------- | --------------------------- | ---------------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier | +| user_id | INT | NOT NULL, FK | Reference to users table | +| role_id | INT | NOT NULL, FK | Reference to roles table | +| organization_id | INT | NULL, FK | Organization scope (if applicable) | +| project_id | INT | NULL, FK | Project scope (if applicable) | +| contract_id | INT | NULL, FK | Contract scope (if applicable) | +| assigned_by_user_id | INT | NULL, FK | User who made the assignment | +| assigned_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Assignment timestamp | + +**Indexes**: + +- PRIMARY KEY (id) +- FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE +- FOREIGN KEY (role_id) REFERENCES roles(role_id) ON DELETE CASCADE +- FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE +- FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE +- FOREIGN KEY (contract_id) REFERENCES contracts(id) ON DELETE CASCADE +- FOREIGN KEY (assigned_by_user_id) REFERENCES users(user_id) +- INDEX (user_id, role_id) +- INDEX (organization_id) +- INDEX (project_id) +- INDEX (contract_id) + +**Constraints**: + +- CHECK: Only one scope field (organization_id, project_id, contract_id) can be NOT NULL, or all NULL for Global scope + +**Relationships**: + +- Parent: users, roles, organizations, projects, contracts + +**Business Rules**: + +- User can have multiple role assignments with different scopes +- Scope inheritance: Contract → Project → Organization → Global +- Global scope: all scope fields are NULL + +--- + +### 2.6 project_organizations + +**Purpose**: Junction table linking projects to participating organizations (M:N) + +| Column Name | Data Type | Constraints | Description | +| --------------- | --------- | --------------- | -------------------------------- | +| project_id | INT | PRIMARY KEY, FK | Reference to projects table | +| organization_id | INT | PRIMARY KEY, FK | Reference to organizations table | + +**Indexes**: + +- PRIMARY KEY (project_id, organization_id) +- FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE +- FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE +- INDEX (organization_id) + +**Relationships**: + +- Parent: projects, organizations + +**Seed Data**: Pre-populated with project-organization relationships + +--- + +### 2.7 contract_organizations + +**Purpose**: Junction table linking contracts to participating organizations with roles (M:N) + +| Column Name | Data Type | Constraints | Description | +| ---------------- | ------------ | --------------- | ------------------------------------------------------------------------- | +| contract_id | INT | PRIMARY KEY, FK | Reference to contracts table | +| organization_id | INT | PRIMARY KEY, FK | Reference to organizations table | +| role_in_contract | VARCHAR(100) | NULL | Organization's role in contract (Owner, Designer, Consultant, Contractor) | + +**Indexes**: + +- PRIMARY KEY (contract_id, organization_id) +- FOREIGN KEY (contract_id) REFERENCES contracts(id) ON DELETE CASCADE +- FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE +- INDEX (organization_id) +- INDEX (role_in_contract) + +**Relationships**: + +- Parent: contracts, organizations + +**Seed Data**: Pre-populated with contract-organization-role relationships + +--- + +## **3. ✉️ Correspondences Tables (เอกสารหลัก, Revisions, Workflows)** + +### 3.1 correspondence_types + +**Purpose**: Master table for correspondence document types + +| Column Name | Data Type | Constraints | Description | +| ----------- | ------------ | --------------------------- | --------------------------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier | +| type_code | VARCHAR(50) | NOT NULL, UNIQUE | Type code (e.g., 'RFA', 'RFI', 'TRANSMITTAL') | +| type_name | VARCHAR(255) | NOT NULL | Full type name | +| sort_order | INT | DEFAULT 0 | Display order | +| is_active | TINYINT(1) | DEFAULT 1 | Active status | + +**Indexes**: + +- PRIMARY KEY (id) +- UNIQUE (type_code) +- INDEX (is_active) +- INDEX (sort_order) + +**Relationships**: + +- Referenced by: correspondences, document_number_formats, document_number_counters + +**Seed Data**: 10 correspondence types including RFA, RFI, TRANSMITTAL, EMAIL, INSTRUCTION, LETTER, MEMO, MOM, NOTICE, OTHER + +--- + +### 3.2 correspondence_status + +**Purpose**: Master table for correspondence status codes + +| Column Name | Data Type | Constraints | Description | +| ----------- | ------------ | --------------------------- | ------------------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier | +| status_code | VARCHAR(50) | NOT NULL, UNIQUE | Status code (e.g., 'DRAFT', 'SUBOWN') | +| status_name | VARCHAR(255) | NOT NULL | Full status name | +| sort_order | INT | DEFAULT 0 | Display order | +| is_active | TINYINT(1) | DEFAULT 1 | Active status | + +**Indexes**: + +- PRIMARY KEY (id) +- UNIQUE (status_code) +- INDEX (is_active) +- INDEX (sort_order) + +**Relationships**: + +- Referenced by: correspondence_revisions + +**Seed Data**: 23 status codes covering draft, submission, reply, resubmission, closure, and cancellation states by different parties (Owner, Designer, CSC, Contractor) + +--- + +### 3.3 correspondences + +**Purpose**: Master table for correspondence documents (non-revisioned data) + +| Column Name | Data Type | Constraints | Description | +| ------------------------- | ------------ | --------------------------- | ------------------------------------------ | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Master correspondence ID | +| correspondence_number | VARCHAR(100) | NOT NULL | Document number (from numbering system) | +| correspondence_type_id | INT | NOT NULL, FK | Reference to correspondence_types | +| is_internal_communication | TINYINT(1) | DEFAULT 0 | Internal (1) or external (0) communication | +| project_id | INT | NOT NULL, FK | Reference to projects table | +| originator_id | INT | NULL, FK | Originating organization | +| created_at | DATETIME | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | +| created_by | INT | NULL, FK | User who created the record | +| deleted_at | DATETIME | NULL | Soft delete timestamp | + +**Indexes**: + +- PRIMARY KEY (id) +- FOREIGN KEY (correspondence_type_id) REFERENCES correspondence_types(id) ON DELETE RESTRICT +- FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE +- FOREIGN KEY (originator_id) REFERENCES organizations(id) ON DELETE SET NULL +- FOREIGN KEY (created_by) REFERENCES users(user_id) ON DELETE SET NULL +- UNIQUE KEY (project_id, correspondence_number) +- INDEX (correspondence_type_id) +- INDEX (originator_id) +- INDEX (deleted_at) + +**Relationships**: + +- Parent: correspondence_types, projects, organizations, users +- Children: correspondence_revisions, correspondence_recipients, correspondence_tags, correspondence_references, correspondence_attachments, circulations, transmittals + +**Business Rules**: + +- One correspondence can have multiple revisions +- Correspondence number must be unique within a project +- Soft delete preserves history + +--- + +### 3.4 correspondence_revisions + +**Purpose**: Child table storing revision history of correspondences (1:N) + +| Column Name | Data Type | Constraints | Description | +| ------------------------ | ------------ | --------------------------- | ------------------------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique revision ID | +| correspondence_id | INT | NOT NULL, FK | Master correspondence ID | +| revision_number | INT | NOT NULL | Revision sequence (0, 1, 2...) | +| revision_label | VARCHAR(10) | NULL | Display revision (A, B, 1.1...) | +| is_current | BOOLEAN | DEFAULT FALSE | Current revision flag | +| correspondence_status_id | INT | NOT NULL, FK | Current status of this revision | +| title | VARCHAR(255) | NOT NULL | Document title | +| document_date | DATE | NULL | Document date | +| issued_date | DATETIME | NULL | Issue date | +| received_date | DATETIME | NULL | Received date | +| due_date | DATETIME | NULL | Due date for response | +| description | TEXT | NULL | Revision description | +| details | JSON | NULL | Type-specific details (e.g., RFI questions) | +| created_at | DATETIME | DEFAULT CURRENT_TIMESTAMP | Revision creation timestamp | +| created_by | INT | NULL, FK | User who created revision | +| updated_by | INT | NULL, FK | User who last updated | + +**Indexes**: + +- PRIMARY KEY (id) +- FOREIGN KEY (correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE +- FOREIGN KEY (correspondence_status_id) REFERENCES correspondence_status(id) ON DELETE RESTRICT +- FOREIGN KEY (created_by) REFERENCES users(user_id) ON DELETE SET NULL +- FOREIGN KEY (updated_by) REFERENCES users(user_id) ON DELETE SET NULL +- UNIQUE KEY (correspondence_id, revision_number) +- UNIQUE KEY (correspondence_id, is_current) - Only one current revision per correspondence +- INDEX (correspondence_status_id) +- INDEX (is_current) +- INDEX (document_date) +- INDEX (issued_date) + +**Relationships**: + +- Parent: correspondences, correspondence_status, users + +**Business Rules**: + +- Only one revision can be marked as current (is_current=TRUE) per correspondence +- Revision numbers are sequential starting from 0 +- JSON details field allows type-specific data storage + +--- + +### 3.5 correspondence_recipients + +**Purpose**: Junction table for correspondence recipients (TO/CC) (M:N) + +| Column Name | Data Type | Constraints | Description | +| ------------------------- | ---------------- | --------------- | ---------------------------- | +| correspondence_id | INT | PRIMARY KEY, FK | Reference to correspondences | +| recipient_organization_id | INT | PRIMARY KEY, FK | Recipient organization | +| recipient_type | ENUM('TO', 'CC') | PRIMARY KEY | Recipient type | + +**Indexes**: + +- PRIMARY KEY (correspondence_id, recipient_organization_id, recipient_type) +- FOREIGN KEY (correspondence_id) REFERENCES correspondence_revisions(correspondence_id) ON DELETE CASCADE +- FOREIGN KEY (recipient_organization_id) REFERENCES organizations(id) ON DELETE RESTRICT +- INDEX (recipient_organization_id) +- INDEX (recipient_type) + +**Relationships**: + +- Parent: correspondences, organizations + +**Business Rules**: + +- One organization can be both TO and CC recipient +- Cascade delete when correspondence is deleted + +--- + +### 3.6 tags + +**Purpose**: Master table for document tagging system + +| Column Name | Data Type | Constraints | Description | +| ----------- | ------------ | ----------------------------------- | ------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique tag ID | +| tag_name | VARCHAR(100) | NOT NULL, UNIQUE | Tag name | +| description | TEXT | NULL | Tag description | +| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | +| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | + +**Indexes**: + +- PRIMARY KEY (id) +- UNIQUE (tag_name) +- INDEX (tag_name) - For autocomplete + +**Relationships**: + +- Referenced by: correspondence_tags + +--- + +### 3.7 correspondence_tags + +**Purpose**: Junction table linking correspondences to tags (M:N) + +| Column Name | Data Type | Constraints | Description | +| ----------------- | --------- | --------------- | ---------------------------- | +| correspondence_id | INT | PRIMARY KEY, FK | Reference to correspondences | +| tag_id | INT | PRIMARY KEY, FK | Reference to tags | + +**Indexes**: + +- PRIMARY KEY (correspondence_id, tag_id) +- FOREIGN KEY (correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE +- FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE +- INDEX (tag_id) + +**Relationships**: + +- Parent: correspondences, tags + +--- + +### 3.8 correspondence_references + +**Purpose**: Junction table for cross-referencing correspondences (M:N) + +| Column Name | Data Type | Constraints | Description | +| --------------------- | --------- | --------------- | ------------------------------------- | +| src_correspondence_id | INT | PRIMARY KEY, FK | Source correspondence ID | +| tgt_correspondence_id | INT | PRIMARY KEY, FK | Target (referenced) correspondence ID | + +**Indexes**: + +- PRIMARY KEY (src_correspondence_id, tgt_correspondence_id) +- FOREIGN KEY (src_correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE +- FOREIGN KEY (tgt_correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE +- INDEX (tgt_correspondence_id) + +**Relationships**: + +- Parent: correspondences (both sides) + +**Business Rules**: + +- Allows tracing document relationships +- Bi-directional references should be created as separate records + +### 3.9 ตาราง correspondence_routing_templates + +**Purpose**: เก็บข้อมูลแม่แบบ (Template) ของสายงานการส่งต่อเอกสารเพื่อขออนุมัติ ทำให้ไม่ต้องกำหนดขั้นตอนซ้ำทุกครั้ง สามารถสร้างเป็นแม่แบบทั่วไป หรือเฉพาะสำหรับโครงการใดโครงการหนึ่งได้ + +| Column Name | Data Type | Constraints | Description | +| ------------- | ------------ | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | ID หลัก (Primary Key) ของแม่แบบ รันค่าอัตโนมัติ | +| template_name | VARCHAR(255) | NOT NULL | ชื่อของแม่แบบ เช่น "เสนอโครงการ", "ขออนุมัติจัดซื้อ" | +| description | TEXT | NULL | คำอธิบายรายละเอียดเกี่ยวกับแม่แบบนี้ | +| project_id | INT | NULL | ID ของโครงการที่แม่แบบนี้สังกัดอยู่ (ถ้ามี) **ค่า NULL หมายถึง** เป็น "แม่แบบทั่วไป" ที่สามารถใช้กับทุกโครงการได้ | +| created_at | TIMESTAMP | NOT NULL, DEFAULT CURRENT_TIMESTAMP | วันที่และเวลาที่สร้างแม่แบบนี้ | +| updated_at | TIMESTAMP | NOT NULL,`DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP | วันที่และเวลาที่แก้ไขข้อมูลในแม่แบบนี้ล่าสุด | +| is_active | BOOLEAN | DEFAULT TRUE | สถานะใช้งาน | + +**Indexes**: + +- ux_routing_template_name_project (template_name, project_id): ดัชนีแบบ UNIQUE ป้องกันการมีชื่อแม่แบบซ้ำกันในแต่ละโครงการ หรือในส่วนของแม่แบบทั่วไป (ที่ project_id เป็น NULL) + +**ความสัมพันธ์ Foreign Key:** + +- fk_crt_project: อ้างอิงไปยัง projects(id) +- ON DELETE CASCAD`: ถ้าโครงการ (projects) ถูกลบ แม่แบบที่เกี่ยวข้องกับโครงการนั้นๆ จะถูกลบไปด้วยทั้งหมด + +--- + +### 3.10 ตาราง correspondence_routing_template_steps + +**Purpose**: เก็บรายละเอียดของแต่ละขั้นตอน (Steps) ภายในแม่แบบสายงาน (correspondence_routing_templates) กำหนดว่าจะส่งไปที่องค์กรไหน ลำดับเป็นเท่าไร และเพื่อวัตถุประสงค์อะไร + +| Column Name | Data Type | Constraints | Description | +| :----------------- | --------- | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | ID หลักของขั้นตอน | +| template_id | INT | NOT NULL | ID ของแม่แบบที่ขั้นตอนนี้สังกัดอยู่ | +| sequence | INT | NOT NULL | ลำดับของขั้นตอน (1, 2, 3, ...) | +| to_organization_id | INT | NOT NULL | ID ขององค์กรที่เป็นผู้รับในขั้นตอนนี้ | +| step_purpose | ENUM | NOT NULL,DEFAULT FOR_REVIEW | วัตถุประสงค์ของการส่งต่อในขั้นตอนนี้ **ค่าที่เป็นไปได้:** [FOR_APPROVAL: เพื่ออนุมัติ, FOR_REVIEW: เพื่อตรวจสอบ/พิจารณา, FOR_INFORMATION: เพื่อทราบ] | +| expected_days | INT | NULL | วันที่คาดหวัง | + +**Indexes**: + +- ux_cor_template_sequence (template_id, sequence): ดัชนีแบบ UNIQUE ป้องกันการมีลำดับขั้นตอนซ้ำกันภายในแม่แบบเดียวกัน + +**ความสัมพันธ์ Foreign Key:** + +- fk_cwts_template: อ้างอิงไปยัง correspondence_routing_templates(id) +- ON DELETE CASCADE: ถ้าแม่แบบถูกลบ ขั้นตอนทั้งหมดภายในแม่แบบนั้นจะถูกลบไปด้วย +- fk_cwts_org: อ้างอิงไปยัง organizations(id) +- ON DELETE CASCADE: ถ้าองค์กรถูกลบ ขั้นตอนที่ชี้ไปยังองค์กรนั้นจะถูกลบ + +--- + +### 3.11 ตาราง correspondence_routings + +**Purpose**: เป็นตารางที่เก็บข้อมูลการส่งต่อเอกสารจริง (Instance/Run-time) ติดตามประวัติการเคลื่อนย้ายของแต่ละเอกสาร ว่าผ่านใครมาบ้าง อยู่ที่ใคร และสถานะปัจจุบันคืออะไร + +| Column Name | Data Type | Constraints | Description | +| -------------------- | --------- | ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | ID หลักของรายการส่งต่อ | +| correspondence_id | INT | NOT NUL | ID ของเอกสาร (FK ไปยัง correspondence_revisions) | +| template_id | INT | NULL | ID ของแม่แบบที่ใช้สร้างสายงานนี้ (เก็บไว้เป็นข้อมูลอ้างอิง) | +| sequence | INT | NOT NULL | ลำดับของขั้นตอนการส่งต่อจริง | +| from_organization_id | INT | NOT NULL | ID ขององค์กรผู้ส่ง | +| to_organization_id | INT | NOT NULL | ID ขององค์กรผู้รับ | +| step_purpose | ENUM | NOT NULL, DEFAULT FOR_REVIEW | วัตถุประสงค์ของการส่งต่อในขั้นตอนนี้จริง **ค่าที่เป็นไปได้:** [FOR_APPROVAL: เพื่ออนุมัติ, FOR_REVIEW: เพื่อตรวจสอบ/พิจารณา, FOR_INFORMATION: เพื่อทราบ, FOR_ACTION: เพื่อดำเนินการ] | +| status | ENUM | NOT NULL, DEFAULT SENT | [ACTIONED: ดำเนินการแล้ว, FORWARDED: ส่งต่อแล้ว, REPLIE: ตอบกลับแล้ว] | +| comments | TEXT | NULL | หมายเหตุหรือความคิดเห็นในการส่งต่อ | +| due_date | DATETIME | NULL | วันที่ครบกำหนดที่ต้องดำเนินการในขั้นตอนนี้ | +| processed_by_user_id | INT | NULL | ID ของผู้ใช้ที่ดำเนินการในขั้นตอนนี้จริงๆ | +| processed_at | TIMESTAMP | NULL | เวลาที่ผู้ใช้ดำเนินการเสร็จสิ้น | +| created_at | TIMESTAMP | NOT NULL, DEFAULT CURRENT_TIMESTAMP | เวลาที่สร้างรายการส่งต่อนี้ | + +**Indexes**: + +- ux_cor_routing_sequence (correspondence_id, sequence): ดัชนีแบบ UNIQUE ทำให้มั่นใจได้ว่าแต่ละเอกสารจะมีขั้นตอนการส่งต่อตามลำดับได้เพียงชุดเดียว + +**ความสัมพันธ์ Foreign Key:** + +- fk_crs_correspondence: อ้างอิงไปยัง correspondence_revisions(correspondence_id) +- ON DELETE CASCADE`: ถ้าเอกสาร (revision) ถูกลบ ประวัติการส่งต่อทั้งหมดจะถูกลบไปด้วย +- fk_crs_template: อ้างอิงไปยัง correspondence_routing_templates(id) +- ON DELETE SET NULL: ถ้าแม่แบบถูกลบ ค่า template_id ในตารางนี้จะถูกเปลี่ยนเป็น NULL เพื่อรักษาประวัติการส่งต่อไว้ +- fk_crs_from_org: อ้างอิงไปยัง organizations(id) +- ON DELETE CASCADE: ถ้าองค์กรผู้ส่งถูกลบ รายการส่งต่อนี้จะถูกลบ +- fk_crs_to_org: อ้างอิงไปยัง organizations(id) +- ON DELETE CASCADE: ถ้าองค์กรผู้รับถูกลบ รายการส่งต่อนี้จะถูกลบ +- fk_crs_processed_by_user: อ้างอิงไปยัง users(user_id) +- ON DELETE SET NULL: ถ้าผู้ใช้ถูกลบ ค่า processed_by_user_id จะถูกเปลี่ยนเป็น NULL เพื่อรักษาประวัติการดำเนินการไว้ + +--- + +### 3.12 ตาราง correspondence_status_transitions + +**Purpose**: ตารางนี้ใช้กำหนดกฎ (State Machine) ว่าสถานะใดสามารถเปลี่ยนไปเป็นสถานะใดได้บ้าง โดยขึ้นอยู่กับประเภทของหนังสือ เพื่อควบคุมการไหลของสถานะให้ถูกต้องตามข้อบังคับ + +| Column Name | Data Type | Constraints | Description | +| -------------- | --------- | ----------- | ----------------------------------------------- | +| type_id | INT | PRIMARY KEY | ID ของประเภทหนังสือ (เช่น หนังสือภายใน, หนังสือภายนอก) | +| from_status_id | INT | PRIMARY KEY | ID ของสถานะต้นทาง (เช่น ร่าง) | +| to_status_id | INT | PRIMARY KEY | ID ของสถานะปลายทาง (เช่น รออนุมัติ) | + +**คีย์หลัก (Primary Key):** + +- (type_id, from_status_id, to_status_id)`: คีย์หลักแบบประกอบ ทำให้แน่ใจว่าแต่ละประเภทหนังสือ การเปลี่ยนจากสถานะหนึ่งไปอีกสถานะหนึ่งจะซ้ำกันไม่ได้ + +**ความสัมพันธ์ Foreign Key:** + +- fk_cst_type : อ้างอิงไปยัง correspondence_types(id) +- fk_cst_from : อ้างอิงไปยัง correspondence_status(id) +- fk_cst_to : อ้างอิงไปยัง correspondence_status(id) +- ไม่มีการกำหนด ON DELETE จึงเป็นค่าเริ่มต้น RESTRICT หมายความว่า จะลบประเภทหนังสือหรือสถานะไม่ได้ ถ้ายังมีการใช้งานอยู่ในตารางนี้ + +--- + +## **4. 📐 approval: RFA Tables (เอกสารขออนุมัติ, Workflows)** + +### 4.1 rfa_types + +**Purpose**: Master table for RFA (Request for Approval) types + +| Column Name | Data Type | Constraints | Description | +| ----------- | ------------ | --------------------------- | ------------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier | +| type_code | VARCHAR(20) | NOT NULL, UNIQUE | Type code (DWG, DOC, MAT, etc.) | +| type_name | VARCHAR(100) | NOT NULL | Full type name | +| description | TEXT | NULL | Type description | +| sort_order | INT | DEFAULT 0 | Display order | +| is_active | TINYINT(1) | DEFAULT 1 | Active status | + +**Indexes**: + +- PRIMARY KEY (id) +- UNIQUE (type_code) +- INDEX (is_active) +- INDEX (sort_order) + +**Relationships**: + +- Referenced by: rfas + +**Seed Data**: 11 RFA types including Shop Drawing (DWG), Document (DOC), Specification (SPC), Calculation (CAL), Test Report (TRP), Survey Report (SRY), QA/QC Document, Method Statement (MES), Material (MAT), As-Built (ASB), Other (OTH) + +--- + +### 4.2 rfa_status_codes + +**Purpose**: Master table for RFA status codes + +| Column Name | Data Type | Constraints | Description | +| ----------- | ------------ | --------------------------- | --------------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier | +| status_code | VARCHAR(20) | NOT NULL, UNIQUE | Status code (DFT, FAP, FRE, etc.) | +| status_name | VARCHAR(100) | NOT NULL | Full status name | +| description | TEXT | NULL | Status description | +| sort_order | INT | DEFAULT 0 | Display order | +| is_active | TINYINT(1) | DEFAULT 1 | Active status | + +**Indexes**: + +- PRIMARY KEY (id) +- UNIQUE (status_code) +- INDEX (is_active) +- INDEX (sort_order) + +**Relationships**: + +- Referenced by: rfa_revisions + +**Seed Data**: 7 status codes + +- DFT: Draft +- FAP: For Approve +- FRE: For Review +- FCO: For Construction +- ASB: AS-Built +- OBS: Obsolete +- CC: Canceled + +--- + +### 4.3 rfa_approve_codes + +**Purpose**: Master table for RFA approval result codes + +| Column Name | Data Type | Constraints | Description | +| ------------ | ------------ | --------------------------- | -------------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier | +| approve_code | VARCHAR(20) | NOT NULL, UNIQUE | Approval code (1A, 1C, 3R, etc.) | +| approve_name | VARCHAR(100) | NOT NULL | Full approval name | +| description | TEXT | NULL | Code description | +| sort_order | INT | DEFAULT 0 | Display order | +| is_active | TINYINT(1) | DEFAULT 1 | Active status | + +**Indexes**: + +- PRIMARY KEY (id) +- UNIQUE (approve_code) +- INDEX (is_active) +- INDEX (sort_order) + +**Relationships**: + +- Referenced by: rfa_revisions + +**Seed Data**: 8 approval codes + +- 1A: Approved by Authority +- 1C: Approved by CSC +- 1N: Approved As Note +- 1R: Approved with Remarks +- 3C: Consultant Comments +- 3R: Revise and Resubmit +- 4X: Reject +- 5N: No Further Action + +--- + +### 4.4 rfas + +**Purpose**: Master table for RFA documents (non-revisioned data) + +| Column Name | Data Type | Constraints | Description | +| ----------- | --------- | --------------------------- | --------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Master RFA ID | +| rfa_type_id | INT | NOT NULL, FK | Reference to rfa_types | +| created_at | DATETIME | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | +| created_by | INT | NULL, FK | User who created the record | +| deleted_at | DATETIME | NULL | Soft delete timestamp | + +**Indexes**: + +- PRIMARY KEY (id) +- FOREIGN KEY (rfa_type_id) REFERENCES rfa_types(id) +- FOREIGN KEY (created_by) REFERENCES users(user_id) ON DELETE SET NULL +- INDEX (rfa_type_id) +- INDEX (deleted_at) + +**Relationships**: + +- Parent: rfa_types, users +- Children: rfa_revisions + +**Business Rules**: + +- One RFA can have multiple revisions +- Soft delete preserves history + +--- + +### 4.5 rfa_revisions + +**Purpose**: Child table storing revision history of RFAs (1:N) + +| Column Name | Data Type | Constraints | Description | +| ------------------- | ------------ | --------------------------- | ---------------------------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique revision ID | +| correspondence_id | INT | NOT NULL, FK | Link to correspondence (RFA as correspondence) | +| rfa_id | INT | NOT NULL, FK | Master RFA ID | +| revision_number | INT | NOT NULL | Revision sequence (0, 1, 2...) | +| revision_label | VARCHAR(10) | NULL | Display revision (A, B, 1.1...) | +| is_current | BOOLEAN | DEFAULT FALSE | Current revision flag | +| rfa_status_code_id | INT | NOT NULL, FK | Current RFA status | +| rfa_approve_code_id | INT | NULL, FK | Approval result code | +| title | VARCHAR(255) | NOT NULL | RFA title | +| document_date | DATE | NULL | Document date | +| issued_date | DATE | NULL | Issue date for approval | +| received_date | DATETIME | NULL | Received date | +| approved_date | DATE | NULL | Approval date | +| description | TEXT | NULL | Revision description | +| created_at | DATETIME | DEFAULT CURRENT_TIMESTAMP | Revision creation timestamp | +| created_by | INT | NULL, FK | User who created revision | +| updated_by | INT | NULL, FK | User who last updated | + +**Indexes**: + +- PRIMARY KEY (id) +- FOREIGN KEY (correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE +- FOREIGN KEY (rfa_id) REFERENCES rfas(id) ON DELETE CASCADE +- FOREIGN KEY (rfa_status_code_id) REFERENCES rfa_status_codes(id) +- FOREIGN KEY (rfa_approve_code_id) REFERENCES rfa_approve_codes(id) ON DELETE SET NULL +- FOREIGN KEY (created_by) REFERENCES users(user_id) ON DELETE SET NULL +- FOREIGN KEY (updated_by) REFERENCES users(user_id) ON DELETE SET NULL +- UNIQUE KEY (rfa_id, revision_number) +- UNIQUE KEY (rfa_id, is_current) +- INDEX (rfa_status_code_id) +- INDEX (rfa_approve_code_id) +- INDEX (is_current) + +**Relationships**: + +- Parent: correspondences, rfas, rfa_status_codes, rfa_approve_codes, users +- Children: rfa_items, rfa_workflows + +**Business Rules**: + +- RFA is a specialized type of correspondence +- Only one revision can be current per RFA +- Links to shop drawings through rfa_items + +--- + +### 4.6 rfa_items + +**Purpose**: Junction table linking RFA revisions to shop drawing revisions (M:N) + +| Column Name | Data Type | Constraints | Description | +| ------------------------ | --------- | --------------- | ------------------------------ | +| rfarev_correspondence_id | INT | PRIMARY KEY, FK | RFA revision correspondence ID | +| shop_drawing_revision_id | INT | PRIMARY KEY, FK | Shop drawing revision ID | + +**Indexes**: + +- PRIMARY KEY (rfarev_correspondence_id, shop_drawing_revision_id) +- FOREIGN KEY (rfarev_correspondence_id) REFERENCES rfa_revisions(correspondence_id) ON DELETE CASCADE +- FOREIGN KEY (shop_drawing_revision_id) REFERENCES shop_drawing_revisions(id) ON DELETE CASCADE +- INDEX (shop_drawing_revision_id) + +**Relationships**: + +- Parent: rfa_revisions, shop_drawing_revisions + +**Business Rules**: + +- Used primarily for RFA type = 'DWG' (Shop Drawing) +- One RFA can contain multiple shop drawings +- One shop drawing can be referenced by multiple RFAs + +--- + +### 4.7 rfa_workflow_templates + +**Purpose**: Master table for RFA approval workflow templates + +| Column Name | Data Type | Constraints | Description | +| ------------- | ------------ | ----------------------------------- | ------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique template ID | +| template_name | VARCHAR(100) | NOT NULL | Template name | +| description | TEXT | NULL | Template description | +| is_active | TINYINT(1) | DEFAULT 1 | Active status | +| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | +| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | + +**Indexes**: + +- PRIMARY KEY (id) +- INDEX (is_active) +- INDEX (template_name) + +**Relationships**: + +- Children: rfa_workflow_template_steps + +**Business Rules**: + +- Defines reusable approval workflows for RFAs +- Can be assigned to specific RFA types or organizations + +--- + +### 4.8 rfa_workflow_template_steps + +**Purpose**: Child table defining steps in workflow templates + +| Column Name | Data Type | Constraints | Description | +| --------------- | --------- | --------------------------- | ----------------------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique step ID | +| template_id | INT | NOT NULL, FK | Reference to workflow template | +| step_number | INT | NOT NULL | Step sequence order | +| organization_id | INT | NOT NULL, FK | Organization responsible for step | +| role_id | INT | NULL, FK | Required role for this step | +| action_type | ENUM | NULL | Action type: REVIEW, APPROVE, ACKNOWLEDGE | +| duration_days | INT | NULL | Expected duration in days | +| is_optional | BOOLEAN | DEFAULT FALSE | Optional step flag | + +**Indexes**: + +- PRIMARY KEY (id) +- FOREIGN KEY (template_id) REFERENCES rfa_workflow_templates(id) ON DELETE CASCADE +- FOREIGN KEY (organization_id) REFERENCES organizations(id) +- FOREIGN KEY (role_id) REFERENCES roles(role_id) +- INDEX (template_id, step_number) +- INDEX (organization_id) + +**Relationships**: + +- Parent: rfa_workflow_templates, organizations, roles + +**Business Rules**: + +- Steps are executed in step_number order +- Optional steps can be skipped +- Duration used for deadline calculation + +--- + +### 4.9 rfa_workflows + +**Purpose**: Transaction log table tracking actual RFA approval workflow execution + +| Column Name | Data Type | Constraints | Description | +| --------------- | --------- | ----------------------------------- | ------------------------------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique workflow log ID | +| rfa_revision_id | INT | NOT NULL, FK | Reference to RFA revision | +| step_number | INT | NOT NULL | Current step number | +| organization_id | INT | NOT NULL, FK | Organization responsible | +| assigned_to | INT | NULL, FK | Assigned user ID | +| action_type | ENUM | NULL | Action type: REVIEW, APPROVE, ACKNOWLEDGE | +| status | ENUM | NULL | Status: PENDING, IN_PROGRESS, COMPLETED, REJECTED | +| comments | TEXT | NULL | Comments/remarks | +| completed_at | DATETIME | NULL | Completion timestamp | +| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | +| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | + +**Indexes**: + +- PRIMARY KEY (id) +- FOREIGN KEY (rfa_revision_id) REFERENCES rfa_revisions(id) ON DELETE CASCADE +- FOREIGN KEY (organization_id) REFERENCES organizations(id) +- FOREIGN KEY (assigned_to) REFERENCES users(user_id) +- INDEX (rfa_revision_id, step_number) +- INDEX (assigned_to, status) +- INDEX (status) + +**Relationships**: + +- Parent: rfa_revisions, organizations, users + +**Business Rules**: + +- Records actual workflow execution history +- Tracks who did what and when +- Multiple records per RFA revision (one per step) +- Status changes tracked via updated_at + +--- + +## **5. 📐 Drawings Tables (แบบ, หมวดหมู่)** + +### 5.1 contract_drawing_volumes + +**Purpose**: Master table for contract drawing volume classification + +| Column Name | Data Type | Constraints | Description | +| ----------- | ------------ | ----------------------------------- | ------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique volume ID | +| project_id | INT | NOT NULL, FK | Reference to projects | +| volume_code | VARCHAR(50) | NOT NULL | Volume code | +| volume_name | VARCHAR(255) | NOT NULL | Volume name | +| description | TEXT | NULL | Volume description | +| sort_order | INT | DEFAULT 0 | Display order | +| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | +| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | + +**Indexes**: + +- PRIMARY KEY (id) +- FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE +- UNIQUE KEY (project_id, volume_code) +- INDEX (sort_order) + +**Relationships**: + +- Parent: projects +- Referenced by: contract_drawings + +**Business Rules**: + +- Volume codes must be unique within a project +- Used for organizing large sets of contract drawings + +--- + +### 5.2 contract_drawing_cats + +**Purpose**: Master table for contract drawing main categories + +| Column Name | Data Type | Constraints | Description | +| ----------- | ------------ | ----------------------------------- | ------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique category ID | +| project_id | INT | NOT NULL, FK | Reference to projects | +| cat_code | VARCHAR(50) | NOT NULL | Category code | +| cat_name | VARCHAR(255) | NOT NULL | Category name | +| description | TEXT | NULL | Category description | +| sort_order | INT | DEFAULT 0 | Display order | +| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | +| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | + +**Indexes**: + +- PRIMARY KEY (id) +- FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE +- UNIQUE KEY (project_id, cat_code) +- INDEX (sort_order) + +**Relationships**: + +- Parent: projects +- Referenced by: contract_drawing_subcat_cat_maps + +**Business Rules**: + +- Category codes must be unique within a project +- Hierarchical relationship with sub-categories via mapping table + +--- + +### 5.3 contract_drawing_sub_cats + +**Purpose**: Master table for contract drawing sub-categories + +| Column Name | Data Type | Constraints | Description | +| ------------ | ------------ | ----------------------------------- | ------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique sub-category ID | +| project_id | INT | NOT NULL, FK | Reference to projects | +| sub_cat_code | VARCHAR(50) | NOT NULL | Sub-category code | +| sub_cat_name | VARCHAR(255) | NOT NULL | Sub-category name | +| description | TEXT | NULL | Sub-category description | +| sort_order | INT | DEFAULT 0 | Display order | +| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | +| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | + +**Indexes**: + +- PRIMARY KEY (id) +- FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE +- UNIQUE KEY (project_id, sub_cat_code) +- INDEX (sort_order) + +**Relationships**: + +- Parent: projects +- Referenced by: contract_drawings, contract_drawing_subcat_cat_maps + +**Business Rules**: + +- Sub-category codes must be unique within a project +- Can be mapped to multiple main categories via mapping table + +--- + +### 5.4 contract_drawing_subcat_cat_maps + +**Purpose**: Junction table mapping sub-categories to main categories (M:N) + +| Column Name | Data Type | Constraints | Description | +| ----------- | --------- | --------------- | -------------------------- | +| project_id | INT | PRIMARY KEY, FK | Reference to projects | +| sub_cat_id | INT | PRIMARY KEY, FK | Reference to sub-category | +| cat_id | INT | PRIMARY KEY, FK | Reference to main category | + +**Indexes**: + +- PRIMARY KEY (project_id, sub_cat_id, cat_id) +- FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE +- FOREIGN KEY (sub_cat_id) REFERENCES contract_drawing_sub_cats(id) ON DELETE CASCADE +- FOREIGN KEY (cat_id) REFERENCES contract_drawing_cats(id) ON DELETE CASCADE +- INDEX (sub_cat_id) +- INDEX (cat_id) + +**Relationships**: + +- Parent: projects, contract_drawing_sub_cats, contract_drawing_cats + +**Business Rules**: + +- Allows flexible categorization +- One sub-category can belong to multiple main categories +- All three fields required for uniqueness + +--- + +### 5.5 contract_drawings + +**Purpose**: Master table for contract drawings (from contract specifications) + +| Column Name | Data Type | Constraints | Description | +| ----------- | ------------ | ----------------------------------- | ------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique drawing ID | +| project_id | INT | NOT NULL, FK | Reference to projects | +| condwg_no | VARCHAR(255) | NOT NULL | Contract drawing number | +| title | VARCHAR(255) | NOT NULL | Drawing title | +| sub_cat_id | INT | NULL, FK | Reference to sub-category | +| volume_id | INT | NULL, FK | Reference to volume | +| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | +| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | +| deleted_at | DATETIME | NULL | Soft delete timestamp | +| updated_by | INT | NULL, FK | User who last updated | + +**Indexes**: + +- PRIMARY KEY (id) +- FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE +- FOREIGN KEY (sub_cat_id) REFERENCES contract_drawing_sub_cats(id) ON DELETE RESTRICT +- FOREIGN KEY (volume_id) REFERENCES contract_drawing_volumes(id) ON DELETE RESTRICT +- FOREIGN KEY (updated_by) REFERENCES users(user_id) +- UNIQUE KEY (project_id, condwg_no) +- INDEX (sub_cat_id) +- INDEX (volume_id) +- INDEX (deleted_at) + +**Relationships**: + +- Parent: projects, contract_drawing_sub_cats, contract_drawing_volumes, users +- Referenced by: shop_drawing_revision_contract_refs, contract_drawing_attachments + +**Business Rules**: + +- Drawing numbers must be unique within a project +- Represents baseline/contract drawings +- Referenced by shop drawings for compliance tracking +- Soft delete preserves history + +--- + +### 5.6 shop_drawing_main_categories + +**Purpose**: Master table for shop drawing main categories (discipline-level) + +| Column Name | Data Type | Constraints | Description | +| ------------------ | ------------ | ----------------------------------- | ------------------------------------ | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique category ID | +| main_category_code | VARCHAR(50) | NOT NULL, UNIQUE | Category code (ARCH, STR, MEP, etc.) | +| main_category_name | VARCHAR(255) | NOT NULL | Category name | +| description | TEXT | NULL | Category description | +| sort_order | INT | DEFAULT 0 | Display order | +| is_active | TINYINT(1) | DEFAULT 1 | Active status | +| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | +| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | + +**Indexes**: + +- PRIMARY KEY (id) +- UNIQUE (main_category_code) +- INDEX (is_active) +- INDEX (sort_order) + +**Relationships**: + +- Referenced by: shop_drawing_sub_categories, shop_drawings + +**Business Rules**: + +- Global categories (not project-specific) +- Typically represents engineering disciplines + +--- + +### 5.7 shop_drawing_sub_categories + +**Purpose**: Master table for shop drawing sub-categories (component-level) + +| Column Name | Data Type | Constraints | Description | +| ----------------- | ------------ | ----------------------------------- | ----------------------------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique sub-category ID | +| sub_category_code | VARCHAR(50) | NOT NULL, UNIQUE | Sub-category code (STR-COLUMN, ARCH-DOOR, etc.) | +| sub_category_name | VARCHAR(255) | NOT NULL | Sub-category name | +| main_category_id | INT | NOT NULL, FK | Reference to main category | +| description | TEXT | NULL | Sub-category description | +| sort_order | INT | DEFAULT 0 | Display order | +| is_active | TINYINT(1) | DEFAULT 1 | Active status | +| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | +| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | + +**Indexes**: + +- PRIMARY KEY (id) +- UNIQUE (sub_category_code) +- FOREIGN KEY (main_category_id) REFERENCES shop_drawing_main_categories(id) +- INDEX (main_category_id) +- INDEX (is_active) +- INDEX (sort_order) + +**Relationships**: + +- Parent: shop_drawing_main_categories +- Referenced by: shop_drawings + +**Business Rules**: + +- Global sub-categories (not project-specific) +- Hierarchical under main categories +- Represents specific drawing types or components + +--- + +### 5.8 shop_drawings + +**Purpose**: Master table for shop drawings (contractor-submitted) + +| Column Name | Data Type | Constraints | Description | +| ---------------- | ------------ | ----------------------------------- | -------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique drawing ID | +| project_id | INT | NOT NULL, FK | Reference to projects | +| drawing_number | VARCHAR(100) | NOT NULL, UNIQUE | Shop drawing number | +| title | VARCHAR(500) | NOT NULL | Drawing title | +| main_category_id | INT | NOT NULL, FK | Reference to main category | +| sub_category_id | INT | NOT NULL, FK | Reference to sub-category | +| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | +| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | +| deleted_at | DATETIME | NULL | Soft delete timestamp | +| updated_by | INT | NULL, FK | User who last updated | + +**Indexes**: + +- PRIMARY KEY (id) +- UNIQUE (drawing_number) +- FOREIGN KEY (project_id) REFERENCES projects(id) +- FOREIGN KEY (main_category_id) REFERENCES shop_drawing_main_categories(id) +- FOREIGN KEY (sub_category_id) REFERENCES shop_drawing_sub_categories(id) +- FOREIGN KEY (updated_by) REFERENCES users(user_id) +- INDEX (project_id) +- INDEX (main_category_id) +- INDEX (sub_category_id) +- INDEX (deleted_at) + +**Relationships**: + +- Parent: projects, shop_drawing_main_categories, shop_drawing_sub_categories, users +- Children: shop_drawing_revisions + +**Business Rules**: + +- Drawing numbers are globally unique across all projects +- Represents contractor shop drawings +- Can have multiple revisions +- Soft delete preserves history + +--- + +### 5.9 shop_drawing_revisions + +**Purpose**: Child table storing revision history of shop drawings (1:N) + +| Column Name | Data Type | Constraints | Description | +| --------------- | ----------- | --------------------------- | ------------------------------ | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique revision ID | +| shop_drawing_id | INT | NOT NULL, FK | Master shop drawing ID | +| revision_number | INT | NOT NULL | Revision sequence (0, 1, 2...) | +| revision_label | VARCHAR(10) | NULL | Display revision (A, B, C...) | +| revision_date | DATE | NULL | Revision date | +| description | TEXT | NULL | Revision description/changes | +| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Revision creation timestamp | + +**Indexes**: + +- PRIMARY KEY (id) +- FOREIGN KEY (shop_drawing_id) REFERENCES shop_drawings(id) ON DELETE CASCADE +- UNIQUE KEY (shop_drawing_id, revision_number) +- INDEX (revision_date) + +**Relationships**: + +- Parent: shop_drawings +- Referenced by: rfa_items, shop_drawing_revision_contract_refs, shop_drawing_revision_attachments + +**Business Rules**: + +- Revision numbers are sequential starting from 0 +- Each revision can reference multiple contract drawings +- Each revision can have multiple file attachments +- Linked to RFAs for approval tracking + +--- + +### 5.10 shop_drawing_revision_contract_refs + +**Purpose**: Junction table linking shop drawing revisions to referenced contract drawings (M:N) + +| Column Name | Data Type | Constraints | Description | +| ------------------------ | --------- | --------------- | ---------------------------------- | +| shop_drawing_revision_id | INT | PRIMARY KEY, FK | Reference to shop drawing revision | +| contract_drawing_id | INT | PRIMARY KEY, FK | Reference to contract drawing | + +**Indexes**: + +- PRIMARY KEY (shop_drawing_revision_id, contract_drawing_id) +- FOREIGN KEY (shop_drawing_revision_id) REFERENCES shop_drawing_revisions(id) ON DELETE CASCADE +- FOREIGN KEY (contract_drawing_id) REFERENCES contract_drawings(id) ON DELETE CASCADE +- INDEX (contract_drawing_id) + +**Relationships**: + +- Parent: shop_drawing_revisions, contract_drawings + +**Business Rules**: + +- Tracks which contract drawings each shop drawing revision is based on +- Ensures compliance with contract specifications +- One shop drawing revision can reference multiple contract drawings + +--- + +## **6. 🔄 Circulations Tables (ใบเวียนภายใน)** + +### 6.1 circulation_status_codes + +**Purpose**: Master table for circulation workflow status codes + +| Column Name | Data Type | Constraints | Description | +| ----------- | ----------- | --------------------------- | --------------------------------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique status ID | +| code | VARCHAR(20) | NOT NULL, UNIQUE | Status code (OPEN, IN_REVIEW, COMPLETED, CANCELLED) | +| description | VARCHAR(50) | NOT NULL | Status description | +| sort_order | INT | DEFAULT 0 | Display order | +| is_active | TINYINT(1) | DEFAULT 1 | Active status | + +**Indexes**: + +- PRIMARY KEY (id) +- UNIQUE (code) +- INDEX (is_active) +- INDEX (sort_order) + +**Relationships**: + +- Referenced by: circulations + +**Seed Data**: 4 status codes + +- OPEN: Initial status when created +- IN_REVIEW: Under review by recipients +- COMPLETED: All recipients have responded +- CANCELLED: Withdrawn/cancelled + +--- + +### 6.2 circulations + +**Purpose**: Master table for internal circulation sheets (document routing) + +| Column Name | Data Type | Constraints | Description | +| ----------------------- | ------------ | ----------------------------------- | ----------------------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique circulation ID | +| correspondence_id | INT | UNIQUE, FK | Link to correspondence (1:1 relationship) | +| organization_id | INT | NOT NULL, FK | Organization that owns this circulation | +| circulation_no | VARCHAR(100) | NOT NULL | Circulation sheet number | +| circulation_subject | VARCHAR(500) | NOT NULL | Subject/title | +| circulation_status_code | VARCHAR(20) | NOT NULL, FK | Current status code | +| created_by_user_id | INT | NOT NULL, FK | User who created circulation | +| submitted_at | TIMESTAMP | NULL | Submission timestamp | +| closed_at | TIMESTAMP | NULL | Closure timestamp | +| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | +| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | + +**Indexes**: + +- PRIMARY KEY (id) +- UNIQUE (correspondence_id) +- FOREIGN KEY (correspondence_id) REFERENCES correspondences(id) +- FOREIGN KEY (organization_id) REFERENCES organizations(id) +- FOREIGN KEY (circulation_status_code) REFERENCES circulation_status_codes(code) +- FOREIGN KEY (created_by_user_id) REFERENCES users(user_id) +- INDEX (organization_id) +- INDEX (circulation_status_code) +- INDEX (created_by_user_id) + +**Relationships**: + +- Parent: correspondences, organizations, circulation_status_codes, users +- Children: circulation_routings, circulation_attachments + +**Business Rules**: + +- Internal document routing within organization +- One-to-one relationship with correspondences +- Tracks document review/approval workflow +- Status progression: OPEN → IN_REVIEW → COMPLETED/CANCELLED + +--- + +### 6.3 circulation_templates + +**Purpose**: Master table for circulation workflow templates + +| Column Name | Data Type | Constraints | Description | +| --------------- | ------------ | ----------------------------------- | --------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique template ID | +| template_name | VARCHAR(100) | NOT NULL | Template name | +| description | TEXT | NULL | Template description | +| organization_id | INT | NOT NULL, FK | Template owner organization | +| is_active | TINYINT(1) | DEFAULT 1 | Active status | +| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | +| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | + +**Indexes**: + +- PRIMARY KEY (id) +- FOREIGN KEY (organization_id) REFERENCES organizations(id) +- INDEX (organization_id) +- INDEX (is_active) + +**Relationships**: + +- Parent: organizations +- Children: circulation_template_assignees + +**Business Rules**: + +- Organization-specific templates +- Defines reusable routing workflows + +--- + +### 6.4 circulation_template_assignees + +**Purpose**: Child table defining steps in circulation templates + +| Column Name | Data Type | Constraints | Description | +| --------------- | --------- | --------------------------- | --------------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique step ID | +| template_id | INT | NOT NULL, FK | Reference to template | +| step_number | INT | NOT NULL | Step sequence order | +| organization_id | INT | NOT NULL, FK | Organization responsible for step | +| role_id | INT | NULL, FK | Required role for this step | +| duration_days | INT | NULL | Expected duration in days | +| is_optional | BOOLEAN | DEFAULT FALSE | Optional step flag | + +**Indexes**: + +- PRIMARY KEY (id) +- FOREIGN KEY (template_id) REFERENCES circulation_templates(id) ON DELETE CASCADE +- FOREIGN KEY (organization_id) REFERENCES organizations(id) +- FOREIGN KEY (role_id) REFERENCES roles(role_id) +- INDEX (template_id, step_number) +- INDEX (organization_id) + +**Relationships**: + +- Parent: circulation_templates, organizations, roles + +**Business Rules**: + +- Steps executed in step_number order +- Optional steps can be skipped +- Duration used for deadline calculation + +--- + +### 6.5 circulation_routings + +**Purpose**: Transaction log table tracking actual circulation routing execution + +| Column Name | Data Type | Constraints | Description | +| --------------- | --------- | ----------------------------------- | ------------------------------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique routing log ID | +| circulation_id | INT | NOT NULL, FK | Reference to circulation | +| step_number | INT | NOT NULL | Current step number | +| organization_id | INT | NOT NULL, FK | Organization responsible | +| assigned_to | INT | NULL, FK | Assigned user ID | +| status | ENUM | NULL | Status: PENDING, IN_PROGRESS, COMPLETED, REJECTED | +| comments | TEXT | NULL | Comments/remarks | +| completed_at | DATETIME | NULL | Completion timestamp | +| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | +| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | + +**Indexes**: + +- PRIMARY KEY (id) +- FOREIGN KEY (circulation_id) REFERENCES circulations(id) ON DELETE CASCADE +- FOREIGN KEY (organization_id) REFERENCES organizations(id) +- FOREIGN KEY (assigned_to) REFERENCES users(user_id) +- INDEX (circulation_id, step_number) +- INDEX (assigned_to, status) +- INDEX (status) + +**Relationships**: + +- Parent: circulations, organizations, users + +**Business Rules**: + +- Records actual routing history +- Multiple records per circulation (one per step) +- Tracks who reviewed/approved and when +- Used in v_user_tasks view for pending items + +--- + +## **7. 📤 Transmittals Tables (เอกสารนำส่ง)** + +### 7.1 transmittals + +**Purpose**: Child table for transmittal-specific data (1:1 with correspondences) + +| Column Name | Data Type | Constraints | Description | +| ----------------- | --------- | --------------- | --------------------------------------------------------- | +| correspondence_id | INT | PRIMARY KEY, FK | Reference to correspondences (1:1) | +| purpose | ENUM | NULL | Purpose: FOR_APPROVAL, FOR_INFORMATION, FOR_REVIEW, OTHER | +| remarks | TEXT | NULL | Additional remarks | + +**Indexes**: + +- PRIMARY KEY (correspondence_id) +- FOREIGN KEY (correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE +- INDEX (purpose) + +**Relationships**: + +- Parent: correspondences +- Children: transmittal_items + +**Business Rules**: + +- One-to-one relationship with correspondences +- Transmittal is a correspondence type for forwarding documents +- Contains metadata about the transmission + +--- + +### 7.2 transmittal_items + +**Purpose**: Junction table listing documents included in transmittal (M:N) + +| Column Name | Data Type | Constraints | Description | +| ---------------------- | ------------ | --------------------------- | --------------------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique item ID | +| transmittal_id | INT | NOT NULL, FK | Reference to transmittal | +| item_correspondence_id | INT | NOT NULL, FK | Reference to document being transmitted | +| quantity | INT | DEFAULT 1 | Number of copies | +| remarks | VARCHAR(255) | NULL | Item-specific remarks | + +**Indexes**: + +- PRIMARY KEY (id) +- FOREIGN KEY (transmittal_id) REFERENCES transmittals(correspondence_id) ON DELETE CASCADE +- FOREIGN KEY (item_correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE +- UNIQUE KEY (transmittal_id, item_correspondence_id) +- INDEX (item_correspondence_id) + +**Relationships**: + +- Parent: transmittals, correspondences + +**Business Rules**: + +- One transmittal can contain multiple documents +- Tracks quantity of physical copies (if applicable) +- Links to any type of correspondence document + +--- + +## **8. 📎 File Management Tables (ไฟล์แนบ)** + +### 8.1 attachments + +**Purpose**: Central repository for all file attachments in the system + +| Column Name | Data Type | Constraints | Description | +| ------------------- | ------------ | --------------------------- | --------------------------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique attachment ID | +| original_filename | VARCHAR(255) | NOT NULL | Original filename from upload | +| stored_filename | VARCHAR(255) | NOT NULL | System-generated unique filename | +| file_path | VARCHAR(500) | NOT NULL | Full file path on server (/share/dms-data/) | +| mime_type | VARCHAR(100) | NOT NULL | MIME type (application/pdf, image/jpeg, etc.) | +| file_size | INT | NOT NULL | File size in bytes | +| uploaded_by_user_id | INT | NOT NULL, FK | User who uploaded file | +| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Upload timestamp | + +**Indexes**: + +- PRIMARY KEY (id) +- FOREIGN KEY (uploaded_by_user_id) REFERENCES users(user_id) ON DELETE CASCADE +- INDEX (stored_filename) +- INDEX (mime_type) +- INDEX (uploaded_by_user_id) +- INDEX (created_at) + +**Relationships**: + +- Parent: users +- Referenced by: correspondence_attachments, circulation_attachments, shop_drawing_revision_attachments, contract_drawing_attachments + +**Business Rules**: + +- Central storage prevents file duplication +- Stored filename prevents naming conflicts +- File path points to QNAP NAS storage +- Original filename preserved for download +- One file record can be linked to multiple documents + +--- + +### 8.2 correspondence_attachments + +**Purpose**: Junction table linking correspondences to file attachments (M:N) + +| Column Name | Data Type | Constraints | Description | +| ----------------- | --------- | --------------- | ---------------------------- | +| correspondence_id | INT | PRIMARY KEY, FK | Reference to correspondences | +| attachment_id | INT | PRIMARY KEY, FK | Reference to attachments | +| is_main_document | BOOLEAN | DEFAULT FALSE | Main/primary document flag | + +**Indexes**: + +- PRIMARY KEY (correspondence_id, attachment_id) +- FOREIGN KEY (correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE +- FOREIGN KEY (attachment_id) REFERENCES attachments(id) ON DELETE CASCADE +- INDEX (attachment_id) +- INDEX (is_main_document) + +**Relationships**: + +- Parent: correspondences, attachments + +**Business Rules**: + +- One correspondence can have multiple attachments +- One attachment can be linked to multiple correspondences +- is_main_document identifies primary file (typically PDF) + +--- + +### 8.3 circulation_attachments + +**Purpose**: Junction table linking circulations to file attachments (M:N) + +| Column Name | Data Type | Constraints | Description | +| ---------------- | --------- | --------------- | -------------------------- | +| circulation_id | INT | PRIMARY KEY, FK | Reference to circulations | +| attachment_id | INT | PRIMARY KEY, FK | Reference to attachments | +| is_main_document | BOOLEAN | DEFAULT FALSE | Main/primary document flag | + +**Indexes**: + +- PRIMARY KEY (circulation_id, attachment_id) +- FOREIGN KEY (circulation_id) REFERENCES circulations(id) ON DELETE CASCADE +- FOREIGN KEY (attachment_id) REFERENCES attachments(id) ON DELETE CASCADE +- INDEX (attachment_id) +- INDEX (is_main_document) + +**Relationships**: + +- Parent: circulations, attachments + +--- + +### 8.4 shop_drawing_revision_attachments + +**Purpose**: Junction table linking shop drawing revisions to file attachments (M:N) + +| Column Name | Data Type | Constraints | Description | +| ------------------------ | --------- | --------------- | ---------------------------------- | +| shop_drawing_revision_id | INT | PRIMARY KEY, FK | Reference to shop drawing revision | +| attachment_id | INT | PRIMARY KEY, FK | Reference to attachments | +| file_type | ENUM | NULL | File type: PDF, DWG, SOURCE, OTHER | +| is_main_document | BOOLEAN | DEFAULT FALSE | Main/primary document flag | + +**Indexes**: + +- PRIMARY KEY (shop_drawing_revision_id, attachment_id) +- FOREIGN KEY (shop_drawing_revision_id) REFERENCES shop_drawing_revisions(id) ON DELETE CASCADE +- FOREIGN KEY (attachment_id) REFERENCES attachments(id) ON DELETE CASCADE +- INDEX (attachment_id) +- INDEX (file_type) +- INDEX (is_main_document) + +**Relationships**: + +- Parent: shop_drawing_revisions, attachments + +**Business Rules**: + +- file_type categorizes drawing file formats +- Typically includes PDF for viewing and DWG for editing +- SOURCE may include native CAD files + +--- + +### 8.5 contract_drawing_attachments + +**Purpose**: Junction table linking contract drawings to file attachments (M:N) + +| Column Name | Data Type | Constraints | Description | +| ------------------- | --------- | --------------- | ---------------------------------- | +| contract_drawing_id | INT | PRIMARY KEY, FK | Reference to contract drawing | +| attachment_id | INT | PRIMARY KEY, FK | Reference to attachments | +| file_type | ENUM | NULL | File type: PDF, DWG, SOURCE, OTHER | +| is_main_document | BOOLEAN | DEFAULT FALSE | Main/primary document flag | + +**Indexes**: + +- PRIMARY KEY (contract_drawing_id, attachment_id) +- FOREIGN KEY (contract_drawing_id) REFERENCES contract_drawings(id) ON DELETE CASCADE +- FOREIGN KEY (attachment_id) REFERENCES attachments(id) ON DELETE CASCADE +- INDEX (attachment_id) +- INDEX (file_type) +- INDEX (is_main_document) + +**Relationships**: + +- Parent: contract_drawings, attachments + +--- + +## **9. 🔢 Document Numbering Tables (การสร้างเลขที่เอกสาร)** + +### 9.1 document_number_formats + +**Purpose**: Master table defining document numbering templates per project and type + +| Column Name | Data Type | Constraints | Description | +| ---------------------- | ------------ | ----------------------------------- | -------------------------------------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique format ID | +| project_id | INT | NOT NULL, FK | Reference to projects | +| correspondence_type_id | INT | NOT NULL, FK | Reference to correspondence types | +| format_template | VARCHAR(255) | NOT NULL | Template string (e.g., '{ORG_CODE}-{TYPE_CODE}-{SEQ:4}') | +| description | TEXT | NULL | Format description | +| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | +| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | + +**Indexes**: + +- PRIMARY KEY (id) +- FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE +- FOREIGN KEY (correspondence_type_id) REFERENCES correspondence_types(id) ON DELETE CASCADE +- UNIQUE KEY (project_id, correspondence_type_id) +- INDEX (project_id) +- INDEX (correspondence_type_id) + +**Relationships**: + +- Parent: projects, correspondence_types + +**Business Rules**: + +- One format template per project per correspondence type combination +- Template placeholders: {ORG_CODE}, {TYPE_CODE}, {YEAR}, {SEQ:n} where n is zero-padding length +- Used by document numbering module to generate unique document numbers + +--- + +### 9.2 document_number_counters + +**Purpose**: Transaction table maintaining running sequence numbers for document numbering + +| Column Name | Data Type | Constraints | Description | +| -------------------------- | --------- | --------------- | --------------------------------- | +| project_id | INT | PRIMARY KEY, FK | Reference to projects | +| originator_organization_id | INT | PRIMARY KEY, FK | Originating organization | +| correspondence_type_id | INT | PRIMARY KEY, FK | Reference to correspondence types | +| current_year | INT | PRIMARY KEY | Year (Buddhist calendar) | +| last_number | INT | DEFAULT 0 | Last assigned sequence number | + +**Indexes**: + +- PRIMARY KEY (project_id, originator_organization_id, correspondence_type_id, current_year) +- FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE +- FOREIGN KEY (originator_organization_id) REFERENCES organizations(id) ON DELETE CASCADE +- FOREIGN KEY (correspondence_type_id) REFERENCES correspondence_types(id) ON DELETE CASCADE +- INDEX (project_id) +- INDEX (originator_organization_id) +- INDEX (correspondence_type_id) +- INDEX (current_year) + +**Relationships**: + +- Parent: projects, organizations, correspondence_types + +**Business Rules**: + +- Composite primary key ensures unique counters per project/organization/type/year +- Counter resets each year +- Thread-safe increments handled by stored procedure sp_get_next_document_number +- last_number tracks highest assigned number +- Used with document_number_formats to generate complete document numbers + +--- + +## **10. ⚙️ System & Logs Tables (ระบบและ Log)** + +### 10.1 audit_logs + +**Purpose**: Comprehensive audit trail for all significant system actions + +| Column Name | Data Type | Constraints | Description | +| ------------ | ------------ | --------------------------- | ------------------------------------------------------ | +| audit_id | BIGINT | PRIMARY KEY, AUTO_INCREMENT | Unique audit log ID | +| user_id | INT | NULL, FK | User who performed action | +| action | VARCHAR(100) | NOT NULL | Action code (e.g., 'rfa.create', 'login.success') | +| entity_type | VARCHAR(50) | NULL | Entity/module affected (e.g., 'rfa', 'correspondence') | +| entity_id | VARCHAR(50) | NULL | Primary ID of affected record | +| details_json | JSON | NULL | Additional context/details in JSON format | +| ip_address | VARCHAR(45) | NULL | Client IP address (supports IPv6) | +| user_agent | VARCHAR(255) | NULL | Browser user agent string | +| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Action timestamp | + +**Indexes**: + +- PRIMARY KEY (audit_id) +- FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE SET NULL +- INDEX (user_id) +- INDEX (action) +- INDEX (entity_type, entity_id) +- INDEX (created_at) +- INDEX (ip_address) + +**Relationships**: + +- Parent: users + +**Business Rules**: + +- Immutable records (no updates/deletes) +- Captures all CRUD operations on sensitive data +- Includes authentication events (login, logout, failed attempts) +- JSON details field for flexible data storage +- Retention policy: typically 7 years for compliance +- Used for security audits, compliance reporting, and troubleshooting + +**Common Actions**: + +- Authentication: login.success, login.failed, logout +- Documents: correspondence.create, correspondence.update, rfa.submit +- Users: user.create, user.deactivate, role.assign +- Workflow: rfa.approve, rfa.reject, circulation.complete + +--- + +### 10.2 notifications + +**Purpose**: User notification queue for email, LINE, and in-system alerts + +| Column Name | Data Type | Constraints | Description | +| ----------------- | ------------ | --------------------------- | ------------------------------------------------ | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique notification ID | +| user_id | INT | NOT NULL, FK | Recipient user ID | +| title | VARCHAR(255) | NOT NULL | Notification title/subject | +| message | TEXT | NOT NULL | Notification message body | +| notification_type | ENUM | NOT NULL | Type: EMAIL, LINE, SYSTEM | +| is_read | BOOLEAN | DEFAULT FALSE | Read status flag | +| entity_type | VARCHAR(50) | NULL | Related entity type (e.g., 'rfa', 'circulation') | +| entity_id | INT | NULL | Related entity ID | +| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Notification creation timestamp | + +**Indexes**: + +- PRIMARY KEY (id) +- FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE +- INDEX (user_id) +- INDEX (notification_type) +- INDEX (is_read) +- INDEX (entity_type, entity_id) +- INDEX (created_at) +- COMPOSITE INDEX (user_id, is_read, created_at) - For user notification listing + +**Relationships**: + +- Parent: users + +**Business Rules**: + +- EMAIL: Sent via SMTP to user's email address +- LINE: Sent via LINE Notify API to user's LINE ID +- SYSTEM: In-app notifications displayed in user interface +- Same notification can trigger multiple types (EMAIL + SYSTEM) +- entity_type/entity_id allow deep-linking to related records +- is_read flag only applicable for SYSTEM notifications +- Auto-cleanup: delete read notifications older than 30 days + +**Common Notification Triggers**: + +- Task assignment (circulation routing, RFA workflow) +- Document status changes (submitted, approved, rejected) +- Approaching deadlines +- System announcements +- Mention in comments + +--- + +### 10.3 search_indices + +**Purpose**: Full-text search index for document content + +| Column Name | Data Type | Constraints | Description | +| ----------- | ----------- | --------------------------- | ------------------------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique index ID | +| entity_type | VARCHAR(50) | NOT NULL | Entity type (e.g., 'correspondence', 'rfa') | +| entity_id | INT | NOT NULL | Entity primary ID | +| content | TEXT | NOT NULL | Searchable text content | +| indexed_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Last indexing timestamp | + +**Indexes**: + +- PRIMARY KEY (id) +- INDEX (entity_type, entity_id) +- INDEX (indexed_at) + +**Business Rules**: + +- Automatically populated/updated when documents change +- Content includes: title, description, document number, metadata +- May include OCR text from PDF attachments (future enhancement) +- Used by advanced search functionality +- Periodic re-indexing to catch missed updates +- Supports Boolean operators, phrase searching + +**Search Features**: + +- Natural language queries +- Wildcard support (\*, ?) +- Boolean operators (AND, OR, NOT) +- Phrase matching with quotes +- Result ranking by relevance + +--- + +### 10.4 backup_logs + +**Purpose**: Log table tracking database and file backup operations + +| Column Name | Data Type | Constraints | Description | +| ------------- | ------------ | --------------------------- | ---------------------------------- | +| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique backup log ID | +| backup_type | ENUM | NOT NULL | Type: DATABASE, FILES, FULL | +| backup_path | VARCHAR(500) | NOT NULL | Path to backup file/directory | +| file_size | BIGINT | NULL | Backup file size in bytes | +| status | ENUM | NOT NULL | Status: STARTED, COMPLETED, FAILED | +| started_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Backup start timestamp | +| completed_at | TIMESTAMP | NULL | Backup completion timestamp | +| error_message | TEXT | NULL | Error details if failed | + +**Indexes**: + +- PRIMARY KEY (id) +- INDEX (backup_type) +- INDEX (status) +- INDEX (started_at) +- INDEX (completed_at) + +**Business Rules**: + +- DATABASE: MariaDB dump of database schema and data +- FILES: Backup of attachment files from QNAP storage +- FULL: Complete system backup (database + files) +- Triggered by n8n cron jobs +- Backup retention policy defined in backup strategy +- Failed backups trigger alert notifications +- completed_at - started_at = backup duration + +**Monitoring**: + +- Alert if no successful backup in 24 hours +- Track backup size trends over time +- Verify backup integrity with test restores + +--- + +## **11. 📊 Views & Procedures (วิว และ โปรซีเดอร์)** + +### 11.1 v_current_correspondences + +**Purpose**: View showing current revision of all non-RFA correspondences + +**Columns**: + +- correspondence_id, correspondence_number, correspondence_type_id/code/name +- project_id, project_code, project_iname +- organization_id, organization_code, organization_name +- revision_id, revision_number, revision_label +- title, document_date, issued_date, received_date, due_date +- correspondence_status_id, correspondence_status_code, correspondence_status_name +- created_by, created_by_username, revision_created_at + +**Filters**: + +- is_current = TRUE (only latest revision) +- correspondence_type NOT IN ('RFA') (excludes RFAs) +- deleted_at IS NULL (excludes soft-deleted records) + +**Business Rules**: + +- Provides flattened view of current correspondence state +- Joins correspondence_revisions with is_current flag +- Used by dashboard, document listing screens +- Excludes RFAs (they have separate view) + +--- + +### 11.2 v_current_rfas + +**Purpose**: View showing current revision of all RFA documents + +**Columns**: + +- rfa_id, rfa_type_id, rfa_type_code, rfa_type_name +- correspondence_id, correspondence_number +- project_id, project_code, project_iname +- organization_id, organization_name +- revision_id, revision_number, revision_label +- title, document_date, issued_date, received_date, approved_date +- rfa_status_code_id, rfa_status_code, rfa_status_name +- rfa_approve_code_id, rfa_approve_code, rfa_approve_code_name +- created_by, created_by_username, revision_created_at + +**Filters**: + +- is_current = TRUE +- deleted_at IS NULL (both rfas and correspondences) + +**Business Rules**: + +- Specialized view for RFA documents +- Includes RFA-specific fields (approval codes, approved date) +- Joins across rfas → rfa_revisions → correspondences +- Used by RFA management screens + +--- + +### 11.3 v_contract_parties_all + +**Purpose**: View showing all organization relationships across contracts and projects + +**Columns**: + +- contract_id, contract_code, contract_name +- project_id, project_code, project_iname +- organization_id, organization_code, organization_name +- role_in_contract + +**Business Rules**: + +- Joins contracts → projects → contract_organizations → organizations +- Shows only active contracts (is_active = TRUE) +- Used for permission checks and document routing +- Supports multi-organization projects/contracts + +--- + +### 11.4 v_user_tasks + +**Purpose**: View showing pending tasks assigned to users (action items) + +**Columns**: + +- routing_id, circulation_id, circulation_no, circulation_subject +- correspondence_id, correspondence_number +- project_id, project_code, project_name +- user_id, username, first_name, last_name +- organization_id, organization_name +- step_number, task_status, comments +- completed_at, assigned_at, circulation_created_at + +**Filters**: + +- status IN ('PENDING', 'IN_PROGRESS') +- assigned_to IS NOT NULL + +**Business Rules**: + +- Shows circulation routings requiring user action +- Used for "My Tasks" / "Inbox" functionality +- Excludes completed/cancelled tasks +- Ordered by creation date (oldest first) + +--- + +### 11.5 v_audit_log_details + +**Purpose**: View enriching audit logs with user information + +**Columns**: + +- audit_id, user_id, username, email, first_name, last_name +- action, entity_type, entity_id +- details_json, ip_address, user_agent +- created_at + +**Business Rules**: + +- Joins audit_logs with users table +- Used for audit trail reports +- Includes user details even if user later deleted (LEFT JOIN) + +--- + +### 11.6 v_user_all_permissions + +**Purpose**: View showing all effective permissions for users across all scopes + +**Columns**: + +- user_id, role_id, role_name +- permission_id, permission_name +- module, scope_level +- organization_id, project_id, contract_id +- permission_scope (GLOBAL, ORGANIZATION, PROJECT, CONTRACT) + +**Business Rules**: + +- UNION of permissions from Global, Organization, Project, and Contract scopes +- Used for authorization checks +- Considers role-permission mappings at all levels +- Only shows active permissions (is_active = 1) +- One row per user-permission-scope combination + +**Usage Example**: + +```sql +SELECT permission_name +FROM v_user_all_permissions +WHERE user_id = ? + AND project_id = ? + AND permission_name = 'document.edit'; +``` + +--- + +### 11.7 v_documents_with_attachments + +**Purpose**: View showing all documents and their attachment counts + +**Columns**: + +- document_type (CORRESPONDENCE, CIRCULATION, SHOP_DRAWING, CONTRACT_DRAWING) +- document_id, document_number +- project_id, project_code, project_name +- attachment_count, latest_attachment_date + +**Business Rules**: + +- UNION of all document types with attachments +- Used for document listing with file indicators +- Helps identify documents missing attachments +- Aggregates count per document + +--- + +### 11.8 v_document_statistics + +**Purpose**: View providing aggregated document statistics by project, type, and status + +**Columns**: + +- project_id, project_code, project_name +- correspondence_type_id, correspondence_type_code, correspondence_type_name +- status_id, status_code, status_name +- document_count, revision_count + +**Business Rules**: + +- CROSS JOIN creates all possible combinations +- LEFT JOIN shows zeros for combinations with no documents +- Only includes active projects, types, and statuses +- Used for dashboard charts and reports +- Groups by project → type → status + +--- + +### 11.9 sp_get_next_document_number + +**Purpose**: Stored procedure to safely generate next sequential document number + +**Parameters**: + +- IN p_project_id INT +- IN p_originator_organization_id INT +- IN p_correspondence_type_id INT +- IN p_current_year INT +- OUT p_next_number INT + +**Logic**: + +1. Start transaction +2. SELECT last_number FOR UPDATE (locks row) +3. If record doesn't exist, INSERT with last_number = 1 +4. Else UPDATE last_number = last_number + 1 +5. Return new number via OUT parameter +6. COMMIT transaction + +**Business Rules**: + +- Thread-safe counter increment +- FOR UPDATE lock prevents race conditions +- Handles first-time counter initialization +- Rolls back on any error +- Must be called within document creation transaction +- Used in conjunction with document_number_formats template + +**Usage Example**: + +```sql +CALL sp_get_next_document_number( + 1, -- project_id + 10, -- organization_id + 1, -- type_id (RFA) + 2568, -- Buddhist year + @next_number +); +-- @next_number now contains next sequence +``` + +--- + +## Database Indexes Summary + +### Performance Optimization Indexes + +**Primary Indexes** (automatic with PRIMARY KEY): + +- All tables have PRIMARY KEY with AUTO_INCREMENT + +**Foreign Key Indexes** (automatic with FOREIGN KEY): + +- All FK relationships automatically indexed + +**Additional Performance Indexes**: + +1. **Correspondence Tables**: + + - `idx_correspondences_type_project` on (correspondence_type_id, project_id) + - `idx_corr_revisions_current_status` on (is_current, correspondence_status_id) + - `idx_corr_revisions_correspondence_current` on (correspondence_id, is_current) + - `idx_correspondences_project_type` on (project_id, correspondence_type_id) + +2. **RFA Tables**: + + - `idx_rfa_revisions_current_status` on (is_current, rfa_status_code_id) + - `idx_rfa_revisions_rfa_current` on (rfa_id, is_current) + +3. **Circulation Tables**: + + - `idx_circulation_routings_status_assigned` on (status, assigned_to) + - `idx_circulation_routings_circulation_status` on (circulation_id, status) + +4. **Document Numbering**: + + - `idx_doc_counter_composite` on (project_id, originator_organization_id, correspondence_type_id, current_year) + +5. **Audit & Notifications**: + + - `idx_audit_logs_reporting` on (created_at, entity_type, action) + - `idx_notifications_user_unread` on (user_id, is_read, created_at) + +--- + +## Data Integrity Constraints + +### Foreign Key Constraints + +**Cascade Delete**: + +- Parent-child relationships where child should be deleted with parent +- Examples: correspondence_revisions, shop_drawing_revisions, project/contract relationships + +**Restrict Delete**: + +- Prevents deletion if references exist +- Examples: correspondence_types, rfa_status_codes, organizations (when referenced) + +**Set NULL**: + +- Preserves record but removes reference +- Examples: originator_id, created_by, updated_by + +### Unique Constraints + +1. **Globally Unique**: + + - usernames, emails + - shop_drawing.drawing_number + +2. **Unique Within Scope**: + + - (project_id, correspondence_number) + - (project_id, condwg_no) + - (correspondence_id, revision_number) + - (rfa_id, revision_number) + +3. **Composite Unique**: + - (correspondence_id, is_current) - ensures only one current revision + - (project_id, correspondence_type_id) - in document_number_formats + +### Check Constraints + +1. **user_assignments.chk_scope**: + - Ensures only one scope field (organization_id, project_id, contract_id) is NOT NULL + - OR all are NULL for Global scope + +### Business Rule Constraints + +1. **Soft Delete Pattern**: + + - deleted_at timestamp instead of hard delete + - Preserves audit trail and relationships + - Applied to: correspondences, rfas, shop_drawings, contract_drawings + +2. **Current Revision Pattern**: + + - is_current flag with UNIQUE constraint + - Ensures only one current revision per document + +3. **Sequential Numbering**: + - revision_number starts at 0, increments by 1 + - Enforced by application logic + stored procedure + +--- + +## Security & Permissions Model + +### Access Control Hierarchy + +```tree +Global Scope (Superadmin) + └── Organization Scope (Org Admin, Document Control) + └── Project Scope (Project Manager) + └── Contract Scope (Contract Admin) +``` + +### Permission Inheritance + +- Users can have multiple role assignments at different scopes +- More specific scopes inherit access from broader scopes +- Permission checks evaluate all applicable scopes +- View v_user_all_permissions aggregates effective permissions + +### Role-Based Access Control (RBAC) + +**7 Predefined Roles**: + +1. Superadmin (Global) - Full system access +2. Org Admin (Organization) - Organization management +3. Document Control (Organization) - Document lifecycle + admin powers +4. Editor (Organization) - Document CRUD +5. Viewer (Organization) - Read-only +6. Project Manager (Project) - Project + document management +7. Contract Admin (Contract) - Contract-specific management + +### Permission Categories (49 total) + +1. **System Management** (1): Full system control +2. **Organization Management** (4): CRUD on organizations +3. **Project Management** (8): CRUD + member/contract management +4. **Role & Permission Management** (4): RBAC administration +5. **Master Data Management** (4): Document types, categories, tags +6. **User Management** (5): User CRUD + organization assignment +7. **Contract Management** (2): Contract administration +8. **Document Management** (16): Full document lifecycle +9. **Workflow Management** (3): Approval workflow control +10. **Search & Reporting** (2): Advanced search, report generation + +--- + +## Data Migration & Seeding + +### Pre-populated Master Data + +1. **organization_roles**: Not used in current implementation +2. **organizations**: 15 organizations (Owner, Consultants, Contractors, Third parties) +3. **projects**: 5 projects (LCBP3 + 4 sub-contracts) +4. **contracts**: 7 contracts +5. **users**: 3 initial users (superadmin, editor01, viewer01) +6. **roles**: 7 predefined roles +7. **permissions**: 49 system permissions +8. **role_permissions**: Complete permission mappings +9. **project_organizations**: Project-organization relationships +10. **contract_organizations**: Contract-organization-role relationships +11. **correspondence_types**: 10 types +12. **correspondence_status**: 23 status codes +13. **rfa_types**: 11 types +14. **rfa_status_codes**: 7 statuses +15. **rfa_approve_codes**: 8 approval codes +16. **circulation_status_codes**: 4 statuses + +### Initial Passwords + +All seed users have password: `password123` + +- Hashed as: `$2y$10$0kjBMxWq7E4G7P.dc8r5i.cjiPBiup553AsFpDfxUt31gKg9h/udq` +- **Must be changed on first login in production** + +--- + +## Backup & Recovery Strategy + +### Database Backup + +**Strategy**: + +- Daily full database backups +- Hourly incremental backups (transaction logs) +- Retention: 30 days online, 7 years archived + +**Backup Method**: + +- MariaDB mysqldump for logical backups +- MariaDB Backup (Mariabackup) for physical backups +- Automated via n8n cron workflows + +### File Backup + +**Strategy**: + +- Daily backup of /share/dms-data/ directory +- QNAP snapshot every 4 hours +- Offsite replication to secondary NAS + +**File Organization**: + +```tree +/share/dms-data/ + ├── attachments/ + │ ├── 2025/ + │ │ ├── 01/ + │ │ │ └── {uuid}-{filename} + │ │ └── 02/ + │ └── 2024/ + └── temp/ +``` + +### Recovery Procedures + +1. **Point-in-Time Recovery**: Using transaction logs +2. **Full Restore**: From latest full backup +3. **Selective Restore**: Individual tables or records +4. **File Recovery**: From QNAP snapshots or backup + +--- + +## Performance Optimization + +### Query Optimization + +1. **Use Indexed Columns**: WHERE, JOIN, ORDER BY clauses +2. **Avoid SELECT**: Specify needed columns +3. **Use Views**: For complex, frequently-used queries +4. **Limit Result Sets**: Use LIMIT and pagination +5. **Analyze Slow Queries**: Enable slow query log + +### Index Maintenance + +```sql +-- Check index usage +SELECT * FROM information_schema.STATISTICS +WHERE TABLE_SCHEMA = 'lcbp3'; + +-- Optimize tables +OPTIMIZE TABLE correspondences; + +-- Analyze tables +ANALYZE TABLE correspondences; +``` + +### Connection Pooling + +- Backend uses connection pool (NestJS TypeORM) +- Min pool size: 5 +- Max pool size: 20 +- Idle timeout: 10 minutes + +--- + +## Data Validation Rules + +### Required Fields Validation + +**At Application Level**: + +- Email format validation +- Date range validation (start_date < end_date) +- File size limits (5MB per attachment) +- File type restrictions (PDF, DWG, DOC, XLS, images) + +**At Database Level**: + +- NOT NULL constraints +- UNIQUE constraints +- Foreign key constraints +- Check constraints (user_assignments scope) + +### Business Logic Validation + +1. **Document Workflow**: + + - Cannot edit submitted documents (unless Document Control) + - Cannot skip workflow steps (unless forced) + - Must provide approval comments + +2. **User Management**: + + - Cannot delete users with active assignments + - Cannot deactivate own account + - Must have valid organization for non-Global roles + +3. **File Management**: + - Original filename preserved for audit + - Unique stored filename prevents conflicts + - File path must exist and be accessible + +--- + +## Change Log & Versioning + +### Database Version: v1.4.0 + +**Changes from v1.3.0**: + +- Added comprehensive RBAC system (roles, permissions, user_assignments) +- Refactored organization-project-contract relationships +- Added junction tables for M:N relationships +- Implemented soft delete pattern +- Added full-text search support +- Enhanced audit logging with JSON details +- Added circulation workflow templates +- Improved document numbering with stored procedure +- Added comprehensive views for common queries +- Optimized indexes for performance + +**Migration Path**: + +- v1.3.0 → v1.4.0: Run migration script (not provided in this excerpt) +- Backup database before migration +- Test migration on staging environment first + +--- + +## Technical Specifications + +### Database Configuration + +**MariaDB Server**: + +- Version: 10.11 +- Character Set: utf8mb4 +- Collation: utf8mb4_general_ci +- Time Zone: +07:00 (Bangkok/Asia) +- SQL Mode: STRICT_TRANS_TABLES, NO_ENGINE_SUBSTITUTION + +**Connection Settings**: + +- Host: Container on QNAP TS-473A +- Port: 3306 (default) +- Max Connections: 100 +- Max Packet Size: 64MB + +### Table Engine + +**InnoDB Features Used**: + +- ACID compliance +- Foreign key constraints +- Row-level locking +- Crash recovery +- Transaction support + +### Storage Requirements + +**Estimated Initial Size**: + +- Database: ~50 MB (with seed data) +- Indexes: ~20 MB +- Total: ~70 MB + +**Growth Estimates**: + +- 1,000 documents/month: +100 MB/month (database) +- 10 attachments/document @ 2MB avg: +20 GB/month (files) +- Plan for 1TB+ storage within first year + +--- + +## Application Integration + +### Backend (NestJS) + +**TypeORM Entities**: + +- One entity class per table +- Decorators for columns, relationships +- DTOs for data transfer +- Repositories for data access + +**Key Modules**: + +- AuthModule: Authentication, authorization +- DocumentsModule: Correspondence, RFA management +- DrawingsModule: Shop drawing, contract drawing +- WorkflowModule: Circulation, approval workflows +- FilesModule: Attachment management +- UsersModule: User, role, permission management + +### Frontend (Next.js) + +**Key Features**: + +- Document listing/search +- Document creation wizards +- Workflow approval interface +- File upload/download +- User management console +- Dashboard analytics + +### Integration Points + +1. **Document Numbering**: + + - Call sp_get_next_document_number + - Format with template from document_number_formats + - Store in correspondences.correspondence_number + +2. **File Upload**: + + - Upload to QNAP /share/dms-data/ + - Create attachment record + - Link via junction table + +3. **Workflow Execution**: + + - Check rfa_workflow_templates + - Create rfa_workflows records + - Update status as steps complete + - Send notifications + +4. **Permission Checks**: + - Query v_user_all_permissions + - Cache results per session + - Re-check on sensitive operations + +--- + +## Monitoring & Maintenance + +### Health Checks + +```sql +-- Database size +SELECT + table_schema, + SUM(data_length + index_length) / 1024 / 1024 AS size_mb +FROM information_schema.TABLES +WHERE table_schema = 'dms_db' +GROUP BY table_schema; + +-- Table sizes +SELECT + table_name, + (data_length + index_length) / 1024 / 1024 AS size_mb, + table_rows +FROM information_schema.TABLES +WHERE table_schema = 'dms_db' +ORDER BY (data_length + index_length) DESC; + +-- Active connections +SHOW PROCESSLIST; + +-- Lock wait statistics +SELECT * FROM information_schema.INNODB_LOCK_WAITS; +``` + +### Scheduled Maintenance + +**Daily**: + +- Full database backup +- Check backup log for failures +- Monitor disk space + +**Weekly**: + +- OPTIMIZE tables +- ANALYZE tables +- Review slow query log +- Check for deadlocks + +**Monthly**: + +- Review audit logs +- Clean up old notifications (30+ days) +- Archive old audit logs (7+ years) +- Verify backup integrity (test restore) + +**Quarterly**: + +- Review and optimize indexes +- Update database statistics +- Capacity planning review + +--- + +## Glossary + +**Terms**: + +- **Correspondence**: Any formal document exchanged between parties +- **RFA**: Request for Approval - formal submittal for review/approval +- **Circulation**: Internal document routing workflow +- **Transmittal**: Cover sheet for forwarding multiple documents +- **Shop Drawing**: Detailed construction drawing from contractor +- **Contract Drawing**: Baseline drawing from contract specifications +- **Revision**: Version of a document +- **Originator**: Organization that creates/sends a document +- **Recipient**: Organization that receives a document (TO or CC) +- **Scope**: Level of permission application (Global, Organization, Project, Contract) + +**Acronyms**: + +- **DMS**: Document Management System +- **LCBP3**: Laem Chabang Port Phase 3 +- **RBAC**: Role-Based Access Control +- **RFA**: Request for Approval +- **RFI**: Request for Information +- **CSC**: Construction Supervision Consultant +- **TO**: Primary recipient (action required) +- **CC**: Carbon copy (for information) +- **QNAP**: Network Attached Storage device manufacturer + +--- + +**Document Control**: + +- Document: Data Dictionary - DMS v1.4.0 +- Version: 1.0 +- Date: 2025-01-XX +- Author: System Architecture Team +- Status: FINAL +- Classification: Internal Technical Documentation + +--- + +_End of Data Dictionary diff --git a/docs/LCBP3-DMS_V1_4_1_Frontend_Development_Plan.md b/Documnets/Project/LCBP3-DMS_V1_4_1_Frontend_Development_Plan.md similarity index 96% rename from docs/LCBP3-DMS_V1_4_1_Frontend_Development_Plan.md rename to Documnets/Project/LCBP3-DMS_V1_4_1_Frontend_Development_Plan.md index c605ada..898f1a2 100644 --- a/docs/LCBP3-DMS_V1_4_1_Frontend_Development_Plan.md +++ b/Documnets/Project/LCBP3-DMS_V1_4_1_Frontend_Development_Plan.md @@ -1,2491 +1,2491 @@ -# 📋 **แผนการพัฒนา Backend (NestJS) - LCBP3-DMS v1.4.1 (ปรับปรุงโดย Claude -> deepseek)** - -## 🎯 ภาพรวมโครงการ - -พัฒนา Frontend สำหรับระบบบริหารจัดการเอกสารโครงการ (Document Management System) ที่ทันสมัย responsive และใช้งานง่าย รองรับการจัดการเอกสารที่ซับซ้อน มี Dashboard แบบ Real-time และระบบ Workflow Visualization เน้น Security, Performance และ User Experience ตาม Requirements v1.4.1 อย่างครบถ้วน - ---- - -## 📐 สถาปัตยกรรมระบบ - -### **Technology Stack** - -- **Framework:** Next.js 14+ (App Router, React 18+, TypeScript, ESM) -- **Styling:** Tailwind CSS + PostCSS -- **Component Library:** shadcn/ui (Radix UI) -- **State Management:** - - **Server State:** TanStack Query (React Query) - - **Global Client State:** Zustand - - **Form State:** React Hook Form + Zod -- **Data Fetching:** Axios + TanStack Query -- **Authentication:** NextAuth.js (JWT Strategy) -- **File Upload:** React Dropzone -- **Tables:** TanStack Table -- **Charts:** Recharts -- **Date Picker:** date-fns + shadcn/ui Calendar -- **Icons:** Lucide React -- **Security & File Processing** clamscan + js-file-download + dompurify -- **JSON Schema & Validation** ajv + ajv-formats + jsonpath + json-schema-ref-parser -- **Performance Monitoring** web-vitals + @axe-core/react -- **Advanced UI Components** react-json-view-lite + react-window (สำหรับ Virtual Scrolling) -- **Testing:** - - **Unit/Integration:** Vitest + React Testing Library - - **E2E:** Playwright - - **API Mocking:** Mock Service Worker (MSW) - -### **โครงสร้างโปรเจกต์** - - ```tree - app/ - ├── (public)/ # Public routes (Landing, Login) - │ ├── page.tsx # Landing Page - │ └── login/ # Login Page - ├── (protected)/ # Protected routes - │ ├── layout.tsx # App Shell (Navbar + Sidebar) - │ ├── dashboard/ # Dashboard - │ ├── correspondences/ # Correspondence Management - │ ├── rfas/ # RFA Management - │ ├── drawings/ # Drawing Management - │ ├── circulations/ # Circulation Management - │ ├── transmittals/ # Transmittal Management - │ ├── search/ # Advanced Search - │ ├── reports/ # Reports - │ ├── admin/ # Admin Panel - │ └── profile/ # User Profile - ├── api/ # API Routes (if needed) - components/ - ├── ui/ # shadcn/ui components - ├── features/ # Feature-specific components - │ ├── auth/ - │ ├── correspondence/ - │ ├── rfa/ - │ ├── drawing/ - │ ├── circulation/ - │ ├── common/ - │ ├── security/ # NEW: Security components - │ │ ├── file-upload-security.tsx - │ │ ├── virus-scan-status.tsx - │ │ └── security-audit-log.tsx - │ ├── json-details/ # NEW: JSON Details management - │ │ ├── json-details-form.tsx - │ │ ├── schema-validator.tsx - │ │ └── dynamic-form-generator.tsx - │ ├── routing/ # NEW: Correspondence routing - │ │ ├── routing-template-manager.tsx - │ │ ├── routing-workflow-visualizer.tsx - │ └── pending-routings-list.tsx - │ └── monitoring/ # NEW: Performance monitoring - │ ├── performance-metrics.tsx - │ ├── real-time-monitor.tsx - │ └── cache-status.tsx - └── layouts/ # Layout components - lib/ - ├── api/ # API client & hooks - ├── stores/ # Zustand stores - ├── utils/ # Utility functions - ├── hooks/ # Custom hooks - ├── types/ # TypeScript types - ├── security/ # NEW: Security utilities - │ ├── file-scanner.ts - │ ├── virus-scan-client.ts - │ └── security-headers.ts - ├── json-schemas/ # NEW: JSON schema management - │ ├── schemas/ - │ ├── validators/ - │ └── transformers/ - └── monitoring/ # NEW: Monitoring utilities - │ ├── performance.ts - │ ├── error-tracking.ts - │ └── metrics-collector.ts - public/ - ├── images/ - └── fonts/ - ``` - ---- - -## 🗓️ แผนการพัฒนาแบบ Phase-Based - -### **Phase 0: Setup & Infrastructure (สัปดาห์ที่ 1)** - -**Milestone:** สร้างโครงสร้างพื้นฐานและ Development Environment - -- **T0.1 Initialize Next.js Project** - - - สร้างโปรเจกต์ด้วย create-next-app: - - ```bash - npx create-next-app@latest lcbp3-frontend --typescript --tailwind --app --src-dir=false - ``` - - - เลือก Options: - - ✅ TypeScript - - ✅ ESLint - - ✅ Tailwind CSS - - ✅ App Router - - ✅ Import alias (@/*) - - Setup .gitignore, README.md - - Deliverable: ✅ โปรเจกต์เริ่มต้นพร้อม - -- **T0.2 Install Core Dependencies** - - ```bash - # State Management & Data Fetching - npm install @tanstack/react-query zustand - npm install axios - npm install react-hook-form @hookform/resolvers zod - - # UI Components & Styling - npm install clsx tailwind-merge - npm install lucide-react - npm install date-fns - - # File Upload - npm install react-dropzone - - # Authentication - npm install next-auth - - # Development Tools - npm install -D @types/node - - # Security & File Processing - npm install clamscan js-file-download - npm install dompurify @types/dompurify - - # JSON Schema & Validation - npm install ajv ajv-formats - npm install jsonpath json-schema-ref-parser - - # Performance Monitoring - npm install web-vitals - npm install @axe-core/react - - # Advanced UI Components - npm install react-json-view-lite - npm install react-window # สำหรับ Virtual Scrolling - ``` - - - Deliverable: ✅ Dependencies ติดตั้งสมบูรณ์ - -- **T0.3 Setup shadcn/ui** - - ```bash - npx shadcn-ui@latest init - ``` - - - เลือก Style: Default - - เลือก Base Color: Slate - - ติดตั้ง Components เบื้องต้น: - - ```bash - npx shadcn-ui@latest add button input label card table dropdown-menu - npx shadcn-ui@latest add dialog sheet toast alert - npx shadcn-ui@latest add form select textarea checkbox - npx shadcn-ui@latest add calendar popover - ``` - - - Deliverable: ✅ shadcn/ui พร้อมใช้งาน - -- **T0.4 Configure Tailwind CSS** - - แก้ไข tailwind.config.ts: - - เพิ่ม Custom Colors (ตาม Brand) - - เพิ่ม Custom Fonts (ภาษาไทย: Noto Sans Thai) - - Configure Container, Spacing - - สร้าง app/globals.css พร้อม Custom Styles - - Deliverable: ✅ Tailwind พร้อมใช้ - -- **T0.5 Setup Development Environment** - - สร้าง .env.local: - - ```yml - NEXT_PUBLIC_API_URL=http://backend.np-dms.work/api - NEXTAUTH_URL=http://localhost:3000 - NEXTAUTH_SECRET=... - ``` - - - Setup ESLint Rules (ไทย Comments OK) - - Setup Prettier - - Setup VS Code Settings - - Deliverable: ✅ Dev Environment พร้อม - -- **T0.6 Setup Git & Docker** - - Push โปรเจกต์ไปยัง Gitea (git.np-dms.work) - - สร้าง Dockerfile สำหรับ Next.js: - - ```dockerfile - FROM node:20-alpine - WORKDIR /app - COPY package*.json ./ - RUN npm ci - COPY . . - RUN npm run build - EXPOSE 3000 - CMD ["npm", "start"] - ``` - - - สร้าง docker-compose.yml (เชื่อม Network `lcbp3`) - - Deliverable: ✅ Project อยู่ใน Git + Docker พร้อม - ---- - -### **Phase 1: Authentication & App Shell (สัปดาห์ที่ 2-3)** - -**Milestone:** ระบบ Login และ Layout หลัก - -- **T1.1 Setup API Client** - - สร้าง lib/api/client.ts: - - ```typescript - import axios from axios; - - export const apiClient = axios.create({ - baseURL: process.env.NEXT_PUBLIC_API_URL, - headers: { - Content-Type: application/json, - }, - }); - - // Request Interceptor (Add JWT Token) - apiClient.interceptors.request.use((config) => { - const token = localStorage.getItem(access_token); - if (token) { - config.headers.Authorization = Bearer ${token}; - } - return config; - }); - - // Response Interceptor (Handle Errors) - apiClient.interceptors.response.use( - (response) => response, - (error) => { - if (error.response?.status === 401) { - // Redirect to login - window.location.href = /login; - } - return Promise.reject(error); - } - ); - ``` - - - Deliverable: ✅ API Client พร้อมใช้ - -- **T1.2 Setup TanStack Query** - -- สร้าง `app/providers.tsx`: - - ```typescript - 'use client'; - import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; - import { useState } from 'react'; - - export function Providers({ children }: { children: React.ReactNode }) { - const [queryClient] = useState(() => new QueryClient({ - defaultOptions: { - queries: { - staleTime: 60 * 1000, // 1 minute - refetchOnWindowFocus: false, - }, - }, - })); - - return ( - - {children} - - ); - } - ``` - -- Wrap ใน `app/layout.tsx` -- Deliverable: ✅ React Query พร้อม - -- **T1.3 Create Auth Store (Zustand)** - -- สร้าง `lib/stores/auth-store.ts`: - - ```typescript - import { create } from 'zustand'; - import { persist } from 'zustand/middleware'; - - interface User { - user_id: number; - username: string; - email: string; - first_name: string; - last_name: string; - primary_organization_id: number; - permissions: string[]; - } - - interface AuthStore { - user: User | null; - token: string | null; - setAuth: (user: User, token: string) => void; - clearAuth: () => void; - hasPermission: (permission: string) => boolean; - } - - export const useAuthStore = create()( - persist( - (set, get) => ({ - user: null, - token: null, - setAuth: (user, token) => { - set({ user, token }); - localStorage.setItem('access_token', token); - }, - clearAuth: () => { - set({ user: null, token: null }); - localStorage.removeItem('access_token'); - }, - hasPermission: (permission) => { - const user = get().user; - return user?.permissions.includes(permission) || false; - }, - }), - { - name: 'auth-storage', - } - ) - ); - ``` - -- Deliverable: ✅ Auth Store พร้อม - -- **T1.4 Create Login Page** - -- สร้าง `app/(public)/login/page.tsx`: - - ```typescript - 'use client'; - import { useForm } from 'react-hook-form'; - import { zodResolver } from '@hookform/resolvers/zod'; - import * as z from 'zod'; - import { Button } from '@/components/ui/button'; - import { Input } from '@/components/ui/input'; - import { useRouter } from 'next/navigation'; - import { useAuthStore } from '@/lib/stores/auth-store'; - import { apiClient } from '@/lib/api/client'; - - const loginSchema = z.object({ - username: z.string().min(1, 'กรุณากรอกชื่อผู้ใช้'), - password: z.string().min(1, 'กรุณากรอกรหัสผ่าน'), - }); - - export default function LoginPage() { - const router = useRouter(); - const setAuth = useAuthStore((state) => state.setAuth); - const form = useForm({ - resolver: zodResolver(loginSchema), - }); - - const handleLogin = async (data: z.infer) => { - try { - const response = await apiClient.post('/auth/login', data); - const { access_token, user } = response.data; - setAuth(user, access_token); - router.push('/dashboard'); - } catch (error) { - console.error('Login failed:', error); - // แสดง Toast Error - } - }; - - return ( -
-
- {/* Form Fields */} -
-
- ); - } - ``` - -- Deliverable: ✅ หน้า Login พร้อม - -- **T1.5 Create Landing Page** - -- สร้าง `app/(public)/page.tsx`: - - Hero Section พร้อมข้อมูลโครงการ - - Feature Highlights - - CTA Button → Login -- ใช้ Tailwind + Animations -- Deliverable: ✅ Landing Page สวยงาม - -- **T1.6 Create Protected Layout (App Shell)** - -- สร้าง `app/(protected)/layout.tsx`: - - ```typescript - 'use client'; - import { useEffect } from 'react'; - import { useRouter } from 'next/navigation'; - import { useAuthStore } from '@/lib/stores/auth-store'; - import Navbar from '@/components/layouts/navbar'; - import Sidebar from '@/components/layouts/sidebar'; - - export default function ProtectedLayout({ children }: { children: React.ReactNode }) { - const router = useRouter(); - const user = useAuthStore((state) => state.user); - - useEffect(() => { - if (!user) { - router.push('/login'); - } - }, [user, router]); - - if (!user) return null; - - return ( -
- -
- -
- {children} -
-
-
- ); - } - ``` - -- Deliverable: ✅ App Shell พร้อม - -- **T1.7 Create Navbar Component** - -- สร้าง `components/layouts/navbar.tsx`: - - แสดงชื่อระบบ - - แสดงชื่อผู้ใช้ + Avatar - - Dropdown Menu: - - Profile - - Settings - - Logout -- Responsive (Mobile Hamburger Menu) -- Deliverable: ✅ Navbar พร้อม - -- **T1.8 Create Sidebar Component** - -- สร้าง `components/layouts/sidebar.tsx`: - - เมนูหลัก: - - Dashboard - - Correspondences - - RFAs - - Drawings (Shop & Contract) - - Circulations - - Transmittals - - Search - - Reports - - เมนู Admin (แสดงตามสิทธิ์): - - Users - - Roles & Permissions - - Master Data - - Document Numbering -- Collapsible Sidebar -- Active State Highlighting -- Deliverable: ✅ Sidebar พร้อม - -- **T1.9 Setup Global Error Handling & Resilience** - - ```typescript - -// สร้าง lib/error-handling/global-error-handler.ts -export class GlobalErrorHandler { - static setup() { - // API Error Interceptors - apiClient.interceptors.response.use( - (response) => response, - (error) => { - this.handleApiError(error); - return Promise.reject(error); - } - ); - - // Frontend Error Boundary - window.addEventListener('error', this.handleWindowError); - window.addEventListener('unhandledrejection', this.handlePromiseRejection); - } - - static handleApiError(error: any) { - // Circuit Breaker Pattern - if (error.response?.status >= 500) { - this.circuitBreaker.recordFailure(); - } - - // User-friendly Error Messages - const userMessage = this.getUserFriendlyMessage(error); - this.showErrorToast(userMessage); - - // Error Reporting - this.reportErrorToService(error); - } -} - - ``` - -T1.10 Setup Security Foundation - - ```typescript -// สร้าง lib/security/security-config.ts -export const SecurityConfig = { - fileUpload: { - allowedTypes: ['pdf', 'dwg', 'docx', 'xlsx', 'zip'], - maxSize: 50 * 1024 * 1024, // 50MB - virusScanRequired: true, - scanTimeout: 30000 // 30 seconds - }, - rateLimiting: { - maxRequests: { - anonymous: 100, - viewer: 500, - editor: 1000, - documentControl: 2000, - admin: 5000 - } - } -}; - ``` - ---- - -### **Phase 2: Dashboard & Common Components (สัปดาห์ที่ 4)** - -**Milestone:** Dashboard และ Reusable Components - -- **T2.1 Create Reusable Components** - -- `components/features/common/data-table.tsx`: - - ใช้ TanStack Table - - รองรับ Pagination, Sorting, Filtering - - Responsive -- `components/features/common/file-upload.tsx`: - - ใช้ React Dropzone - - รองรับ Multi-file Upload - - Drag & Drop - - Progress Bar -- `components/features/common/status-badge.tsx`: - - แสดง Status แบบสีสัน (Draft, Submitted, Approved) -- `components/features/common/permission-guard.tsx`: - - ซ่อน/แสดง Component ตามสิทธิ์ - - -- Deliverable: ✅ Reusable Components พร้อม - -- **T2.2 Create Dashboard Page** - -- สร้าง `app/(protected)/dashboard/page.tsx`: - - **KPI Cards Section**: - - จำนวนเอกสารทั้งหมด - - งานที่รอดำเนินการ - - เอกสารที่เกินกำหนด - - RFA ที่รออนุมัติ - - **My Tasks Table**: - - ดึงข้อมูลจาก `/api/circulations/my-tasks` (ใช้ `v_user_tasks`) - - แสดงรายการงานที่ต้องทำ (Pending, In Progress) - - Columns: Document Number, Title, Type, Status, Deadline, Actions - - คลิกแถวแล้วไปยังหน้า Detail - - **Recent Activity Feed**: - - ดึงข้อมูลจาก `/api/audit-logs/user/:userId` - - แสดง 10 รายการล่าสุด -- Deliverable: ✅ Dashboard ครบถ้วน - -- **T2.3 Create API Hooks** - -- สร้าง `lib/api/hooks/use-my-tasks.ts`: - - ```typescript - import { useQuery } from '@tanstack/react-query'; - import { apiClient } from '../client'; - - export function useMyTasks() { - return useQuery({ - queryKey: ['my-tasks'], - queryFn: async () => { - const response = await apiClient.get('/circulations/my-tasks'); - return response.data; - }, - }); - } - ``` - -- สร้าง Hooks เพิ่มเติม: - - `use-dashboard-stats.ts` - - `use-recent-activity.ts` -- Deliverable: ✅ API Hooks พร้อม - ---- - -### **Phase 3: Correspondence Management (สัปดาห์ที่ 5-6)** - -**Milestone:** ระบบจัดการเอกสารโต้ตอบ - -- **T3.1 Create Correspondence List Page** - -- สร้าง `app/(protected)/correspondences/page.tsx`: - - Data Table แสดงรายการเอกสาร - - Columns: - - Document Number (คลิกไปยัง Detail) - - Title - - Type - - Status (Badge) - - Originator - - Date - - Actions (View, Edit, Delete) - - Filters: - - ประเภทเอกสาร (Dropdown) - - สถานะ (Dropdown) - - วันที่ (Date Range Picker) - - องค์กร (Dropdown) - - Pagination (Server-side) - - Search Box - - Create Button (ตรวจสิทธิ์) -- Deliverable: ✅ หน้ารายการเอกสาร - -- **T3.2 Create Correspondence Detail Page** - -- สร้าง `app/(protected)/correspondences/[id]/page.tsx`: - - **Header Section**: - - Document Number (ใหญ่) - - Status Badge - - Action Buttons: Edit, Delete, Export PDF - - **Metadata Section**: - - Title, Description - - Document Date, Issued Date, Received Date - - Originator, Recipients (TO/CC) - - Due Date (ถ้ามี) - - **Revision History**: - - แสดง Revisions ทั้งหมดเป็น Timeline - - แต่ละ Revision แสดง: Revision Number, Date, Changes, User - - **Attachments**: - - แสดงไฟล์แนบทั้งหมด - - กำหนดไฟล์หลัก (Main Document) ด้วยไอคอน - - ปุ่ม Download - - **References**: - - แสดงเอกสารที่อ้างถึง (Links) - - - **Tags**: - - แสดง Tags แบบ Chips - - **Activity Log**: - - แสดง Audit Log ของเอกสารนี้ -- Deliverable: ✅ หน้า Detail ครบถ้วน - -- **T3.3 Create Correspondence Form (Create/Edit)** - -- สร้าง `app/(protected)/correspondences/create/page.tsx`: -- สร้าง `app/(protected)/correspondences/[id]/edit/page.tsx`: -- Form Fields: - - **Basic Info**: - - Correspondence Type (Dropdown) - - Title (Text) - - Description (Textarea) - - Document Date (Date Picker) - - **Recipients**: - - TO: Multi-select Organizations - - CC: Multi-select Organizations - - **References**: - - Search & Select เอกสารอื่นๆ - - - **Tags**: - - Autocomplete Tag Input - - **Attachments**: - - File Upload (Multi-file) - - กำหนด Main Document (Radio) - - **Deadline**: - - Due Date (Date Picker) -- Validation ด้วย Zod -- Submit → API → Redirect to Detail -- Deliverable: ✅ ฟอร์มสร้าง/แก้ไข - -- **T3.4 Create Status Management** - -- ใน Detail Page เพิ่มปุ่ม Status Actions: - - **Draft → Submit** (Document Control) - - **Submit → Close** (Admin) - - **Submit → Cancel** (Admin + Dialog ให้กรอกเหตุผล) -- แสดง Confirmation Dialog ก่อนเปลี่ยนสถานะ -- Deliverable: ✅ เปลี่ยนสถานะได้ - ---- - -### **Phase 4: RFA & Workflow Visualization (สัปดาห์ที่ 7-8)** - -**Milestone:** ระบบ RFA และ Workflow - -- **T4.1 Create RFA List Page** - -- สร้าง `app/(protected)/rfas/page.tsx`: - - คล้าย Correspondence List - - Columns เพิ่มเติม: - - RFA Type (DWG, DOC, MAT) - - Approval Status (Badge) - - Approval Code (1A, 3R, etc.) - - Filters: - - RFA Type - - Status - - Approval Code -- Deliverable: ✅ หน้ารายการ RFA - -- **T4.2 Create RFA Detail Page** - -- สร้าง `app/(protected)/rfas/[id]/page.tsx`: - - คล้าย Correspondence Detail - - เพิ่ม Section: - - **Shop Drawings** (สำหรับ RFA_DWG): - - แสดงรายการ Shop Drawings ที่เชื่อมโยง - - แสดง Revision ของแต่ละแบบ - - Link ไปยัง Shop Drawing Detail - - **Workflow Visualization** (ดูรายละเอียดใน T4.3) -- Deliverable: ✅ หน้า Detail RFA - -- **T4.3 Create Workflow Visualization Component** - -- สร้าง `components/features/rfa/workflow-visualizer.tsx`: - - **Layout**: Steps แนวนอน (Timeline) - - **Step States**: - - ✅ **Completed**: สีเขียว, ไอคอน Check - - ⏳ **Active**: สีฟ้า, ปุ่ม Action เปิดใช้งาน - - ⏸️ **Pending**: สีเทา, ปุ่ม disabled - - ❌ **Rejected**: สีแดง - - **Step Info Card** (เมื่อคลิก): - - Organization - - Assigned User - - Action Type (Review, Approve) - - Status - - Comments - - Completed Date - - **Actions** (สำหรับ Active Step): - - ปุ่ม "อนุมัติ" (Approve) - - ปุ่ม "ปฏิเสธ" (Reject) - - Dialog ให้กรอก Comments - - **Admin Override**: - - ปุ่ม "ไปยังขั้นตอนต่อไป" (Skip Step) - - ปุ่ม "ย้อนกลับ" (Previous Step) -- Deliverable: ✅ Workflow Component พร้อม - -- **T4.4 Create RFA Form (Create/Edit)** - -- สร้าง `app/(protected)/rfas/create/page.tsx`: -- Form Fields: - - RFA Type (Dropdown) - - Title, Description - - Document Date - - **Shop Drawings Section** (สำหรับ RFA_DWG): - - Search & Select Shop Drawings - - แสดง Revisions ที่มี (Dropdown) - - เพิ่มได้หลายแบบ - - Attachments - - Workflow Template (Dropdown) -- Submit → สร้าง RFA + Start Workflow -- Deliverable: ✅ ฟอร์ม RFA พร้อม - -- **T4.5 Implement Workflow Actions API** - -- สร้าง `lib/api/hooks/use-rfa-workflow.ts`: - - ```typescript - import { useMutation, useQueryClient } from '@tanstack/react-query'; - import { apiClient } from '../client'; - - export function useCompleteWorkflowStep() { - const queryClient = useQueryClient(); - - return useMutation({ - mutationFn: async ({ rfaId, stepNumber, action, comments }) => { - const response = await apiClient.post( - `/rfas/${rfaId}/workflow/steps/${stepNumber}/complete`, - { action, comments } - ); - return response.data; - }, - onSuccess: (_, variables) => { - queryClient.invalidateQueries(['rfa', variables.rfaId]); - queryClient.invalidateQueries(['my-tasks']); - }, - }); - } - ``` - -- Hooks เพิ่มเติม: - - `use-reject-workflow-step.ts` - - `use-start-workflow.ts` -- Deliverable: ✅ Workflow Actions ทำงานได้ - ---- - -### **Phase 5: Drawing Management (สัปดาห์ที่ 9)** - -**Milestone:** ระบบจัดการแบบ - -- **T5.1 Create Shop Drawing List Page** - -- สร้าง `app/(protected)/drawings/shop/page.tsx`: - - Data Table: - - Drawing Number - - Title - - Main Category - - Sub Category - - Current Revision - - Actions - - Filters: - - Category (Dropdown) - - Sub Category (Dropdown) - - Create Button -- Deliverable: ✅ หน้ารายการ Shop Drawings - -- **T5.2 Create Shop Drawing Detail Page** - -- สร้าง `app/(protected)/drawings/shop/[id]/page.tsx`: - - **Header**: Drawing Number, Title - - **Current Revision Info**: - - Revision Number, Date - - Description - - Attachments (PDF, DWG) - - **Contract Drawing References**: - - แสดง Contract Drawings ที่อ้างถึง - - Links ไปยัง Contract Drawing Detail - - **Revision History**: - - แสดง Revisions ทั้งหมดเป็น Timeline - - **Related RFAs**: - - แสดง RFAs ที่เชื่อมโยงกับแบบนี้ -- Deliverable: ✅ หน้า Detail Shop Drawing - -- **T5.3 Create Shop Drawing Form** - -- สร้าง `app/(protected)/drawings/shop/create/page.tsx`: -- Form Fields: - - Drawing Number (Auto-generate หรือ Manual) - - Title - - Main Category (Dropdown) - - Sub Category (Dropdown, dependent on Main) - - **Contract Drawing References**: - - Search & Select Contract Drawings (Multi-select) - - **Revision Info**: - - Revision Number (Auto) - - Revision Label (A, B, C) - - Description - - **Attachments**: - - Upload PDF (Main) - - Upload DWG (Optional) - - Upload Other Files -- Deliverable: ✅ ฟอร์ม Shop Drawing - -- **T5.4 Create Contract Drawing List & Detail** - -- สร้าง `app/(protected)/drawings/contract/page.tsx`: - - Data Table: - - Drawing Number - - Title - - Volume - - Category - - Sub Category - - Filters: - - Volume (Dropdown) - - Category (Dropdown) -- สร้าง `app/(protected)/drawings/contract/[id]/page.tsx`: - - แสดง Metadata - - Attachments - - **Referenced By**: - - แสดง Shop Drawings ที่อ้างถึงแบบนี้ -- Deliverable: ✅ Contract Drawing Pages - ---- - -### **Phase 6: Circulation & Transmittal (สัปดาห์ที่ 10)** - -**Milestone:** ระบบใบเวียนและเอกสารนำส่ง - -- **T6.1 Create Circulation List Page** - -- สร้าง `app/(protected)/circulations/page.tsx`: - - Data Table: - - Circulation Number - - Subject - - Status (Badge) - - Created By - - Created Date - - Filters: - - Status - - Date Range -- Deliverable: ✅ หน้ารายการใบเวียน - -- **T6.2 Create Circulation Detail & Workflow** - -- สร้าง `app/(protected)/circulations/[id]/page.tsx`: - - **Header**: Circulation Number, Subject, Status - - **Linked Correspondence**: - - Link ไปยังเอกสารต้นทาง - - **Workflow Visualization**: - - คล้าย RFA Workflow - - แสดง Steps: - - Organization - - Assigned Users (Main, Action, Information) - - Status - - Comments - - Deadline - - **Actions** (สำหรับ Assigned User): - - ปุ่ม "ดำเนินการเสร็จสิ้น" (Complete) - - Dialog ให้กรอก Comments - - **Close Circulation** (Document Control): - - ปุ่ม "ปิดใบเวียน" (เมื่อตอบกลับองค์กรผู้ส่งแล้ว) -- Deliverable: ✅ หน้า Detail ใบเวียน - -- **T6.3 Create Circulation Form** - -- สร้าง `app/(protected)/circulations/create/page.tsx`: -- Form Fields: - - **Linked Correspondence**: - - Search & Select Correspondence (Required) - - **Subject**: (Text) - - **Workflow Template** (Optional): - - Dropdown เลือก Template ที่มีอยู่ - - หรือสร้างแบบ Custom - - **Assignees Section**: - - **Main** (ผู้รับผิดชอบหลัก): - - Multi-select Users - - กำหนด Deadline (Date Picker) - - **Action** (ผู้ร่วมปฏิบัติงาน): - - Multi-select Users - - กำหนด Deadline - - **Information** (ผู้ที่ต้องรับทราบ): - - Multi-select Users - - ไม่ต้องกำหนด Deadline - - **Attachments** (Optional): - - อัปโหลดไฟล์เพิ่มเติมนอกจากเอกสารต้นทาง -- Submit → สร้าง Circulation + Send Notifications -- Deliverable: ✅ ฟอร์มสร้างใบเวียน - -- **T6.4 Create Circulation Template Management** - -- สร้าง `app/(protected)/admin/circulation-templates/page.tsx`: - - List Templates - - Create/Edit Template - - Template Form Fields: - - Template Name - - Description - - **Steps**: - - Step Number (Auto) - - Organization (Dropdown) - - Role (Dropdown, Optional) - - Duration (Days) - - Is Optional (Checkbox) -- Deliverable: ✅ จัดการ Template ได้ - -- **T6.5 Create Transmittal Pages** - -- สร้าง `app/(protected)/transmittals/page.tsx`: - - Data Table: - - Transmittal Number - - Purpose (Badge) - - TO Organization - - Date - - Item Count -- สร้าง `app/(protected)/transmittals/[id]/page.tsx`: - - Header: Transmittal Number, Purpose - - Metadata: Originator, Recipients, Date, Remarks - - **Items Section**: - - Data Table: - - Document Number (Link) - - Title - - Type - - Quantity - - Remarks -- สร้าง `app/(protected)/transmittals/create/page.tsx`: - - Form Fields: - - Purpose (Dropdown: FOR_APPROVAL, FOR_INFORMATION, FOR_REVIEW) - - TO Organization (Dropdown) - - CC Organizations (Multi-select) - - Remarks (Textarea) - - **Items**: - - Search & Select Correspondences/RFAs (Multi-select) - - กำหนด Quantity และ Remarks ต่อแต่ละรายการ - - Attachments (Cover Letter) -- Deliverable: ✅ ระบบ Transmittal ครบถ้วน - ---- - -### **Phase 7: Search & Reports (สัปดาห์ที่ 11)** - -**Milestone:** ระบบค้นหาและรายงาน - -- **T7.1 Create Advanced Search Page** - -- สร้าง `app/(protected)/search/page.tsx`: - - **Search Filters Panel** (Sidebar): - - Document Type (Checkboxes): - - Correspondence - - RFA - - Shop Drawing - - Contract Drawing - - Circulation - - Transmittal - - Text Search: - - Keyword (Full-text) - - Document Number - - Title - - Date Range: - - From Date (Date Picker) - - To Date (Date Picker) - - Status (Multi-select) - - Organization (Multi-select) - - Tags (Autocomplete Multi-select) - - Project (Dropdown) - - Contract (Dropdown) - - **Search Results Panel** (Main Area): - - Data Table: - - Document Type (Icon + Badge) - - Document Number (Link) - - Title - - Status - - Date - - Organization - - Match Score (จาก Elasticsearch) - - Pagination - - Sort Options (Relevance, Date, Title) - - **Export Results**: - - ปุ่ม "Export to CSV" - - ปุ่ม "Export to Excel" -- Deliverable: ✅ หน้าค้นหาขั้นสูง - -- **T7.2 Create Search API Hooks** - -- สร้าง `lib/api/hooks/use-search.ts`: - - ```typescript - import { useQuery } from '@tanstack/react-query'; - import { apiClient } from '../client'; - - interface SearchFilters { - q?: string; - types?: string[]; - statuses?: string[]; - organizations?: number[]; - tags?: number[]; - from?: string; - to?: string; - page?: number; - pageSize?: number; - } - - export function useSearch(filters: SearchFilters) { - return useQuery({ - queryKey: ['search', filters], - queryFn: async () => { - const response = await apiClient.get('/search', { params: filters }); - return response.data; - }, - enabled: !!filters.q || Object.keys(filters).length > 1, - }); - } - ``` - -- Deliverable: ✅ Search Hooks พร้อม - -- **T7.3 Create Reports Page** - -- สร้าง `app/(protected)/reports/page.tsx`: - - **Report Types** (Tabs): - - **Correspondence Summary**: - - Filter: Project, Date Range, Type - - Chart: Bar Chart (จำนวนเอกสารแยกตามประเภท) - - Table: รายการเอกสารพร้อมสถิติ - - **RFA Summary**: - - Filter: Project, Date Range, Type - - Chart: Pie Chart (สัดส่วนสถานะ) - - Table: รายการ RFA พร้อมสถิติ - - **Activity Report**: - - Filter: User, Date Range - - Timeline: แสดงกิจกรรมตามเวลา - - Table: รายละเอียดกิจกรรม - - **Overdue Report**: - - แสดงเอกสาร/งานที่เกินกำหนด - - Group by: Type, Organization, User - - **Export Options**: - - PDF Report (ใช้ Browser Print) - - Excel Export -- Deliverable: ✅ หน้ารายงาน - -- **T7.4 Integrate Charts (Recharts)** - -```bash -npm install recharts -``` - -- สร้าง Chart Components: - - `components/features/reports/bar-chart.tsx` - - `components/features/reports/pie-chart.tsx` - - `components/features/reports/line-chart.tsx` -- ใช้ใน Reports Page -- Deliverable: ✅ Charts พร้อมใช้ - ---- - -### **Phase 8: Admin Panel (สัปดาห์ที่ 12-13)** - -**Milestone:** ระบบจัดการสำหรับ Admin - -- **T8.1 Create User Management Pages** - -- สร้าง `app/(protected)/admin/users/page.tsx`: - - **Permission Guard**: ตรวจสอบสิทธิ์ `users.view` - - Data Table: - - Username - - Name - - Email - - Organization - - Roles (Badges) - - Status (Active/Inactive) - - Actions (Edit, Deactivate, Reset Password) - - Filters: - - Organization - - Role - - Status - - Create User Button -- สร้าง `app/(protected)/admin/users/create/page.tsx`: - - Form Fields: - - Username (Text, Unique) - - Email (Email, Unique) - - Password (Password) - - First Name, Last Name (Text) - - Line ID (Text, Optional) - - Primary Organization (Dropdown) - - **Global Role** (Dropdown, Optional) - - **Project Roles** (Multi-select): - - เลือก Project + Role - - **Contract Roles** (Multi-select): - - เลือก Contract + Role -- สร้าง `app/(protected)/admin/users/[id]/edit/page.tsx`: - - คล้าย Create Form - - เพิ่ม: Deactivate Button, Reset Password Button -- Deliverable: ✅ จัดการผู้ใช้ได้ - -- **T8.2 Create Role & Permission Management** - -- สร้าง `app/(protected)/admin/roles/page.tsx`: - - **Permission Guard**: `roles.view` - - List Roles (Cards): - - Role Name - - Scope (Global, Organization, Project, Contract) - - Permission Count - - Edit Button -- สร้าง `app/(protected)/admin/roles/[id]/edit/page.tsx`: - - Form Fields: - - Role Name (Text) - - Scope (Radio: Global, Organization, Project, Contract) - - Description (Textarea) - - **Permissions** (Grouped Checkboxes): - - Group by Module: - - System Management - - User Management - - Project Management - - Document Management - - Workflow Management - - Search & Reporting - - แต่ละ Permission มี Checkbox + Description -- Deliverable: ✅ จัดการ Roles และ Permissions ได้ - -- **T8.3 Create Master Data Management** - -- สร้าง `app/(protected)/admin/master-data/page.tsx`: - - - **Tabs**: - - **Correspondence Types**: - - List + Create/Edit Form - - Fields: Type Code, Type Name, Sort Order - - **RFA Types**: - - List + Create/Edit Form - - **Status Codes**: - - List + Create/Edit Form - - - **Tags**: - - List + Create/Edit Form - - **Drawing Categories**: - - List + Create/Edit Form (Main & Sub Categories) -- Deliverable: ✅ จัดการ Master Data ได้ - -- **T8.4 Create Document Numbering Management** - -- สร้าง `app/(protected)/admin/document-numbering/page.tsx`: - - **Document Number Formats Section**: - - Data Table: - - Project - - Document Type - - Format Template - - Example - - Actions (Edit, Delete) - - Create Format Button - - **Create/Edit Format Form**: - - Project (Dropdown) - - Document Type (Dropdown) - - Format Template (Text): - - แสดง Available Placeholders: - - `{ORG_CODE}` - รหัสองค์กร - - `{TYPE_CODE}` - รหัสประเภทเอกสาร - - `{YEAR}` - ปี พ.ศ. 4 หลัก - - `{YEAR_SHORT}` - ปี พ.ศ. 2 หลัก - - `{SEQ:n}` - เลขลำดับ (n = จำนวนหลัก) - - Live Preview: แสดงตัวอย่างเลขที่จากรูปแบบที่กรอก - - Description (Textarea) - - **Current Counters Section** (Read-only): - - Data Table: - - Project - - Organization - - Document Type - - Year - - Last Number -- Deliverable: ✅ จัดการ Document Numbering ได้ - -- **T8.5 Create Organization Onboarding Workflow** - -- สร้าง `app/(protected)/admin/organizations/page.tsx`: - - **Permission Guard**: `organizations.manage` (Superadmin only) - - List Organizations: - - Organization Code - - Organization Name - - Status - - Org Admin (ชื่อ) - - Actions - - Create Organization Button -- สร้าง `app/(protected)/admin/organizations/create/page.tsx`: - - **Step 1: Organization Info**: - - Organization Code (Text, Unique) - - Organization Name (Text) - - Description (Textarea) - - **Step 2: Appoint Org Admin**: - - Search & Select User - - หรือ Create New User - - Assign Role: "Org Admin" - - **Step 3: Confirmation**: - - แสดงสรุปข้อมูล - - Submit → สร้างองค์กรและ Assign Admin -- Deliverable: ✅ Superadmin สามารถ Onboard องค์กรใหม่ได้ - -- **T8.6 Create Project & Contract Management** - -- สร้าง `app/(protected)/admin/projects/page.tsx`: - - **Permission Guard**: `projects.view` - - List Projects - - Create/Edit Project - - **Project Detail Page**: - - Metadata - - **Participating Organizations** (Multi-select) - - **Contracts Section**: - - List Contracts ในโครงการนี้ - - Create Contract Button - - **Members Section**: - - List Users ในโครงการ - - Assign User to Project Button - - กำหนด Project Role -- สร้าง `app/(protected)/admin/contracts/[id]/page.tsx`: - - Contract Info - - **Contract Organizations**: - - Organization + Role in Contract (Owner, Designer, Contractor) - - **Members Section**: - - Assign User to Contract - - กำหนด Contract Role -- Deliverable: ✅ จัดการ Projects และ Contracts ได้ - ---- - -### **Phase 9: User Profile & Settings (สัปดาห์ที่ 14)** - -**Milestone:** หน้าโปรไฟล์และการตั้งค่า - -- **T9.1 Create Profile Page** - -- สร้าง `app/(protected)/profile/page.tsx`: - - **User Info Section**: - - Avatar (Upload รูปภาพ) - - Username (Read-only) - - Email (Editable) - - First Name, Last Name (Editable) - - Line ID (Editable) - - Primary Organization (Read-only) - - **My Roles Section**: - - แสดง Roles ทั้งหมดที่ได้รับ: - - Global Role - - Organization Roles - - Project Roles - - Contract Roles - - แสดงเป็น Cards พร้อม Scope และ Permissions - - **Change Password Section**: - - Current Password (Password) - - New Password (Password) - - Confirm Password (Password) - - Submit Button - - **Notification Settings**: - - Email Notifications (Toggle) - - Line Notifications (Toggle) - - ประเภทการแจ้งเตือน (Checkboxes): - - New Document Received - - Task Assigned - - Document Approved/Rejected - - Approaching Deadline -- Deliverable: ✅ หน้า Profile พร้อม - -- **T9.2 Create Settings Page** (Optional) - -- สร้าง `app/(protected)/settings/page.tsx`: - - **Display Preferences**: - - Language (ไทย/English) - Future - - Date Format (DD/MM/YYYY, MM/DD/YYYY) - - Time Zone (Auto-detect) - - - **Table Preferences**: - - Default Page Size (10, 20, 50) - - Default Sort Order - - **Export Preferences**: - - Default Export Format (CSV, Excel) -- Deliverable: ✅ หน้า Settings พร้อม - ---- - -### **Phase 10: Testing & Optimization (สัปดาห์ที่ 15-16)** - -**Milestone:** ทดสอบและปรับปรุงประสิทธิภาพ - -- **T10.1 Setup Testing Environment** - -- ติดตั้ง Testing Libraries: - - ```bash - npm install -D vitest @testing-library/react @testing-library/jest-dom - npm install -D @testing-library/user-event - npm install -D msw - npm install -D @playwright/test - ``` - -- สร้าง `vitest.config.ts` -- สร้าง `playwright.config.ts` -- Setup MSW Handlers: `lib/mocks/handlers.ts` -- Deliverable: ✅ Testing Setup พร้อม - -- **T10.2 Unit Testing** - -- เขียน Unit Tests สำหรับ: - - **Utilities**: `lib/utils/*.ts` - - **Hooks**: `lib/api/hooks/*.ts` - - **Components**: - - `components/features/common/data-table.test.tsx` - - `components/features/common/file-upload.test.tsx` - - `components/features/common/status-badge.test.tsx` -- Target: 70% Code Coverage -- Deliverable: ✅ Unit Tests ผ่านทั้งหมด - -- **T10.3 Integration Testing** - -- เขียน Integration Tests สำหรับ: - - **Authentication Flow**: - - Login → Dashboard → Logout - - **Correspondence Flow**: - - List → Create → Detail → Edit - - **RFA Workflow**: - - Create RFA → Start Workflow → Complete Step - - **Circulation Flow**: - - Create → Assign → Complete → Close -- ใช้ MSW เพื่อ Mock API Responses -- Deliverable: ✅ Integration Tests ผ่าน - -- **T10.4 E2E Testing (Playwright)** - -- เขียน E2E Tests สำหรับ Critical User Flows: - - **User Registration & Login** - - **Create Correspondence (Full Flow)**: - - Fill Form → Upload Files → Submit → Verify in List - - **Create RFA with Shop Drawings**: - - Select Drawings → Fill Form → Start Workflow → Verify Status - - **Complete RFA Workflow**: - - Login as Reviewer → Go to RFA → Complete Step → Verify Next Step - - **Search Documents**: - - Enter Query → Verify Results → Click Result → Verify Detail -- Deliverable: ✅ E2E Tests ผ่าน - -- **T10.5 Performance Optimization** - -- **Code Splitting**: - - ใช้ Dynamic Imports สำหรับ Heavy Components - - Example: - - ```typescript - const RfaWorkflowVisualizer = dynamic( - () => import('@/components/features/rfa/workflow-visualizer'), - { loading: () => } - ); - ``` - -- **Image Optimization**: - - ใช้ Next.js `` Component - - Setup Image CDN (ถ้ามี) -- **Data Fetching Optimization**: - - ใช้ `prefetchQuery` สำหรับ Critical Data - - Implement Infinite Scroll สำหรับ Long Lists -- **Bundle Size Analysis**: - - ```bash - npm run build - npx @next/bundle-analyzer - ``` - - - ลบ Dependencies ที่ไม่ใช้ - - Tree Shaking -- Deliverable: ✅ Performance Metrics ดีขึ้น - -- **T10.6 Accessibility (a11y) Testing** - -- ติดตั้ง `@axe-core/react` -- รัน axe DevTools ในหน้าสำคัญ -- แก้ไข Issues: - - Missing alt text - - Low contrast ratios - - Missing ARIA labels - - Keyboard navigation -- Target: Zero Critical/Serious Issues -- Deliverable: ✅ Accessibility Checklist ผ่าน - -- **T10.7 Responsive Design Testing** - -- ทดสอบบนอุปกรณ์ต่างๆ: - - Desktop (1920x1080, 1366x768) - - Tablet (768x1024) - - Mobile (375x667, 414x896) -- แก้ไข Layout Issues: - - Sidebar Collapse บน Mobile - - Table Horizontal Scroll - - Form Layout -- Deliverable: ✅ Responsive บนทุกอุปกรณ์ - -- **T10.8 Security Hardening** - -- **Input Sanitization**: - - ตรวจสอบ XSS ใน User Inputs - - ใช้ DOMPurify สำหรับ Rich Text (ถ้ามี) -- **CSRF Protection**: - - Verify NextAuth CSRF Tokens -- **Content Security Policy**: - - Setup CSP Headers ใน `next.config.js` -- **API Security**: - - ตรวจสอบว่า Token ถูกส่งใน Headers ถูกต้อง - - Handle 401/403 Errors properly -- Deliverable: ✅ Security Checklist ผ่าน - ---- - -### **Phase 11: Documentation & Deployment (สัปดาห์ที่ 17)** - -**Milestone:** เอกสารและ Deploy สู่ Production - -- **T11.1 Component Documentation (Storybook)** (Optional) - -- ติดตั้ง Storybook: - - ```bash - npx storybook@latest init - ``` - -- เขียน Stories สำหรับ Reusable Components: - - Button, Input, Card, Table - - FileUpload, StatusBadge, PermissionGuard - - WorkflowVisualizer -- Deliverable: ✅ Storybook พร้อม - -- **T11.2 User Documentation** - -- เขียนคู่มือผู้ใช้งาน (ภาษาไทย): - - **Getting Started**: - - วิธีล็อกอิน - - ภาพรวม Dashboard - - **Correspondence Management**: - - วิธีสร้างเอกสาร - - วิธีแก้ไขและเปลี่ยนสถานะ - - วิธีค้นหาเอกสาร - - **RFA Workflow**: - - วิธีสร้าง RFA - - วิธีตรวจสอบและอนุมัติ - - วิธีติดตาม Workflow - - **Circulation**: - - วิธีสร้างใบเวียน - - วิธีดำเนินการตามใบเวียน - - **Drawing Management**: - - วิธีอัปโหลดแบบ - - วิธีเชื่อมโยงแบบ - - **Admin Functions**: - - วิธีจัดการผู้ใช้ - - วิธีกำหนดสิทธิ์ - - วิธีจัดการ Master Data -- Format: PDF + Online (ใน `/docs` Route) -- Deliverable: ✅ User Guide พร้อม - -- **T11.3 Developer Documentation** - -- เขียนเอกสารทางเทคนิค: - - **Architecture Overview**: - - Tech Stack - - Folder Structure - - State Management Strategy - - **Component Guidelines**: - - Naming Conventions - - Props Interface Design - - Styling Best Practices - - **API Integration**: - - API Client Setup - - React Query Usage - - Error Handling - - - **Testing Guidelines**: - - Unit Test Examples - - Integration Test Examples - - E2E Test Examples - - **Deployment Guide**: - - Build Process - - Environment Variables - - Docker Configuration -- Format: Markdown (ใน `/docs` Folder) -- Deliverable: ✅ Dev Docs พร้อม - -- **T11.4 Deployment Preparation** - -- **Production Build**: - - ```bash - npm run build - ``` - - - ตรวจสอบ Build Output - - แก้ไข Build Errors/Warnings -- **Environment Variables**: - - สร้างไฟล์ `.env.production` - - กำหนดค่าใน docker-compose.yml: - - ```yaml - environment: - - NEXT_PUBLIC_API_URL=https://backend.np-dms.work/api - - NEXTAUTH_URL=https://lcbp3.np-dms.work - - NEXTAUTH_SECRET=${NEXTAUTH_SECRET} - ``` - -- **Docker Image**: - - Build Image: - - ```bash - docker build -t lcbp3-frontend:v1.0.0 . - ``` - - - Test Image Locally -- Deliverable: ✅ Production Build พร้อม - -- **T11.5 Deploy to QNAP** - -- **Upload Image to QNAP**: - - Export Image: - - ```bash - docker save lcbp3-frontend:v1.0.0 > frontend.tar - ``` - - - Upload ผ่าน QNAP File Station - - Import ใน Container Station -- **Update docker-compose.yml** บน QNAP: - - ```yaml - services: - frontend: - image: lcbp3-frontend:v1.0.0 - container_name: frontend - networks: - - lcbp3 - environment: - - NEXT_PUBLIC_API_URL=https://backend.np-dms.work/api - - NEXTAUTH_URL=https://lcbp3.np-dms.work - - NEXTAUTH_SECRET=${NEXTAUTH_SECRET} - restart: unless-stopped - ``` - -- **Start Container**: - - รันผ่าน Container Station UI - - ตรวจสอบ Logs -- Deliverable: ✅ Frontend รันบน Production - -- **T11.6 Configure Nginx Proxy Manager** - -- เพิ่ม Proxy Host ใหม่: - - Domain: `lcbp3.np-dms.work` - - Forward to: `frontend:3000` - - Enable Websocket Support - - Enable SSL (Let's Encrypt) - - Force HTTPS -- ทดสอบเข้าถึงผ่าน HTTPS -- Deliverable: ✅ HTTPS พร้อมใช้ - -- **T11.7 Monitoring & Health Check** - -- สร้าง Health Check Endpoint (ถ้า Backend ยังไม่มี): - - ```typescript - // app/api/health/route.ts - export async function GET() { - return Response.json({ status: 'ok', timestamp: new Date().toISOString() }); - } - ``` - -- Setup Monitoring: - - QNAP Container Resource Monitor - - Log Aggregation (ถ้ามี) -- Deliverable: ✅ Monitoring Setup - -- **T11.8 User Acceptance Testing (UAT)** - -- เตรียม UAT Checklist: - - ✅ ล็อกอินได้ทุก Role - - ✅ สร้าง Correspondence ได้ - - ✅ สร้าง RFA และ Start Workflow ได้ - - ✅ Workflow อนุมัติได้ถูกต้อง - - ✅ สร้าง Circulation และมอบหมายงานได้ - - ✅ อัปโหลดไฟล์ได้ - - ✅ ค้นหาเอกสารได้ - - ✅ สร้างรายงานได้ - - ✅ Admin จัดการผู้ใช้และสิทธิ์ได้ -- เชิญ Stakeholders ทดสอบ -- เก็บ Feedback -- แก้ไข Bugs/Issues -- Deliverable: ✅ UAT ผ่าน - -- **T11.9 Training & Handover** - -- จัด Workshop สำหรับผู้ใช้งาน: - - **Session 1: Basic Users** (2 ชม.): - - วิธีใช้ Dashboard - - วิธีสร้างและจัดการเอกสาร - - วิธีตอบกลับ Circulation - - **Session 2: Document Control** (2 ชม.): - - วิธีจัดการเอกสารขั้นสูง - - วิธีควบคุม Workflow - - วิธีดู Reports - - **Session 3: Admin** (2 ชม.): - - วิธีจัดการผู้ใช้และสิทธิ์ - - วิธีจัดการ Master Data - - วิธีตั้งค่า Document Numbering -- บันทึก Video Training (Optional) -- Deliverable: ✅ Users ใช้งานเป็น - ---- - -## 📊 สรุป Timeline - -| Phase | ระยะเวลา | จำนวนงาน | Output หลัก | -| -------- | ------------ | ------------ | ----------------------------- | -| Phase 0 | 1 สัปดาห์ | 6 | Infrastructure Ready | -| Phase 1 | 2 สัปดาห์ | 8 | Auth & App Shell | -| Phase 2 | 1 สัปดาห์ | 3 | Dashboard & Components | -| Phase 3 | 2 สัปดาห์ | 4 | Correspondence Management | -| Phase 4 | 2 สัปดาห์ | 5 | RFA & Workflow | -| Phase 5 | 1 สัปดาห์ | 4 | Drawing Management | -| Phase 6 | 1 สัปดาห์ | 5 | Circulation & Transmittal | -| Phase 7 | 1 สัปดาห์ | 4 | Search & Reports | -| Phase 8 | 2 สัปดาห์ | 6 | Admin Panel | -| Phase 9 | 1 สัปดาห์ | 2 | Profile & Settings | -| Phase 10 | 2 สัปดาห์ | 8 | Testing & Optimization | -| Phase 11 | 1 สัปดาห์ | 9 | Documentation & Deploy | -| **รวม** | **17 สัปดาห์** | **64 Tasks** | **Production-Ready Frontend** | - ---- - -## 🎯 Critical Success Factors - -1. **API Contract**: รอ Backend Swagger Documentation ก่อนเริ่ม Phase 3 -2. **Design System**: สร้าง Design System ใน Figma ก่อนเริ่ม Phase 1 -3. **Component Library**: สร้าง Reusable Components ให้ครบใน Phase 2 ก่อนไปต่ - -## 🎯 Critical Success Factors (ต่อ) - -4. **Mobile-First Approach**: ออกแบบ Mobile ก่อน แล้วค่อย Scale up เป็น Desktop -5. **Accessibility**: ทดสอบ Keyboard Navigation และ Screen Reader ทุก Phase -6. **Performance Budget**: - - Initial Load < 3s - - Time to Interactive < 5s - - Bundle Size < 500KB (gzipped) -7. **User Feedback Loop**: ทำ Usability Testing ทุก 2 สัปดาห์ -8. **Code Quality**: Code Review ทุก PR, ห้าม Merge โดยไม่มี Tests - ---- - -## 🔄 Dependencies & Integration Points - -### Backend Dependencies (Critical Path) - -| Frontend Feature | Required Backend API | Blocker Phase | -| ------------------- | --------------------------------- | ------------- | -| Login | `POST /auth/login` | Phase 1 | -| Dashboard | `GET /api/circulations/my-tasks` | Phase 2 | -| Correspondence CRUD | `/api/correspondences/*` | Phase 3 | -| RFA Workflow | `/api/rfas/*/workflow/*` | Phase 4 | -| Drawing Management | `/api/drawings/*` | Phase 5 | -| Circulation | `/api/circulations/*` | Phase 6 | -| Search | `GET /api/search` (Elasticsearch) | Phase 7 | -| Reports | `/api/reports/*` | Phase 7 | -| User Management | `/api/users/*`, `/api/roles/*` | Phase 8 | - -**รอเอกสาร Swagger ให้ครบก่อน Phase 3** เพื่อหลีกเลี่ยงการแก้ไขซ้ำ - ---- - -## 🛠️ Development Workflow - -### Daily Routine - -``` -09:00-09:15 Daily Standup (อะไรทำเสร็จ, จะทำอะไร, มีอุปสรรคอะไร) -09:15-12:00 Development (Focus Time) -12:00-13:00 Lunch -13:00-16:00 Development + Code Review -16:00-16:30 Testing (Manual + Automated) -16:30-17:00 Documentation + Git Commit -``` - -### Git Workflow - -```bash -# Feature Branch Strategy -git checkout -g develop -git pull origin develop -git checkout -b feature/T3.1-correspondence-list - -# Work on Feature... -git add . -git commit -m "feat(correspondence): implement list page with filters - -- Add DataTable component -- Implement server-side pagination -- Add filters for type, status, date range -- Add search functionality - -Closes #T3.1" - -# Push และสร้าง Pull Request -git push origin feature/T3.1-correspondence-list -``` - -### Commit Message Convention - -``` -(): - - - -