Files
lcbp3/docs/4_Data_Dictionary_V1_5_1.md
2025-12-04 16:50:09 +07:00

90 KiB

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

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

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

📝 สรุปรายการปรับปรุง (Summary of Changes in v1.5.1)

  1. Enhanced Document Numbering: ปรับปรุงตาราง document_number_counters ให้รองรับ 8-column Composite PK และเพิ่มตาราง document_number_audit, document_number_errors
  2. Unified Workflow Engine: เพิ่มตาราง workflow_definitions, workflow_instances, workflow_histories เพื่อรองรับ Workflow แบบ Dynamic
  3. New Master Tables: เพิ่มตาราง disciplines และ correspondence_sub_types ตาม Req 6B
  4. System Enhancements: เพิ่มตาราง json_schemas และ user_preferences
  5. Schema Updates: เพิ่ม discipline_id ในตาราง correspondences และ rfas

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

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

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

1.5 disciplines (NEW v1.5.1)

Purpose: เก็บข้อมูลสาขางาน (Disciplines) แยกตามสัญญา (Req 6B)

Column Name Data Type Constraints Description
id INT PK, AI Unique identifier
contract_id INT FK, NOT NULL ผูกกับสัญญา
discipline_code VARCHAR(10) NOT NULL รหัสสาขา (เช่น GEN, STR)
code_name_th VARCHAR(255) NULL ชื่อไทย
code_name_en VARCHAR(255) NULL ชื่ออังกฤษ
is_active TINYINT(1) DEFAULT 1 สถานะการใช้งาน

Indexes:

  • UNIQUE (contract_id, discipline_code)

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

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

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

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

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)

Relationships:

  • Parent: users, roles, organizations, projects, contracts

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

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

2.8 user_preferences (NEW v1.5.1)

Purpose: เก็บการตั้งค่าส่วนตัวของผู้ใช้ (Req 5.5, 6.8.3)

Column Name Data Type Constraints Description
user_id INT PK, FK User ID
notify_email BOOLEAN DEFAULT TRUE รับอีเมลแจ้งเตือน
notify_line BOOLEAN DEFAULT TRUE รับไลน์แจ้งเตือน
digest_mode BOOLEAN DEFAULT FALSE รับแจ้งเตือนแบบรวม
ui_theme VARCHAR(20) DEFAULT 'light' UI Theme

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

3.2 correspondence_sub_types (NEW v1.5.1)

Purpose: เก็บประเภทหนังสือย่อย (Sub Types) สำหรับ Mapping เลขรหัส (Req 6B)

Column Name Data Type Constraints Description
id INT PK, AI Unique identifier
contract_id INT FK, NOT NULL ผูกกับสัญญา
correspondence_type_id INT FK, NOT NULL ผูกกับประเภทเอกสารหลัก
sub_type_code VARCHAR(20) NOT NULL รหัสย่อย (เช่น MAT, SHP)
sub_type_name VARCHAR(255) NULL ชื่อประเภทหนังสือย่อย
sub_type_number VARCHAR(10) NULL เลขรหัสสำหรับ Running Number

3.3 correspondences (UPDATE v1.5.1)

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
discipline_id INT NULL, FK [NEW] สาขางาน (ถ้ามี)
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 (discipline_id) REFERENCES disciplines(id) ON DELETE SET NULL
  • 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, disciplines, projects, organizations, users
  • Children: correspondence_revisions, correspondence_recipients, correspondence_tags, correspondence_references, correspondence_attachments, circulations, transmittals

3.4 correspondence_revisions (UPDATE v1.5.1)

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
v_doc_subtype VARCHAR(50) GENERATED ALWAYS AS (...) VIRTUAL Virtual Column ดึง Type จาก JSON details
schema_version INT DEFAULT 1 Version of the schema used with this 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)
  • INDEX (correspondence_status_id)
  • INDEX (is_current)
  • INDEX (document_date)
  • INDEX (issued_date)
  • INDEX (v_ref_project_id)
  • INDEX (v_ref_type)
  • INDEX (v_doc_subtype)

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

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)

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

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

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

