Files
lcbp3/docs/Markdown/4_Data_Dictionary_V1_4_3.md
admin aaa5da3ec1
Some checks failed
Spec Validation / validate-markdown (push) Has been cancelled
Spec Validation / validate-diagrams (push) Has been cancelled
Spec Validation / check-todos (push) Has been cancelled
251217:1704 Docunment Number: Update to 1.6.2
2025-12-17 17:04:06 +07:00

127 KiB

ตารางฐานข้อมูล (Data Dictionary) - LCBP3-DMS (V1.4.3)

เอกสารนี้สรุปโครงสร้างตาราง, Foreign Keys (FK), และ Constraints ที่สำคัญทั้งหมดในฐานข้อมูล LCBP3-DMS (v1.4) เพื่อใช้เป็นเอกสารอ้างอิงสำหรับทีมพัฒนา Backend (NestJS) และ Frontend (Next.js) โดยอิงจาก Requirements และ SQL Script ล่าสุด [GEMINI]

สถานะ: FINAL GUIDELINE วันที่: 2025-11-19 อ้างอิง: Requirements v1.4.2 & FullStackJS Guidelines v1.4.2 Classification: Internal Technical Documentation


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
deleted_at DATETIME NULL Deleted at

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
v_ref_project_id INT GENERATED ALWAYS AS (...) VIRTUAL Virtual Column ดึง Project ID จาก JSON details เพื่อทำ Index
v_ref_type VARCHAR(50) GENERATED ALWAYS AS (...) VIRTUAL Virtual Column ดึง Type จาก JSON details

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)
  • INDEX (v_ref_project_id)
  • INDEX (v_ref_type)

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 สถานะใช้งาน
workflow_config JSON NULL เก็บ State Machine Configuration หรือ Rules เพิ่มเติมที่ซับซ้อนกว่า Column ปกติ

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 เวลาที่สร้างรายการส่งต่อนี้
state_context JSON NULL เก็บข้อมูล Context ของ Workflow ณ ขณะนั้น (Snapshot)

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
workflow_config JSON NULL เก็บ State Machine Configuration หรือ Rules เพิ่มเติมที่ซับซ้อนกว่า Column ปกติ

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
state_context JSON* NULL เก็บข้อมูล Context ของ Workflow ณ ขณะนั้น (Snapshot)

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
is_temporary BOOLEAN DEFAULT TRUE ระบุว่าเป็นไฟล์ชั่วคราว (ยังไม่ได้ Commit)
temp_id* VARCHAR(100) NULL ID ชั่วคราวสำหรับอ้างอิงตอน Upload Phase 1 (อาจใช้ร่วมกับ id หรือแยกก็ได้)
expires_at DATETIME NULL เวลาหมดอายุของไฟล์ Temp (เพื่อให้ Cron Job ลบออก)
checksum VARCHAR(64) NULL SHA-256 Checksum สำหรับ Verify File Integrity [Req 3.9.3]

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)
version INT DEFAULT 0 ใช้สำหรับ Optimistic Locking (ตรวจสอบค่าก่อน Update)
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 DocumentNumberingService in NestJS using Redis Lock and Optimistic Locking on version column
  • 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
v_ref_project_id INT GENERATED ALWAYS AS (...) VIRTUAL Virtual Column ดึง Project ID จาก JSON details เพื่อทำ Index
v_ref_type VARCHAR(50) GENERATED ALWAYS AS (...) VIRTUAL Virtual Column ดึง Type จาก JSON details
request_id VARCHAR(100) NULL Request ID/Trace ID เพื่อเชื่อมโยงกับ App Logs
severity ENUM('INFO', 'WARN', 'ERROR', 'CRITICAL') NULL ระดับความรุนแรงของเหตุการณ์

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)
  • INDEX (v_ref_project_id)
  • INDEX (v_ref_type)

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

10.5 json_schemas

Purpose: องรับ Centralized JSON Schema Registry เพื่อ Validate ข้อมูล JSON Details ของเอกสารแต่ละประเภท ตาม Requirements 6.11.1 และ Backend Plan T2.5.1

Column Name Data Type Constraints Description
id INT PK, AI Unique Identifier
schema_code VARCHAR(100) UNIQUE, NOT NULL รหัส Schema (เช่น RFA_DWG_V1, CORR_RFI_V1)
version INT NOT NULL เวอร์ชันของ Schema
schema_definition JSON NOT NULL โครงสร้าง JSON Schema (Standard JSON Schema format)
is_active BOOLEAN DEFAULT TRUE สถานะการใช้งาน
created_at TIMESTAMP วันที่สร้าง

10.6 user_preferences

Purpose: แยกข้อมูลการตั้งค่าส่วนตัว (เช่น Notification Settings) ออกจากตาราง Users เพื่อความยืดหยุ่น ตาม Requirements 5.5 และ 6.8.3

Column Name Data Type Constraints Description
user_id INT PK, FK อ้างอิงตาราง users
notify_email BOOLEAN DEFAULT TRUE รับแจ้งเตือนทางอีเมล
notify_line BOOLEAN DEFAULT TRUE รับแจ้งเตือนทาง LINE
digest_mode BOOLEAN DEFAULT TRUE รับแจ้งเตือนแบบรวม (Digest) แทน Real-time
ui_theme VARCHAR(20) DEFAULT 'light' ธีมหน้าจอ (Light/Dark)
updated_at TIMESTAMP วันที่แก้ไขล่าสุด

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:

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

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

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:

/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

-- 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 DocumentNumberingService.generateNextNumber() (NestJS) which handles Redis locking and retry logic
    • 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

-- 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 v1.4.3
  • Version: 1.4
  • Date: 2025-11-22
  • Author: NAP LCBP3-DMS & Gemini
  • Status: FINAL
  • Classification: Internal Technical Documentation
  • Approved By: Nattanin

End of Data Dictionary v1.4.3 (ฉบับปรับปรุง)