From 7dce419745d81d21a2b8281f239ed6becf8a88f0 Mon Sep 17 00:00:00 2001 From: admin Date: Fri, 5 Dec 2025 23:42:12 +0700 Subject: [PATCH] 251205:2300 debug backend/frontend --- .agent/rules/00_project_specs.md | 59 + .agent/rules/code-references.md | 11 - .agent/rules/coding-standards.md | 11 - .../07-database/data-dictionary-v1.5.1.md.sql | 2548 +++++++++++++++++ specs/07-database/lcbp3-v1.5.1-shema.sql.sql | 1844 ++++++++++++ 5 files changed, 4451 insertions(+), 22 deletions(-) create mode 100644 .agent/rules/00_project_specs.md delete mode 100644 .agent/rules/code-references.md delete mode 100644 .agent/rules/coding-standards.md create mode 100644 specs/07-database/data-dictionary-v1.5.1.md.sql create mode 100644 specs/07-database/lcbp3-v1.5.1-shema.sql.sql diff --git a/.agent/rules/00_project_specs.md b/.agent/rules/00_project_specs.md new file mode 100644 index 0000000..4fc8bd4 --- /dev/null +++ b/.agent/rules/00_project_specs.md @@ -0,0 +1,59 @@ +--- +trigger: always_on +--- + +# Project Specifications & Context Protocol + +Description: Enforces strict adherence to the project's documentation structure (specs/00-06) for all agent activities. +Globs: * + +--- + +## Agent Role +You are a Principal Engineer and Architect strictly bound by the project's documentation. You do not improvise outside of the defined specifications. + +## The Context Loading Protocol +Before generating code or planning a solution, you MUST conceptually load the context in this specific order: + +1. **ðŸŽŊ ACTIVE TASK (`specs/06-tasks/`)** + - Identify the current active task file. + - *Action:* Determine the immediate scope. Do NOT implement features not listed here. + +2. **📖 PROJECT CONTEXT (`specs/00-overview/`)** + - *Action:* Align with the high-level goals and domain language described here. + +3. **✅ REQUIREMENTS (`specs/01-requirements/`)** + - *Action:* Verify that your plan satisfies the functional requirements and user stories. + - *Constraint:* If a requirement is ambiguous, stop and ask. + +4. **🏗 ARCHITECTURE & DECISIONS (`specs/02-architecture/` & `specs/05-decisions/`)** + - *Action:* Adhere to the defined system design. + - *Crucial:* Check `specs/05-decisions/` (ADRs) to ensure you do not violate previously agreed-upon technical decisions. + +5. **ðŸ’ū DATABASE & SCHEMA (`specs/07-databasee/`)** + - *Action:* - **Read `specs/07-database/lcbp3-v1.5.1-shema.sql`** (or relevant `.sql` files) for exact table structures and constraints. + - **Consult `specs/database/data-dictionary-v1.5.1.md`** for field meanings and business rules. + - **Check `specs/database/seeds/`** to understand initial data states. + - *Constraint:* NEVER invent table names or columns. Use ONLY what is defined here. + +6. **⚙ïļ IMPLEMENTATION DETAILS (`specs/03-implementation/`)** + - *Action:* Follow Tech Stack, Naming Conventions, and Code Patterns. + +7. **🚀 OPERATIONS (`specs/04-operations/`)** + - *Action:* Ensure deployability and configuration compliance. + +## Execution Rules + +### 1. Citation Requirement +When proposing a change or writing code, you must explicitly reference the source of truth: +> "Implementing feature X per `specs/01-requirements/README.md` and `specs/01-requirements/**.md` using pattern defined in `specs/03-implementation/**.md`." + +### 2. Conflict Resolution +- **Spec vs. Training Data:** The `specs/` folder ALWAYS supersedes your general training data. +- **Spec vs. User Prompt:** If a user prompt contradicts `specs/05-decisions/`, warn the user before proceeding. + +### 3. File Generation +- Do not create new files outside of the structure defined in `specs/02-architecture/`. +- Keep the code style consistent with `specs/03-implementation/`. + +--- diff --git a/.agent/rules/code-references.md b/.agent/rules/code-references.md deleted file mode 100644 index d174d3b..0000000 --- a/.agent/rules/code-references.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -trigger: always_on ---- - -# Basic data: - -- For Application Requirements, refer to 0_Requirements_V1_4_4.md -- For detailed Full Stack JS, refer to 1_FullStackJS_V1_4_4.md -- For detailed Backend Development Plan, refer to 2_Backend_Plan_V1_4_4.md, 2_Backend_Plan_V1_4_4.Phase_Addition.md, 2_Backend_Plan_Phase6A_V1_4_3.md -- For detailed Frontend Development Plan, refer to 3_Frontend_Plan_V1_4_4.md -- For detailed DB schema, refer to 4_Data_Dictionary_V1_4_4.md, 8_lcbp3_v1_4_4.sql, 8_lcbp3_v1_4_4_seed.sql diff --git a/.agent/rules/coding-standards.md b/.agent/rules/coding-standards.md deleted file mode 100644 index 77d9a7e..0000000 --- a/.agent/rules/coding-standards.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -trigger: always_on ---- - -# 📏 Coding Standards (Strict Rules) - -1. **Language:** - Code logic & Naming: **English**. - - Comments & Documentation: **Thai Language (āļ āļēāļĐāļēāđ„āļ—āļĒ)**. -2. **File Structure:** Follow `kebab-case` for files (e.g., `user-service.ts`). -3. **Comments:** Add `// File: path/to/file` at the top of every file. -4. **Secrets:** NEVER hardcode secrets. Use `process.env` and assume `docker-compose.override.yml` is used for local dev. diff --git a/specs/07-database/data-dictionary-v1.5.1.md.sql b/specs/07-database/data-dictionary-v1.5.1.md.sql new file mode 100644 index 0000000..63c3147 --- /dev/null +++ b/specs/07-database/data-dictionary-v1.5.1.md.sql @@ -0,0 +1,2548 @@ +INSERT INTO organization_roles (id, role_name) +VALUES (1, 'OWNER'), + (2, 'DESIGNER'), + (3, 'CONSULTANT'), + (4, 'CONTRACTOR'), + (5, 'THIRD PARTY'), + (6, 'GUEST'); + +INSERT INTO organizations ( + id, + organization_code, + organization_name, + role_id + ) +VALUES (1, 'āļāļ—āļ—.', 'āļāļēāļĢāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāđˆāļ‡āļ›āļĢāļ°āđ€āļ—āļĻāđ„āļ—āļĒ', 1), + ( + 10, + 'āļŠāļ„āļ‰.3', + 'āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3', + 1 + ), + ( + 11, + 'āļŠāļ„āļ‰.3-01', + 'āļ•āļĢāļ§āļˆāļĢāļąāļšāļžāļąāļŠāļ”āļļ āļ—āļĩāđˆāļ›āļĢāļķāļāļĐāļēāļ„āļ§āļšāļ„āļļāļĄāļ‡āļēāļ™', + 1 + ), + (12, 'āļŠāļ„āļ‰.3-02', 'āļ•āļĢāļ§āļˆāļĢāļąāļšāļžāļąāļŠāļ”āļļ āļ‡āļēāļ™āļ—āļēāļ‡āļ—āļ°āđ€āļĨ', 1), + ( + 13, + 'āļŠāļ„āļ‰.3-03', + 'āļ•āļĢāļ§āļˆāļĢāļąāļšāļžāļąāļŠāļ”āļļ āļ­āļēāļ„āļēāļĢāđāļĨāļ°āļĢāļ°āļšāļšāļŠāļēāļ˜āļēāļĢāļ“āļđāļ›āđ‚āļ āļ„', + 1 + ), + ( + 14, + 'āļŠāļ„āļ‰.3-04', + 'āļ•āļĢāļ§āļˆāļĢāļąāļšāļžāļąāļŠāļ”āļļ āļ•āļĢāļ§āļˆāļŠāļ­āļšāļœāļĨāļāļĢāļ°āļ—āļšāļŠāļīāđˆāļ‡āđāļ§āļ”āļĨāđ‰āļ­āļĄ', + 1 + ), + ( + 15, + 'āļŠāļ„āļ‰.3-05', + 'āļ•āļĢāļ§āļˆāļĢāļąāļšāļžāļąāļŠāļ”āļļ āđ€āļĒāļĩāļĒāļ§āļĒāļēāļāļēāļĢāļ›āļĢāļ°āļĄāļ‡', + 1 + ), + ( + 16, + 'āļŠāļ„āļ‰.3-06', + 'āļ•āļĢāļ§āļˆāļĢāļąāļšāļžāļąāļŠāļ”āļļ āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 3', + 1 + ), + ( + 17, + 'āļŠāļ„āļ‰.3-07', + 'āļ•āļĢāļ§āļˆāļĢāļąāļšāļžāļąāļŠāļ”āļļ āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 4', + 1 + ), + ( + 18, + 'āļŠāļ„āļ‰.3-xx', + 'āļ•āļĢāļ§āļˆāļĢāļąāļšāļžāļąāļŠāļ”āļļ āļ—āļĩāđˆāļ›āļĢāļķāļāļĐāļēāļ­āļ­āļāđāļšāļš āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 4', + 1 + ), + ( + 21, + 'TEAM', + 'Designer Consulting Ltd.', + 2 + ), + ( + 22, + 'āļ„āļ„āļ‡.', + 'Construction Supervision Ltd.', + 3 + ), + ( + 41, + 'āļœāļĢāļĄ.1', + 'Contractor āļ‡āļēāļ™āļ—āļēāļ‡āļ—āļ°āđ€āļĨ', + 4 + ), + ( + 42, + 'āļœāļĢāļĄ.2', + 'Contractor āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡', + 4 + ), + ( + 43, + 'āļœāļĢāļĄ.3', + 'Contractor āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 3', + 4 + ), + ( + 44, + 'āļœāļĢāļĄ.4', + 'Contractor āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 4', + 4 + ), + ( + 31, + 'EN', + 'Third Party Environment', + 5 + ), + ( + 32, + 'CAR', + 'Third Party Fishery Care', + 5 + ); + +-- Seed project +INSERT INTO projects (project_code, project_name) +VALUES ( + 'LCBP3', + 'āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 1-4)' + ), + ( + 'LCBP3-C1', + 'āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 1) āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡āļ‡āļēāļ™āļ—āļēāļ‡āļ—āļ°āđ€āļĨ' + ), + ( + 'LCBP3-C2', + 'āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 2) āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡āļ­āļēāļ„āļēāļĢ āļ—āđˆāļēāđ€āļ—āļĩāļĒāļšāđ€āļĢāļ·āļ­ āļĢāļ°āļšāļšāļ–āļ™āļ™ āđāļĨāļ°āļĢāļ°āļšāļšāļŠāļēāļ˜āļēāļĢāļ“āļđāļ›āđ‚āļ āļ„' + ), + ( + 'LCBP3-C3', + 'āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 3) āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡' + ), + ( + 'LCBP3-C4', + 'āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 4) āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡' + ), + ( + 'LCBP3-EN', + 'āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 4) āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡' + ); + +-- Seed contract +-- āđƒāļŠāđ‰ Subquery āđ€āļžāļ·āđˆāļ­āļ”āļķāļ‡ project_id āļĄāļēāđ€āļŠāļ·āđˆāļ­āļĄāđ‚āļĒāļ‡ āļ—āļģāđƒāļŦāđ‰āđ„āļĄāđˆāļ•āđ‰āļ­āļ‡āļĄāļēāļ™āļąāđˆāļ‡āļˆāļąāļ”āļāļēāļĢ ID āļ”āđ‰āļ§āļĒāļ•āļąāļ§āđ€āļ­āļ‡ +INSERT INTO contracts ( + contract_code, + contract_name, + project_id, + is_active + ) +VALUES ( + 'LCBP3-DS', + 'āļ‡āļēāļ™āļˆāđ‰āļēāļ‡āļ—āļĩāđˆāļ›āļĢāļĩāļāļĐāļēāļ­āļ­āļāđāļšāļš āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 1-4)', + ( + SELECT id + FROM projects + WHERE project_code = 'LCBP3' + ), + TRUE + ), + ( + 'LCBP3-PS', + 'āļ‡āļēāļ™āļˆāđ‰āļēāļ‡āļ—āļĩāđˆāļ›āļĢāļĩāļāļĐāļēāļ„āļ§āļšāļ„āļļāļĄāļ‡āļēāļ™ āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 1-4)', + ( + SELECT id + FROM projects + WHERE project_code = 'LCBP3' + ), + TRUE + ), + ( + 'LCBP3-C1', + 'āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 1) āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡āļ‡āļēāļ™āļ—āļēāļ‡āļ—āļ°āđ€āļĨ', + ( + SELECT id + FROM projects + WHERE project_code = 'LCBP3-C1' + ), + TRUE + ), + ( + 'LCBP3-C2', + 'āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 2) āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡āļ­āļēāļ„āļēāļĢ āļ—āđˆāļēāđ€āļ—āļĩāļĒāļšāđ€āļĢāļ·āļ­ āļĢāļ°āļšāļšāļ–āļ™āļ™ āđāļĨāļ°āļĢāļ°āļšāļšāļŠāļēāļ˜āļēāļĢāļ“āļđāļ›āđ‚āļ āļ„', + ( + SELECT id + FROM projects + WHERE project_code = 'LCBP3-C2' + ), + TRUE + ), + ( + 'LCBP3-C3', + 'āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 3) āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡', + ( + SELECT id + FROM projects + WHERE project_code = 'LCBP3-C3' + ), + TRUE + ), + ( + 'LCBP3-C4', + 'āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 4) āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡', + ( + SELECT id + FROM projects + WHERE project_code = 'LCBP3-C4' + ), + TRUE + ), + ( + 'LCBP3-EN', + 'āļ‡āļēāļ™āļˆāđ‰āļēāļ‡āđ€āļŦāļĄāļēāļ•āļĢāļ§āļˆāļŠāļ­āļšāļœāļĨāļāļĢāļ°āļ—āļšāļŠāļīāđˆāļ‡āđāļ§āļ”āļĨāđ‰āļ­āļĄāļ™āļ°āļŦāļ§āđˆāļēāļ‡āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 1-4)', + ( + SELECT id + FROM projects + WHERE project_code = 'LCBP3' + ), + TRUE + ); + +-- Seed user +-- Initial SUPER_ADMIN user +INSERT INTO users ( + `user_id`, + `username`, + `password_hash`, + `first_name`, + `last_name`, + `email`, + `line_id`, + `primary_organization_id` + ) +VALUES ( + 1, + 'superadmin', + '$2b$10$E6d5k.f46jr.POGWKHhiQ.X1ZsFrMpZox//sCxeOiLUULGuAHO0NW', + 'Super', + 'Admin', + 'superadmin @example.com', + NULL, + NULL + ), + ( + 2, + 'admin', + '$2b$10$E6d5k.f46jr.POGWKHhiQ.X1ZsFrMpZox//sCxeOiLUULGuAHO0NW', + 'Admin', + 'āļ„āļ„āļ‡.', + 'admin@example.com', + NULL, + 1 + ), + ( + 3, + 'editor01', + '$2b$10$E6d5k.f46jr.POGWKHhiQ.X1ZsFrMpZox//sCxeOiLUULGuAHO0NW', + 'DC', + 'C1', + 'editor01 @example.com', + NULL, + 41 + ), + ( + 4, + 'viewer01', + '$2b$10$E6d5k.f46jr.POGWKHhiQ.X1ZsFrMpZox//sCxeOiLUULGuAHO0NW', + 'Viewer', + 'āļŠāļ„āļ‰.03', + 'viewer01 @example.com', + NULL, + 10 + ); + +-- ========================================================== +-- Seed Roles (āļšāļ—āļšāļēāļ—āļžāļ·āđ‰āļ™āļāļēāļ™ 5 āļšāļ—āļšāļēāļ— āļ•āļēāļĄ Req 4.3) +-- ========================================================== +-- 1. Superadmin (Global) +INSERT INTO roles (role_id, role_name, scope, description) +VALUES ( + 1, + 'Superadmin', + 'Global', + 'āļœāļđāđ‰āļ”āļđāđāļĨāļĢāļ°āļšāļšāļŠāļđāļ‡āļŠāļļāļ”: āļŠāļēāļĄāļēāļĢāļ–āļ—āļģāļ—āļļāļāļ­āļĒāđˆāļēāļ‡āđƒāļ™āļĢāļ°āļšāļš, āļˆāļąāļ”āļāļēāļĢāļ­āļ‡āļ„āđŒāļāļĢ, āđāļĨāļ°āļˆāļąāļ”āļāļēāļĢāļ‚āđ‰āļ­āļĄāļđāļĨāļŦāļĨāļąāļāļĢāļ°āļ”āļąāļš Global' + ), + -- 2. Org Admin (Organization) + ( + 2, + 'Org Admin', + 'Organization', + 'āļœāļđāđ‰āļ”āļđāđāļĨāļ­āļ‡āļ„āđŒāļāļĢ: āļˆāļąāļ”āļāļēāļĢāļœāļđāđ‰āđƒāļŠāđ‰āđƒāļ™āļ­āļ‡āļ„āđŒāļāļĢ, āļˆāļąāļ”āļāļēāļĢāļšāļ—āļšāļēāļ— / āļŠāļīāļ—āļ˜āļīāđŒāļ āļēāļĒāđƒāļ™āļ­āļ‡āļ„āđŒāļāļĢ, āđāļĨāļ°āļ”āļđāļĢāļēāļĒāļ‡āļēāļ™āļ‚āļ­āļ‡āļ­āļ‡āļ„āđŒāļāļĢ' + ), + -- 3. Document Control (Organization) + ( + 3, + 'Document Control', + 'Organization', + 'āļ„āļ§āļšāļ„āļļāļĄāđ€āļ­āļāļŠāļēāļĢāļ‚āļ­āļ‡āļ­āļ‡āļ„āđŒāļāļĢ: āđ€āļžāļīāđˆāļĄ / āđāļāđ‰āđ„āļ‚ / āļĨāļšāđ€āļ­āļāļŠāļēāļĢ, āđāļĨāļ°āļāļģāļŦāļ™āļ”āļŠāļīāļ—āļ˜āļīāđŒāđ€āļ­āļāļŠāļēāļĢāļ āļēāļĒāđƒāļ™āļ­āļ‡āļ„āđŒāļāļĢ' + ), + -- 4. Editor (Organization) + ( + 4, + 'Editor', + 'Organization', + 'āļœāļđāđ‰āđāļāđ‰āđ„āļ‚āđ€āļ­āļāļŠāļēāļĢāļ‚āļ­āļ‡āļ­āļ‡āļ„āđŒāļāļĢ: āđ€āļžāļīāđˆāļĄ / āđāļāđ‰āđ„āļ‚āđ€āļ­āļāļŠāļēāļĢāļ—āļĩāđˆāđ„āļ”āđ‰āļĢāļąāļšāļĄāļ­āļšāļŦāļĄāļēāļĒ' + ), + -- 5. Viewer (Organization) + ( + 5, + 'Viewer', + 'Organization', + 'āļœāļđāđ‰āļ”āļđāđ€āļ­āļāļŠāļēāļĢāļ‚āļ­āļ‡āļ­āļ‡āļ„āđŒāļāļĢ: āļ”āļđāđ€āļ­āļāļŠāļēāļĢāļ—āļĩāđˆāļĄāļĩāļŠāļīāļ—āļ˜āļīāđŒāđ€āļ‚āđ‰āļēāļ–āļķāļ‡āđ€āļ—āđˆāļēāļ™āļąāđ‰āļ™' + ), + -- 6. Project Manager (Project) + ( + 6, + 'Project Manager', + 'Project', + 'āļœāļđāđ‰āļˆāļąāļ”āļāļēāļĢāđ‚āļ„āļĢāļ‡āļāļēāļĢ: āļˆāļąāļ”āļāļēāļĢāļŠāļĄāļēāļŠāļīāļāđƒāļ™āđ‚āļ„āļĢāļ‡āļāļēāļĢ, āļŠāļĢāđ‰āļēāļ‡ / āļˆāļąāļ”āļāļēāļĢāļŠāļąāļāļāļēāđƒāļ™āđ‚āļ„āļĢāļ‡āļāļēāļĢ, āđāļĨāļ°āļ”āļđāļĢāļēāļĒāļ‡āļēāļ™āđ‚āļ„āļĢāļ‡āļāļēāļĢ' + ), + -- 7. Contract Admin (Contract) + ( + 7, + 'Contract Admin', + 'Contract', + 'āļœāļđāđ‰āļ”āļđāđāļĨāļŠāļąāļāļāļē: āļˆāļąāļ”āļāļēāļĢāļŠāļĄāļēāļŠāļīāļāđƒāļ™āļŠāļąāļāļāļē, āļŠāļĢāđ‰āļēāļ‡ / āļˆāļąāļ”āļāļēāļĢāļ‚āđ‰āļ­āļĄāļđāļĨāļŦāļĨāļąāļāđ€āļ‰āļžāļēāļ°āļŠāļąāļāļāļē, āđāļĨāļ°āļ­āļ™āļļāļĄāļąāļ•āļīāđ€āļ­āļāļŠāļēāļĢāđƒāļ™āļŠāļąāļāļāļē' + ); + +-- ===================================================== +-- 2. Seed Permissions (āļŠāļīāļ—āļ˜āļīāđŒāļāļēāļĢāđƒāļŠāđ‰āļ‡āļēāļ™āļ—āļąāđ‰āļ‡āļŦāļĄāļ”) +-- āļŠāļīāļ—āļ˜āļīāđŒāļĢāļ°āļ”āļąāļšāļĢāļ°āļšāļšāđāļĨāļ°āļāļēāļĢāļˆāļąāļ”āļāļēāļĢāļŦāļĨāļąāļ (System & Master Data) +-- ===================================================== +INSERT INTO permissions ( + permission_id, + permission_name, + description + ) +VALUES ( + 1, + 'system.manage_all', + 'āļ—āļģāļ—āļļāļāļ­āļĒāđˆāļēāļ‡āđƒāļ™āļĢāļ°āļšāļš (Superadmin Power)' + ), + -- āļāļēāļĢāļˆāļąāļ”āļāļēāļĢāļ­āļ‡āļ„āđŒāļāļĢ + ( + 2, + 'organization.create', + 'āļŠāļĢāđ‰āļēāļ‡āļ­āļ‡āļ„āđŒāļāļĢāđƒāļŦāļĄāđˆ' + ), + ( + 3, + 'organization.edit', + 'āđāļāđ‰āđ„āļ‚āļ‚āđ‰āļ­āļĄāļđāļĨāļ­āļ‡āļ„āđŒāļāļĢ' + ), + ( + 4, + 'organization.delete', + 'āļĨāļšāļ­āļ‡āļ„āđŒāļāļĢ' + ), + ( + 5, + 'organization.view', + 'āļ”āļđāļĢāļēāļĒāļāļēāļĢāļ­āļ‡āļ„āđŒāļāļĢ' + ), + -- āļāļēāļĢāļˆāļąāļ”āļāļēāļĢāđ‚āļ„āļĢāļ‡āļāļēāļĢ + ( + 6, + 'project.create', + 'āļŠāļĢāđ‰āļēāļ‡āđ‚āļ„āļĢāļ‡āļāļēāļĢāđƒāļŦāļĄāđˆ' + ), + ( + 7, + 'project.edit', + 'āđāļāđ‰āđ„āļ‚āļ‚āđ‰āļ­āļĄāļđāļĨāđ‚āļ„āļĢāļ‡āļāļēāļĢ' + ), + (8, 'project.delete', 'āļĨāļšāđ‚āļ„āļĢāļ‡āļāļēāļĢ'), + ( + 9, + 'project.view', + 'āļ”āļđāļĢāļēāļĒāļāļēāļĢāđ‚āļ„āļĢāļ‡āļāļēāļĢ' + ), + -- āļāļēāļĢāļˆāļąāļ”āļāļēāļĢāļšāļ—āļšāļēāļ—āđāļĨāļ°āļŠāļīāļ—āļ˜āļīāđŒ (Roles & Permissions) + ( + 10, + 'role.create', + 'āļŠāļĢāđ‰āļēāļ‡āļšāļ—āļšāļēāļ— (Role) āđƒāļŦāļĄāđˆ' + ), + ( + 11, + 'role.edit', + 'āđāļāđ‰āđ„āļ‚āļšāļ—āļšāļēāļ— (Role)' + ), + (12, 'role.delete', 'āļĨāļšāļšāļ—āļšāļēāļ— (Role)'), + ( + 13, + 'permission.assign', + 'āļĄāļ­āļšāļŠāļīāļ—āļ˜āļīāđŒāđƒāļŦāđ‰āļāļąāļšāļšāļ—āļšāļēāļ— (Role)' + ), + -- āļāļēāļĢāļˆāļąāļ”āļāļēāļĢāļ‚āđ‰āļ­āļĄāļđāļĨāļŦāļĨāļąāļ (Master Data) + ( + 14, + 'master_data.document_type.manage', + 'āļˆāļąāļ”āļāļēāļĢāļ›āļĢāļ°āđ€āļ āļ—āđ€āļ­āļāļŠāļēāļĢ (Document Types)' + ), + ( + 15, + 'master_data.document_status.manage', + 'āļˆāļąāļ”āļāļēāļĢāļŠāļ–āļēāļ™āļ°āđ€āļ­āļāļŠāļēāļĢ (Document Statuses)' + ), + ( + 16, + 'master_data.drawing_category.manage', + 'āļˆāļąāļ”āļāļēāļĢāļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāđāļšāļš (Drawing Categories)' + ), + ( + 17, + 'master_data.tag.manage', + 'āļˆāļąāļ”āļāļēāļĢ Tags' + ), + -- āļāļēāļĢāļˆāļąāļ”āļāļēāļĢāļœāļđāđ‰āđƒāļŠāđ‰āļ‡āļēāļ™ + ( + 18, + 'user.create', + 'āļŠāļĢāđ‰āļēāļ‡āļœāļđāđ‰āđƒāļŠāđ‰āļ‡āļēāļ™āđƒāļŦāļĄāđˆ' + ), + ( + 19, + 'user.edit', + 'āđāļāđ‰āđ„āļ‚āļ‚āđ‰āļ­āļĄāļđāļĨāļœāļđāđ‰āđƒāļŠāđ‰āļ‡āļēāļ™' + ), + ( + 20, + 'user.delete', + 'āļĨāļš / āļ›āļīāļ”āļāļēāļĢāđƒāļŠāđ‰āļ‡āļēāļ™āļœāļđāđ‰āđƒāļŠāđ‰' + ), + ( + 21, + 'user.view', + 'āļ”āļđāļ‚āđ‰āļ­āļĄāļđāļĨāļœāļđāđ‰āđƒāļŠāđ‰āļ‡āļēāļ™' + ), + ( + 22, + 'user.assign_organization', + 'āļĄāļ­āļšāļœāļđāđ‰āđƒāļŠāđ‰āļ‡āļēāļ™āđƒāļŦāđ‰āļāļąāļšāļ­āļ‡āļ„āđŒāļāļĢ' + ); + +-- ===================================================== +-- == 2. āļŠāļīāļ—āļ˜āļīāđŒāļāļēāļĢāļˆāļąāļ”āļāļēāļĢāđ‚āļ„āļĢāļ‡āļāļēāļĢāđāļĨāļ°āļŠāļąāļāļāļē (Project & Contract) == +-- ===================================================== +INSERT INTO permissions ( + permission_id, + permission_name, + description + ) +VALUES ( + 23, + 'project.manage_members', + 'āļˆāļąāļ”āļāļēāļĢāļŠāļĄāļēāļŠāļīāļāđƒāļ™āđ‚āļ„āļĢāļ‡āļāļēāļĢ (āđ€āļŠāļīāļ / āļ–āļ­āļ”āļŠāļĄāļēāļŠāļīāļ)' + ), + ( + 24, + 'project.create_contracts', + 'āļŠāļĢāđ‰āļēāļ‡āļŠāļąāļāļāļēāđƒāļ™āđ‚āļ„āļĢāļ‡āļāļēāļĢ' + ), + ( + 25, + 'project.manage_contracts', + 'āļˆāļąāļ”āļāļēāļĢāļŠāļąāļāļāļēāđƒāļ™āđ‚āļ„āļĢāļ‡āļāļēāļĢ' + ), + ( + 26, + 'project.view_reports', + 'āļ”āļđāļĢāļēāļĒāļ‡āļēāļ™āļĢāļ°āļ”āļąāļšāđ‚āļ„āļĢāļ‡āļāļēāļĢ' + ), + ( + 27, + 'contract.manage_members', + 'āļˆāļąāļ”āļāļēāļĢāļŠāļĄāļēāļŠāļīāļāđƒāļ™āļŠāļąāļāļāļē' + ), + ( + 28, + 'contract.view', + 'āļ”āļđāļ‚āđ‰āļ­āļĄāļđāļĨāļŠāļąāļāļāļē' + ); + +-- ===================================================== +-- == 3. āļŠāļīāļ—āļ˜āļīāđŒāļāļēāļĢāļˆāļąāļ”āļāļēāļĢāđ€āļ­āļāļŠāļēāļĢ (Document Management) == +-- ===================================================== +-- āļŠāļīāļ—āļ˜āļīāđŒāļ—āļąāđˆāļ§āđ„āļ›āļŠāļģāļŦāļĢāļąāļšāđ€āļ­āļāļŠāļēāļĢāļ—āļļāļāļ›āļĢāļ°āđ€āļ āļ— +INSERT INTO permissions ( + permission_id, + permission_name, + description + ) +VALUES ( + 29, + 'document.create_draft', + 'āļŠāļĢāđ‰āļēāļ‡āđ€āļ­āļāļŠāļēāļĢāđƒāļ™āļŠāļ–āļēāļ™āļ°āļ‰āļšāļąāļšāļĢāđˆāļēāļ‡ (Draft) ' + ), + ( + 30, + 'document.submit', + 'āļŠāđˆāļ‡āđ€āļ­āļāļŠāļēāļĢ (Submitted)' + ), + (31, 'document.view', 'āļ”āļđāđ€āļ­āļāļŠāļēāļĢ'), + ( + 32, + 'document.edit', + 'āđāļāđ‰āđ„āļ‚āđ€āļ­āļāļŠāļēāļĢ (āļ—āļąāđˆāļ§āđ„āļ›)' + ), + ( + 33, + 'document.admin_edit', + 'āđāļāđ‰āđ„āļ‚ / āļ–āļ­āļ™ / āļĒāļāđ€āļĨāļīāļāđ€āļ­āļāļŠāļēāļĢāļ—āļĩāđˆāļŠāđˆāļ‡āđāļĨāđ‰āļ§ (Admin Power) ' + ), + (34, 'document.delete', 'āļĨāļšāđ€āļ­āļāļŠāļēāļĢ'), + ( + 35, + 'document.attach', + 'āļˆāļąāļ”āļāļēāļĢāđ„āļŸāļĨāđŒāđāļ™āļš (āļ­āļąāļ›āđ‚āļŦāļĨāļ” / āļĨāļš) ' + ), + -- āļŠāļīāļ—āļ˜āļīāđŒāđ€āļ‰āļžāļēāļ°āļŠāļģāļŦāļĢāļąāļš Correspondence + ( + 36, + 'correspondence.create', + 'āļŠāļĢāđ‰āļēāļ‡āđ€āļ­āļāļŠāļēāļĢāđ‚āļ•āđ‰āļ•āļ­āļš (Correspondence) ' + ), + -- āļŠāļīāļ—āļ˜āļīāđŒāđ€āļ‰āļžāļēāļ°āļŠāļģāļŦāļĢāļąāļš Request for Approval (RFA) + ( + 37, + 'rfa.create', + 'āļŠāļĢāđ‰āļēāļ‡āđ€āļ­āļāļŠāļēāļĢāļ‚āļ­āļ­āļ™āļļāļĄāļąāļ•āļī (RFA)' + ), + ( + 38, + 'rfa.manage_shop_drawings', + 'āļˆāļąāļ”āļāļēāļĢāļ‚āđ‰āļ­āļĄāļđāļĨ Shop Drawing āđāļĨāļ° Contract Drawing āļ—āļĩāđˆāđ€āļāļĩāđˆāļĒāļ§āļ‚āđ‰āļ­āļ‡' + ), + -- āļŠāļīāļ—āļ˜āļīāđŒāđ€āļ‰āļžāļēāļ°āļŠāļģāļŦāļĢāļąāļš Shop Drawing & Contract Drawing + ( + 39, + 'drawing.create', + 'āļŠāļĢāđ‰āļēāļ‡ / āđāļāđ‰āđ„āļ‚āļ‚āđ‰āļ­āļĄāļđāļĨāđāļšāļš (Shop / Contract Drawing)' + ), + -- āļŠāļīāļ—āļ˜āļīāđŒāđ€āļ‰āļžāļēāļ°āļŠāļģāļŦāļĢāļąāļš Transmittal + ( + 40, + 'transmittal.create', + 'āļŠāļĢāđ‰āļēāļ‡āđ€āļ­āļāļŠāļēāļĢāļ™āļģāļŠāđˆāļ‡ (Transmittal)' + ), + -- āļŠāļīāļ—āļ˜āļīāđŒāđ€āļ‰āļžāļēāļ°āļŠāļģāļŦāļĢāļąāļš Circulation Sheet (āđƒāļšāđ€āļ§āļĩāļĒāļ™) + ( + 41, + 'circulation.create', + 'āļŠāļĢāđ‰āļēāļ‡āđƒāļšāđ€āļ§āļĩāļĒāļ™āđ€āļ­āļāļŠāļēāļĢ (Circulation)' + ), + ( + 42, + 'circulation.respond', + 'āļ•āļ­āļšāļāļĨāļąāļšāđƒāļšāđ€āļ§āļĩāļĒāļ™ (Main / Action)' + ), + ( + 43, + 'circulation.acknowledge', + 'āļĢāļąāļšāļ—āļĢāļēāļšāđƒāļšāđ€āļ§āļĩāļĒāļ™ (Information)' + ), + ( + 44, + 'circulation.close', + 'āļ›āļīāļ”āđƒāļšāđ€āļ§āļĩāļĒāļ™' + ); + +-- ===================================================== +-- == 4. āļŠāļīāļ—āļ˜āļīāđŒāļāļēāļĢāļˆāļąāļ”āļāļēāļĢ Workflow == +-- ===================================================== +INSERT INTO permissions ( + permission_id, + permission_name, + description + ) +VALUES ( + 45, + 'workflow.action_review', + 'āļ”āļģāđ€āļ™āļīāļ™āļāļēāļĢāđƒāļ™āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļ›āļąāļˆāļˆāļļāļšāļąāļ™ (āđ€āļŠāđˆāļ™ āļ•āļĢāļ§āļˆāļŠāļ­āļšāđāļĨāđ‰āļ§)' + ), + ( + 46, + 'workflow.force_proceed', + 'āļšāļąāļ‡āļ„āļąāļšāđ„āļ›āļĒāļąāļ‡āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļ–āļąāļ”āđ„āļ› (Document Control Power)' + ), + ( + 47, + 'workflow.revert', + 'āļĒāđ‰āļ­āļ™āļāļĨāļąāļšāđ„āļ›āļĒāļąāļ‡āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļāđˆāļ­āļ™āļŦāļ™āđ‰āļē (Document Control Power)' + ); + +-- ===================================================== +-- == 5. āļŠāļīāļ—āļ˜āļīāđŒāļ”āđ‰āļēāļ™āļāļēāļĢāļ„āđ‰āļ™āļŦāļēāđāļĨāļ°āļĢāļēāļĒāļ‡āļēāļ™ (Search & Reporting) == +-- ===================================================== +INSERT INTO permissions ( + permission_id, + permission_name, + description + ) +VALUES ( + 48, + 'search.advanced', + 'āđƒāļŠāđ‰āļ‡āļēāļ™āļāļēāļĢāļ„āđ‰āļ™āļŦāļēāļ‚āļąāđ‰āļ™āļŠāļđāļ‡' + ), + ( + 49, + 'report.generate', + 'āļŠāļĢāđ‰āļēāļ‡āļĢāļēāļĒāļ‡āļēāļ™āļŠāļĢāļļāļ› (āļĢāļēāļĒāļ§āļąāļ™ / āļŠāļąāļ›āļ”āļēāļŦāđŒ / āđ€āļ”āļ·āļ­āļ™ / āļ›āļĩ)' + ); + +-- ========================================================== +-- Seed Role-Permissions Mapping (āļˆāļąāļšāļ„āļđāđˆāļŠāļīāļ—āļ˜āļīāđŒāđ€āļĢāļīāđˆāļĄāļ•āđ‰āļ™) +-- ========================================================== +-- Seed data for the 'role_permissions 'table +-- This table links roles to their specific permissions. +-- NOTE: This assumes the role_id and permission_id FROM the previous seed data files. +-- Superadmin (role_id = 1), Org Admin (role_id = 2), Document Control (role_id = 3), etc. +-- ===================================================== +-- == 1. Superadmin (role_id = 1) - Gets ALL permissions == +-- ===================================================== +-- Superadmin can do everything. We can dynamically link all permissions to this role. +-- This is a robust way to ensure Superadmin always has full power. +INSERT INTO role_permissions (role_id, permission_id) +SELECT 1, + permission_id +FROM permissions; + +-- ===================================================== +-- == 2. Org Admin (role_id = 2) == +-- ===================================================== +INSERT INTO role_permissions (role_id, permission_id) +VALUES -- āļˆāļąāļ”āļāļēāļĢāļœāļđāđ‰āđƒāļŠāđ‰āđƒāļ™āļ­āļ‡āļ„āđŒāļāļĢ + (2, 18), + -- user.create + (2, 19), + -- user.edit + (2, 20), + -- user.delete + (2, 21), + -- user.view + (2, 22), + -- user.assign_organization + -- āļˆāļąāļ”āļāļēāļĢāļ­āļ‡āļ„āđŒāļāļĢ + (2, 3), + -- organization.edit + (2, 5), + -- organization.view + -- āļˆāļąāļ”āļāļēāļĢāļ‚āđ‰āļ­āļĄāļđāļĨāļŦāļĨāļąāļāļ—āļĩāđˆāļ­āļ™āļļāļāļēāļ• (āđ€āļ‰āļžāļēāļ° Tags) + (2, 17), + -- master_data.tag.manage + -- āļ”āļđāļ‚āđ‰āļ­āļĄāļđāļĨāļ•āđˆāļēāļ‡āđ† āđƒāļ™āļ­āļ‡āļ„āđŒāļāļĢ + (2, 31), + -- document.view + (2, 9), + -- project.view + (2, 28), + -- contract.view + -- āļāļēāļĢāļ„āđ‰āļ™āļŦāļēāđāļĨāļ°āļĢāļēāļĒāļ‡āļēāļ™ + (2, 48), + -- search.advanced + (2, 49); + +-- report.generate +-- ===================================================== +-- == 3. Document Control (role_id = 3) == +-- ===================================================== +INSERT INTO role_permissions (role_id, permission_id) +VALUES -- āļŠāļīāļ—āļ˜āļīāđŒāļˆāļąāļ”āļāļēāļĢāđ€āļ­āļāļŠāļēāļĢāļ—āļąāđ‰āļ‡āļŦāļĄāļ” + (3, 29), + -- document.create_draft + (3, 30), + -- document.submit + (3, 31), + -- document.view + (3, 32), + -- document.edit + (3, 33), + -- document.admin_edit + (3, 34), + -- document.delete + (3, 35), + -- document.attach + -- āļŠāļīāļ—āļ˜āļīāđŒāļŠāļĢāđ‰āļēāļ‡āđ€āļ­āļāļŠāļēāļĢāđāļ•āđˆāļĨāļ°āļ›āļĢāļ°āđ€āļ āļ— + (3, 36), + -- correspondence.create + (3, 37), + -- rfa.create + (3, 39), + -- drawing.create + (3, 40), + -- transmittal.create + (3, 41), + -- circulation.create + -- āļŠāļīāļ—āļ˜āļīāđŒāļˆāļąāļ”āļāļēāļĢ Workflow + (3, 45), + -- workflow.action_review + (3, 46), + -- workflow.force_proceed + (3, 47), + -- workflow.revert + -- āļŠāļīāļ—āļ˜āļīāđŒāļˆāļąāļ”āļāļēāļĢ Circulation + (3, 42), + -- circulation.respond + (3, 43), + -- circulation.acknowledge + (3, 44), + -- circulation.close + -- āļŠāļīāļ—āļ˜āļīāđŒāļ­āļ·āđˆāļ™āđ† āļ—āļĩāđˆāļˆāļģāđ€āļ›āđ‡āļ™ + (3, 38), + -- rfa.manage_shop_drawings + (3, 48), + -- search.advanced + (3, 49); + +-- report.generate +-- ===================================================== +-- == 4. Editor (role_id = 4) == +-- ===================================================== +INSERT INTO role_permissions (role_id, permission_id) +VALUES -- āļŠāļīāļ—āļ˜āļīāđŒāđāļāđ‰āđ„āļ‚āđ€āļ­āļāļŠāļēāļĢ (āđāļ•āđˆāđ„āļĄāđˆāđƒāļŠāđˆāļŠāļīāļ—āļ˜āļīāđŒ Admin) + (4, 29), + -- document.create_draft + (4, 30), + -- document.submit + (4, 31), + -- document.view + (4, 32), + -- document.edit + (4, 35), + -- document.attach + -- āļŠāļīāļ—āļ˜āļīāđŒāļŠāļĢāđ‰āļēāļ‡āđ€āļ­āļāļŠāļēāļĢāđāļ•āđˆāļĨāļ°āļ›āļĢāļ°āđ€āļ āļ— + (4, 36), + -- correspondence.create + (4, 37), + -- rfa.create + (4, 39), + -- drawing.create + (4, 40), + -- transmittal.create + (4, 41), + -- circulation.create + -- āļŠāļīāļ—āļ˜āļīāđŒāļ­āļ·āđˆāļ™āđ† āļ—āļĩāđˆāļˆāļģāđ€āļ›āđ‡āļ™ + (4, 38), + -- rfa.manage_shop_drawings + (4, 48); + +-- search.advanced +-- ===================================================== +-- == 5. Viewer (role_id = 5) == +-- ===================================================== +INSERT INTO role_permissions (role_id, permission_id) +VALUES -- āļŠāļīāļ—āļ˜āļīāđŒāļ”āļđāđ€āļ—āđˆāļēāļ™āļąāđ‰āļ™ + (5, 31), + -- document.view + (5, 48); + +-- search.advanced +-- ===================================================== +-- == 6. Project Manager (role_id = 6) == +-- ===================================================== +INSERT INTO role_permissions (role_id, permission_id) +VALUES -- āļŠāļīāļ—āļ˜āļīāđŒāļˆāļąāļ”āļāļēāļĢāđ‚āļ„āļĢāļ‡āļāļēāļĢ + (6, 23), + -- project.manage_members + (6, 24), + -- project.create_contracts + (6, 25), + -- project.manage_contracts + (6, 26), + -- project.view_reports + (6, 9), + -- project.view + -- āļŠāļīāļ—āļ˜āļīāđŒāļˆāļąāļ”āļāļēāļĢāļ‚āđ‰āļ­āļĄāļđāļĨāļŦāļĨāļąāļāļĢāļ°āļ”āļąāļšāđ‚āļ„āļĢāļ‡āļāļēāļĢ + (6, 16), + -- master_data.drawing_category.manage + -- āļŠāļīāļ—āļ˜āļīāđŒāļ”āļđāļ‚āđ‰āļ­āļĄāļđāļĨāđƒāļ™āļŠāļąāļāļāļē + (6, 28), + -- contract.view + -- āļŠāļīāļ—āļ˜āļīāđŒāđƒāļ™āļāļēāļĢāļˆāļąāļ”āļāļēāļĢāđ€āļ­āļāļŠāļēāļĢ (āļĢāļ°āļ”āļąāļš Editor) + (6, 29), + -- document.create_draft + (6, 30), + -- document.submit + (6, 31), + -- document.view + (6, 32), + -- document.edit + (6, 35), + -- document.attach + (6, 36), + -- correspondence.create + (6, 37), + -- rfa.create + (6, 39), + -- drawing.create + (6, 40), + -- transmittal.create + (6, 41), + -- circulation.create + (6, 38), + -- rfa.manage_shop_drawings + (6, 48), + -- search.advanced + (6, 49); + +-- report.generate +-- ===================================================== +-- == 7. Contract Admin (role_id = 7) == +-- ===================================================== +INSERT INTO role_permissions (role_id, permission_id) +VALUES -- āļŠāļīāļ—āļ˜āļīāđŒāļˆāļąāļ”āļāļēāļĢāļŠāļąāļāļāļē + (7, 27), + -- contract.manage_members + (7, 28), + -- contract.view + -- āļŠāļīāļ—āļ˜āļīāđŒāđƒāļ™āļāļēāļĢāļ­āļ™āļļāļĄāļąāļ•āļī (āļŠāđˆāļ§āļ™āļŦāļ™āļķāđˆāļ‡āļ‚āļ­āļ‡ Workflow) + (7, 45), + -- workflow.action_review + -- āļŠāļīāļ—āļ˜āļīāđŒāļˆāļąāļ”āļāļēāļĢāļ‚āđ‰āļ­āļĄāļđāļĨāđ€āļ‰āļžāļēāļ°āļŠāļąāļāļāļē + (7, 38), + -- rfa.manage_shop_drawings + (7, 39), + -- drawing.create + -- āļŠāļīāļ—āļ˜āļīāđŒāđƒāļ™āļāļēāļĢāļˆāļąāļ”āļāļēāļĢāđ€āļ­āļāļŠāļēāļĢ (āļĢāļ°āļ”āļąāļš Editor) + (7, 29), + -- document.create_draft + (7, 30), + -- document.submit + (7, 31), + -- document.view + (7, 32), + -- document.edit + (7, 35), + -- document.attach + (7, 36), + -- correspondence.create + (7, 37), + -- rfa.create + (7, 40), + -- transmittal.create + (7, 41), + -- circulation.create + (7, 48); + +-- Seed data for the 'user_assignments' table +INSERT INTO `user_assignments` ( + `id`, + `user_id`, + `role_id`, + `organization_id`, + `project_id`, + `contract_id`, + `assigned_by_user_id` + ) +VALUES ( + 1, + 1, + 1, + NULL, + NULL, + NULL, + NULL + ), + (2, 2, 2, 1, NULL, NULL, NULL); + +-- ===================================================== +-- == 4. āļāļēāļĢāđ€āļŠāļ·āđˆāļ­āļĄāđ‚āļĒāļ‡āđ‚āļ„āļĢāļ‡āļāļēāļĢāļāļąāļšāļ­āļ‡āļ„āđŒāļāļĢ (project_organizations) == +-- ===================================================== +-- āđ‚āļ„āļĢāļ‡āļāļēāļĢāļŦāļĨāļąāļ (LCBP3) āļˆāļ°āļĄāļĩāļ­āļ‡āļ„āđŒāļāļĢāļŦāļĨāļąāļāđ† āđ€āļ‚āđ‰āļēāļĄāļēāđ€āļāļĩāđˆāļĒāļ§āļ‚āđ‰āļ­āļ‡āļ—āļąāđ‰āļ‡āļŦāļĄāļ” +INSERT INTO project_organizations (project_id, organization_id) +SELECT ( + SELECT id + FROM projects + WHERE project_code = 'LCBP3' + ), + id +FROM organizations +WHERE organization_code IN ( + 'āļāļ—āļ—.', + 'āļŠāļ„āļ‰.3', + 'TEAM', + 'āļ„āļ„āļ‡.', + 'āļœāļĢāļĄ.1', + 'āļœāļĢāļĄ.2', + 'āļœāļĢāļĄ.3', + 'āļœāļĢāļĄ.4', + 'EN', + 'CAR' + ); + +-- āđ‚āļ„āļĢāļ‡āļāļēāļĢāļĒāđˆāļ­āļĒ (LCBP3C1) āļˆāļ°āļĄāļĩāđ€āļ‰āļžāļēāļ°āļ­āļ‡āļ„āđŒāļāļĢāļ—āļĩāđˆāđ€āļāļĩāđˆāļĒāļ§āļ‚āđ‰āļ­āļ‡ +INSERT INTO project_organizations (project_id, organization_id) +SELECT ( + SELECT id + FROM projects + WHERE project_code = 'LCBP3-C1' + ), + id +FROM organizations +WHERE organization_code IN ( + 'āļāļ—āļ—.', + 'āļŠāļ„āļ‰.3', + 'āļŠāļ„āļ‰.3 -02', + 'āļ„āļ„āļ‡.', + 'āļœāļĢāļĄ.1 ' + ); + +-- āļ—āļģāđ€āļŠāđˆāļ™āđ€āļ”āļĩāļĒāļ§āļāļąāļ™āļŠāļģāļŦāļĢāļąāļšāđ‚āļ„āļĢāļ‡āļāļēāļĢāļ­āļ·āđˆāļ™āđ† (āļ•āļąāļ§āļ­āļĒāđˆāļēāļ‡) +INSERT INTO project_organizations (project_id, organization_id) +SELECT ( + SELECT id + FROM projects + WHERE project_code = 'LCBP3-C2' + ), + id +FROM organizations +WHERE organization_code IN ( + 'āļāļ—āļ—.', + 'āļŠāļ„āļ‰.3', + 'āļŠāļ„āļ‰.3 -03', + 'āļ„āļ„āļ‡.', + 'āļœāļĢāļĄ.2' + ); + +-- ===================================================== +-- == 5. āļāļēāļĢāđ€āļŠāļ·āđˆāļ­āļĄāđ‚āļĒāļ‡āļŠāļąāļāļāļēāļāļąāļšāļ­āļ‡āļ„āđŒāļāļĢ (contract_organizations) == +-- ===================================================== +-- āļŠāļąāļāļāļēāļ—āļĩāđˆāļ›āļĢāļķāļāļĐāļēāļ­āļ­āļāđāļšāļš (DSLCBP3) +INSERT INTO contract_organizations ( + contract_id, + organization_id, + role_in_contract + ) +VALUES ( + ( + SELECT id + FROM contracts + WHERE contract_code = 'LCBP3-DS' + ), + ( + SELECT id + FROM organizations + WHERE organization_code = 'āļāļ—āļ—.' + ), + 'Owner' + ), + ( + ( + SELECT id + FROM contracts + WHERE contract_code = 'LCBP3-DS' + ), + ( + SELECT id + FROM organizations + WHERE organization_code = 'TEAM' + ), + 'Designer' + ); + +-- āļŠāļąāļāļāļēāļ—āļĩāđˆāļ›āļĢāļķāļāļĐāļēāļ„āļ§āļšāļ„āļļāļĄāļ‡āļēāļ™ (PSLCBP3) +INSERT INTO contract_organizations ( + contract_id, + organization_id, + role_in_contract + ) +VALUES ( + ( + SELECT id + FROM contracts + WHERE contract_code = 'LCBP3-PS' + ), + ( + SELECT id + FROM organizations + WHERE organization_code = 'āļāļ—āļ—.' + ), + 'Owner' + ), + ( + ( + SELECT id + FROM contracts + WHERE contract_code = 'LCBP3-PS' + ), + ( + SELECT id + FROM organizations + WHERE organization_code = 'āļ„āļ„āļ‡.' + ), + 'Consultant' + ); + +-- āļŠāļąāļāļāļēāļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 1 (LCBP3-C1) +INSERT INTO contract_organizations ( + contract_id, + organization_id, + role_in_contract + ) +VALUES ( + ( + SELECT id + FROM contracts + WHERE contract_code = 'LCBP3-C1' + ), + ( + SELECT id + FROM organizations + WHERE organization_code = 'āļāļ—āļ—.' + ), + 'Owner' + ), + ( + ( + SELECT id + FROM contracts + WHERE contract_code = 'LCBP3-C1' + ), + ( + SELECT id + FROM organizations + WHERE organization_code = 'āļœāļĢāļĄ.1' + ), + 'Contractor' + ); + +-- āļŠāļąāļāļāļēāļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 2 (LCBP3-C2) +INSERT INTO contract_organizations ( + contract_id, + organization_id, + role_in_contract + ) +VALUES ( + ( + SELECT id + FROM contracts + WHERE contract_code = 'LCBP3-C2' + ), + ( + SELECT id + FROM organizations + WHERE organization_code = 'āļāļ—āļ—.' + ), + 'Owner' + ), + ( + ( + SELECT id + FROM contracts + WHERE contract_code = 'LCBP3-C2' + ), + ( + SELECT id + FROM organizations + WHERE organization_code = 'āļœāļĢāļĄ.2' + ), + 'Contractor' + ); + +-- āļŠāļąāļāļāļēāļ•āļĢāļ§āļˆāļŠāļ­āļšāļŠāļīāđˆāļ‡āđāļ§āļ”āļĨāđ‰āļ­āļĄ (LCBP3-EN) +INSERT INTO contract_organizations ( + contract_id, + organization_id, + role_in_contract + ) +VALUES ( + ( + SELECT id + FROM contracts + WHERE contract_code = 'LCBP3-EN' + ), + ( + SELECT id + FROM organizations + WHERE organization_code = 'āļāļ—āļ—.' + ), + 'Owner' + ), + ( + ( + SELECT id + FROM contracts + WHERE contract_code = 'LCBP3-EN' + ), + ( + SELECT id + FROM organizations + WHERE organization_code = 'EN' + ), + 'Consultant' + ); + +-- Seed correspondence_status +INSERT INTO correspondence_status ( + status_code, + status_name, + sort_order, + is_active + ) +VALUES ('DRAFT', 'Draft', 10, 1), + ( + 'SUBOWN', + 'Submitted to Owner', + 21, + 1 + ), + ( + 'SUBDSN', + 'Submitted to Designer', + 22, + 1 + ), + ( + 'SUBCSC', + 'Submitted to CSC', + 23, + 1 + ), + ( + 'SUBCON', + 'Submitted to Contractor', + 24, + 1 + ), + ( + 'SUBOTH', + 'Submitted to Others', + 25, + 1 + ), + ( + 'REPOWN', + 'Reply by Owner', + 31, + 1 + ), + ( + 'REPDSN', + 'Reply by Designer', + 32, + 1 + ), + ('REPCSC', 'Reply by CSC', 33, 1), + ( + 'REPCON', + 'Reply by Contractor', + 34, + 1 + ), + ( + 'REPOTH', + 'Reply by Others', + 35, + 1 + ), + ( + 'RSBOWN', + 'Resubmited by Owner', + 41, + 1 + ), + ( + 'RSBDSN', + 'Resubmited by Designer', + 42, + 1 + ), + ( + 'RSBCSC', + 'Resubmited by CSC', + 43, + 1 + ), + ( + 'RSBCON', + 'Resubmited by Contractor', + 44, + 1 + ), + ( + 'CLBOWN', + 'Closed by Owner', + 51, + 1 + ), + ( + 'CLBDSN', + 'Closed by Designer', + 52, + 1 + ), + ('CLBCSC', 'Closed by CSC', 53, 1), + ( + 'CLBCON', + 'Closed by Contractor', + 54, + 1 + ), + ( + 'CCBOWN', + 'Canceled by Owner', + 91, + 1 + ), + ( + 'CCBDSN', + 'Canceled by Designer', + 92, + 1 + ), + ( + 'CCBCSC', + 'Canceled by CSC', + 93, + 1 + ), + ( + 'CCBCON', + 'Canceled by Contractor', + 94, + 1 + ); + +-- Seed correspondence_types +INSERT INTO correspondence_types ( + type_code, + type_name, + sort_order, + is_active + ) +VALUES ( + 'RFA', + 'Request for Approval', + 1, + 1 + ), + ( + 'RFI', + 'Request for Information', + 2, + 1 + ), + ( + 'TRANSMITTAL', + 'Transmittal', + 3, + 1 + ), + ('EMAIL', 'Email', 4, 1), + ( + 'INSTRUCTION', + 'Instruction', + 5, + 1 + ), + ('LETTER', 'Letter', 6, 1), + ('MEMO', 'Memorandum', 7, 1), + ( + 'MOM', + 'Minutes of Meeting', + 8, + 1 + ), + ('NOTICE', 'Notice', 9, 1), + ('OTHER', 'Other', 10, 1); + +-- Seed rfa_types +INSERT INTO rfa_types ( + contract_id, + type_code, + type_name_en, + type_name_th + ) +SELECT id, + 'ADW', + 'As Built Drawing', + 'āđāļšāļšāļĢāđˆāļēāļ‡āļŦāļĨāļąāļ‡āļāļēāļĢāļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'BC', + 'Box Culvert', + 'āļ—āđˆāļ­āļĢāļ°āļšāļēāļĒāļ™āđ‰āļģāļĢāļđāļ›āļāļĨāđˆāļ­āļ‡' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'BM', + 'Benchmark', + 'āļŦāļĄāļļāļ”āļŦāļĨāļąāļāļāļēāļ™' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'CER', + 'Certificates', + 'āđƒāļšāļĢāļąāļšāļĢāļ­āļ‡' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'CN', + 'Canal Drainage', + 'āļĢāļ°āļšāļšāļĢāļ°āļšāļēāļĒāļ™āđ‰āļģāđƒāļ™āļ„āļĨāļ­āļ‡' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'CON', + 'Contract', + 'āļŠāļąāļāļāļē' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'DDS', + 'Design Data Submission', + 'āļ™āļģāļŠāđˆāļ‡āļ‚āđ‰āļ­āļĄāļđāļĨāļāļēāļĢāļ­āļ­āļāđāļšāļš' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'DDW', + 'Draft Drawing', + 'āđāļšāļšāļĢāđˆāļēāļ‡' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'DRW', + 'Drawings (All Types)', + 'āđāļšāļšāļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'DSN', + 'Design/Calculation/Manual (All Stages)', + 'āļ­āļ­āļāđāļšāļš / āļ„āļģāļ™āļ§āļ“ / āļ„āļđāđˆāļĄāļ·āļ­' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'GEN', + 'General', + 'āļ—āļąāđˆāļ§āđ„āļ›' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'ICR', + 'Incident Report', + 'āļĢāļēāļĒāļ‡āļēāļ™āļāļēāļĢāđ€āļāļīāļ”āļ­āļļāļšāļąāļ•āļīāđ€āļŦāļ•āļļāđāļĨāļ°āļāļēāļĢāļšāļēāļ”āđ€āļˆāđ‡āļš' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'INS', + 'Insurances/Bond/Guarantee', + 'āļāļēāļĢāļ›āļĢāļ°āļāļąāļ™ / āļžāļąāļ™āļ˜āļšāļąāļ•āļĢ / āļāļēāļĢāļ„āđ‰āļģāļ›āļĢāļ°āļāļąāļ™' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'INR', + 'Inspection/Audit/Surveillance Report', + 'āļĢāļēāļĒāļ‡āļēāļ™āļāļēāļĢāļ•āļĢāļ§āļˆāļŠāļ­āļš / āļāļēāļĢāļ•āļĢāļ§āļˆāļŠāļ­āļš / āļĢāļēāļĒāļ‡āļēāļ™āļāļēāļĢāđ€āļāđ‰āļēāļĢāļ°āļ§āļąāļ‡' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'ITP', + 'Inspection and Test Plan', + 'āđāļœāļ™āļāļēāļĢāļ•āļĢāļ§āļˆāļŠāļ­āļšāđāļĨāļ°āļ—āļ”āļŠāļ­āļš' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'JSA', + 'Jobs Analysis', + 'āļĢāļēāļĒāļ‡āļēāļ™āļāļēāļĢāļ§āļīāđ€āļ„āļĢāļēāļ°āļŦāđŒāļ„āļ§āļēāļĄāļ›āļĨāļ­āļ”āļ āļąāļĒ' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'MAN', + 'Manual', + 'āļ„āļđāđˆāļĄāļ·āļ­' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'MAT', + 'Materials/Equipment/Plant', + 'āļ§āļąāļŠāļ”āļļ / āļ­āļļāļ›āļāļĢāļ“āđŒ / āđ‚āļĢāļ‡āļ‡āļēāļ™' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'MOM', + 'Minutes of Meeting', + 'āļĢāļēāļĒāļ‡āļēāļ™āļāļēāļĢāļ›āļĢāļ°āļŠāļļāļĄ' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'MPR', + 'Monthly Progress Report', + 'āļĢāļēāļĒāļ‡āļēāļ™āļ„āļ§āļēāļĄāļ„āļ·āļšāļŦāļ™āđ‰āļēāļ›āļĢāļ°āļˆāļģāđ€āļ”āļ·āļ­āļ™' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'MST', + 'Method Statement for Construction/Installation', + 'āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļāļēāļĢāļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ / āļ•āļīāļ”āļ•āļąāđ‰āļ‡' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'NDS', + 'Non-Design Data Submission', + 'āļ™āļģāļŠāđˆāļ‡āļ‚āđ‰āļ­āļĄāļđāļĨāļ—āļĩāđˆāđ„āļĄāđˆāđ€āļāļĩāđˆāļĒāļ§āļ‚āđ‰āļ­āļ‡āļāļąāļšāļāļēāļĢāļ­āļ­āļāđāļšāļš' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'PMA', + 'Payment/Invoice/Retention/Estimate', + 'āļāļēāļĢāļŠāļģāļĢāļ°āđ€āļ‡āļīāļ™ / āđƒāļšāđāļˆāđ‰āļ‡āļŦāļ™āļĩāđ‰ / āļ›āļĢāļ°āļāļąāļ™āļœāļĨāļ‡āļēāļ™ / āļ›āļĢāļ°āļĄāļēāļ“āļāļēāļĢ' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'PRD', + 'Procedure', + 'āļĢāļ°āđ€āļšāļĩāļĒāļšāļ›āļāļīāļšāļąāļ•āļī' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'PRG', + 'Progress of Construction', + 'āļ„āļ§āļēāļĄāļ„āļ·āļšāļŦāļ™āđ‰āļēāļ‚āļ­āļ‡āļāļēāļĢāļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ / āļ āļēāļžāļ–āđˆāļēāļĒ / āļ§āļīāļ”āļĩāđ‚āļ­' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'QMS', + 'Quality Document (Plan/Work Instruction)', + 'āđ€āļ­āļāļŠāļēāļĢāļ”āđ‰āļēāļ™āļ„āļļāļ“āļ āļēāļž (āđāļœāļ™āļ‡āļēāļ™ / āļ‚āđ‰āļ­āđāļ™āļ°āļ™āļģāđƒāļ™āļāļēāļĢāļ—āļģāļ‡āļēāļ™)' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'RPT', + 'Report', + 'āļĢāļēāļĒāļ‡āļēāļ™' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'SAR', + 'Semi Annual Report', + 'āļĢāļēāļĒāļ‡āļēāļ™āļ›āļĢāļ°āļˆāļģāļŦāļāđ€āļ”āļ·āļ­āļ™' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'SCH', + 'Schedule and Program', + 'āđāļœāļ™āļ‡āļēāļ™' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'SDW', + 'Shop Drawing', + 'āđāļšāļšāļ‚āļĒāļēāļĒāļĢāļēāļĒāļĨāļ°āđ€āļ­āļĩāļĒāļ”' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'SI', + 'Soil Investigation', + 'āļāļēāļĢāļ•āļĢāļ§āļˆāļŠāļ­āļšāļ”āļīāļ™' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'SPE', + 'Specification', + 'āļ‚āđ‰āļ­āļāļģāļŦāļ™āļ”' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'TNR', + 'Training Report', + 'āļĢāļēāļĒāļ‡āļēāļ™āļāļēāļĢāļāļķāļāļ›āļāļīāļšāļąāļ•āļī' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'UC', + 'Underground Construction', + 'āđ‚āļ„āļĢāļ‡āļŠāļĢāđ‰āļēāļ‡āđƒāļ•āđ‰āļ”āļīāļ™' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'VEN', + 'Vendor', + 'āļœāļđāđ‰āļ‚āļēāļĒ' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'VRO', + 'Variation Request/Instruction/Order', + 'āļ„āļģāļ‚āļ­āđ€āļ›āļĨāļĩāđˆāļĒāļ™āđāļ›āļĨāļ‡ / āļ‚āđ‰āļ­āđ€āļŠāļ™āļ­āđāļ™āļ° / āļ‚āđ‰āļ­āđ€āļĢāļĩāļĒāļāļĢāđ‰āļ­āļ‡' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'WTY', + 'Warranty', + 'āļāļēāļĢāļ›āļĢāļ°āļāļąāļ™' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'GEN', + 'General', + 'āļ—āļąāđˆāļ§āđ„āļ›' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'CON', + 'Contract', + 'āļŠāļąāļāļāļē' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'INS', + 'Insurances/Bond/Guarantee', + 'āļāļēāļĢāļ›āļĢāļ°āļāļąāļ™ / āļžāļąāļ™āļ˜āļšāļąāļ•āļĢ / āļāļēāļĢāļ„āđ‰āļģāļ›āļĢāļ°āļāļąāļ™' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'SCH', + 'Schedule and Program', + 'āđāļœāļ™āļ‡āļēāļ™' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'PMA', + 'Payment/Invoice/Retention/Estimate', + 'āļāļēāļĢāļŠāļģāļĢāļ°āđ€āļ‡āļīāļ™ / āđƒāļšāđāļˆāđ‰āļ‡āļŦāļ™āļĩāđ‰ / āļ›āļĢāļ°āļāļąāļ™āļœāļĨāļ‡āļēāļ™ / āļ›āļĢāļ°āļĄāļēāļ“āļāļēāļĢ' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'VRO', + 'Variation Request/Instruction/Order', + 'āļ„āļģāļ‚āļ­āđ€āļ›āļĨāļĩāđˆāļĒāļ™āđāļ›āļĨāļ‡ / āļ‚āđ‰āļ­āđ€āļŠāļ™āļ­āđāļ™āļ° / āļ‚āđ‰āļ­āđ€āļĢāļĩāļĒāļāļĢāđ‰āļ­āļ‡' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'VEN', + 'Vendor', + 'āļœāļđāđ‰āļ‚āļēāļĒ' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'WTY', + 'Warranty', + 'āļāļēāļĢāļ›āļĢāļ°āļāļąāļ™' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'DRW', + 'Drawings (All Types)', + 'āđāļšāļšāļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'DDW', + 'Draft Drawing', + 'āđāļšāļšāļĢāđˆāļēāļ‡' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'SDW', + 'Shop Drawing', + 'āđāļšāļšāļ‚āļĒāļēāļĒāļĢāļēāļĒāļĨāļ°āđ€āļ­āļĩāļĒāļ”' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'ADW', + 'As Built Drawing', + 'āđāļšāļšāļĢāđˆāļēāļ‡āļŦāļĨāļąāļ‡āļāļēāļĢāļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'DDS', + 'Design Data Submission', + 'āļ™āļģāļŠāđˆāļ‡āļ‚āđ‰āļ­āļĄāļđāļĨāļāļēāļĢāļ­āļ­āļāđāļšāļš' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'DSN', + 'Design/Calculation/Manual (All Stages)', + 'āļ­āļ­āļāđāļšāļš / āļ„āļģāļ™āļ§āļ“ / āļ„āļđāđˆāļĄāļ·āļ­' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'NDS', + 'Non-Design Data Submission', + 'āļ™āļģāļŠāđˆāļ‡āļ‚āđ‰āļ­āļĄāļđāļĨāļ—āļĩāđˆāđ„āļĄāđˆāđ€āļāļĩāđˆāļĒāļ§āļ‚āđ‰āļ­āļ‡āļāļąāļšāļāļēāļĢāļ­āļ­āļāđāļšāļš' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'PRD', + 'Procedure', + 'āļĢāļ°āđ€āļšāļĩāļĒāļšāļ›āļāļīāļšāļąāļ•āļī' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'MST', + 'Method Statement for Construction/Installation', + 'āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļāļēāļĢāļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ / āļ•āļīāļ”āļ•āļąāđ‰āļ‡' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'QMS', + 'Quality Document (Plan/Work Instruction)', + 'āđ€āļ­āļāļŠāļēāļĢāļ”āđ‰āļēāļ™āļ„āļļāļ“āļ āļēāļž (āđāļœāļ™āļ‡āļēāļ™ / āļ‚āđ‰āļ­āđāļ™āļ°āļ™āļģāđƒāļ™āļāļēāļĢāļ—āļģāļ‡āļēāļ™)' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'INR', + 'Inspection/Audit/Surveillance Report', + 'āļĢāļēāļĒāļ‡āļēāļ™āļāļēāļĢāļ•āļĢāļ§āļˆāļŠāļ­āļš / āļāļēāļĢāļ•āļĢāļ§āļˆāļŠāļ­āļš / āļĢāļēāļĒāļ‡āļēāļ™āļāļēāļĢāđ€āļāđ‰āļēāļĢāļ°āļ§āļąāļ‡' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'ITP', + 'Inspection and Test Plan', + 'āđāļœāļ™āļāļēāļĢāļ•āļĢāļ§āļˆāļŠāļ­āļšāđāļĨāļ°āļ—āļ”āļŠāļ­āļš' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'MAT', + 'Materials/Equipment/Plant', + 'āļ§āļąāļŠāļ”āļļ / āļ­āļļāļ›āļāļĢāļ“āđŒ / āđ‚āļĢāļ‡āļ‡āļēāļ™' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'SPE', + 'Specification', + 'āļ‚āđ‰āļ­āļāļģāļŦāļ™āļ”' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'MAN', + 'Manual', + 'āļ„āļđāđˆāļĄāļ·āļ­' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'CER', + 'Certificates', + 'āđƒāļšāļĢāļąāļšāļĢāļ­āļ‡' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'SAR', + 'Semi Annual Report', + 'āļĢāļēāļĒāļ‡āļēāļ™āļ›āļĢāļ°āļˆāļģāļŦāļāđ€āļ”āļ·āļ­āļ™' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'JSA', + 'Jobs Analysis', + 'āļĢāļēāļĒāļ‡āļēāļ™āļāļēāļĢāļ§āļīāđ€āļ„āļĢāļēāļ°āļŦāđŒāļ„āļ§āļēāļĄāļ›āļĨāļ­āļ”āļ āļąāļĒ' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'MOM', + 'Minutes of Meeting', + 'āļĢāļēāļĒāļ‡āļēāļ™āļāļēāļĢāļ›āļĢāļ°āļŠāļļāļĄ' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'MPR', + 'Monthly Progress Report', + 'āļĢāļēāļĒāļ‡āļēāļ™āļ„āļ§āļēāļĄāļ„āļ·āļšāļŦāļ™āđ‰āļēāļ›āļĢāļ°āļˆāļģāđ€āļ”āļ·āļ­āļ™' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'ICR', + 'Incident Report', + 'āļĢāļēāļĒāļ‡āļēāļ™āļāļēāļĢāđ€āļāļīāļ”āļ­āļļāļšāļąāļ•āļīāđ€āļŦāļ•āļļāđāļĨāļ°āļāļēāļĢāļšāļēāļ”āđ€āļˆāđ‡āļš' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'PRG', + 'Progress of Construction', + 'āļ„āļ§āļēāļĄāļ„āļ·āļšāļŦāļ™āđ‰āļēāļ‚āļ­āļ‡āļāļēāļĢāļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ / āļ āļēāļžāļ–āđˆāļēāļĒ / āļ§āļīāļ”āļĩāđ‚āļ­' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'RPT', + 'Report', + 'āļĢāļēāļĒāļ‡āļēāļ™' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'TNR', + 'Training Report', + 'āļĢāļēāļĒāļ‡āļēāļ™āļāļēāļĢāļāļķāļāļ›āļāļīāļšāļąāļ•āļī' +FROM contracts +WHERE contract_code = 'LCBP3-C2'; + +-- Seed rfa_status_codes +INSERT INTO rfa_status_codes ( + status_code, + status_name, + description, + sort_order + ) +VALUES ('DFT', 'Draft', 'āļ‰āļšāļąāļšāļĢāđˆāļēāļ‡', 1), + ( + 'FAP', + 'For Approve', + 'āđ€āļžāļ·āđˆāļ­āļ‚āļ­āļ­āļ™āļļāļĄāļąāļ•āļī', + 11 + ), + ( + 'FRE', + 'For Review', + 'āđ€āļžāļ·āđˆāļ­āļ•āļĢāļ§āļˆāļŠāļ­āļš', + 12 + ), + ( + 'FCO', + 'For Construction', + 'āđ€āļžāļ·āđˆāļ­āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡', + 20 + ), + ( + 'ASB', + 'AS - Built', + 'āđāļšāļšāļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡āļˆāļĢāļīāļ‡', + 30 + ), + ( + 'OBS', + 'Obsolete', + 'āđ„āļĄāđˆāđƒāļŠāđ‰āļ‡āļēāļ™', + 80 + ), + ('CC', 'Canceled', 'āļĒāļāđ€āļĨāļīāļ', 99); + +INSERT INTO rfa_approve_codes ( + approve_code, + approve_name, + sort_order, + is_active + ) +VALUES ( + '1A', + 'Approved by Authority', + 10, + 1 + ), + ('1C', 'Approved by CSC', 11, 1), + ('1N', 'Approved As Note', 12, 1), + ( + '1R', + 'Approved with Remarks', + 13, + 1 + ), + ( + '3C', + 'Consultant Comments', + 31, + 1 + ), + ( + '3R', + 'Revise + and Resubmit', + 32, + 1 + ), + ('4X', 'Reject', 40, 1), + ('5N', 'No Further Action', 50, 1); + +-- Seed circulation_status_codes +INSERT INTO circulation_status_codes (code, description, sort_order) +VALUES ('OPEN', 'Open', 1), + ('IN_REVIEW', 'In Review', 2), + ('COMPLETED', 'āļ›Completed', 3), + ( + 'CANCELLED', + 'Cancelled / Withdrawn', + 9 + ); + +-- āļ•āļēāļĢāļēāļ‡ "āđāļĄāđˆ" āļ‚āļ­āļ‡ RFA (āļĄāļĩāļ„āļ§āļēāļĄāļŠāļąāļĄāļžāļąāļ™āļ˜āđŒ 1:N āļāļąāļš rfa_revisions) +-- ========================================================== +-- SEED DATA 6B.md (Disciplines, RFA Types, Sub Types) +-- ========================================================== +-- 1. Seed āļ‚āđ‰āļ­āļĄāļđāļĨ Disciplines (āļŠāļēāļ‚āļēāļ‡āļēāļ™) +-- LCBP3-C1 +INSERT INTO disciplines ( + contract_id, + discipline_code, + code_name_th, + code_name_en + ) +SELECT id, + 'GEN', + 'āļ‡āļēāļ™āļšāļĢāļīāļŦāļēāļĢāđ‚āļ„āļĢāļ‡āļāļēāļĢ', + 'General Management' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'COD', + 'āļŠāļąāļāļāļēāđāļĨāļ°āļ‚āđ‰āļ­āđ‚āļ•āđ‰āđāļĒāđ‰āļ‡', + 'Contracting' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'QSB', + 'āļŠāļģāļĢāļ§āļˆāļ›āļĢāļīāļĄāļēāļ“āđāļĨāļ°āļ„āļ§āļšāļ„āļļāļĄāļ‡āļšāļ›āļĢāļ°āļĄāļēāļ“', + 'Quantity Survey and Budget Control' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'PPG', + 'āļšāļĢāļīāļŦāļēāļĢāđāļœāļ™āđāļĨāļ°āļ„āļ§āļēāļĄāļāđ‰āļēāļ§āļŦāļ™āđ‰āļē', + 'Plan and Progress Management' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'PRC', + 'āļ‡āļēāļ™āļˆāļąāļ”āļ‹āļ·āđ‰āļ­', + 'Procurement' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'SUB', + 'āļœāļđāđ‰āļĢāļąāļšāđ€āļŦāļĄāļēāļŠāđˆāļ§āļ‡', + 'Subcontractor' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'ODC', + 'āļŠāļģāļ™āļąāļāļ‡āļēāļ™-āļ„āļ§āļšāļ„āļļāļĄāđ€āļ­āļāļŠāļēāļĢ', + 'Operation Docment Control' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'LAW', + 'āļāļŽāļŦāļĄāļēāļĒ', + 'Law' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'TRF', + 'āļˆāļĢāļēāļˆāļĢ', + 'Traffic' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'BIM', + 'BIM', + 'Building information modeling' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'SRV', + 'āļ‡āļēāļ™āļŠāļģāļĢāļ§āļˆ', + 'Survey' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'SFT', + 'āļ„āļ§āļēāļĄāļ›āļĨāļ­āļ”āļ āļąāļĒ', + 'Safety' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'BST', + 'āļ‡āļēāļ™āđ‚āļ„āļĢāļ‡āļŠāļĢāđ‰āļēāļ‡āļ­āļēāļ„āļēāļĢ', + 'Building Structure Work' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'TEM', + 'āļ‡āļēāļ™āļŠāļąāđˆāļ§āļ„āļĢāļēāļ§', + 'Temporary Work' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'UTL', + 'āļ‡āļēāļ™āļĢāļ°āļšāļšāļŠāļēāļ˜āļēāļĢāļ“āļđāļ›āđ‚āļ āļ„', + 'Utility' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'EPW', + 'āļ‡āļēāļ™āļĢāļ°āļšāļšāđ„āļŸāļŸāđ‰āļē', + 'Electrical Power Work' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'ECM', + 'āļ‡āļēāļ™āļĢāļ°āļšāļšāđ„āļŸāļŸāđ‰āļēāļŠāļ·āđˆāļ­āļŠāļēāļĢ', + 'Electrical Communication Work' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'ENV', + 'āļŠāļīāđˆāļ‡āđāļ§āļ”āļĨāđ‰āļ­āļĄ', + 'Environment' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'AQV', + 'āļ„āļļāļ“āļ āļēāļžāļ­āļēāļāļēāļĻāđāļĨāļ°āļ„āļ§āļēāļĄāļŠāļąāđˆāļ™āļŠāļ°āđ€āļ—āļ·āļ­āļ™', + 'Air quality and vibration' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'WAB', + 'āļ„āļļāļ“āļ āļēāļžāļ™āđ‰āļģāđāļĨāļ°āļŠāļĩāļ§āļ§āļīāļ—āļĒāļēāļ—āļēāļ‡āļ™āđ‰āļģ', + 'Water quality and Aquatic biology' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'ONS', + 'āļ§āļīāļĻāļ§āļāļĢāļĢāļĄāļŠāļēāļĒāļāļąāđˆāļ‡', + 'Onshore Engineer Work' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'PPR', + 'āļĄāļ§āļĨāļŠāļ™āļŠāļąāļĄāļžāļąāļ™āļ˜āđŒāđāļĨāļ°āļāļēāļĢāļ›āļĢāļ°āļŠāļēāļŠāļąāļĄāļžāļąāļ™āļ˜āđŒ', + 'Public Relations' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'OSW', + 'āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡āļ‡āļēāļ™āļ—āļēāļ‡āļ—āļ°āđ€āļĨ', + 'Offshore Work' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'DRE', + 'āļ‡āļēāļ™āļ‚āļļāļ”āđāļĨāļ°āļ–āļĄāļ—āļ°āđ€āļĨ', + 'Dredging and Reclamation' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'REV', + 'āļ‡āļēāļ™āļ„āļąāļ™āļŦāļīāļ™āļĨāđ‰āļ­āļĄāļžāļ·āđ‰āļ™āļ—āļĩāđˆāļ–āļĄāļ—āļ°āđ€āļĨ', + 'Revetment' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'BRW', + 'āļ‡āļēāļ™āđ€āļ‚āļ·āđˆāļ­āļ™āļāļąāļ™āļ„āļĨāļ·āđˆāļ™', + 'Breakwater' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'SOI', + 'āļ›āļĢāļąāļšāļ›āļĢāļļāļ‡āļ„āļļāļ“āļ āļēāļžāļ”āļīāļ™', + 'Soil Improvement' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'BLC', + 'āļ‡āļēāļ™āļ›āļĢāļąāļšāļ›āļĢāļļāļ‡āļ„āļĨāļ­āļ‡āļšāļēāļ‡āļĨāļ°āļĄāļļāļ‡', + 'Bang Lamung Canal Bank Protection' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'FUP', + 'āļ‡āļēāļ™āļ›āļĢāļ°āļ•āļđāļĢāļ°āļšāļēāļĒāļ™āđ‰āļģāđāļĨāļ°āļ—āđˆāļ­āļĨāļ­āļ”', + 'Floodgate & Under Ground Piping Works' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'SWP', + 'āļ‡āļēāļ™āļ­āļēāļ„āļēāļĢāļ„āļ§āļšāļ„āļļāļĄāļŠāļ–āļēāļ™āļĩāļŠāļđāļšāļ™āđ‰āļģāļ—āļ°āđ€āļĨ', + 'Sea Water Pumping Station Control BuilDing' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'NAV', + 'āļ‡āļēāļ™āļ•āļīāļ”āļ•āļąāđ‰āļ‡āđ€āļ„āļĢāļ·āđˆāļ­āļ‡āļŦāļĄāļēāļĒāļŠāđˆāļ§āļ‡āļāļēāļĢāđ€āļ”āļīāļ™āđ€āļĢāļ·āļ­', + 'Navigations Aids' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'GEO', + 'āļ‡āļēāļ™āļ”āđ‰āļēāļ™āļ˜āļĢāļ“āļĩāđ€āļ—āļ„āļ™āļīāļ„', + 'Geotechnical' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'CRW', + 'āļ‡āļēāļ™āļ”āđ‰āļēāļ™āđ‚āļĒāļ˜āļē - Rock Works', + 'Civil-Rock work' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'DVR', + 'āļ—āļĩāļĄāļ™āļąāļāļ›āļĢāļ°āļ”āļēāļ™āđ‰āļģ', + 'Dive Work' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'MTS', + 'āļ‡āļēāļ™āļ—āļ”āļŠāļ­āļšāļ§āļąāļŠāļ”āļļāđāļĨāļ°āļ˜āļĢāļ“āļĩāđ€āļ—āļ„āļ™āļīāļ„', + 'Materials and Geotechnical Testing' +FROM contracts +WHERE contract_code = 'LCBP3-C1' +UNION ALL +SELECT id, + 'OTH', + 'āļ­āļ·āđˆāļ™āđ†', + 'Other' +FROM contracts +WHERE contract_code = 'LCBP3-C1'; + +-- LCBP3-C2 +INSERT INTO disciplines ( + contract_id, + discipline_code, + code_name_th, + code_name_en + ) +SELECT id, + 'GEN', + 'āļ‡āļēāļ™āļšāļĢāļīāļŦāļēāļĢāđ‚āļ„āļĢāļ‡āļāļēāļĢ', + 'Project Management' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'COD', + 'āļŠāļąāļāļāļēāđāļĨāļ°āļ‚āđ‰āļ­āđ‚āļ•āđ‰āđāļĒāđ‰āļ‡', + 'Contracts and arguments' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'QSB', + 'āļŠāļģāļĢāļ§āļˆāļ›āļĢāļīāļĄāļēāļ“āđāļĨāļ°āļ„āļ§āļšāļ„āļļāļĄāļ‡āļšāļ›āļĢāļ°āļĄāļēāļ“', + 'Survey the quantity and control the budget' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'PPM', + 'āļšāļĢāļīāļŦāļēāļĢāđāļœāļ™āđāļĨāļ°āļ„āļ§āļēāļĄāļāđ‰āļēāļ§āļŦāļ™āđ‰āļē', + 'Plan Management & Progress' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'ODC', + 'āļŠāļģāļ™āļąāļāļ‡āļēāļ™-āļ„āļ§āļšāļ„āļļāļĄāđ€āļ­āļāļŠāļēāļĢ', + 'Document Control Office' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'LAW', + 'āļāļŽāļŦāļĄāļēāļĒ', + 'Law' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'TRF', + 'āļˆāļĢāļēāļˆāļĢ', + 'Traffic' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'BIM', + 'Building Information Modeling', + 'Building Information Modeling' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'SRV', + 'āļ‡āļēāļ™āļŠāļģāļĢāļ§āļˆ', + 'Survey' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'SFT', + 'āļ„āļ§āļēāļĄāļ›āļĨāļ­āļ”āļ āļąāļĒ', + 'Safety' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'BST', + 'āļ‡āļēāļ™āđ‚āļ„āļĢāļ‡āļŠāļĢāđ‰āļēāļ‡āļ­āļēāļ„āļēāļĢ', + 'Building Structure' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'UTL', + 'āļ‡āļēāļ™āļ°āļšāļšāļŠāļēāļ˜āļēāļĢāļ“āļđāļ›āđ‚āļ āļ„', + 'Public Utilities' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'EPW', + 'āļ‡āļēāļ™āļĢāļ°āļšāļšāđ„āļŸāļŸāđ‰āļē', + 'Electrical Systems' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'ECM', + 'āļ‡āļēāļ™āļĢāļ°āļšāļšāđ„āļŸāļŸāđ‰āļēāļŠāļ·āđˆāļ­āļŠāļēāļĢ', + 'Electrical Communication System' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'ENV', + 'āļŠāļīāđˆāļ‡āđāļ§āļ”āļĨāđ‰āļ­āļĄ', + 'Environment' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'AQV', + 'āļ„āļļāļ“āļ āļēāļžāļ­āļēāļāļēāļĻāđāļĨāļ°āļ„āļ§āļēāļĄāļŠāļąāđˆāļ™āļŠāļ°āđ€āļ—āļ·āļ­āļ™', + 'Air Quality and Vibration' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'WAB', + 'āļ„āļļāļ“āļ āļēāļžāļ™āđ‰āļģāđāļĨāļ°āļŠāļĩāļ§āļ§āļīāļ—āļĒāļēāļ—āļēāļ‡āļ™āđ‰āļģ', + 'Water Quality and Aquatic Biology' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'ONS', + 'āļ§āļīāļĻāļ§āļāļĢāļĢāļĄāļŠāļēāļĒāļāļąāđˆāļ‡', + 'Coastal Engineering' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'PPR', + 'āļĄāļ§āļĨāļŠāļ™āļŠāļąāļĄāļžāļąāļ™āļ˜āđŒāđāļĨāļ°āļ›āļĢāļ°āļŠāļēāļŠāļąāļĄāļžāļąāļ™āļ˜āđŒ', + 'Mass Relations and Public Relations' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'OFW', + 'āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡āļ—āļēāļ‡āļ—āļ°āđ€āļĨ', + 'Marine Construction' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'EXR', + 'āļ‡āļēāļ™āļ‚āļļāļ”āđāļĨāļ°āļ–āļĄāļ—āļ°āđ€āļĨ', + 'Excavation and reclamation' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'GEO', + 'āļ‡āļēāļ™āļ”āđ‰āļēāļ™āļ˜āļĢāļ“āļĩāđ€āļ—āļ„āļ™āļīāļ„', + 'Geotechnical work' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'CRW', + 'āļ‡āļēāļ™āļ”āđ‰āļēāļ™āđ‚āļĒāļ˜āļē - Rock Works', + 'Civil Works - Rock Works' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'DVW', + 'āļ—āļĩāļĄāļ™āļąāļāļ›āļĢāļ°āļ”āļēāļ™āđ‰āļģ', + 'Team of Divers' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'MTT', + 'āļ‡āļēāļ™āļ—āļ”āļŠāļ­āļšāļ§āļąāļŠāļ”āļļ', + 'Materials Testing' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'ARC', + 'āļ‡āļēāļ™āļŠāļ–āļēāļ›āļąāļ•āļĒāļāļĢāļĢāļĄ', + 'Architecture' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'STR', + 'āļ‡āļēāļ™āđ‚āļ„āļĢāļ‡āļŠāļĢāđ‰āļēāļ‡', + 'Structural work' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'SAN', + 'āļ‡āļēāļ™āļĢāļ°āļšāļšāļŠāļļāļ‚āļēāļ āļīāļšāļēāļĨ', + 'Sanitation System' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'DRA', + 'āļ‡āļēāļ™āļĢāļ°āļšāļšāļĢāļ°āļšāļēāļĒāļ™āđ‰āļģ', + 'Drainage system work' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'TER', + 'āļ‡āļēāļ™āļ—āđˆāļēāđ€āļ—āļĩāļĒāļšāđ€āļĢāļ·āļ­', + 'Terminal Work work' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'BUD', + 'āļ‡āļēāļ™āļ­āļēāļ„āļēāļĢ', + 'Building' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'ROW', + 'āļ‡āļēāļ™āļ–āļ™āļ™āđāļĨāļ°āļŠāļ°āļžāļēāļ™', + 'Road and Bridge Work' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'MEC', + 'āļ‡āļēāļ™āđ€āļ„āļĢāļīāļ­āļ‡āļāļĨ', + 'Mechanical work' +FROM contracts +WHERE contract_code = 'LCBP3-C2' +UNION ALL +SELECT id, + 'OTH', + 'āļ­āļ·āđˆāļ™ āđ†', + 'Others' +FROM contracts +WHERE contract_code = 'LCBP3-C2'; + +-- 2. Seed āļ‚āđ‰āļ­āļĄāļđāļĨ Correspondence Sub Types (Mapping RFA Types āļāļąāļš Number) +-- āđ€āļ™āļ·āđˆāļ­āļ‡āļˆāļēāļ sub_type_code āļ•āļĢāļ‡āļāļąāļš RFA Type Code āđāļ•āđˆ Req āļ•āđ‰āļ­āļ‡āļāļēāļĢ Mapping āđ€āļ›āđ‡āļ™ Number +-- LCBP3-C1 +-- LCBP3-C1 +INSERT INTO correspondence_sub_types ( + contract_id, + correspondence_type_id, + sub_type_code, + sub_type_name, + sub_type_number + ) +SELECT c.id, + ct.id, + 'MAT', + 'Material Approval', + '11' +FROM contracts c, + correspondence_types ct +WHERE c.contract_code = 'LCBP3-C1' + AND ct.type_code = 'RFA' +UNION ALL +SELECT c.id, + ct.id, + 'SHP', + 'Shop Drawing Submittal', + '12' +FROM contracts c, + correspondence_types ct +WHERE c.contract_code = 'LCBP3-C1' + AND ct.type_code = 'RFA' +UNION ALL +SELECT c.id, + ct.id, + 'DWG', + 'Document Approval', + '13' +FROM contracts c, + correspondence_types ct +WHERE c.contract_code = 'LCBP3-C1' + AND ct.type_code = 'RFA' +UNION ALL +SELECT c.id, + ct.id, + 'MET', + 'Engineering Document Submittal', + '14' +FROM contracts c, + correspondence_types ct +WHERE c.contract_code = 'LCBP3-C1' + AND ct.type_code = 'RFA'; + +-- LCBP3-C2 +INSERT INTO correspondence_sub_types ( + contract_id, + correspondence_type_id, + sub_type_code, + sub_type_name, + sub_type_number + ) +SELECT c.id, + ct.id, + 'MAT', + 'Material Approval', + '21' +FROM contracts c, + correspondence_types ct +WHERE c.contract_code = 'LCBP3-C2' + AND ct.type_code = 'RFA' +UNION ALL +SELECT c.id, + ct.id, + 'SHP', + 'Shop Drawing Submittal', + '22' +FROM contracts c, + correspondence_types ct +WHERE c.contract_code = 'LCBP3-C2' + AND ct.type_code = 'RFA' +UNION ALL +SELECT c.id, + ct.id, + 'DWG', + 'Document Approval', + '23' +FROM contracts c, + correspondence_types ct +WHERE c.contract_code = 'LCBP3-C2' + AND ct.type_code = 'RFA' +UNION ALL +SELECT c.id, + ct.id, + 'MET', + 'Engineering Document Submittal', + '24' +FROM contracts c, + correspondence_types ct +WHERE c.contract_code = 'LCBP3-C2' + AND ct.type_code = 'RFA'; + +-- LCBP3-C3 +INSERT INTO correspondence_sub_types ( + contract_id, + correspondence_type_id, + sub_type_code, + sub_type_name, + sub_type_number + ) +SELECT c.id, + ct.id, + 'MAT', + 'Material Approval', + '31' +FROM contracts c, + correspondence_types ct +WHERE c.contract_code = 'LCBP3-C3' + AND ct.type_code = 'RFA' +UNION ALL +SELECT c.id, + ct.id, + 'SHP', + 'Shop Drawing Submittal', + '32' +FROM contracts c, + correspondence_types ct +WHERE c.contract_code = 'LCBP3-C3' + AND ct.type_code = 'RFA' +UNION ALL +SELECT c.id, + ct.id, + 'DWG', + 'Document Approval', + '33' +FROM contracts c, + correspondence_types ct +WHERE c.contract_code = 'LCBP3-C3' + AND ct.type_code = 'RFA' +UNION ALL +SELECT c.id, + ct.id, + 'MET', + 'Engineering Document Submittal', + '34' +FROM contracts c, + correspondence_types ct +WHERE c.contract_code = 'LCBP3-C3' + AND ct.type_code = 'RFA'; + +-- LCBP3-C4 +INSERT INTO correspondence_sub_types ( + contract_id, + correspondence_type_id, + sub_type_code, + sub_type_name, + sub_type_number + ) +SELECT c.id, + ct.id, + 'MAT', + 'Material Approval', + '41' +FROM contracts c, + correspondence_types ct +WHERE c.contract_code = 'LCBP3-C4' + AND ct.type_code = 'RFA' +UNION ALL +SELECT c.id, + ct.id, + 'SHP', + 'Shop Drawing Submittal', + '42' +FROM contracts c, + correspondence_types ct +WHERE c.contract_code = 'LCBP3-C4' + AND ct.type_code = 'RFA' +UNION ALL +SELECT c.id, + ct.id, + 'DWG', + 'Document Approval', + '43' +FROM contracts c, + correspondence_types ct +WHERE c.contract_code = 'LCBP3-C4' + AND ct.type_code = 'RFA' +UNION ALL +SELECT c.id, + ct.id, + 'MET', + 'Engineering Document Submittal', + '44' +FROM contracts c, + correspondence_types ct +WHERE c.contract_code = 'LCBP3-C4' + AND ct.type_code = 'RFA'; diff --git a/specs/07-database/lcbp3-v1.5.1-shema.sql.sql b/specs/07-database/lcbp3-v1.5.1-shema.sql.sql new file mode 100644 index 0000000..b8458db --- /dev/null +++ b/specs/07-database/lcbp3-v1.5.1-shema.sql.sql @@ -0,0 +1,1844 @@ +-- ========================================================== +-- DMS v1.5.1 Document Management System Database +-- Deploy Script Schema +-- Server: Container Station on QNAP TS-473A +-- Database service: MariaDB 10.11 +-- database web ui: phpmyadmin 5-apache +-- database development ui: DBeaver +-- backend service: NestJS +-- frontend service: next.js +-- reverse proxy: jc21/nginx-proxy-manager:latest +-- cron service: n8n +-- ========================================================== +-- [v1.5.1 UPDATE] Enhanced Document Numbering System +-- Update: Upgraded from v1.4.5 +-- Last Updated: 2025-12-02 +-- Major Changes: +-- 1. Document Numbering: 8-column composite PK (was 5 columns) +-- 2. New Tables: document_number_audit, document_number_errors +-- 3. Enhanced indexes and constraints for document_number_counters +-- 4. Based on specs v1.5.1 (refs: 03.11-document-numbering.md) +-- ========================================================== +SET NAMES utf8mb4; + +SET time_zone = '+07:00'; + +-- āļ›āļīāļ”āļāļēāļĢāļ•āļĢāļ§āļˆāļŠāļ­āļš Foreign Key āļŠāļąāđˆāļ§āļ„āļĢāļēāļ§āđ€āļžāļ·āđˆāļ­āđƒāļŦāđ‰āļŠāļēāļĄāļēāļĢāļ–āļĨāļšāļ•āļēāļĢāļēāļ‡āđ„āļ”āđ‰āļ—āļąāđ‰āļ‡āļŦāļĄāļ” +SET FOREIGN_KEY_CHECKS = 0; + +DROP VIEW IF EXISTS v_document_statistics; + +DROP VIEW IF EXISTS v_documents_with_attachments; + +DROP VIEW IF EXISTS v_user_all_permissions; + +DROP VIEW IF EXISTS v_audit_log_details; + +DROP VIEW IF EXISTS v_user_tasks; + +DROP VIEW IF EXISTS v_contract_parties_all; + +DROP VIEW IF EXISTS v_current_rfas; + +DROP VIEW IF EXISTS v_current_correspondences; + +-- DROP PROCEDURE IF EXISTS sp_get_next_document_number; +-- 🗑ïļ DROP TABLE SCRIPT: LCBP3-DMS v1.4.2 +-- āļ„āļģāđ€āļ•āļ·āļ­āļ™: āļ‚āđ‰āļ­āļĄāļđāļĨāļ—āļąāđ‰āļ‡āļŦāļĄāļ”āļˆāļ°āļŦāļēāļĒāđ„āļ› āļāļĢāļļāļ“āļē Backup āļāđˆāļ­āļ™āļĢāļąāļ™āļšāļ™ Production +SET FOREIGN_KEY_CHECKS = 0; + +-- ============================================================ +-- āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 1: āļ•āļēāļĢāļēāļ‡ System, Logs & Preferences (āļ•āļēāļĢāļēāļ‡āļ›āļĨāļēāļĒāļ—āļēāļ‡/āļŠāđˆāļ§āļ™āđ€āļŠāļĢāļīāļĄ) +-- ============================================================ +DROP TABLE IF EXISTS backup_logs; + +DROP TABLE IF EXISTS search_indices; + +DROP TABLE IF EXISTS notifications; + +DROP TABLE IF EXISTS audit_logs; + +-- [NEW v1.4.2] āļ•āļēāļĢāļēāļ‡āļāļēāļĢāļ•āļąāđ‰āļ‡āļ„āđˆāļēāļŠāđˆāļ§āļ™āļ•āļąāļ§āļ‚āļ­āļ‡āļœāļđāđ‰āđƒāļŠāđ‰ (FK -> users) +DROP TABLE IF EXISTS user_preferences; + +-- [NEW v1.4.2] āļ•āļēāļĢāļēāļ‡āđ€āļāđ‡āļš Schema āļŠāļģāļŦāļĢāļąāļš Validate JSON (Stand-alone) +DROP TABLE IF EXISTS json_schemas; + +-- [v1.5.1 NEW] āļ•āļēāļĢāļēāļ‡ Audit āđāļĨāļ° Error Log āļŠāļģāļŦāļĢāļąāļš Document Numbering +DROP TABLE IF EXISTS document_number_errors; + +DROP TABLE IF EXISTS document_number_audit; + +-- ============================================================ +-- āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 2: āļ•āļēāļĢāļēāļ‡ Junction (āđ€āļŠāļ·āđˆāļ­āļĄāđ‚āļĒāļ‡āļ‚āđ‰āļ­āļĄāļđāļĨ M:N) +-- ============================================================ +DROP TABLE IF EXISTS correspondence_tags; + +DROP TABLE IF EXISTS shop_drawing_revision_contract_refs; + +DROP TABLE IF EXISTS contract_drawing_subcat_cat_maps; + +-- ============================================================ +-- āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 3: āļ•āļēāļĢāļēāļ‡āđ„āļŸāļĨāđŒāđāļ™āļšāđāļĨāļ°āļāļēāļĢāđ€āļŠāļ·āđˆāļ­āļĄāđ‚āļĒāļ‡ (Attachments) +-- ============================================================ +DROP TABLE IF EXISTS contract_drawing_attachments; + +DROP TABLE IF EXISTS circulation_attachments; + +DROP TABLE IF EXISTS shop_drawing_revision_attachments; + +DROP TABLE IF EXISTS correspondence_attachments; + +DROP TABLE IF EXISTS attachments; + +-- āļ•āļēāļĢāļēāļ‡āļŦāļĨāļąāļāđ€āļāđ‡āļš path āđ„āļŸāļĨāđŒ +-- ============================================================ +-- āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 4: āļ•āļēāļĢāļēāļ‡ Workflow & Routing (Process Logic) +-- ============================================================ +-- Correspondence Workflow +-- ============================================================ +-- āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 5: āļ•āļēāļĢāļēāļ‡ Mapping āļŠāļīāļ—āļ˜āļīāđŒāđāļĨāļ°āđ‚āļ„āļĢāļ‡āļŠāļĢāđ‰āļēāļ‡ (Access Control) +-- ============================================================ +DROP TABLE IF EXISTS role_permissions; + +DROP TABLE IF EXISTS user_assignments; + +DROP TABLE IF EXISTS contract_organizations; + +DROP TABLE IF EXISTS project_organizations; + +-- ============================================================ +-- āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 6: āļ•āļēāļĢāļēāļ‡āļĢāļēāļĒāļĨāļ°āđ€āļ­āļĩāļĒāļ”āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢ (Revisions & Items) +-- ============================================================ +DROP TABLE IF EXISTS transmittal_items; + +DROP TABLE IF EXISTS shop_drawing_revisions; + +DROP TABLE IF EXISTS rfa_items; + +DROP TABLE IF EXISTS rfa_revisions; + +DROP TABLE IF EXISTS correspondence_references; + +DROP TABLE IF EXISTS correspondence_recipients; + +DROP TABLE IF EXISTS correspondence_revisions; + +-- [Modified v1.4.2] āļĄāļĩ Virtual Columns +-- ============================================================ +-- āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 7: āļ•āļēāļĢāļēāļ‡āđ€āļ­āļāļŠāļēāļĢāļŦāļĨāļąāļ (Core Documents) +-- ============================================================ +DROP TABLE IF EXISTS circulations; + +DROP TABLE IF EXISTS transmittals; + +DROP TABLE IF EXISTS contract_drawings; + +DROP TABLE IF EXISTS shop_drawings; + +DROP TABLE IF EXISTS rfas; + +DROP TABLE IF EXISTS correspondences; + +-- ============================================================ +-- āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 8: āļ•āļēāļĢāļēāļ‡āļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāđāļĨāļ°āļ‚āđ‰āļ­āļĄāļđāļĨāļŦāļĨāļąāļ (Master Data) +-- ============================================================ +-- [NEW 6B] āļĨāļšāļ•āļēāļĢāļēāļ‡āđƒāļŦāļĄāđˆāļ—āļĩāđˆāđ€āļžāļīāđˆāļĄāđ€āļ‚āđ‰āļēāļĄāļēāđ€āļžāļ·āđˆāļ­āļ›āđ‰āļ­āļ‡āļāļąāļ™ Error āđ€āļ§āļĨāļē Re-deploy +DROP TABLE IF EXISTS correspondence_sub_types; + +DROP TABLE IF EXISTS disciplines; + +DROP TABLE IF EXISTS shop_drawing_sub_categories; + +DROP TABLE IF EXISTS shop_drawing_main_categories; + +DROP TABLE IF EXISTS contract_drawing_sub_cats; + +DROP TABLE IF EXISTS contract_drawing_cats; + +DROP TABLE IF EXISTS contract_drawing_volumes; + +DROP TABLE IF EXISTS circulation_status_codes; + +DROP TABLE IF EXISTS rfa_approve_codes; + +DROP TABLE IF EXISTS rfa_status_codes; + +DROP TABLE IF EXISTS rfa_types; + +DROP TABLE IF EXISTS correspondence_status; + +DROP TABLE IF EXISTS correspondence_types; + +DROP TABLE IF EXISTS document_number_counters; + +-- [Modified v1.4.2] āļĄāļĩ version column +DROP TABLE IF EXISTS document_number_formats; + +DROP TABLE IF EXISTS tags; + +-- ============================================================ +-- āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 9: āļ•āļēāļĢāļēāļ‡āļœāļđāđ‰āđƒāļŠāđ‰ āļšāļ—āļšāļēāļ— āđāļĨāļ°āđ‚āļ„āļĢāļ‡āļŠāļĢāđ‰āļēāļ‡āļĢāļēāļāļāļēāļ™ (Root Tables) +-- ============================================================ +DROP TABLE IF EXISTS organization_roles; + +DROP TABLE IF EXISTS roles; + +DROP TABLE IF EXISTS permissions; + +DROP TABLE IF EXISTS contracts; + +DROP TABLE IF EXISTS projects; + +DROP TABLE IF EXISTS users; + +-- Referenced by user_preferences, audit_logs, etc. +DROP TABLE IF EXISTS organizations; + +-- Referenced by users, projects, etc. +-- ===================================================== +-- 1. ðŸĒ Core & Master Data (āļ­āļ‡āļ„āđŒāļāļĢ, āđ‚āļ„āļĢāļ‡āļāļēāļĢ, āļŠāļąāļāļāļē) +-- ===================================================== +-- āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļšāļ›āļĢāļ°āđ€āļ āļ—āļšāļ—āļšāļēāļ—āļ‚āļ­āļ‡āļ­āļ‡āļ„āđŒāļāļĢ +CREATE TABLE organization_roles ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + role_name VARCHAR(20) NOT NULL UNIQUE COMMENT 'āļŠāļ·āđˆāļ­āļšāļ—āļšāļēāļ— (OWNER, DESIGNER, CONSULTANT, CONTRACTOR, THIRD PARTY)' +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļšāļ›āļĢāļ°āđ€āļ āļ—āļšāļ—āļšāļēāļ—āļ‚āļ­āļ‡āļ­āļ‡āļ„āđŒāļāļĢ'; + +-- āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨāļ­āļ‡āļ„āđŒāļāļĢāļ—āļąāđ‰āļ‡āļŦāļĄāļ”āļ—āļĩāđˆāđ€āļāļĩāđˆāļĒāļ§āļ‚āđ‰āļ­āļ‡āđƒāļ™āļĢāļ°āļšāļš +CREATE TABLE organizations ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + organization_code VARCHAR(20) NOT NULL UNIQUE COMMENT 'āļĢāļŦāļąāļŠāļ­āļ‡āļ„āđŒāļāļĢ', + organization_name VARCHAR(255) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āļ­āļ‡āļ„āđŒāļāļĢ', + role_id INT COMMENT 'āļšāļ—āļšāļēāļ—āļ‚āļ­āļ‡āļ­āļ‡āļ„āđŒāļāļĢ', + is_active BOOLEAN DEFAULT TRUE COMMENT 'āļŠāļ–āļēāļ™āļ°āļāļēāļĢāđƒāļŠāđ‰āļ‡āļēāļ™', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', + FOREIGN KEY (role_id) REFERENCES organization_roles (id) ON DELETE + SET NULL +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨāļ­āļ‡āļ„āđŒāļāļĢāļ—āļąāđ‰āļ‡āļŦāļĄāļ”āļ—āļĩāđˆāđ€āļāļĩāđˆāļĒāļ§āļ‚āđ‰āļ­āļ‡āđƒāļ™āļĢāļ°āļšāļš'; + +-- āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨāđ‚āļ„āļĢāļ‡āļāļēāļĢ +CREATE TABLE projects ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + project_code VARCHAR(50) NOT NULL UNIQUE COMMENT 'āļĢāļŦāļąāļŠāđ‚āļ„āļĢāļ‡āļāļēāļĢ', + project_name VARCHAR(255) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āđ‚āļ„āļĢāļ‡āļāļēāļĢ', + -- parent_project_id INT COMMENT 'āļĢāļŦāļąāļŠāđ‚āļ„āļĢāļ‡āļāļēāļĢāļŦāļĨāļąāļ (āļ–āđ‰āļēāļĄāļĩ)', + -- contractor_organization_id INT COMMENT 'āļĢāļŦāļąāļŠāļ­āļ‡āļ„āđŒāļāļĢāļœāļđāđ‰āļĢāļąāļšāđ€āļŦāļĄāļē (āļ–āđ‰āļēāļĄāļĩ)', + is_active TINYINT(1) DEFAULT 1 COMMENT 'āļŠāļ–āļēāļ™āļ°āļāļēāļĢāđƒāļŠāđ‰āļ‡āļēāļ™' -- FOREIGN KEY (parent_project_id) REFERENCES projects(id) ON DELETE SET NULL, + -- FOREIGN KEY (contractor_organization_id) REFERENCES organizations(id) ON DELETE SET NULL +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨāđ‚āļ„āļĢāļ‡āļāļēāļĢ'; + +-- āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨāļŠāļąāļāļāļē +CREATE TABLE contracts ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + project_id INT NOT NULL, + contract_code VARCHAR(50) NOT NULL UNIQUE COMMENT 'āļĢāļŦāļąāļŠāļŠāļąāļāļāļē', + contract_name VARCHAR(255) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āļŠāļąāļāļāļē', + description TEXT COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒāļŠāļąāļāļāļē', + start_date DATE COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđ€āļĢāļīāđˆāļĄāļŠāļąāļāļāļē', + end_date DATE COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļīāđ‰āļ™āļŠāļļāļ”āļŠāļąāļāļāļē', + is_active BOOLEAN DEFAULT TRUE, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', + FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨāļŠāļąāļāļāļē'; + +-- ===================================================== +-- 2. ðŸ‘Ĩ Users & RBAC (āļœāļđāđ‰āđƒāļŠāđ‰, āļŠāļīāļ—āļ˜āļīāđŒ, āļšāļ—āļšāļēāļ—) +-- ===================================================== +-- āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨāļœāļđāđ‰āđƒāļŠāđ‰āļ‡āļēāļ™ (User) +CREATE TABLE users ( + user_id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + username VARCHAR(50) NOT NULL UNIQUE COMMENT 'āļŠāļ·āđˆāļ­āļœāļđāđ‰āđƒāļŠāđ‰āļ‡āļēāļ™', + password_hash VARCHAR(255) NOT NULL COMMENT 'āļĢāļŦāļąāļŠāļœāđˆāļēāļ™ (Hashed)', + first_name VARCHAR(50) COMMENT 'āļŠāļ·āđˆāļ­āļˆāļĢāļīāļ‡', + last_name VARCHAR(50) COMMENT 'āļ™āļēāļĄāļŠāļāļļāļĨ', + email VARCHAR(100) NOT NULL UNIQUE COMMENT 'āļ­āļĩāđ€āļĄāļĨ', + line_id VARCHAR(100) COMMENT 'LINE ID', + primary_organization_id INT COMMENT 'āļŠāļąāļ‡āļāļąāļ”āļ­āļ‡āļ„āđŒāļāļĢ', + is_active TINYINT(1) DEFAULT 1 COMMENT 'āļŠāļ–āļēāļ™āļ°āļāļēāļĢāđƒāļŠāđ‰āļ‡āļēāļ™', + failed_attempts INT DEFAULT 0 COMMENT 'āļˆāļģāļ™āļ§āļ™āļ„āļĢāļąāđ‰āļ‡āļ—āļĩāđˆāļĨāđ‡āļ­āļāļ­āļīāļ™āļĨāđ‰āļĄāđ€āļŦāļĨāļ§', + locked_until DATETIME COMMENT 'āļĨāđ‡āļ­āļāļ­āļīāļ™āđ„āļĄāđˆāđ„āļ”āđ‰āļˆāļ™āļ–āļķāļ‡āđ€āļ§āļĨāļē', + last_login_at TIMESTAMP NULL COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđāļĨāļ°āđ€āļ§āļĨāļēāļ—āļĩāđˆāļĨāđ‡āļ­āļāļ­āļīāļ™āļĨāđˆāļēāļŠāļļāļ”', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', + deleted_at DATETIME NULL DEFAULT NULL COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļĨāļš', + FOREIGN KEY (primary_organization_id) REFERENCES organizations (id) ON DELETE + SET NULL +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨāļœāļđāđ‰āđƒāļŠāđ‰āļ‡āļēāļ™ (User)'; + +-- āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļš "āļšāļ—āļšāļēāļ—" āļ‚āļ­āļ‡āļœāļđāđ‰āđƒāļŠāđ‰āđƒāļ™āļĢāļ°āļšāļš +CREATE TABLE roles ( + role_id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + -- role_code VARCHAR(50) NOT NULL UNIQUE COMMENT 'āļĢāļŦāļąāļŠāļšāļ—āļšāļēāļ— (āđ€āļŠāđˆāļ™ SUPER_ADMIN, ADMIN, EDITOR, VIEWER)', + role_name VARCHAR(100) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āļšāļ—āļšāļēāļ—', + scope ENUM( + 'Global', + 'Organization', + 'Project', + 'Contract' + ) NOT NULL, + -- āļ‚āļ­āļšāđ€āļ‚āļ•āļ‚āļ­āļ‡āļšāļ—āļšāļēāļ— (āļˆāļēāļāļ‚āđ‰āļ­ 4.3) + description TEXT COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒāļšāļ—āļšāļēāļ—', + is_system BOOLEAN DEFAULT FALSE COMMENT '(1 = āļšāļ—āļšāļēāļ—āļ‚āļ­āļ‡āļĢāļ°āļšāļš āļĨāļšāđ„āļĄāđˆāđ„āļ”āđ‰)' +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļš "āļšāļ—āļšāļēāļ—" āļ‚āļ­āļ‡āļœāļđāđ‰āđƒāļŠāđ‰āđƒāļ™āļĢāļ°āļšāļš'; + +-- āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļš "āļŠāļīāļ—āļ˜āļīāđŒ" (Permission) āļŦāļĢāļ·āļ­ "āļāļēāļĢāļāļĢāļ°āļ—āļģ" āļ—āļąāđ‰āļ‡āļŦāļĄāļ”āđƒāļ™āļĢāļ°āļšāļš +CREATE TABLE permissions ( + permission_id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + permission_name VARCHAR(100) NOT NULL UNIQUE COMMENT 'āļĢāļŦāļąāļŠāļŠāļīāļ—āļ˜āļīāđŒ (āđ€āļŠāđˆāļ™ rfas.create, rfas.view)', + description TEXT COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒāļŠāļīāļ—āļ˜āļīāđŒ', + module VARCHAR(50) COMMENT 'āđ‚āļĄāļ”āļđāļĨāļ—āļĩāđˆāđ€āļāļĩāđˆāļĒāļ§āļ‚āđ‰āļ­āļ‡', + scope_level ENUM('GLOBAL', 'ORG', 'PROJECT') COMMENT 'āļĢāļ°āļ”āļąāļšāļ‚āļ­āļšāđ€āļ‚āļ•āļ‚āļ­āļ‡āļŠāļīāļ—āļ˜āļīāđŒ', + is_active TINYINT(1) DEFAULT 1 COMMENT 'āļŠāļ–āļēāļ™āļ°āļāļēāļĢāđƒāļŠāđ‰āļ‡āļēāļ™' +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļš "āļŠāļīāļ—āļ˜āļīāđŒ" (Permission) āļŦāļĢāļ·āļ­ "āļāļēāļĢāļāļĢāļ°āļ—āļģ" āļ—āļąāđ‰āļ‡āļŦāļĄāļ”āđƒāļ™āļĢāļ°āļšāļš'; + +-- āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļĢāļ°āļŦāļ§āđˆāļēāļ‡ roles āđāļĨāļ° permissions (M:N) +CREATE TABLE role_permissions ( + role_id INT COMMENT 'ID āļ‚āļ­āļ‡āļšāļ—āļšāļēāļ—', + permission_id INT COMMENT 'ID āļ‚āļ­āļ‡āļŠāļīāļ—āļ˜āļīāđŒ', + 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 +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļĢāļ°āļŦāļ§āđˆāļēāļ‡ roles āđāļĨāļ° permissions (M :N)'; + +-- search.advanced +-- āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļœāļđāđ‰āđƒāļŠāđ‰ (users) +CREATE TABLE user_assignments ( + id INT AUTO_INCREMENT PRIMARY KEY, + user_id INT NOT NULL, + role_id INT NOT NULL, + -- āļ„āļ­āļĨāļąāļĄāļ™āđŒāļŠāļģāļŦāļĢāļąāļšāļāļģāļŦāļ™āļ”āļ‚āļ­āļšāđ€āļ‚āļ• (āļˆāļ°āđƒāļŠāđ‰āđ€āļžāļĩāļĒāļ‡āļ­āļąāļ™āđ€āļ”āļĩāļĒāļ§āļ•āđˆāļ­āđāļ–āļ§) + organization_id INT NULL, + project_id INT NULL, + contract_id INT NULL, + assigned_by_user_id INT, + -- āļœāļđāđ‰āļ—āļĩāđˆāļĄāļ­āļšāļŦāļĄāļēāļĒāļšāļ—āļšāļēāļ—āļ™āļĩāđ‰ + assigned_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + 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), + -- Constraint āđ€āļžāļ·āđˆāļ­āđƒāļŦāđ‰āđāļ™āđˆāđƒāļˆāļ§āđˆāļēāļĄāļĩāđ€āļžāļĩāļĒāļ‡āļ‚āļ­āļšāđ€āļ‚āļ•āđ€āļ”āļĩāļĒāļ§āļ—āļĩāđˆāļ–āļđāļāļāļģāļŦāļ™āļ”āđƒāļ™āđāļ•āđˆāļĨāļ°āđāļ–āļ§ + CONSTRAINT chk_scope CHECK ( + ( + organization_id IS NOT NULL + AND project_id IS NULL + AND contract_id IS NULL + ) + OR ( + organization_id IS NULL + AND project_id IS NOT NULL + AND contract_id IS NULL + ) + OR ( + organization_id IS NULL + AND project_id IS NULL + AND contract_id IS NOT NULL + ) + OR ( + organization_id IS NULL + AND project_id IS NULL + AND contract_id IS NULL + ) -- āļŠāļģāļŦāļĢāļąāļš Global scope + ) +); + +CREATE TABLE project_organizations ( + project_id INT NOT NULL, + organization_id INT NOT NULL, + 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 +); + +CREATE TABLE contract_organizations ( + contract_id INT NOT NULL, + organization_id INT NOT NULL, + role_in_contract VARCHAR(100), + -- āđ€āļŠāđˆāļ™ 'Owner', 'Designer', 'Consultant', 'Contractor ' + 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 +); + +-- ===================================================== +-- 3. ✉ïļ Correspondences (āđ€āļ­āļāļŠāļēāļĢāļŦāļĨāļąāļ, Revisions) +-- ===================================================== +-- āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļšāļ›āļĢāļ°āđ€āļ āļ—āđ€āļ­āļāļŠāļēāļĢāđ‚āļ•āđ‰āļ•āļ­āļš +CREATE TABLE correspondence_types ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + type_code VARCHAR(50) NOT NULL UNIQUE COMMENT 'āļĢāļŦāļąāļŠāļ›āļĢāļ°āđ€āļ āļ— (āđ€āļŠāđˆāļ™ RFA, RFI)', + type_name VARCHAR(255) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āļ›āļĢāļ°āđ€āļ āļ—', + sort_order INT DEFAULT 0 COMMENT 'āļĨāļģāļ”āļąāļšāļāļēāļĢāđāļŠāļ”āļ‡āļœāļĨ', + is_active TINYINT(1) DEFAULT 1 COMMENT 'āļŠāļ–āļēāļ™āļ°āļāļēāļĢāđƒāļŠāđ‰āļ‡āļēāļ™ ' +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļšāļ›āļĢāļ°āđ€āļ āļ—āđ€āļ­āļāļŠāļēāļĢāđ‚āļ•āđ‰āļ•āļ­āļš'; + +-- āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļšāļŠāļ–āļēāļ™āļ°āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢ +CREATE TABLE correspondence_status ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + status_code VARCHAR(50) NOT NULL UNIQUE COMMENT 'āļĢāļŦāļąāļŠāļŠāļ–āļēāļ™āļ°āļŦāļ™āļąāļ‡āļŠāļ·āļ­ (āđ€āļŠāđˆāļ™ DRAFT, SUBOWN)', + status_name VARCHAR(255) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āļŠāļ–āļēāļ™āļ°āļŦāļ™āļąāļ‡āļŠāļ·āļ­', + sort_order INT DEFAULT 0 COMMENT 'āļĨāļģāļ”āļąāļšāļāļēāļĢāđāļŠāļ”āļ‡āļœāļĨ', + is_active TINYINT(1) DEFAULT 1 COMMENT 'āļŠāļ–āļēāļ™āļ°āļāļēāļĢāđƒāļŠāđ‰āļ‡āļēāļ™ ' +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļšāļŠāļ–āļēāļ™āļ°āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢ'; + +-- āļ•āļēāļĢāļēāļ‡ "āđāļĄāđˆ" āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢāđ‚āļ•āđ‰āļ•āļ­āļš āđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨāļ—āļĩāđˆāđ„āļĄāđˆāđ€āļ›āļĨāļĩāđˆāļĒāļ™āļ•āļēāļĄ Revision +CREATE TABLE correspondences ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡ (āļ™āļĩāđˆāļ„āļ·āļ­ "Master ID" āļ—āļĩāđˆāđƒāļŠāđ‰āđ€āļŠāļ·āđˆāļ­āļĄāđ‚āļĒāļ‡)', + correspondence_number VARCHAR(100) NOT NULL COMMENT 'āđ€āļĨāļ‚āļ—āļĩāđˆāđ€āļ­āļāļŠāļēāļĢ (āļŠāļĢāđ‰āļēāļ‡āļˆāļēāļ DocumentNumberingModule)', + correspondence_type_id INT NOT NULL COMMENT 'āļ›āļĢāļ°āđ€āļ āļ—āđ€āļ­āļāļŠāļēāļĢ', + is_internal_communication TINYINT(1) DEFAULT 0 COMMENT '(1 = āļ āļēāļĒāđƒāļ™, 0 = āļ āļēāļĒāļ™āļ­āļ)', + project_id INT NOT NULL COMMENT 'āļ­āļĒāļđāđˆāđƒāļ™āđ‚āļ„āļĢāļ‡āļāļēāļĢ', + originator_id INT COMMENT 'āļ­āļ‡āļ„āđŒāļāļĢāļœāļđāđ‰āļŠāđˆāļ‡', + created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', + created_by INT COMMENT 'āļœāļđāđ‰āļŠāļĢāđ‰āļēāļ‡', + deleted_at DATETIME NULL COMMENT 'āļŠāļģāļŦāļĢāļąāļš Soft Delete', + FOREIGN KEY (correspondence_type_id) REFERENCES correspondence_types (id) ON DELETE RESTRICT, + FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE, + FOREIGN KEY (originator_id) REFERENCES organizations (id) ON DELETE + SET NULL, + FOREIGN KEY (created_by) REFERENCES users (user_id) ON DELETE + SET NULL, + UNIQUE KEY uq_corr_no_per_project ( + project_id, + correspondence_number + ) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ "āđāļĄāđˆ" āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢāđ‚āļ•āđ‰āļ•āļ­āļš āđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨāļ—āļĩāđˆāđ„āļĄāđˆāđ€āļ›āļĨāļĩāđˆāļĒāļ™āļ•āļēāļĄ Revision'; + +-- āļ•āļēāļĢāļēāļ‡ "āļĨāļđāļ" āđ€āļāđ‡āļšāļ›āļĢāļ°āļ§āļąāļ•āļīāļāļēāļĢāđāļāđ‰āđ„āļ‚ (Revisions) āļ‚āļ­āļ‡ correspondences (1:N) +CREATE TABLE correspondence_revisions ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡ Revision', + correspondence_id INT NOT NULL COMMENT 'Master ID', + revision_number INT NOT NULL COMMENT 'āļŦāļĄāļēāļĒāđ€āļĨāļ‚ Revision (0, 1, 2...)', + revision_label VARCHAR(10) COMMENT 'Revision āļ—āļĩāđˆāđāļŠāļ”āļ‡ (āđ€āļŠāđˆāļ™ A, B, 1.1)', + is_current BOOLEAN DEFAULT FALSE COMMENT '(1 = Revision āļ›āļąāļˆāļˆāļļāļšāļąāļ™)', + correspondence_status_id INT NOT NULL COMMENT 'āļŠāļ–āļēāļ™āļ°āļ‚āļ­āļ‡ Revision āļ™āļĩāđ‰', + title VARCHAR(255) NOT NULL COMMENT 'āđ€āļĢāļ·āđˆāļ­āļ‡', + document_date DATE COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđƒāļ™āđ€āļ­āļāļŠāļēāļĢ', + issued_date DATETIME COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļ­āļ­āļāđ€āļ­āļāļŠāļēāļĢ', + received_date DATETIME COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļĨāļ‡āļĢāļąāļšāđ€āļ­āļāļŠāļēāļĢ', + due_date DATETIME COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļ„āļĢāļšāļāļģāļŦāļ™āļ”', + description TEXT COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒāļāļēāļĢāđāļāđ‰āđ„āļ‚āđƒāļ™ Revision āļ™āļĩāđ‰', + details JSON COMMENT 'āļ‚āđ‰āļ­āļĄāļđāļĨāđ€āļ‰āļžāļēāļ° (āđ€āļŠāđˆāļ™ RFI details)', + created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡āđ€āļ­āļāļŠāļēāļĢ', + created_by INT COMMENT 'āļœāļđāđ‰āļŠāļĢāđ‰āļēāļ‡', + updated_by INT COMMENT 'āļœāļđāđ‰āđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', + 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 uq_master_revision_number ( + correspondence_id, + revision_number + ), + UNIQUE KEY uq_master_current (correspondence_id, is_current) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ "āļĨāļđāļ" āđ€āļāđ‡āļšāļ›āļĢāļ°āļ§āļąāļ•āļīāļāļēāļĢāđāļāđ‰āđ„āļ‚ (Revisions) āļ‚āļ­āļ‡ correspondences (1 :N)'; + +-- āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļœāļđāđ‰āļĢāļąāļš (TO/CC) āļŠāļģāļŦāļĢāļąāļšāđ€āļ­āļāļŠāļēāļĢāđāļ•āđˆāļĨāļ°āļ‰āļšāļąāļš (M:N) +CREATE TABLE correspondence_recipients ( + correspondence_id INT COMMENT 'ID āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢ', + recipient_organization_id INT COMMENT 'ID āļ­āļ‡āļ„āđŒāļāļĢāļœāļđāđ‰āļĢāļąāļš', + recipient_type ENUM('TO', 'CC ') COMMENT 'āļ›āļĢāļ°āđ€āļ āļ—āļœāļđāđ‰āļĢāļąāļš (TO āļŦāļĢāļ·āļ­ CC)', + 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 +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļœāļđāđ‰āļĢāļąāļš (TO / CC) āļŠāļģāļŦāļĢāļąāļšāđ€āļ­āļāļŠāļēāļĢāđāļ•āđˆāļĨāļ°āļ‰āļšāļąāļš (M :N)'; + +-- āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļš Tags āļ—āļąāđ‰āļ‡āļŦāļĄāļ”āļ—āļĩāđˆāđƒāļŠāđ‰āđƒāļ™āļĢāļ°āļšāļš +CREATE TABLE tags ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + tag_name VARCHAR(100) NOT NULL UNIQUE COMMENT 'āļŠāļ·āđˆāļ­ Tag', + description TEXT COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒāđāļ—āđ‡āļ', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ” ' +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļš Tags āļ—āļąāđ‰āļ‡āļŦāļĄāļ”āļ—āļĩāđˆāđƒāļŠāđ‰āđƒāļ™āļĢāļ°āļšāļš'; + +-- āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļĢāļ°āļŦāļ§āđˆāļēāļ‡ correspondences āđāļĨāļ° tags (M:N) +CREATE TABLE correspondence_tags ( + correspondence_id INT COMMENT 'ID āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢ', + tag_id INT COMMENT 'ID āļ‚āļ­āļ‡ Tag', + 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 +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļĢāļ°āļŦāļ§āđˆāļēāļ‡ correspondences āđāļĨāļ° tags (M :N)'; + +-- āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļāļēāļĢāļ­āđ‰āļēāļ‡āļ­āļīāļ‡āļĢāļ°āļŦāļ§āđˆāļēāļ‡āđ€āļ­āļāļŠāļēāļĢ (M:N) +CREATE TABLE correspondence_references ( + src_correspondence_id INT COMMENT 'ID āđ€āļ­āļāļŠāļēāļĢāļ•āđ‰āļ™āļ—āļēāļ‡', + tgt_correspondence_id INT COMMENT 'ID āđ€āļ­āļāļŠāļēāļĢāđ€āļ›āđ‰āļēāļŦāļĄāļēāļĒ', + 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 +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļāļēāļĢāļ­āđ‰āļēāļ‡āļ­āļīāļ‡āļĢāļ°āļŦāļ§āđˆāļēāļ‡āđ€āļ­āļāļŠāļēāļĢ (M :N)'; + +-- ===================================================== +-- 4. 📐 approval: RFA (āđ€āļ­āļāļŠāļēāļĢāļ‚āļ­āļ­āļ™āļļāļĄāļąāļ•āļī, Workflows) +-- ===================================================== +-- āļ•āļēāļĢāļēāļ‡ Master āļŠāļģāļŦāļĢāļąāļšāļ›āļĢāļ°āđ€āļ āļ— RFA +CREATE TABLE rfa_types ( + id INT PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + contract_id INT NOT NULL COMMENT 'āļœāļđāļāļāļąāļšāļŠāļąāļāļāļē', + type_code VARCHAR(20) NOT NULL COMMENT 'āļĢāļŦāļąāļŠāļ›āļĢāļ°āđ€āļ āļ— RFA (āđ€āļŠāđˆāļ™ DWG, DOC, MAT)', + type_name_th VARCHAR(100) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āļ›āļĢāļ°āđ€āļ āļ— RFA th', + type_name_en VARCHAR(100) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āļ›āļĢāļ°āđ€āļ āļ— RFA en', + remark TEXT COMMENT 'āļŦāļĄāļēāļĒāđ€āļŦāļ•āļļ', + -- sort_order INT DEFAULT 0 COMMENT 'āļĨāļģāļ”āļąāļšāļāļēāļĢāđāļŠāļ”āļ‡āļœāļĨ', + is_active TINYINT(1) DEFAULT 1 COMMENT 'āļŠāļ–āļēāļ™āļ°āļāļēāļĢāđƒāļŠāđ‰āļ‡āļēāļ™ ', + UNIQUE KEY uk_rfa_types_contract_code (contract_id, type_code), + FOREIGN KEY (contract_id) REFERENCES contracts (id) ON DELETE CASCADE +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ Master āļŠāļģāļŦāļĢāļąāļšāļ›āļĢāļ°āđ€āļ āļ— RFA'; + +-- [NEW 6B] āļ•āļēāļĢāļēāļ‡āđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨāļŠāļēāļ‚āļēāļ‡āļēāļ™ (Disciplines) āđāļĒāļāļ•āļēāļĄāļŠāļąāļāļāļē +CREATE TABLE disciplines ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + contract_id INT NOT NULL COMMENT 'āļœāļđāļāļāļąāļšāļŠāļąāļāļāļē', + discipline_code VARCHAR(10) NOT NULL COMMENT 'āļĢāļŦāļąāļŠāļŠāļēāļ‚āļē (āđ€āļŠāđˆāļ™ GEN, STR)', + code_name_th VARCHAR(255) COMMENT 'āļŠāļ·āđˆāļ­āđ„āļ—āļĒ', + code_name_en VARCHAR(255) COMMENT 'āļŠāļ·āđˆāļ­āļ­āļąāļ‡āļāļĪāļĐ', + is_active TINYINT(1) DEFAULT 1 COMMENT 'āļŠāļ–āļēāļ™āļ°āļāļēāļĢāđƒāļŠāđ‰āļ‡āļēāļ™', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + FOREIGN KEY (contract_id) REFERENCES contracts (id) ON DELETE CASCADE, + UNIQUE KEY uk_discipline_contract (contract_id, discipline_code) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨāļŠāļēāļ‚āļēāļ‡āļēāļ™ (Disciplines) āļ•āļēāļĄ Req 6B'; + +-- [NEW 6B] āļ•āļēāļĢāļēāļ‡āđ€āļāđ‡āļšāļ›āļĢāļ°āđ€āļ āļ—āļŦāļ™āļąāļ‡āļŠāļ·āļ­āļĒāđˆāļ­āļĒ (Sub Types) āļŠāļģāļŦāļĢāļąāļš Mapping āđ€āļĨāļ‚āļĢāļŦāļąāļŠ +CREATE TABLE correspondence_sub_types ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + contract_id INT NOT NULL COMMENT 'āļœāļđāļāļāļąāļšāļŠāļąāļāļāļē', + correspondence_type_id INT NOT NULL COMMENT 'āļœāļđāļāļāļąāļšāļ›āļĢāļ°āđ€āļ āļ—āđ€āļ­āļāļŠāļēāļĢāļŦāļĨāļąāļ (āđ€āļŠāđˆāļ™ RFA)', + sub_type_code VARCHAR(20) NOT NULL COMMENT 'āļĢāļŦāļąāļŠāļĒāđˆāļ­āļĒ (āđ€āļŠāđˆāļ™ MAT, SHP)', + sub_type_name VARCHAR(255) COMMENT 'āļŠāļ·āđˆāļ­āļ›āļĢāļ°āđ€āļ āļ—āļŦāļ™āļąāļ‡āļŠāļ·āļ­āļĒāđˆāļ­āļĒ', + sub_type_number VARCHAR(10) COMMENT 'āđ€āļĨāļ‚āļĢāļŦāļąāļŠāļŠāļģāļŦāļĢāļąāļš Running Number (āđ€āļŠāđˆāļ™ 11, 22)', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (contract_id) REFERENCES contracts (id) ON DELETE CASCADE, + FOREIGN KEY (correspondence_type_id) REFERENCES correspondence_types (id) ON DELETE CASCADE +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļāđ‡āļšāļ›āļĢāļ°āđ€āļ āļ—āļŦāļ™āļąāļ‡āļŠāļ·āļ­āļĒāđˆāļ­āļĒ (Sub Types) āļ•āļēāļĄ Req 6B'; + +-- āļŦāļĢāļ·āļ­āđƒāļŠāđ‰ ALTER TABLE (āđāļ™āļ°āļ™āļģāđƒāļŦāđ‰āļĢāļąāļ™āļŦāļĨāļąāļ‡āļŠāļĢāđ‰āļēāļ‡āļ•āļēāļĢāļēāļ‡ disciplines āđ€āļŠāļĢāđ‡āļˆ) +ALTER TABLE correspondences +ADD COLUMN discipline_id INT NULL COMMENT 'āļŠāļēāļ‚āļēāļ‡āļēāļ™ (āļ–āđ‰āļēāļĄāļĩ)' +AFTER correspondence_type_id; + +ALTER TABLE correspondences +ADD CONSTRAINT fk_corr_discipline FOREIGN KEY (discipline_id) REFERENCES disciplines (id) ON DELETE +SET NULL; + +-- āļ•āļēāļĢāļēāļ‡ Master āļŠāļģāļŦāļĢāļąāļšāļŠāļ–āļēāļ™āļ° RFA +CREATE TABLE rfa_status_codes ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + status_code VARCHAR(20) NOT NULL UNIQUE COMMENT 'āļĢāļŦāļąāļŠāļŠāļ–āļēāļ™āļ° RFA (āđ€āļŠāđˆāļ™ DFT - Draft, FAP - For Approve)', + status_name VARCHAR(100) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āļŠāļ–āļēāļ™āļ°', + description TEXT COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒ', + sort_order INT DEFAULT 0 COMMENT 'āļĨāļģāļ”āļąāļšāļāļēāļĢāđāļŠāļ”āļ‡āļœāļĨ', + is_active TINYINT(1) DEFAULT 1 COMMENT 'āļŠāļ–āļēāļ™āļ°āļāļēāļĢāđƒāļŠāđ‰āļ‡āļēāļ™ ' +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ Master āļŠāļģāļŦāļĢāļąāļšāļŠāļ–āļēāļ™āļ° RFA'; + +-- āļ•āļēāļĢāļēāļ‡ Master āļŠāļģāļŦāļĢāļąāļšāļĢāļŦāļąāļŠāļœāļĨāļāļēāļĢāļ­āļ™āļļāļĄāļąāļ•āļī RFA +CREATE TABLE rfa_approve_codes ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + approve_code VARCHAR(20) NOT NULL UNIQUE COMMENT 'āļĢāļŦāļąāļŠāļœāļĨāļāļēāļĢāļ­āļ™āļļāļĄāļąāļ•āļī ( + āđ€āļŠāđˆāļ™ 1A - Approved, + 3R - Revise + and Resubmit + )', + approve_name VARCHAR(100) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āļœāļĨāļāļēāļĢāļ­āļ™āļļāļĄāļąāļ•āļī', + description TEXT COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒ', + sort_order INT DEFAULT 0 COMMENT 'āļĨāļģāļ”āļąāļšāļāļēāļĢāđāļŠāļ”āļ‡āļœāļĨ', + is_active TINYINT(1) DEFAULT 1 COMMENT 'āļŠāļ–āļēāļ™āļ°āļāļēāļĢāđƒāļŠāđ‰āļ‡āļēāļ™ ' +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ Master āļŠāļģāļŦāļĢāļąāļšāļĢāļŦāļąāļŠāļœāļĨāļāļēāļĢāļ­āļ™āļļāļĄāļąāļ•āļī RFA'; + +CREATE TABLE rfas ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡ (RFA Master ID)', + rfa_type_id INT NOT NULL COMMENT 'āļ›āļĢāļ°āđ€āļ āļ— RFA', + created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', + created_by INT COMMENT 'āļœāļđāđ‰āļŠāļĢāđ‰āļēāļ‡', + deleted_at DATETIME NULL COMMENT 'āļŠāļģāļŦāļĢāļąāļš Soft Delete', + FOREIGN KEY (rfa_type_id) REFERENCES rfa_types (id), + FOREIGN KEY (created_by) REFERENCES users (user_id) ON DELETE + SET NULL +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ "āđāļĄāđˆ" āļ‚āļ­āļ‡ RFA (āļĄāļĩāļ„āļ§āļēāļĄāļŠāļąāļĄāļžāļąāļ™āļ˜āđŒ 1 :N āļāļąāļš rfa_revisions)'; + +ALTER TABLE rfas +ADD COLUMN discipline_id INT NULL COMMENT 'āļŠāļēāļ‚āļēāļ‡āļēāļ™ (āļ–āđ‰āļēāļĄāļĩ)' +AFTER rfa_type_id; + +ALTER TABLE rfas +ADD CONSTRAINT fk_rfa_discipline FOREIGN KEY (discipline_id) REFERENCES disciplines (id) ON DELETE +SET NULL; + +-- āļ•āļēāļĢāļēāļ‡ "āļĨāļđāļ" āđ€āļāđ‡āļšāļ›āļĢāļ°āļ§āļąāļ•āļī (Revisions) āļ‚āļ­āļ‡ rfas (1:N) +CREATE TABLE rfa_revisions ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡ Revision', + correspondence_id INT NOT NULL COMMENT 'Master ID āļ‚āļ­āļ‡ Correspondence', + rfa_id INT NOT NULL COMMENT 'Master ID āļ‚āļ­āļ‡ RFA', + revision_number INT NOT NULL COMMENT 'āļŦāļĄāļēāļĒāđ€āļĨāļ‚ Revision (0, 1, 2...)', + revision_label VARCHAR(10) COMMENT 'Revision āļ—āļĩāđˆāđāļŠāļ”āļ‡ (āđ€āļŠāđˆāļ™ A, B, 1.1)', + is_current BOOLEAN DEFAULT FALSE COMMENT '(1 = Revision āļ›āļąāļˆāļˆāļļāļšāļąāļ™)', + rfa_status_code_id INT NOT NULL COMMENT 'āļŠāļ–āļēāļ™āļ° RFA', + rfa_approve_code_id INT COMMENT 'āļœāļĨāļāļēāļĢāļ­āļ™āļļāļĄāļąāļ•āļī', + title VARCHAR(255) NOT NULL COMMENT 'āđ€āļĢāļ·āđˆāļ­āļ‡', + document_date DATE COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđƒāļ™āđ€āļ­āļāļŠāļēāļĢ', + issued_date DATE COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāđˆāļ‡āļ‚āļ­āļ­āļ™āļļāļĄāļąāļ•āļī', + received_date DATETIME COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļĨāļ‡āļĢāļąāļšāđ€āļ­āļāļŠāļēāļĢ', + approved_date DATE COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļ­āļ™āļļāļĄāļąāļ•āļī', + description TEXT COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒāļāļēāļĢāđāļāđ‰āđ„āļ‚āđƒāļ™ Revision āļ™āļĩāđ‰', + created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡āđ€āļ­āļāļŠāļēāļĢ', + created_by INT COMMENT 'āļœāļđāđ‰āļŠāļĢāđ‰āļēāļ‡', + updated_by INT COMMENT 'āļœāļđāđ‰āđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', + FOREIGN KEY (correspondence_id) REFERENCES correspondences (id) ON DELETE CASCADE, + FOREIGN KEY (rfa_id) REFERENCES rfas (id) ON DELETE CASCADE, + FOREIGN KEY (rfa_status_code_id) REFERENCES rfa_status_codes (id), + FOREIGN KEY (rfa_approve_code_id) REFERENCES rfa_approve_codes (id) ON DELETE + SET NULL, + FOREIGN KEY (created_by) REFERENCES users (user_id) ON DELETE + SET NULL, + FOREIGN KEY (updated_by) REFERENCES users (user_id) ON DELETE + SET NULL, + UNIQUE KEY uq_rr_rev_number (rfa_id, revision_number), + UNIQUE KEY uq_rr_current (rfa_id, is_current) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ "āļĨāļđāļ" āđ€āļāđ‡āļšāļ›āļĢāļ°āļ§āļąāļ•āļī (Revisions) āļ‚āļ­āļ‡ rfas (1 :N)'; + +-- āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļĢāļ°āļŦāļ§āđˆāļēāļ‡ rfa_revisions (āļ—āļĩāđˆāđ€āļ›āđ‡āļ™āļ›āļĢāļ°āđ€āļ āļ— DWG) āļāļąāļš shop_drawing_revisions (M:N) +CREATE TABLE rfa_items ( + rfarev_correspondence_id INT COMMENT 'ID āļ‚āļ­āļ‡ RFA Revision', + shop_drawing_revision_id INT COMMENT 'ID āļ‚āļ­āļ‡ Shop Drawing Revision', + PRIMARY KEY ( + rfarev_correspondence_id, + shop_drawing_revision_id + ), + FOREIGN KEY (rfarev_correspondence_id) REFERENCES rfa_revisions (correspondence_id) ON DELETE CASCADE, + FOREIGN KEY (shop_drawing_revision_id) REFERENCES shop_drawing_revisions (id) ON DELETE CASCADE +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļĢāļ°āļŦāļ§āđˆāļēāļ‡ rfa_revisions (āļ—āļĩāđˆāđ€āļ›āđ‡āļ™āļ›āļĢāļ°āđ€āļ āļ— DWG) āļāļąāļš shop_drawing_revisions (M :N)'; + +-- ===================================================== +-- 5. 📐 Drawings (āđāļšāļš, āļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆ) +-- ===================================================== +-- āļ•āļēāļĢāļēāļ‡ Master āļŠāļģāļŦāļĢāļąāļš "āđ€āļĨāđˆāļĄ" āļ‚āļ­āļ‡āđāļšāļšāļ„āļđāđˆāļŠāļąāļāļāļē +CREATE TABLE contract_drawing_volumes ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + project_id INT NOT NULL COMMENT 'āđ‚āļ„āļĢāļ‡āļāļēāļĢ', + volume_code VARCHAR(50) NOT NULL COMMENT 'āļĢāļŦāļąāļŠāđ€āļĨāđˆāļĄ', + volume_name VARCHAR(255) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āđ€āļĨāđˆāļĄ', + description TEXT COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒ', + sort_order INT DEFAULT 0 COMMENT 'āļĨāļģāļ”āļąāļšāļāļēāļĢāđāļŠāļ”āļ‡āļœāļĨ', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', + FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE, + UNIQUE KEY ux_volume_project (project_id, volume_code) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ Master āļŠāļģāļŦāļĢāļąāļš "āđ€āļĨāđˆāļĄ" āļ‚āļ­āļ‡āđāļšāļšāļ„āļđāđˆāļŠāļąāļāļāļē'; + +-- āļ•āļēāļĢāļēāļ‡ Master āļŠāļģāļŦāļĢāļąāļš "āļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāļŦāļĨāļąāļ" āļ‚āļ­āļ‡āđāļšāļšāļ„āļđāđˆāļŠāļąāļāļāļē +CREATE TABLE contract_drawing_cats ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + project_id INT NOT NULL COMMENT 'āđ‚āļ„āļĢāļ‡āļāļēāļĢ', + cat_code VARCHAR(50) NOT NULL COMMENT 'āļĢāļŦāļąāļŠāļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāļŦāļĨāļąāļ', + cat_name VARCHAR(255) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāļŦāļĨāļąāļ', + description TEXT COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒ', + sort_order INT DEFAULT 0 COMMENT 'āļĨāļģāļ”āļąāļšāļāļēāļĢāđāļŠāļ”āļ‡āļœāļĨ', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', + FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE, + UNIQUE KEY ux_cat_project (project_id, cat_code) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ Master āļŠāļģāļŦāļĢāļąāļš "āļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāļŦāļĨāļąāļ" āļ‚āļ­āļ‡āđāļšāļšāļ„āļđāđˆāļŠāļąāļāļāļē'; + +-- āļ•āļēāļĢāļēāļ‡ Master āļŠāļģāļŦāļĢāļąāļš "āļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāļĒāđˆāļ­āļĒ" āļ‚āļ­āļ‡āđāļšāļšāļ„āļđāđˆāļŠāļąāļāļāļē +CREATE TABLE contract_drawing_sub_cats ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + project_id INT NOT NULL COMMENT 'āđ‚āļ„āļĢāļ‡āļāļēāļĢ', + sub_cat_code VARCHAR(50) NOT NULL COMMENT 'āļĢāļŦāļąāļŠāļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāļĒāđˆāļ­āļĒ', + sub_cat_name VARCHAR(255) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāļĒāđˆāļ­āļĒ', + description TEXT COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒ', + sort_order INT DEFAULT 0 COMMENT 'āļĨāļģāļ”āļąāļšāļāļēāļĢāđāļŠāļ”āļ‡āļœāļĨ', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', + FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE, + UNIQUE KEY ux_subcat_project (project_id, sub_cat_code) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ Master āļŠāļģāļŦāļĢāļąāļš "āļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāļĒāđˆāļ­āļĒ" āļ‚āļ­āļ‡āđāļšāļšāļ„āļđāđˆāļŠāļąāļāļāļē'; + +-- āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļĢāļ°āļŦāļ§āđˆāļēāļ‡ āļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāļŦāļĨāļąāļ-āļĒāđˆāļ­āļĒ (M:N) +CREATE TABLE contract_drawing_subcat_cat_maps ( + project_id INT COMMENT 'ID āļ‚āļ­āļ‡āđ‚āļ„āļĢāļ‡āļāļēāļĢ', + sub_cat_id INT COMMENT 'ID āļ‚āļ­āļ‡āļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāļĒāđˆāļ­āļĒ', + cat_id INT COMMENT 'ID āļ‚āļ­āļ‡āļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāļŦāļĨāļąāļ', + PRIMARY KEY ( + project_id, + sub_cat_id, + cat_id + ), + FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE, + FOREIGN KEY (sub_cat_id) REFERENCES contract_drawing_sub_cats (id) ON DELETE CASCADE, + FOREIGN KEY (cat_id) REFERENCES contract_drawing_cats (id) ON DELETE CASCADE +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļĢāļ°āļŦāļ§āđˆāļēāļ‡ āļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāļŦāļĨāļąāļ - āļĒāđˆāļ­āļĒ (M :N)'; + +-- āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨ "āđāļšāļšāļ„āļđāđˆāļŠāļąāļāļāļē" +CREATE TABLE contract_drawings ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + project_id INT NOT NULL COMMENT 'āđ‚āļ„āļĢāļ‡āļāļēāļĢ', + condwg_no VARCHAR(255) NOT NULL COMMENT 'āđ€āļĨāļ‚āļ—āļĩāđˆāđāļšāļšāļŠāļąāļāļāļē', + title VARCHAR(255) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āđāļšāļšāļŠāļąāļāļāļē', + sub_cat_id INT COMMENT 'āļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāļĒāđˆāļ­āļĒ', + volume_id INT COMMENT 'āđ€āļĨāđˆāļĄ', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', + deleted_at DATETIME NULL COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļĨāļš', + updated_by INT COMMENT 'āļœāļđāđ‰āđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', + FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE, + FOREIGN KEY (sub_cat_id) REFERENCES contract_drawing_sub_cats (id) ON DELETE RESTRICT, + FOREIGN KEY (volume_id) REFERENCES contract_drawing_volumes (id) ON DELETE RESTRICT, + UNIQUE KEY ux_condwg_no_project (project_id, condwg_no) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨ "āđāļšāļšāļ„āļđāđˆāļŠāļąāļāļāļē"'; + +-- āļ•āļēāļĢāļēāļ‡ Master āļŠāļģāļŦāļĢāļąāļš "āļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāļŦāļĨāļąāļ" āļ‚āļ­āļ‡āđāļšāļšāļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ +CREATE TABLE shop_drawing_main_categories ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + main_category_code VARCHAR(50) NOT NULL UNIQUE COMMENT 'āļĢāļŦāļąāļŠāļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāļŦāļĨāļąāļ (āđ€āļŠāđˆāļ™ ARCH, STR)', + main_category_name VARCHAR(255) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāļŦāļĨāļąāļ', + description TEXT COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒ', + sort_order INT DEFAULT 0 COMMENT 'āļĨāļģāļ”āļąāļšāļāļēāļĢāđāļŠāļ”āļ‡āļœāļĨ', + is_active TINYINT(1) DEFAULT 1 COMMENT 'āļŠāļ–āļēāļ™āļ°āļāļēāļĢāđƒāļŠāđ‰āļ‡āļēāļ™', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ” ' +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ Master āļŠāļģāļŦāļĢāļąāļš "āļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāļŦāļĨāļąāļ" āļ‚āļ­āļ‡āđāļšāļšāļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡'; + +-- āļ•āļēāļĢāļēāļ‡ Master āļŠāļģāļŦāļĢāļąāļš "āļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāļĒāđˆāļ­āļĒ" āļ‚āļ­āļ‡āđāļšāļšāļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ +CREATE TABLE shop_drawing_sub_categories ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + sub_category_code VARCHAR(50) NOT NULL UNIQUE COMMENT 'āļĢāļŦāļąāļŠāļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāļĒāđˆāļ­āļĒ (āđ€āļŠāđˆāļ™ STR - COLUMN)', + sub_category_name VARCHAR(255) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāļĒāđˆāļ­āļĒ', + main_category_id INT NOT NULL COMMENT 'āļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāļŦāļĨāļąāļ', + description TEXT COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒ', + sort_order INT DEFAULT 0 COMMENT 'āļĨāļģāļ”āļąāļšāļāļēāļĢāđāļŠāļ”āļ‡āļœāļĨ', + is_active TINYINT(1) DEFAULT 1 COMMENT 'āļŠāļ–āļēāļ™āļ°āļāļēāļĢāđƒāļŠāđ‰āļ‡āļēāļ™', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', + FOREIGN KEY (main_category_id) REFERENCES shop_drawing_main_categories (id) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ Master āļŠāļģāļŦāļĢāļąāļš "āļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāļĒāđˆāļ­āļĒ" āļ‚āļ­āļ‡āđāļšāļšāļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡'; + +-- āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨ "āđāļšāļšāļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡" +CREATE TABLE shop_drawings ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + project_id INT NOT NULL COMMENT 'āđ‚āļ„āļĢāļ‡āļāļēāļĢ', + drawing_number VARCHAR(100) NOT NULL UNIQUE COMMENT 'āđ€āļĨāļ‚āļ—āļĩāđˆ Shop Drawing', + title VARCHAR(500) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āđāļšāļš', + main_category_id INT NOT NULL COMMENT 'āļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāļŦāļĨāļąāļ', + sub_category_id INT NOT NULL COMMENT 'āļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāļĒāđˆāļ­āļĒ', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', + deleted_at DATETIME NULL COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļĨāļš', + updated_by INT COMMENT 'āļœāļđāđ‰āđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', + 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) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨ "āđāļšāļšāļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡"'; + +-- āļ•āļēāļĢāļēāļ‡ "āļĨāļđāļ" āđ€āļāđ‡āļšāļ›āļĢāļ°āļ§āļąāļ•āļī (Revisions) āļ‚āļ­āļ‡ shop_drawings (1:N) +CREATE TABLE shop_drawing_revisions ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡ Revision', + shop_drawing_id INT NOT NULL COMMENT 'Master ID', + revision_number INT NOT NULL COMMENT 'āļŦāļĄāļēāļĒāđ€āļĨāļ‚ Revision (āđ€āļŠāđˆāļ™ 0, 1, 2...)', + revision_label VARCHAR(10) COMMENT 'Revision āļ—āļĩāđˆāđāļŠāļ”āļ‡ (āđ€āļŠāđˆāļ™ A, B, 1.1)', + revision_date DATE COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļ‚āļ­āļ‡ Revision', + description TEXT COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒāļāļēāļĢāđāļāđ‰āđ„āļ‚', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', + FOREIGN KEY (shop_drawing_id) REFERENCES shop_drawings (id) ON DELETE CASCADE, + UNIQUE KEY ux_sd_rev_drawing_revision (shop_drawing_id, revision_number) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ "āļĨāļđāļ" āđ€āļāđ‡āļšāļ›āļĢāļ°āļ§āļąāļ•āļī (Revisions) āļ‚āļ­āļ‡ shop_drawings (1 :N)'; + +-- āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļĢāļ°āļŦāļ§āđˆāļēāļ‡ shop_drawing_revisions āļāļąāļš contract_drawings (M:N) +CREATE TABLE shop_drawing_revision_contract_refs ( + shop_drawing_revision_id INT COMMENT 'ID āļ‚āļ­āļ‡ Shop Drawing Revision', + contract_drawing_id INT COMMENT 'ID āļ‚āļ­āļ‡ Contract Drawing', + 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 +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļĢāļ°āļŦāļ§āđˆāļēāļ‡ shop_drawing_revisions āļāļąāļš contract_drawings (M :N)'; + +-- ===================================================== +-- 6. 🔄 Circulations (āđƒāļšāđ€āļ§āļĩāļĒāļ™āļ āļēāļĒāđƒāļ™) +-- ===================================================== +-- āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļšāļŠāļ–āļēāļ™āļ°āđƒāļšāđ€āļ§āļĩāļĒāļ™ +CREATE TABLE circulation_status_codes ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + code VARCHAR(20) NOT NULL UNIQUE COMMENT 'āļĢāļŦāļąāļŠāļŠāļ–āļēāļ™āļ°āļāļēāļĢāļ”āļģāđ€āļ™āļīāļ™āļ‡āļēāļ™', + description VARCHAR(50) NOT NULL COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒāļŠāļ–āļēāļ™āļ°āļāļēāļĢāļ”āļģāđ€āļ™āļīāļ™āļ‡āļēāļ™', + sort_order INT DEFAULT 0 COMMENT 'āļĨāļģāļ”āļąāļšāļāļēāļĢāđāļŠāļ”āļ‡āļœāļĨ', + is_active TINYINT(1) DEFAULT 1 COMMENT 'āļŠāļ–āļēāļ™āļ°āļāļēāļĢāđƒāļŠāđ‰āļ‡āļēāļ™ ' +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļšāļŠāļ–āļēāļ™āļ°āđƒāļšāđ€āļ§āļĩāļĒāļ™'; + +-- āļ•āļēāļĢāļēāļ‡ "āđāļĄāđˆ" āļ‚āļ­āļ‡āđƒāļšāđ€āļ§āļĩāļĒāļ™āđ€āļ­āļāļŠāļēāļĢāļ āļēāļĒāđƒāļ™ +CREATE TABLE circulations ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡āđƒāļšāđ€āļ§āļĩāļĒāļ™', + correspondence_id INT UNIQUE COMMENT 'ID āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢ (āļˆāļēāļāļ•āļēāļĢāļēāļ‡ correspondences)', + organization_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āļ­āļ‡āļ„āđŒāļāļĢāļ“āđŒāļ—āļĩāđˆāđ€āļ›āđ‡āļ™āđ€āļˆāđ‰āļēāļ‚āļ­āļ‡āđƒāļšāđ€āļ§āļĩāļĒāļ™āļ™āļĩāđ‰', + circulation_no VARCHAR(100) NOT NULL COMMENT 'āđ€āļĨāļ‚āļ—āļĩāđˆāđƒāļšāđ€āļ§āļĩāļĒāļ™', + circulation_subject VARCHAR(500) NOT NULL COMMENT 'āđ€āļĢāļ·āđˆāļ­āļ‡āđƒāļšāđ€āļ§āļĩāļĒāļ™', + circulation_status_code VARCHAR(20) NOT NULL COMMENT 'āļĢāļŦāļąāļŠāļŠāļ–āļēāļ™āļ°āđƒāļšāđ€āļ§āļĩāļĒāļ™', + created_by_user_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āļœāļđāđ‰āļŠāļĢāđ‰āļēāļ‡āđƒāļšāđ€āļ§āļĩāļĒāļ™', + submitted_at TIMESTAMP NULL COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāđˆāļ‡āđƒāļšāđ€āļ§āļĩāļĒāļ™', + closed_at TIMESTAMP NULL COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļ›āļīāļ”āđƒāļšāđ€āļ§āļĩāļĒāļ™', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', + 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) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ "āđāļĄāđˆ" āļ‚āļ­āļ‡āđƒāļšāđ€āļ§āļĩāļĒāļ™āđ€āļ­āļāļŠāļēāļĢāļ āļēāļĒāđƒāļ™'; + +-- ===================================================== +-- 7. ðŸ“Ī Transmittals (āđ€āļ­āļāļŠāļēāļĢāļ™āļģāļŠāđˆāļ‡) +-- ===================================================== +-- āļ•āļēāļĢāļēāļ‡āļ‚āđ‰āļ­āļĄāļđāļĨāđ€āļ‰āļžāļēāļ°āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢāļ™āļģāļŠāđˆāļ‡ (āđ€āļ›āđ‡āļ™āļ•āļēāļĢāļēāļ‡āļĨāļđāļ 1:1 āļ‚āļ­āļ‡ correspondences) +CREATE TABLE transmittals ( + correspondence_id INT PRIMARY KEY COMMENT 'ID āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢ', + purpose ENUM( + 'FOR_APPROVAL', + 'FOR_INFORMATION', + 'FOR_REVIEW', + 'OTHER ' + ) COMMENT 'āļ§āļąāļ•āļ–āļļāļ›āļĢāļ°āļŠāļ‡āļ„āđŒ', + remarks TEXT COMMENT 'āļŦāļĄāļēāļĒāđ€āļŦāļ•āļļ', + FOREIGN KEY (correspondence_id) REFERENCES correspondences (id) ON DELETE CASCADE +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āļ‚āđ‰āļ­āļĄāļđāļĨāđ€āļ‰āļžāļēāļ°āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢāļ™āļģāļŠāđˆāļ‡ (āđ€āļ›āđ‡āļ™āļ•āļēāļĢāļēāļ‡āļĨāļđāļ 1 :1 āļ‚āļ­āļ‡ correspondences)'; + +-- āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļĢāļ°āļŦāļ§āđˆāļēāļ‡ transmittals āđāļĨāļ°āđ€āļ­āļāļŠāļēāļĢāļ—āļĩāđˆāļ™āļģāļŠāđˆāļ‡ (M:N) +CREATE TABLE transmittal_items ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļĢāļēāļĒāļāļēāļĢ', + transmittal_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡ Transmittal', + item_correspondence_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢāļ—āļĩāđˆāđāļ™āļšāđ„āļ›', + quantity INT DEFAULT 1 COMMENT 'āļˆāļģāļ™āļ§āļ™', + remarks VARCHAR(255) COMMENT 'āļŦāļĄāļēāļĒāđ€āļŦāļ•āļļāļŠāļģāļŦāļĢāļąāļšāļĢāļēāļĒāļāļēāļĢāļ™āļĩāđ‰', + FOREIGN KEY (transmittal_id) REFERENCES transmittals (correspondence_id) ON DELETE CASCADE, + FOREIGN KEY (item_correspondence_id) REFERENCES correspondences (id) ON DELETE CASCADE, + UNIQUE KEY ux_transmittal_item ( + transmittal_id, + item_correspondence_id + ) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļĢāļ°āļŦāļ§āđˆāļēāļ‡ transmittals āđāļĨāļ°āđ€āļ­āļāļŠāļēāļĢāļ—āļĩāđˆāļ™āļģāļŠāđˆāļ‡ (M :N)'; + +-- ===================================================== +-- 8. 📎 File Management (āđ„āļŸāļĨāđŒāđāļ™āļš) +-- ===================================================== +-- āļ•āļēāļĢāļēāļ‡ "āļāļĨāļēāļ‡" āđ€āļāđ‡āļšāđ„āļŸāļĨāđŒāđāļ™āļšāļ—āļąāđ‰āļ‡āļŦāļĄāļ”āļ‚āļ­āļ‡āļĢāļ°āļšāļš +-- 2.2 Attachments - Two-Phase Storage & Security +-- āļĢāļ­āļ‡āļĢāļąāļš: Backend Plan T2.2, Req 3.9.1 +-- āđ€āļŦāļ•āļļāļœāļĨ: āļˆāļąāļ”āļāļēāļĢāđ„āļŸāļĨāđŒāļ‚āļĒāļ° (Orphan Files) āđāļĨāļ°āļ•āļĢāļ§āļˆāļŠāļ­āļšāļ„āļ§āļēāļĄāļ–āļđāļāļ•āđ‰āļ­āļ‡āđ„āļŸāļĨāđŒ +CREATE TABLE attachments ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āđ„āļŸāļĨāđŒāđāļ™āļš', + original_filename VARCHAR(255) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āđ„āļŸāļĨāđŒāļ”āļąāđ‰āļ‡āđ€āļ”āļīāļĄāļ•āļ­āļ™āļ­āļąāļ›āđ‚āļŦāļĨāļ”', + stored_filename VARCHAR(255) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āđ„āļŸāļĨāđŒāļ—āļĩāđˆāđ€āļāđ‡āļšāļˆāļĢāļīāļ‡āļšāļ™ Server (āļ›āđ‰āļ­āļ‡āļāļąāļ™āļŠāļ·āđˆāļ­āļ‹āđ‰āļģ)', + file_path VARCHAR(500) NOT NULL COMMENT 'Path āļ—āļĩāđˆāđ€āļāđ‡āļšāđ„āļŸāļĨāđŒ (āļšāļ™ QNAP / share / dms - data /)', + mime_type VARCHAR(100) NOT NULL COMMENT 'āļ›āļĢāļ°āđ€āļ āļ—āđ„āļŸāļĨāđŒ (āđ€āļŠāđˆāļ™ application / pdf)', + file_size INT NOT NULL COMMENT 'āļ‚āļ™āļēāļ”āđ„āļŸāļĨāđŒ (bytes)', + is_temporary BOOLEAN DEFAULT TRUE COMMENT 'True = āļĒāļąāļ‡āđ„āļĄāđˆ Commit āļĨāļ‡ DB āļˆāļĢāļīāļ‡', + temp_id VARCHAR(100) NULL COMMENT 'ID āļŠāļąāđˆāļ§āļ„āļĢāļēāļ§āļŠāļģāļŦāļĢāļąāļšāļ­āđ‰āļēāļ‡āļ­āļīāļ‡āļ•āļ­āļ™ Upload Phase 1', + uploaded_by_user_id INT NOT NULL COMMENT 'āļœāļđāđ‰āļ­āļąāļ›āđ‚āļŦāļĨāļ”āđ„āļŸāļĨāđŒ', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļ­āļąāļ›āđ‚āļŦāļĨāļ”', + expires_at DATETIME NULL COMMENT 'āđ€āļ§āļĨāļēāļŦāļĄāļ”āļ­āļēāļĒāļļāļ‚āļ­āļ‡āđ„āļŸāļĨāđŒ Temp', + CHECKSUM VARCHAR(64) NULL COMMENT 'SHA -256 Checksum', + FOREIGN KEY (uploaded_by_user_id) REFERENCES users (user_id) ON DELETE CASCADE +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ "āļāļĨāļēāļ‡" āđ€āļāđ‡āļšāđ„āļŸāļĨāđŒāđāļ™āļšāļ—āļąāđ‰āļ‡āļŦāļĄāļ”āļ‚āļ­āļ‡āļĢāļ°āļšāļš'; + +-- āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄ correspondences āļāļąāļš attachments (M:N) +CREATE TABLE correspondence_attachments ( + correspondence_id INT COMMENT 'ID āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢ', + attachment_id INT COMMENT 'ID āļ‚āļ­āļ‡āđ„āļŸāļĨāđŒāđāļ™āļš', + is_main_document BOOLEAN DEFAULT FALSE COMMENT '(1 = āđ„āļŸāļĨāđŒāļŦāļĨāļąāļ)', + 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 +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄ correspondences āļāļąāļš attachments (M :N)'; + +-- āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄ circulations āļāļąāļš attachments (M:N) +CREATE TABLE circulation_attachments ( + circulation_id INT COMMENT 'ID āļ‚āļ­āļ‡āđƒāļšāđ€āļ§āļĩāļĒāļ™', + attachment_id INT COMMENT 'ID āļ‚āļ­āļ‡āđ„āļŸāļĨāđŒāđāļ™āļš', + is_main_document BOOLEAN DEFAULT FALSE COMMENT '(1 = āđ„āļŸāļĨāđŒāļŦāļĨāļąāļāļ‚āļ­āļ‡āđƒāļšāđ€āļ§āļĩāļĒāļ™)', + 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 +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄ circulations āļāļąāļš attachments (M :N)'; + +-- āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄ shop_drawing_revisions āļāļąāļš attachments (M:N) +CREATE TABLE shop_drawing_revision_attachments ( + shop_drawing_revision_id INT COMMENT 'ID āļ‚āļ­āļ‡ Shop Drawing Revision', + attachment_id INT COMMENT 'ID āļ‚āļ­āļ‡āđ„āļŸāļĨāđŒāđāļ™āļš', + file_type ENUM( + 'PDF', + 'DWG', + 'SOURCE', + 'OTHER ' + ) COMMENT 'āļ›āļĢāļ°āđ€āļ āļ—āđ„āļŸāļĨāđŒ', + is_main_document BOOLEAN DEFAULT FALSE COMMENT '(1 = āđ„āļŸāļĨāđŒāļŦāļĨāļąāļ)', + 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 +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄ shop_drawing_revisions āļāļąāļš attachments (M :N)'; + +-- āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄ contract_drawings āļāļąāļš attachments (M:N) +CREATE TABLE contract_drawing_attachments ( + contract_drawing_id INT COMMENT 'ID āļ‚āļ­āļ‡ Contract Drawing', + attachment_id INT COMMENT 'ID āļ‚āļ­āļ‡āđ„āļŸāļĨāđŒāđāļ™āļš', + file_type ENUM( + 'PDF', + 'DWG', + 'SOURCE', + 'OTHER ' + ) COMMENT 'āļ›āļĢāļ°āđ€āļ āļ—āđ„āļŸāļĨāđŒ', + is_main_document BOOLEAN DEFAULT FALSE COMMENT '(1 = āđ„āļŸāļĨāđŒāļŦāļĨāļąāļ)', + 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 +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄ contract_drawings āļāļąāļš attachments (M :N)'; + +-- ===================================================== +-- 9. ðŸ”Ē Document Numbering (āļāļēāļĢāļŠāļĢāđ‰āļēāļ‡āđ€āļĨāļ‚āļ—āļĩāđˆāđ€āļ­āļāļŠāļēāļĢ) +-- ===================================================== +-- āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļš "āļĢāļđāļ›āđāļšāļš" Template āļ‚āļ­āļ‡āđ€āļĨāļ‚āļ—āļĩāđˆāđ€āļ­āļāļŠāļēāļĢ +CREATE TABLE document_number_formats ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + project_id INT NOT NULL COMMENT 'āđ‚āļ„āļĢāļ‡āļāļēāļĢ', + correspondence_type_id INT NOT NULL COMMENT 'āļ›āļĢāļ°āđ€āļ āļ—āđ€āļ­āļāļŠāļēāļĢ', + format_template VARCHAR(255) NOT NULL COMMENT 'āļĢāļđāļ›āđāļšāļš Template (āđ€āļŠāđˆāļ™ { ORG_CODE } - { TYPE_CODE } - { SEQ :4 })', + description TEXT COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒāļĢāļđāļ›āđāļšāļšāļ™āļĩāđ‰', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', + FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE, + FOREIGN KEY (correspondence_type_id) REFERENCES correspondence_types (id) ON DELETE CASCADE, + UNIQUE KEY uk_project_type ( + project_id, + correspondence_type_id + ) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļš "āļĢāļđāļ›āđāļšāļš" Template āļ‚āļ­āļ‡āđ€āļĨāļ‚āļ—āļĩāđˆāđ€āļ­āļāļŠāļēāļĢ'; + +-- ========================================================== +-- [v1.5.1 UPDATE] āļ•āļēāļĢāļēāļ‡āđ€āļāđ‡āļš "āļ•āļąāļ§āļ™āļąāļš" (Running Number) āļĨāđˆāļēāļŠāļļāļ” +-- āđ€āļ›āļĨāļĩāđˆāļĒāļ™āđāļ›āļĨāļ‡āļŦāļĨāļąāļ: +-- - PRIMARY KEY: āđ€āļ›āļĨāļĩāđˆāļĒāļ™āļˆāļēāļ 5 āļ„āļ­āļĨāļąāļĄāļ™āđŒāđ€āļ›āđ‡āļ™ 8 āļ„āļ­āļĨāļąāļĄāļ™āđŒ +-- - āđ€āļžāļīāđˆāļĄāļ„āļ­āļĨāļąāļĄāļ™āđŒ: recipient_organization_id, sub_type_id, rfa_type_id +-- - āđ€āļžāļīāđˆāļĄ INDEXES āļŠāļģāļŦāļĢāļąāļš performance +-- - āđ€āļžāļīāđˆāļĄ CONSTRAINTS āļŠāļģāļŦāļĢāļąāļš data validation +-- āđ€āļŦāļ•āļļāļœāļĨ: āļĢāļ­āļ‡āļĢāļąāļš 10 token types āđāļĨāļ° granular counter management +-- āļĢāļ­āļ‡āļĢāļąāļš: Backend Plan T2.3, Req 3.11.5, specs v1.5.1 +-- ========================================================== +CREATE TABLE document_number_counters ( + -- [v1.5.1] Composite Primary Key Columns (8 columns total) + project_id INT NOT NULL COMMENT 'āđ‚āļ„āļĢāļ‡āļāļēāļĢ', + originator_organization_id INT NOT NULL COMMENT 'āļ­āļ‡āļ„āđŒāļāļĢāļœāļđāđ‰āļŠāđˆāļ‡', + -- āđ€āļ›āļĨāļĩāđˆāļĒāļ™āļˆāļēāļ NULL āđ€āļ›āđ‡āļ™ DEFAULT -1 + recipient_organization_id INT NOT NULL DEFAULT -1 COMMENT '[v1.5.1 NEW] āļ­āļ‡āļ„āđŒāļāļĢāļœāļđāđ‰āļĢāļąāļš (-1 = āļ—āļļāļāļ­āļ‡āļ„āđŒāļāļĢ)', + -- recipient_organization_id INT NULL COMMENT '[v1.5.1 NEW] āļ­āļ‡āļ„āđŒāļāļĢāļœāļđāđ‰āļĢāļąāļš (NULL = āļ—āļļāļāļ­āļ‡āļ„āđŒāļāļĢ)', + correspondence_type_id INT NOT NULL COMMENT 'āļ›āļĢāļ°āđ€āļ āļ—āđ€āļ­āļāļŠāļēāļĢ (LETTER, RFA, TRANSMITTAL, etc.)', + sub_type_id INT DEFAULT 0 COMMENT '[v1.5.1 NEW] āļ›āļĢāļ°āđ€āļ āļ—āļĒāđˆāļ­āļĒ āļŠāļģāļŦāļĢāļąāļš TRANSMITTAL (0 = āđ„āļĄāđˆāļĢāļ°āļšāļļ)', + rfa_type_id INT DEFAULT 0 COMMENT '[v1.5.1 NEW] āļ›āļĢāļ°āđ€āļ āļ— RFA āđ€āļŠāđˆāļ™ SHD, RPT, MAT (0 = āđ„āļĄāđˆāđƒāļŠāđˆ RFA)', + discipline_id INT DEFAULT 0 COMMENT 'āļŠāļēāļ‚āļēāļ‡āļēāļ™ āđ€āļŠāđˆāļ™ TER, STR, GEO (0 = āđ„āļĄāđˆāļĢāļ°āļšāļļ)', + current_year INT NOT NULL COMMENT 'āļ›āļĩ āļ„.āļĻ. āļ‚āļ­āļ‡āļ•āļąāļ§āļ™āļąāļš (auto-reset āļ—āļļāļāļ›āļĩ)', + -- Counter Data + version INT DEFAULT 0 NOT NULL COMMENT 'Optimistic Lock Version (TypeORM @VersionColumn)', + last_number INT DEFAULT 0 COMMENT 'āđ€āļĨāļ‚āļ—āļĩāđˆāļĨāđˆāļēāļŠāļļāļ”āļ—āļĩāđˆāđƒāļŠāđ‰āđ„āļ›āđāļĨāđ‰āļ§ (auto-increment)', + -- [v1.5.1 UPDATE] Primary Key: 5 columns -> 8 columns + -- āđƒāļŠāđ‰ COALESCE āđ€āļžāļ·āđˆāļ­āļĢāļ­āļ‡āļĢāļąāļš NULL āđƒāļ™ recipient_organization_id + PRIMARY KEY ( + project_id, + originator_organization_id, + recipient_organization_id, + -- [v1.5.1 NEW] Handle NULL values + correspondence_type_id, + sub_type_id, + -- [v1.5.1 NEW] + rfa_type_id, + -- [v1.5.1 NEW] + discipline_id, + current_year + ), + -- Foreign Keys + FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE, + FOREIGN KEY (originator_organization_id) REFERENCES organizations (id) ON DELETE CASCADE, + FOREIGN KEY (recipient_organization_id) REFERENCES organizations (id) ON DELETE CASCADE, + FOREIGN KEY (correspondence_type_id) REFERENCES correspondence_types (id) ON DELETE CASCADE, + -- āđƒāļŠāđ‰ CHECK constraint āđ€āļžāļ·āđˆāļ­āđ„āļĄāđˆāđƒāļŦāđ‰āļ•āļĢāļ§āļˆāļŠāļ­āļšāđ€āļĄāļ·āđˆāļ­āđ€āļ›āđ‡āļ™ -1 + CONSTRAINT fk_recipient_when_not_all FOREIGN KEY (recipient_organization_id) REFERENCES organizations (id) ON DELETE CASCADE, + -- [v1.5.1 NEW] Performance Indexes + INDEX idx_counter_lookup ( + project_id, + correspondence_type_id, + current_year + ), + INDEX idx_counter_org ( + originator_organization_id, + current_year + ), + -- [v1.5.1 NEW] Data Validation Constraints + -- CONSTRAINT chk_last_number_positive CHECK (last_number >= 0), + -- CONSTRAINT chk_current_year_valid CHECK (current_year BETWEEN 2020 AND 2100) + -- Constraints + CONSTRAINT chk_last_number_positive CHECK (last_number >= 0), + CONSTRAINT chk_current_year CHECK ( + current_year BETWEEN 2020 AND 2100 + ), + CONSTRAINT chk_recipient_special CHECK ( + recipient_organization_id = -1 + OR recipient_organization_id > 0 + ) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '[v1.5.1 UPDATE] āļ•āļēāļĢāļēāļ‡āđ€āļāđ‡āļš Running Number Counters - āļĢāļ­āļ‡āļĢāļąāļš 8-column composite PK'; + +-- ========================================================== +-- [v1.5.1 NEW] āļ•āļēāļĢāļēāļ‡āđ€āļāđ‡āļš Audit Trail āļŠāļģāļŦāļĢāļąāļšāļāļēāļĢāļŠāļĢāđ‰āļēāļ‡āđ€āļĨāļ‚āļ—āļĩāđˆāđ€āļ­āļāļŠāļēāļĢ +-- āđ€āļžāļīāđˆāļĄāļ•āļēāļĢāļēāļ‡: document_number_audit +-- āđ€āļŦāļ•āļļāļœāļĨ: āļšāļąāļ™āļ—āļķāļāļ›āļĢāļ°āļ§āļąāļ•āļīāļāļēāļĢāļŠāļĢāđ‰āļēāļ‡āđ€āļĨāļ‚āļ—āļĩāđˆ āļĢāļ­āļ‡āļĢāļąāļš audit requirement â‰Ĩ 7 āļ›āļĩ +-- āļĢāļ­āļ‡āļĢāļąāļš: Req 3.11.8, Backend Plan T2.8 +-- ========================================================== +CREATE TABLE document_number_audit ( + id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT 'ID āļ‚āļ­āļ‡ audit record', + -- Document Info + document_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢāļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡āđ€āļĨāļ‚āļ—āļĩāđˆ (correspondences.id)', + generated_number VARCHAR(100) NOT NULL COMMENT 'āđ€āļĨāļ‚āļ—āļĩāđˆāđ€āļ­āļāļŠāļēāļĢāļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡ (āļœāļĨāļĨāļąāļžāļ˜āđŒ)', + counter_key JSON NOT NULL COMMENT 'Counter key āļ—āļĩāđˆāđƒāļŠāđ‰ (JSON format) - 8 fields', + template_used VARCHAR(200) NOT NULL COMMENT 'Template āļ—āļĩāđˆāđƒāļŠāđ‰āđƒāļ™āļāļēāļĢāļŠāļĢāđ‰āļēāļ‡', + -- User Info + user_id INT NOT NULL COMMENT 'āļœāļđāđ‰āļ‚āļ­āļŠāļĢāđ‰āļēāļ‡āđ€āļĨāļ‚āļ—āļĩāđˆ', + ip_address VARCHAR(45) COMMENT 'IP address āļ‚āļ­āļ‡āļœāļđāđ‰āļ‚āļ­ (IPv4/IPv6)', + user_agent TEXT COMMENT 'User agent string (browser info)', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆ/āđ€āļ§āļĨāļēāļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', + -- Performance & Error Tracking + retry_count INT DEFAULT 0 COMMENT 'āļˆāļģāļ™āļ§āļ™āļ„āļĢāļąāđ‰āļ‡āļ—āļĩāđˆ retry āļāđˆāļ­āļ™āļŠāļģāđ€āļĢāđ‡āļˆ', + lock_wait_ms INT COMMENT 'āđ€āļ§āļĨāļēāļĢāļ­ Redis lock (milliseconds)', + total_duration_ms INT COMMENT 'āđ€āļ§āļĨāļēāļĢāļ§āļĄāļ—āļąāđ‰āļ‡āļŦāļĄāļ”āđƒāļ™āļāļēāļĢāļŠāļĢāđ‰āļēāļ‡ (milliseconds)', + fallback_used ENUM('NONE', 'DB_LOCK', 'RETRY') DEFAULT 'NONE' COMMENT 'Fallback strategy āļ—āļĩāđˆāļ–āļđāļāđƒāļŠāđ‰ (NONE=normal, DB_LOCK=Redis down, RETRY=conflict)', + -- Indexes for performance + INDEX idx_document_id (document_id), + INDEX idx_user_id (user_id), + INDEX idx_created_at (created_at), + INDEX idx_generated_number (generated_number), + -- Foreign Keys + FOREIGN KEY (document_id) REFERENCES correspondences (id) ON DELETE CASCADE, + FOREIGN KEY (user_id) REFERENCES users (user_id) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '[v1.5.1 NEW] Audit Trail āļŠāļģāļŦāļĢāļąāļšāļāļēāļĢāļŠāļĢāđ‰āļēāļ‡āđ€āļĨāļ‚āļ—āļĩāđˆāđ€āļ­āļāļŠāļēāļĢ - āđ€āļāđ‡āļš â‰Ĩ 7 āļ›āļĩ'; + +-- ========================================================== +-- [v1.5.1 NEW] āļ•āļēāļĢāļēāļ‡āđ€āļāđ‡āļš Error Logs āļŠāļģāļŦāļĢāļąāļš Document Numbering +-- āđ€āļžāļīāđˆāļĄāļ•āļēāļĢāļēāļ‡: document_number_errors +-- āđ€āļŦāļ•āļļāļœāļĨ: āļ•āļīāļ”āļ•āļēāļĄ errors, troubleshooting, monitoring +-- āļĢāļ­āļ‡āļĢāļąāļš: Req 3.11.6, Ops monitoring requirements +-- ========================================================== +CREATE TABLE document_number_errors ( + id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT 'ID āļ‚āļ­āļ‡ error record', + -- Error Classification + error_type ENUM( + 'LOCK_TIMEOUT', + -- Redis lock timeout + 'VERSION_CONFLICT', + -- Optimistic lock version mismatch + 'DB_ERROR', + -- Database connection/query error + 'REDIS_ERROR', + -- Redis connection error + 'VALIDATION_ERROR' -- Template/input validation error + ) NOT NULL COMMENT 'āļ›āļĢāļ°āđ€āļ āļ— error (5 types)', + -- Error Details + error_message TEXT COMMENT 'āļ‚āđ‰āļ­āļ„āļ§āļēāļĄ error (stack top)', + stack_trace TEXT COMMENT 'Stack trace āđāļšāļšāđ€āļ•āđ‡āļĄ (āļŠāļģāļŦāļĢāļąāļš debugging)', + context_data JSON COMMENT 'Context āļ‚āļ­āļ‡ request (user, project, counter_key, etc.)', + -- User Info + user_id INT COMMENT 'āļœāļđāđ‰āļ—āļĩāđˆāđ€āļāļīāļ” error', + ip_address VARCHAR(45) COMMENT 'IP address', + -- Timestamps + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđ€āļāļīāļ” error', + resolved_at TIMESTAMP NULL COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđāļāđ‰āđ„āļ‚āđāļĨāđ‰āļ§ (NULL = āļĒāļąāļ‡āđ„āļĄāđˆāđāļāđ‰)', + -- Indexes for troubleshooting + INDEX idx_error_type (error_type), + INDEX idx_created_at (created_at), + INDEX idx_user_id (user_id), + INDEX idx_unresolved (resolved_at) -- Find unresolved errors +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '[v1.5.1 NEW] Error Log āļŠāļģāļŦāļĢāļąāļš Document Numbering System'; + +-- ===================================================== +-- 10. ⚙ïļ System & Logs (āļĢāļ°āļšāļšāđāļĨāļ° Log) +-- ===================================================== +-- 1.1 JSON Schemas Registry +-- āļĢāļ­āļ‡āļĢāļąāļš: Backend Plan T2.5.1, Req 6.11.1 +-- āđ€āļŦāļ•āļļāļœāļĨ: āđ€āļžāļ·āđˆāļ­ Validate āđ‚āļ„āļĢāļ‡āļŠāļĢāđ‰āļēāļ‡ JSON Details āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢāđāļ•āđˆāļĨāļ°āļ›āļĢāļ°āđ€āļ āļ—āđāļšāļš Centralized +CREATE TABLE json_schemas ( + id INT AUTO_INCREMENT PRIMARY KEY, + schema_code VARCHAR(100) NOT NULL COMMENT 'āļĢāļŦāļąāļŠ Schema (āđ€āļŠāđˆāļ™ RFA_DWG)', + version INT NOT NULL DEFAULT 1 COMMENT 'āđ€āļ§āļ­āļĢāđŒāļŠāļąāļ™āļ‚āļ­āļ‡ Schema', + table_name VARCHAR(100) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āļ•āļēāļĢāļēāļ‡āđ€āļ›āđ‰āļēāļŦāļĄāļēāļĒ (āđ€āļŠāđˆāļ™ rfa_revisions)', + schema_definition JSON NOT NULL COMMENT 'āđ‚āļ„āļĢāļ‡āļŠāļĢāđ‰āļēāļ‡ Data Schema (AJV Standard)', + ui_schema JSON NULL COMMENT 'āđ‚āļ„āļĢāļ‡āļŠāļĢāđ‰āļēāļ‡ UI Schema āļŠāļģāļŦāļĢāļąāļš Frontend', + virtual_columns JSON NULL COMMENT 'Config āļŠāļģāļŦāļĢāļąāļšāļŠāļĢāđ‰āļēāļ‡ Virtual Columns', + migration_script JSON NULL COMMENT 'Script āļŠāļģāļŦāļĢāļąāļšāđāļ›āļĨāļ‡āļ‚āđ‰āļ­āļĄāļđāļĨāļˆāļēāļāđ€āļ§āļ­āļĢāđŒāļŠāļąāļ™āļāđˆāļ­āļ™āļŦāļ™āđ‰āļē', + is_active BOOLEAN DEFAULT TRUE COMMENT 'āļŠāļ–āļēāļ™āļ°āļāļēāļĢāđƒāļŠāđ‰āļ‡āļēāļ™', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + -- āļ›āđ‰āļ­āļ‡āļāļąāļ™ Schema Code āļ‹āđ‰āļģāļāļąāļ™āđƒāļ™ Version āđ€āļ”āļĩāļĒāļ§āļāļąāļ™ + UNIQUE KEY uk_schema_version (schema_code, version) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļāđ‡āļš JSON Schema āđāļĨāļ° Configuration'; + +-- 1.2 User Preferences +-- āļĢāļ­āļ‡āļĢāļąāļš: Req 5.5, 6.8.3 +-- āđ€āļŦāļ•āļļāļœāļĨ: āđāļĒāļāļāļēāļĢāļ•āļąāđ‰āļ‡āļ„āđˆāļē Notification āđāļĨāļ° UI āļ­āļ­āļāļˆāļēāļāļ•āļēāļĢāļēāļ‡ Users āļŦāļĨāļąāļ +CREATE TABLE user_preferences ( + user_id INT PRIMARY KEY, + notify_email BOOLEAN DEFAULT TRUE, + notify_line BOOLEAN DEFAULT TRUE, + digest_mode BOOLEAN DEFAULT FALSE COMMENT 'āļĢāļąāļšāđāļˆāđ‰āļ‡āđ€āļ•āļ·āļ­āļ™āđāļšāļšāļĢāļ§āļĄ (Digest) āđāļ—āļ™ Real - time', + ui_theme VARCHAR(20) DEFAULT 'light', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + CONSTRAINT fk_user_prefs_user FOREIGN KEY (user_id) REFERENCES users (user_id) ON DELETE CASCADE +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci; + +-- āļ•āļēāļĢāļēāļ‡āđ€āļāđ‡āļšāļšāļąāļ™āļ—āļķāļāļāļēāļĢāļāļĢāļ°āļ—āļģāļ‚āļ­āļ‡āļœāļđāđ‰āđƒāļŠāđ‰ +-- 4.1 Audit Logs Enhancements +-- āļĢāļ­āļ‡āļĢāļąāļš: Req 6.1 +-- āđ€āļŦāļ•āļļāļœāļĨ: āļĢāļ­āļ‡āļĢāļąāļš Distributed Tracing āđāļĨāļ°āļĢāļ°āļšāļļāļ„āļ§āļēāļĄāļĢāļļāļ™āđāļĢāļ‡ +CREATE TABLE audit_logs ( + audit_id BIGINT NOT NULL AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡ Log', + request_id VARCHAR(100) NULL COMMENT 'Trace ID linking to app logs', + user_id INT COMMENT 'āļœāļđāđ‰āļāļĢāļ°āļ—āļģ', + ACTION VARCHAR(100) NOT NULL COMMENT 'āļāļēāļĢāļāļĢāļ°āļ—āļģ ( + āđ€āļŠāđˆāļ™ rfa.create, + correspondence.update, + login.success + )', + severity ENUM( + 'INFO', + 'WARN', + 'ERROR', + 'CRITICAL ' + ) DEFAULT 'INFO', + entity_type VARCHAR(50) COMMENT 'āļ•āļēāļĢāļēāļ‡ / āđ‚āļĄāļ”āļđāļĨ (āđ€āļŠāđˆāļ™ ''rfa '', ''correspondence '')', + entity_id VARCHAR(50) COMMENT 'Primary ID āļ‚āļ­āļ‡āļĢāļ°āđ€āļšāļĩāļĒāļ™āļ—āļĩāđˆāđ„āļ”āđ‰āļĢāļąāļšāļœāļĨāļāļĢāļ°āļ—āļģ', + details_json JSON COMMENT 'āļ‚āđ‰āļ­āļĄāļđāļĨāļšāļĢāļīāļšāļ—', + ip_address VARCHAR(45) COMMENT 'IP Address', + user_agent VARCHAR(255) COMMENT 'User Agent', + created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 'āđ€āļ§āļĨāļēāļ—āļĩāđˆāļāļĢāļ°āļ—āļģ', + -- [āđāļāđ‰āđ„āļ‚] āļĢāļ§āļĄ created_at āđ€āļ‚āđ‰āļēāļĄāļēāđƒāļ™ Primary Key āđ€āļžāļ·āđˆāļ­āļĢāļ­āļ‡āļĢāļąāļš Partition + PRIMARY KEY (audit_id, created_at), + -- [āđāļāđ‰āđ„āļ‚] āđƒāļŠāđ‰ Index āļ˜āļĢāļĢāļĄāļ”āļēāđāļ—āļ™ Foreign Key āđ€āļžāļ·āđˆāļ­āđ„āļĄāđˆāđƒāļŦāđ‰āļ•āļīāļ”āļ‚āđ‰āļ­āļˆāļģāļāļąāļ”āļ‚āļ­āļ‡ Partition Table + 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) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļāđ‡āļšāļšāļąāļ™āļ—āļķāļāļāļēāļĢāļāļĢāļ°āļ—āļģāļ‚āļ­āļ‡āļœāļđāđ‰āđƒāļŠāđ‰' -- [āđ€āļžāļīāđˆāļĄ] āļ„āļģāļŠāļąāđˆāļ‡ Partition +PARTITION BY RANGE (YEAR(created_at)) ( + PARTITION p_old + VALUES LESS THAN (2024), + PARTITION p2024 + VALUES LESS THAN (2025), + PARTITION p2025 + VALUES LESS THAN (2026), + PARTITION p2026 + VALUES LESS THAN (2027), + PARTITION p2027 + VALUES LESS THAN (2028), + PARTITION p2028 + VALUES LESS THAN (2029), + PARTITION p2029 + VALUES LESS THAN (2030), + PARTITION p2030 + VALUES LESS THAN (2031), + PARTITION p_future + VALUES LESS THAN MAXVALUE +); + +-- āļ•āļēāļĢāļēāļ‡āļŠāļģāļŦāļĢāļąāļšāļˆāļąāļ”āļāļēāļĢāļāļēāļĢāđāļˆāđ‰āļ‡āđ€āļ•āļ·āļ­āļ™ (Email/Line/System) +CREATE TABLE notifications ( + id INT NOT NULL AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļāļēāļĢāđāļˆāđ‰āļ‡āđ€āļ•āļ·āļ­āļ™', + user_id INT NOT NULL COMMENT 'ID āļœāļđāđ‰āđƒāļŠāđ‰', + title VARCHAR(255) NOT NULL COMMENT 'āļŦāļąāļ§āļ‚āđ‰āļ­āļāļēāļĢāđāļˆāđ‰āļ‡āđ€āļ•āļ·āļ­āļ™', + message TEXT NOT NULL COMMENT 'āļĢāļēāļĒāļĨāļ°āđ€āļ­āļĩāļĒāļ”āļāļēāļĢāđāļˆāđ‰āļ‡āđ€āļ•āļ·āļ­āļ™', + notification_type ENUM('EMAIL', 'LINE', 'SYSTEM ') NOT NULL COMMENT 'āļ›āļĢāļ°āđ€āļ āļ— (EMAIL, LINE, SYSTEM)', + is_read BOOLEAN DEFAULT FALSE COMMENT 'āļŠāļ–āļēāļ™āļ°āļāļēāļĢāļ­āđˆāļēāļ™', + entity_type VARCHAR(50) COMMENT 'āđ€āļŠāđˆāļ™ ''rfa '', + ''circulation ''', + entity_id INT COMMENT 'ID āļ‚āļ­āļ‡āđ€āļ­āļ™āļ—āļīāļ•āļĩāļ—āļĩāđˆāđ€āļāļĩāđˆāļĒāļ§āļ‚āđ‰āļ­āļ‡', + created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', + -- [āđāļāđ‰āđ„āļ‚] āļĢāļ§āļĄ created_at āđ€āļ‚āđ‰āļēāļĄāļēāđƒāļ™ Primary Key + PRIMARY KEY (id, created_at), + -- [āđāļāđ‰āđ„āļ‚] āđƒāļŠāđ‰ Index āļ˜āļĢāļĢāļĄāļ”āļēāđāļ—āļ™ Foreign 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) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āļŠāļģāļŦāļĢāļąāļšāļˆāļąāļ”āļāļēāļĢāļāļēāļĢāđāļˆāđ‰āļ‡āđ€āļ•āļ·āļ­āļ™ (Email / Line / System)' -- [āđ€āļžāļīāđˆāļĄ] āļ„āļģāļŠāļąāđˆāļ‡ Partition +PARTITION BY RANGE (YEAR(created_at)) ( + PARTITION p_old + VALUES LESS THAN (2024), + PARTITION p2024 + VALUES LESS THAN (2025), + PARTITION p2025 + VALUES LESS THAN (2026), + PARTITION p2026 + VALUES LESS THAN (2027), + PARTITION p2027 + VALUES LESS THAN (2028), + PARTITION p2028 + VALUES LESS THAN (2029), + PARTITION p2029 + VALUES LESS THAN (2030), + PARTITION p2030 + VALUES LESS THAN (2031), + PARTITION p_future + VALUES LESS THAN MAXVALUE +); + +-- āļ•āļēāļĢāļēāļ‡āļŠāļģāļŦāļĢāļąāļšāļˆāļąāļ”āļāļēāļĢāļ”āļąāļŠāļ™āļĩāļāļēāļĢāļ„āđ‰āļ™āļŦāļēāļ‚āļąāđ‰āļ™āļŠāļđāļ‡ (Full-text Search) +CREATE TABLE search_indices ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ”āļąāļŠāļ™āļĩ', + entity_type VARCHAR(50) NOT NULL COMMENT 'āļŠāļ™āļīāļ”āđ€āļ­āļ™āļ—āļīāļ•āļĩ (āđ€āļŠāđˆāļ™ ''correspondence '', ''rfa '')', + entity_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āđ€āļ­āļ™āļ—āļīāļ•āļĩ', + content TEXT NOT NULL COMMENT 'āđ€āļ™āļ·āđ‰āļ­āļŦāļēāļ—āļĩāđˆāļˆāļ°āļ„āđ‰āļ™āļŦāļē', + indexed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡ / āļ­āļąāļ›āđ€āļ”āļ•āļąāļŠāļ™āļĩ ' +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āļŠāļģāļŦāļĢāļąāļšāļˆāļąāļ”āļāļēāļĢāļ”āļąāļŠāļ™āļĩāļāļēāļĢāļ„āđ‰āļ™āļŦāļēāļ‚āļąāđ‰āļ™āļŠāļđāļ‡ (Full - text Search)'; + +-- āļ•āļēāļĢāļēāļ‡āļŠāļģāļŦāļĢāļąāļšāļšāļąāļ™āļ—āļķāļāļ›āļĢāļ°āļ§āļąāļ•āļīāļāļēāļĢāļŠāļģāļĢāļ­āļ‡āļ‚āđ‰āļ­āļĄāļđāļĨ +CREATE TABLE backup_logs ( + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļāļēāļĢāļŠāļģāļĢāļ­āļ‡', + backup_type ENUM('DATABASE', 'FILES', 'FULL') NOT NULL COMMENT 'āļ›āļĢāļ°āđ€āļ āļ— (DATABASE, FILES, FULL)', + backup_path VARCHAR(500) NOT NULL COMMENT 'āļ•āļģāđāļŦāļ™āđˆāļ‡āđ„āļŸāļĨāđŒāļŠāļģāļĢāļ­āļ‡', + file_size BIGINT COMMENT 'āļ‚āļ™āļēāļ”āđ„āļŸāļĨāđŒ', + STATUS ENUM( + 'STARTED', + 'COMPLETED', + 'FAILED' + ) NOT NULL COMMENT 'āļŠāļ–āļēāļ™āļ°', + started_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āđ€āļ§āļĨāļēāđ€āļĢāļīāđˆāļĄāļ•āđ‰āļ™', + completed_at TIMESTAMP NULL COMMENT 'āđ€āļ§āļĨāļēāđ€āļŠāļĢāđ‡āļˆāļŠāļīāđ‰āļ™', + error_message TEXT COMMENT 'āļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļœāļīāļ”āļžāļĨāļēāļ” (āļ–āđ‰āļēāļĄāļĩ)' +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āļŠāļģāļŦāļĢāļąāļšāļšāļąāļ™āļ—āļķāļāļ›āļĢāļ°āļ§āļąāļ•āļīāļāļēāļĢāļŠāļģāļĢāļ­āļ‡āļ‚āđ‰āļ­āļĄāļđāļĨ'; + +-- 4.2 Virtual Columns for JSON Search (āļ•āļąāļ§āļ­āļĒāđˆāļēāļ‡āļŠāļģāļŦāļĢāļąāļš Correspondence) +-- āļĢāļ­āļ‡āļĢāļąāļš: Backend Plan T2.1, Req 3.11.3 +-- āđ€āļŦāļ•āļļāļœāļĨ: āđ€āļžāļīāđˆāļĄāļ„āļ§āļēāļĄāđ€āļĢāđ‡āļ§āđƒāļ™āļāļēāļĢ Search/Sort āļ‚āđ‰āļ­āļĄāļđāļĨāļ—āļĩāđˆāļ­āļĒāļđāđˆāđƒāļ™ JSON details +-- āļŦāļĄāļēāļĒāđ€āļŦāļ•āļļ: āļ•āđ‰āļ­āļ‡āļĄāļąāđˆāļ™āđƒāļˆāļ§āđˆāļē MariaDB āđ€āļ§āļ­āļĢāđŒāļŠāļąāļ™ 10.11+ āļĢāļ­āļ‡āļĢāļąāļš Syntax āļ™āļĩāđ‰ +-- āļ•āļąāļ§āļ­āļĒāđˆāļēāļ‡: āļ”āļķāļ‡ Project ID āļ—āļĩāđˆāļ­āđ‰āļēāļ‡āļ­āļīāļ‡āđƒāļ™ details āļ­āļ­āļāļĄāļēāļ—āļģ Index +ALTER TABLE correspondence_revisions +ADD COLUMN v_ref_project_id INT GENERATED ALWAYS AS ( + JSON_UNQUOTE( + JSON_EXTRACT(details, '$.projectId') + ) + ) VIRTUAL, + ADD INDEX idx_corr_rev_v_project (v_ref_project_id); + +-- āļ•āļąāļ§āļ­āļĒāđˆāļēāļ‡: āļ”āļķāļ‡ Document Type āļĒāđˆāļ­āļĒāļˆāļēāļ details +ALTER TABLE correspondence_revisions +ADD COLUMN v_doc_subtype VARCHAR(50) GENERATED ALWAYS AS ( + JSON_UNQUOTE(JSON_EXTRACT(details, '$.subType')) + ) VIRTUAL, + ADD INDEX idx_corr_rev_v_subtype (v_doc_subtype); + +-- 2. āļ›āļĢāļąāļšāļ›āļĢāļļāļ‡āļ•āļēāļĢāļēāļ‡ correspondence_revisions +-- āđ€āļžāļīāđˆāļĄ Virtual Columns āđāļĨāļ° Schema Version +ALTER TABLE correspondence_revisions +ADD COLUMN schema_version INT DEFAULT 1 COMMENT 'āđ€āļ§āļ­āļĢāđŒāļŠāļąāļ™āļ‚āļ­āļ‡ Schema āļ—āļĩāđˆāđƒāļŠāđ‰āļāļąāļš details' +AFTER details; + +-- āļ—āļģāđāļšāļšāđ€āļ”āļĩāļĒāļ§āļāļąāļ™āļāļąāļš RFA Revisions āļŦāļēāļāļĄāļĩāļāļēāļĢāđ€āļāđ‡āļš JSON details +ALTER TABLE rfa_revisions +ADD COLUMN details JSON NULL COMMENT 'RFA Specific Details' +AFTER description; + +ALTER TABLE rfa_revisions +ADD COLUMN v_ref_drawing_count INT GENERATED ALWAYS AS ( + JSON_UNQUOTE( + JSON_EXTRACT(details, '$.drawingCount') + ) + ) VIRTUAL; + +ALTER TABLE rfa_revisions +ADD COLUMN schema_version INT DEFAULT 1 COMMENT 'Version āļ‚āļ­āļ‡ JSON Schema' +AFTER details; + +CREATE INDEX idx_rfa_rev_v_drawing_count ON rfa_revisions (v_ref_drawing_count); + +-- ... (āļ•āđˆāļ­āļ—āđ‰āļēāļĒāđ„āļŸāļĨāđŒāđ€āļ”āļīāļĄ) +-- ============================================================ +-- āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 11: Unified Workflow Engine (Phase 6A/Phase 3) +-- ============================================================ +DROP TABLE IF EXISTS workflow_histories; + +DROP TABLE IF EXISTS workflow_instances; + +DROP TABLE IF EXISTS workflow_definitions; + +-- 1. āļ•āļēāļĢāļēāļ‡āđ€āļāđ‡āļšāļ™āļīāļĒāļēāļĄ Workflow (Definition / DSL) +CREATE TABLE workflow_definitions ( + id CHAR(36) NOT NULL PRIMARY KEY COMMENT 'UUID āļ‚āļ­āļ‡ Workflow Definition', + workflow_code VARCHAR(50) NOT NULL COMMENT 'āļĢāļŦāļąāļŠ Workflow āđ€āļŠāđˆāļ™ RFA_FLOW_V1, CORRESPONDENCE_FLOW_V1', + version INT NOT NULL DEFAULT 1 COMMENT 'āļŦāļĄāļēāļĒāđ€āļĨāļ‚ Version', + description TEXT NULL COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒ Workflow', + dsl JSON NOT NULL COMMENT 'āļ™āļīāļĒāļēāļĄ Workflow āļ•āđ‰āļ™āļ‰āļšāļąāļš (YAML/JSON Format)', + compiled JSON NOT NULL COMMENT 'āđ‚āļ„āļĢāļ‡āļŠāļĢāđ‰āļēāļ‡ Execution Tree āļ—āļĩāđˆ Compile āđāļĨāđ‰āļ§', + is_active BOOLEAN DEFAULT TRUE COMMENT 'āļŠāļ–āļēāļ™āļ°āļāļēāļĢāđƒāļŠāđ‰āļ‡āļēāļ™', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', + -- āļ›āđ‰āļ­āļ‡āļāļąāļ™āļāļēāļĢāļĄāļĩ Workflow Code āđāļĨāļ° Version āļ‹āđ‰āļģāļāļąāļ™ + UNIQUE KEY uq_workflow_version (workflow_code, version) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļāđ‡āļšāļ™āļīāļĒāļēāļĄāļāļŽāļāļēāļĢāđ€āļ”āļīāļ™āđ€āļ­āļāļŠāļēāļĢ (Workflow DSL)'; + +-- āļŠāļĢāđ‰āļēāļ‡ Index āļŠāļģāļŦāļĢāļąāļšāļāļēāļĢāļ„āđ‰āļ™āļŦāļē Workflow āļ—āļĩāđˆ Active āļĨāđˆāļēāļŠāļļāļ”āđ„āļ”āđ‰āđ€āļĢāđ‡āļ§āļ‚āļķāđ‰āļ™ +CREATE INDEX idx_workflow_active ON workflow_definitions (workflow_code, is_active, version); + +-- 2. āļ•āļēāļĢāļēāļ‡āđ€āļāđ‡āļš Workflow Instance (āļŠāļ–āļēāļ™āļ°āđ€āļ­āļāļŠāļēāļĢāļˆāļĢāļīāļ‡) +CREATE TABLE workflow_instances ( + id CHAR(36) NOT NULL PRIMARY KEY COMMENT 'UUID āļ‚āļ­āļ‡ Instance', + definition_id CHAR(36) NOT NULL COMMENT 'āļ­āđ‰āļēāļ‡āļ­āļīāļ‡ Definition āļ—āļĩāđˆāđƒāļŠāđ‰', + entity_type VARCHAR(50) NOT NULL COMMENT 'āļ›āļĢāļ°āđ€āļ āļ—āđ€āļ­āļāļŠāļēāļĢ (rfa_revision, correspondence_revision, circulation)', + entity_id VARCHAR(50) NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢ (String/Int)', + current_state VARCHAR(50) NOT NULL COMMENT 'āļŠāļ–āļēāļ™āļ°āļ›āļąāļˆāļˆāļļāļšāļąāļ™', + STATUS ENUM( + 'ACTIVE', + 'COMPLETED', + 'CANCELLED', + 'TERMINATED' + ) DEFAULT 'ACTIVE' COMMENT 'āļŠāļ–āļēāļ™āļ°āļ āļēāļžāļĢāļ§āļĄ', + context JSON NULL COMMENT 'āļ•āļąāļ§āđāļ›āļĢ Context āļŠāļģāļŦāļĢāļąāļšāļ•āļąāļ”āļŠāļīāļ™āđƒāļˆ', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + CONSTRAINT fk_wf_inst_def FOREIGN KEY (definition_id) REFERENCES workflow_definitions (id) ON DELETE CASCADE +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļāđ‡āļšāļŠāļ–āļēāļ™āļ°āļāļēāļĢāđ€āļ”āļīāļ™āđ€āļĢāļ·āđˆāļ­āļ‡āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢ'; + +CREATE INDEX idx_wf_inst_entity ON workflow_instances (entity_type, entity_id); + +CREATE INDEX idx_wf_inst_state ON workflow_instances (current_state); + +-- 3. āļ•āļēāļĢāļēāļ‡āđ€āļāđ‡āļšāļ›āļĢāļ°āļ§āļąāļ•āļī (Audit Log / History) +CREATE TABLE workflow_histories ( + id CHAR(36) NOT NULL PRIMARY KEY COMMENT 'UUID', + instance_id CHAR(36) NOT NULL COMMENT 'āļ­āđ‰āļēāļ‡āļ­āļīāļ‡ Instance', + from_state VARCHAR(50) NOT NULL COMMENT 'āļŠāļ–āļēāļ™āļ°āļ•āđ‰āļ™āļ—āļēāļ‡', + to_state VARCHAR(50) NOT NULL COMMENT 'āļŠāļ–āļēāļ™āļ°āļ›āļĨāļēāļĒāļ—āļēāļ‡', + ACTION VARCHAR(50) NOT NULL COMMENT 'Action āļ—āļĩāđˆāļāļĢāļ°āļ—āļģ', + action_by_user_id INT NULL COMMENT 'User ID āļœāļđāđ‰āļāļĢāļ°āļ—āļģ', + COMMENT TEXT NULL COMMENT 'āļ„āļ§āļēāļĄāđ€āļŦāđ‡āļ™', + metadata JSON NULL COMMENT 'Snapshot āļ‚āđ‰āļ­āļĄāļđāļĨ āļ“ āļ‚āļ“āļ°āļ™āļąāđ‰āļ™', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + CONSTRAINT fk_wf_hist_inst FOREIGN KEY (instance_id) REFERENCES workflow_instances (id) ON DELETE CASCADE +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āļ›āļĢāļ°āļ§āļąāļ•āļīāļāļēāļĢāđ€āļ›āļĨāļĩāđˆāļĒāļ™āļŠāļ–āļēāļ™āļ° Workflow'; + +CREATE INDEX idx_wf_hist_instance ON workflow_histories (instance_id); + +CREATE INDEX idx_wf_hist_user ON workflow_histories (action_by_user_id); + +-- ============================================================ +-- 5. PARTITIONING PREPARATION (Advance - Optional) +-- ============================================================ +-- āļŦāļĄāļēāļĒāđ€āļŦāļ•āļļ: āļāļēāļĢāļ—āļģ Partitioning āļšāļ™āļ•āļēāļĢāļēāļ‡āļ—āļĩāđˆāļĄāļĩāļ­āļĒāļđāđˆāđāļĨāđ‰āļ§ (audit_logs, notifications) +-- āļĄāļąāļāļˆāļ°āļ•āđ‰āļ­āļ‡ Drop Primary Key āđ€āļ”āļīāļĄ āđāļĨāđ‰āļ§āļŠāļĢāđ‰āļēāļ‡āđƒāļŦāļĄāđˆāđ‚āļ”āļĒāļĢāļ§āļĄ Partition Key (created_at) āđ€āļ‚āđ‰āļēāđ„āļ› +-- āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļ™āļĩāđ‰āļ„āļ§āļĢāļ—āļģāđāļĒāļāļ•āđˆāļēāļ‡āļŦāļēāļāđ€āļĄāļ·āđˆāļ­āļĢāļ°āļšāļšāđ€āļĢāļīāđˆāļĄāļĄāļĩāļ‚āđ‰āļ­āļĄāļđāļĨāđ€āļĒāļ­āļ° āļŦāļĢāļ·āļ­āļ—āļģāđƒāļ™ Maintenance Window +-- +-- āļ•āļąāļ§āļ­āļĒāđˆāļēāļ‡ SQL āļŠāļģāļŦāļĢāļąāļš Audit Logs (Reference Only): +-- ALTER TABLE audit_logs DROP PRIMARY KEY, ADD PRIMARY KEY (audit_id, created_at); +-- 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 +-- ); +-- ===================================================== +-- CREATE INDEXES +-- ===================================================== +-- Indexes for document_number_formats +CREATE INDEX idx_document_number_formats_project ON document_number_formats (project_id); + +CREATE INDEX idx_document_number_formats_type ON document_number_formats (correspondence_type_id); + +CREATE INDEX idx_document_number_formats_project_type ON document_number_formats (project_id, correspondence_type_id); + +-- Indexes for document_number_counters +CREATE INDEX idx_document_number_counters_project ON document_number_counters (project_id); + +CREATE INDEX idx_document_number_counters_org ON document_number_counters (originator_organization_id); + +CREATE INDEX idx_document_number_counters_type ON document_number_counters (correspondence_type_id); + +CREATE INDEX idx_document_number_counters_year ON document_number_counters (current_year); + +-- Indexes for tags +CREATE INDEX idx_tags_name ON tags (tag_name); + +CREATE INDEX idx_tags_created_at ON tags (created_at); + +-- Indexes for correspondence_tags +CREATE INDEX idx_correspondence_tags_correspondence ON correspondence_tags (correspondence_id); + +CREATE INDEX idx_correspondence_tags_tag ON correspondence_tags (tag_id); + +-- Indexes for audit_logs +CREATE INDEX idx_audit_logs_user ON audit_logs (user_id); + +CREATE INDEX idx_audit_logs_action ON audit_logs (ACTION); + +CREATE INDEX idx_audit_logs_entity ON audit_logs (entity_type, entity_id); + +CREATE INDEX idx_audit_logs_created_at ON audit_logs (created_at); + +CREATE INDEX idx_audit_logs_ip ON audit_logs (ip_address); + +-- Indexes for notifications +CREATE INDEX idx_notifications_user ON notifications (user_id); + +CREATE INDEX idx_notifications_type ON notifications (notification_type); + +CREATE INDEX idx_notifications_read ON notifications (is_read); + +CREATE INDEX idx_notifications_entity ON notifications (entity_type, entity_id); + +CREATE INDEX idx_notifications_created_at ON notifications (created_at); + +-- Indexes for search_indices +CREATE INDEX idx_search_indices_entity ON search_indices (entity_type, entity_id); + +CREATE INDEX idx_search_indices_indexed_at ON search_indices (indexed_at); + +-- Indexes for backup_logs +CREATE INDEX idx_backup_logs_type ON backup_logs (backup_type); + +CREATE INDEX idx_backup_logs_status ON backup_logs (STATUS); + +CREATE INDEX idx_backup_logs_started_at ON backup_logs (started_at); + +CREATE INDEX idx_backup_logs_completed_at ON backup_logs (completed_at); + +-- ===================================================== +-- Additional Composite Indexes for Performance +-- ===================================================== +-- Composite index for document_number_counters for faster lookups +CREATE INDEX idx_doc_counter_composite ON document_number_counters ( + project_id, + originator_organization_id, + correspondence_type_id, + current_year +); + +-- Composite index for notifications for user-specific queries +CREATE INDEX idx_notifications_user_unread ON notifications (user_id, is_read, created_at); + +-- Composite index for audit_logs for reporting +CREATE INDEX idx_audit_logs_reporting ON audit_logs (created_at, entity_type, ACTION); + +-- Composite index for search_indices for entity-based queries +CREATE INDEX idx_search_entities ON search_indices (entity_type, entity_id, indexed_at); + +-- āļŠāļĢāđ‰āļēāļ‡ Index āļŠāļģāļŦāļĢāļąāļš Cleanup Job +CREATE INDEX idx_attachments_temp_cleanup ON attachments (is_temporary, expires_at); + +CREATE INDEX idx_attachments_temp_id ON attachments (temp_id); + +CREATE INDEX idx_audit_request_id ON audit_logs (request_id); + +-- ===================================================== +-- SQL Script for LCBP3-DMS (V1.4.0) - MariaDB +-- Generated from Data Dictionary +-- ===================================================== +-- ===================================================== +-- 11. 📊 Views & Procedures (āļ§āļīāļ§ āđāļĨāļ° āđ‚āļ›āļĢāļ‹āļĩāđ€āļ”āļ­āļĢāđŒ) +-- ===================================================== +-- View āđāļŠāļ”āļ‡ Revision "āļ›āļąāļˆāļˆāļļāļšāļąāļ™" āļ‚āļ­āļ‡ correspondences āļ—āļąāđ‰āļ‡āļŦāļĄāļ” (āļ—āļĩāđˆāđ„āļĄāđˆāđƒāļŠāđˆ RFA) +CREATE VIEW v_current_correspondences AS +SELECT c.id AS correspondence_id, + c.correspondence_number, + c.correspondence_type_id, + ct.type_code AS correspondence_type_code, + ct.type_name AS correspondence_type_name, + c.project_id, + p.project_code, + p.project_name, + c.originator_id, + org.organization_code AS originator_code, + org.organization_name AS originator_name, + cr.id AS revision_id, + cr.revision_number, + cr.revision_label, + cr.title, + cr.document_date, + cr.issued_date, + cr.received_date, + cr.due_date, + cr.correspondence_status_id, + cs.status_code, + cs.status_name, + cr.created_by, + u.username AS created_by_username, + cr.created_at AS revision_created_at +FROM correspondences c + INNER JOIN correspondence_types ct ON c.correspondence_type_id = ct.id + INNER JOIN projects p ON c.project_id = p.id + LEFT JOIN organizations org ON c.originator_id = org.id + INNER JOIN correspondence_revisions cr ON c.id = cr.correspondence_id + INNER JOIN correspondence_status cs ON cr.correspondence_status_id = cs.id + LEFT JOIN users u ON cr.created_by = u.user_id +WHERE cr.is_current = TRUE + AND c.correspondence_type_id NOT IN( + SELECT id + FROM correspondence_types + WHERE type_code = 'RFA' + ) + AND c.deleted_at IS NULL; + +-- View āđāļŠāļ”āļ‡ Revision "āļ›āļąāļˆāļˆāļļāļšāļąāļ™" āļ‚āļ­āļ‡ rfa_revisions āļ—āļąāđ‰āļ‡āļŦāļĄāļ” +CREATE VIEW v_current_rfas AS +SELECT r.id AS rfa_id, + r.rfa_type_id, + rt.type_code AS rfa_type_code, + rt.type_name_th AS rfa_type_name_th, + rt.type_name_en AS rfa_type_name_en, + rr.correspondence_id, + c.correspondence_number, + c.project_id, + p.project_code, + p.project_name, + c.originator_id, + org.organization_name AS originator_name, + rr.id AS revision_id, + rr.revision_number, + rr.revision_label, + rr.title, + rr.document_date, + rr.issued_date, + rr.received_date, + rr.approved_date, + rr.rfa_status_code_id, + rsc.status_code AS rfa_status_code, + rsc.status_name AS rfa_status_name, + rr.rfa_approve_code_id, + rac.approve_code AS rfa_approve_code, + rac.approve_name AS rfa_approve_name, + rr.created_by, + u.username AS created_by_username, + rr.created_at AS revision_created_at +FROM rfas r + INNER JOIN rfa_types rt ON r.rfa_type_id = rt.id + INNER JOIN rfa_revisions rr ON r.id = rr.rfa_id + INNER JOIN correspondences c ON rr.correspondence_id = c.id + INNER JOIN projects p ON c.project_id = p.id + INNER JOIN organizations org ON c.originator_id = org.id + INNER JOIN rfa_status_codes rsc ON rr.rfa_status_code_id = rsc.id + LEFT JOIN rfa_approve_codes rac ON rr.rfa_approve_code_id = rac.id + LEFT JOIN users u ON rr.created_by = u.user_id +WHERE rr.is_current = TRUE + AND r.deleted_at IS NULL + AND c.deleted_at IS NULL; + +-- View āđāļŠāļ”āļ‡āļ„āļ§āļēāļĄāļŠāļąāļĄāļžāļąāļ™āļ˜āđŒāļ—āļąāđ‰āļ‡āļŦāļĄāļ”āļĢāļ°āļŦāļ§āđˆāļēāļ‡ Contract, Project, āđāļĨāļ° Organization +CREATE VIEW v_contract_parties_all AS +SELECT c.id AS contract_id, + c.contract_code, + c.contract_name, + p.id AS project_id, + p.project_code, + p.project_name, + o.id AS organization_id, + o.organization_code, + o.organization_name, + co.role_in_contract +FROM contracts c + INNER JOIN projects p ON c.project_id = p.id + INNER JOIN contract_organizations co ON c.id = co.contract_id + INNER JOIN organizations o ON co.organization_id = o.id +WHERE c.is_active = TRUE; + +-- ============================================================ +-- View: v_user_tasks (Unified Workflow Engine Edition) +-- ============================================================ +-- āļŦāļ™āđ‰āļēāļ—āļĩāđˆ: āļĢāļ§āļĄāļĢāļēāļĒāļāļēāļĢāļ‡āļēāļ™āļ—āļĩāđˆāļĒāļąāļ‡āļ„āđ‰āļēāļ‡āļ­āļĒāļđāđˆ (Status = ACTIVE) āļˆāļēāļāļ—āļļāļāļĢāļ°āļšāļš (RFA, Circulation, Correspondence) +-- āđ€āļžāļ·āđˆāļ­āļ™āļģāđ„āļ›āđāļŠāļ”āļ‡āđƒāļ™āļŦāļ™āđ‰āļē Dashboard "My Tasks" +-- ============================================================ +CREATE OR REPLACE VIEW v_user_tasks AS +SELECT -- 1. Workflow Instance Info + wi.id AS instance_id, + wd.workflow_code, + wi.current_state, + wi.status AS workflow_status, + wi.created_at AS assigned_at, + -- 2. Entity Info (Polymorphic Identity) + wi.entity_type, + wi.entity_id, + -- 3. Normalized Document Info (āļ”āļķāļ‡āļ‚āđ‰āļ­āļĄāļđāļĨāļˆāļĢāļīāļ‡āļˆāļēāļāļ•āļēāļĢāļēāļ‡āļĨāļđāļāļ•āļēāļĄāļ›āļĢāļ°āđ€āļ āļ—) + -- āđƒāļŠāđ‰ CASE WHEN āđ€āļžāļ·āđˆāļ­āļĢāļ§āļĄāļ„āļ­āļĨāļąāļĄāļ™āđŒāļ—āļĩāđˆāļŠāļ·āđˆāļ­āļ•āđˆāļēāļ‡āļāļąāļ™āđƒāļŦāđ‰āđ€āļ›āđ‡āļ™āļŠāļ·āđˆāļ­āļāļĨāļēāļ‡ (document_number, subject) + CASE + WHEN wi.entity_type = 'rfa_revision' THEN rfa_corr.correspondence_number + WHEN wi.entity_type = 'circulation' THEN circ.circulation_no + WHEN wi.entity_type = 'correspondence_revision' THEN corr_corr.correspondence_number + ELSE 'N/A' + END AS document_number, + CASE + WHEN wi.entity_type = 'rfa_revision' THEN rfa_rev.title + WHEN wi.entity_type = 'circulation' THEN circ.circulation_subject + WHEN wi.entity_type = 'correspondence_revision' THEN corr_rev.title + ELSE 'Unknown Document' + END AS subject, + -- 4. Context Info (āļŠāļģāļŦāļĢāļąāļš Filter āļŠāļīāļ—āļ˜āļīāđŒāļāļēāļĢāļĄāļ­āļ‡āđ€āļŦāđ‡āļ™āļ—āļĩāđˆ Backend) + -- āļ”āļķāļ‡āđ€āļ›āđ‡āļ™ JSON String āđ€āļžāļ·āđˆāļ­āđƒāļŦāđ‰ Backend āđ„āļ› Parse āļŦāļĢāļ·āļ­āđƒāļŠāđ‰ JSON_CONTAINS + JSON_UNQUOTE(JSON_EXTRACT(wi.context, '$.ownerId')) AS owner_id, + JSON_EXTRACT(wi.context, '$.assigneeIds') AS assignee_ids_json +FROM workflow_instances wi + JOIN workflow_definitions wd ON wi.definition_id = wd.id -- 5. Joins for RFA (āļ‹āļąāļšāļ‹āđ‰āļ­āļ™āļŦāļ™āđˆāļ­āļĒāđ€āļžāļĢāļēāļ° RFA āļœāļđāļāļāļąāļš Correspondence āļ­āļĩāļāļ—āļĩ) + LEFT JOIN rfa_revisions rfa_rev ON wi.entity_type = 'rfa_revision' + AND wi.entity_id = CAST(rfa_rev.id AS CHAR) + LEFT JOIN correspondences rfa_corr ON rfa_rev.correspondence_id = rfa_corr.id -- 6. Joins for Circulation + LEFT JOIN circulations circ ON wi.entity_type = 'circulation' + AND wi.entity_id = CAST(circ.id AS CHAR) -- 7. Joins for Correspondence + LEFT JOIN correspondence_revisions corr_rev ON wi.entity_type = 'correspondence_revision' + AND wi.entity_id = CAST(corr_rev.id AS CHAR) + LEFT JOIN correspondences corr_corr ON corr_rev.correspondence_id = corr_corr.id -- 8. Filter āđ€āļ‰āļžāļēāļ°āļ‡āļēāļ™āļ—āļĩāđˆāļĒāļąāļ‡ Active āļ­āļĒāļđāđˆ +WHERE wi.status = 'ACTIVE'; + +-- View āđāļŠāļ”āļ‡ audit_logs āļžāļĢāđ‰āļ­āļĄāļ‚āđ‰āļ­āļĄāļđāļĨ username āđāļĨāļ° email āļ‚āļ­āļ‡āļœāļđāđ‰āļāļĢāļ°āļ—āļģ +CREATE VIEW v_audit_log_details AS +SELECT al.audit_id, + al.user_id, + u.username, + u.email, + u.first_name, + u.last_name, + al.action, + al.entity_type, + al.entity_id, + al.details_json, + al.ip_address, + al.user_agent, + al.created_at +FROM audit_logs al + LEFT JOIN users u ON al.user_id = u.user_id; + +-- View āļĢāļ§āļĄāļŠāļīāļ—āļ˜āļīāđŒāļ—āļąāđ‰āļ‡āļŦāļĄāļ” (Global + Project) āļ‚āļ­āļ‡āļœāļđāđ‰āđƒāļŠāđ‰āļ—āļļāļāļ„āļ™ +CREATE VIEW v_user_all_permissions AS -- Global Permissions +SELECT ua.user_id, + ua.role_id, + r.role_name, + rp.permission_id, + p.permission_name, + p.module, + p.scope_level, + ua.organization_id, + NULL AS project_id, + NULL AS contract_id, + 'GLOBAL' AS permission_scope +FROM user_assignments ua + INNER JOIN roles r ON ua.role_id = r.role_id + INNER JOIN role_permissions rp ON ua.role_id = rp.role_id + INNER JOIN permissions p ON rp.permission_id = p.permission_id -- Global scope +WHERE p.is_active = 1 + AND ua.organization_id IS NULL + AND ua.project_id IS NULL + AND ua.contract_id IS NULL +UNION ALL +-- Organization-specific Permissions +SELECT ua.user_id, + ua.role_id, + r.role_name, + rp.permission_id, + p.permission_name, + p.module, + p.scope_level, + ua.organization_id, + NULL AS project_id, + NULL AS contract_id, + 'ORGANIZATION' AS permission_scope +FROM user_assignments ua + INNER JOIN roles r ON ua.role_id = r.role_id + INNER JOIN role_permissions rp ON ua.role_id = rp.role_id + INNER JOIN permissions p ON rp.permission_id = p.permission_id -- Organization scope +WHERE p.is_active = 1 + AND ua.organization_id IS NOT NULL + AND ua.project_id IS NULL + AND ua.contract_id IS NULL +UNION ALL +-- Project-specific Permissions +SELECT ua.user_id, + ua.role_id, + r.role_name, + rp.permission_id, + p.permission_name, + p.module, + p.scope_level, + ua.organization_id, + ua.project_id, + NULL AS contract_id, + 'PROJECT' AS permission_scope +FROM user_assignments ua + INNER JOIN roles r ON ua.role_id = r.role_id + INNER JOIN role_permissions rp ON ua.role_id = rp.role_id + INNER JOIN permissions p ON rp.permission_id = p.permission_id -- Project scope +WHERE p.is_active = 1 + AND ua.project_id IS NOT NULL + AND ua.contract_id IS NULL +UNION ALL +-- Contract-specific Permissions +SELECT ua.user_id, + ua.role_id, + r.role_name, + rp.permission_id, + p.permission_name, + p.module, + p.scope_level, + ua.organization_id, + ua.project_id, + ua.contract_id, + 'CONTRACT' AS permission_scope +FROM user_assignments ua + INNER JOIN roles r ON ua.role_id = r.role_id + INNER JOIN role_permissions rp ON ua.role_id = rp.role_id + INNER JOIN permissions p ON rp.permission_id = p.permission_id -- Contract scope +WHERE p.is_active = 1 + AND ua.contract_id IS NOT NULL; + +-- ===================================================== +-- Additional Useful Views +-- ===================================================== +-- View āđāļŠāļ”āļ‡āđ€āļ­āļāļŠāļēāļĢāļ—āļąāđ‰āļ‡āļŦāļĄāļ”āļ—āļĩāđˆāļĄāļĩāđ„āļŸāļĨāđŒāđāļ™āļš +CREATE VIEW v_documents_with_attachments AS +SELECT 'CORRESPONDENCE' AS document_type, + c.id AS document_id, + c.correspondence_number AS document_number, + c.project_id, + p.project_code, + p.project_name, + COUNT(ca.attachment_id) AS attachment_count, + MAX(a.created_at) AS latest_attachment_date +FROM correspondences c + INNER JOIN projects p ON c.project_id = p.id + LEFT JOIN correspondence_attachments ca ON c.id = ca.correspondence_id + LEFT JOIN attachments a ON ca.attachment_id = a.id +WHERE c.deleted_at IS NULL +GROUP BY c.id, + c.correspondence_number, + c.project_id, + p.project_code, + p.project_name +UNION ALL +SELECT 'CIRCULATION' AS document_type, + circ.id AS document_id, + circ.circulation_no AS document_number, + corr.project_id, + p.project_code, + p.project_name, + COUNT(ca.attachment_id) AS attachment_count, + MAX(a.created_at) AS latest_attachment_date +FROM circulations circ + INNER JOIN correspondences corr ON circ.correspondence_id = corr.id + INNER JOIN projects p ON corr.project_id = p.id + LEFT JOIN circulation_attachments ca ON circ.id = ca.circulation_id + LEFT JOIN attachments a ON ca.attachment_id = a.id +GROUP BY circ.id, + circ.circulation_no, + corr.project_id, + p.project_code, + p.project_name +UNION ALL +SELECT 'SHOP_DRAWING' AS document_type, + sdr.id AS document_id, + sd.drawing_number AS document_number, + sd.project_id, + p.project_code, + p.project_name, + COUNT(sdra.attachment_id) AS attachment_count, + MAX(a.created_at) AS latest_attachment_date +FROM shop_drawing_revisions sdr + INNER JOIN shop_drawings sd ON sdr.shop_drawing_id = sd.id + INNER JOIN projects p ON sd.project_id = p.id + LEFT JOIN shop_drawing_revision_attachments sdra ON sdr.id = sdra.shop_drawing_revision_id + LEFT JOIN attachments a ON sdra.attachment_id = a.id +WHERE sd.deleted_at IS NULL +GROUP BY sdr.id, + sd.drawing_number, + sd.project_id, + p.project_code, + p.project_name +UNION ALL +SELECT 'CONTRACT_DRAWING' AS document_type, + cd.id AS document_id, + cd.condwg_no AS document_number, + cd.project_id, + p.project_code, + p.project_name, + COUNT(cda.attachment_id) AS attachment_count, + MAX(a.created_at) AS latest_attachment_date +FROM contract_drawings cd + INNER JOIN projects p ON cd.project_id = p.id + LEFT JOIN contract_drawing_attachments cda ON cd.id = cda.contract_drawing_id + LEFT JOIN attachments a ON cda.attachment_id = a.id +WHERE cd.deleted_at IS NULL +GROUP BY cd.id, + cd.condwg_no, + cd.project_id, + p.project_code, + p.project_name; + +-- View āđāļŠāļ”āļ‡āļŠāļ–āļīāļ•āļīāđ€āļ­āļāļŠāļēāļĢāļ•āļēāļĄāļ›āļĢāļ°āđ€āļ āļ—āđāļĨāļ°āļŠāļ–āļēāļ™āļ° +CREATE VIEW v_document_statistics AS +SELECT p.id AS project_id, + p.project_code, + p.project_name, + ct.id AS correspondence_type_id, + ct.type_code, + ct.type_name, + cs.id AS status_id, + cs.status_code, + cs.status_name, + COUNT(DISTINCT c.id) AS document_count, + COUNT(DISTINCT cr.id) AS revision_count +FROM projects p + CROSS JOIN correspondence_types ct + CROSS JOIN correspondence_status cs + LEFT JOIN correspondences c ON p.id = c.project_id + AND ct.id = c.correspondence_type_id + LEFT JOIN correspondence_revisions cr ON c.id = cr.correspondence_id + AND cs.id = cr.correspondence_status_id + AND cr.is_current = TRUE +WHERE p.is_active = 1 + AND ct.is_active = 1 + AND cs.is_active = 1 +GROUP BY p.id, + p.project_code, + p.project_name, + ct.id, + ct.type_code, + ct.type_name, + cs.id, + cs.status_code, + cs.status_name; + +-- ===================================================== +-- Indexes for View Performance Optimization +-- ===================================================== +-- Indexes for v_current_correspondences performance +CREATE INDEX idx_correspondences_type_project ON correspondences (correspondence_type_id, project_id); + +CREATE INDEX idx_corr_revisions_current_status ON correspondence_revisions (is_current, correspondence_status_id); + +CREATE INDEX idx_corr_revisions_correspondence_current ON correspondence_revisions (correspondence_id, is_current); + +-- Indexes for v_current_rfas performance +CREATE INDEX idx_rfa_revisions_current_status ON rfa_revisions (is_current, rfa_status_code_id); + +CREATE INDEX idx_rfa_revisions_rfa_current ON rfa_revisions (rfa_id, is_current); + +-- Indexes for document statistics performance +CREATE INDEX idx_correspondences_project_type ON correspondences (project_id, correspondence_type_id); + +CREATE INDEX idx_corr_revisions_status_current ON correspondence_revisions (correspondence_status_id, is_current); + +SET FOREIGN_KEY_CHECKS = 1;