4.4 rfas (UPDATE v1.5.1)

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
discipline_id INT NULL, FK [NEW] สาขางาน (ถ้ามี)
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 (discipline_id) REFERENCES disciplines(id) ON DELETE SET NULL
  • FOREIGN KEY (created_by) REFERENCES users(user_id) ON DELETE SET NULL
  • INDEX (rfa_type_id)
  • INDEX (deleted_at)

Relationships:

  • Parent: rfa_types, disciplines, users
  • Children: rfa_revisions

4.5 rfa_revisions (UPDATE v1.5.1)

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
details JSON NULL Type-specific details (e.g., RFI questions)
v_ref_drawing_count INT GENERATED ALWAYS AS (...) VIRTUAL Virtual Column ดึง Drawing Count จาก JSON details เพื่อทำ Index
schema_version INT DEFAULT 1 Version of the schema used with this details

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)
  • INDEX (v_ref_drawing_count): ตัวอย่างการ Index ข้อมูลตัวเลขใน JSON

Relationships:

  • Parent: correspondences, rfas, rfa_status_codes, rfa_approve_codes, users
  • Children: rfa_items, rfa_workflows

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_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

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 System Tables (ระบบเลขที่เอกสาร)

9.1 document_number_formats

Purpose: Master table defining numbering formats for each document 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_string VARCHAR(100) NOT NULL Format pattern (e.g., {ORG}-{TYPE}-{YYYY}-#)
description TEXT NULL Format description
is_active TINYINT(1) DEFAULT 1 Active status

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 (is_active)

Relationships:

  • Parent: projects, correspondence_types

Business Rules:

  • Defines how document numbers are constructed
  • Supports placeholders: {PROJ}, {ORG}, {TYPE}, {YYYY}, {MM}, {#}

9.2 document_number_counters (UPDATE v1.5.1)

Purpose: Transaction table tracking running numbers (High Concurrency)

Column Name Data Type Constraints Description
project_id INT PK, NOT NULL โครงการ
originator_organization_id INT PK, NOT NULL องค์กรผู้ส่ง
recipient_organization_id INT PK, NOT NULL [NEW] องค์กรผู้รับ (-1 = ทุกองค์กร)
correspondence_type_id INT PK, NOT NULL ประเภทเอกสาร
sub_type_id INT PK, DEFAULT 0 [NEW] ประเภทย่อย สำหรับ TRANSMITTAL (0 = ไม่ระบุ)
rfa_type_id INT PK, DEFAULT 0 [NEW] ประเภท RFA (0 = ไม่ใช่ RFA)
discipline_id INT PK, DEFAULT 0 [NEW] สาขางาน (0 = ไม่ระบุ)
current_year INT PK, NOT NULL ปี ค.ศ. ของตัวนับ (auto-reset ทุกปี)
last_number INT DEFAULT 0 เลขล่าสุดที่ถูกใช้งานไปแล้ว
updated_at TIMESTAMP ON UPDATE เวลาที่อัปเดตล่าสุด

Indexes:

  • PRIMARY KEY (project_id, originator_organization_id, recipient_organization_id, correspondence_type_id, sub_type_id, rfa_type_id, discipline_id, current_year)

Business Rules:

  • Composite Primary Key 8 Columns: เพื่อรองรับการรันเลขที่ซับซ้อนตาม Req 6B
  • Concurrency Control: ใช้ Redis Lock หรือ Optimistic Locking ในการอัปเดต last_number
  • Reset Rule: current_year เปลี่ยน -> เริ่มนับ 1 ใหม่

9.3 document_number_audit (NEW v1.5.1)

Purpose: Audit log for document number generation (Debugging & Tracking)

Column Name Data Type Constraints Description
id BIGINT PK, AI Unique ID
transaction_id VARCHAR(36) NOT NULL UUID ของ Transaction การขอเลข
counter_key_json JSON NOT NULL ค่า Key ที่ใช้ในการ Query (เก็บเป็น JSON)
generated_number VARCHAR(100) NOT NULL เลขที่ได้
requested_by INT FK User ที่ขอเลข
requested_at TIMESTAMP DEFAULT NOW เวลาที่ขอ
execution_time_ms INT NULL เวลาที่ใช้ในการประมวลผล (ms)

9.4 document_number_errors (NEW v1.5.1)

Purpose: Error log for failed document number generation

Column Name Data Type Constraints Description
id BIGINT PK, AI Unique ID
transaction_id VARCHAR(36) NOT NULL UUID ของ Transaction
error_code VARCHAR(50) NOT NULL รหัส Error (เช่น ERR_LOCK_TIMEOUT)
error_message TEXT NOT NULL รายละเอียด Error
counter_key_json JSON NULL ค่า Key ที่พยายามใช้
occurred_at TIMESTAMP DEFAULT NOW เวลาที่เกิด Error

10. ⚙️ Unified Workflow Engine Tables (NEW v1.5.1)

10.1 workflow_definitions

Purpose: เก็บแม่แบบ (Template) ของ Workflow (Req 3.6)

Column Name Data Type Constraints Description
id INT PK, AI Unique ID
workflow_code VARCHAR(50) UNIQUE รหัส Workflow (เช่น WF-RFA-GENERIC)
workflow_name VARCHAR(255) NOT NULL ชื่อ Workflow
description TEXT NULL คำอธิบาย
module VARCHAR(50) NOT NULL ใช้กับ Module ไหน (RFA, CORRESPONDENCE)
steps_config JSON NOT NULL การตั้งค่า Step (Sequence, Approvers, Conditions)
is_active BOOLEAN DEFAULT TRUE สถานะการใช้งาน
version INT DEFAULT 1 เวอร์ชันของ Definition

Business Rules:

  • steps_config เก็บ Logic ของ Workflow ทั้งหมดในรูปแบบ JSON เพื่อความยืดหยุ่น

10.2 workflow_instances

Purpose: เก็บสถานะของ Workflow ที่กำลังรันอยู่จริง (Runtime)

Column Name Data Type Constraints Description
id BIGINT PK, AI Unique ID
workflow_definition_id INT FK, NOT NULL อ้างอิง Definition
business_key VARCHAR(100) INDEX ID ของเอกสารที่ผูกกับ Workflow นี้ (เช่น RFA-001)
current_step_name VARCHAR(100) NOT NULL ชื่อ Step ปัจจุบัน
status ENUM NOT NULL IN_PROGRESS, COMPLETED, TERMINATED
context_data JSON NULL ข้อมูลประกอบการตัดสินใจ (Variables)
started_at TIMESTAMP DEFAULT NOW เวลาที่เริ่ม
completed_at TIMESTAMP NULL เวลาที่จบ

10.3 workflow_histories

Purpose: เก็บประวัติการดำเนินการในแต่ละ Step (Audit Trail)

Column Name Data Type Constraints Description
id BIGINT PK, AI Unique ID
workflow_instance_id BIGINT FK, NOT NULL อ้างอิง Instance
step_name VARCHAR(100) NOT NULL ชื่อ Step
action VARCHAR(50) NOT NULL การกระทำ (APPROVE, REJECT, COMMENT)
actor_id INT FK, NULL User ที่กระทำ
comments TEXT NULL ความเห็นเพิ่มเติม
performed_at TIMESTAMP DEFAULT NOW เวลาที่กระทำ

11. 🖥️ System & Logs Tables (ระบบ, บันทึก)

11.1 json_schemas (NEW v1.5.1)

Purpose: เก็บ Schema สำหรับ Validate JSON Columns (Req 3.12)

Column Name Data Type Constraints Description
id INT PK, AI Unique ID
schema_code VARCHAR(50) UNIQUE รหัส Schema (เช่น RFA_DETAILS_V1)
schema_body JSON NOT NULL JSON Schema Draft 7/2020-12 definition
description TEXT NULL คำอธิบาย
is_active BOOLEAN DEFAULT TRUE สถานะ

11.2 audit_logs (UPDATE v1.5.1)

Purpose: Centralized audit logging for all system actions

Column Name Data Type Constraints Description
id BIGINT PRIMARY KEY, AUTO_INCREMENT Unique log ID
user_id INT NULL, FK User who performed action
action VARCHAR(50) NOT NULL Action name (CREATE, UPDATE, DELETE, etc)
module VARCHAR(50) NOT NULL Module name (USERS, RFA, etc)
entity_id VARCHAR(50) NULL ID of affected entity
old_values JSON NULL Data before change
new_values JSON NULL Data after change
ip_address VARCHAR(45) NULL User IP address
user_agent VARCHAR(255) NULL User browser/client info
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP Log timestamp

Indexes:

  • PRIMARY KEY (id, created_at) -- Partition Key
  • INDEX (user_id)
  • INDEX (module)
  • INDEX (action)
  • INDEX (created_at)
  • INDEX (entity_id)

Partitioning:

  • PARTITION BY RANGE (YEAR(created_at)): แบ่ง Partition รายปี เพื่อประสิทธิภาพในการเก็บข้อมูลระยะยาว

11.3 notifications (UPDATE v1.5.1)

Purpose: System notifications for users

Column Name Data Type Constraints Description
id BIGINT PRIMARY KEY, AUTO_INCREMENT Unique notification ID
user_id INT NOT NULL, FK Recipient user ID
title VARCHAR(255) NOT NULL Notification title
message TEXT NOT NULL Notification body
link VARCHAR(500) NULL Action link URL
type VARCHAR(50) DEFAULT 'INFO' Type: INFO, WARNING, ERROR, SUCCESS
is_read BOOLEAN DEFAULT FALSE Read status
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP Notification timestamp

Indexes:

  • PRIMARY KEY (id, created_at) -- Partition Key
  • FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE
  • INDEX (user_id, is_read)
  • INDEX (created_at)

Partitioning:

  • PARTITION BY RANGE (YEAR(created_at)): แบ่ง Partition รายปี

12. 🔍 Views (มุมมองข้อมูล)

12.1 v_correspondence_details

Purpose: Denormalized view for correspondence listing and searching

CREATE VIEW v_correspondence_details AS
SELECT
    c.id,
    c.correspondence_number,
    c.correspondence_type_id,
    ct.type_name,
    c.project_id,
    p.project_code,
    c.originator_id,
    org.organization_code AS originator_code,
    cr.title,
    cr.revision_number,
    cr.correspondence_status_id,
    cs.status_name,
    cr.document_date,
    cr.created_at
FROM correspondences c
JOIN correspondence_revisions cr ON c.id = cr.correspondence_id AND cr.is_current = 1
JOIN correspondence_types ct ON c.correspondence_type_id = ct.id
JOIN projects p ON c.project_id = p.id
LEFT JOIN organizations org ON c.originator_id = org.id
LEFT JOIN correspondence_status cs ON cr.correspondence_status_id = cs.id;

12.2 v_rfa_details

Purpose: Denormalized view for RFA listing and searching

CREATE VIEW v_rfa_details AS
SELECT
    r.id,
    c.correspondence_number AS rfa_number,
    rt.type_code AS rfa_type,
    rr.title,
    rr.revision_number,
    rsc.status_name AS rfa_status,
    rac.approve_name AS approval_result,
    rr.document_date,
    rr.due_date
FROM rfas r
JOIN correspondences c ON r.id = c.id -- Assuming 1:1 mapping logic or shared ID
JOIN rfa_revisions rr ON r.id = rr.rfa_id AND rr.is_current = 1
JOIN rfa_types rt ON r.rfa_type_id = rt.id
JOIN rfa_status_codes rsc ON rr.rfa_status_code_id = rsc.id
LEFT JOIN rfa_approve_codes rac ON rr.rfa_approve_code_id = rac.id;

13. 📊 Index Summaries (สรุป Index)

13.1 Performance Indexes

Table Name Index Columns Purpose
correspondences (project_id, correspondence_number) Fast lookup by document number
correspondences (correspondence_type_id) Filter by type
correspondence_revisions (correspondence_id, is_current) Get current revision
rfas (rfa_type_id) Filter by RFA type
rfa_revisions (rfa_id, is_current) Get current RFA revision
rfa_revisions (rfa_status_code_id) Filter by status
audit_logs (created_at) Date range queries
audit_logs (user_id) User activity history
audit_logs (module, action) Action type analysis
notifications (user_id, is_read) Unread notifications query
document_number_counters (project_id, correspondence_type_id, current_year) Running number generation
workflow_instances (business_key) Workflow lookup by document ID
workflow_instances (status) Monitor active workflows

13.2 Unique Constraints

Table Name Columns Description
users (username) Unique login name
users (email) Unique email address
organizations (organization_code) Unique organization code
projects (project_code) Unique project code
contracts (contract_code) Unique contract code
correspondences (project_id, correspondence_number) Unique document number per project
rfas (drawing_number) Unique shop drawing number
document_number_formats (project_id, correspondence_type_id) One format per type per project
workflow_definitions (workflow_code) Unique workflow code

14. 🛡️ Data Integrity Constraints (ความถูกต้องของข้อมูล)

14.1 Soft Delete Policy

  • Tables with deleted_at:
    • users
    • organizations
    • projects
    • contracts
    • correspondences
    • rfas
    • shop_drawings
    • contract_drawings
  • Rule: Records are never physically deleted. deleted_at is set to timestamp.
  • Query Rule: All standard queries MUST include WHERE deleted_at IS NULL.

14.2 Foreign Key Cascades

  • ON DELETE CASCADE:
    • Used for child tables that cannot exist without parent (e.g., correspondence_revisions, rfa_revisions, correspondence_attachments).
  • ON DELETE RESTRICT:
    • Used for master data references to prevent accidental deletion of used data (e.g., correspondence_types, organizations).
  • ON DELETE SET NULL:
    • Used for optional references (e.g., created_by, originator_id).

15. 🔐 Security & Permissions Model (ความปลอดภัย)

15.1 Row-Level Security (RLS) Logic

  • Organization Scope: Users can only see documents where originator_id OR recipient_organization_id matches their organization.
  • Project Scope: Users can only see documents within projects they are assigned to.
  • Confidentiality: Documents marked is_confidential are visible ONLY to specific roles or users.

15.2 Role-Based Access Control (RBAC)

  • Permissions are granular (e.g., correspondence.view, correspondence.create).
  • Roles aggregate permissions (e.g., Document Controller = view + create + edit).
  • Assignments link Users to Roles within a Context (Global, Project, or Organization).

16. 🔄 Data Migration & Seeding (การย้ายข้อมูล)

16.1 Initial Seeding (V1.5.1)

  1. Master Data:
    • organizations: Owner, Consultant, Contractor
    • projects: LCBP3
    • correspondence_types: LETTER, MEMO, TRANSMITTAL, RFA
    • rfa_types: DWG, MAT, DOC, RFI
    • rfa_status_codes: DFT, PEND, APPR, REJ
    • disciplines: GEN, STR, ARC, MEP (New V1.5.1)
  2. System Users:
    • admin: Super Admin
    • system: System Bot for automated tasks

16.2 Migration Strategy

  • Schema Migration: Use TypeORM Migrations or raw SQL scripts (versioned).
  • Data Migration:
    • V1.4.5 -> V1.5.1:
      • Run SQL script 8_lcbp3_v1_5_1.sql
      • Populate disciplines table.
      • Update document_number_counters PK (Requires careful migration of existing counters).
      • Initialize workflow_definitions.

17. 📈 Monitoring & Maintenance (การดูแลรักษา)

17.1 Database Maintenance

  • Daily: Incremental Backup.
  • Weekly: Full Backup + OPTIMIZE TABLE for heavy tables (audit_logs, notifications).
  • Monthly: Archive old audit_logs partitions to cold storage.

17.2 Health Checks

  • Monitor document_number_errors for numbering failures.
  • Monitor workflow_instances for stuck workflows (status = 'IN_PROGRESS' > 7 days).
  • Check document_number_counters for gaps or resets.

18. 📖 Glossary (คำศัพท์)

  • RFA: Request for Approval (เอกสารขออนุมัติ)
  • Transmittal: Document Transmittal Sheet (ใบนำส่งเอกสาร)
  • Shop Drawing: แบบก่อสร้างที่ผู้รับเหมาจัดทำ
  • Contract Drawing: แบบสัญญา (แบบตั้งต้น)
  • Revision: ฉบับแก้ไข (0, 1, 2, A, B, C)
  • Originator: ผู้จัดทำ/ผู้ส่งเอกสาร
  • Recipient: ผู้รับเอกสาร
  • Workflow: กระบวนการทำงาน/อนุมัติ
  • Discipline: สาขางาน (เช่น โยธา, สถาปัตย์, ไฟฟ้า)

End of Data Dictionary V1.5.1