diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 695aba7..aaf647c 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,4 +1,40 @@ { "recommendations": [ - "ms-vscode.powershell""] + "ms-vscode.powershell", + "ms-vscode.csharp", + "dbaeumer.vscode-eslint", + "esbenp.prettier-vscode", + "usernamehw.errorlens", + "yoavbls.pretty-typescript-errors", + "wix.vscode-import-cost", + "aaron-bond.better-comments", + "gruntfuggly.todo-tree", + "ashinzekene.nestjs", + "orta.vscode-jest", + "bradlc.vscode-tailwindcss", + "heybourn.headwind", + "prisma.prisma", + "rangav.vscode-thunder-client", + "humao.rest-client", + "formulahendry.auto-close-tag", + "formulahendry.auto-rename-tag", + "ms-azuretools.vscode-docker", + "mtxr.sqltools", + "redhat.vscode-yaml", + "mikestead.dotenv", + "editorconfig.editorconfig", + "eamodio.gitlens", + "mhutchie.git-graph", + "vivaxy.vscode-conventional-commits", + "christian-kohler.path-intellisense", + "christian-kohler.npm-intellisense", + "chakrounanas.turbo-console-log", + "pranaygp.vscode-css-peek", + "alefragnani.bookmarks", + "wallabyjs.console-ninja", + "pkief.material-icon-theme", + "github.copilot", + "bierner.markdown-mermaid", + "renesaarsoo.sql-formatter-vsc" + ] } diff --git a/ReneSaarsoo.sql-formatter-vsc-4.2.5.vsix b/ReneSaarsoo.sql-formatter-vsc-4.2.5.vsix new file mode 100644 index 0000000..27b8bc4 Binary files /dev/null and b/ReneSaarsoo.sql-formatter-vsc-4.2.5.vsix differ diff --git a/docs/8_lcbp3_v1_5_1.sql b/docs/8_lcbp3_v1_5_1.sql index 65f0609..8a82c37 100644 --- a/docs/8_lcbp3_v1_5_1.sql +++ b/docs/8_lcbp3_v1_5_1.sql @@ -20,16 +20,25 @@ -- 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 @@ -39,8 +48,11 @@ 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; @@ -48,20 +60,27 @@ DROP TABLE IF EXISTS user_preferences; 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 ไฟล์ -- ============================================================ @@ -72,58 +91,91 @@ DROP TABLE IF EXISTS attachments; -- ส่วนที่ 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; @@ -133,567 +185,586 @@ DROP TABLE IF EXISTS organizations; -- ===================================================== -- ตาราง 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)' + 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 + 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 + 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 + 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 + 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 = บทบาทของระบบ ลบไม่ได้)' + 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 'สถานะการใช้งาน' + 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 + 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 + 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 ) - 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 + 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 + 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 'สถานะการใช้งาน ' + 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 'สถานะการใช้งาน ' + 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) + 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), + 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 + 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 'วันที่แก้ไขล่าสุด ' + 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 + 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 + 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 + 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) + 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 + 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; +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; +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 'สถานะการใช้งาน ' + 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 'รหัสผลการอนุมัติ ( + 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 'สถานะการใช้งาน ' + 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 + 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; +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; +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, + 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 + 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) + 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) + 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) + 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 + 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) + 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 'วันที่แก้ไขล่าสุด ' + 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) + 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) + 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) + 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 + 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 'สถานะการใช้งาน ' + 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) + 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 + 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) + 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 (ไฟล์แนบ) @@ -703,73 +774,95 @@ CREATE TABLE transmittal_items ( -- รองรับ: 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 + 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 + 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 + 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 + 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 + 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) + 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) ล่าสุด @@ -782,46 +875,53 @@ CREATE TABLE document_number_formats ( -- รองรับ: 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 'องค์กรผู้ส่ง', - 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, - COALESCE(recipient_organization_id, 0), - -- [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, - -- [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 - ) + -- [v1.5.1] Composite Primary Key Columns (8 columns total) + project_id INT NOT NULL COMMENT 'โครงการ', + originator_organization_id INT NOT NULL COMMENT 'องค์กรผู้ส่ง', + 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, + COALESCE(recipient_organization_id, 0), + -- [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, + -- [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 + ) ) 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 สำหรับการสร้างเลขที่เอกสาร @@ -830,30 +930,30 @@ CREATE TABLE document_number_counters ( -- รองรับ: 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) + 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 @@ -862,34 +962,34 @@ CREATE TABLE document_number_audit ( -- รองรับ: 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 + 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) @@ -898,138 +998,167 @@ CREATE TABLE document_number_errors ( -- รองรับ: 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) + 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 + 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 'การกระทำ ( + 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) + 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 -); +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 '', + 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) + 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 -); +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 'วันที่สร้าง / อัปเดตัชนี ' + 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 'ข้อความผิดพลาด (ถ้ามี)' + 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 @@ -1038,83 +1167,106 @@ CREATE TABLE backup_logs ( -- ตัวอย่าง: ดึง 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); + 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); +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; +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; +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; + 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); +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) + 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); +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 + 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); + +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 + 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); + +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) -- ============================================================ @@ -1133,60 +1285,92 @@ CREATE INDEX idx_wf_hist_user ON workflow_histories(action_by_user_id); -- 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); +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); +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); +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); +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); +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); +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); +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); +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 +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); +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); +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); +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); +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 @@ -1196,105 +1380,115 @@ CREATE INDEX idx_audit_request_id ON audit_logs(request_id); -- ===================================================== -- 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; +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; +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; +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) -- ============================================================ @@ -1303,266 +1497,309 @@ WHERE c.is_active = TRUE; -- ============================================================ 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'; + 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 +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; + 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 +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 +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 +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; +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 +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 +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 +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; +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; +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); +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); +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; +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; \ No newline at end of file diff --git a/docs/8_lcbp3_v1_5_1_seed.sql b/docs/8_lcbp3_v1_5_1_seed.sql index 8472933..297a460 100644 --- a/docs/8_lcbp3_v1_5_1_seed.sql +++ b/docs/8_lcbp3_v1_5_1_seed.sql @@ -1,186 +1,534 @@ -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 Ltd.', 4), - ( 44, 'ผรม.4' , 'Contractor #4 Ltd.', 4), - ( 31, 'EN' , 'Third Party Environment', 5), - ( 32, 'CAR' , 'Third Party Fishery Care', 5); +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) งานก่อสร้าง' ); +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 ); +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 ); +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' , 'ผู้ดูแลสัญญา: จัดการสมาชิกในสัญญา, สร้าง / จัดการข้อมูลหลักเฉพาะสัญญา, และอนุมัติเอกสารในสัญญา' ); - +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' , 'มอบผู้ใช้งานให้กับองค์กร' ); +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' , 'ดูข้อมูลสัญญา' ); +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' , 'ปิดใบเวียน' ); +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)' ); +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' , 'สร้างรายงานสรุป (รายวัน / สัปดาห์ / เดือน / ปี)' ); +INSERT INTO permissions ( + permission_id, + permission_name, + description + ) +VALUES ( + 48, + 'search.advanced', + 'ใช้งานการค้นหาขั้นสูง' + ), + ( + 49, + 'report.generate', + 'สร้างรายงานสรุป (รายวัน / สัปดาห์ / เดือน / ปี)' + ); -- ========================================================== -- Seed Role-Permissions Mapping (จับคู่สิทธิ์เริ่มต้น) -- ========================================================== @@ -195,1563 +543,1927 @@ INSERT INTO permissions ( permission_id, permission_name, description ) VALUES -- This is a robust way to ensure Superadmin always has full power. INSERT INTO role_permissions (role_id, permission_id) SELECT 1, - permission_id + 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); + (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); + (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); + (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); + (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); + (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); + (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 ); +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 + SELECT id + FROM projects + WHERE project_code = 'LCBP3 ' + ), + id FROM organizations -WHERE organization_code in ( 'กทท.' , 'สคฉ.3' , 'TEAM' , 'คคง.' , 'ผรม.1' , 'ผรม.2' , 'ผรม.3' , 'ผรม.4' , 'EN' , 'CAR ' ); +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 + SELECT id + FROM projects + WHERE project_code = 'LCBP3-C1 ' + ), + id FROM organizations -WHERE organization_code in ( 'กทท.' , 'สคฉ.3' , 'สคฉ.3 -02' , 'คคง.' , 'ผรม.1 ' ); +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 + SELECT id + FROM projects + WHERE project_code = 'LCBP3-C2 ' + ), + id FROM organizations -WHERE organization_code in ( 'กทท.' , 'สคฉ.3' , 'สคฉ.3 -03' , 'คคง.' , 'ผรม.2 ' ); +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' ); +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' ); +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' ); +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' ); +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' ); +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 ); +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 ); +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 ) +INSERT INTO rfa_types ( + contract_id, + type_code, + type_name_en, + type_name_th + ) SELECT id, - 'ADW' , - 'As Built Drawing' , - 'แบบร่างหลังการก่อสร้าง' + 'ADW', + 'As Built Drawing', + 'แบบร่างหลังการก่อสร้าง' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'BC' , - 'Box Culvert' , - 'ท่อระบายน้ำรูปกล่อง' + 'BC', + 'Box Culvert', + 'ท่อระบายน้ำรูปกล่อง' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'BM' , - 'Benchmark' , - 'หมุดหลักฐาน' + 'BM', + 'Benchmark', + 'หมุดหลักฐาน' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'CER' , - 'Certificates' , - 'ใบรับรอง' + 'CER', + 'Certificates', + 'ใบรับรอง' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'CN' , - 'Canal Drainage' , - 'ระบบระบายน้ำในคลอง' + 'CN', + 'Canal Drainage', + 'ระบบระบายน้ำในคลอง' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'CON' , - 'Contract' , - 'สัญญา' + 'CON', + 'Contract', + 'สัญญา' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'DDS' , - 'Design Data Submission' , - 'นำส่งข้อมูลการออกแบบ' + 'DDS', + 'Design Data Submission', + 'นำส่งข้อมูลการออกแบบ' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'DDW' , - 'Draft Drawing' , - 'แบบร่าง' + 'DDW', + 'Draft Drawing', + 'แบบร่าง' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'DRW' , - 'Drawings (All Types)' , - 'แบบก่อสร้าง' + 'DRW', + 'Drawings (All Types)', + 'แบบก่อสร้าง' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'DSN' , - 'Design/Calculation/Manual (All Stages)' , - 'ออกแบบ / คำนวณ / คู่มือ' + 'DSN', + 'Design/Calculation/Manual (All Stages)', + 'ออกแบบ / คำนวณ / คู่มือ' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'GEN' , - 'General' , - 'ทั่วไป' + 'GEN', + 'General', + 'ทั่วไป' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'ICR' , - 'Incident Report' , - 'รายงานการเกิดอุบัติเหตุและการบาดเจ็บ' + 'ICR', + 'Incident Report', + 'รายงานการเกิดอุบัติเหตุและการบาดเจ็บ' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'INS' , - 'Insurances/Bond/Guarantee' , - 'การประกัน / พันธบัตร / การค้ำประกัน' + 'INS', + 'Insurances/Bond/Guarantee', + 'การประกัน / พันธบัตร / การค้ำประกัน' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'INR' , - 'Inspection/Audit/Surveillance Report' , - 'รายงานการตรวจสอบ / การตรวจสอบ / รายงานการเฝ้าระวัง' + 'INR', + 'Inspection/Audit/Surveillance Report', + 'รายงานการตรวจสอบ / การตรวจสอบ / รายงานการเฝ้าระวัง' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'ITP' , - 'Inspection and Test Plan' , - 'แผนการตรวจสอบและทดสอบ' + 'ITP', + 'Inspection and Test Plan', + 'แผนการตรวจสอบและทดสอบ' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'JSA' , - 'Jobs Analysis' , - 'รายงานการวิเคราะห์ความปลอดภัย' + 'JSA', + 'Jobs Analysis', + 'รายงานการวิเคราะห์ความปลอดภัย' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'MAN' , - 'Manual' , - 'คู่มือ' + 'MAN', + 'Manual', + 'คู่มือ' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'MAT' , - 'Materials/Equipment/Plant' , - 'วัสดุ / อุปกรณ์ / โรงงาน' + 'MAT', + 'Materials/Equipment/Plant', + 'วัสดุ / อุปกรณ์ / โรงงาน' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'MOM' , - 'Minutes of Meeting' , - 'รายงานการประชุม' + 'MOM', + 'Minutes of Meeting', + 'รายงานการประชุม' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'MPR' , - 'Monthly Progress Report' , - 'รายงานความคืบหน้าประจำเดือน' + 'MPR', + 'Monthly Progress Report', + 'รายงานความคืบหน้าประจำเดือน' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'MST' , - 'Method Statement for Construction/Installation' , - 'ขั้นตอนการก่อสร้าง / ติดตั้ง' + 'MST', + 'Method Statement for Construction/Installation', + 'ขั้นตอนการก่อสร้าง / ติดตั้ง' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'NDS' , - 'Non-Design Data Submission' , - 'นำส่งข้อมูลที่ไม่เกี่ยวข้องกับการออกแบบ' + 'NDS', + 'Non-Design Data Submission', + 'นำส่งข้อมูลที่ไม่เกี่ยวข้องกับการออกแบบ' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'PMA' , - 'Payment/Invoice/Retention/Estimate' , - 'การชำระเงิน / ใบแจ้งหนี้ / ประกันผลงาน / ประมาณการ' + 'PMA', + 'Payment/Invoice/Retention/Estimate', + 'การชำระเงิน / ใบแจ้งหนี้ / ประกันผลงาน / ประมาณการ' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'PRD' , - 'Procedure' , - 'ระเบียบปฏิบัติ' + 'PRD', + 'Procedure', + 'ระเบียบปฏิบัติ' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'PRG' , - 'Progress of Construction' , - 'ความคืบหน้าของการก่อสร้าง / ภาพถ่าย / วิดีโอ' + 'PRG', + 'Progress of Construction', + 'ความคืบหน้าของการก่อสร้าง / ภาพถ่าย / วิดีโอ' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'QMS' , - 'Quality Document (Plan/Work Instruction)' , - 'เอกสารด้านคุณภาพ (แผนงาน / ข้อแนะนำในการทำงาน)' + 'QMS', + 'Quality Document (Plan/Work Instruction)', + 'เอกสารด้านคุณภาพ (แผนงาน / ข้อแนะนำในการทำงาน)' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'RPT' , - 'Report' , - 'รายงาน' + 'RPT', + 'Report', + 'รายงาน' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'SAR' , - 'Semi Annual Report' , - 'รายงานประจำหกเดือน' + 'SAR', + 'Semi Annual Report', + 'รายงานประจำหกเดือน' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'SCH' , - 'Schedule and Program' , - 'แผนงาน' + 'SCH', + 'Schedule and Program', + 'แผนงาน' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'SDW' , - 'Shop Drawing' , - 'แบบขยายรายละเอียด' + 'SDW', + 'Shop Drawing', + 'แบบขยายรายละเอียด' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'SI' , - 'Soil Investigation' , - 'การตรวจสอบดิน' + 'SI', + 'Soil Investigation', + 'การตรวจสอบดิน' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'SPE' , - 'Specification' , - 'ข้อกำหนด' + 'SPE', + 'Specification', + 'ข้อกำหนด' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'TNR' , - 'Training Report' , - 'รายงานการฝึกปฏิบัติ' + 'TNR', + 'Training Report', + 'รายงานการฝึกปฏิบัติ' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'UC' , - 'Underground Construction' , - 'โครงสร้างใต้ดิน' + 'UC', + 'Underground Construction', + 'โครงสร้างใต้ดิน' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'VEN' , - 'Vendor' , - 'ผู้ขาย' + 'VEN', + 'Vendor', + 'ผู้ขาย' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'VRO' , - 'Variation Request/Instruction/Order' , - 'คำขอเปลี่ยนแปลง / ข้อเสนอแนะ / ข้อเรียกร้อง' + 'VRO', + 'Variation Request/Instruction/Order', + 'คำขอเปลี่ยนแปลง / ข้อเสนอแนะ / ข้อเรียกร้อง' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'WTY' , - 'Warranty' , - 'การประกัน' + 'WTY', + 'Warranty', + 'การประกัน' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'GEN' , - 'General' , - 'ทั่วไป' + 'GEN', + 'General', + 'ทั่วไป' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'CON' , - 'Contract' , - 'สัญญา' + 'CON', + 'Contract', + 'สัญญา' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'INS' , - 'Insurances/Bond/Guarantee' , - 'การประกัน / พันธบัตร / การค้ำประกัน' + 'INS', + 'Insurances/Bond/Guarantee', + 'การประกัน / พันธบัตร / การค้ำประกัน' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'SCH' , - 'Schedule and Program' , - 'แผนงาน' + 'SCH', + 'Schedule and Program', + 'แผนงาน' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'PMA' , - 'Payment/Invoice/Retention/Estimate' , - 'การชำระเงิน / ใบแจ้งหนี้ / ประกันผลงาน / ประมาณการ' + 'PMA', + 'Payment/Invoice/Retention/Estimate', + 'การชำระเงิน / ใบแจ้งหนี้ / ประกันผลงาน / ประมาณการ' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'VRO' , - 'Variation Request/Instruction/Order' , - 'คำขอเปลี่ยนแปลง / ข้อเสนอแนะ / ข้อเรียกร้อง' + 'VRO', + 'Variation Request/Instruction/Order', + 'คำขอเปลี่ยนแปลง / ข้อเสนอแนะ / ข้อเรียกร้อง' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'VEN' , - 'Vendor' , - 'ผู้ขาย' + 'VEN', + 'Vendor', + 'ผู้ขาย' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'WTY' , - 'Warranty' , - 'การประกัน' + 'WTY', + 'Warranty', + 'การประกัน' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'DRW' , - 'Drawings (All Types)' , - 'แบบก่อสร้าง' + 'DRW', + 'Drawings (All Types)', + 'แบบก่อสร้าง' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'DDW' , - 'Draft Drawing' , - 'แบบร่าง' + 'DDW', + 'Draft Drawing', + 'แบบร่าง' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'SDW' , - 'Shop Drawing' , - 'แบบขยายรายละเอียด' + 'SDW', + 'Shop Drawing', + 'แบบขยายรายละเอียด' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'ADW' , - 'As Built Drawing' , - 'แบบร่างหลังการก่อสร้าง' + 'ADW', + 'As Built Drawing', + 'แบบร่างหลังการก่อสร้าง' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'DDS' , - 'Design Data Submission' , - 'นำส่งข้อมูลการออกแบบ' + 'DDS', + 'Design Data Submission', + 'นำส่งข้อมูลการออกแบบ' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'DSN' , - 'Design/Calculation/Manual (All Stages)' , - 'ออกแบบ / คำนวณ / คู่มือ' + 'DSN', + 'Design/Calculation/Manual (All Stages)', + 'ออกแบบ / คำนวณ / คู่มือ' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'NDS' , - 'Non-Design Data Submission' , - 'นำส่งข้อมูลที่ไม่เกี่ยวข้องกับการออกแบบ' + 'NDS', + 'Non-Design Data Submission', + 'นำส่งข้อมูลที่ไม่เกี่ยวข้องกับการออกแบบ' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'PRD' , - 'Procedure' , - 'ระเบียบปฏิบัติ' + 'PRD', + 'Procedure', + 'ระเบียบปฏิบัติ' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'MST' , - 'Method Statement for Construction/Installation' , - 'ขั้นตอนการก่อสร้าง / ติดตั้ง' + 'MST', + 'Method Statement for Construction/Installation', + 'ขั้นตอนการก่อสร้าง / ติดตั้ง' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'QMS' , - 'Quality Document (Plan/Work Instruction)' , - 'เอกสารด้านคุณภาพ (แผนงาน / ข้อแนะนำในการทำงาน)' + 'QMS', + 'Quality Document (Plan/Work Instruction)', + 'เอกสารด้านคุณภาพ (แผนงาน / ข้อแนะนำในการทำงาน)' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'INR' , - 'Inspection/Audit/Surveillance Report' , - 'รายงานการตรวจสอบ / การตรวจสอบ / รายงานการเฝ้าระวัง' + 'INR', + 'Inspection/Audit/Surveillance Report', + 'รายงานการตรวจสอบ / การตรวจสอบ / รายงานการเฝ้าระวัง' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'ITP' , - 'Inspection and Test Plan' , - 'แผนการตรวจสอบและทดสอบ' + 'ITP', + 'Inspection and Test Plan', + 'แผนการตรวจสอบและทดสอบ' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'MAT' , - 'Materials/Equipment/Plant' , - 'วัสดุ / อุปกรณ์ / โรงงาน' + 'MAT', + 'Materials/Equipment/Plant', + 'วัสดุ / อุปกรณ์ / โรงงาน' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'SPE' , - 'Specification' , - 'ข้อกำหนด' + 'SPE', + 'Specification', + 'ข้อกำหนด' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'MAN' , - 'Manual' , - 'คู่มือ' + 'MAN', + 'Manual', + 'คู่มือ' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'CER' , - 'Certificates' , - 'ใบรับรอง' + 'CER', + 'Certificates', + 'ใบรับรอง' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'SAR' , - 'Semi Annual Report' , - 'รายงานประจำหกเดือน' + 'SAR', + 'Semi Annual Report', + 'รายงานประจำหกเดือน' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'JSA' , - 'Jobs Analysis' , - 'รายงานการวิเคราะห์ความปลอดภัย' + 'JSA', + 'Jobs Analysis', + 'รายงานการวิเคราะห์ความปลอดภัย' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'MOM' , - 'Minutes of Meeting' , - 'รายงานการประชุม' + 'MOM', + 'Minutes of Meeting', + 'รายงานการประชุม' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'MPR' , - 'Monthly Progress Report' , - 'รายงานความคืบหน้าประจำเดือน' + 'MPR', + 'Monthly Progress Report', + 'รายงานความคืบหน้าประจำเดือน' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'ICR' , - 'Incident Report' , - 'รายงานการเกิดอุบัติเหตุและการบาดเจ็บ' + 'ICR', + 'Incident Report', + 'รายงานการเกิดอุบัติเหตุและการบาดเจ็บ' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'PRG' , - 'Progress of Construction' , - 'ความคืบหน้าของการก่อสร้าง / ภาพถ่าย / วิดีโอ' + 'PRG', + 'Progress of Construction', + 'ความคืบหน้าของการก่อสร้าง / ภาพถ่าย / วิดีโอ' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'RPT' , - 'Report' , - 'รายงาน' + 'RPT', + 'Report', + 'รายงาน' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'TNR' , - 'Training Report' , - 'รายงานการฝึกปฏิบัติ' + '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 ); +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 ); +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 ) +INSERT INTO disciplines ( + contract_id, + discipline_code, + code_name_th, + code_name_en + ) SELECT id, - 'GEN' , - 'งานบริหารโครงการ' , - 'General Management' + 'GEN', + 'งานบริหารโครงการ', + 'General Management' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'COD' , - 'สัญญาและข้อโต้แย้ง' , - 'Contracting' + 'COD', + 'สัญญาและข้อโต้แย้ง', + 'Contracting' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'QSB' , - 'สำรวจปริมาณและควบคุมงบประมาณ' , - 'Quantity Survey and Budget Control' + 'QSB', + 'สำรวจปริมาณและควบคุมงบประมาณ', + 'Quantity Survey and Budget Control' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'PPG' , - 'บริหารแผนและความก้าวหน้า' , - 'Plan and Progress Management' + 'PPG', + 'บริหารแผนและความก้าวหน้า', + 'Plan and Progress Management' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'PRC' , - 'งานจัดซื้อ' , - 'Procurement' + 'PRC', + 'งานจัดซื้อ', + 'Procurement' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'SUB' , - 'ผู้รับเหมาช่วง' , - 'Subcontractor' + 'SUB', + 'ผู้รับเหมาช่วง', + 'Subcontractor' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'ODC' , - 'สำนักงาน-ควบคุมเอกสาร' , - 'Operation Docment Control' + 'ODC', + 'สำนักงาน-ควบคุมเอกสาร', + 'Operation Docment Control' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'LAW' , - 'กฎหมาย' , - 'Law' + 'LAW', + 'กฎหมาย', + 'Law' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'TRF' , - 'จราจร' , - 'Traffic' + 'TRF', + 'จราจร', + 'Traffic' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'BIM' , - 'BIM' , - 'Building information modeling' + 'BIM', + 'BIM', + 'Building information modeling' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'SRV' , - 'งานสำรวจ' , - 'Survey' + 'SRV', + 'งานสำรวจ', + 'Survey' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'SFT' , - 'ความปลอดภัย' , - 'Safety' + 'SFT', + 'ความปลอดภัย', + 'Safety' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'BST' , - 'งานโครงสร้างอาคาร' , - 'Building Structure Work' + 'BST', + 'งานโครงสร้างอาคาร', + 'Building Structure Work' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'TEM' , - 'งานชั่วคราว' , - 'Temporary Work' + 'TEM', + 'งานชั่วคราว', + 'Temporary Work' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'UTL' , - 'งานระบบสาธารณูปโภค' , - 'Utility' + 'UTL', + 'งานระบบสาธารณูปโภค', + 'Utility' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'EPW' , - 'งานระบบไฟฟ้า' , - 'Electrical Power Work' + 'EPW', + 'งานระบบไฟฟ้า', + 'Electrical Power Work' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'ECM' , - 'งานระบบไฟฟ้าสื่อสาร' , - 'Electrical Communication Work' + 'ECM', + 'งานระบบไฟฟ้าสื่อสาร', + 'Electrical Communication Work' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'ENV' , - 'สิ่งแวดล้อม' , - 'Environment' + 'ENV', + 'สิ่งแวดล้อม', + 'Environment' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'AQV' , - 'คุณภาพอากาศและความสั่นสะเทือน' , - 'Air quality and vibration' + 'AQV', + 'คุณภาพอากาศและความสั่นสะเทือน', + 'Air quality and vibration' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'WAB' , - 'คุณภาพน้ำและชีววิทยาทางน้ำ' , - 'Water quality and Aquatic biology' + 'WAB', + 'คุณภาพน้ำและชีววิทยาทางน้ำ', + 'Water quality and Aquatic biology' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'ONS' , - 'วิศวกรรมชายฝั่ง' , - 'Onshore Engineer Work' + 'ONS', + 'วิศวกรรมชายฝั่ง', + 'Onshore Engineer Work' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'PPR' , - 'มวลชนสัมพันธ์และการประชาสัมพันธ์' , - 'Public Relations' + 'PPR', + 'มวลชนสัมพันธ์และการประชาสัมพันธ์', + 'Public Relations' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'OSW' , - 'งานก่อสร้างงานทางทะเล' , - 'Offshore Work' + 'OSW', + 'งานก่อสร้างงานทางทะเล', + 'Offshore Work' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'DRE' , - 'งานขุดและถมทะเล' , - 'Dredging and Reclamation' + 'DRE', + 'งานขุดและถมทะเล', + 'Dredging and Reclamation' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'REV' , - 'งานคันหินล้อมพื้นที่ถมทะเล' , - 'Revetment' + 'REV', + 'งานคันหินล้อมพื้นที่ถมทะเล', + 'Revetment' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'BRW' , - 'งานเขื่อนกันคลื่น' , - 'Breakwater' + 'BRW', + 'งานเขื่อนกันคลื่น', + 'Breakwater' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'SOI' , - 'ปรับปรุงคุณภาพดิน' , - 'Soil Improvement' + 'SOI', + 'ปรับปรุงคุณภาพดิน', + 'Soil Improvement' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'BLC' , - 'งานปรับปรุงคลองบางละมุง' , - 'Bang Lamung Canal Bank Protection' + 'BLC', + 'งานปรับปรุงคลองบางละมุง', + 'Bang Lamung Canal Bank Protection' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'FUP' , - 'งานประตูระบายน้ำและท่อลอด' , - 'Floodgate & Under Ground Piping Works' + 'FUP', + 'งานประตูระบายน้ำและท่อลอด', + 'Floodgate & Under Ground Piping Works' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'SWP' , - 'งานอาคารควบคุมสถานีสูบน้ำทะเล' , - 'Sea Water Pumping Station Control BuilDing' + 'SWP', + 'งานอาคารควบคุมสถานีสูบน้ำทะเล', + 'Sea Water Pumping Station Control BuilDing' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'NAV' , - 'งานติดตั้งเครื่องหมายช่วงการเดินเรือ' , - 'Navigations Aids' + 'NAV', + 'งานติดตั้งเครื่องหมายช่วงการเดินเรือ', + 'Navigations Aids' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'GEO' , - 'งานด้านธรณีเทคนิค' , - 'Geotechnical' + 'GEO', + 'งานด้านธรณีเทคนิค', + 'Geotechnical' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'CRW' , - 'งานด้านโยธา - Rock Works' , - 'Civil-Rock work' + 'CRW', + 'งานด้านโยธา - Rock Works', + 'Civil-Rock work' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'DVR' , - 'ทีมนักประดาน้ำ' , - 'Dive Work' + 'DVR', + 'ทีมนักประดาน้ำ', + 'Dive Work' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'MTS' , - 'งานทดสอบวัสดุและธรณีเทคนิค' , - 'Materials and Geotechnical Testing' + 'MTS', + 'งานทดสอบวัสดุและธรณีเทคนิค', + 'Materials and Geotechnical Testing' FROM contracts WHERE contract_code = 'LCBP3-C1' -union all +UNION ALL SELECT id, - 'OTH' , - 'อื่นๆ' , - 'Other' + 'OTH', + 'อื่นๆ', + 'Other' FROM contracts WHERE contract_code = 'LCBP3-C1'; -- LCBP3-C2 -INSERT INTO disciplines ( contract_id, discipline_code, code_name_th, code_name_en ) +INSERT INTO disciplines ( + contract_id, + discipline_code, + code_name_th, + code_name_en + ) SELECT id, - 'GEN' , - 'งานบริหารโครงการ' , - 'Project Management' + 'GEN', + 'งานบริหารโครงการ', + 'Project Management' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'COD' , - 'สัญญาและข้อโต้แย้ง' , - 'Contracts and arguments' + 'COD', + 'สัญญาและข้อโต้แย้ง', + 'Contracts and arguments' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'QSB' , - 'สำรวจปริมาณและควบคุมงบประมาณ' , - 'Survey the quantity and control the budget' + 'QSB', + 'สำรวจปริมาณและควบคุมงบประมาณ', + 'Survey the quantity and control the budget' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'PPM' , - 'บริหารแผนและความก้าวหน้า' , - 'Plan Management & Progress' + 'PPM', + 'บริหารแผนและความก้าวหน้า', + 'Plan Management & Progress' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'ODC' , - 'สำนักงาน-ควบคุมเอกสาร' , - 'Document Control Office' + 'ODC', + 'สำนักงาน-ควบคุมเอกสาร', + 'Document Control Office' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'LAW' , - 'กฎหมาย' , - 'Law' + 'LAW', + 'กฎหมาย', + 'Law' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'TRF' , - 'จราจร' , - 'Traffic' + 'TRF', + 'จราจร', + 'Traffic' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'BIM' , - 'Building Information Modeling' , - 'Building Information Modeling' + 'BIM', + 'Building Information Modeling', + 'Building Information Modeling' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'SRV' , - 'งานสำรวจ' , - 'Survey' + 'SRV', + 'งานสำรวจ', + 'Survey' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'SFT' , - 'ความปลอดภัย' , - 'Safety' + 'SFT', + 'ความปลอดภัย', + 'Safety' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'BST' , - 'งานโครงสร้างอาคาร' , - 'Building Structure' + 'BST', + 'งานโครงสร้างอาคาร', + 'Building Structure' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'UTL' , - 'งานะบบสาธารณูปโภค' , - 'Public Utilities' + 'UTL', + 'งานะบบสาธารณูปโภค', + 'Public Utilities' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'EPW' , - 'งานระบบไฟฟ้า' , - 'Electrical Systems' + 'EPW', + 'งานระบบไฟฟ้า', + 'Electrical Systems' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'ECM' , - 'งานระบบไฟฟ้าสื่อสาร' , - 'Electrical Communication System' + 'ECM', + 'งานระบบไฟฟ้าสื่อสาร', + 'Electrical Communication System' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'ENV' , - 'สิ่งแวดล้อม' , - 'Environment' + 'ENV', + 'สิ่งแวดล้อม', + 'Environment' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'AQV' , - 'คุณภาพอากาศและความสั่นสะเทือน' , - 'Air Quality and Vibration' + 'AQV', + 'คุณภาพอากาศและความสั่นสะเทือน', + 'Air Quality and Vibration' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'WAB' , - 'คุณภาพน้ำและชีววิทยาทางน้ำ' , - 'Water Quality and Aquatic Biology' + 'WAB', + 'คุณภาพน้ำและชีววิทยาทางน้ำ', + 'Water Quality and Aquatic Biology' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'ONS' , - 'วิศวกรรมชายฝั่ง' , - 'Coastal Engineering' + 'ONS', + 'วิศวกรรมชายฝั่ง', + 'Coastal Engineering' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'PPR' , - 'มวลชนสัมพันธ์และประชาสัมพันธ์' , - 'Mass Relations and Public Relations' + 'PPR', + 'มวลชนสัมพันธ์และประชาสัมพันธ์', + 'Mass Relations and Public Relations' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'OFW' , - 'งานก่อสร้างทางทะเล' , - 'Marine Construction' + 'OFW', + 'งานก่อสร้างทางทะเล', + 'Marine Construction' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'EXR' , - 'งานขุดและถมทะเล' , - 'Excavation and reclamation' + 'EXR', + 'งานขุดและถมทะเล', + 'Excavation and reclamation' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'GEO' , - 'งานด้านธรณีเทคนิค' , - 'Geotechnical work' + 'GEO', + 'งานด้านธรณีเทคนิค', + 'Geotechnical work' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'CRW' , - 'งานด้านโยธา - Rock Works' , - 'Civil Works - Rock Works' + 'CRW', + 'งานด้านโยธา - Rock Works', + 'Civil Works - Rock Works' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'DVW' , - 'ทีมนักประดาน้ำ' , - 'Team of Divers' + 'DVW', + 'ทีมนักประดาน้ำ', + 'Team of Divers' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'MTT' , - 'งานทดสอบวัสดุ' , - 'Materials Testing' + 'MTT', + 'งานทดสอบวัสดุ', + 'Materials Testing' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'ARC' , - 'งานสถาปัตยกรรม' , - 'Architecture' + 'ARC', + 'งานสถาปัตยกรรม', + 'Architecture' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'STR' , - 'งานโครงสร้าง' , - 'Structural work' + 'STR', + 'งานโครงสร้าง', + 'Structural work' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'SAN' , - 'งานระบบสุขาภิบาล' , - 'Sanitation System' + 'SAN', + 'งานระบบสุขาภิบาล', + 'Sanitation System' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'DRA' , - 'งานระบบระบายน้ำ' , - 'Drainage system work' + 'DRA', + 'งานระบบระบายน้ำ', + 'Drainage system work' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'TER' , - 'งานท่าเทียบเรือ' , - 'Terminal Work work' + 'TER', + 'งานท่าเทียบเรือ', + 'Terminal Work work' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'BUD' , - 'งานอาคาร' , - 'Building' + 'BUD', + 'งานอาคาร', + 'Building' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'ROW' , - 'งานถนนและสะพาน' , - 'Road and Bridge Work' + 'ROW', + 'งานถนนและสะพาน', + 'Road and Bridge Work' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'MEC' , - 'งานเคริองกล' , - 'Mechanical work' + 'MEC', + 'งานเคริองกล', + 'Mechanical work' FROM contracts WHERE contract_code = 'LCBP3-C2' -union all +UNION ALL SELECT id, - 'OTH' , - 'อื่น ๆ' , - 'Others' + '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 -INSERT INTO correspondence_sub_types ( contract_id, correspondence_type_id, sub_type_code, sub_type_name, ) +INSERT INTO correspondence_sub_types ( + contract_id, + correspondence_type_id, + sub_type_code, + sub_type_name, + ) SELECT c.id, - ct.id, - 'MAT' , - 'Material Approval' , - '11' + ct.id, + 'MAT', + 'Material Approval', + '11' FROM contracts c, - correspondence_types ct + correspondence_types ct WHERE c.contract_code = 'LCBP3-C1' - and ct.type_code = 'RFA' -union all + AND ct.type_code = 'RFA' +UNION ALL SELECT c.id, - ct.id, - 'SHP' , - 'Shop Drawing Submittal' , - '12' + ct.id, + 'SHP', + 'Shop Drawing Submittal', + '12' FROM contracts c, - correspondence_types ct + correspondence_types ct WHERE c.contract_code = 'LCBP3-C1' - and ct.type_code = 'RFA' -union all + AND ct.type_code = 'RFA' +UNION ALL SELECT c.id, - ct.id, - 'DWG' , - 'Document Approval' , - '13' + ct.id, + 'DWG', + 'Document Approval', + '13' FROM contracts c, - correspondence_types ct + correspondence_types ct WHERE c.contract_code = 'LCBP3-C1' - and ct.type_code = 'RFA' -union all + AND ct.type_code = 'RFA' +UNION ALL SELECT c.id, - ct.id, - 'MET' , - 'Engineering Document Submittal' , - '14' + ct.id, + 'MET', + 'Engineering Document Submittal', + '14' FROM contracts c, - correspondence_types ct + correspondence_types ct WHERE c.contract_code = 'LCBP3-C1' - and ct.type_code = 'RFA'; + 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 ) +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' + ct.id, + 'MAT', + 'Material Approval', + '21' FROM contracts c, - correspondence_types ct + correspondence_types ct WHERE c.contract_code = 'LCBP3-C2' - and ct.type_code = 'RFA' -union all + AND ct.type_code = 'RFA' +UNION ALL SELECT c.id, - ct.id, - 'SHP' , - 'Shop Drawing Submittal' , - '22' + ct.id, + 'SHP', + 'Shop Drawing Submittal', + '22' FROM contracts c, - correspondence_types ct + correspondence_types ct WHERE c.contract_code = 'LCBP3-C2' - and ct.type_code = 'RFA' -union all + AND ct.type_code = 'RFA' +UNION ALL SELECT c.id, - ct.id, - 'DWG' , - 'Document Approval' , - '23' + ct.id, + 'DWG', + 'Document Approval', + '23' FROM contracts c, - correspondence_types ct + correspondence_types ct WHERE c.contract_code = 'LCBP3-C2' - and ct.type_code = 'RFA' -union all + AND ct.type_code = 'RFA' +UNION ALL SELECT c.id, - ct.id, - 'MET' , - 'Engineering Document Submittal' , - '24' + ct.id, + 'MET', + 'Engineering Document Submittal', + '24' FROM contracts c, - correspondence_types ct + correspondence_types ct WHERE c.contract_code = 'LCBP3-C2' - and ct.type_code = 'RFA'; + 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 ) +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' + ct.id, + 'MAT', + 'Material Approval', + '31' FROM contracts c, - correspondence_types ct + correspondence_types ct WHERE c.contract_code = 'LCBP3-C3' - and ct.type_code = 'RFA' -union all + AND ct.type_code = 'RFA' +UNION ALL SELECT c.id, - ct.id, - 'SHP' , - 'Shop Drawing Submittal' , - '32' + ct.id, + 'SHP', + 'Shop Drawing Submittal', + '32' FROM contracts c, - correspondence_types ct + correspondence_types ct WHERE c.contract_code = 'LCBP3-C3' - and ct.type_code = 'RFA' -union all + AND ct.type_code = 'RFA' +UNION ALL SELECT c.id, - ct.id, - 'DWG' , - 'Document Approval' , - '33' + ct.id, + 'DWG', + 'Document Approval', + '33' FROM contracts c, - correspondence_types ct + correspondence_types ct WHERE c.contract_code = 'LCBP3-C3' - and ct.type_code = 'RFA' -union all + AND ct.type_code = 'RFA' +UNION ALL SELECT c.id, - ct.id, - 'MET' , - 'Engineering Document Submittal' , - '34' + ct.id, + 'MET', + 'Engineering Document Submittal', + '34' FROM contracts c, - correspondence_types ct + correspondence_types ct WHERE c.contract_code = 'LCBP3-C4' - and ct.type_code = 'RFA'; + AND ct.type_code = 'RFA'; -- Note: 6B data has C4 on the right column for MET but C3 on left, checking logic... MD says C3 for first 3 rows, then C4 mixed. I will assume C4 starts at row 12 in the MD table. -- LCBP3-C4 -INSERT INTO correspondence_sub_types ( contract_id, correspondence_type_id, sub_type_code, sub_type_name, sub_type_number ) +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' + ct.id, + 'MAT', + 'Material Approval', + '41' FROM contracts c, - correspondence_types ct + correspondence_types ct WHERE c.contract_code = 'LCBP3-C4' - and ct.type_code = 'RFA' -union all + AND ct.type_code = 'RFA' +UNION ALL SELECT c.id, - ct.id, - 'SHP' , - 'Shop Drawing Submittal' , - '42' + ct.id, + 'SHP', + 'Shop Drawing Submittal', + '42' FROM contracts c, - correspondence_types ct + correspondence_types ct WHERE c.contract_code = 'LCBP3-C4' - and ct.type_code = 'RFA' -union all + AND ct.type_code = 'RFA' +UNION ALL SELECT c.id, - ct.id, - 'DWG' , - 'Document Approval' , - '43' + ct.id, + 'DWG', + 'Document Approval', + '43' FROM contracts c, - correspondence_types ct + correspondence_types ct WHERE c.contract_code = 'LCBP3-C4' - and ct.type_code = 'RFA' -union all + AND ct.type_code = 'RFA' +UNION ALL SELECT c.id, - ct.id, - 'MET' , - 'Engineering Document Submittal' , - '44' + ct.id, + 'MET', + 'Engineering Document Submittal', + '44' FROM contracts c, - correspondence_types ct + correspondence_types ct WHERE c.contract_code = 'LCBP3-C4' - and ct.type_code = 'RFA'; + AND ct.type_code = 'RFA'; diff --git a/lcbp3.code-workspace b/lcbp3.code-workspace index 6552246..4e80235 100644 --- a/lcbp3.code-workspace +++ b/lcbp3.code-workspace @@ -73,29 +73,18 @@ "editor.defaultFormatter": "dbaeumer.vscode-eslint" }, "[sql]": { - "editor.tabSize": 2, - "editor.insertSpaces": true + "editor.defaultFormatter": "renesaarsoo.sql-formatter-vsc" }, - "sqltools.codelensLanguages": ["sql"], - "sqltools.format": { - "language": "sql", - "params": { - "keywordCase": "upper", // ทำให้ INSERT, VALUES เป็นตัวใหญ่ - "reservedWordCase": "upper", // ทำให้คำสงวนเป็นตัวใหญ่ - "tabWidth": 2, // เยื้อง 2 ช่องว่าง - "expressionWidth": 100, // ความยาวสูงสุดต่อบรรทัดก่อนตีบรรทัดใหม่ (ป้องกันคอลัมน์แยกบรรทัด) - "logicalOperatorNewline": "before", - "aliasAs": "before", - "commaPosition": "after", - "linesBetweenQueries": 1, - "linesAroundComments": 0, - "tabulateAlias": false, - "newlineBeforeSemicolon": false, - "newlineBeforeOnClauseItems": false - } - }, - "sqltools.formatOnSave": true, - "sqltools.formatOnSaveLanguage": "sql", + "sql-formatter.dialect": "mysql", + "sql-formatter.indentStyle": "standard", + "sql-formatter.logicalOperatorNewline": "before", + "sql-formatter.expressionWidth": 120, + "sql-formatter.linesBetweenQueries": 2, + "sql-formatter.denseOperators": false, + "sql-formatter.newlineBeforeSemicolon": false, + "sql-formatter.keywordCase": "upper", + "sql-formatter.dataTypeCase": "upper", + "sql-formatter.functionCase": "upper", // ======================================== // CODE ACTION ON SAVE // ======================================== @@ -132,40 +121,40 @@ "path-intellisense.mappings": { // Backend paths - "@backend": "${workspaceFolder:🔧 Backend (NestJS)}/src", - "@backend/*": "${workspaceFolder:🔧 Backend (NestJS)}/src/*", - "@modules": "${workspaceFolder:🔧 Backend (NestJS)}/src/modules", - "@common": "${workspaceFolder:🔧 Backend (NestJS)}/src/common", - "@config": "${workspaceFolder:🔧 Backend (NestJS)}/src/common/config", - "@circulation": "${workspaceFolder:🔧 Backend (NestJS)}/src/modules/circulation", - "@correspondence": "${workspaceFolder:🔧 Backend (NestJS)}/src/modules/correspondence", - "@document-numbering": "${workspaceFolder:🔧 Backend (NestJS)}/src/modules/document-numbering", - "@drawing": "${workspaceFolder:🔧 Backend (NestJS)}/src/modules/drawing", - "@json-schema": "${workspaceFolder:🔧 Backend (NestJS)}/src/modules/json-schema", - "@master": "${workspaceFolder:🔧 Backend (NestJS)}/src/modules/master", - "@monitoring": "${workspaceFolder:🔧 Backend (NestJS)}/src/modules/monitoring", - "@notification": "${workspaceFolder:🔧 Backend (NestJS)}/src/modules/notification", - "@project": "${workspaceFolder:🔧 Backend (NestJS)}/src/modules/project", - "@rfa": "${workspaceFolder:🔧 Backend (NestJS)}/src/modules/rfa", - "@search": "${workspaceFolder:🔧 Backend (NestJS)}/src/modules/search", - "@transmittal": "${workspaceFolder:🔧 Backend (NestJS)}/src/modules/transmittal", - "@users": "${workspaceFolder:🔧 Backend (NestJS)}/src/modules/users", - "@workflow-engine": "${workspaceFolder:🔧 Backend (NestJS)}/src/modules/workflow-engine", + "@backend": "${workspaceFolder:🔧 Backend}/src", + "@backend/*": "${workspaceFolder:🔧 Backend}/src/*", + "@modules": "${workspaceFolder:🔧 Backend}/src/modules", + "@common": "${workspaceFolder:🔧 Backend}/src/common", + "@config": "${workspaceFolder:🔧 Backend}/src/common/config", + "@circulation": "${workspaceFolder:🔧 Backend}/src/modules/circulation", + "@correspondence": "${workspaceFolder:🔧 Backend}/src/modules/correspondence", + "@document-numbering": "${workspaceFolder:🔧 Backend}/src/modules/document-numbering", + "@drawing": "${workspaceFolder:🔧 Backend}/src/modules/drawing", + "@json-schema": "${workspaceFolder:🔧 Backend}/src/modules/json-schema", + "@master": "${workspaceFolder:🔧 Backend}/src/modules/master", + "@monitoring": "${workspaceFolder:🔧 Backend}/src/modules/monitoring", + "@notification": "${workspaceFolder:🔧 Backend}/src/modules/notification", + "@project": "${workspaceFolder:🔧 Backend}/src/modules/project", + "@rfa": "${workspaceFolder:🔧 Backend}/src/modules/rfa", + "@search": "${workspaceFolder:🔧 Backend}/src/modules/search", + "@transmittal": "${workspaceFolder:🔧 Backend}/src/modules/transmittal", + "@users": "${workspaceFolder:🔧 Backend}/src/modules/users", + "@workflow-engine": "${workspaceFolder:🔧 Backend}/src/modules/workflow-engine", // Frontend paths (ไม่มี src) - "@": "${workspaceFolder:🎨 Frontend (React/Next.js)}/app", - "@/*": "${workspaceFolder:🎨 Frontend (React/Next.js)}/app/*", - "@app": "${workspaceFolder:🎨 Frontend (React/Next.js)}/app", - "@components": "${workspaceFolder:🎨 Frontend (React/Next.js)}/components", - "@config": "${workspaceFolder:🎨 Frontend (React/Next.js)}/config", - "@lib": "${workspaceFolder:🎨 Frontend (React/Next.js)}/lib", - "@hooks": "${workspaceFolder:🎨 Frontend (React/Next.js)}/app/hooks", - "@utils": "${workspaceFolder:🎨 Frontend (React/Next.js)}/utils", - "@providers": "${workspaceFolder:🎨 Frontend (React/Next.js)}/providers", - "@public": "${workspaceFolder:🎨 Frontend (React/Next.js)}/public", - "@styles": "${workspaceFolder:🎨 Frontend (React/Next.js)}/styles", - "@types": "${workspaceFolder:🎨 Frontend (React/Next.js)}/types", - "@api": "${workspaceFolder:🎨 Frontend (React/Next.js)}/app/api" + "@": "${workspaceFolder:🎨 Frontend}/app", + "@/*": "${workspaceFolder:🎨 Frontend}/app/*", + "@app": "${workspaceFolder:🎨 Frontend}/app", + "@components": "${workspaceFolder:🎨 Frontend}/components", + "@config": "${workspaceFolder:🎨 Frontend}/config", + "@lib": "${workspaceFolder:🎨 Frontend}/lib", + "@hooks": "${workspaceFolder:🎨 Frontend}/app/hooks", + "@utils": "${workspaceFolder:🎨 Frontend}/utils", + "@providers": "${workspaceFolder:🎨 Frontend}/providers", + "@public": "${workspaceFolder:🎨 Frontend}/public", + "@styles": "${workspaceFolder:🎨 Frontend}/styles", + "@types": "${workspaceFolder:🎨 Frontend}/types", + "@api": "${workspaceFolder:🎨 Frontend}/app/api" }, "path-intellisense.autoSlashAfterDirectory": true, "path-intellisense.extensionOnImport": false, @@ -380,8 +369,10 @@ "typescript.inlayHints.variableTypes.enabled": false, "typescript.inlayHints.propertyDeclarationTypes.enabled": true, "typescript.preferences.importModuleSpecifier": "relative", - "typescript.tsdk": "node_modules/typescript/lib", - + "typescript.tsdk": { + "backend": "backend/node_modules/typescript/lib", + "frontend": "frontend/node_modules/typescript/lib" + }, // ======================================== // EMMET // ======================================== @@ -482,17 +473,6 @@ "workbench.editor.limit.enabled": true, "workbench.editor.limit.value": 10, "workbench.startupEditor": "welcomePage", - "workbench.colorCustomizations": { - "[One Dark Pro]": { - "activityBarBadge.background": "#FF8C00", - "list.activeSelectionForeground": "#FF8C00", - "list.inactiveSelectionForeground": "#FF8C00", - "list.highlightForeground": "#FF8C00", - "scrollbarSlider.activeBackground": "#FF8C0050", - "editorSuggestWidget.highlightForeground": "#FF8C00", - "textLink.foreground": "#FF8C00" - } - }, // ======================================== // EXPLORER // ======================================== @@ -548,8 +528,10 @@ "jest.pathToJest": "node_modules/.bin/jest", // กำหนด config ของ Jest ถ้ามีไฟล์ jest.config.js - "jest.pathToConfig": "jest.config.js", - + "jest.pathToConfig": { + "backend": "backend/jest.config.js", + "frontend": "frontend/jest.config.js" + }, "jest.disabledWorkspaceFolders": ["🎯 Root", "🗓️ docs", "🔗 specs"], // ======================================== @@ -674,13 +656,18 @@ "username": "root", "password": "Center#2025" } - ] + ], + "database-client.variableIndicator": [":", "$"], + "workbench.colorTheme": "Default Dark Modern", + "workbench.sideBar.location": "left", + "workbench.view.alwaysShowHeaderActions": true, + "workbench.view.showQuietly": { + "workbench.panel.output": false + } }, - // ======================================== // LAUNCH CONFIGURATIONS // ======================================== - "launch": { "version": "0.2.0", "configurations": [ @@ -736,11 +723,9 @@ } ] }, - // ======================================== // TASKS // ======================================== - "tasks": { "version": "2.0.0", "tasks": [ @@ -835,19 +820,6 @@ "command": "docker-compose down", "problemMatcher": [] }, - { - "label": "Start Backend", - "type": "shell", - "command": "npm run start:dev", - "options": { - "cwd": "${workspaceFolder:🔧 Backend}" - }, - "presentation": { - "panel": "dedicated", - "group": "dev", - "reveal": "always" - } - }, // 1. Task หลักที่จะรันอัตโนมัติเมื่อเปิดโปรแกรม { "label": "🚀 Setup Workspace", @@ -860,7 +832,6 @@ }, "problemMatcher": [] }, - // 2. Task ย่อย: เปิด Terminal ที่ Backend { "label": "🔧 PS: Backend", @@ -878,7 +849,6 @@ "focus": false // ไม่ต้องแย่ง Focus ทันที } }, - // 3. Task ย่อย: เปิด Terminal ที่ Frontend { "label": "🎨 PS: Frontend", @@ -897,47 +867,5 @@ } } ] - }, - - // ======================================== - // EXTENSIONS - // ======================================== - - "extensions": { - "recommendations": [ - "dbaeumer.vscode-eslint", - "esbenp.prettier-vscode", - "usernamehw.errorlens", - "yoavbls.pretty-typescript-errors", - "wix.vscode-import-cost", - "aaron-bond.better-comments", - "gruntfuggly.todo-tree", - "ashinzekene.nestjs", - "dsznajder.es7-react-js-snippets", - "orta.vscode-jest", - "bradlc.vscode-tailwindcss", - "heybourn.headwind", - "prisma.prisma", - "rangav.vscode-thunder-client", - "humao.rest-client", - "formulahendry.auto-close-tag", - "formulahendry.auto-rename-tag", - "ms-azuretools.vscode-docker", - "mtxr.sqltools", - "redhat.vscode-yaml", - "mikestead.dotenv", - "editorconfig.editorconfig", - "eamodio.gitlens", - "mhutchie.git-graph", - "vivaxy.vscode-conventional-commits", - "christian-kohler.path-intellisense", - "christian-kohler.npm-intellisense", - "pranaygp.vscode-css-peek", - "alefragnani.bookmarks", - "chakrounanas.turbo-console-log", - "wallabyjs.console-ninja", - "pkief.material-icon-theme", - "github.copilot" - ] } }