2906 lines
131 KiB
Markdown
2906 lines
131 KiB
Markdown
# **ตารางฐานข้อมูล (Data Dictionary) - LCBP3-DMS (V1.4.4)**
|
|
|
|
เอกสารนี้สรุปโครงสร้างตาราง, Foreign Keys (FK), และ Constraints ที่สำคัญทั้งหมดในฐานข้อมูล LCBP3-DMS (v1.4) เพื่อใช้เป็นเอกสารอ้างอิงสำหรับทีมพัฒนา Backend (NestJS) และ Frontend (Next.js) โดยอิงจาก Requirements และ SQL Script ล่าสุด [GEMINI]
|
|
|
|
**สถานะ:** FINAL GUIDELINE
|
|
**วันที่:** 2025-11-26
|
|
**อ้างอิง:** Requirements v1.4.4 & FullStackJS Guidelines v1.4.4
|
|
**Classification:** Internal Technical Documentation
|
|
|
|
## 📝 สรุปรายการปรับปรุง (Summary of Changes)
|
|
|
|
1. **เพิ่มตาราง `disciplines`**: สำหรับเก็บข้อมูลสาขางาน (เช่น GEN, STR, ARC)
|
|
2. **เพิ่มตาราง `correspondence_sub_types`**: สำหรับเก็บรหัสย่อย (เช่น MAT-11, SHP-12)
|
|
3. **แก้ไขตาราง `correspondences`**: เพิ่ม Column `discipline_id`
|
|
4. **แก้ไขตาราง `rfas`**: เพิ่ม Column `discipline_id`
|
|
5. **แก้ไขตาราง `document_number_counters`**: เพิ่ม `discipline_id` ใน Primary Key
|
|
6. Seeded data for disciplines and RFA types based on Requirement 6B.
|
|
|
|
---
|
|
|
|
## **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 |
|
|
| **discipline_id** | **INT** | **NULL, FK** | **Reference to disciplines (if applicable)** |
|
|
| 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
|
|
|
|
**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 |
|
|
| **discipline_id** | **INT** | **NULL, FK** | **Reference to disciplines (if applicable)** |
|
|
| 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
|
|
|
|
**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
|
|
|
|
### 4.10 disciplines
|
|
|
|
**Purpose**: Master table for Project Disciplines (สาขางาน) [Added in v1.4.4 based on Req 6B]
|
|
|
|
| Column Name | Data Type | Constraints | Description |
|
|
| --------------- | ------------ | --------------------------- | -------------------------------- |
|
|
| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier |
|
|
| contract_id | INT | NOT NULL, FK | Reference to contracts |
|
|
| discipline_code | VARCHAR(10) | NOT NULL | Code (e.g., 'GEN', 'STR', 'ARC') |
|
|
| code_name_th | VARCHAR(255) | NULL | Thai Name |
|
|
| code_name_en | VARCHAR(255) | NULL | English Name |
|
|
| is_active | TINYINT(1) | DEFAULT 1 | Active status |
|
|
| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Creation timestamp |
|
|
|
|
**Indexes**:
|
|
|
|
- PRIMARY KEY (id)
|
|
- FOREIGN KEY (contract_id) REFERENCES contracts(id) ON DELETE CASCADE
|
|
- **UNIQUE KEY (contract_id, discipline_code)** - Ensures unique code per contract
|
|
|
|
**Relationships**:
|
|
|
|
- Parent: contracts
|
|
- Referenced by: rfas, correspondences, document_number_counters
|
|
|
|
---
|
|
|
|
### 4.11 correspondence_sub_types
|
|
|
|
**Purpose**: Master table for Correspondence/RFA Sub-types mapping [Added in v1.4.4 based on Req 6B]
|
|
|
|
| Column Name | Data Type | Constraints | Description |
|
|
| ---------------------- | ------------ | --------------------------- | -------------------------------------------- |
|
|
| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier |
|
|
| contract_id | INT | NOT NULL, FK | Reference to contracts |
|
|
| correspondence_type_id | INT | NOT NULL, FK | Reference to correspondence_types |
|
|
| sub_type_code | VARCHAR(20) | NOT NULL | Sub-type Code (e.g., 'MAT', 'SHP') |
|
|
| sub_type_name | VARCHAR(255) | NULL | Full Name |
|
|
| sub_type_number | VARCHAR(10) | NULL | Numeric code for running number (e.g., '11') |
|
|
| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Creation timestamp |
|
|
|
|
**Indexes**:
|
|
|
|
- PRIMARY KEY (id)
|
|
- FOREIGN KEY (contract_id) REFERENCES contracts(id) ON DELETE CASCADE
|
|
- FOREIGN KEY (correspondence_type_id) REFERENCES correspondence_types(id) ON DELETE CASCADE
|
|
|
|
**Relationships**:
|
|
|
|
- Parent: contracts, correspondence_types
|
|
- Referenced by: (Used in logic for Document Numbering)
|
|
---
|
|
|
|
## **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 |
|
|
| **discipline_id** | **INT** | **PRIMARY KEY** | **Discipline ID (0 if not applicable)** |
|
|
| 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, discipline_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**:
|
|
|
|
- **Updated v1.4.4:** Composite primary key now includes `discipline_id` to support independent running numbers per discipline (e.g., STR-001, ARC-001).
|
|
- 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**:
|
|
|
|
```sql
|
|
SELECT permission_name
|
|
FROM v_user_all_permissions
|
|
WHERE user_id = ?
|
|
AND project_id = ?
|
|
AND permission_name = 'document.edit';
|
|
```
|
|
|
|
---
|
|
|
|
### 11.7 v_documents_with_attachments
|
|
|
|
**Purpose**: View showing all documents and their attachment counts
|
|
|
|
**Columns**:
|
|
|
|
- document_type (CORRESPONDENCE, CIRCULATION, SHOP_DRAWING, CONTRACT_DRAWING)
|
|
- document_id, document_number
|
|
- project_id, project_code, project_name
|
|
- attachment_count, latest_attachment_date
|
|
|
|
**Business Rules**:
|
|
|
|
- UNION of all document types with attachments
|
|
- Used for document listing with file indicators
|
|
- Helps identify documents missing attachments
|
|
- Aggregates count per document
|
|
|
|
---
|
|
|
|
### 11.8 v_document_statistics
|
|
|
|
**Purpose**: View providing aggregated document statistics by project, type, and status
|
|
|
|
**Columns**:
|
|
|
|
- project_id, project_code, project_name
|
|
- correspondence_type_id, correspondence_type_code, correspondence_type_name
|
|
- status_id, status_code, status_name
|
|
- document_count, revision_count
|
|
|
|
**Business Rules**:
|
|
|
|
- CROSS JOIN creates all possible combinations
|
|
- LEFT JOIN shows zeros for combinations with no documents
|
|
- Only includes active projects, types, and statuses
|
|
- Used for dashboard charts and reports
|
|
- Groups by project → type → status
|
|
|
|
---
|
|
|
|
## Database Indexes Summary
|
|
|
|
### Performance Optimization Indexes
|
|
|
|
**Primary Indexes** (automatic with PRIMARY KEY):
|
|
|
|
- All tables have PRIMARY KEY with AUTO_INCREMENT
|
|
|
|
**Foreign Key Indexes** (automatic with FOREIGN KEY):
|
|
|
|
- All FK relationships automatically indexed
|
|
|
|
**Additional Performance Indexes**:
|
|
|
|
1. **Correspondence Tables**:
|
|
|
|
- `idx_correspondences_type_project` on (correspondence_type_id, project_id)
|
|
- `idx_corr_revisions_current_status` on (is_current, correspondence_status_id)
|
|
- `idx_corr_revisions_correspondence_current` on (correspondence_id, is_current)
|
|
- `idx_correspondences_project_type` on (project_id, correspondence_type_id)
|
|
|
|
2. **RFA Tables**:
|
|
|
|
- `idx_rfa_revisions_current_status` on (is_current, rfa_status_code_id)
|
|
- `idx_rfa_revisions_rfa_current` on (rfa_id, is_current)
|
|
|
|
3. **Circulation Tables**:
|
|
|
|
- `idx_circulation_routings_status_assigned` on (status, assigned_to)
|
|
- `idx_circulation_routings_circulation_status` on (circulation_id, status)
|
|
|
|
4. **Document Numbering**:
|
|
|
|
- `idx_doc_counter_composite` on (project_id, originator_organization_id, correspondence_type_id, current_year)
|
|
|
|
5. **Audit & Notifications**:
|
|
|
|
- `idx_audit_logs_reporting` on (created_at, entity_type, action)
|
|
- `idx_notifications_user_unread` on (user_id, is_read, created_at)
|
|
|
|
---
|
|
|
|
## Data Integrity Constraints
|
|
|
|
### Foreign Key Constraints
|
|
|
|
**Cascade Delete**:
|
|
|
|
- Parent-child relationships where child should be deleted with parent
|
|
- Examples: correspondence_revisions, shop_drawing_revisions, project/contract relationships
|
|
|
|
**Restrict Delete**:
|
|
|
|
- Prevents deletion if references exist
|
|
- Examples: correspondence_types, rfa_status_codes, organizations (when referenced)
|
|
|
|
**Set NULL**:
|
|
|
|
- Preserves record but removes reference
|
|
- Examples: originator_id, created_by, updated_by
|
|
|
|
### Unique Constraints
|
|
|
|
1. **Globally Unique**:
|
|
|
|
- usernames, emails
|
|
- shop_drawing.drawing_number
|
|
|
|
2. **Unique Within Scope**:
|
|
|
|
- (project_id, correspondence_number)
|
|
- (project_id, condwg_no)
|
|
- (correspondence_id, revision_number)
|
|
- (rfa_id, revision_number)
|
|
|
|
3. **Composite Unique**:
|
|
- (correspondence_id, is_current) - ensures only one current revision
|
|
- (project_id, correspondence_type_id) - in document_number_formats
|
|
|
|
### Check Constraints
|
|
|
|
1. **user_assignments.chk_scope**:
|
|
- Ensures only one scope field (organization_id, project_id, contract_id) is NOT NULL
|
|
- OR all are NULL for Global scope
|
|
|
|
### Business Rule Constraints
|
|
|
|
1. **Soft Delete Pattern**:
|
|
|
|
- deleted_at timestamp instead of hard delete
|
|
- Preserves audit trail and relationships
|
|
- Applied to: correspondences, rfas, shop_drawings, contract_drawings
|
|
|
|
2. **Current Revision Pattern**:
|
|
|
|
- is_current flag with UNIQUE constraint
|
|
- Ensures only one current revision per document
|
|
|
|
3. **Sequential Numbering**:
|
|
- revision_number starts at 0, increments by 1
|
|
- Enforced by application logic + stored procedure
|
|
|
|
---
|
|
|
|
## Security & Permissions Model
|
|
|
|
### Access Control Hierarchy
|
|
|
|
```tree
|
|
Global Scope (Superadmin)
|
|
└── Organization Scope (Org Admin, Document Control)
|
|
└── Project Scope (Project Manager)
|
|
└── Contract Scope (Contract Admin)
|
|
```
|
|
|
|
### Permission Inheritance
|
|
|
|
- Users can have multiple role assignments at different scopes
|
|
- More specific scopes inherit access from broader scopes
|
|
- Permission checks evaluate all applicable scopes
|
|
- View v_user_all_permissions aggregates effective permissions
|
|
|
|
### Role-Based Access Control (RBAC)
|
|
|
|
**7 Predefined Roles**:
|
|
|
|
1. Superadmin (Global) - Full system access
|
|
2. Org Admin (Organization) - Organization management
|
|
3. Document Control (Organization) - Document lifecycle + admin powers
|
|
4. Editor (Organization) - Document CRUD
|
|
5. Viewer (Organization) - Read-only
|
|
6. Project Manager (Project) - Project + document management
|
|
7. Contract Admin (Contract) - Contract-specific management
|
|
|
|
### Permission Categories (49 total)
|
|
|
|
1. **System Management** (1): Full system control
|
|
2. **Organization Management** (4): CRUD on organizations
|
|
3. **Project Management** (8): CRUD + member/contract management
|
|
4. **Role & Permission Management** (4): RBAC administration
|
|
5. **Master Data Management** (4): Document types, categories, tags
|
|
6. **User Management** (5): User CRUD + organization assignment
|
|
7. **Contract Management** (2): Contract administration
|
|
8. **Document Management** (16): Full document lifecycle
|
|
9. **Workflow Management** (3): Approval workflow control
|
|
10. **Search & Reporting** (2): Advanced search, report generation
|
|
|
|
---
|
|
|
|
## Data Migration & Seeding
|
|
|
|
### Pre-populated Master Data
|
|
|
|
1. **organization_roles**: Not used in current implementation
|
|
2. **organizations**: 15 organizations (Owner, Consultants, Contractors, Third parties)
|
|
3. **projects**: 5 projects (LCBP3 + 4 sub-contracts)
|
|
4. **contracts**: 7 contracts
|
|
5. **users**: 3 initial users (superadmin, editor01, viewer01)
|
|
6. **roles**: 7 predefined roles
|
|
7. **permissions**: 49 system permissions
|
|
8. **role_permissions**: Complete permission mappings
|
|
9. **project_organizations**: Project-organization relationships
|
|
10. **contract_organizations**: Contract-organization-role relationships
|
|
11. **correspondence_types**: 10 types
|
|
12. **correspondence_status**: 23 status codes
|
|
13. **rfa_types**: 11 types
|
|
14. **rfa_status_codes**: 7 statuses
|
|
15. **rfa_approve_codes**: 8 approval codes
|
|
16. **circulation_status_codes**: 4 statuses
|
|
|
|
### Initial Passwords
|
|
|
|
All seed users have password: `password123`
|
|
|
|
- Hashed as: `$2y$10$0kjBMxWq7E4G7P.dc8r5i.cjiPBiup553AsFpDfxUt31gKg9h/udq`
|
|
- **Must be changed on first login in production**
|
|
|
|
---
|
|
|
|
## Backup & Recovery Strategy
|
|
|
|
### Database Backup
|
|
|
|
**Strategy**:
|
|
|
|
- Daily full database backups
|
|
- Hourly incremental backups (transaction logs)
|
|
- Retention: 30 days online, 7 years archived
|
|
|
|
**Backup Method**:
|
|
|
|
- MariaDB mysqldump for logical backups
|
|
- MariaDB Backup (Mariabackup) for physical backups
|
|
- Automated via n8n cron workflows
|
|
|
|
### File Backup
|
|
|
|
**Strategy**:
|
|
|
|
- Daily backup of /share/dms-data/ directory
|
|
- QNAP snapshot every 4 hours
|
|
- Offsite replication to secondary NAS
|
|
|
|
**File Organization**:
|
|
|
|
```tree
|
|
/share/dms-data/
|
|
├── attachments/
|
|
│ ├── 2025/
|
|
│ │ ├── 01/
|
|
│ │ │ └── {uuid}-{filename}
|
|
│ │ └── 02/
|
|
│ └── 2024/
|
|
└── temp/
|
|
```
|
|
|
|
### Recovery Procedures
|
|
|
|
1. **Point-in-Time Recovery**: Using transaction logs
|
|
2. **Full Restore**: From latest full backup
|
|
3. **Selective Restore**: Individual tables or records
|
|
4. **File Recovery**: From QNAP snapshots or backup
|
|
|
|
---
|
|
|
|
## Performance Optimization
|
|
|
|
### Query Optimization
|
|
|
|
1. **Use Indexed Columns**: WHERE, JOIN, ORDER BY clauses
|
|
2. **Avoid SELECT**: Specify needed columns
|
|
3. **Use Views**: For complex, frequently-used queries
|
|
4. **Limit Result Sets**: Use LIMIT and pagination
|
|
5. **Analyze Slow Queries**: Enable slow query log
|
|
|
|
### Index Maintenance
|
|
|
|
```sql
|
|
-- Check index usage
|
|
SELECT * FROM information_schema.STATISTICS
|
|
WHERE TABLE_SCHEMA = 'lcbp3';
|
|
|
|
-- Optimize tables
|
|
OPTIMIZE TABLE correspondences;
|
|
|
|
-- Analyze tables
|
|
ANALYZE TABLE correspondences;
|
|
```
|
|
|
|
### Connection Pooling
|
|
|
|
- Backend uses connection pool (NestJS TypeORM)
|
|
- Min pool size: 5
|
|
- Max pool size: 20
|
|
- Idle timeout: 10 minutes
|
|
|
|
---
|
|
|
|
## Data Validation Rules
|
|
|
|
### Required Fields Validation
|
|
|
|
**At Application Level**:
|
|
|
|
- Email format validation
|
|
- Date range validation (start_date < end_date)
|
|
- File size limits (5MB per attachment)
|
|
- File type restrictions (PDF, DWG, DOC, XLS, images)
|
|
|
|
**At Database Level**:
|
|
|
|
- NOT NULL constraints
|
|
- UNIQUE constraints
|
|
- Foreign key constraints
|
|
- Check constraints (user_assignments scope)
|
|
|
|
### Business Logic Validation
|
|
|
|
1. **Document Workflow**:
|
|
|
|
- Cannot edit submitted documents (unless Document Control)
|
|
- Cannot skip workflow steps (unless forced)
|
|
- Must provide approval comments
|
|
|
|
2. **User Management**:
|
|
|
|
- Cannot delete users with active assignments
|
|
- Cannot deactivate own account
|
|
- Must have valid organization for non-Global roles
|
|
|
|
3. **File Management**:
|
|
- Original filename preserved for audit
|
|
- Unique stored filename prevents conflicts
|
|
- File path must exist and be accessible
|
|
|
|
---
|
|
|
|
## Change Log & Versioning
|
|
|
|
### Database Version: v1.4.0
|
|
|
|
**Changes from v1.3.0**:
|
|
|
|
- Added comprehensive RBAC system (roles, permissions, user_assignments)
|
|
- Refactored organization-project-contract relationships
|
|
- Added junction tables for M:N relationships
|
|
- Implemented soft delete pattern
|
|
- Added full-text search support
|
|
- Enhanced audit logging with JSON details
|
|
- Added circulation workflow templates
|
|
- Improved document numbering with stored procedure
|
|
- Added comprehensive views for common queries
|
|
- Optimized indexes for performance
|
|
|
|
**Migration Path**:
|
|
|
|
- v1.3.0 → v1.4.0: Run migration script (not provided in this excerpt)
|
|
- Backup database before migration
|
|
- Test migration on staging environment first
|
|
|
|
---
|
|
|
|
## Technical Specifications
|
|
|
|
### Database Configuration
|
|
|
|
**MariaDB Server**:
|
|
|
|
- Version: 10.11
|
|
- Character Set: utf8mb4
|
|
- Collation: utf8mb4_general_ci
|
|
- Time Zone: +07:00 (Bangkok/Asia)
|
|
- SQL Mode: STRICT_TRANS_TABLES, NO_ENGINE_SUBSTITUTION
|
|
|
|
**Connection Settings**:
|
|
|
|
- Host: Container on QNAP TS-473A
|
|
- Port: 3306 (default)
|
|
- Max Connections: 100
|
|
- Max Packet Size: 64MB
|
|
|
|
### Table Engine
|
|
|
|
**InnoDB Features Used**:
|
|
|
|
- ACID compliance
|
|
- Foreign key constraints
|
|
- Row-level locking
|
|
- Crash recovery
|
|
- Transaction support
|
|
|
|
### Storage Requirements
|
|
|
|
**Estimated Initial Size**:
|
|
|
|
- Database: ~50 MB (with seed data)
|
|
- Indexes: ~20 MB
|
|
- Total: ~70 MB
|
|
|
|
**Growth Estimates**:
|
|
|
|
- 1,000 documents/month: +100 MB/month (database)
|
|
- 10 attachments/document @ 2MB avg: +20 GB/month (files)
|
|
- Plan for 1TB+ storage within first year
|
|
|
|
---
|
|
|
|
## Application Integration
|
|
|
|
### Backend (NestJS)
|
|
|
|
**TypeORM Entities**:
|
|
|
|
- One entity class per table
|
|
- Decorators for columns, relationships
|
|
- DTOs for data transfer
|
|
- Repositories for data access
|
|
|
|
**Key Modules**:
|
|
|
|
- AuthModule: Authentication, authorization
|
|
- DocumentsModule: Correspondence, RFA management
|
|
- DrawingsModule: Shop drawing, contract drawing
|
|
- WorkflowModule: Circulation, approval workflows
|
|
- FilesModule: Attachment management
|
|
- UsersModule: User, role, permission management
|
|
|
|
### Frontend (Next.js)
|
|
|
|
**Key Features**:
|
|
|
|
- Document listing/search
|
|
- Document creation wizards
|
|
- Workflow approval interface
|
|
- File upload/download
|
|
- User management console
|
|
- Dashboard analytics
|
|
|
|
### Integration Points
|
|
|
|
1. **Document Numbering**:
|
|
|
|
- Call 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
|
|
|
|
```sql
|
|
-- Database size
|
|
SELECT
|
|
table_schema,
|
|
SUM(data_length + index_length) / 1024 / 1024 AS size_mb
|
|
FROM information_schema.TABLES
|
|
WHERE table_schema = 'dms_db'
|
|
GROUP BY table_schema;
|
|
|
|
-- Table sizes
|
|
SELECT
|
|
table_name,
|
|
(data_length + index_length) / 1024 / 1024 AS size_mb,
|
|
table_rows
|
|
FROM information_schema.TABLES
|
|
WHERE table_schema = 'dms_db'
|
|
ORDER BY (data_length + index_length) DESC;
|
|
|
|
-- Active connections
|
|
SHOW PROCESSLIST;
|
|
|
|
-- Lock wait statistics
|
|
SELECT * FROM information_schema.INNODB_LOCK_WAITS;
|
|
```
|
|
|
|
### Scheduled Maintenance
|
|
|
|
**Daily**:
|
|
|
|
- Full database backup
|
|
- Check backup log for failures
|
|
- Monitor disk space
|
|
|
|
**Weekly**:
|
|
|
|
- OPTIMIZE tables
|
|
- ANALYZE tables
|
|
- Review slow query log
|
|
- Check for deadlocks
|
|
|
|
**Monthly**:
|
|
|
|
- Review audit logs
|
|
- Clean up old notifications (30+ days)
|
|
- Archive old audit logs (7+ years)
|
|
- Verify backup integrity (test restore)
|
|
|
|
**Quarterly**:
|
|
|
|
- Review and optimize indexes
|
|
- Update database statistics
|
|
- Capacity planning review
|
|
|
|
---
|
|
|
|
## Glossary
|
|
|
|
**Terms**:
|
|
|
|
- **Correspondence**: Any formal document exchanged between parties
|
|
- **RFA**: Request for Approval - formal submittal for review/approval
|
|
- **Circulation**: Internal document routing workflow
|
|
- **Transmittal**: Cover sheet for forwarding multiple documents
|
|
- **Shop Drawing**: Detailed construction drawing from contractor
|
|
- **Contract Drawing**: Baseline drawing from contract specifications
|
|
- **Revision**: Version of a document
|
|
- **Originator**: Organization that creates/sends a document
|
|
- **Recipient**: Organization that receives a document (TO or CC)
|
|
- **Scope**: Level of permission application (Global, Organization, Project, Contract)
|
|
|
|
**Acronyms**:
|
|
|
|
- **DMS**: Document Management System
|
|
- **LCBP3**: Laem Chabang Port Phase 3
|
|
- **RBAC**: Role-Based Access Control
|
|
- **RFA**: Request for Approval
|
|
- **RFI**: Request for Information
|
|
- **CSC**: Construction Supervision Consultant
|
|
- **TO**: Primary recipient (action required)
|
|
- **CC**: Carbon copy (for information)
|
|
- **QNAP**: Network Attached Storage device manufacturer
|
|
|
|
---
|
|
|
|
## **Document Control:**
|
|
|
|
- **Document:** Data Dictionary v1.4.4
|
|
- **Version:** 1.4
|
|
- **Date:** 2025-11-26
|
|
- **Author:** NAP LCBP3-DMS & Gemini
|
|
- **Status:** FINAL.Rev.04
|
|
- **Classification:** Internal Technical Documentation
|
|
- **Approved By:** Nattanin
|
|
|
|
---
|
|
|
|
`End of Data Dictionary v1.4.4 (ฉบับปรับปรุง)`
|