2202 lines
117 KiB
Markdown
2202 lines
117 KiB
Markdown
---
|
||
title: 'Data & Storage: Data Dictionary and Data Model Architecture'
|
||
version: 1.8.0
|
||
status: released
|
||
owner: Nattanin Peancharoen
|
||
last_updated: 2026-02-28
|
||
related:
|
||
- specs/01-requirements/02-architecture.md
|
||
- specs/01-requirements/03-functional-requirements.md
|
||
---
|
||
|
||
# 1. Data Model Architecture Overview
|
||
|
||
## ð 1.1 Overview
|
||
āđāļāļāļŠāļēāļĢāļāļĩāđāļāļāļīāļāļēāļĒāļŠāļāļēāļāļąāļāļĒāļāļĢāļĢāļĄāļāļāļ Data Model āļŠāļģāļŦāļĢāļąāļāļĢāļ°āļāļ LCBP3-DMS āđāļāļĒāļāļĢāļāļāļāļĨāļļāļĄāđāļāļĢāļāļŠāļĢāđāļēāļāļāļēāļāļāđāļāļĄāļđāļĨ, āļāļ§āļēāļĄāļŠāļąāļĄāļāļąāļāļāđāļĢāļ°āļŦāļ§āđāļēāļāļāļēāļĢāļēāļ, āđāļĨāļ°āļŦāļĨāļąāļāļāļēāļĢāļāļāļāđāļāļāļāļĩāđāļŠāļģāļāļąāļ
|
||
|
||
## ðŊ 1.2 Design Principles
|
||
### 1. Separation of Concerns
|
||
|
||
- **Master-Revision Pattern**: āđāļĒāļāļāđāļāļĄāļđāļĨāļāļĩāđāđāļĄāđāđāļāļĨāļĩāđāļĒāļāđāļāļĨāļ (Master) āļāļēāļāļāđāļāļĄāļđāļĨāļāļĩāđāļĄāļĩāļāļēāļĢāđāļāđāđāļ (Revisions)
|
||
- `correspondences` (Master) â `correspondence_revisions` (Revisions)
|
||
- `rfas` (Master) â `rfa_revisions` (Revisions)
|
||
- `shop_drawings` (Master) â `shop_drawing_revisions` (Revisions)
|
||
|
||
### 2. Data Integrity
|
||
|
||
- **Foreign Key Constraints**: āđāļāđ FK āļāļļāļāļāļ§āļēāļĄāļŠāļąāļĄāļāļąāļāļāđāđāļāļ·āđāļāļĢāļąāļāļĐāļēāļāļ§āļēāļĄāļŠāļĄāļāļđāļĢāļāđāļāļāļāļāđāļāļĄāļđāļĨ
|
||
- **Soft Delete**: āđāļāđ `deleted_at` āđāļāļāļāļēāļĢāļĨāļāļāđāļāļĄāļđāļĨāļāļĢāļīāļ āđāļāļ·āđāļāļĢāļąāļāļĐāļēāļāļĢāļ°āļ§āļąāļāļī
|
||
- **Optimistic Locking**: āđāļāđ `version` column āđāļ `document_number_counters` āļāđāļāļāļāļąāļ Race Condition
|
||
|
||
### 3. Flexibility & Extensibility
|
||
|
||
- **JSON Details Field**: āđāļāđāļāļāđāļāļĄāļđāļĨāđāļāļāļēāļ°āļāļĢāļ°āđāļ āļāđāļ `correspondence_revisions.details`
|
||
- **Virtual Columns**: āļŠāļĢāđāļēāļ Index āļāļēāļ JSON fields āļŠāļģāļŦāļĢāļąāļ Performance
|
||
- **Master Data Tables**: āđāļĒāļāļāđāļāļĄāļđāļĨ Master (Types, Status, Codes) āđāļāļ·āđāļāļāļ§āļēāļĄāļĒāļ·āļāļŦāļĒāļļāđāļ
|
||
|
||
### 4. Security & Audit
|
||
|
||
- **RBAC (Role-Based Access Control)**: āļĢāļ°āļāļāļŠāļīāļāļāļīāđāđāļāļ Hierarchical Scope
|
||
- **Audit Trail**: āļāļąāļāļāļķāļāļāļđāđāļŠāļĢāđāļēāļ/āđāļāđāđāļ āđāļĨāļ°āđāļ§āļĨāļēāđāļāļāļļāļāļāļēāļĢāļēāļ
|
||
- **Two-Phase File Upload**: āļāđāļāļāļāļąāļāđāļāļĨāđāļāļĒāļ°āļāđāļ§āļĒ Temporary Storage
|
||
|
||
# 2. Database Schema Overview (ERD)
|
||
### Entity Relationship Diagram
|
||
|
||
```mermaid
|
||
erDiagram
|
||
%% Core Entities
|
||
organizations ||--o{ users : "employs"
|
||
projects ||--o{ contracts : "contains"
|
||
projects ||--o{ correspondences : "manages"
|
||
|
||
%% RBAC
|
||
users ||--o{ user_assignments : "has"
|
||
roles ||--o{ user_assignments : "assigned_to"
|
||
roles ||--o{ role_permissions : "has"
|
||
permissions ||--o{ role_permissions : "granted_by"
|
||
|
||
%% Correspondences
|
||
correspondences ||--o{ correspondence_revisions : "has_revisions"
|
||
correspondence_types ||--o{ correspondences : "categorizes"
|
||
correspondence_status ||--o{ correspondence_revisions : "defines_state"
|
||
disciplines ||--o{ correspondences : "classifies"
|
||
|
||
%% RFAs
|
||
rfas ||--o{ rfa_revisions : "has_revisions"
|
||
rfa_types ||--o{ rfas : "categorizes"
|
||
rfa_status_codes ||--o{ rfa_revisions : "defines_state"
|
||
rfa_approve_codes ||--o{ rfa_revisions : "defines_result"
|
||
disciplines ||--o{ rfas : "classifies"
|
||
|
||
%% Drawings
|
||
shop_drawings ||--o{ shop_drawing_revisions : "has_revisions"
|
||
shop_drawing_main_categories ||--o{ shop_drawings : "categorizes"
|
||
shop_drawing_sub_categories ||--o{ shop_drawings : "sub_categorizes"
|
||
|
||
%% Attachments
|
||
attachments ||--o{ correspondence_attachments : "attached_to"
|
||
correspondences ||--o{ correspondence_attachments : "has"
|
||
```
|
||
|
||
---
|
||
|
||
# 3. Data Dictionary V1.8.0
|
||
|
||
> āļŦāļĄāļēāļĒāđāļŦāļāļļ: PK = Primary Key, FK = Foreign Key, AI = AUTO_INCREMENT. āļĢāļđāļāđāļāļ Soft Delete āļāļ°āļāļĢāļēāļāļ Column `deleted_at DATETIME NULL` āđāļāđāļāļĄāļēāļāļĢāļāļēāļ
|
||
|
||
## **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 (
|
||
CONTRACTOR,
|
||
THIRD PARTY
|
||
) |
|
||
| 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 | ** 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 |
|
||
| deleted_at | DATETIME | NULL | Soft delete timestamp | ** INDEXES **: - PRIMARY KEY (id) - UNIQUE (organization_code) - INDEX (is_active) ** Relationships **: - Referenced by: users,
|
||
project_organizations,
|
||
contract_organizations,
|
||
correspondences,
|
||
circulations ---
|
||
|
||
### 1.3 projects
|
||
|
||
* * Purpose **: MASTER TABLE FOR ALL projects IN the system | COLUMN Name | Data TYPE | Constraints | Description | | ------------ | ------------ | --------------------------- | ----------------------------- |
|
||
| id | INT | PRIMARY KEY,
|
||
AUTO_INCREMENT | UNIQUE identifier FOR project | | project_code | VARCHAR(50) | NOT NULL,
|
||
UNIQUE | Project code (e.g., 'LCBP3') | | project_name | VARCHAR(255) | NOT NULL | FULL project name | | is_active | TINYINT(1) | DEFAULT 1 | Active STATUS |
|
||
| 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 |
|
||
** INDEXES **: - PRIMARY KEY (id) - UNIQUE (project_code) - INDEX (is_active) ** Relationships **: - Referenced by: contracts,
|
||
correspondences,
|
||
document_number_formats,
|
||
drawings ---
|
||
|
||
### 1.4 contracts
|
||
|
||
* * Purpose **: MASTER TABLE FOR contracts within projects | COLUMN Name | Data TYPE | Constraints | Description | | ------------- | ------------ | ----------------------------------- | ------------------------------ |
|
||
| id | INT | PRIMARY KEY,
|
||
AUTO_INCREMENT | UNIQUE identifier FOR contract | | project_id | INT | NOT NULL,
|
||
FK | Reference TO projects TABLE | | contract_code | VARCHAR(50) | NOT NULL,
|
||
UNIQUE | Contract code | | contract_name | VARCHAR(255) | NOT NULL | FULL contract name | | description | TEXT | NULL | Contract description | | start_date | DATE | NULL | Contract START date | | end_date | DATE | NULL | Contract
|
||
END date | | is_active | BOOLEAN | DEFAULT TRUE | Active STATUS | | created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | | updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last
|
||
UPDATE timestamp |
|
||
| deleted_at | DATETIME | NULL | Soft delete timestamp | ** INDEXES **: - PRIMARY KEY (id) - UNIQUE (contract_code) - FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE - INDEX (project_id, is_active) ** Relationships **: - Parent: projects - Referenced by: contract_organizations,
|
||
user_assignments ---
|
||
|
||
### 1.5 disciplines (NEW v1.5.1)
|
||
|
||
* * Purpose **: āđāļāđāļāļāđāļāļĄāļđāļĨāļŠāļēāļāļēāļāļēāļ (Disciplines) āđāļĒāļāļāļēāļĄāļŠāļąāļāļāļē (Req 6B) | COLUMN Name | Data TYPE | Constraints | Description | |: -------------- | :----------- | :----------- | :--------------------- |
|
||
| id | INT | PK,
|
||
AI | UNIQUE identifier | | contract_id | INT | FK,
|
||
NOT NULL | āļāļđāļāļāļąāļāļŠāļąāļāļāļē | | discipline_code | VARCHAR(10) | NOT NULL | āļĢāļŦāļąāļŠāļŠāļēāļāļē (āđāļāđāļ GEN, STR) | | code_name_th | VARCHAR(255) | NULL | āļāļ·āđāļāđāļāļĒ | | code_name_en | VARCHAR(255) | NULL | āļāļ·āđāļāļāļąāļāļāļĪāļĐ | | is_active | TINYINT(1) | DEFAULT 1 | āļŠāļāļēāļāļ°āļāļēāļĢāđāļāđāļāļēāļ | ** INDEXES **: - UNIQUE (contract_id, discipline_code) ---
|
||
|
||
## **2. ðĨ Users & RBAC Tables (āļāļđāđāđāļāđ, āļŠāļīāļāļāļīāđ, āļāļāļāļēāļ)**
|
||
|
||
### 2.1 users
|
||
|
||
* * Purpose **: MASTER TABLE storing ALL system users | COLUMN Name | Data TYPE | Constraints | Description | | ----------------------- | ------------ | ----------------------------------- | -------------------------------- |
|
||
| user_id | INT | PRIMARY KEY,
|
||
AUTO_INCREMENT | UNIQUE identifier FOR user | | username | VARCHAR(50) | NOT NULL,
|
||
UNIQUE | Login username | | password_hash | VARCHAR(255) | NOT NULL | Hashed PASSWORD (bcrypt) | | first_name | VARCHAR(50) | NULL | User 's first name |
|
||
| last_name | VARCHAR(50) | NULL | User' s last name | | email | VARCHAR(100) | NOT NULL,
|
||
UNIQUE | Email address | | line_id | VARCHAR(100) | NULL | LINE messenger ID | | primary_organization_id | INT | NULL,
|
||
FK | PRIMARY organization affiliation | | is_active | TINYINT(1) | DEFAULT 1 | Active STATUS | | failed_attempts | INT | DEFAULT 0 | Failed login attempts counter | | locked_until | DATETIME | NULL | Account LOCK expiration time | | last_login_at | TIMESTAMP | NULL | Last successful login timestamp | | created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | | updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last
|
||
UPDATE timestamp | | deleted_at | DATETIME | NULL | Deleted at | ** INDEXES **: - PRIMARY KEY (user_id) - UNIQUE (username) - UNIQUE (email) - FOREIGN KEY (primary_organization_id) REFERENCES organizations(id) ON DELETE
|
||
SET NULL - INDEX (is_active) - INDEX (email) ** Relationships **: - Parent: organizations (primary_organization_id) - Referenced by: user_assignments,
|
||
audit_logs,
|
||
notifications,
|
||
circulation_routings ---
|
||
|
||
### 2.2 roles
|
||
|
||
* * Purpose **: MASTER TABLE defining system roles WITH scope levels | COLUMN Name | Data TYPE | Constraints | Description | | ----------- | ------------ | --------------------------- | ---------------------------------------------------- |
|
||
| role_id | INT | PRIMARY KEY,
|
||
AUTO_INCREMENT | UNIQUE identifier FOR role | | role_name | VARCHAR(100) | NOT NULL | Role name (e.g., 'Superadmin', 'Document Control') | | scope | ENUM | NOT NULL | Scope LEVEL: GLOBAL,
|
||
Organization,
|
||
Project,
|
||
Contract | | description | TEXT | NULL | Role description | | is_system | BOOLEAN | DEFAULT FALSE | System role flag (cannot be deleted) |
|
||
| 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 |
|
||
** INDEXES **: - PRIMARY KEY (role_id) - INDEX (scope) ** Relationships **: - Referenced by: role_permissions,
|
||
user_assignments ---
|
||
|
||
### 2.3 permissions
|
||
|
||
* * Purpose **: MASTER TABLE defining ALL system permissions | COLUMN Name | Data TYPE | Constraints | Description | | --------------- | ------------ | --------------------------- | ------------------------------------------------------ |
|
||
| permission_id | INT | PRIMARY KEY,
|
||
AUTO_INCREMENT | UNIQUE identifier FOR permission | | permission_name | VARCHAR(100) | NOT NULL,
|
||
UNIQUE | Permission code (e.g., 'rfas.create', 'document.view') | | description | TEXT | NULL | Permission description | | module | VARCHAR(50) | NULL | Related module name | | scope_level | ENUM | NULL | Scope: GLOBAL,
|
||
ORG,
|
||
PROJECT | | is_active | TINYINT(1) | DEFAULT 1 | Active STATUS |
|
||
| 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 |
|
||
** INDEXES **: - PRIMARY KEY (permission_id) - UNIQUE (permission_name) - INDEX (module) - INDEX (scope_level) - INDEX (is_active) ** Relationships **: - Referenced by: role_permissions ---
|
||
|
||
### 2.4 role_permissions
|
||
|
||
* * Purpose **: Junction TABLE mapping roles TO permissions (M :N) | COLUMN Name | Data TYPE | Constraints | Description | | ------------- | --------- | --------------- | ------------------------------ |
|
||
| role_id | INT | PRIMARY KEY,
|
||
FK | Reference TO roles TABLE | | permission_id | INT | PRIMARY KEY,
|
||
FK | Reference TO permissions TABLE | ** INDEXES **: - PRIMARY KEY (role_id, permission_id) - FOREIGN KEY (role_id) REFERENCES roles(role_id) ON DELETE CASCADE - FOREIGN KEY (permission_id) REFERENCES permissions(permission_id) ON DELETE CASCADE - INDEX (permission_id) ** Relationships **: - Parent: roles,
|
||
permissions ---
|
||
|
||
### 2.5 user_assignments
|
||
|
||
* * Purpose **: Junction TABLE assigning users TO roles WITH scope context | COLUMN Name | Data TYPE | Constraints | Description | | ------------------- | --------- | --------------------------- | ---------------------------------- |
|
||
| id | INT | PRIMARY KEY,
|
||
AUTO_INCREMENT | UNIQUE identifier | | user_id | INT | NOT NULL,
|
||
FK | Reference TO users TABLE | | role_id | INT | NOT NULL,
|
||
FK | Reference TO roles TABLE | | organization_id | INT | NULL,
|
||
FK | Organization scope (IF applicable) | | project_id | INT | NULL,
|
||
FK | Project scope (IF applicable) | | contract_id | INT | NULL,
|
||
FK | Contract scope (IF applicable) | | assigned_by_user_id | INT | NULL,
|
||
FK | User who made the assignment | | assigned_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Assignment timestamp | ** INDEXES **: - PRIMARY KEY (id) - FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE - FOREIGN KEY (role_id) REFERENCES roles(role_id) ON DELETE CASCADE - FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE - FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE - FOREIGN KEY (contract_id) REFERENCES contracts(id) ON DELETE CASCADE - FOREIGN KEY (assigned_by_user_id) REFERENCES users(user_id) - INDEX (user_id, role_id) - INDEX (organization_id) - INDEX (project_id) - INDEX (contract_id) ** Relationships **: - Parent: users,
|
||
roles,
|
||
organizations,
|
||
projects,
|
||
contracts ---
|
||
|
||
### 2.6 project_organizations
|
||
|
||
* * Purpose **: Junction TABLE linking projects TO participating organizations (M :N) | COLUMN Name | Data TYPE | Constraints | Description | | --------------- | --------- | --------------- | -------------------------------- |
|
||
| project_id | INT | PRIMARY KEY,
|
||
FK | Reference TO projects TABLE | | organization_id | INT | PRIMARY KEY,
|
||
FK | Reference TO organizations TABLE | ** INDEXES **: - PRIMARY KEY (project_id, organization_id) - FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE - FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE - INDEX (organization_id) ** Relationships **: - Parent: projects,
|
||
organizations ---
|
||
|
||
### 2.7 contract_organizations
|
||
|
||
* * Purpose **: Junction TABLE linking contracts TO participating organizations WITH roles (M :N) | COLUMN Name | Data TYPE | Constraints | Description | | ---------------- | ------------ | --------------- | ------------------------------------------------------------------------- |
|
||
| contract_id | INT | PRIMARY KEY,
|
||
FK | Reference TO contracts TABLE | | organization_id | INT | PRIMARY KEY,
|
||
FK | Reference TO organizations TABLE | | role_in_contract | VARCHAR(100) | NULL | Organization 's role in contract (Owner, Designer, Consultant, Contractor) |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (contract_id, organization_id)
|
||
* FOREIGN KEY (contract_id) REFERENCES contracts(id) ON DELETE CASCADE
|
||
* FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE
|
||
* INDEX (organization_id)
|
||
* INDEX (role_in_contract)
|
||
|
||
**Relationships**:
|
||
|
||
* Parent: contracts, organizations
|
||
|
||
---
|
||
|
||
### 2.8 user_preferences (NEW v1.5.1)
|
||
|
||
**Purpose**: āđāļāđāļāļāļēāļĢāļāļąāđāļāļāđāļēāļŠāđāļ§āļāļāļąāļ§āļāļāļāļāļđāđāđāļāđ (Req 5.5, 6.8.3)
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| :----------- | :---------- | :---------------- | :-------------- |
|
||
| user_id | INT | PK, FK | User ID |
|
||
| notify_email | BOOLEAN | DEFAULT TRUE | āļĢāļąāļāļāļĩāđāļĄāļĨāđāļāđāļāđāļāļ·āļāļ |
|
||
| notify_line | BOOLEAN | DEFAULT TRUE | āļĢāļąāļāđāļĨāļāđāđāļāđāļāđāļāļ·āļāļ |
|
||
| digest_mode | BOOLEAN | DEFAULT FALSE | āļĢāļąāļāđāļāđāļāđāļāļ·āļāļāđāļāļāļĢāļ§āļĄ |
|
||
| ui_theme | VARCHAR(20) | DEFAULT ' light ' | UI Theme |
|
||
|
||
---
|
||
|
||
### 2.9 refresh_tokens (NEW v1.5.1)
|
||
|
||
**Purpose**: āđāļāđāļ Refresh Tokens āļŠāļģāļŦāļĢāļąāļāļāļēāļĢāļāļģ Authentication āđāļĨāļ° Token Rotation
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| :---------------- | :----------- | :------------------------ | :------------------------------------ |
|
||
| token_id | INT | PK, AI | Unique Token ID |
|
||
| user_id | INT | FK, NOT NULL | āđāļāđāļēāļāļāļ Token |
|
||
| token_hash | VARCHAR(255) | NOT NULL | Hash āļāļāļ Refresh Token (Security) |
|
||
| expires_at | DATETIME | NOT NULL | āļ§āļąāļāļŦāļĄāļāļāļēāļĒāļļāļāļāļ Token |
|
||
| is_revoked | BOOLEAN | DEFAULT FALSE | āļŠāļāļēāļāļ°āļāļđāļāļĒāļāđāļĨāļīāļ (True = āđāļāđāļāļēāļāđāļĄāđāđāļāđ) |
|
||
| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | āđāļ§āļĨāļēāļāļĩāđāļŠāļĢāđāļēāļ |
|
||
| replaced_by_token | VARCHAR(255) | NULL | Token āđāļŦāļĄāđāļāļĩāđāļĄāļēāđāļāļāļāļĩāđ (āļāļĢāļāļĩ Token Rotation) |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (token_id)
|
||
* FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE
|
||
* INDEX (user_id)
|
||
|
||
**Relationships**:
|
||
|
||
* Parent: users
|
||
|
||
---
|
||
|
||
## **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 |
|
||
| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp |
|
||
| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Last update timestamp |
|
||
| deleted_at | DATETIME | NULL | Soft delete timestamp |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (id)
|
||
* UNIQUE (type_code)
|
||
* INDEX (is_active)
|
||
* INDEX (sort_order)
|
||
|
||
**Relationships**:
|
||
|
||
* Referenced by: correspondences, document_number_formats, document_number_counters
|
||
|
||
---
|
||
|
||
### 3.2 correspondence_sub_types (NEW v1.5.1)
|
||
|
||
**Purpose**: āđāļāđāļāļāļĢāļ°āđāļ āļāļŦāļāļąāļāļŠāļ·āļāļĒāđāļāļĒ (Sub Types) āļŠāļģāļŦāļĢāļąāļ Mapping āđāļĨāļāļĢāļŦāļąāļŠ (Req 6B)
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| :--------------------- | :----------- | :----------- | :------------------------ |
|
||
| id | INT | PK, AI | Unique identifier |
|
||
| contract_id | INT | FK, NOT NULL | āļāļđāļāļāļąāļāļŠāļąāļāļāļē |
|
||
| correspondence_type_id | INT | FK, NOT NULL | āļāļđāļāļāļąāļāļāļĢāļ°āđāļ āļāđāļāļāļŠāļēāļĢāļŦāļĨāļąāļ |
|
||
| sub_type_code | VARCHAR(20) | NOT NULL | āļĢāļŦāļąāļŠāļĒāđāļāļĒ (āđāļāđāļ MAT, SHP) |
|
||
| sub_type_name | VARCHAR(255) | NULL | āļāļ·āđāļāļāļĢāļ°āđāļ āļāļŦāļāļąāļāļŠāļ·āļāļĒāđāļāļĒ |
|
||
| sub_type_number | VARCHAR(10) | NULL | āđāļĨāļāļĢāļŦāļąāļŠāļŠāļģāļŦāļĢāļąāļ Running Number |
|
||
|
||
---
|
||
|
||
### 3.3 correspondences (UPDATE v1.7.0)
|
||
|
||
**Purpose**: Master table for correspondence documents (non-revisioned data)
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| ------------------------- | ------------ | --------------------------- | ------------------------------------------ |
|
||
| id | INT | PRIMARY KEY, AUTO_INCREMENT | Master correspondence ID |
|
||
| correspondence_number | VARCHAR(100) | NOT NULL | Document number (from numbering system) |
|
||
| correspondence_type_id | INT | NOT NULL, FK | Reference to correspondence_types |
|
||
| **discipline_id** | **INT** | **NULL, FK** | **[NEW] āļŠāļēāļāļēāļāļēāļ (āļāđāļēāļĄāļĩ)** |
|
||
| is_internal_communication | TINYINT(1) | DEFAULT 0 | Internal (1) or external (0) communication |
|
||
| project_id | INT | NOT NULL, FK | Reference to projects table |
|
||
| originator_id | INT | NULL, FK | Originating organization |
|
||
| created_at | DATETIME | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp |
|
||
| created_by | INT | NULL, FK | User who created the record |
|
||
| deleted_at | DATETIME | NULL | Soft delete timestamp |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (id)
|
||
* FOREIGN KEY (correspondence_type_id) REFERENCES correspondence_types(id) ON DELETE RESTRICT
|
||
* **FOREIGN KEY (discipline_id) REFERENCES disciplines(id) ON DELETE SET NULL**
|
||
* FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE
|
||
* FOREIGN KEY (originator_id) REFERENCES organizations(id) ON DELETE SET NULL
|
||
* FOREIGN KEY (created_by) REFERENCES users(user_id) ON DELETE SET NULL
|
||
* UNIQUE KEY (project_id, correspondence_number)
|
||
* INDEX (correspondence_type_id)
|
||
* INDEX (originator_id)
|
||
* INDEX (deleted_at)
|
||
|
||
**Relationships**:
|
||
|
||
* Parent: correspondence_types, **disciplines**, projects, organizations, users
|
||
* Children: correspondence_revisions, correspondence_recipients, correspondence_tags, correspondence_references, correspondence_attachments, circulations, transmittals
|
||
|
||
---
|
||
|
||
### 3.4 correspondence_revisions (UPDATE v1.7.0)
|
||
|
||
**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_doc_subtype | VARCHAR(50) | GENERATED ALWAYS AS (...) VIRTUAL | Virtual Column āļāļķāļ Type āļāļēāļ JSON details |
|
||
| schema_version | INT | DEFAULT 1 | Version of the schema used with this details |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (id)
|
||
* FOREIGN KEY (correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE
|
||
* FOREIGN KEY (correspondence_status_id) REFERENCES correspondence_status(id) ON DELETE RESTRICT
|
||
* FOREIGN KEY (created_by) REFERENCES users(user_id) ON DELETE SET NULL
|
||
* FOREIGN KEY (updated_by) REFERENCES users(user_id) ON DELETE SET NULL
|
||
* UNIQUE KEY (correspondence_id, revision_number)
|
||
* UNIQUE KEY (correspondence_id, is_current)
|
||
* INDEX (correspondence_status_id)
|
||
* INDEX (is_current)
|
||
* INDEX (document_date)
|
||
* INDEX (issued_date)
|
||
* INDEX (v_ref_project_id)
|
||
* INDEX (v_doc_subtype)
|
||
|
||
---
|
||
|
||
### 3.5 correspondence_recipients
|
||
|
||
**Purpose**: Junction table for correspondence recipients (TO/CC) (M:N)
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| ------------------------- | -------------------- | --------------- | ---------------------------- |
|
||
| correspondence_id | INT | PRIMARY KEY, FK | Reference to correspondences |
|
||
| recipient_organization_id | INT | PRIMARY KEY, FK | Recipient organization |
|
||
| recipient_type | ENUM(' TO ', ' CC ') | PRIMARY KEY | Recipient type |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (correspondence_id, recipient_organization_id, recipient_type)
|
||
* FOREIGN KEY (correspondence_id) REFERENCES correspondence_revisions(correspondence_id) ON DELETE CASCADE
|
||
* FOREIGN KEY (recipient_organization_id) REFERENCES organizations(id) ON DELETE RESTRICT
|
||
* INDEX (recipient_organization_id)
|
||
* INDEX (recipient_type)
|
||
|
||
**Relationships**:
|
||
|
||
* Parent: correspondences, organizations
|
||
|
||
---
|
||
|
||
### 3.6 tags
|
||
|
||
**Purpose**: Master table for document tagging system
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| ----------- | ------------ | ----------------------------------- | ------------------------- |
|
||
| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique tag ID |
|
||
| tag_name | VARCHAR(100) | NOT NULL, UNIQUE | Tag name |
|
||
| description | TEXT | NULL | Tag description |
|
||
| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp |
|
||
| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (id)
|
||
* UNIQUE (tag_name)
|
||
* INDEX (tag_name) - For autocomplete
|
||
|
||
**Relationships**:
|
||
|
||
* Referenced by: correspondence_tags
|
||
|
||
---
|
||
|
||
### 3.7 correspondence_tags
|
||
|
||
**Purpose**: Junction table linking correspondences to tags (M:N)
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| ----------------- | --------- | --------------- | ---------------------------- |
|
||
| correspondence_id | INT | PRIMARY KEY, FK | Reference to correspondences |
|
||
| tag_id | INT | PRIMARY KEY, FK | Reference to tags |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (correspondence_id, tag_id)
|
||
* FOREIGN KEY (correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE
|
||
* FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE
|
||
* INDEX (tag_id)
|
||
|
||
**Relationships**:
|
||
|
||
* Parent: correspondences, tags
|
||
|
||
---
|
||
|
||
### 3.8 correspondence_references
|
||
|
||
**Purpose**: Junction table for cross-referencing correspondences (M:N)
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| --------------------- | --------- | --------------- | ------------------------------------- |
|
||
| src_correspondence_id | INT | PRIMARY KEY, FK | Source correspondence ID |
|
||
| tgt_correspondence_id | INT | PRIMARY KEY, FK | Target (referenced) correspondence ID |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (src_correspondence_id, tgt_correspondence_id)
|
||
* FOREIGN KEY (src_correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE
|
||
* FOREIGN KEY (tgt_correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE
|
||
* INDEX (tgt_correspondence_id)
|
||
|
||
**Relationships**:
|
||
|
||
* Parent: correspondences (both sides)
|
||
|
||
---
|
||
|
||
## **4. ð approval: RFA Tables (āđāļāļāļŠāļēāļĢāļāļāļāļāļļāļĄāļąāļāļī, Workflows)**
|
||
|
||
### 4.1 rfa_types (UPDATE v1.7.0)
|
||
|
||
**Purpose**: Master table for RFA (Request for Approval) types
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| :----------- | :----------- | :-------------------------- | :------------------------------ |
|
||
| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier |
|
||
| contract_id | INT | NOT NULL, FK | Contract reference |
|
||
| type_code | VARCHAR(20) | NOT NULL | Type code (DWG, DOC, MAT, etc.) |
|
||
| type_name_th | VARCHAR(100) | NOT NULL | Full type name (TH) |
|
||
| type_name_en | VARCHAR(100) | NOT NULL | Full type name (EN) |
|
||
| remark | TEXT | NULL | Remark |
|
||
| is_active | TINYINT(1) | DEFAULT 1 | Active status |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (id)
|
||
* UNIQUE (contract_id, type_code)
|
||
* FOREIGN KEY (contract_id) REFERENCES contracts(id) ON DELETE CASCADE
|
||
* INDEX (is_active)
|
||
|
||
**Relationships**:
|
||
|
||
* Referenced by: rfas
|
||
|
||
---
|
||
|
||
### 4.2 rfa_status_codes
|
||
|
||
**Purpose**: Master table for RFA status codes
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| ----------- | ------------ | --------------------------- | --------------------------------- |
|
||
| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier |
|
||
| status_code | VARCHAR(20) | NOT NULL, UNIQUE | Status code (DFT, FAP, FRE, etc.) |
|
||
| status_name | VARCHAR(100) | NOT NULL | Full status name |
|
||
| description | TEXT | NULL | Status description |
|
||
| sort_order | INT | DEFAULT 0 | Display order |
|
||
| is_active | TINYINT(1) | DEFAULT 1 | Active status |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (id)
|
||
* UNIQUE (status_code)
|
||
* INDEX (is_active)
|
||
* INDEX (sort_order)
|
||
|
||
**Relationships**:
|
||
|
||
* Referenced by: rfa_revisions
|
||
|
||
---
|
||
|
||
### 4.3 rfa_approve_codes
|
||
|
||
**Purpose**: Master table for RFA approval result codes
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| ------------ | ------------ | --------------------------- | -------------------------------- |
|
||
| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier |
|
||
| approve_code | VARCHAR(20) | NOT NULL, UNIQUE | Approval code (1A, 1C, 3R, etc.) |
|
||
| approve_name | VARCHAR(100) | NOT NULL | Full approval name |
|
||
| description | TEXT | NULL | Code description |
|
||
| sort_order | INT | DEFAULT 0 | Display order |
|
||
| is_active | TINYINT(1) | DEFAULT 1 | Active status |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (id)
|
||
* UNIQUE (approve_code)
|
||
* INDEX (is_active)
|
||
* INDEX (sort_order)
|
||
|
||
**Relationships**:
|
||
|
||
* Referenced by: rfa_revisions
|
||
|
||
---
|
||
|
||
### 4.4 rfas (UPDATE v1.7.0)
|
||
|
||
**Purpose**: Master table for RFA documents (non-revisioned data)
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| :---------- | :-------- | :------------------------ | :------------------------------------------ |
|
||
| id | INT | PK, FK | Master RFA ID (Shared with correspondences) |
|
||
| rfa_type_id | INT | NOT NULL, FK | Reference to rfa_types |
|
||
| created_at | DATETIME | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp |
|
||
| created_by | INT | NULL, FK | User who created the record |
|
||
| deleted_at | DATETIME | NULL | Soft delete timestamp |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (id)
|
||
* FOREIGN KEY (id) REFERENCES correspondences(id) ON DELETE CASCADE
|
||
* FOREIGN KEY (rfa_type_id) REFERENCES rfa_types(id)
|
||
* FOREIGN KEY (created_by) REFERENCES users(user_id) ON DELETE SET NULL
|
||
* INDEX (rfa_type_id)
|
||
* INDEX (deleted_at)
|
||
|
||
**Relationships**:
|
||
|
||
* Parent: correspondences, rfa_types, users
|
||
* Children: rfa_revisions
|
||
|
||
---
|
||
|
||
### 4.5 rfa_revisions (UPDATE v1.7.0)
|
||
|
||
**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 |
|
||
|
||
| rfa_id | INT | NOT NULL, FK | Master RFA ID |
|
||
| revision_number | INT | NOT NULL | Revision sequence (0, 1, 2...) |
|
||
| revision_label | VARCHAR(10) | NULL | Display revision (A, B, 1.1...) |
|
||
| is_current | BOOLEAN | DEFAULT FALSE | Current revision flag |
|
||
| rfa_status_code_id | INT | NOT NULL, FK | Current RFA status |
|
||
| rfa_approve_code_id | INT | NULL, FK | Approval result code |
|
||
| title | VARCHAR(255) | NOT NULL | RFA title |
|
||
| document_date | DATE | NULL | Document date |
|
||
| issued_date | DATE | NULL | Issue date for approval |
|
||
| received_date | DATETIME | NULL | Received date |
|
||
| approved_date | DATE | NULL | Approval date |
|
||
| description | TEXT | NULL | Revision description |
|
||
| created_at | DATETIME | DEFAULT CURRENT_TIMESTAMP | Revision creation timestamp |
|
||
| created_by | INT | NULL, FK | User who created revision |
|
||
| updated_by | INT | NULL, FK | User who last updated |
|
||
| details | JSON | NULL | Type-specific details (e.g., RFI questions) |
|
||
| v_ref_drawing_count | INT | GENERATED ALWAYS AS (...) VIRTUAL | Virtual Column āļāļķāļ Drawing Count āļāļēāļ JSON details āđāļāļ·āđāļāļāļģ Index |
|
||
| schema_version | INT | DEFAULT 1 | Version of the schema used with this details |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (id)
|
||
* FOREIGN KEY (rfa_id) REFERENCES rfas(id) ON DELETE CASCADE
|
||
* FOREIGN KEY (rfa_status_code_id) REFERENCES rfa_status_codes(id)
|
||
* FOREIGN KEY (rfa_approve_code_id) REFERENCES rfa_approve_codes(id) ON DELETE SET NULL
|
||
* FOREIGN KEY (created_by) REFERENCES users(user_id) ON DELETE SET NULL
|
||
* FOREIGN KEY (updated_by) REFERENCES users(user_id) ON DELETE SET NULL
|
||
* UNIQUE KEY (rfa_id, revision_number)
|
||
* UNIQUE KEY (rfa_id, is_current)
|
||
* INDEX (rfa_status_code_id)
|
||
* INDEX (rfa_approve_code_id)
|
||
* INDEX (is_current)
|
||
* INDEX (v_ref_drawing_count): āļāļąāļ§āļāļĒāđāļēāļāļāļēāļĢ Index āļāđāļāļĄāļđāļĨāļāļąāļ§āđāļĨāļāđāļ JSON
|
||
|
||
**Relationships**:
|
||
|
||
* Parent: correspondences, rfas, rfa_status_codes, rfa_approve_codes, users
|
||
* Children: rfa_items
|
||
|
||
---
|
||
|
||
### 4.6 rfa_items
|
||
|
||
**Purpose**: Junction table linking RFA revisions to shop drawing revisions (M:N)
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| :----------------------- | :-------- | :-------------- | :----------------------- |
|
||
| rfa_revision_id | INT | PRIMARY KEY, FK | RFA Revision ID |
|
||
| shop_drawing_revision_id | INT | PRIMARY KEY, FK | Shop drawing revision ID |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (rfa_revision_id, shop_drawing_revision_id)
|
||
* FOREIGN KEY (rfa_revision_id) REFERENCES rfa_revisions(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
|
||
|
||
---
|
||
|
||
|
||
---
|
||
|
||
## **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 (UPDATE v1.7.0)
|
||
|
||
**Purpose**: Junction table mapping sub-categories to main categories (M:N)
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| ----------- | --------- | ------------------------------- | -------------------------- |
|
||
| **id** | **INT** | **PRIMARY KEY, AUTO_INCREMENT** | **Unique mapping ID** |
|
||
| project_id | INT | NOT NULL, FK | Reference to projects |
|
||
| sub_cat_id | INT | NOT NULL, FK | Reference to sub-category |
|
||
| cat_id | INT | NOT NULL, FK | Reference to main category |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (id)
|
||
* **UNIQUE 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
|
||
* Referenced by: contract_drawings
|
||
|
||
**Business Rules**:
|
||
|
||
* Allows flexible categorization
|
||
* One sub-category can belong to multiple main categories
|
||
* Composite uniqueness enforced via UNIQUE constraint
|
||
|
||
---
|
||
|
||
### 5.5 contract_drawings (UPDATE v1.7.0)
|
||
|
||
**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 |
|
||
| **map_cat_id** | **INT** | **NULL, FK** | **[CHANGED] Reference to mapping table** |
|
||
| volume_id | INT | NULL, FK | Reference to volume |
|
||
| **volume_page** | **INT** | **NULL** | **[NEW] Page number within 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 (map_cat_id) REFERENCES contract_drawing_subcat_cat_maps(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 (map_cat_id)
|
||
* INDEX (volume_id)
|
||
* INDEX (deleted_at)
|
||
|
||
**Relationships**:
|
||
|
||
* Parent: projects, contract_drawing_subcat_cat_maps, 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
|
||
* **map_cat_id references the mapping table for flexible categorization**
|
||
|
||
---
|
||
|
||
### 5.6 shop_drawing_main_categories (UPDATE v1.7.0)
|
||
|
||
**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 |
|
||
| **project_id** | **INT** | **NOT NULL, FK** | **[NEW] Reference to projects** |
|
||
| 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)
|
||
* **FOREIGN KEY (project_id) REFERENCES projects(id)**
|
||
* UNIQUE (main_category_code)
|
||
* INDEX (is_active)
|
||
* INDEX (sort_order)
|
||
|
||
**Relationships**:
|
||
|
||
* **Parent: projects**
|
||
* Referenced by: shop_drawings, asbuilt_drawings
|
||
|
||
**Business Rules**:
|
||
|
||
* **[CHANGED] Project-specific categories (was global)**
|
||
* Typically represents engineering disciplines
|
||
|
||
---
|
||
|
||
### 5.7 shop_drawing_sub_categories (UPDATE v1.7.0)
|
||
|
||
**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 |
|
||
| **project_id** | **INT** | **NOT NULL, FK** | **[NEW] Reference to projects** |
|
||
| 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 |
|
||
| 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)
|
||
* **FOREIGN KEY (project_id) REFERENCES projects(id)**
|
||
* UNIQUE (sub_category_code)
|
||
* INDEX (is_active)
|
||
* INDEX (sort_order)
|
||
|
||
**Relationships**:
|
||
|
||
* **Parent: projects**
|
||
* Referenced by: shop_drawings, asbuilt_drawings
|
||
|
||
**Business Rules**:
|
||
|
||
* **[CHANGED] Project-specific sub-categories (was global)**
|
||
* **[REMOVED] No longer hierarchical under main categories**
|
||
* Represents specific drawing types or components
|
||
|
||
---
|
||
|
||
### 5.8 shop_drawings (UPDATE v1.7.0)
|
||
|
||
**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 |
|
||
| 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
|
||
* **[CHANGED] Title moved to shop_drawing_revisions table**
|
||
|
||
---
|
||
|
||
### 5.9 shop_drawing_revisions (UPDATE v1.7.0)
|
||
|
||
**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 |
|
||
| **title** | **VARCHAR(500)** | **NOT NULL** | **[NEW] Drawing title** |
|
||
| description | TEXT | NULL | Revision description/changes |
|
||
| **legacy_drawing_number** | **VARCHAR(100)** | **NULL** | **[NEW] Original/legacy drawing number** |
|
||
| 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, asbuilt_revision_shop_revisions_refs
|
||
|
||
**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
|
||
* **[NEW] Title stored at revision level for version-specific naming**
|
||
* **[NEW] legacy_drawing_number supports data migration from old systems**
|
||
|
||
---
|
||
|
||
### 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
|
||
|
||
---
|
||
|
||
### 5.11 asbuilt_drawings (NEW v1.7.0)
|
||
|
||
**Purpose**: Master table for AS Built drawings (final construction records)
|
||
|
||
| 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 | AS Built drawing number |
|
||
| 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: asbuilt_drawing_revisions
|
||
|
||
**Business Rules**:
|
||
|
||
* Drawing numbers are globally unique across all projects
|
||
* Represents final as-built construction drawings
|
||
* Can have multiple revisions
|
||
* Soft delete preserves history
|
||
* Uses same category structure as shop drawings
|
||
|
||
---
|
||
|
||
### 5.12 asbuilt_drawing_revisions (NEW v1.7.0)
|
||
|
||
**Purpose**: Child table storing revision history of AS Built drawings (1:N)
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| --------------------- | ------------ | --------------------------- | ------------------------------ |
|
||
| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique revision ID |
|
||
| asbuilt_drawing_id | INT | NOT NULL, FK | Master AS Built 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 |
|
||
| title | VARCHAR(500) | NOT NULL | Drawing title |
|
||
| description | TEXT | NULL | Revision description/changes |
|
||
| legacy_drawing_number | VARCHAR(100) | NULL | Original/legacy drawing number |
|
||
| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Revision creation timestamp |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (id)
|
||
* FOREIGN KEY (asbuilt_drawing_id) REFERENCES asbuilt_drawings(id) ON DELETE CASCADE
|
||
* UNIQUE KEY (asbuilt_drawing_id, revision_number)
|
||
* INDEX (revision_date)
|
||
|
||
**Relationships**:
|
||
|
||
* Parent: asbuilt_drawings
|
||
* Referenced by: asbuilt_revision_shop_revisions_refs, asbuilt_drawing_revision_attachments
|
||
|
||
**Business Rules**:
|
||
|
||
* Revision numbers are sequential starting from 0
|
||
* Each revision can reference multiple shop drawing revisions
|
||
* Each revision can have multiple file attachments
|
||
* Title stored at revision level for version-specific naming
|
||
* legacy_drawing_number supports data migration from old systems
|
||
|
||
---
|
||
|
||
### 5.13 asbuilt_revision_shop_revisions_refs (NEW v1.7.0)
|
||
|
||
**Purpose**: Junction table linking AS Built drawing revisions to shop drawing revisions (M:N)
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| --------------------------- | --------- | --------------- | ---------------------------------- |
|
||
| asbuilt_drawing_revision_id | INT | PRIMARY KEY, FK | Reference to AS Built revision |
|
||
| shop_drawing_revision_id | INT | PRIMARY KEY, FK | Reference to shop drawing revision |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (asbuilt_drawing_revision_id, shop_drawing_revision_id)
|
||
* FOREIGN KEY (asbuilt_drawing_revision_id) REFERENCES asbuilt_drawing_revisions(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: asbuilt_drawing_revisions, shop_drawing_revisions
|
||
|
||
**Business Rules**:
|
||
|
||
* Tracks which shop drawings each AS Built drawing revision is based on
|
||
* Maintains construction document lineage
|
||
* One AS Built revision can reference multiple shop drawing revisions
|
||
* Supports traceability from final construction to approved shop drawings
|
||
|
||
---
|
||
|
||
### 5.14 asbuilt_drawing_revision_attachments (NEW v1.7.0)
|
||
|
||
**Purpose**: Junction table linking AS Built drawing revisions to file attachments (M:N)
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| --------------------------- | ------------------------------------- | --------------- | ------------------------------------- |
|
||
| asbuilt_drawing_revision_id | INT | PRIMARY KEY, FK | Reference to AS Built revision |
|
||
| attachment_id | INT | PRIMARY KEY, FK | Reference to attachment file |
|
||
| file_type | ENUM('PDF', 'DWG', 'SOURCE', 'OTHER') | NULL | File type classification |
|
||
| is_main_document | BOOLEAN | DEFAULT FALSE | Main document flag (1 = primary file) |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (asbuilt_drawing_revision_id, attachment_id)
|
||
* FOREIGN KEY (asbuilt_drawing_revision_id) REFERENCES asbuilt_drawing_revisions(id) ON DELETE CASCADE
|
||
* FOREIGN KEY (attachment_id) REFERENCES attachments(id) ON DELETE CASCADE
|
||
* INDEX (attachment_id)
|
||
|
||
**Relationships**:
|
||
|
||
* Parent: asbuilt_drawing_revisions, attachments
|
||
|
||
**Business Rules**:
|
||
|
||
* Each AS Built revision can have multiple file attachments
|
||
* File types: PDF (documents), DWG (CAD files), SOURCE (source files), OTHER (miscellaneous)
|
||
* One attachment can be marked as main document per revision
|
||
* Cascade delete when revision is deleted
|
||
|
||
---
|
||
|
||
## **6. ð Circulations Tables (āđāļāđāļ§āļĩāļĒāļāļ āļēāļĒāđāļ)**
|
||
|
||
### 6.1 circulation_status_codes
|
||
|
||
**Purpose**: Master table for circulation workflow status codes
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| ----------- | ----------- | --------------------------- | --------------------------------------------------- |
|
||
| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique status ID |
|
||
| code | VARCHAR(20) | NOT NULL, UNIQUE | Status code (OPEN, IN_REVIEW, COMPLETED, CANCELLED) |
|
||
| description | VARCHAR(50) | NOT NULL | Status description |
|
||
| sort_order | INT | DEFAULT 0 | Display order |
|
||
| is_active | TINYINT(1) | DEFAULT 1 | Active status |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (id)
|
||
* UNIQUE (code)
|
||
* INDEX (is_active)
|
||
* INDEX (sort_order)
|
||
|
||
**Relationships**:
|
||
|
||
* Referenced by: circulations
|
||
|
||
**Seed Data**: 4 status codes
|
||
|
||
* OPEN: Initial status when created
|
||
* IN_REVIEW: Under review by recipients
|
||
* COMPLETED: All recipients have responded
|
||
* CANCELLED: Withdrawn/cancelled
|
||
|
||
---
|
||
|
||
### 6.2 circulations
|
||
|
||
**Purpose**: Master table for internal circulation sheets (document routing)
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| ----------------------- | ------------ | ----------------------------------- | ----------------------------------------- |
|
||
| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique circulation ID |
|
||
| correspondence_id | INT | UNIQUE, FK | Link to correspondence (1:1 relationship) |
|
||
| organization_id | INT | NOT NULL, FK | Organization that owns this circulation |
|
||
| circulation_no | VARCHAR(100) | NOT NULL | Circulation sheet number |
|
||
| circulation_subject | VARCHAR(500) | NOT NULL | Subject/title |
|
||
| circulation_status_code | VARCHAR(20) | NOT NULL, FK | Current status code |
|
||
| created_by_user_id | INT | NOT NULL, FK | User who created circulation |
|
||
| submitted_at | TIMESTAMP | NULL | Submission timestamp |
|
||
| closed_at | TIMESTAMP | NULL | Closure timestamp |
|
||
| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp |
|
||
| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (id)
|
||
* UNIQUE (correspondence_id)
|
||
* FOREIGN KEY (correspondence_id) REFERENCES correspondences(id)
|
||
* FOREIGN KEY (organization_id) REFERENCES organizations(id)
|
||
* FOREIGN KEY (circulation_status_code) REFERENCES circulation_status_codes(code)
|
||
* FOREIGN KEY (created_by_user_id) REFERENCES users(user_id)
|
||
* INDEX (organization_id)
|
||
* INDEX (circulation_status_code)
|
||
* INDEX (created_by_user_id)
|
||
|
||
**Relationships**:
|
||
|
||
* Parent: correspondences, organizations, circulation_status_codes, users
|
||
* Children: circulation_routings, circulation_attachments
|
||
|
||
**Business Rules**:
|
||
|
||
* Internal document routing within organization
|
||
* One-to-one relationship with correspondences
|
||
* Tracks document review/approval workflow
|
||
* Status progression: OPEN â IN_REVIEW â COMPLETED/CANCELLED
|
||
|
||
---
|
||
|
||
## **7. ðĪ Transmittals Tables (āđāļāļāļŠāļēāļĢāļāļģāļŠāđāļ)**
|
||
|
||
### 7.1 transmittals
|
||
|
||
**Purpose**: Child table for transmittal-specific data (1:1 with correspondences)
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| ----------------- | --------- | --------------- | --------------------------------------------------------- |
|
||
| correspondence_id | INT | PRIMARY KEY, FK | Reference to correspondences (1:1) |
|
||
| purpose | ENUM | NULL | Purpose: FOR_APPROVAL, FOR_INFORMATION, FOR_REVIEW, OTHER |
|
||
| remarks | TEXT | NULL | Additional remarks |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (correspondence_id)
|
||
* FOREIGN KEY (correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE
|
||
* INDEX (purpose)
|
||
|
||
**Relationships**:
|
||
|
||
* Parent: correspondences
|
||
* Children: transmittal_items
|
||
|
||
**Business Rules**:
|
||
|
||
* One-to-one relationship with correspondences
|
||
* Transmittal is a correspondence type for forwarding documents
|
||
* Contains metadata about the transmission
|
||
|
||
---
|
||
|
||
### 7.2 transmittal_items
|
||
|
||
**Purpose**: Junction table listing documents included in transmittal (M:N)
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| ---------------------- | ------------ | --------------------------- | --------------------------------------- |
|
||
| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique item ID |
|
||
| transmittal_id | INT | NOT NULL, FK | Reference to transmittal |
|
||
| item_correspondence_id | INT | NOT NULL, FK | Reference to document being transmitted |
|
||
| quantity | INT | DEFAULT 1 | Number of copies |
|
||
| remarks | VARCHAR(255) | NULL | Item-specific remarks |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (id)
|
||
* FOREIGN KEY (transmittal_id) REFERENCES transmittals(correspondence_id) ON DELETE CASCADE
|
||
* FOREIGN KEY (item_correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE
|
||
* UNIQUE KEY (transmittal_id, item_correspondence_id)
|
||
* INDEX (item_correspondence_id)
|
||
|
||
**Relationships**:
|
||
|
||
* Parent: transmittals, correspondences
|
||
|
||
**Business Rules**:
|
||
|
||
* One transmittal can contain multiple documents
|
||
* Tracks quantity of physical copies (if applicable)
|
||
* Links to any type of correspondence document
|
||
|
||
---
|
||
|
||
## **8. ð File Management Tables (āđāļāļĨāđāđāļāļ)**
|
||
|
||
### 8.1 attachments
|
||
|
||
**Purpose**: Central repository for all file attachments in the system
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| ------------------- | ------------ | --------------------------- | ------------------------------------------------------------------------ |
|
||
| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique attachment ID |
|
||
| original_filename | VARCHAR(255) | NOT NULL | Original filename from upload |
|
||
| stored_filename | VARCHAR(255) | NOT NULL | System-generated unique filename |
|
||
| file_path | VARCHAR(500) | NOT NULL | Full file path on server (/share/dms-data/) |
|
||
| mime_type | VARCHAR(100) | NOT NULL | MIME type (application/pdf, image/jpeg, etc.) |
|
||
| file_size | INT | NOT NULL | File size in bytes |
|
||
| uploaded_by_user_id | INT | NOT NULL, FK | User who uploaded file |
|
||
| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Upload timestamp |
|
||
| is_temporary | BOOLEAN | DEFAULT TRUE | āļĢāļ°āļāļļāļ§āđāļēāđāļāđāļāđāļāļĨāđāļāļąāđāļ§āļāļĢāļēāļ§ (āļĒāļąāļāđāļĄāđāđāļāđ Commit) |
|
||
| temp_id\* | VARCHAR(100) | NULL | ID āļāļąāđāļ§āļāļĢāļēāļ§āļŠāļģāļŦāļĢāļąāļāļāđāļēāļāļāļīāļāļāļāļ Upload Phase 1 (āļāļēāļāđāļāđāļĢāđāļ§āļĄāļāļąāļ id āļŦāļĢāļ·āļāđāļĒāļāļāđāđāļāđ) |
|
||
| expires_at | DATETIME | NULL | āđāļ§āļĨāļēāļŦāļĄāļāļāļēāļĒāļļāļāļāļāđāļāļĨāđ Temp (āđāļāļ·āđāļāđāļŦāđ Cron Job āļĨāļāļāļāļ) |
|
||
| checksum | VARCHAR(64) | NULL | SHA-256 Checksum āļŠāļģāļŦāļĢāļąāļ Verify File Integrity [Req 3.9.3] |
|
||
| reference_date | DATE | NULL | Date used for folder structure (e.g. Issue Date) to prevent broken paths |
|
||
|
||
**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)
|
||
* INDEX (reference_date)
|
||
|
||
**Relationships**:
|
||
|
||
* Parent: users
|
||
* Referenced by: correspondence_attachments, circulation_attachments, shop_drawing_revision_attachments, contract_drawing_attachments
|
||
|
||
**Business Rules**:
|
||
|
||
* Central storage prevents file duplication
|
||
* Stored filename prevents naming conflicts
|
||
* File path points to QNAP NAS storage
|
||
* Original filename preserved for download
|
||
* One file record can be linked to multiple documents
|
||
|
||
---
|
||
|
||
### 8.2 correspondence_attachments
|
||
|
||
**Purpose**: Junction table linking correspondences to file attachments (M:N)
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| ----------------- | --------- | --------------- | ---------------------------- |
|
||
| correspondence_id | INT | PRIMARY KEY, FK | Reference to correspondences |
|
||
| attachment_id | INT | PRIMARY KEY, FK | Reference to attachments |
|
||
| is_main_document | BOOLEAN | DEFAULT FALSE | Main/primary document flag |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (correspondence_id, attachment_id)
|
||
* FOREIGN KEY (correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE
|
||
* FOREIGN KEY (attachment_id) REFERENCES attachments(id) ON DELETE CASCADE
|
||
* INDEX (attachment_id)
|
||
* INDEX (is_main_document)
|
||
|
||
**Relationships**:
|
||
|
||
* Parent: correspondences, attachments
|
||
|
||
**Business Rules**:
|
||
|
||
* One correspondence can have multiple attachments
|
||
* One attachment can be linked to multiple correspondences
|
||
* is_main_document identifies primary file (typically PDF)
|
||
|
||
---
|
||
|
||
### 8.3 circulation_attachments
|
||
|
||
**Purpose**: Junction table linking circulations to file attachments (M:N)
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| ---------------- | --------- | --------------- | -------------------------- |
|
||
| circulation_id | INT | PRIMARY KEY, FK | Reference to circulations |
|
||
| attachment_id | INT | PRIMARY KEY, FK | Reference to attachments |
|
||
| is_main_document | BOOLEAN | DEFAULT FALSE | Main/primary document flag |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (circulation_id, attachment_id)
|
||
* FOREIGN KEY (circulation_id) REFERENCES circulations(id) ON DELETE CASCADE
|
||
* FOREIGN KEY (attachment_id) REFERENCES attachments(id) ON DELETE CASCADE
|
||
* INDEX (attachment_id)
|
||
* INDEX (is_main_document)
|
||
|
||
**Relationships**:
|
||
|
||
* Parent: circulations, attachments
|
||
|
||
---
|
||
|
||
### 8.4 shop_drawing_revision_attachments
|
||
|
||
**Purpose**: Junction table linking shop drawing revisions to file attachments (M:N)
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| ------------------------ | --------- | --------------- | ---------------------------------- |
|
||
| shop_drawing_revision_id | INT | PRIMARY KEY, FK | Reference to shop drawing revision |
|
||
| attachment_id | INT | PRIMARY KEY, FK | Reference to attachments |
|
||
| file_type | ENUM | NULL | File type: PDF, DWG, SOURCE, OTHER |
|
||
| is_main_document | BOOLEAN | DEFAULT FALSE | Main/primary document flag |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (shop_drawing_revision_id, attachment_id)
|
||
* FOREIGN KEY (shop_drawing_revision_id) REFERENCES shop_drawing_revisions(id) ON DELETE CASCADE
|
||
* FOREIGN KEY (attachment_id) REFERENCES attachments(id) ON DELETE CASCADE
|
||
* INDEX (attachment_id)
|
||
* INDEX (file_type)
|
||
* INDEX (is_main_document)
|
||
|
||
**Relationships**:
|
||
|
||
* Parent: shop_drawing_revisions, attachments
|
||
|
||
**Business Rules**:
|
||
|
||
* file_type categorizes drawing file formats
|
||
* Typically includes PDF for viewing and DWG for editing
|
||
* SOURCE may include native CAD files
|
||
|
||
---
|
||
|
||
### 8.5 contract_drawing_attachments
|
||
|
||
**Purpose**: Junction table linking contract drawings to file attachments (M:N)
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| ------------------- | --------- | --------------- | ---------------------------------- |
|
||
| contract_drawing_id | INT | PRIMARY KEY, FK | Reference to contract drawing |
|
||
| attachment_id | INT | PRIMARY KEY, FK | Reference to attachments |
|
||
| file_type | ENUM | NULL | File type: PDF, DWG, SOURCE, OTHER |
|
||
| is_main_document | BOOLEAN | DEFAULT FALSE | Main/primary document flag |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (contract_drawing_id, attachment_id)
|
||
* FOREIGN KEY (contract_drawing_id) REFERENCES contract_drawings(id) ON DELETE CASCADE
|
||
* FOREIGN KEY (attachment_id) REFERENCES attachments(id) ON DELETE CASCADE
|
||
* INDEX (attachment_id)
|
||
* INDEX (file_type)
|
||
* INDEX (is_main_document)
|
||
|
||
**Relationships**:
|
||
|
||
* Parent: contract_drawings, attachments
|
||
|
||
---
|
||
|
||
## **9. ðĒ Document Numbering System Tables (āļĢāļ°āļāļāđāļĨāļāļāļĩāđāđāļāļāļŠāļēāļĢ)**
|
||
|
||
### 9.1 document_number_formats
|
||
|
||
**Purpose**: Master table defining numbering formats for each document type
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| ---------------------- | ------------ | --------------------------- | -------------------------------------------- |
|
||
| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique format ID |
|
||
| project_id | INT | NOT NULL, FK | Reference to projects |
|
||
| correspondence_type_id | INT | NOT NULL, FK | Reference to correspondence_types |
|
||
| format_string | VARCHAR(100) | NOT NULL | Format pattern (e.g., {ORG}-{TYPE}-{YYYY}-#) |
|
||
| description | TEXT | NULL | Format description |
|
||
| reset_annually | BOOLEAN | DEFAULT TRUE | Start sequence new every year |
|
||
| is_active | TINYINT(1) | DEFAULT 1 | Active status |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (id)
|
||
* FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE
|
||
* FOREIGN KEY (correspondence_type_id) REFERENCES correspondence_types(id) ON DELETE CASCADE
|
||
* UNIQUE KEY (project_id, correspondence_type_id)
|
||
* INDEX (is_active)
|
||
|
||
**Relationships**:
|
||
|
||
* Parent: projects, correspondence_types
|
||
|
||
**Business Rules**:
|
||
|
||
* Defines how document numbers are constructed
|
||
* Supports placeholders: {PROJ}, {ORG}, {TYPE}, {YYYY}, {MM}, {#}
|
||
|
||
---
|
||
|
||
### 9.2 document_number_counters (UPDATE v1.7.0)
|
||
|
||
**Purpose**: Transaction table tracking running numbers (High Concurrency)
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| -------------------------- | ----------- | ------------- | ----------------------------------------------- |
|
||
| project_id | INT | PK, NOT NULL | āđāļāļĢāļāļāļēāļĢ |
|
||
| originator_organization_id | INT | PK, NOT NULL | āļāļāļāđāļāļĢāļāļđāđāļŠāđāļ |
|
||
| recipient_organization_id | INT | PK, NOT NULL | āļāļāļāđāļāļĢāļāļđāđāļĢāļąāļ (0 = no recipient / RFA) |
|
||
| correspondence_type_id | INT | PK, NULL | āļāļĢāļ°āđāļ āļāđāļāļāļŠāļēāļĢ (NULL = default) |
|
||
| sub_type_id | INT | PK, DEFAULT 0 | āļāļĢāļ°āđāļ āļāļĒāđāļāļĒ āļŠāļģāļŦāļĢāļąāļ TRANSMITTAL (0 = āđāļĄāđāļĢāļ°āļāļļ) |
|
||
| rfa_type_id | INT | PK, DEFAULT 0 | āļāļĢāļ°āđāļ āļ RFA (0 = āđāļĄāđāđāļāđ RFA) |
|
||
| discipline_id | INT | PK, DEFAULT 0 | āļŠāļēāļāļēāļāļēāļ (0 = āđāļĄāđāļĢāļ°āļāļļ) |
|
||
| reset_scope | VARCHAR(20) | PK, NOT NULL | Scope of reset (YEAR_2024, MONTH_2024_01, NONE) |
|
||
| last_number | INT | DEFAULT 0 | āđāļĨāļāļĨāđāļēāļŠāļļāļāļāļĩāđāļāļđāļāđāļāđāļāļēāļāđāļāđāļĨāđāļ§ |
|
||
| version | INT | DEFAULT 0 | Optimistic Lock Version |
|
||
| updated_at | DATETIME(6) | ON UPDATE | āđāļ§āļĨāļēāļāļĩāđāļāļąāļāđāļāļāļĨāđāļēāļŠāļļāļ |
|
||
|
||
**Indexes**:
|
||
|
||
* **PRIMARY KEY (project_id, originator_organization_id, recipient_organization_id, correspondence_type_id, sub_type_id, rfa_type_id, discipline_id, reset_scope)**
|
||
* INDEX idx_counter_lookup (project_id, correspondence_type_id, reset_scope)
|
||
* INDEX idx_counter_org (originator_organization_id, reset_scope)
|
||
|
||
**Business Rules**:
|
||
|
||
* **Composite Primary Key 8 Columns**: āđāļāļ·āđāļāļĢāļāļāļĢāļąāļāļāļēāļĢāļĢāļąāļāđāļĨāļāļāļĩāđāļāļąāļāļāđāļāļāđāļĨāļ° Reset Scope āļāļĩāđāļŦāļĨāļēāļāļŦāļĨāļēāļĒ
|
||
* **Concurrency Control**: āđāļāđ Redis Lock āļŦāļĢāļ·āļ Optimistic Locking (version)
|
||
* **Reset Scope**: āđāļāđ Field `reset_scope` āļāļ§āļāļāļļāļĄāļāļēāļĢ Reset āđāļāļ `current_year` āđāļāļāđāļāļīāļĄ
|
||
|
||
---
|
||
|
||
### 9.3 document_number_audit (UPDATE v1.7.0)
|
||
|
||
**Purpose**: Audit log for document number generation (Debugging & Tracking)
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| :------------------------- | :----------- | :----------------- | :-------------------------------------- |
|
||
| id | INT | PK, AI | ID āļāļāļ audit record |
|
||
| document_id | INT | NULL, FK | ID āļāļāļāđāļāļāļŠāļēāļĢāļāļĩāđāļŠāļĢāđāļēāļāđāļĨāļāļāļĩāđ (NULL if failed) |
|
||
| document_type | VARCHAR(50) | NULL | āļāļĢāļ°āđāļ āļāđāļāļāļŠāļēāļĢ |
|
||
| document_number | VARCHAR(100) | NOT NULL | āđāļĨāļāļāļĩāđāđāļāļāļŠāļēāļĢāļāļĩāđāļŠāļĢāđāļēāļ (āļāļĨāļĨāļąāļāļāđ) |
|
||
| operation | ENUM | DEFAULT 'CONFIRM' | RESERVE, CONFIRM, MANUAL_OVERRIDE, etc. |
|
||
| status | ENUM | DEFAULT 'RESERVED' | RESERVED, CONFIRMED, CANCELLED, VOID |
|
||
| counter_key | JSON | NOT NULL | Counter key āļāļĩāđāđāļāđ (JSON 8 fields) |
|
||
| reservation_token | VARCHAR(36) | NULL | Token āļāļēāļĢāļāļāļ |
|
||
| idempotency_key | VARCHAR(128) | NULL | Idempotency Key from request |
|
||
| originator_organization_id | INT | NULL | āļāļāļāđāļāļĢāļāļđāđāļŠāđāļ |
|
||
| recipient_organization_id | INT | NULL | āļāļāļāđāļāļĢāļāļđāđāļĢāļąāļ |
|
||
| template_used | VARCHAR(200) | NOT NULL | Template āļāļĩāđāđāļāđāđāļāļāļēāļĢāļŠāļĢāđāļēāļ |
|
||
| old_value | TEXT | NULL | Previous value |
|
||
| new_value | TEXT | NULL | New value |
|
||
| user_id | INT | NULL, FK | āļāļđāđāļāļāļŠāļĢāđāļēāļāđāļĨāļāļāļĩāđ |
|
||
| is_success | BOOLEAN | DEFAULT TRUE | āļŠāļāļēāļāļ°āļāļ§āļēāļĄāļŠāļģāđāļĢāđāļ |
|
||
| created_at | TIMESTAMP | DEFAULT NOW | āļ§āļąāļāļāļĩāđ/āđāļ§āļĨāļēāļāļĩāđāļŠāļĢāđāļēāļ |
|
||
| total_duration_ms | INT | NULL | āđāļ§āļĨāļēāļĢāļ§āļĄāļāļąāđāļāļŦāļĄāļāđāļāļāļēāļĢāļŠāļĢāđāļēāļ (ms) |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (id)
|
||
* FOREIGN KEY (document_id) REFERENCES correspondences(id) ON DELETE CASCADE
|
||
* FOREIGN KEY (user_id) REFERENCES users(user_id)
|
||
* INDEX (document_id)
|
||
* INDEX (user_id)
|
||
* INDEX (status)
|
||
* INDEX (operation)
|
||
* INDEX (document_number)
|
||
* INDEX (reservation_token)
|
||
* INDEX (created_at)
|
||
|
||
---
|
||
|
||
### 9.4 document_number_errors (UPDATE v1.7.0)
|
||
|
||
**Purpose**: Error log for failed document number generation
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| :------------ | :-------- | :---------- | :--------------------------------------------- |
|
||
| id | INT | PK, AI | ID āļāļāļ error record |
|
||
| error_type | ENUM | NOT NULL | LOCK_TIMEOUT, VERSION_CONFLICT, DB_ERROR, etc. |
|
||
| error_message | TEXT | NULL | āļāđāļāļāļ§āļēāļĄ error |
|
||
| stack_trace | TEXT | NULL | Stack trace āļŠāļģāļŦāļĢāļąāļ debugging |
|
||
| context_data | JSON | NULL | Context āļāļāļ request |
|
||
| user_id | INT | NULL | āļāļđāđāļāļĩāđāđāļāļīāļ error |
|
||
| created_at | TIMESTAMP | DEFAULT NOW | āļ§āļąāļāļāļĩāđāđāļāļīāļ error |
|
||
| resolved_at | TIMESTAMP | NULL | āļ§āļąāļāļāļĩāđāđāļāđāđāļāđāļĨāđāļ§ |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (id)
|
||
* INDEX (error_type)
|
||
* INDEX (created_at)
|
||
* INDEX (user_id)
|
||
* INDEX (resolved_at)
|
||
|
||
---
|
||
|
||
### 9.5 document_number_reservations (NEW v1.7.0)
|
||
|
||
**Purpose**: Two-Phase Commit table for document number reservation
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| :--------------------- | :----------- | :--------------- | :----------------------------------- |
|
||
| id | INT | PK, AI | Unique ID |
|
||
| token | VARCHAR(36) | UNIQUE, NOT NULL | UUID v4 Reservation Token |
|
||
| document_number | VARCHAR(100) | UNIQUE, NOT NULL | āđāļĨāļāļāļĩāđāđāļāļāļŠāļēāļĢāļāļĩāđāļāļāļ |
|
||
| document_number_status | ENUM | DEFAULT RESERVED | RESERVED, CONFIRMED, CANCELLED, VOID |
|
||
| document_id | INT | NULL, FK | ID āļāļāļāđāļāļāļŠāļēāļĢ (āđāļĄāļ·āđāļ Confirm āđāļĨāđāļ§) |
|
||
| expires_at | DATETIME(6) | NOT NULL | āđāļ§āļĨāļēāļŦāļĄāļāļāļēāļĒāļļāļāļēāļĢāļāļāļ |
|
||
| project_id | INT | NOT NULL, FK | Project Context |
|
||
| user_id | INT | NOT NULL, FK | User Context |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (id)
|
||
* FOREIGN KEY (document_id) REFERENCES correspondence_revisions(id) ON DELETE SET NULL
|
||
* FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE
|
||
* FOREIGN KEY (correspondence_type_id) REFERENCES correspondence_types(id) ON DELETE CASCADE
|
||
* FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE
|
||
* INDEX idx_token (token)
|
||
* INDEX idx_status (document_number_status)
|
||
* INDEX idx_status_expires (document_number_status, expires_at)
|
||
* INDEX idx_document_id (document_id)
|
||
* INDEX idx_user_id (user_id)
|
||
* INDEX idx_reserved_at (reserved_at)
|
||
|
||
---
|
||
|
||
## **10. âïļ Unified Workflow Engine Tables (UPDATE v1.7.0)**
|
||
|
||
### 10.1 workflow_definitions
|
||
|
||
**Purpose**: āđāļāđāļāđāļĄāđāđāļāļ (Template) āļāļāļ Workflow (Definition / DSL)
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| :------------ | :---------- | :----------- | :------------------------------------- |
|
||
| id | CHAR(36) | PK, UUID | Unique Workflow Definition ID |
|
||
| workflow_code | VARCHAR(50) | NOT NULL | āļĢāļŦāļąāļŠ Workflow (āđāļāđāļ RFA_FLOW_V1) |
|
||
| version | INT | DEFAULT 1 | āļŦāļĄāļēāļĒāđāļĨāļ Version |
|
||
| description | TEXT | NULL | āļāļģāļāļāļīāļāļēāļĒ Workflow |
|
||
| dsl | JSON | NOT NULL | āļāļīāļĒāļēāļĄ Workflow āļāđāļāļāļāļąāļ (YAML/JSON Format) |
|
||
| compiled | JSON | NOT NULL | āđāļāļĢāļāļŠāļĢāđāļēāļ Execution Tree āļāļĩāđ Compile āđāļĨāđāļ§ |
|
||
| is_active | BOOLEAN | DEFAULT TRUE | āļŠāļāļēāļāļ°āļāļēāļĢāđāļāđāļāļēāļ |
|
||
| created_at | TIMESTAMP | DEFAULT NOW | āļ§āļąāļāļāļĩāđāļŠāļĢāđāļēāļ |
|
||
| updated_at | TIMESTAMP | ON UPDATE | āļ§āļąāļāļāļĩāđāđāļāđāđāļāļĨāđāļēāļŠāļļāļ |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (id)
|
||
* UNIQUE KEY (workflow_code, version)
|
||
* INDEX (is_active)
|
||
|
||
---
|
||
|
||
### 10.2 workflow_instances
|
||
|
||
**Purpose**: āđāļāđāļāļŠāļāļēāļāļ°āļāļāļ Workflow āļāļĩāđāļāļģāļĨāļąāļāļĢāļąāļāļāļĒāļđāđāļāļĢāļīāļ (Runtime)
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| :------------ | :---------- | :--------------- | :--------------------------------------------- |
|
||
| id | CHAR(36) | PK, UUID | Unique Instance ID |
|
||
| definition_id | CHAR(36) | FK, NOT NULL | āļāđāļēāļāļāļīāļ Definition āļāļĩāđāđāļāđ |
|
||
| entity_type | VARCHAR(50) | NOT NULL | āļāļĢāļ°āđāļ āļāđāļāļāļŠāļēāļĢ (rfa_revision, correspondence...) |
|
||
| entity_id | VARCHAR(50) | NOT NULL | ID āļāļāļāđāļāļāļŠāļēāļĢ |
|
||
| current_state | VARCHAR(50) | NOT NULL | āļŠāļāļēāļāļ°āļāļąāļāļāļļāļāļąāļ |
|
||
| status | ENUM | DEFAULT 'ACTIVE' | ACTIVE, COMPLETED, CANCELLED, TERMINATED |
|
||
| context | JSON | NULL | āļāļąāļ§āđāļāļĢ Context āļŠāļģāļŦāļĢāļąāļāļāļąāļāļŠāļīāļāđāļ |
|
||
| created_at | TIMESTAMP | DEFAULT NOW | āđāļ§āļĨāļēāļāļĩāđāļŠāļĢāđāļēāļ |
|
||
| updated_at | TIMESTAMP | ON UPDATE | āđāļ§āļĨāļēāļāļĩāđāļāļąāļāđāļāļāļĨāđāļēāļŠāļļāļ |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (id)
|
||
* FOREIGN KEY (definition_id) REFERENCES workflow_definitions(id) ON DELETE CASCADE
|
||
* INDEX (entity_type, entity_id)
|
||
* INDEX (current_state)
|
||
|
||
---
|
||
|
||
### 10.3 workflow_histories
|
||
|
||
**Purpose**: āđāļāđāļāļāļĢāļ°āļ§āļąāļāļīāļāļēāļĢāļāļģāđāļāļīāļāļāļēāļĢāđāļāđāļāđāļĨāļ° Step (Audit Trail)
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| :---------------- | :---------- | :----------- | :-------------------- |
|
||
| id | CHAR(36) | PK, UUID | Unique ID |
|
||
| instance_id | CHAR(36) | FK, NOT NULL | āļāđāļēāļāļāļīāļ Instance |
|
||
| from_state | VARCHAR(50) | NOT NULL | āļŠāļāļēāļāļ°āļāđāļāļāļēāļ |
|
||
| to_state | VARCHAR(50) | NOT NULL | āļŠāļāļēāļāļ°āļāļĨāļēāļĒāļāļēāļ |
|
||
| action | VARCHAR(50) | NOT NULL | Action āļāļĩāđāļāļĢāļ°āļāļģ |
|
||
| action_by_user_id | INT | FK, NULL | User ID āļāļđāđāļāļĢāļ°āļāļģ |
|
||
| comment | TEXT | NULL | āļāļ§āļēāļĄāđāļŦāđāļ |
|
||
| metadata | JSON | NULL | Snapshot āļāđāļāļĄāļđāļĨ āļ āļāļāļ°āļāļąāđāļ |
|
||
| created_at | TIMESTAMP | DEFAULT NOW | āđāļ§āļĨāļēāļāļĩāđāļāļĢāļ°āļāļģ |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (id)
|
||
* FOREIGN KEY (instance_id) REFERENCES workflow_instances(id) ON DELETE CASCADE
|
||
* INDEX (instance_id)
|
||
* INDEX (action_by_user_id)
|
||
|
||
---
|
||
|
||
## **11. ðĨïļ System & Logs Tables (āļĢāļ°āļāļ, āļāļąāļāļāļķāļ)**
|
||
|
||
> **Audit Logging Architecture:**
|
||
### 1. Audit Logging
|
||
|
||
**Table: `audit_logs`**
|
||
|
||
āļāļąāļāļāļķāļāļāļēāļĢāđāļāļĨāļĩāđāļĒāļāđāļāļĨāļāļŠāļģāļāļąāļ:
|
||
|
||
- User actions (CREATE, UPDATE, DELETE)
|
||
- Entity type āđāļĨāļ° Entity ID
|
||
- Old/New values (JSON)
|
||
- IP Address, User Agent
|
||
|
||
### 2. User Preferences
|
||
|
||
**Table: `user_preferences`**
|
||
|
||
āđāļāđāļāļāļēāļĢāļāļąāđāļāļāđāļēāļŠāđāļ§āļāļāļąāļ§:
|
||
|
||
- Language preference
|
||
- Notification settings
|
||
- UI preferences (JSON)
|
||
|
||
### 3. JSON Schema Validation
|
||
|
||
**Table: `json_schemas`**
|
||
|
||
āđāļāđāļ Schema āļŠāļģāļŦāļĢāļąāļ Validate JSON fields:
|
||
|
||
- `correspondence_revisions.details`
|
||
- `user_preferences.preferences`
|
||
|
||
---
|
||
|
||
|
||
### 11.1 json_schemas (UPDATE v1.7.0)
|
||
|
||
**Purpose**: āđāļāđāļ Schema āļŠāļģāļŦāļĢāļąāļ Validate JSON Columns (Req 3.12)
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| :---------------- | :----------- | :----------- | :------------------------------- |
|
||
| id | INT | PK, AI | Unique ID |
|
||
| schema_code | VARCHAR(100) | NOT NULL | āļĢāļŦāļąāļŠ Schema (āđāļāđāļ RFA_DWG) |
|
||
| version | INT | DEFAULT 1 | āđāļ§āļāļĢāđāļāļąāļāļāļāļ Schema |
|
||
| table_name | VARCHAR(100) | NOT NULL | āļāļ·āđāļāļāļēāļĢāļēāļāđāļāđāļēāļŦāļĄāļēāļĒ |
|
||
| schema_definition | JSON | NOT NULL | JSON Schema Definition |
|
||
| ui_schema | JSON | NULL | āđāļāļĢāļāļŠāļĢāđāļēāļ UI Schema āļŠāļģāļŦāļĢāļąāļ Frontend |
|
||
| virtual_columns | JSON | NULL | Config āļŠāļģāļŦāļĢāļąāļāļŠāļĢāđāļēāļ Virtual Columns |
|
||
| migration_script | JSON | NULL | Script āļŠāļģāļŦāļĢāļąāļāđāļāļĨāļāļāđāļāļĄāļđāļĨ |
|
||
| is_active | BOOLEAN | DEFAULT TRUE | āļŠāļāļēāļāļ°āļāļēāļĢāđāļāđāļāļēāļ |
|
||
|
||
|
||
---
|
||
|
||
### 11.2 audit_logs (UPDATE v1.7.0)
|
||
|
||
**Purpose**: Centralized audit logging for all system actions (Req 6.1)
|
||
|
||
| Column Name | Data Type | Constraints | Description |
|
||
| :----------- | :----------- | :------------------------ | :------------------------------------------- |
|
||
| audit_id | BIGINT | PK, AI | Unique log ID |
|
||
| request_id | VARCHAR(100) | NULL | Trace ID linking to app logs |
|
||
| user_id | INT | NULL, FK | User who performed action |
|
||
| action | VARCHAR(100) | NOT NULL | Action name (e.g. rfa.create) |
|
||
| severity | ENUM | DEFAULT 'INFO' | INFO, WARN, ERROR, CRITICAL |
|
||
| entity_type | VARCHAR(50) | NULL | Module/Table name (e.g. rfa, correspondence) |
|
||
| entity_id | VARCHAR(50) | NULL | ID of affected entity |
|
||
| details_json | JSON | NULL | Context data / Old & New values |
|
||
| ip_address | VARCHAR(45) | NULL | User IP address |
|
||
| user_agent | VARCHAR(255) | NULL | User browser/client info |
|
||
| created_at | DATETIME | DEFAULT CURRENT_TIMESTAMP | Log timestamp |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (audit_id, created_at) -- **Partition Key**
|
||
* INDEX idx_audit_user (user_id)
|
||
* INDEX idx_audit_action (action)
|
||
* INDEX idx_audit_entity (entity_type, entity_id)
|
||
* INDEX idx_audit_created (created_at)
|
||
|
||
**Partitioning**:
|
||
* **PARTITION BY RANGE (YEAR(created_at))**: āđāļāđāļ Partition āļĢāļēāļĒāļāļĩ āđāļāļ·āđāļāļāļĢāļ°āļŠāļīāļāļāļīāļ āļēāļāđāļāļāļēāļĢāđāļāđāļāļāđāļāļĄāļđāļĨāļĢāļ°āļĒāļ°āļĒāļēāļ§
|
||
|
||
---
|
||
|
||
### 11.3 notifications (UPDATE v1.7.0)
|
||
|
||
**Purpose**: System notifications for users
|
||
|
||
| 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 |
|
||
| message | TEXT | NOT NULL | Notification body |
|
||
| notification_type | ENUM | NOT NULL | Type: EMAIL, LINE, SYSTEM |
|
||
| is_read | BOOLEAN | DEFAULT FALSE | Read status |
|
||
| entity_type | VARCHAR(50) | NULL | Related Entity Type |
|
||
| entity_id | INT | NULL | Related Entity ID |
|
||
| created_at | DATETIME | DEFAULT CURRENT_TIMESTAMP | Notification timestamp |
|
||
|
||
**Indexes**:
|
||
|
||
* PRIMARY KEY (id, created_at) -- **Partition Key**
|
||
* INDEX idx_notif_user (user_id)
|
||
* INDEX idx_notif_type (notification_type)
|
||
* INDEX idx_notif_read (is_read)
|
||
* INDEX idx_notif_created (created_at)
|
||
|
||
**Partitioning**:
|
||
* **PARTITION BY RANGE (YEAR(created_at))**: āđāļāđāļ Partition āļĢāļēāļĒāļāļĩ
|
||
|
||
---
|
||
|
||
## **12. ð Views (āļĄāļļāļĄāļĄāļāļāļāđāļāļĄāļđāļĨ)**
|
||
|
||
### 12.1 v_current_correspondences
|
||
|
||
**Purpose**: āđāļŠāļāļāļāđāļāļĄāļđāļĨ Correspondence Revision āļĨāđāļēāļŠāļļāļ (is_current = TRUE)
|
||
|
||
### 12.2 v_current_rfas
|
||
|
||
**Purpose**: āđāļŠāļāļāļāđāļāļĄāļđāļĨ RFA Revision āļĨāđāļēāļŠāļļāļ āļāļĢāđāļāļĄ Status āđāļĨāļ° Approve Code
|
||
|
||
### 12.3 v_user_tasks (Unified Workflow)
|
||
|
||
**Purpose**: āļĢāļ§āļĄāļĢāļēāļĒāļāļēāļĢāļāļēāļāļāļĩāđāļĒāļąāļāļāđāļēāļāļāļĒāļđāđ (Status = ACTIVE) āļāļēāļāļāļļāļāļĢāļ°āļāļ (RFA, Circulation, Correspondence) āđāļāļ·āđāļāļāļģāđāļāđāļŠāļāļāđāļ Dashboard
|
||
|
||
### 12.4 v_audit_log_details
|
||
|
||
**Purpose**: āđāļŠāļāļ audit_logs āļāļĢāđāļāļĄāļāđāļāļĄāļđāļĨ username āđāļĨāļ° email āļāļāļāļāļđāđāļāļĢāļ°āļāļģ
|
||
|
||
### 12.5 v_user_all_permissions
|
||
|
||
**Purpose**: āļĢāļ§āļĄāļŠāļīāļāļāļīāđāļāļąāđāļāļŦāļĄāļ (Global + Project + Organization) āļāļāļāļāļđāđāđāļāđāļāļļāļāļāļ
|
||
|
||
### 12.6 v_documents_with_attachments
|
||
|
||
**Purpose**: āđāļŠāļāļāđāļāļāļŠāļēāļĢāļāļąāđāļāļŦāļĄāļāļāļĩāđāļĄāļĩāđāļāļĨāđāđāļāļ (Correspondence, Circulation, Drawings)
|
||
|
||
### 12.7 v_document_statistics
|
||
|
||
**Purpose**: āđāļŠāļāļāļŠāļāļīāļāļīāđāļāļāļŠāļēāļĢāļāļēāļĄāļāļĢāļ°āđāļ āļāđāļĨāļ°āļŠāļāļēāļāļ°
|
||
|
||
---
|
||
|
||
## **13. ð Index Summaries (āļŠāļĢāļļāļ Index)**
|
||
|
||
> **Performance Optimization Strategy:**
|
||
### 1. Indexing Strategy
|
||
|
||
**Primary Indexes:**
|
||
|
||
- Primary Keys (AUTO_INCREMENT)
|
||
- Foreign Keys (automatic in InnoDB)
|
||
- Unique Constraints (business keys)
|
||
|
||
**Secondary Indexes:**
|
||
|
||
```sql
|
||
-- Correspondence search
|
||
CREATE INDEX idx_corr_type_status ON correspondence_revisions(correspondence_type_id, correspondence_status_id);
|
||
CREATE INDEX idx_corr_date ON correspondence_revisions(document_date);
|
||
|
||
-- Virtual columns for JSON
|
||
CREATE INDEX idx_v_ref_project ON correspondence_revisions(v_ref_project_id);
|
||
CREATE INDEX idx_v_doc_subtype ON correspondence_revisions(v_doc_subtype);
|
||
|
||
-- User lookup
|
||
CREATE INDEX idx_user_email ON users(email);
|
||
CREATE INDEX idx_user_org ON users(primary_organization_id, is_active);
|
||
```
|
||
|
||
### 2. Virtual Columns
|
||
|
||
āđāļāđ Virtual Columns āļŠāļģāļŦāļĢāļąāļ Index JSON fields:
|
||
|
||
```sql
|
||
ALTER TABLE correspondence_revisions
|
||
ADD COLUMN v_ref_project_id INT GENERATED ALWAYS AS (JSON_UNQUOTE(JSON_EXTRACT(details, '$.ref_project_id'))) VIRTUAL,
|
||
ADD INDEX idx_v_ref_project(v_ref_project_id);
|
||
```
|
||
|
||
### 3. Partitioning (Future)
|
||
|
||
āļāļīāļāļēāļĢāļāļē Partition āļāļēāļĢāļēāļ `audit_logs` āļāļēāļĄāļāļĩ:
|
||
|
||
```sql
|
||
ALTER TABLE audit_logs
|
||
PARTITION BY RANGE (YEAR(created_at)) (
|
||
PARTITION p2024 VALUES LESS THAN (2025),
|
||
PARTITION p2025 VALUES LESS THAN (2026),
|
||
PARTITION p_future VALUES LESS THAN MAXVALUE
|
||
);
|
||
```
|
||
|
||
---
|
||
|
||
|
||
### 13.1 Performance Indexes
|
||
|
||
| Table Name | Index Columns | Purpose |
|
||
| :----------------------- | :------------------------------------------------ | :----------------------------- |
|
||
| correspondences | (project_id, correspondence_number) | Fast lookup by document number |
|
||
| correspondences | (correspondence_type_id) | Filter by type |
|
||
| correspondence_revisions | (correspondence_id, is_current) | Get current revision |
|
||
| rfas | (rfa_type_id) | Filter by RFA type |
|
||
| rfa_revisions | (rfa_id, is_current) | Get current RFA revision |
|
||
| rfa_revisions | (rfa_status_code_id) | Filter by status |
|
||
| audit_logs | (created_at) | Date range queries |
|
||
| audit_logs | (user_id) | User activity history |
|
||
| audit_logs | (module, action) | Action type analysis |
|
||
| notifications | (user_id, is_read) | Unread notifications query |
|
||
| document_number_counters | (project_id, correspondence_type_id, reset_scope) | Running number generation |
|
||
| workflow_instances | (entity_type, entity_id) | Workflow lookup by document ID |
|
||
| workflow_instances | (current_state) | Monitor active workflows |
|
||
|
||
### 13.2 Unique Constraints
|
||
|
||
| Table Name | Columns | Description |
|
||
| :---------------------- | :----------------------------------- | :--------------------------------- |
|
||
| users | (username) | Unique login name |
|
||
| users | (email) | Unique email address |
|
||
| organizations | (organization_code) | Unique organization code |
|
||
| projects | (project_code) | Unique project code |
|
||
| contracts | (contract_code) | Unique contract code |
|
||
| correspondences | (project_id, correspondence_number) | Unique document number per project |
|
||
| shop_drawings | (drawing_number) | Unique shop drawing number |
|
||
| document_number_formats | (project_id, correspondence_type_id) | One format per type per project |
|
||
| workflow_definitions | (workflow_code, version) | Unique workflow code per version |
|
||
|
||
---
|
||
|
||
## **14. ðĄïļ Data Integrity Constraints (āļāļ§āļēāļĄāļāļđāļāļāđāļāļāļāļāļāļāđāļāļĄāļđāļĨ)**
|
||
|
||
### 14.1 Soft Delete Policy
|
||
|
||
* **Tables with `deleted_at`**:
|
||
* users
|
||
* organizations
|
||
* projects
|
||
* contracts
|
||
* correspondences
|
||
* rfas
|
||
* shop_drawings
|
||
* contract_drawings
|
||
* **Rule**: Records are never physically deleted. `deleted_at` is set to timestamp.
|
||
* **Query Rule**: All standard queries MUST include `WHERE deleted_at IS NULL`.
|
||
|
||
### 14.2 Foreign Key Cascades
|
||
|
||
* **ON DELETE CASCADE**:
|
||
* Used for child tables that cannot exist without parent (e.g., `correspondence_revisions`, `rfa_revisions`, `correspondence_attachments`).
|
||
* **ON DELETE RESTRICT**:
|
||
* Used for master data references to prevent accidental deletion of used data (e.g., `correspondence_types`, `organizations`).
|
||
* **ON DELETE SET NULL**:
|
||
* Used for optional references (e.g., `created_by`, `originator_id`).
|
||
|
||
---
|
||
|
||
## **15. ð Security & Permissions Model (āļāļ§āļēāļĄāļāļĨāļāļāļ āļąāļĒ)**
|
||
|
||
### 15.1 Row-Level Security (RLS) Logic
|
||
|
||
* **Organization Scope**: Users can only see documents where `originator_id` OR `recipient_organization_id` matches their organization.
|
||
* **Project Scope**: Users can only see documents within projects they are assigned to.
|
||
* **Confidentiality**: Documents marked `is_confidential` are visible ONLY to specific roles or users.
|
||
|
||
### 15.2 Role-Based Access Control (RBAC)
|
||
|
||
* **Permissions** are granular (e.g., `correspondence.view`, `correspondence.create`).
|
||
* **Roles** aggregate permissions (e.g., `Document Controller` = `view` + `create` + `edit`).
|
||
* **Assignments** link Users to Roles within a Context (Global, Project, or Organization).
|
||
|
||
---
|
||
|
||
## **16. ð Data Migration & Seeding (āļāļēāļĢāļĒāđāļēāļĒāļāđāļāļĄāļđāļĨ)**
|
||
|
||
### 16.1 Initial Seeding (V1.7.0)
|
||
|
||
1. **Master Data**:
|
||
* `organizations`: Owner, Consultant, Contractor
|
||
* `projects`: LCBP3
|
||
* `correspondence_types`: LETTER, MEMO, TRANSMITTAL, RFA
|
||
* `rfa_types`: DWG, MAT, DOC, RFI
|
||
* `rfa_status_codes`: DFT, PEND, APPR, REJ
|
||
* `disciplines`: GEN, STR, ARC, MEP
|
||
2. **System Users**:
|
||
* `admin`: Super Admin
|
||
* `system`: System Bot for automated tasks
|
||
|
||
### 16.2 Migration Strategy
|
||
|
||
* **Schema Migration**: Use TypeORM Migrations or raw SQL scripts (versioned).
|
||
* **Data Migration**:
|
||
* **V1.6.0 -> V1.7.0**:
|
||
* Run SQL script `9_lcbp3_v1_7_0.sql`
|
||
* Migrate `document_number_counters` to 8-col composite PK.
|
||
* Initialize `document_number_reservations`.
|
||
* Update `json_schemas` with new columns.
|
||
|
||
---
|
||
|
||
|
||
### 16.3 Temporary Migration Tracking Tables (V1.8.0 n8n Migration)
|
||
|
||
āļāļēāļĢāļēāļāđāļŦāļĨāđāļēāļāļĩāđāļāļđāļāđāļāđāļāļąāđāļ§āļāļĢāļēāļ§āļĢāļ°āļŦāļ§āđāļēāļāļāļĢāļ°āļāļ§āļāļāļēāļĢ Migrate āđāļāļāļŠāļēāļĢ PDF 20,000 āļāļāļąāļāļāđāļ§āļĒ n8n (āļāļđāļĢāļēāļĒāļĨāļ°āđāļāļĩāļĒāļāđāļ |