diff --git a/01_lcbp3_v1_4_2.sql b/01_lcbp3_v1_4_2.sql index 46498bf..c799845 100644 --- a/01_lcbp3_v1_4_2.sql +++ b/01_lcbp3_v1_4_2.sql @@ -24,7 +24,7 @@ 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 PROCEDURE IF EXISTS sp_get_next_document_number; -- 🗑ïļ DROP TABLE SCRIPT: LCBP3-DMS v1.4.2 -- āļ„āļģāđ€āļ•āļ·āļ­āļ™: āļ‚āđ‰āļ­āļĄāļđāļĨāļ—āļąāđ‰āļ‡āļŦāļĄāļ”āļˆāļ°āļŦāļēāļĒāđ„āļ› āļāļĢāļļāļ“āļē Backup āļāđˆāļ­āļ™āļĢāļąāļ™āļšāļ™ Production SET FOREIGN_KEY_CHECKS = 0; @@ -36,7 +36,8 @@ DROP TABLE IF EXISTS search_indices; DROP TABLE IF EXISTS notifications; DROP TABLE IF EXISTS audit_logs; -- [NEW v1.4.2] āļ•āļēāļĢāļēāļ‡āļāļēāļĢāļ•āļąāđ‰āļ‡āļ„āđˆāļēāļŠāđˆāļ§āļ™āļ•āļąāļ§āļ‚āļ­āļ‡āļœāļđāđ‰āđƒāļŠāđ‰ (FK -> users) -DROP TABLE IF EXISTS user_preferencesāļ§ -- [NEW v1.4.2] āļ•āļēāļĢāļēāļ‡āđ€āļāđ‡āļš Schema āļŠāļģāļŦāļĢāļąāļš Validate JSON (Stand-alone) +DROP TABLE IF EXISTS user_preferences; +-- [NEW v1.4.2] āļ•āļēāļĢāļēāļ‡āđ€āļāđ‡āļš Schema āļŠāļģāļŦāļĢāļąāļš Validate JSON (Stand-alone) DROP TABLE IF EXISTS json_schemas; -- ============================================================ -- āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 2: āļ•āļēāļĢāļēāļ‡ Junction (āđ€āļŠāļ·āđˆāļ­āļĄāđ‚āļĒāļ‡āļ‚āđ‰āļ­āļĄāļđāļĨ M:N) @@ -131,248 +132,249 @@ 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 āđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨāļ­āļ‡āļ„āđŒāļāļĢāļ—āļąāđ‰āļ‡āļŦāļĄāļ”āļ—āļĩāđˆāđ€āļāļĩāđˆāļĒāļ§āļ‚āđ‰āļ­āļ‡āđƒāļ™āļĢāļ°āļšāļš'; -- Seed organization INSERT INTO organizations (id, organization_code, organization_name) VALUES (1, 'āļāļ—āļ—.', 'āļāļēāļĢāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāđˆāļ‡āļ›āļĢāļ°āđ€āļ—āļĻāđ„āļ—āļĒ'), - ( - 10, - 'āļŠāļ„āļ‰.3', - 'āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3' - ), - ( - 11, - 'āļŠāļ„āļ‰.3-01', - 'āļ•āļĢāļ§āļˆāļĢāļąāļšāļžāļąāļŠāļ”āļļ āļ—āļĩāđˆāļ›āļĢāļķāļāļĐāļēāļ„āļ§āļšāļ„āļļāļĄāļ‡āļēāļ™' - ), - (12, 'āļŠāļ„āļ‰.3-02', 'āļ•āļĢāļ§āļˆāļĢāļąāļšāļžāļąāļŠāļ”āļļ āļ‡āļēāļ™āļ—āļēāļ‡āļ—āļ°āđ€āļĨ'), - ( - 13, - 'āļŠāļ„āļ‰.3-03', - 'āļ•āļĢāļ§āļˆāļĢāļąāļšāļžāļąāļŠāļ”āļļ āļ­āļēāļ„āļēāļĢāđāļĨāļ°āļĢāļ°āļšāļšāļŠāļēāļ˜āļēāļĢāļ“āļđāļ›āđ‚āļ āļ„' - ), - ( - 14, - 'āļŠāļ„āļ‰.3-04', - 'āļ•āļĢāļ§āļˆāļĢāļąāļšāļžāļąāļŠāļ”āļļ āļ•āļĢāļ§āļˆāļŠāļ­āļšāļœāļĨāļāļĢāļ°āļ—āļšāļŠāļīāđˆāļ‡āđāļ§āļ”āļĨāđ‰āļ­āļĄ' - ), - (15, 'āļŠāļ„āļ‰.3-05', 'āļ•āļĢāļ§āļˆāļĢāļąāļšāļžāļąāļŠāļ”āļļ āđ€āļĒāļĩāļĒāļ§āļĒāļēāļāļēāļĢāļ›āļĢāļ°āļĄāļ‡'), - ( - 16, - 'āļŠāļ„āļ‰.3-06', - 'āļ•āļĢāļ§āļˆāļĢāļąāļšāļžāļąāļŠāļ”āļļ āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 3' - ), - ( - 17, - 'āļŠāļ„āļ‰.3-07', - 'āļ•āļĢāļ§āļˆāļĢāļąāļšāļžāļąāļŠāļ”āļļ āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 4' - ), - ( - 18, - 'āļŠāļ„āļ‰.3-xx', - 'āļ•āļĢāļ§āļˆāļĢāļąāļšāļžāļąāļŠāļ”āļļ āļ—āļĩāđˆāļ›āļĢāļķāļāļĐāļēāļ­āļ­āļāđāļšāļš āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 4' - ), - (21, 'TEAM', 'Designer Consulting Ltd.'), - (22, 'āļ„āļ„āļ‡.', 'Construction Supervision Ltd.'), - (41, 'āļœāļĢāļĄ.1', 'Contractor āļ‡āļēāļ™āļ—āļēāļ‡āļ—āļ°āđ€āļĨ'), - (42, 'āļœāļĢāļĄ.2', 'Contractor āļ­āļēāļ„āļēāļĢāđāļĨāļ°āļĢāļ°āļšāļš'), - (43, 'āļœāļĢāļĄ.3', 'Contractor #3 Ltd.'), - (44, 'āļœāļĢāļĄ.4', 'Contractor #4 Ltd.'), - (31, 'EN', 'Third Party Environment'), - (32, 'CAR', 'Third Party Fishery Care'); + ( + 10, + 'āļŠāļ„āļ‰.3', + 'āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3' + ), + ( + 11, + 'āļŠāļ„āļ‰.3-01', + 'āļ•āļĢāļ§āļˆāļĢāļąāļšāļžāļąāļŠāļ”āļļ āļ—āļĩāđˆāļ›āļĢāļķāļāļĐāļēāļ„āļ§āļšāļ„āļļāļĄāļ‡āļēāļ™' + ), + (12, 'āļŠāļ„āļ‰.3-02', 'āļ•āļĢāļ§āļˆāļĢāļąāļšāļžāļąāļŠāļ”āļļ āļ‡āļēāļ™āļ—āļēāļ‡āļ—āļ°āđ€āļĨ'), + ( + 13, + 'āļŠāļ„āļ‰.3-03', + 'āļ•āļĢāļ§āļˆāļĢāļąāļšāļžāļąāļŠāļ”āļļ āļ­āļēāļ„āļēāļĢāđāļĨāļ°āļĢāļ°āļšāļšāļŠāļēāļ˜āļēāļĢāļ“āļđāļ›āđ‚āļ āļ„' + ), + ( + 14, + 'āļŠāļ„āļ‰.3-04', + 'āļ•āļĢāļ§āļˆāļĢāļąāļšāļžāļąāļŠāļ”āļļ āļ•āļĢāļ§āļˆāļŠāļ­āļšāļœāļĨāļāļĢāļ°āļ—āļšāļŠāļīāđˆāļ‡āđāļ§āļ”āļĨāđ‰āļ­āļĄ' + ), + (15, 'āļŠāļ„āļ‰.3-05', 'āļ•āļĢāļ§āļˆāļĢāļąāļšāļžāļąāļŠāļ”āļļ āđ€āļĒāļĩāļĒāļ§āļĒāļēāļāļēāļĢāļ›āļĢāļ°āļĄāļ‡'), + ( + 16, + 'āļŠāļ„āļ‰.3-06', + 'āļ•āļĢāļ§āļˆāļĢāļąāļšāļžāļąāļŠāļ”āļļ āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 3' + ), + ( + 17, + 'āļŠāļ„āļ‰.3-07', + 'āļ•āļĢāļ§āļˆāļĢāļąāļšāļžāļąāļŠāļ”āļļ āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 4' + ), + ( + 18, + 'āļŠāļ„āļ‰.3-xx', + 'āļ•āļĢāļ§āļˆāļĢāļąāļšāļžāļąāļŠāļ”āļļ āļ—āļĩāđˆāļ›āļĢāļķāļāļĐāļēāļ­āļ­āļāđāļšāļš āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 4' + ), + (21, 'TEAM', 'Designer Consulting Ltd.'), + (22, 'āļ„āļ„āļ‡.', 'Construction Supervision Ltd.'), + (41, 'āļœāļĢāļĄ.1', 'Contractor āļ‡āļēāļ™āļ—āļēāļ‡āļ—āļ°āđ€āļĨ'), + (42, 'āļœāļĢāļĄ.2', 'Contractor āļ­āļēāļ„āļēāļĢāđāļĨāļ°āļĢāļ°āļšāļš'), + (43, 'āļœāļĢāļĄ.3', 'Contractor #3 Ltd.'), + (44, 'āļœāļĢāļĄ.4', 'Contractor #4 Ltd.'), + (31, 'EN', 'Third Party Environment'), + (32, 'CAR', 'Third Party Fishery Care'); -- āļ•āļēāļĢāļēāļ‡ 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 āđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨāđ‚āļ„āļĢāļ‡āļāļēāļĢ'; INSERT INTO projects (project_code, project_name) VALUES ( - 'LCBP3', - 'āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 1-4)' - ), - ( - 'LCBP3C1', - 'āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 1) āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡āļ‡āļēāļ™āļ—āļēāļ‡āļ—āļ°āđ€āļĨ' - ), - ( - 'LCBP3C2', - 'āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 2) āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡āļ­āļēāļ„āļēāļĢ āļ—āđˆāļēāđ€āļ—āļĩāļĒāļšāđ€āļĢāļ·āļ­ āļĢāļ°āļšāļšāļ–āļ™āļ™ āđāļĨāļ°āļĢāļ°āļšāļšāļŠāļēāļ˜āļēāļĢāļ“āļđāļ›āđ‚āļ āļ„' - ), - ( - 'LCBP3C3', - 'āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 3) āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡' - ), - ( - 'LCBP3C4', - 'āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 4) āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡' - ); + 'LCBP3', + 'āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 1-4)' + ), + ( + 'LCBP3C1', + 'āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 1) āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡āļ‡āļēāļ™āļ—āļēāļ‡āļ—āļ°āđ€āļĨ' + ), + ( + 'LCBP3C2', + 'āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 2) āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡āļ­āļēāļ„āļēāļĢ āļ—āđˆāļēāđ€āļ—āļĩāļĒāļšāđ€āļĢāļ·āļ­ āļĢāļ°āļšāļšāļ–āļ™āļ™ āđāļĨāļ°āļĢāļ°āļšāļšāļŠāļēāļ˜āļēāļĢāļ“āļđāļ›āđ‚āļ āļ„' + ), + ( + 'LCBP3C3', + 'āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 3) āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡' + ), + ( + 'LCBP3C4', + 'āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 4) āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡' + ); -- āļ•āļēāļĢāļēāļ‡ 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 āđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨāļŠāļąāļāļāļē'; -- āđƒāļŠāđ‰ Subquery āđ€āļžāļ·āđˆāļ­āļ”āļķāļ‡ project_id āļĄāļēāđ€āļŠāļ·āđˆāļ­āļĄāđ‚āļĒāļ‡ āļ—āļģāđƒāļŦāđ‰āđ„āļĄāđˆāļ•āđ‰āļ­āļ‡āļĄāļēāļ™āļąāđˆāļ‡āļˆāļąāļ”āļāļēāļĢ ID āļ”āđ‰āļ§āļĒāļ•āļąāļ§āđ€āļ­āļ‡ INSERT INTO contracts ( - contract_code, - contract_name, - project_id, - is_active - ) + contract_code, + contract_name, + project_id, + is_active + ) VALUES ( - 'DSLCBP3', - 'āļ‡āļēāļ™āļˆāđ‰āļēāļ‡āļ—āļĩāđˆāļ›āļĢāļĩāļāļĐāļēāļ­āļ­āļāđāļšāļš āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 1-4)', - ( - SELECT id - FROM projects - WHERE project_code = 'LCBP3' - ), - TRUE - ), + 'DSLCBP3', + 'āļ‡āļēāļ™āļˆāđ‰āļēāļ‡āļ—āļĩāđˆāļ›āļĢāļĩāļāļĐāļēāļ­āļ­āļāđāļšāļš āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 1-4)', ( - 'PSLCBP3', - 'āļ‡āļēāļ™āļˆāđ‰āļēāļ‡āļ—āļĩāđˆāļ›āļĢāļĩāļāļĐāļēāļ„āļ§āļšāļ„āļļāļĄāļ‡āļēāļ™ āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 1-4)', - ( - SELECT id - FROM projects - WHERE project_code = 'LCBP3' - ), - TRUE + SELECT id + FROM projects + WHERE project_code = 'LCBP3' ), + TRUE + ), + ( + 'PSLCBP3', + 'āļ‡āļēāļ™āļˆāđ‰āļēāļ‡āļ—āļĩāđˆāļ›āļĢāļĩāļāļĐāļēāļ„āļ§āļšāļ„āļļāļĄāļ‡āļēāļ™ āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 1-4)', ( - 'LCBP3-C1', - 'āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 1) āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡āļ‡āļēāļ™āļ—āļēāļ‡āļ—āļ°āđ€āļĨ', - ( - SELECT id - FROM projects - WHERE project_code = 'LCBP3C1' - ), - TRUE + SELECT id + FROM projects + WHERE project_code = 'LCBP3' ), + TRUE + ), + ( + 'LCBP3-C1', + 'āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 1) āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡āļ‡āļēāļ™āļ—āļēāļ‡āļ—āļ°āđ€āļĨ', ( - 'LCBP3-C2', - 'āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 2) āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡āļ­āļēāļ„āļēāļĢ āļ—āđˆāļēāđ€āļ—āļĩāļĒāļšāđ€āļĢāļ·āļ­ āļĢāļ°āļšāļšāļ–āļ™āļ™ āđāļĨāļ°āļĢāļ°āļšāļšāļŠāļēāļ˜āļēāļĢāļ“āļđāļ›āđ‚āļ āļ„', - ( - SELECT id - FROM projects - WHERE project_code = 'LCBP3C2' - ), - TRUE + SELECT id + FROM projects + WHERE project_code = 'LCBP3C1' ), + TRUE + ), + ( + 'LCBP3-C2', + 'āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 2) āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡āļ­āļēāļ„āļēāļĢ āļ—āđˆāļēāđ€āļ—āļĩāļĒāļšāđ€āļĢāļ·āļ­ āļĢāļ°āļšāļšāļ–āļ™āļ™ āđāļĨāļ°āļĢāļ°āļšāļšāļŠāļēāļ˜āļēāļĢāļ“āļđāļ›āđ‚āļ āļ„', ( - 'LCBP3-C3', - 'āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 3) āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡', - ( - SELECT id - FROM projects - WHERE project_code = 'LCBP3C3' - ), - TRUE + SELECT id + FROM projects + WHERE project_code = 'LCBP3C2' ), + TRUE + ), + ( + 'LCBP3-C3', + 'āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 3) āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡', ( - 'LCBP3-C4', - 'āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 4) āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡', - ( - SELECT id - FROM projects - WHERE project_code = 'LCBP3C4' - ), - TRUE + SELECT id + FROM projects + WHERE project_code = 'LCBP3C3' ), + TRUE + ), + ( + 'LCBP3-C4', + 'āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡ āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 4) āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡', ( - 'ENLCBP3', - 'āļ‡āļēāļ™āļˆāđ‰āļēāļ‡āđ€āļŦāļĄāļēāļ•āļĢāļ§āļˆāļŠāļ­āļšāļœāļĨāļāļĢāļ°āļ—āļšāļŠāļīāđˆāļ‡āđāļ§āļ”āļĨāđ‰āļ­āļĄāļ™āļ°āļŦāļ§āđˆāļēāļ‡āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 1-4)', - ( - SELECT id - FROM projects - WHERE project_code = 'LCBP3' - ), - TRUE - ); + SELECT id + FROM projects + WHERE project_code = 'LCBP3C4' + ), + TRUE + ), + ( + 'ENLCBP3', + 'āļ‡āļēāļ™āļˆāđ‰āļēāļ‡āđ€āļŦāļĄāļēāļ•āļĢāļ§āļˆāļŠāļ­āļšāļœāļĨāļāļĢāļ°āļ—āļšāļŠāļīāđˆāļ‡āđāļ§āļ”āļĨāđ‰āļ­āļĄāļ™āļ°āļŦāļ§āđˆāļēāļ‡āļ‡āļēāļ™āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡āđ‚āļ„āļĢāļ‡āļāļēāļĢāļžāļąāļ’āļ™āļēāļ—āđˆāļēāđ€āļĢāļ·āļ­āđāļŦāļĨāļĄāļ‰āļšāļąāļ‡ āļĢāļ°āļĒāļ°āļ—āļĩāđˆ 3 (āļŠāđˆāļ§āļ™āļ—āļĩāđˆ 1-4)', + ( + SELECT id + FROM projects + WHERE project_code = 'LCBP3' + ), + TRUE + ); -- ===================================================== -- 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 'āļ§āļąāļ™āļ—āļĩāđˆāđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', - 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)'; -- Initial SUPER_ADMIN user INSERT INTO users (username, password_hash, email, is_active) VALUES ( - 'superadmin', - '$2y$10$0kjBMxWq7E4G7P.dc8r5i.cjiPBiup553AsFpDfxUt31gKg9h/udq', - 'superadmin@example.com', - 1 - ) ON DUPLICATE KEY + 'superadmin', + '$2y$10$0kjBMxWq7E4G7P.dc8r5i.cjiPBiup553AsFpDfxUt31gKg9h', + 'superadmin @example.com', + 1 + ) ON DUPLICATE KEY UPDATE email = VALUES(email), - is_active = + is_active = VALUES(is_active); -- Create editor01 user INSERT IGNORE INTO users (username, password_hash, email, is_active) VALUES ( - 'editor01', - '$2y$10$0kjBMxWq7E4G7P.dc8r5i.cjiPBiup553AsFpDfxUt31gKg9h/udq', - 'editor01@example.com', - 1 - ); + 'editor01', + '$2y$10$0kjBMxWq7E4G7P.dc8r5i.cjiPBiup553AsFpDfxUt31gKg9h', + 'editor01 @example.com', + 1 + ); -- Create viewer01 user (password hash placeholder, must change later) INSERT IGNORE INTO users (username, password_hash, email, is_active) VALUES ( - 'viewer01', - '$2y$10$0kjBMxWq7E4G7P.dc8r5i.cjiPBiup553AsFpDfxUt31gKg9h/udq', - 'viewer01@example.com', - 1 - ); + 'viewer01', + '$2y$10$0kjBMxWq7E4G7P.dc8r5i.cjiPBiup553AsFpDfxUt31gKg9h', + 'viewer01 @example.com', + 1 + ); -- āļ•āļēāļĢāļēāļ‡ 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 āđ€āļāđ‡āļš "āļšāļ—āļšāļēāļ—" āļ‚āļ­āļ‡āļœāļđāđ‰āđƒāļŠāđ‰āđƒāļ™āļĢāļ°āļšāļš'; -- ========================================================== -- Seed Roles (āļšāļ—āļšāļēāļ—āļžāļ·āđ‰āļ™āļāļēāļ™ 5 āļšāļ—āļšāļēāļ— āļ•āļēāļĄ Req 4.3) @@ -380,67 +382,67 @@ CREATE TABLE roles ( -- 1. Superadmin (Global) INSERT INTO roles (role_id, role_name, scope, description) VALUES ( - 1, - 'Superadmin', - 'Global', - 'āļœāļđāđ‰āļ”āļđāđāļĨāļĢāļ°āļšāļšāļŠāļđāļ‡āļŠāļļāļ”: āļŠāļēāļĄāļēāļĢāļ–āļ—āļģāļ—āļļāļāļ­āļĒāđˆāļēāļ‡āđƒāļ™āļĢāļ°āļšāļš, āļˆāļąāļ”āļāļēāļĢāļ­āļ‡āļ„āđŒāļāļĢ, āđāļĨāļ°āļˆāļąāļ”āļāļēāļĢāļ‚āđ‰āļ­āļĄāļđāļĨāļŦāļĨāļąāļāļĢāļ°āļ”āļąāļš Global' - ); + 1, + 'Superadmin', + 'Global', + 'āļœāļđāđ‰āļ”āļđāđāļĨāļĢāļ°āļšāļšāļŠāļđāļ‡āļŠāļļāļ”: āļŠāļēāļĄāļēāļĢāļ–āļ—āļģāļ—āļļāļāļ­āļĒāđˆāļēāļ‡āđƒāļ™āļĢāļ°āļšāļš, āļˆāļąāļ”āļāļēāļĢāļ­āļ‡āļ„āđŒāļāļĢ, āđāļĨāļ°āļˆāļąāļ”āļāļēāļĢāļ‚āđ‰āļ­āļĄāļđāļĨāļŦāļĨāļąāļāļĢāļ°āļ”āļąāļš Global' + ); -- 2. Org Admin (Organization) INSERT INTO roles (role_id, role_name, scope, description) VALUES ( - 2, - 'Org Admin', - 'Organization', - 'āļœāļđāđ‰āļ”āļđāđāļĨāļ­āļ‡āļ„āđŒāļāļĢ: āļˆāļąāļ”āļāļēāļĢāļœāļđāđ‰āđƒāļŠāđ‰āđƒāļ™āļ­āļ‡āļ„āđŒāļāļĢ, āļˆāļąāļ”āļāļēāļĢāļšāļ—āļšāļēāļ—/āļŠāļīāļ—āļ˜āļīāđŒāļ āļēāļĒāđƒāļ™āļ­āļ‡āļ„āđŒāļāļĢ, āđāļĨāļ°āļ”āļđāļĢāļēāļĒāļ‡āļēāļ™āļ‚āļ­āļ‡āļ­āļ‡āļ„āđŒāļāļĢ' - ); + 2, + 'Org Admin', + 'Organization', + 'āļœāļđāđ‰āļ”āļđāđāļĨāļ­āļ‡āļ„āđŒāļāļĢ: āļˆāļąāļ”āļāļēāļĢāļœāļđāđ‰āđƒāļŠāđ‰āđƒāļ™āļ­āļ‡āļ„āđŒāļāļĢ, āļˆāļąāļ”āļāļēāļĢāļšāļ—āļšāļēāļ— / āļŠāļīāļ—āļ˜āļīāđŒāļ āļēāļĒāđƒāļ™āļ­āļ‡āļ„āđŒāļāļĢ, āđāļĨāļ°āļ”āļđāļĢāļēāļĒāļ‡āļēāļ™āļ‚āļ­āļ‡āļ­āļ‡āļ„āđŒāļāļĢ' + ); -- 3. Document Control (Organization) INSERT INTO roles (role_id, role_name, scope, description) VALUES ( - 3, - 'Document Control', - 'Organization', - 'āļ„āļ§āļšāļ„āļļāļĄāđ€āļ­āļāļŠāļēāļĢāļ‚āļ­āļ‡āļ­āļ‡āļ„āđŒāļāļĢ: āđ€āļžāļīāđˆāļĄ/āđāļāđ‰āđ„āļ‚/āļĨāļšāđ€āļ­āļāļŠāļēāļĢ, āđāļĨāļ°āļāļģāļŦāļ™āļ”āļŠāļīāļ—āļ˜āļīāđŒāđ€āļ­āļāļŠāļēāļĢāļ āļēāļĒāđƒāļ™āļ­āļ‡āļ„āđŒāļāļĢ' - ); + 3, + 'Document Control', + 'Organization', + 'āļ„āļ§āļšāļ„āļļāļĄāđ€āļ­āļāļŠāļēāļĢāļ‚āļ­āļ‡āļ­āļ‡āļ„āđŒāļāļĢ: āđ€āļžāļīāđˆāļĄ / āđāļāđ‰āđ„āļ‚ / āļĨāļšāđ€āļ­āļāļŠāļēāļĢ, āđāļĨāļ°āļāļģāļŦāļ™āļ”āļŠāļīāļ—āļ˜āļīāđŒāđ€āļ­āļāļŠāļēāļĢāļ āļēāļĒāđƒāļ™āļ­āļ‡āļ„āđŒāļāļĢ' + ); -- 4. Editor (Organization) INSERT INTO roles (role_id, role_name, scope, description) VALUES ( - 4, - 'Editor', - 'Organization', - 'āļœāļđāđ‰āđāļāđ‰āđ„āļ‚āđ€āļ­āļāļŠāļēāļĢāļ‚āļ­āļ‡āļ­āļ‡āļ„āđŒāļāļĢ: āđ€āļžāļīāđˆāļĄ/āđāļāđ‰āđ„āļ‚āđ€āļ­āļāļŠāļēāļĢāļ—āļĩāđˆāđ„āļ”āđ‰āļĢāļąāļšāļĄāļ­āļšāļŦāļĄāļēāļĒ' - ); + 4, + 'Editor', + 'Organization', + 'āļœāļđāđ‰āđāļāđ‰āđ„āļ‚āđ€āļ­āļāļŠāļēāļĢāļ‚āļ­āļ‡āļ­āļ‡āļ„āđŒāļāļĢ: āđ€āļžāļīāđˆāļĄ / āđāļāđ‰āđ„āļ‚āđ€āļ­āļāļŠāļēāļĢāļ—āļĩāđˆāđ„āļ”āđ‰āļĢāļąāļšāļĄāļ­āļšāļŦāļĄāļēāļĒ' + ); -- 5. Viewer (Organization) INSERT INTO roles (role_id, role_name, scope, description) VALUES ( - 5, - 'Viewer', - 'Organization', - 'āļœāļđāđ‰āļ”āļđāđ€āļ­āļāļŠāļēāļĢāļ‚āļ­āļ‡āļ­āļ‡āļ„āđŒāļāļĢ: āļ”āļđāđ€āļ­āļāļŠāļēāļĢāļ—āļĩāđˆāļĄāļĩāļŠāļīāļ—āļ˜āļīāđŒāđ€āļ‚āđ‰āļēāļ–āļķāļ‡āđ€āļ—āđˆāļēāļ™āļąāđ‰āļ™' - ); + 5, + 'Viewer', + 'Organization', + 'āļœāļđāđ‰āļ”āļđāđ€āļ­āļāļŠāļēāļĢāļ‚āļ­āļ‡āļ­āļ‡āļ„āđŒāļāļĢ: āļ”āļđāđ€āļ­āļāļŠāļēāļĢāļ—āļĩāđˆāļĄāļĩāļŠāļīāļ—āļ˜āļīāđŒāđ€āļ‚āđ‰āļēāļ–āļķāļ‡āđ€āļ—āđˆāļēāļ™āļąāđ‰āļ™' + ); -- 6. Project Manager (Project) INSERT INTO roles (role_id, role_name, scope, description) VALUES ( - 6, - 'Project Manager', - 'Project', - 'āļœāļđāđ‰āļˆāļąāļ”āļāļēāļĢāđ‚āļ„āļĢāļ‡āļāļēāļĢ: āļˆāļąāļ”āļāļēāļĢāļŠāļĄāļēāļŠāļīāļāđƒāļ™āđ‚āļ„āļĢāļ‡āļāļēāļĢ, āļŠāļĢāđ‰āļēāļ‡/āļˆāļąāļ”āļāļēāļĢāļŠāļąāļāļāļēāđƒāļ™āđ‚āļ„āļĢāļ‡āļāļēāļĢ, āđāļĨāļ°āļ”āļđāļĢāļēāļĒāļ‡āļēāļ™āđ‚āļ„āļĢāļ‡āļāļēāļĢ' - ); + 6, + 'Project Manager', + 'Project', + 'āļœāļđāđ‰āļˆāļąāļ”āļāļēāļĢāđ‚āļ„āļĢāļ‡āļāļēāļĢ: āļˆāļąāļ”āļāļēāļĢāļŠāļĄāļēāļŠāļīāļāđƒāļ™āđ‚āļ„āļĢāļ‡āļāļēāļĢ, āļŠāļĢāđ‰āļēāļ‡ / āļˆāļąāļ”āļāļēāļĢāļŠāļąāļāļāļēāđƒāļ™āđ‚āļ„āļĢāļ‡āļāļēāļĢ, āđāļĨāļ°āļ”āļđāļĢāļēāļĒāļ‡āļēāļ™āđ‚āļ„āļĢāļ‡āļāļēāļĢ' + ); -- 7. Contract Admin (Contract) INSERT INTO roles (role_id, role_name, scope, description) VALUES ( - 7, - 'Contract Admin', - 'Contract', - 'āļœāļđāđ‰āļ”āļđāđāļĨāļŠāļąāļāļāļē: āļˆāļąāļ”āļāļēāļĢāļŠāļĄāļēāļŠāļīāļāđƒāļ™āļŠāļąāļāļāļē, āļŠāļĢāđ‰āļēāļ‡/āļˆāļąāļ”āļāļēāļĢāļ‚āđ‰āļ­āļĄāļđāļĨāļŦāļĨāļąāļāđ€āļ‰āļžāļēāļ°āļŠāļąāļāļāļē, āđāļĨāļ°āļ­āļ™āļļāļĄāļąāļ•āļīāđ€āļ­āļāļŠāļēāļĢāđƒāļ™āļŠāļąāļāļāļē' - ); + 7, + 'Contract Admin', + 'Contract', + 'āļœāļđāđ‰āļ”āļđāđāļĨāļŠāļąāļāļāļē: āļˆāļąāļ”āļāļēāļĢāļŠāļĄāļēāļŠāļīāļāđƒāļ™āļŠāļąāļāļāļē, āļŠāļĢāđ‰āļēāļ‡ / āļˆāļąāļ”āļāļēāļĢāļ‚āđ‰āļ­āļĄāļđāļĨāļŦāļĨāļąāļāđ€āļ‰āļžāļēāļ°āļŠāļąāļāļāļē, āđāļĨāļ°āļ­āļ™āļļāļĄāļąāļ•āļīāđ€āļ­āļāļŠāļēāļĢāđƒāļ™āļŠāļąāļāļāļē' + ); -- āļ•āļēāļĢāļēāļ‡ 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) āļŦāļĢāļ·āļ­ "āļāļēāļĢāļāļĢāļ°āļ—āļģ" āļ—āļąāđ‰āļ‡āļŦāļĄāļ”āđƒāļ™āļĢāļ°āļšāļš'; -- ===================================================== -- 2. Seed Permissions (āļŠāļīāļ—āļ˜āļīāđŒāļāļēāļĢāđƒāļŠāđ‰āļ‡āļēāļ™āļ—āļąāđ‰āļ‡āļŦāļĄāļ”) @@ -448,193 +450,193 @@ CREATE TABLE permissions ( -- ===================================================== 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', - 'āļĄāļ­āļšāļœāļđāđ‰āđƒāļŠāđ‰āļ‡āļēāļ™āđƒāļŦāđ‰āļāļąāļšāļ­āļ‡āļ„āđŒāļāļĢ' - ); + 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', 'āļ”āļđāļ‚āđ‰āļ­āļĄāļđāļĨāļŠāļąāļāļāļē'); + 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', 'āļ›āļīāļ”āđƒāļšāđ€āļ§āļĩāļĒāļ™'); + 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)' - ); + 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', - 'āļŠāļĢāđ‰āļēāļ‡āļĢāļēāļĒāļ‡āļēāļ™āļŠāļĢāļļāļ› (āļĢāļēāļĒāļ§āļąāļ™/āļŠāļąāļ›āļ”āļēāļŦāđŒ/āđ€āļ”āļ·āļ­āļ™/āļ›āļĩ)' - ); + ( + 49, + 'report.generate', + 'āļŠāļĢāđ‰āļēāļ‡āļĢāļēāļĒāļ‡āļēāļ™āļŠāļĢāļļāļ› (āļĢāļēāļĒāļ§āļąāļ™ / āļŠāļąāļ›āļ”āļēāļŦāđŒ / āđ€āļ”āļ·āļ­āļ™ / āļ›āļĩ)' + ); -- āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļĢāļ°āļŦāļ§āđˆāļēāļ‡ roles āđāļĨāļ° permissions (M:N) CREATE TABLE role_permissions ( - role_id INT COMMENT 'ID āļ‚āļ­āļ‡āļšāļ—āļšāļēāļ—', - permission_id INT COMMENT 'ID āļ‚āļ­āļ‡āļŠāļīāļ—āļ˜āļīāđŒ', - PRIMARY KEY (role_id, permission_id), - FOREIGN KEY (role_id) REFERENCES roles(role_id) ON DELETE CASCADE, - FOREIGN KEY (permission_id) REFERENCES permissions(permission_id) ON DELETE CASCADE -) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļĢāļ°āļŦāļ§āđˆāļēāļ‡ roles āđāļĨāļ° permissions (M:N)'; + 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)'; -- ========================================================== -- Seed Role-Permissions Mapping (āļˆāļąāļšāļ„āļđāđˆāļŠāļīāļ—āļ˜āļīāđŒāđ€āļĢāļīāđˆāļĄāļ•āđ‰āļ™) -- ========================================================== --- Seed data for the 'role_permissions' table +-- Seed data for the 'role_permissions 'table -- This table links roles to their specific permissions. -- NOTE: This assumes the role_id and permission_id from the previous seed data files. -- Superadmin (role_id = 1), Org Admin (role_id = 2), Document Control (role_id = 3), etc. @@ -645,277 +647,277 @@ CREATE TABLE role_permissions ( -- 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); -- search.advanced -- āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļœāļđāđ‰āđƒāļŠāđ‰ (users) CREATE TABLE user_assignments ( - id INT AUTO_INCREMENT PRIMARY KEY, - user_id INT NOT NULL, - role_id INT NOT NULL, - -- āļ„āļ­āļĨāļąāļĄāļ™āđŒāļŠāļģāļŦāļĢāļąāļšāļāļģāļŦāļ™āļ”āļ‚āļ­āļšāđ€āļ‚āļ• (āļˆāļ°āđƒāļŠāđ‰āđ€āļžāļĩāļĒāļ‡āļ­āļąāļ™āđ€āļ”āļĩāļĒāļ§āļ•āđˆāļ­āđāļ–āļ§) - organization_id INT NULL, - project_id INT NULL, - contract_id INT NULL, - assigned_by_user_id INT, - -- āļœāļđāđ‰āļ—āļĩāđˆāļĄāļ­āļšāļŦāļĄāļēāļĒāļšāļ—āļšāļēāļ—āļ™āļĩāđ‰ - assigned_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE, - FOREIGN KEY (role_id) REFERENCES roles(role_id) ON DELETE CASCADE, - FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE, - FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE, - FOREIGN KEY (contract_id) REFERENCES contracts(id) ON DELETE CASCADE, - FOREIGN KEY (assigned_by_user_id) REFERENCES users(user_id), - -- Constraint āđ€āļžāļ·āđˆāļ­āđƒāļŦāđ‰āđāļ™āđˆāđƒāļˆāļ§āđˆāļēāļĄāļĩāđ€āļžāļĩāļĒāļ‡āļ‚āļ­āļšāđ€āļ‚āļ•āđ€āļ”āļĩāļĒāļ§āļ—āļĩāđˆāļ–āļđāļāļāļģāļŦāļ™āļ”āđƒāļ™āđāļ•āđˆāļĨāļ°āđāļ–āļ§ - CONSTRAINT chk_scope CHECK ( - ( - organization_id IS NOT NULL - AND project_id IS NULL - AND contract_id IS NULL - ) - OR ( - organization_id IS NULL - AND project_id IS NOT NULL - AND contract_id IS NULL - ) - OR ( - organization_id IS NULL - AND project_id IS NULL - AND contract_id IS NOT NULL - ) - OR ( - organization_id IS NULL - AND project_id IS NULL - AND contract_id IS NULL - ) -- āļŠāļģāļŦāļĢāļąāļš Global scope + id INT AUTO_INCREMENT PRIMARY KEY, + user_id INT NOT NULL, + role_id INT NOT NULL, + -- āļ„āļ­āļĨāļąāļĄāļ™āđŒāļŠāļģāļŦāļĢāļąāļšāļāļģāļŦāļ™āļ”āļ‚āļ­āļšāđ€āļ‚āļ• (āļˆāļ°āđƒāļŠāđ‰āđ€āļžāļĩāļĒāļ‡āļ­āļąāļ™āđ€āļ”āļĩāļĒāļ§āļ•āđˆāļ­āđāļ–āļ§) + organization_id INT NULL, + project_id INT NULL, + contract_id INT NULL, + assigned_by_user_id INT, + -- āļœāļđāđ‰āļ—āļĩāđˆāļĄāļ­āļšāļŦāļĄāļēāļĒāļšāļ—āļšāļēāļ—āļ™āļĩāđ‰ + assigned_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE, + FOREIGN KEY (role_id) REFERENCES roles(role_id) ON DELETE CASCADE, + FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE, + FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE, + FOREIGN KEY (contract_id) REFERENCES contracts(id) ON DELETE CASCADE, + FOREIGN KEY (assigned_by_user_id) REFERENCES users(user_id), + -- Constraint āđ€āļžāļ·āđˆāļ­āđƒāļŦāđ‰āđāļ™āđˆāđƒāļˆāļ§āđˆāļēāļĄāļĩāđ€āļžāļĩāļĒāļ‡āļ‚āļ­āļšāđ€āļ‚āļ•āđ€āļ”āļĩāļĒāļ§āļ—āļĩāđˆāļ–āļđāļāļāļģāļŦāļ™āļ”āđƒāļ™āđāļ•āđˆāļĨāļ°āđāļ–āļ§ + CONSTRAINT chk_scope CHECK ( + ( + organization_id IS NOT NULL + AND project_id IS NULL + AND contract_id IS NULL ) + OR ( + organization_id IS NULL + AND project_id IS NOT NULL + AND contract_id IS NULL + ) + OR ( + organization_id IS NULL + AND project_id IS NULL + AND contract_id IS NOT NULL + ) + OR ( + organization_id IS NULL + AND project_id IS NULL + AND contract_id IS NULL + ) -- āļŠāļģāļŦāļĢāļąāļš Global scope + ) ); CREATE TABLE project_organizations ( - project_id INT NOT NULL, - organization_id INT NOT NULL, - PRIMARY KEY (project_id, organization_id), - FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE, - FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE + 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 ); -- ===================================================== -- == 4. āļāļēāļĢāđ€āļŠāļ·āđˆāļ­āļĄāđ‚āļĒāļ‡āđ‚āļ„āļĢāļ‡āļāļēāļĢāļāļąāļšāļ­āļ‡āļ„āđŒāļāļĢ (project_organizations) == @@ -923,329 +925,329 @@ CREATE TABLE contract_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' - ); + 'āļāļ—āļ—.', + 'āļŠāļ„āļ‰.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 = 'LCBP3C1' - ), - id + SELECT id + FROM projects + WHERE project_code = 'LCBP3C1 ' + ), + 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 = 'LCBP3C2' - ), - id + SELECT id + FROM projects + WHERE project_code = 'LCBP3C2 ' + ), + 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 = 'DSLCBP3' - ), - ( - SELECT id - FROM organizations - WHERE organization_code = 'āļāļ—āļ—.' - ), - 'Owner' + ( + SELECT id + FROM contracts + WHERE contract_code = 'DSLCBP3' ), ( - ( - SELECT id - FROM contracts - WHERE contract_code = 'DSLCBP3' - ), - ( - SELECT id - FROM organizations - WHERE organization_code = 'TEAM' - ), - 'Designer' - ); + SELECT id + FROM organizations + WHERE organization_code = 'āļāļ—āļ—.' + ), + 'Owner' + ), + ( + ( + SELECT id + FROM contracts + WHERE contract_code = 'DSLCBP3' + ), + ( + 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 = 'PSLCBP3' - ), - ( - SELECT id - FROM organizations - WHERE organization_code = 'āļāļ—āļ—.' - ), - 'Owner' + ( + SELECT id + FROM contracts + WHERE contract_code = 'PSLCBP3 ' ), ( - ( - SELECT id - FROM contracts - WHERE contract_code = 'PSLCBP3' - ), - ( - SELECT id - FROM organizations - WHERE organization_code = 'āļ„āļ„āļ‡.' - ), - 'Consultant' - ); + SELECT id + FROM organizations + WHERE organization_code = 'āļāļ—āļ—.' + ), + 'Owner' + ), + ( + ( + SELECT id + FROM contracts + WHERE contract_code = 'PSLCBP3 ' + ), + ( + 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 contracts - WHERE contract_code = 'LCBP3-C1' - ), - ( - SELECT id - FROM organizations - WHERE organization_code = 'āļœāļĢāļĄ.1' - ), - 'Contractor' - ); + 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 contracts - WHERE contract_code = 'LCBP3-C2' - ), - ( - SELECT id - FROM organizations - WHERE organization_code = 'āļœāļĢāļĄ.2' - ), - 'Contractor' - ); + 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' + ); -- āļŠāļąāļāļāļēāļ•āļĢāļ§āļˆāļŠāļ­āļšāļŠāļīāđˆāļ‡āđāļ§āļ”āļĨāđ‰āļ­āļĄ (ENLCBP3) INSERT INTO contract_organizations (contract_id, organization_id, role_in_contract) VALUES ( - ( - SELECT id - FROM contracts - WHERE contract_code = 'ENLCBP3' - ), - ( - SELECT id - FROM organizations - WHERE organization_code = 'āļāļ—āļ—.' - ), - 'Owner' + ( + SELECT id + FROM contracts + WHERE contract_code = 'ENLCBP3' ), ( - ( - SELECT id - FROM contracts - WHERE contract_code = 'ENLCBP3' - ), - ( - SELECT id - FROM organizations - WHERE organization_code = 'EN' - ), - 'Consultant' - ); + SELECT id + FROM organizations + WHERE organization_code = 'āļāļ—āļ—.' + ), + 'Owner' + ), + ( + ( + SELECT id + FROM contracts + WHERE contract_code = 'ENLCBP3' + ), + ( + SELECT id + FROM organizations + WHERE organization_code = 'EN' + ), + 'Consultant' + ); -- ===================================================== -- 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 āđ€āļāđ‡āļšāļ›āļĢāļ°āđ€āļ āļ—āđ€āļ­āļāļŠāļēāļĢāđ‚āļ•āđ‰āļ•āļ­āļš'; 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 - ); + ('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 + ); -- āļ•āļēāļĢāļēāļ‡ 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 āđ€āļāđ‡āļšāļŠāļ–āļēāļ™āļ°āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢ'; 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); + ('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); -- āļ•āļēāļĢāļēāļ‡ "āđāļĄāđˆ" āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢāđ‚āļ•āđ‰āļ•āļ­āļš āđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨāļ—āļĩāđˆāđ„āļĄāđˆāđ€āļ›āļĨāļĩāđˆāļĒāļ™āļ•āļēāļĄ 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), - UNIQUE KEY uq_master_current (correspondence_id, is_current) -) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ "āļĨāļđāļ" āđ€āļāđ‡āļšāļ›āļĢāļ°āļ§āļąāļ•āļīāļāļēāļĢāđāļāđ‰āđ„āļ‚ (Revisions) āļ‚āļ­āļ‡ correspondences (1:N)'; + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡ Revision', + correspondence_id INT NOT NULL COMMENT 'Master ID', + revision_number INT NOT NULL COMMENT 'āļŦāļĄāļēāļĒāđ€āļĨāļ‚ Revision (0, 1, 2...)', + revision_label VARCHAR(10) COMMENT 'Revision āļ—āļĩāđˆāđāļŠāļ”āļ‡ (āđ€āļŠāđˆāļ™ A, B, 1.1)', + is_current BOOLEAN DEFAULT FALSE COMMENT '(1 = Revision āļ›āļąāļˆāļˆāļļāļšāļąāļ™)', + correspondence_status_id INT NOT NULL COMMENT 'āļŠāļ–āļēāļ™āļ°āļ‚āļ­āļ‡ Revision āļ™āļĩāđ‰', + title VARCHAR(255) NOT NULL COMMENT 'āđ€āļĢāļ·āđˆāļ­āļ‡', + document_date DATE COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđƒāļ™āđ€āļ­āļāļŠāļēāļĢ', + issued_date DATETIME COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļ­āļ­āļāđ€āļ­āļāļŠāļēāļĢ', + received_date DATETIME COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļĨāļ‡āļĢāļąāļšāđ€āļ­āļāļŠāļēāļĢ', + due_date DATETIME COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļ„āļĢāļšāļāļģāļŦāļ™āļ”', + description TEXT COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒāļāļēāļĢāđāļāđ‰āđ„āļ‚āđƒāļ™ Revision āļ™āļĩāđ‰', + details JSON COMMENT 'āļ‚āđ‰āļ­āļĄāļđāļĨāđ€āļ‰āļžāļēāļ° (āđ€āļŠāđˆāļ™ RFI details)', + created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡āđ€āļ­āļāļŠāļēāļĢ', + created_by INT COMMENT 'āļœāļđāđ‰āļŠāļĢāđ‰āļēāļ‡', + updated_by INT COMMENT 'āļœāļđāđ‰āđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', + FOREIGN KEY (correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE, + FOREIGN KEY (correspondence_status_id) REFERENCES correspondence_status(id) ON DELETE RESTRICT, + FOREIGN KEY (created_by) REFERENCES users(user_id) ON DELETE + SET NULL, + FOREIGN KEY (updated_by) REFERENCES users(user_id) ON DELETE + SET NULL, + UNIQUE KEY uq_master_revision_number (correspondence_id, revision_number), + UNIQUE KEY uq_master_current (correspondence_id, is_current) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ "āļĨāļđāļ" āđ€āļāđ‡āļšāļ›āļĢāļ°āļ§āļąāļ•āļīāļāļēāļĢāđāļāđ‰āđ„āļ‚ (Revisions) āļ‚āļ­āļ‡ correspondences (1 :N)'; -- āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļœāļđāđ‰āļĢāļąāļš (TO/CC) āļŠāļģāļŦāļĢāļąāļšāđ€āļ­āļāļŠāļēāļĢāđāļ•āđˆāļĨāļ°āļ‰āļšāļąāļš (M:N) CREATE TABLE correspondence_recipients ( - correspondence_id INT COMMENT 'ID āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢ', - recipient_organization_id INT COMMENT 'ID āļ­āļ‡āļ„āđŒāļāļĢāļœāļđāđ‰āļĢāļąāļš', - recipient_type ENUM('TO', 'CC') COMMENT 'āļ›āļĢāļ°āđ€āļ āļ—āļœāļđāđ‰āļĢāļąāļš (TO āļŦāļĢāļ·āļ­ CC)', - PRIMARY KEY ( - correspondence_id, - recipient_organization_id, - recipient_type - ), - FOREIGN KEY (correspondence_id) REFERENCES correspondence_revisions(correspondence_id) ON DELETE CASCADE, - FOREIGN KEY (recipient_organization_id) REFERENCES organizations(id) ON DELETE RESTRICT -) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļœāļđāđ‰āļĢāļąāļš (TO/CC) āļŠāļģāļŦāļĢāļąāļšāđ€āļ­āļāļŠāļēāļĢāđāļ•āđˆāļĨāļ°āļ‰āļšāļąāļš (M:N)'; + 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 -) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļĢāļ°āļŦāļ§āđˆāļēāļ‡ correspondences āđāļĨāļ° tags (M:N)'; + correspondence_id INT COMMENT 'ID āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢ', + tag_id INT COMMENT 'ID āļ‚āļ­āļ‡ Tag', + PRIMARY KEY (correspondence_id, tag_id), + FOREIGN KEY (correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE, + FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļĢāļ°āļŦāļ§āđˆāļēāļ‡ correspondences āđāļĨāļ° tags (M :N)'; -- āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļāļēāļĢāļ­āđ‰āļēāļ‡āļ­āļīāļ‡āļĢāļ°āļŦāļ§āđˆāļēāļ‡āđ€āļ­āļāļŠāļēāļĢ (M:N) CREATE TABLE correspondence_references ( - src_correspondence_id INT COMMENT 'ID āđ€āļ­āļāļŠāļēāļĢāļ•āđ‰āļ™āļ—āļēāļ‡', - tgt_correspondence_id INT COMMENT 'ID āđ€āļ­āļāļŠāļēāļĢāđ€āļ›āđ‰āļēāļŦāļĄāļēāļĒ', - PRIMARY KEY (src_correspondence_id, tgt_correspondence_id), - FOREIGN KEY (src_correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE, - FOREIGN KEY (tgt_correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE -) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļāļēāļĢāļ­āđ‰āļēāļ‡āļ­āļīāļ‡āļĢāļ°āļŦāļ§āđˆāļēāļ‡āđ€āļ­āļāļŠāļēāļĢ (M:N)'; + 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) -- ===================================================== @@ -1253,486 +1255,493 @@ CREATE TABLE correspondence_references ( -- āļĢāļ­āļ‡āļĢāļąāļš: Backend Plan T3.1 -- āđ€āļŦāļ•āļļāļœāļĨ: āđ€āļāđ‡āļš Logic āļāļēāļĢāđ€āļ”āļīāļ™āđ€āļ­āļāļŠāļēāļĢāļ—āļĩāđˆāļ‹āļąāļšāļ‹āđ‰āļ­āļ™āļāļ§āđˆāļē Column āļ›āļāļ•āļī CREATE TABLE correspondence_routing_templates ( - id INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āđāļĄāđˆāđāļšāļš', - template_name VARCHAR(255) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āđāļĄāđˆāđāļšāļš', - description TEXT COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒ', - project_id INT NULL COMMENT 'ID āđ‚āļ„āļĢāļ‡āļāļēāļĢ (āļ–āđ‰āļēāđ€āļ›āđ‡āļ™āđāļĄāđˆāđāļšāļšāđ€āļ‰āļžāļēāļ°āđ‚āļ„āļĢāļ‡āļāļēāļĢ)', - -- NULL = āđāļĄāđˆāđāļšāļšāļ—āļąāđˆāļ§āđ„āļ› - created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', - updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', - is_active BOOLEAN DEFAULT TRUE, - workflow_config JSON NULL COMMENT 'Routing Logic Configuration', - UNIQUE KEY ux_routing_template_name_project (template_name, project_id), - CONSTRAINT fk_crt_project FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE + id INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āđāļĄāđˆāđāļšāļš', + template_name VARCHAR(255) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āđāļĄāđˆāđāļšāļš', + description TEXT COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒ', + project_id INT NULL COMMENT 'ID āđ‚āļ„āļĢāļ‡āļāļēāļĢ (āļ–āđ‰āļēāđ€āļ›āđ‡āļ™āđāļĄāđˆāđāļšāļšāđ€āļ‰āļžāļēāļ°āđ‚āļ„āļĢāļ‡āļāļēāļĢ)', + -- NULL = āđāļĄāđˆāđāļšāļšāļ—āļąāđˆāļ§āđ„āļ› + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', + is_active BOOLEAN DEFAULT TRUE, + workflow_config JSON NULL COMMENT 'Routing Logic Configuration', + UNIQUE KEY ux_routing_template_name_project (template_name, project_id), + CONSTRAINT fk_crt_project FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āđāļĄāđˆāđāļšāļšāļŠāļēāļĒāļ‡āļēāļ™āļāļēāļĢāļŠāđˆāļ‡āļ•āđˆāļ­āđ€āļ­āļāļŠāļēāļĢāļ‚āļ­āļ­āļ™āļļāļĄāļąāļ•āļī'; CREATE TABLE correspondence_status_transitions( - type_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āļ›āļĢāļ°āđ€āļ āļ—āļŦāļ™āļąāļ‡āļŠāļ·āļ­', - from_status_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āļŠāļ–āļēāļ™āļ°āļ•āđ‰āļ™āļ—āļēāļ‡', - to_status_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āļŠāļ–āļēāļ™āļ°āļ›āļĨāļēāļĒāļ—āļēāļ‡', - PRIMARY KEY (type_id, from_status_id, to_status_id), - CONSTRAINT fk_cst_type FOREIGN KEY (type_id) REFERENCES correspondence_types(id), - CONSTRAINT fk_cst_from FOREIGN KEY (from_status_id) REFERENCES correspondence_status(id), - CONSTRAINT fk_cst_to FOREIGN KEY (to_status_id) REFERENCES correspondence_status(id) + type_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āļ›āļĢāļ°āđ€āļ āļ—āļŦāļ™āļąāļ‡āļŠāļ·āļ­', + from_status_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āļŠāļ–āļēāļ™āļ°āļ•āđ‰āļ™āļ—āļēāļ‡', + to_status_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āļŠāļ–āļēāļ™āļ°āļ›āļĨāļēāļĒāļ—āļēāļ‡', + PRIMARY KEY (type_id, from_status_id, to_status_id), + CONSTRAINT fk_cst_type FOREIGN KEY (type_id) REFERENCES correspondence_types(id), + CONSTRAINT fk_cst_from FOREIGN KEY (from_status_id) REFERENCES correspondence_status(id), + CONSTRAINT fk_cst_to FOREIGN KEY (to_status_id) REFERENCES correspondence_status(id) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āļŠāļ–āļēāļ™āļ°āļ—āļĩāđˆāļ­āļ™āļļāļāļēāļ•āđƒāļŦāđ‰āđ€āļ›āļĨāļĩāđˆāļĒāļ™āđāļ›āļĨāļ‡āđ„āļ”āđ‰āļ•āļēāļĄāļ›āļĢāļ°āđ€āļ āļ—āļŦāļ™āļąāļ‡āļŠāļ·āļ­'; -- 1.18.1 correspondence_routing_template_steps Table CREATE TABLE correspondence_routing_template_steps ( - id INT NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'ID āļ‚āļ­āļ‡āļ‚āļąāđ‰āļ™āļ•āļ­āļ™', - template_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āđāļĄāđˆāđāļšāļš', - sequence INT NOT NULL COMMENT 'āļĨāļģāļ”āļąāļšāļ‚āļąāđ‰āļ™āļ•āļ­āļ™', - to_organization_id INT NOT NULL COMMENT 'ID āļ­āļ‡āļ„āđŒāļāļĢāļ“āđŒāļœāļđāđ‰āļĢāļąāļšāđƒāļ™āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļ™āļĩāđ‰', - step_purpose ENUM('FOR_APPROVAL', 'FOR_REVIEW', 'FOR_INFORMATION') NOT NULL DEFAULT 'FOR_REVIEW' COMMENT 'āļ§āļąāļ•āļ–āļļāļ›āļĢāļ°āļŠāļ‡āļ„āđŒāļ‚āļ­āļ‡āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļ™āļĩāđ‰', - expected_days INT NULL, - UNIQUE KEY ux_cor_template_sequence (template_id, sequence), - CONSTRAINT fk_cwts_template FOREIGN KEY (template_id) REFERENCES correspondence_routing_templates(id) ON DELETE CASCADE, - CONSTRAINT fk_cwts_org FOREIGN KEY (to_organization_id) REFERENCES organizations(id) ON DELETE CASCADE + id INT NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'ID āļ‚āļ­āļ‡āļ‚āļąāđ‰āļ™āļ•āļ­āļ™', + template_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āđāļĄāđˆāđāļšāļš', + sequence INT NOT NULL COMMENT 'āļĨāļģāļ”āļąāļšāļ‚āļąāđ‰āļ™āļ•āļ­āļ™', + to_organization_id INT NOT NULL COMMENT 'ID āļ­āļ‡āļ„āđŒāļāļĢāļ“āđŒāļœāļđāđ‰āļĢāļąāļšāđƒāļ™āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļ™āļĩāđ‰', + step_purpose ENUM('FOR_APPROVAL', 'FOR_REVIEW', 'FOR_INFORMATION ') NOT NULL DEFAULT 'FOR_REVIEW ' COMMENT 'āļ§āļąāļ•āļ–āļļāļ›āļĢāļ°āļŠāļ‡āļ„āđŒāļ‚āļ­āļ‡āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļ™āļĩāđ‰', + expected_days INT NULL, + UNIQUE KEY ux_cor_template_sequence (template_id, sequence), + CONSTRAINT fk_cwts_template FOREIGN KEY (template_id) REFERENCES correspondence_routing_templates(id) ON DELETE CASCADE, + CONSTRAINT fk_cwts_org FOREIGN KEY (to_organization_id) REFERENCES organizations(id) ON DELETE CASCADE ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āđƒāļ™āđāļĄāđˆāđāļšāļš Workflow āļāļēāļĢāļŠāđˆāļ‡āļ•āđˆāļ­āđ€āļ­āļāļŠāļēāļĢ'; -- 1.19.1 correspondence_routings -- 3.2 State Context for Running Workflows -- āļĢāļ­āļ‡āļĢāļąāļš: Backend Plan T3.1 -- āđ€āļŦāļ•āļļāļœāļĨ: āđ€āļāđ‡āļš Snapshot āļ‚āđ‰āļ­āļĄāļđāļĨ āļ“ āļ‚āļ“āļ°āļ™āļąāđ‰āļ™āđ€āļžāļ·āđˆāļ­āđƒāļŠāđ‰āļ•āļąāļ”āļŠāļīāļ™āđƒāļˆāđƒāļ™ Step āļ–āļąāļ”āđ„āļ› CREATE TABLE correspondence_routings ( - id INT NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'ID āļ‚āļ­āļ‡āļ‚āļąāđ‰āļ™āļ•āļ­āļ™', - correspondence_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢ(FK -> correspondence_revisions)', - template_id INT NULL COMMENT 'ID āļ‚āļ­āļ‡āđāļĄāđˆāđāļšāļšāļ—āļĩāđˆāđƒāļŠāđ‰ (āļ–āđ‰āļēāļĄāļĩ)', - -- āļŠāļģāļŦāļĢāļąāļšāļ­āđ‰āļēāļ‡āļ­āļīāļ‡āļ–āļķāļ‡āđāļĄāđˆāđāļšāļš - sequence INT NOT NULL COMMENT 'āļĨāļģāļ”āļąāļšāļ‚āļ­āļ‡āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļāļēāļĢāļŠāđˆāļ‡āļ•āđˆāļ­', - from_organization_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āļ­āļ‡āļ„āđŒāļāļĢāļ“āđŒāļœāļđāđ‰āļŠāđˆāļ‡', - to_organization_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āļ­āļ‡āļ„āđŒāļāļĢāļ“āđŒāļœāļđāđ‰āļĢāļąāļš', - step_purpose ENUM( - 'FOR_APPROVAL', - 'FOR_REVIEW', - 'FOR_INFORMATION', - 'FOR_ACTION' - ) NOT NULL DEFAULT 'FOR_REVIEW' COMMENT 'āļ§āļąāļ•āļ–āļļāļ›āļĢāļ°āļŠāļ‡āļ„āđŒāļ‚āļ­āļ‡āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļ™āļĩāđ‰ āđ€āļŠāđˆāļ™ āđ€āļžāļ·āđˆāļ­āļ­āļ™āļļāļĄāļąāļ•āļī, āđ€āļžāļ·āđˆāļ­āļ•āļĢāļ§āļˆāļŠāļ­āļš, āļŦāļĢāļ·āļ­āđ€āļžāļ·āđˆāļ­āļĢāļąāļšāļ—āļĢāļēāļš', - status ENUM( - 'SENT', - 'RECEIVED', - 'ACTIONED', - 'FORWARDED', - 'REPLIED' - ) NOT NULL DEFAULT 'SENT' COMMENT 'āļŠāļ–āļēāļ™āļ°āļāļēāļĢāļ”āļģāđ€āļ™āļīāļ™āļāļēāļĢāļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢāđƒāļ™āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļ™āļĩāđ‰', - comments TEXT COMMENT 'āļŦāļĄāļēāļĒāđ€āļŦāļ•āļļ āļŦāļĢāļ·āļ­āļ„āļ§āļēāļĄāļ„āļīāļ”āđ€āļŦāđ‡āļ™āđƒāļ™āļāļēāļĢāļŠāđˆāļ‡āļ•āđˆāļ­', - due_date DATETIME NULL COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļ•āđ‰āļ­āļ‡āļ•āļ­āļšāđ€āļ­āļāļŠāļēāļĢāđƒāļ™āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļ™āļĩāđ‰', - processed_by_user_id INT NULL COMMENT 'ID āļ‚āļ­āļ‡āļœāļđāđ‰āđƒāļŠāđ‰āļ—āļĩāđˆāļ”āļģāđ€āļ™āļīāļ™āļāļēāļĢāđƒāļ™āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļ™āļĩāđ‰', - processed_at TIMESTAMP NULL COMMENT 'āđ€āļ§āļĨāļēāļ—āļĩāđˆāļ”āļģāđ€āļ™āļīāļ™āļāļēāļĢ', - created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'āđ€āļ§āļĨāļēāļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļ™āļĩāđ‰', - state_context JSON NULL COMMENT 'Snapshot of routing state context', - UNIQUE KEY ux_cor_routing_sequence (correspondence_id, sequence), - -- Foreign Keys - CONSTRAINT fk_crs_correspondence FOREIGN KEY (correspondence_id) REFERENCES correspondence_revisions(correspondence_id) ON DELETE CASCADE, - CONSTRAINT fk_crs_template FOREIGN KEY (template_id) REFERENCES correspondence_routing_templates(id) ON DELETE - SET NULL, - CONSTRAINT fk_crs_from_org FOREIGN KEY (from_organization_id) REFERENCES organizations(id) ON DELETE CASCADE, - CONSTRAINT fk_crs_to_org FOREIGN KEY (to_organization_id) REFERENCES organizations(id) ON DELETE CASCADE, - CONSTRAINT fk_crs_processed_by_user FOREIGN KEY (processed_by_user_id) REFERENCES users(user_id) ON DELETE - SET NULL + id INT NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'ID āļ‚āļ­āļ‡āļ‚āļąāđ‰āļ™āļ•āļ­āļ™', + correspondence_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢ(FK->correspondence_revisions)', + template_id INT NULL COMMENT 'ID āļ‚āļ­āļ‡āđāļĄāđˆāđāļšāļšāļ—āļĩāđˆāđƒāļŠāđ‰ (āļ–āđ‰āļēāļĄāļĩ)', + -- āļŠāļģāļŦāļĢāļąāļšāļ­āđ‰āļēāļ‡āļ­āļīāļ‡āļ–āļķāļ‡āđāļĄāđˆāđāļšāļš + sequence INT NOT NULL COMMENT 'āļĨāļģāļ”āļąāļšāļ‚āļ­āļ‡āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļāļēāļĢāļŠāđˆāļ‡āļ•āđˆāļ­', + from_organization_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āļ­āļ‡āļ„āđŒāļāļĢāļ“āđŒāļœāļđāđ‰āļŠāđˆāļ‡', + to_organization_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āļ­āļ‡āļ„āđŒāļāļĢāļ“āđŒāļœāļđāđ‰āļĢāļąāļš', + step_purpose ENUM( + 'FOR_APPROVAL', + 'FOR_REVIEW', + 'FOR_INFORMATION', + 'FOR_ACTION ' + ) NOT NULL DEFAULT 'FOR_REVIEW ' COMMENT 'āļ§āļąāļ•āļ–āļļāļ›āļĢāļ°āļŠāļ‡āļ„āđŒāļ‚āļ­āļ‡āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļ™āļĩāđ‰ āđ€āļŠāđˆāļ™ āđ€āļžāļ·āđˆāļ­āļ­āļ™āļļāļĄāļąāļ•āļī, + āđ€āļžāļ·āđˆāļ­āļ•āļĢāļ§āļˆāļŠāļ­āļš, + āļŦāļĢāļ·āļ­āđ€āļžāļ·āđˆāļ­āļĢāļąāļšāļ—āļĢāļēāļš', + status ENUM( + 'SENT', + 'RECEIVED', + 'ACTIONED', + 'FORWARDED', + 'REPLIED ' + ) NOT NULL DEFAULT 'SENT ' COMMENT 'āļŠāļ–āļēāļ™āļ°āļāļēāļĢāļ”āļģāđ€āļ™āļīāļ™āļāļēāļĢāļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢāđƒāļ™āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļ™āļĩāđ‰', + comments TEXT COMMENT 'āļŦāļĄāļēāļĒāđ€āļŦāļ•āļļ āļŦāļĢāļ·āļ­āļ„āļ§āļēāļĄāļ„āļīāļ”āđ€āļŦāđ‡āļ™āđƒāļ™āļāļēāļĢāļŠāđˆāļ‡āļ•āđˆāļ­', + due_date DATETIME NULL COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļ•āđ‰āļ­āļ‡āļ•āļ­āļšāđ€āļ­āļāļŠāļēāļĢāđƒāļ™āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļ™āļĩāđ‰', + processed_by_user_id INT NULL COMMENT 'ID āļ‚āļ­āļ‡āļœāļđāđ‰āđƒāļŠāđ‰āļ—āļĩāđˆāļ”āļģāđ€āļ™āļīāļ™āļāļēāļĢāđƒāļ™āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļ™āļĩāđ‰', + processed_at TIMESTAMP NULL COMMENT 'āđ€āļ§āļĨāļēāļ—āļĩāđˆāļ”āļģāđ€āļ™āļīāļ™āļāļēāļĢ', + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'āđ€āļ§āļĨāļēāļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļ™āļĩāđ‰', + state_context JSON NULL COMMENT 'Snapshot of routing state context', + UNIQUE KEY ux_cor_routing_sequence (correspondence_id, sequence), + -- Foreign Keys + CONSTRAINT fk_crs_correspondence FOREIGN KEY (correspondence_id) REFERENCES correspondence_revisions(correspondence_id) ON DELETE CASCADE, + CONSTRAINT fk_crs_template FOREIGN KEY (template_id) REFERENCES correspondence_routing_templates(id) ON DELETE + SET NULL, + CONSTRAINT fk_crs_from_org FOREIGN KEY (from_organization_id) REFERENCES organizations(id) ON DELETE CASCADE, + CONSTRAINT fk_crs_to_org FOREIGN KEY (to_organization_id) REFERENCES organizations(id) ON DELETE CASCADE, + CONSTRAINT fk_crs_processed_by_user FOREIGN KEY (processed_by_user_id) REFERENCES users(user_id) ON DELETE + SET NULL ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āļ•āļīāļ”āļ•āļēāļĄ Workflow āļāļēāļĢāļŠāđˆāļ‡āļ•āđˆāļ­āđ€āļ­āļāļŠāļēāļĢāļ—āļąāđˆāļ§āđ„āļ›'; -- āļ•āļēāļĢāļēāļ‡ Master āļŠāļģāļŦāļĢāļąāļšāļ›āļĢāļ°āđ€āļ āļ— RFA CREATE TABLE rfa_types ( - id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', - type_code VARCHAR(20) NOT NULL UNIQUE COMMENT 'āļĢāļŦāļąāļŠāļ›āļĢāļ°āđ€āļ āļ— RFA (āđ€āļŠāđˆāļ™ DWG, DOC, MAT)', - type_name VARCHAR(100) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āļ›āļĢāļ°āđ€āļ āļ— RFA', - description TEXT 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(20) NOT NULL UNIQUE COMMENT 'āļĢāļŦāļąāļŠāļ›āļĢāļ°āđ€āļ āļ— RFA (āđ€āļŠāđˆāļ™ DWG, DOC, MAT)', + type_name VARCHAR(100) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āļ›āļĢāļ°āđ€āļ āļ— RFA', + 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'; INSERT INTO rfa_types (type_code, type_name, sort_order, is_active) VALUES ('DWG', 'Shop Drawing', 10, 1), - ('DOC', 'Document', 20, 1), - ('SPC', 'Specification', 21, 1), - ('CAL', 'Calculation', 22, 1), - ('TRP', 'Test Report', 23, 1), - ('SRY', 'Survey Report', 24, 1), - ('QAQC', 'QA/QC Document', 25, 1), - ('MES', 'Method Statement', 30, 1), - ('MAT', 'Material', 40, 1), - ('ASB', 'As-Built', 50, 1), - ('OTH', 'Other', 99, 1); + ('DOC', 'Document', 20, 1), + ('SPC', 'Specification', 21, 1), + ('CAL', 'Calculation', 22, 1), + ('TRP', 'Test Report', 23, 1), + ('SRY', 'Survey Report', 24, 1), + ('QAQC', 'QA / QC Document', 25, 1), + ('MES', 'Method Statement', 30, 1), + ('MAT', 'Material', 40, 1), + ('ASB', 'As - Built', 50, 1), + ('OTH', 'Other', 99, 1); -- āļ•āļēāļĢāļēāļ‡ 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'; INSERT INTO rfa_status_codes ( - status_code, - status_name, - description, - sort_order - ) + 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); + ('FAP', 'For Approve', 'āđ€āļžāļ·āđˆāļ­āļ‚āļ­āļ­āļ™āļļāļĄāļąāļ•āļī', 11), + ('FRE', 'For Review', 'āđ€āļžāļ·āđˆāļ­āļ•āļĢāļ§āļˆāļŠāļ­āļš', 12), + ('FCO', 'For Construction', 'āđ€āļžāļ·āđˆāļ­āļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡', 20), + ('ASB', 'AS - Built', 'āđāļšāļšāļāđˆāļ­āļŠāļĢāđ‰āļēāļ‡āļˆāļĢāļīāļ‡', 30), + ('OBS', 'Obsolete', 'āđ„āļĄāđˆāđƒāļŠāđ‰āļ‡āļēāļ™', 80), + ('CC', 'Canceled', 'āļĒāļāđ€āļĨāļīāļ', 99); -- āļ•āļēāļĢāļēāļ‡ Master āļŠāļģāļŦāļĢāļąāļšāļĢāļŦāļąāļŠāļœāļĨāļāļēāļĢāļ­āļ™āļļāļĄāļąāļ•āļī RFA CREATE TABLE rfa_approve_codes ( - id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', - approve_code VARCHAR(20) NOT NULL UNIQUE COMMENT 'āļĢāļŦāļąāļŠāļœāļĨāļāļēāļĢāļ­āļ™āļļāļĄāļąāļ•āļī (āđ€āļŠāđˆāļ™ 1A - Approved, 3R - Revise and Resubmit)', - approve_name VARCHAR(100) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āļœāļĨāļāļēāļĢāļ­āļ™āļļāļĄāļąāļ•āļī', - description TEXT COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒ', - sort_order INT DEFAULT 0 COMMENT 'āļĨāļģāļ”āļąāļšāļāļēāļĢāđāļŠāļ”āļ‡āļœāļĨ', - is_active TINYINT(1) DEFAULT 1 COMMENT 'āļŠāļ–āļēāļ™āļ°āļāļēāļĢāđƒāļŠāđ‰āļ‡āļēāļ™' + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + approve_code VARCHAR(20) NOT NULL UNIQUE COMMENT 'āļĢāļŦāļąāļŠāļœāļĨāļāļēāļĢāļ­āļ™āļļāļĄāļąāļ•āļī ( + āđ€āļŠāđˆāļ™ 1A - Approved, + 3R - Revise + and Resubmit + )', + approve_name VARCHAR(100) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āļœāļĨāļāļēāļĢāļ­āļ™āļļāļĄāļąāļ•āļī', + description TEXT COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒ', + sort_order INT DEFAULT 0 COMMENT 'āļĨāļģāļ”āļąāļšāļāļēāļĢāđāļŠāļ”āļ‡āļœāļĨ', + is_active TINYINT(1) DEFAULT 1 COMMENT 'āļŠāļ–āļēāļ™āļ°āļāļēāļĢāđƒāļŠāđ‰āļ‡āļēāļ™ ' ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ Master āļŠāļģāļŦāļĢāļąāļšāļĢāļŦāļąāļŠāļœāļĨāļāļēāļĢāļ­āļ™āļļāļĄāļąāļ•āļī RFA'; INSERT INTO rfa_approve_codes ( - approve_code, - approve_name, - sort_order, - is_active - ) + 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); + ('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); -- āļ•āļēāļĢāļēāļ‡ "āđāļĄāđˆ" āļ‚āļ­āļ‡ RFA (āļĄāļĩāļ„āļ§āļēāļĄāļŠāļąāļĄāļžāļąāļ™āļ˜āđŒ 1:N āļāļąāļš rfa_revisions) CREATE TABLE rfas ( - id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡ (RFA Master ID)', - rfa_type_id INT NOT NULL COMMENT 'āļ›āļĢāļ°āđ€āļ āļ— RFA', - created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', - created_by INT COMMENT 'āļœāļđāđ‰āļŠāļĢāđ‰āļēāļ‡', - deleted_at DATETIME NULL COMMENT 'āļŠāļģāļŦāļĢāļąāļš Soft Delete', - FOREIGN KEY (rfa_type_id) REFERENCES rfa_types(id), - FOREIGN KEY (created_by) REFERENCES users(user_id) ON DELETE - SET NULL -) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ "āđāļĄāđˆ" āļ‚āļ­āļ‡ RFA (āļĄāļĩāļ„āļ§āļēāļĄāļŠāļąāļĄāļžāļąāļ™āļ˜āđŒ 1:N āļāļąāļš rfa_revisions)'; + 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)'; -- āļ•āļēāļĢāļēāļ‡ "āļĨāļđāļ" āđ€āļāđ‡āļšāļ›āļĢāļ°āļ§āļąāļ•āļī (Revisions) āļ‚āļ­āļ‡ rfas (1:N) CREATE TABLE rfa_revisions ( - id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡ Revision', - correspondence_id INT NOT NULL COMMENT 'Master ID āļ‚āļ­āļ‡ Correspondence', - rfa_id INT NOT NULL COMMENT 'Master ID āļ‚āļ­āļ‡ RFA', - revision_number INT NOT NULL COMMENT 'āļŦāļĄāļēāļĒāđ€āļĨāļ‚ Revision (0, 1, 2...)', - revision_label VARCHAR(10) COMMENT 'Revision āļ—āļĩāđˆāđāļŠāļ”āļ‡ (āđ€āļŠāđˆāļ™ A, B, 1.1)', - is_current BOOLEAN DEFAULT FALSE COMMENT '(1 = Revision āļ›āļąāļˆāļˆāļļāļšāļąāļ™)', - rfa_status_code_id INT NOT NULL COMMENT 'āļŠāļ–āļēāļ™āļ° RFA', - rfa_approve_code_id INT COMMENT 'āļœāļĨāļāļēāļĢāļ­āļ™āļļāļĄāļąāļ•āļī', - title VARCHAR(255) NOT NULL COMMENT 'āđ€āļĢāļ·āđˆāļ­āļ‡', - document_date DATE COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđƒāļ™āđ€āļ­āļāļŠāļēāļĢ', - issued_date DATE COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāđˆāļ‡āļ‚āļ­āļ­āļ™āļļāļĄāļąāļ•āļī', - received_date DATETIME COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļĨāļ‡āļĢāļąāļšāđ€āļ­āļāļŠāļēāļĢ', - approved_date DATE COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļ­āļ™āļļāļĄāļąāļ•āļī', - description TEXT COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒāļāļēāļĢāđāļāđ‰āđ„āļ‚āđƒāļ™ Revision āļ™āļĩāđ‰', - created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡āđ€āļ­āļāļŠāļēāļĢ', - created_by INT COMMENT 'āļœāļđāđ‰āļŠāļĢāđ‰āļēāļ‡', - updated_by INT COMMENT 'āļœāļđāđ‰āđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', - FOREIGN KEY (correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE, - FOREIGN KEY (rfa_id) REFERENCES rfas(id) ON DELETE CASCADE, - FOREIGN KEY (rfa_status_code_id) REFERENCES rfa_status_codes(id), - FOREIGN KEY (rfa_approve_code_id) REFERENCES rfa_approve_codes(id) ON DELETE - SET NULL, - FOREIGN KEY (created_by) REFERENCES users(user_id) ON DELETE - SET NULL, - FOREIGN KEY (updated_by) REFERENCES users(user_id) ON DELETE - SET NULL, - UNIQUE KEY uq_rr_rev_number (rfa_id, revision_number), - UNIQUE KEY uq_rr_current (rfa_id, is_current) -) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ "āļĨāļđāļ" āđ€āļāđ‡āļšāļ›āļĢāļ°āļ§āļąāļ•āļī (Revisions) āļ‚āļ­āļ‡ rfas (1:N)'; + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡ Revision', + correspondence_id INT NOT NULL COMMENT 'Master ID āļ‚āļ­āļ‡ Correspondence', + rfa_id INT NOT NULL COMMENT 'Master ID āļ‚āļ­āļ‡ RFA', + revision_number INT NOT NULL COMMENT 'āļŦāļĄāļēāļĒāđ€āļĨāļ‚ Revision (0, 1, 2...)', + revision_label VARCHAR(10) COMMENT 'Revision āļ—āļĩāđˆāđāļŠāļ”āļ‡ (āđ€āļŠāđˆāļ™ A, B, 1.1)', + is_current BOOLEAN DEFAULT FALSE COMMENT '(1 = Revision āļ›āļąāļˆāļˆāļļāļšāļąāļ™)', + rfa_status_code_id INT NOT NULL COMMENT 'āļŠāļ–āļēāļ™āļ° RFA', + rfa_approve_code_id INT COMMENT 'āļœāļĨāļāļēāļĢāļ­āļ™āļļāļĄāļąāļ•āļī', + title VARCHAR(255) NOT NULL COMMENT 'āđ€āļĢāļ·āđˆāļ­āļ‡', + document_date DATE COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđƒāļ™āđ€āļ­āļāļŠāļēāļĢ', + issued_date DATE COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāđˆāļ‡āļ‚āļ­āļ­āļ™āļļāļĄāļąāļ•āļī', + received_date DATETIME COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļĨāļ‡āļĢāļąāļšāđ€āļ­āļāļŠāļēāļĢ', + approved_date DATE COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļ­āļ™āļļāļĄāļąāļ•āļī', + description TEXT COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒāļāļēāļĢāđāļāđ‰āđ„āļ‚āđƒāļ™ Revision āļ™āļĩāđ‰', + created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡āđ€āļ­āļāļŠāļēāļĢ', + created_by INT COMMENT 'āļœāļđāđ‰āļŠāļĢāđ‰āļēāļ‡', + updated_by INT COMMENT 'āļœāļđāđ‰āđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', + FOREIGN KEY (correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE, + FOREIGN KEY (rfa_id) REFERENCES rfas(id) ON DELETE CASCADE, + FOREIGN KEY (rfa_status_code_id) REFERENCES rfa_status_codes(id), + FOREIGN KEY (rfa_approve_code_id) REFERENCES rfa_approve_codes(id) ON DELETE + SET NULL, + FOREIGN KEY (created_by) REFERENCES users(user_id) ON DELETE + SET NULL, + FOREIGN KEY (updated_by) REFERENCES users(user_id) ON DELETE + SET NULL, + UNIQUE KEY uq_rr_rev_number (rfa_id, revision_number), + UNIQUE KEY uq_rr_current (rfa_id, is_current) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ "āļĨāļđāļ" āđ€āļāđ‡āļšāļ›āļĢāļ°āļ§āļąāļ•āļī (Revisions) āļ‚āļ­āļ‡ rfas (1 :N)'; -- āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļĢāļ°āļŦāļ§āđˆāļēāļ‡ rfa_revisions (āļ—āļĩāđˆāđ€āļ›āđ‡āļ™āļ›āļĢāļ°āđ€āļ āļ— DWG) āļāļąāļš shop_drawing_revisions (M:N) CREATE TABLE rfa_items ( - rfarev_correspondence_id INT COMMENT 'ID āļ‚āļ­āļ‡ RFA Revision', - shop_drawing_revision_id INT COMMENT 'ID āļ‚āļ­āļ‡ Shop Drawing Revision', - PRIMARY KEY ( - rfarev_correspondence_id, - shop_drawing_revision_id - ), - FOREIGN KEY (rfarev_correspondence_id) REFERENCES rfa_revisions(correspondence_id) ON DELETE CASCADE, - FOREIGN KEY (shop_drawing_revision_id) REFERENCES shop_drawing_revisions(id) ON DELETE CASCADE -) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļĢāļ°āļŦāļ§āđˆāļēāļ‡ rfa_revisions (āļ—āļĩāđˆāđ€āļ›āđ‡āļ™āļ›āļĢāļ°āđ€āļ āļ— DWG) āļāļąāļš shop_drawing_revisions (M:N)'; + 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)'; -- āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļšāđāļĄāđˆāđāļšāļšāļŠāļēāļĒāļ­āļ™āļļāļĄāļąāļ•āļī -- 3.1 Workflow Config for Templates -- āļĢāļ­āļ‡āļĢāļąāļš: Backend Plan T3.1 -- āđ€āļŦāļ•āļļāļœāļĨ: āđ€āļāđ‡āļš Logic āļāļēāļĢāđ€āļ”āļīāļ™āđ€āļ­āļāļŠāļēāļĢāļ—āļĩāđˆāļ‹āļąāļšāļ‹āđ‰āļ­āļ™āļāļ§āđˆāļē Column āļ›āļāļ•āļī CREATE TABLE rfa_workflow_templates ( - id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', - template_name VARCHAR(100) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āđāļĄāđˆāđāļšāļšāļŠāļēāļĒāļ­āļ™āļļāļĄāļąāļ•āļī', - description TEXT 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 'āļ§āļąāļ™āļ—āļĩāđˆāđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', - workflow_config JSON NULL COMMENT 'State Machine Configuration Rules' + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + template_name VARCHAR(100) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āđāļĄāđˆāđāļšāļšāļŠāļēāļĒāļ­āļ™āļļāļĄāļąāļ•āļī', + description TEXT 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 'āļ§āļąāļ™āļ—āļĩāđˆāđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', + workflow_config JSON NULL COMMENT 'State Machine Configuration Rules ' ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļšāđāļĄāđˆāđāļšāļšāļŠāļēāļĒāļ­āļ™āļļāļĄāļąāļ•āļī'; -- āļ•āļēāļĢāļēāļ‡āļĨāļđāļ āđ€āļāđ‡āļšāļ‚āļąāđ‰āļ™āļ•āļ­āļ™āđƒāļ™āđāļĄāđˆāđāļšāļš CREATE TABLE rfa_workflow_template_steps ( - id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', - template_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āđāļĄāđˆāđāļšāļš', - step_number INT NOT NULL COMMENT 'āļĨāļģāļ”āļąāļšāļ‚āļąāđ‰āļ™āļ•āļ­āļ™', - organization_id INT NOT NULL COMMENT 'āļ­āļ‡āļ„āđŒāļāļĢāļ—āļĩāđˆāļĢāļąāļšāļœāļīāļ”āļŠāļ­āļš', - role_id INT COMMENT 'āļšāļ—āļšāļēāļ—āļ—āļĩāđˆāļĢāļąāļšāļœāļīāļ”āļŠāļ­āļš', - action_type ENUM('REVIEW', 'APPROVE', 'ACKNOWLEDGE') COMMENT 'āļ›āļĢāļ°āđ€āļ āļ—āļāļēāļĢāļāļĢāļ°āļ—āļģ', - duration_days INT COMMENT 'āļĢāļ°āļĒāļ°āđ€āļ§āļĨāļēāļ—āļĩāđˆāļāļģāļŦāļ™āļ” (āļ§āļąāļ™)', - is_optional BOOLEAN DEFAULT FALSE COMMENT 'āđ€āļ›āđ‡āļ™āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āđ€āļĨāļ·āļ­āļāļŦāļĢāļ·āļ­āđ„āļĄāđˆ', - FOREIGN KEY (template_id) REFERENCES rfa_workflow_templates(id) ON DELETE CASCADE, - FOREIGN KEY (organization_id) REFERENCES organizations(id), - FOREIGN KEY (role_id) REFERENCES roles(role_id) + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + template_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āđāļĄāđˆāđāļšāļš', + step_number INT NOT NULL COMMENT 'āļĨāļģāļ”āļąāļšāļ‚āļąāđ‰āļ™āļ•āļ­āļ™', + organization_id INT NOT NULL COMMENT 'āļ­āļ‡āļ„āđŒāļāļĢāļ—āļĩāđˆāļĢāļąāļšāļœāļīāļ”āļŠāļ­āļš', + role_id INT COMMENT 'āļšāļ—āļšāļēāļ—āļ—āļĩāđˆāļĢāļąāļšāļœāļīāļ”āļŠāļ­āļš', + action_type ENUM('REVIEW', 'APPROVE', 'ACKNOWLEDGE ') COMMENT 'āļ›āļĢāļ°āđ€āļ āļ—āļāļēāļĢāļāļĢāļ°āļ—āļģ', + duration_days INT COMMENT 'āļĢāļ°āļĒāļ°āđ€āļ§āļĨāļēāļ—āļĩāđˆāļāļģāļŦāļ™āļ” (āļ§āļąāļ™)', + is_optional BOOLEAN DEFAULT FALSE COMMENT 'āđ€āļ›āđ‡āļ™āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āđ€āļĨāļ·āļ­āļāļŦāļĢāļ·āļ­āđ„āļĄāđˆ', + FOREIGN KEY (template_id) REFERENCES rfa_workflow_templates(id) ON DELETE CASCADE, + FOREIGN KEY (organization_id) REFERENCES organizations(id), + FOREIGN KEY (role_id) REFERENCES roles(role_id) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āļĨāļđāļ āđ€āļāđ‡āļšāļ‚āļąāđ‰āļ™āļ•āļ­āļ™āđƒāļ™āđāļĄāđˆāđāļšāļš'; -- āļ•āļēāļĢāļēāļ‡āļ›āļĢāļ°āļ§āļąāļ•āļī (Log) āļāļēāļĢāļ­āļ™āļļāļĄāļąāļ•āļīāļ‚āļ­āļ‡ RFA āļˆāļĢāļīāļ‡āļ•āļēāļĄāļŠāļēāļĒāļ‡āļēāļ™ -- 3.2 State Context for Running Workflows -- āļĢāļ­āļ‡āļĢāļąāļš: Backend Plan T3.1 -- āđ€āļŦāļ•āļļāļœāļĨ: āđ€āļāđ‡āļš Snapshot āļ‚āđ‰āļ­āļĄāļđāļĨ āļ“ āļ‚āļ“āļ°āļ™āļąāđ‰āļ™āđ€āļžāļ·āđˆāļ­āđƒāļŠāđ‰āļ•āļąāļ”āļŠāļīāļ™āđƒāļˆāđƒāļ™ Step āļ–āļąāļ”āđ„āļ› CREATE TABLE rfa_workflows ( - id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', - rfa_revision_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡ RFA Revision', - step_number INT NOT NULL COMMENT 'āļĨāļģāļ”āļąāļšāļ‚āļąāđ‰āļ™āļ•āļ­āļ™', - organization_id INT NOT NULL COMMENT 'āļ­āļ‡āļ„āđŒāļāļĢāļ—āļĩāđˆāļĢāļąāļšāļœāļīāļ”āļŠāļ­āļš', - assigned_to INT COMMENT 'āļœāļđāđ‰āđƒāļŠāđ‰āļ—āļĩāđˆāđ„āļ”āđ‰āļĢāļąāļšāļĄāļ­āļšāļŦāļĄāļēāļĒ', - action_type ENUM('REVIEW', 'APPROVE', 'ACKNOWLEDGE') COMMENT 'āļ›āļĢāļ°āđ€āļ āļ—āļāļēāļĢāļāļĢāļ°āļ—āļģ', - status ENUM( - 'PENDING', - 'IN_PROGRESS', - 'COMPLETED', - 'REJECTED' - ) COMMENT 'āļŠāļ–āļēāļ™āļ°', - comments TEXT COMMENT 'āļ„āļ§āļēāļĄāļ„āļīāļ”āđ€āļŦāđ‡āļ™', - completed_at DATETIME COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđ€āļŠāļĢāđ‡āļˆāļŠāļīāđ‰āļ™', - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', - state_context JSON NULL COMMENT 'Snapshot of workflow state context', - FOREIGN KEY (rfa_revision_id) REFERENCES rfa_revisions(id) ON DELETE CASCADE, - FOREIGN KEY (organization_id) REFERENCES organizations(id), - FOREIGN KEY (assigned_to) REFERENCES users(user_id) + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + rfa_revision_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡ RFA Revision', + step_number INT NOT NULL COMMENT 'āļĨāļģāļ”āļąāļšāļ‚āļąāđ‰āļ™āļ•āļ­āļ™', + organization_id INT NOT NULL COMMENT 'āļ­āļ‡āļ„āđŒāļāļĢāļ—āļĩāđˆāļĢāļąāļšāļœāļīāļ”āļŠāļ­āļš', + assigned_to INT COMMENT 'āļœāļđāđ‰āđƒāļŠāđ‰āļ—āļĩāđˆāđ„āļ”āđ‰āļĢāļąāļšāļĄāļ­āļšāļŦāļĄāļēāļĒ', + action_type ENUM('REVIEW', 'APPROVE', 'ACKNOWLEDGE ') COMMENT 'āļ›āļĢāļ°āđ€āļ āļ—āļāļēāļĢāļāļĢāļ°āļ—āļģ', + status ENUM( + 'PENDING', + 'IN_PROGRESS', + 'COMPLETED', + 'REJECTED ' + ) COMMENT 'āļŠāļ–āļēāļ™āļ°', + comments TEXT COMMENT 'āļ„āļ§āļēāļĄāļ„āļīāļ”āđ€āļŦāđ‡āļ™', + completed_at DATETIME COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđ€āļŠāļĢāđ‡āļˆāļŠāļīāđ‰āļ™', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', + state_context JSON NULL COMMENT 'Snapshot of workflow state context', + FOREIGN KEY (rfa_revision_id) REFERENCES rfa_revisions(id) ON DELETE CASCADE, + FOREIGN KEY (organization_id) REFERENCES organizations(id), + FOREIGN KEY (assigned_to) REFERENCES users(user_id) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āļ›āļĢāļ°āļ§āļąāļ•āļī (Log) āļāļēāļĢāļ­āļ™āļļāļĄāļąāļ•āļīāļ‚āļ­āļ‡ RFA āļˆāļĢāļīāļ‡āļ•āļēāļĄāļŠāļēāļĒāļ‡āļēāļ™'; -- ===================================================== -- 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 -) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļĢāļ°āļŦāļ§āđˆāļēāļ‡ āļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāļŦāļĨāļąāļ-āļĒāđˆāļ­āļĒ (M:N)'; + 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) -) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ "āļĨāļđāļ" āđ€āļāđ‡āļšāļ›āļĢāļ°āļ§āļąāļ•āļī (Revisions) āļ‚āļ­āļ‡ shop_drawings (1:N)'; + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡ Revision', + shop_drawing_id INT NOT NULL COMMENT 'Master ID', + revision_number INT NOT NULL COMMENT 'āļŦāļĄāļēāļĒāđ€āļĨāļ‚ Revision (āđ€āļŠāđˆāļ™ 0, 1, 2...)', + revision_label VARCHAR(10) COMMENT 'Revision āļ—āļĩāđˆāđāļŠāļ”āļ‡ (āđ€āļŠāđˆāļ™ A, B, 1.1)', + revision_date DATE COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļ‚āļ­āļ‡ Revision', + description TEXT COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒāļāļēāļĢāđāļāđ‰āđ„āļ‚', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', + FOREIGN KEY (shop_drawing_id) REFERENCES shop_drawings(id) ON DELETE CASCADE, + UNIQUE KEY ux_sd_rev_drawing_revision (shop_drawing_id, revision_number) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ "āļĨāļđāļ" āđ€āļāđ‡āļšāļ›āļĢāļ°āļ§āļąāļ•āļī (Revisions) āļ‚āļ­āļ‡ shop_drawings (1 :N)'; -- āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļĢāļ°āļŦāļ§āđˆāļēāļ‡ shop_drawing_revisions āļāļąāļš contract_drawings (M:N) CREATE TABLE shop_drawing_revision_contract_refs ( - shop_drawing_revision_id INT COMMENT 'ID āļ‚āļ­āļ‡ Shop Drawing Revision', - contract_drawing_id INT COMMENT 'ID āļ‚āļ­āļ‡ Contract Drawing', - PRIMARY KEY (shop_drawing_revision_id, contract_drawing_id), - FOREIGN KEY (shop_drawing_revision_id) REFERENCES shop_drawing_revisions(id) ON DELETE CASCADE, - FOREIGN KEY (contract_drawing_id) REFERENCES contract_drawings(id) ON DELETE CASCADE -) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļĢāļ°āļŦāļ§āđˆāļēāļ‡ shop_drawing_revisions āļāļąāļš contract_drawings (M:N)'; + 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 āđ€āļāđ‡āļšāļŠāļ–āļēāļ™āļ°āđƒāļšāđ€āļ§āļĩāļĒāļ™'; 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); + ('IN_REVIEW', 'In Review', 2), + ('COMPLETED', 'āļ›Completed', 3), + ('CANCELLED', 'Cancelled / Withdrawn', 9); -- āļ•āļēāļĢāļēāļ‡ "āđāļĄāđˆ" āļ‚āļ­āļ‡āđƒāļšāđ€āļ§āļĩāļĒāļ™āđ€āļ­āļāļŠāļēāļĢāļ āļēāļĒāđƒāļ™ 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 = 'āļ•āļēāļĢāļēāļ‡ "āđāļĄāđˆ" āļ‚āļ­āļ‡āđƒāļšāđ€āļ§āļĩāļĒāļ™āđ€āļ­āļāļŠāļēāļĢāļ āļēāļĒāđƒāļ™'; -- āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļšāđāļĄāđˆāđāļšāļšāļŠāļēāļĒāļ‡āļēāļ™ CREATE TABLE circulation_templates ( - id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', - template_name VARCHAR(100) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āđāļĄāđˆāđāļšāļšāļŠāļēāļĒāļ‡āļēāļ™', - description TEXT COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒ', - organization_id INT NOT NULL 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 (organization_id) REFERENCES organizations(id) + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + template_name VARCHAR(100) NOT NULL COMMENT 'āļŠāļ·āđˆāļ­āđāļĄāđˆāđāļšāļšāļŠāļēāļĒāļ‡āļēāļ™', + description TEXT COMMENT 'āļ„āļģāļ­āļ˜āļīāļšāļēāļĒ', + organization_id INT NOT NULL 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 (organization_id) REFERENCES organizations(id) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡ Master āđ€āļāđ‡āļšāđāļĄāđˆāđāļšāļšāļŠāļēāļĒāļ‡āļēāļ™'; -- āļ•āļēāļĢāļēāļ‡āļĨāļđāļ āđ€āļāđ‡āļšāļ‚āļąāđ‰āļ™āļ•āļ­āļ™āđƒāļ™āđāļĄāđˆāđāļšāļš CREATE TABLE circulation_template_assignees ( - id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', - template_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āđāļĄāđˆāđāļšāļš', - step_number INT NOT NULL COMMENT 'āļĨāļģāļ”āļąāļšāļ‚āļąāđ‰āļ™āļ•āļ­āļ™', - organization_id INT NOT NULL COMMENT 'āļ­āļ‡āļ„āđŒāļāļĢāļ—āļĩāđˆāļĢāļąāļšāļœāļīāļ”āļŠāļ­āļš', - role_id INT COMMENT 'āļšāļ—āļšāļēāļ—āļ—āļĩāđˆāļĢāļąāļšāļœāļīāļ”āļŠāļ­āļš', - duration_days INT COMMENT 'āļĢāļ°āļĒāļ°āđ€āļ§āļĨāļēāļ—āļĩāđˆāļāļģāļŦāļ™āļ” (āļ§āļąāļ™)', - is_optional BOOLEAN DEFAULT FALSE COMMENT 'āđ€āļ›āđ‡āļ™āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āđ€āļĨāļ·āļ­āļāļŦāļĢāļ·āļ­āđ„āļĄāđˆ', - FOREIGN KEY (template_id) REFERENCES circulation_templates(id) ON DELETE CASCADE, - FOREIGN KEY (organization_id) REFERENCES organizations(id), - FOREIGN KEY (role_id) REFERENCES roles(role_id) + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + template_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āđāļĄāđˆāđāļšāļš', + step_number INT NOT NULL COMMENT 'āļĨāļģāļ”āļąāļšāļ‚āļąāđ‰āļ™āļ•āļ­āļ™', + organization_id INT NOT NULL COMMENT 'āļ­āļ‡āļ„āđŒāļāļĢāļ—āļĩāđˆāļĢāļąāļšāļœāļīāļ”āļŠāļ­āļš', + role_id INT COMMENT 'āļšāļ—āļšāļēāļ—āļ—āļĩāđˆāļĢāļąāļšāļœāļīāļ”āļŠāļ­āļš', + duration_days INT COMMENT 'āļĢāļ°āļĒāļ°āđ€āļ§āļĨāļēāļ—āļĩāđˆāļāļģāļŦāļ™āļ” (āļ§āļąāļ™)', + is_optional BOOLEAN DEFAULT FALSE COMMENT 'āđ€āļ›āđ‡āļ™āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āđ€āļĨāļ·āļ­āļāļŦāļĢāļ·āļ­āđ„āļĄāđˆ', + FOREIGN KEY (template_id) REFERENCES circulation_templates(id) ON DELETE CASCADE, + FOREIGN KEY (organization_id) REFERENCES organizations(id), + FOREIGN KEY (role_id) REFERENCES roles(role_id) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āļĨāļđāļ āđ€āļāđ‡āļšāļ‚āļąāđ‰āļ™āļ•āļ­āļ™āđƒāļ™āđāļĄāđˆāđāļšāļš'; -- āļ•āļēāļĢāļēāļ‡āļ›āļĢāļ°āļ§āļąāļ•āļī (Log) āļāļēāļĢāļŠāđˆāļ‡āļ•āđˆāļ­āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢāļˆāļĢāļīāļ‡āļ•āļēāļĄ Workflow CREATE TABLE circulation_routings ( - id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', - circulation_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āđƒāļšāđ€āļ§āļĩāļĒāļ™', - step_number INT NOT NULL COMMENT 'āļĨāļģāļ”āļąāļšāļ‚āļąāđ‰āļ™āļ•āļ­āļ™', - organization_id INT NOT NULL COMMENT 'āļ­āļ‡āļ„āđŒāļāļĢāļ—āļĩāđˆāļĢāļąāļšāļœāļīāļ”āļŠāļ­āļš', - assigned_to INT COMMENT 'āļœāļđāđ‰āđƒāļŠāđ‰āļ—āļĩāđˆāđ„āļ”āđ‰āļĢāļąāļšāļĄāļ­āļšāļŦāļĄāļēāļĒ', - status ENUM( - 'PENDING', - 'IN_PROGRESS', - 'COMPLETED', - 'REJECTED' - ) COMMENT 'āļŠāļ–āļēāļ™āļ°', - comments TEXT COMMENT 'āļ„āļ§āļēāļĄāļ„āļīāļ”āđ€āļŦāđ‡āļ™', - completed_at DATETIME COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđ€āļŠāļĢāđ‡āļˆāļŠāļīāđ‰āļ™', - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', - FOREIGN KEY (circulation_id) REFERENCES circulations(id) ON DELETE CASCADE, - FOREIGN KEY (organization_id) REFERENCES organizations(id), - FOREIGN KEY (assigned_to) REFERENCES users(user_id) + id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ•āļēāļĢāļēāļ‡', + circulation_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āđƒāļšāđ€āļ§āļĩāļĒāļ™', + step_number INT NOT NULL COMMENT 'āļĨāļģāļ”āļąāļšāļ‚āļąāđ‰āļ™āļ•āļ­āļ™', + organization_id INT NOT NULL COMMENT 'āļ­āļ‡āļ„āđŒāļāļĢāļ—āļĩāđˆāļĢāļąāļšāļœāļīāļ”āļŠāļ­āļš', + assigned_to INT COMMENT 'āļœāļđāđ‰āđƒāļŠāđ‰āļ—āļĩāđˆāđ„āļ”āđ‰āļĢāļąāļšāļĄāļ­āļšāļŦāļĄāļēāļĒ', + status ENUM( + 'PENDING', + 'IN_PROGRESS', + 'COMPLETED', + 'REJECTED ' + ) COMMENT 'āļŠāļ–āļēāļ™āļ°', + comments TEXT COMMENT 'āļ„āļ§āļēāļĄāļ„āļīāļ”āđ€āļŦāđ‡āļ™', + completed_at DATETIME COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđ€āļŠāļĢāđ‡āļˆāļŠāļīāđ‰āļ™', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāđāļāđ‰āđ„āļ‚āļĨāđˆāļēāļŠāļļāļ”', + FOREIGN KEY (circulation_id) REFERENCES circulations(id) ON DELETE CASCADE, + FOREIGN KEY (organization_id) REFERENCES organizations(id), + FOREIGN KEY (assigned_to) REFERENCES users(user_id) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āļ›āļĢāļ°āļ§āļąāļ•āļī (Log) āļāļēāļĢāļŠāđˆāļ‡āļ•āđˆāļ­āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢāļˆāļĢāļīāļ‡āļ•āļēāļĄ Workflow'; -- ===================================================== -- 7. ðŸ“Ī Transmittals (āđ€āļ­āļāļŠāļēāļĢāļ™āļģāļŠāđˆāļ‡) -- ===================================================== -- āļ•āļēāļĢāļēāļ‡āļ‚āđ‰āļ­āļĄāļđāļĨāđ€āļ‰āļžāļēāļ°āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢāļ™āļģāļŠāđˆāļ‡ (āđ€āļ›āđ‡āļ™āļ•āļēāļĢāļēāļ‡āļĨāļđāļ 1:1 āļ‚āļ­āļ‡ correspondences) CREATE TABLE transmittals ( - correspondence_id INT PRIMARY KEY COMMENT 'ID āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢ', - purpose ENUM( - 'FOR_APPROVAL', - 'FOR_INFORMATION', - 'FOR_REVIEW', - 'OTHER' - ) COMMENT 'āļ§āļąāļ•āļ–āļļāļ›āļĢāļ°āļŠāļ‡āļ„āđŒ', - remarks TEXT COMMENT 'āļŦāļĄāļēāļĒāđ€āļŦāļ•āļļ', - FOREIGN KEY (correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE -) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āļ‚āđ‰āļ­āļĄāļđāļĨāđ€āļ‰āļžāļēāļ°āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢāļ™āļģāļŠāđˆāļ‡ (āđ€āļ›āđ‡āļ™āļ•āļēāļĢāļēāļ‡āļĨāļđāļ 1:1 āļ‚āļ­āļ‡ correspondences)'; + correspondence_id INT PRIMARY KEY COMMENT 'ID āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢ', + purpose ENUM( + 'FOR_APPROVAL', + 'FOR_INFORMATION', + 'FOR_REVIEW', + 'OTHER ' + ) COMMENT 'āļ§āļąāļ•āļ–āļļāļ›āļĢāļ°āļŠāļ‡āļ„āđŒ', + remarks TEXT COMMENT 'āļŦāļĄāļēāļĒāđ€āļŦāļ•āļļ', + FOREIGN KEY (correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āļ‚āđ‰āļ­āļĄāļđāļĨāđ€āļ‰āļžāļēāļ°āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢāļ™āļģāļŠāđˆāļ‡ (āđ€āļ›āđ‡āļ™āļ•āļēāļĢāļēāļ‡āļĨāļđāļ 1 :1 āļ‚āļ­āļ‡ correspondences)'; -- āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļĢāļ°āļŦāļ§āđˆāļēāļ‡ transmittals āđāļĨāļ°āđ€āļ­āļāļŠāļēāļĢāļ—āļĩāđˆāļ™āļģāļŠāđˆāļ‡ (M:N) CREATE TABLE transmittal_items ( - id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļĢāļēāļĒāļāļēāļĢ', - transmittal_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡ Transmittal', - item_correspondence_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢāļ—āļĩāđˆāđāļ™āļšāđ„āļ›', - quantity INT DEFAULT 1 COMMENT 'āļˆāļģāļ™āļ§āļ™', - remarks VARCHAR(255) COMMENT 'āļŦāļĄāļēāļĒāđ€āļŦāļ•āļļāļŠāļģāļŦāļĢāļąāļšāļĢāļēāļĒāļāļēāļĢāļ™āļĩāđ‰', - FOREIGN KEY (transmittal_id) REFERENCES transmittals(correspondence_id) ON DELETE CASCADE, - FOREIGN KEY (item_correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE, - UNIQUE KEY ux_transmittal_item (transmittal_id, item_correspondence_id) -) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄāļĢāļ°āļŦāļ§āđˆāļēāļ‡ transmittals āđāļĨāļ°āđ€āļ­āļāļŠāļēāļĢāļ—āļĩāđˆāļ™āļģāļŠāđˆāļ‡ (M:N)'; + 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 (āđ„āļŸāļĨāđŒāđāļ™āļš) -- ===================================================== @@ -1741,91 +1750,94 @@ 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 -) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄ correspondences āļāļąāļš attachments (M:N)'; + correspondence_id INT COMMENT 'ID āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢ', + attachment_id INT COMMENT 'ID āļ‚āļ­āļ‡āđ„āļŸāļĨāđŒāđāļ™āļš', + is_main_document BOOLEAN DEFAULT FALSE COMMENT '(1 = āđ„āļŸāļĨāđŒāļŦāļĨāļąāļ)', + PRIMARY KEY (correspondence_id, attachment_id), + FOREIGN KEY (correspondence_id) REFERENCES correspondences(id) ON DELETE CASCADE, + FOREIGN KEY (attachment_id) REFERENCES attachments(id) ON DELETE CASCADE +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄ correspondences āļāļąāļš attachments (M :N)'; -- āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄ circulations āļāļąāļš attachments (M:N) CREATE TABLE circulation_attachments ( - circulation_id INT COMMENT 'ID āļ‚āļ­āļ‡āđƒāļšāđ€āļ§āļĩāļĒāļ™', - attachment_id INT COMMENT 'ID āļ‚āļ­āļ‡āđ„āļŸāļĨāđŒāđāļ™āļš', - is_main_document BOOLEAN DEFAULT FALSE COMMENT '(1 = āđ„āļŸāļĨāđŒāļŦāļĨāļąāļāļ‚āļ­āļ‡āđƒāļšāđ€āļ§āļĩāļĒāļ™)', - PRIMARY KEY (circulation_id, attachment_id), - FOREIGN KEY (circulation_id) REFERENCES circulations(id) ON DELETE CASCADE, - FOREIGN KEY (attachment_id) REFERENCES attachments(id) ON DELETE CASCADE -) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄ circulations āļāļąāļš attachments (M:N)'; + circulation_id INT COMMENT 'ID āļ‚āļ­āļ‡āđƒāļšāđ€āļ§āļĩāļĒāļ™', + attachment_id INT COMMENT 'ID āļ‚āļ­āļ‡āđ„āļŸāļĨāđŒāđāļ™āļš', + is_main_document BOOLEAN DEFAULT FALSE COMMENT '(1 = āđ„āļŸāļĨāđŒāļŦāļĨāļąāļāļ‚āļ­āļ‡āđƒāļšāđ€āļ§āļĩāļĒāļ™)', + PRIMARY KEY (circulation_id, attachment_id), + FOREIGN KEY (circulation_id) REFERENCES circulations(id) ON DELETE CASCADE, + FOREIGN KEY (attachment_id) REFERENCES attachments(id) ON DELETE CASCADE +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄ circulations āļāļąāļš attachments (M :N)'; -- āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄ shop_drawing_revisions āļāļąāļš attachments (M:N) CREATE TABLE shop_drawing_revision_attachments ( - shop_drawing_revision_id INT COMMENT 'ID āļ‚āļ­āļ‡ Shop Drawing Revision', - attachment_id INT COMMENT 'ID āļ‚āļ­āļ‡āđ„āļŸāļĨāđŒāđāļ™āļš', - file_type ENUM('PDF', 'DWG', 'SOURCE', 'OTHER') COMMENT 'āļ›āļĢāļ°āđ€āļ āļ—āđ„āļŸāļĨāđŒ', - is_main_document BOOLEAN DEFAULT FALSE COMMENT '(1 = āđ„āļŸāļĨāđŒāļŦāļĨāļąāļ)', - PRIMARY KEY (shop_drawing_revision_id, attachment_id), - FOREIGN KEY (shop_drawing_revision_id) REFERENCES shop_drawing_revisions(id) ON DELETE CASCADE, - FOREIGN KEY (attachment_id) REFERENCES attachments(id) ON DELETE CASCADE -) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄ shop_drawing_revisions āļāļąāļš attachments (M:N)'; + shop_drawing_revision_id INT COMMENT 'ID āļ‚āļ­āļ‡ Shop Drawing Revision', + attachment_id INT COMMENT 'ID āļ‚āļ­āļ‡āđ„āļŸāļĨāđŒāđāļ™āļš', + file_type ENUM('PDF', 'DWG', 'SOURCE', 'OTHER ') COMMENT 'āļ›āļĢāļ°āđ€āļ āļ—āđ„āļŸāļĨāđŒ', + is_main_document BOOLEAN DEFAULT FALSE COMMENT '(1 = āđ„āļŸāļĨāđŒāļŦāļĨāļąāļ)', + PRIMARY KEY (shop_drawing_revision_id, attachment_id), + FOREIGN KEY (shop_drawing_revision_id) REFERENCES shop_drawing_revisions(id) ON DELETE CASCADE, + FOREIGN KEY (attachment_id) REFERENCES attachments(id) ON DELETE CASCADE +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄ shop_drawing_revisions āļāļąāļš attachments (M :N)'; -- āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄ contract_drawings āļāļąāļš attachments (M:N) CREATE TABLE contract_drawing_attachments ( - contract_drawing_id INT COMMENT 'ID āļ‚āļ­āļ‡ Contract Drawing', - attachment_id INT COMMENT 'ID āļ‚āļ­āļ‡āđ„āļŸāļĨāđŒāđāļ™āļš', - file_type ENUM('PDF', 'DWG', 'SOURCE', 'OTHER') COMMENT 'āļ›āļĢāļ°āđ€āļ āļ—āđ„āļŸāļĨāđŒ', - is_main_document BOOLEAN DEFAULT FALSE COMMENT '(1 = āđ„āļŸāļĨāđŒāļŦāļĨāļąāļ)', - PRIMARY KEY (contract_drawing_id, attachment_id), - FOREIGN KEY (contract_drawing_id) REFERENCES contract_drawings(id) ON DELETE CASCADE, - FOREIGN KEY (attachment_id) REFERENCES attachments(id) ON DELETE CASCADE -) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļŠāļ·āđˆāļ­āļĄ contract_drawings āļāļąāļš attachments (M:N)'; + 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 āļ‚āļ­āļ‡āđ€āļĨāļ‚āļ—āļĩāđˆāđ€āļ­āļāļŠāļēāļĢ'; -- āļ•āļēāļĢāļēāļ‡āđ€āļāđ‡āļš "āļ•āļąāļ§āļ™āļąāļš" (Running Number) āļĨāđˆāļēāļŠāļļāļ” -- 2.1 Document Numbering - Optimistic Locking -- āļĢāļ­āļ‡āļĢāļąāļš: Backend Plan T2.3, Req 3.10.5 -- āđ€āļŦāļ•āļļāļœāļĨ: āļ›āđ‰āļ­āļ‡āļāļąāļ™ Race Condition āđ€āļ§āļĨāļēāļ‚āļ­āđ€āļĨāļ‚āļ—āļĩāđˆāđ€āļ­āļāļŠāļēāļĢāļžāļĢāđ‰āļ­āļĄāļāļąāļ™ CREATE TABLE document_number_counters ( - project_id INT COMMENT 'āđ‚āļ„āļĢāļ‡āļāļēāļĢ', - originator_organization_id INT COMMENT 'āļ­āļ‡āļ„āđŒāļāļĢāļœāļđāđ‰āļŠāđˆāļ‡', - correspondence_type_id INT COMMENT 'āļ›āļĢāļ°āđ€āļ āļ—āđ€āļ­āļāļŠāļēāļĢ', - current_year INT COMMENT 'āļ›āļĩ āļ„.āļĻ. āļ‚āļ­āļ‡āļ•āļąāļ§āļ™āļąāļš', - version INT DEFAULT 0 NOT NULL COMMENT 'Optimistic Lock Version', - last_number INT DEFAULT 0 COMMENT 'āđ€āļĨāļ‚āļ—āļĩāđˆāļĨāđˆāļēāļŠāļļāļ”āļ—āļĩāđˆāđƒāļŠāđ‰āđ„āļ›āđāļĨāđ‰āļ§', - PRIMARY KEY ( - project_id, - originator_organization_id, - correspondence_type_id, - current_year - ), - FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE, - FOREIGN KEY (originator_organization_id) REFERENCES organizations(id) ON DELETE CASCADE, - FOREIGN KEY (correspondence_type_id) REFERENCES correspondence_types(id) ON DELETE CASCADE + project_id INT COMMENT 'āđ‚āļ„āļĢāļ‡āļāļēāļĢ', + originator_organization_id INT COMMENT 'āļ­āļ‡āļ„āđŒāļāļĢāļœāļđāđ‰āļŠāđˆāļ‡', + correspondence_type_id INT COMMENT 'āļ›āļĢāļ°āđ€āļ āļ—āđ€āļ­āļāļŠāļēāļĢ', + current_year INT COMMENT 'āļ›āļĩ āļ„.āļĻ.āļ‚āļ­āļ‡āļ•āļąāļ§āļ™āļąāļš', + version INT DEFAULT 0 NOT NULL COMMENT 'Optimistic Lock Version', + last_number INT DEFAULT 0 COMMENT 'āđ€āļĨāļ‚āļ—āļĩāđˆāļĨāđˆāļēāļŠāļļāļ”āļ—āļĩāđˆāđƒāļŠāđ‰āđ„āļ›āđāļĨāđ‰āļ§', + PRIMARY KEY ( + project_id, + originator_organization_id, + correspondence_type_id, + current_year + ), + FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE, + FOREIGN KEY (originator_organization_id) REFERENCES organizations(id) ON DELETE CASCADE, + FOREIGN KEY (correspondence_type_id) REFERENCES correspondence_types(id) ON DELETE CASCADE ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļāđ‡āļš "āļ•āļąāļ§āļ™āļąāļš" (Running Number) āļĨāđˆāļēāļŠāļļāļ”'; -- ===================================================== -- 10. ⚙ïļ System & Logs (āļĢāļ°āļšāļšāđāļĨāļ° Log) @@ -1834,77 +1846,83 @@ CREATE TABLE document_number_counters ( -- āļĢāļ­āļ‡āļĢāļąāļš: Backend Plan T2.5.1, Req 6.11.1 -- āđ€āļŦāļ•āļļāļœāļĨ: āđ€āļžāļ·āđˆāļ­ Validate āđ‚āļ„āļĢāļ‡āļŠāļĢāđ‰āļēāļ‡ JSON Details āļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢāđāļ•āđˆāļĨāļ°āļ›āļĢāļ°āđ€āļ āļ—āđāļšāļš Centralized CREATE TABLE IF NOT EXISTS json_schemas ( - id INT AUTO_INCREMENT PRIMARY KEY, - schema_code VARCHAR(100) NOT NULL UNIQUE COMMENT 'āļĢāļŦāļąāļŠ Schema āđ€āļŠāđˆāļ™ RFA_DWG_V1, CORR_GENERIC', - version INT NOT NULL DEFAULT 1 COMMENT 'āđ€āļ§āļ­āļĢāđŒāļŠāļąāļ™āļ‚āļ­āļ‡ Schema', - schema_definition JSON NOT NULL COMMENT 'āđ‚āļ„āļĢāļ‡āļŠāļĢāđ‰āļēāļ‡ JSON Schema (Standard Format)', - is_active BOOLEAN DEFAULT TRUE, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - INDEX idx_schema_code (schema_code) + id INT AUTO_INCREMENT PRIMARY KEY, + schema_code VARCHAR(100) NOT NULL UNIQUE COMMENT 'āļĢāļŦāļąāļŠ Schema āđ€āļŠāđˆāļ™ RFA_DWG_V1, + CORR_GENERIC', + version INT NOT NULL DEFAULT 1 COMMENT 'āđ€āļ§āļ­āļĢāđŒāļŠāļąāļ™āļ‚āļ­āļ‡ Schema', + schema_definition JSON NOT NULL COMMENT 'āđ‚āļ„āļĢāļ‡āļŠāļĢāđ‰āļēāļ‡ JSON Schema (Standard Format)', + is_active BOOLEAN DEFAULT TRUE, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_schema_code (schema_code) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci; -- 1.2 User Preferences -- āļĢāļ­āļ‡āļĢāļąāļš: Req 5.5, 6.8.3 -- āđ€āļŦāļ•āļļāļœāļĨ: āđāļĒāļāļāļēāļĢāļ•āļąāđ‰āļ‡āļ„āđˆāļē Notification āđāļĨāļ° UI āļ­āļ­āļāļˆāļēāļāļ•āļēāļĢāļēāļ‡ Users āļŦāļĨāļąāļ CREATE TABLE IF NOT EXISTS 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 PRIMARY KEY 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 TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āđ€āļ§āļĨāļēāļ—āļĩāđˆāļāļĢāļ°āļ—āļģ', - FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE - SET NULL + audit_id BIGINT PRIMARY KEY 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 TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āđ€āļ§āļĨāļēāļ—āļĩāđˆāļāļĢāļ°āļ—āļģ', + FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE + SET NULL ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āđ€āļāđ‡āļšāļšāļąāļ™āļ—āļķāļāļāļēāļĢāļāļĢāļ°āļ—āļģāļ‚āļ­āļ‡āļœāļđāđ‰āđƒāļŠāđ‰'; -- āļ•āļēāļĢāļēāļ‡āļŠāļģāļŦāļĢāļąāļšāļˆāļąāļ”āļāļēāļĢāļāļēāļĢāđāļˆāđ‰āļ‡āđ€āļ•āļ·āļ­āļ™ (Email/Line/System) CREATE TABLE notifications ( - id INT PRIMARY KEY 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 TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', - FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE -) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āļŠāļģāļŦāļĢāļąāļšāļˆāļąāļ”āļāļēāļĢāļāļēāļĢāđāļˆāđ‰āļ‡āđ€āļ•āļ·āļ­āļ™ (Email/Line/System)'; + id INT PRIMARY KEY 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 TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡', + FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āļŠāļģāļŦāļĢāļąāļšāļˆāļąāļ”āļāļēāļĢāļāļēāļĢāđāļˆāđ‰āļ‡āđ€āļ•āļ·āļ­āļ™ (Email / Line / System)'; -- āļ•āļēāļĢāļēāļ‡āļŠāļģāļŦāļĢāļąāļšāļˆāļąāļ”āļāļēāļĢāļ”āļąāļŠāļ™āļĩāļāļēāļĢāļ„āđ‰āļ™āļŦāļēāļ‚āļąāđ‰āļ™āļŠāļđāļ‡ (Full-text Search) CREATE TABLE search_indices ( - id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID āļ‚āļ­āļ‡āļ”āļąāļŠāļ™āļĩ', - entity_type VARCHAR(50) NOT NULL COMMENT 'āļŠāļ™āļīāļ”āđ€āļ­āļ™āļ—āļīāļ•āļĩ (āđ€āļŠāđˆāļ™ ''correspondence'', ''rfa'')', - entity_id INT NOT NULL COMMENT 'ID āļ‚āļ­āļ‡āđ€āļ­āļ™āļ—āļīāļ•āļĩ', - content TEXT NOT NULL COMMENT 'āđ€āļ™āļ·āđ‰āļ­āļŦāļēāļ—āļĩāđˆāļˆāļ°āļ„āđ‰āļ™āļŦāļē', - indexed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'āļ§āļąāļ™āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡/āļ­āļąāļ›āđ€āļ”āļ•āļąāļŠāļ™āļĩ' -) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'āļ•āļēāļĢāļēāļ‡āļŠāļģāļŦāļĢāļąāļšāļˆāļąāļ”āļāļēāļĢāļ”āļąāļŠāļ™āļĩāļāļēāļĢāļ„āđ‰āļ™āļŦāļēāļ‚āļąāđ‰āļ™āļŠāļđāļ‡ (Full-text Search)'; + 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 @@ -1913,21 +1931,21 @@ 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 INDEX idx_corr_rev_v_subtype (v_doc_subtype); -- āļ—āļģāđāļšāļšāđ€āļ”āļĩāļĒāļ§āļāļąāļ™āļāļąāļš RFA Revisions āļŦāļēāļāļĄāļĩāļāļēāļĢāđ€āļāđ‡āļš JSON details ALTER TABLE rfa_revisions ADD COLUMN details JSON NULL COMMENT 'RFA Specific Details' AFTER description; ALTER TABLE rfa_revisions ADD COLUMN v_ref_drawing_count INT GENERATED ALWAYS AS ( - JSON_UNQUOTE(JSON_EXTRACT(details, '$.drawingCount')) - ) VIRTUAL; + JSON_UNQUOTE(JSON_EXTRACT(details, '$.drawingCount')) + ) VIRTUAL; -- ============================================================ -- 5. PARTITIONING PREPARATION (Advance - Optional) -- ============================================================ @@ -1985,10 +2003,10 @@ CREATE INDEX idx_backup_logs_completed_at ON backup_logs(completed_at); -- ===================================================== -- 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 + 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); @@ -2010,346 +2028,346 @@ 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 + 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 + 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; + 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 AS rfa_type_name, - 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 + r.rfa_type_id, + rt.type_code AS rfa_type_code, + rt.type_name AS rfa_type_name, + 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 + 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; + 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 + 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 + 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 āđāļŠāļ”āļ‡āļĢāļēāļĒāļāļēāļĢ "āļ‡āļēāļ™āļ‚āļ­āļ‡āļ‰āļąāļ™" (My Tasks) āļ—āļĩāđˆāļĒāļąāļ‡āđ„āļĄāđˆāđ€āļŠāļĢāđ‡āļˆ CREATE VIEW v_user_tasks AS SELECT cr.id AS routing_id, - c.id AS circulation_id, - c.circulation_no, - c.circulation_subject, - c.correspondence_id, - corr.correspondence_number, - corr.project_id, - p.project_code, - p.project_name, - cr.assigned_to AS user_id, - u.username, - u.first_name, - u.last_name, - cr.organization_id, - org.organization_name, - cr.step_number, - cr.status AS task_status, - cr.comments, - cr.completed_at, - cr.created_at AS assigned_at, - c.created_at AS circulation_created_at + c.id AS circulation_id, + c.circulation_no, + c.circulation_subject, + c.correspondence_id, + corr.correspondence_number, + corr.project_id, + p.project_code, + p.project_name, + cr.assigned_to AS user_id, + u.username, + u.first_name, + u.last_name, + cr.organization_id, + org.organization_name, + cr.step_number, + cr.status AS task_status, + cr.comments, + cr.completed_at, + cr.created_at AS assigned_at, + c.created_at AS circulation_created_at FROM circulation_routings cr - INNER JOIN circulations c ON cr.circulation_id = c.id - INNER JOIN correspondences corr ON c.correspondence_id = corr.id - INNER JOIN projects p ON corr.project_id = p.id - INNER JOIN organizations org ON cr.organization_id = org.id - INNER JOIN users u ON cr.assigned_to = u.user_id + INNER JOIN circulations c ON cr.circulation_id = c.id + INNER JOIN correspondences corr ON c.correspondence_id = corr.id + INNER JOIN projects p ON corr.project_id = p.id + INNER JOIN organizations org ON cr.organization_id = org.id + INNER JOIN users u ON cr.assigned_to = u.user_id WHERE cr.status IN ('PENDING', 'IN_PROGRESS') - AND cr.assigned_to IS NOT NULL; + AND cr.assigned_to IS NOT NULL; -- 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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; + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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; + 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 + 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 + 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 + 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; + 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 -- ===================================================== diff --git a/Documnets/Project/4_Data_Dictionary_V1_4_2.md b/Documnets/Project/4_Data_Dictionary_V1_4_2.md index a8b2966..2a919ad 100644 --- a/Documnets/Project/4_Data_Dictionary_V1_4_2.md +++ b/Documnets/Project/4_Data_Dictionary_V1_4_2.md @@ -146,6 +146,7 @@ | last_login_at | TIMESTAMP | NULL | Last successful login timestamp | | created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp | | updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp | +| deleted_at | DATETIME | NULL | Deleted at | **Indexes**: diff --git a/Setting Project.md b/Setting Project.md index c0d325a..af228f7 100644 --- a/Setting Project.md +++ b/Setting Project.md @@ -117,7 +117,7 @@ PORT=3000 NODE_ENV=development # Security -JWT_SECRET=your_super_secret_key_change_it +JWT_SECRET=eebc122aa65adde8c76c6a0847d9649b2b67a06db1504693e6c912e51499b76e ``` ### āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļ•āđˆāļ­āđ„āļ› (Next Steps) @@ -374,3 +374,144 @@ JWT_EXPIRATION=8h 2. **Environment:** āļ„āļ§āļĢāđāļĒāļ Secret āļĢāļ°āļŦāļ§āđˆāļēāļ‡āđ€āļ„āļĢāļ·āđˆāļ­āļ‡ `Development` āđāļĨāļ° `Production` āđ„āļĄāđˆāļ„āļ§āļĢāđƒāļŠāđ‰ Key āđ€āļ”āļĩāļĒāļ§āļāļąāļ™ āļ„āļļāļ“āļ•āđ‰āļ­āļ‡āļāļēāļĢāđƒāļŦāđ‰āļœāļĄāļŠāđˆāļ§āļĒāļ•āļąāđ‰āļ‡āļ„āđˆāļē `ConfigModule` āđƒāļ™ NestJS āđ€āļžāļ·āđˆāļ­āļ­āđˆāļēāļ™āļ„āđˆāļē `JWT_SECRET` āļ™āļĩāđ‰āļ­āļĒāđˆāļēāļ‡āļ›āļĨāļ­āļ”āļ āļąāļĒāļžāļĢāđ‰āļ­āļĄ Validate āļ§āđˆāļēāļŦāđ‰āļēāļĄāđ€āļ›āđ‡āļ™āļ„āđˆāļēāļ§āđˆāļēāļ‡āđ„āļŦāļĄāļ„āļĢāļąāļš? + +## āđ„āļ”āđ‰āđ€āļĨāļĒāļ„āļĢāļąāļš āđ€āļĢāļēāļĄāļēāļĨāļļāļĒāļ‡āļēāļ™ **T0.1 Secure Configuration Setup** āļ•āļēāļĄāđāļœāļ™ Backend Plan āļāļąāļ™āļ•āđˆāļ­āļ„āļĢāļąāļš + +āđ€āļ›āđ‰āļēāļŦāļĄāļēāļĒāļ‚āļ­āļ‡ Task āļ™āļĩāđ‰āļ„āļ·āļ­āļāļēāļĢāļ—āļģāđƒāļŦāđ‰āļĢāļ°āļšāļšāļ­āđˆāļēāļ™āļ„āđˆāļē Environment Variables āđ„āļ”āđ‰āļ­āļĒāđˆāļēāļ‡āļ–āļđāļāļ•āđ‰āļ­āļ‡ āđāļĨāļ° **"āļ•āđ‰āļ­āļ‡āđ„āļĄāđˆ Start"** āļ–āđ‰āļēāļ„āđˆāļē Config āļŠāļģāļ„āļąāļāđ† (āđ€āļŠāđˆāļ™ Database Password, JWT Secret) āļŦāļēāļĒāđ„āļ› āļŦāļĢāļ·āļ­āđ„āļĄāđˆāļ–āļđāļāļ•āđ‰āļ­āļ‡ āđ€āļžāļ·āđˆāļ­āļ„āļ§āļēāļĄāļ›āļĨāļ­āļ”āļ āļąāļĒāļ„āļĢāļąāļš + +### 1. āļ•āļīāļ”āļ•āļąāđ‰āļ‡ Library āļ—āļĩāđˆāļˆāļģāđ€āļ›āđ‡āļ™ + +āđ€āļĢāļēāļˆāļ°āđƒāļŠāđ‰ `@nestjs/config` āļŠāļģāļŦāļĢāļąāļšāļˆāļąāļ”āļāļēāļĢ Config āđāļĨāļ° `joi` āļŠāļģāļŦāļĢāļąāļšāļ•āļĢāļ§āļˆāļŠāļ­āļšāļ„āļ§āļēāļĄāļ–āļđāļāļ•āđ‰āļ­āļ‡ (Validation) āļ„āļĢāļąāļš + +āļĢāļąāļ™āļ„āļģāļŠāļąāđˆāļ‡āļ™āļĩāđ‰āđƒāļ™ Terminal: + +```bash +pnpm add @nestjs/config joi +``` + +### 2. āļŠāļĢāđ‰āļēāļ‡ Validation Schema + +āđ€āļĢāļēāļˆāļ°āđāļĒāļ Logic āļāļēāļĢāļ•āļĢāļ§āļˆāļŠāļ­āļšāļ­āļ­āļāļĄāļēāđ€āļ›āđ‡āļ™āđ„āļŸāļĨāđŒāđ€āļ‰āļžāļēāļ° āđ€āļžāļ·āđˆāļ­āđƒāļŦāđ‰āđ‚āļ„āđ‰āļ”āđ€āļ›āđ‡āļ™āļĢāļ°āđ€āļšāļĩāļĒāļšāļ„āļĢāļąāļš + +āļŠāļĢāđ‰āļēāļ‡āđ„āļŸāļĨāđŒāđƒāļŦāļĄāđˆ: `src/common/config/env.validation.ts` + +```typescript +// File: src/common/config/env.validation.ts +import Joi from 'joi'; + +// āļŠāļĢāđ‰āļēāļ‡ Schema āļŠāļģāļŦāļĢāļąāļšāļ•āļĢāļ§āļˆāļŠāļ­āļšāļ„āđˆāļē Environment Variables +export const envValidationSchema = Joi.object({ + // 1. Application Environment + NODE_ENV: Joi.string() + .valid('development', 'production', 'test', 'provision') + .default('development'), + PORT: Joi.number().default(3000), + + // 2. Database Configuration (MariaDB) + // āļŦāđ‰āļēāļĄāđ€āļ›āđ‡āļ™āļ„āđˆāļēāļ§āđˆāļēāļ‡ (required) + DB_HOST: Joi.string().required(), + DB_PORT: Joi.number().default(3306), + DB_USERNAME: Joi.string().required(), + DB_PASSWORD: Joi.string().required(), + DB_DATABASE: Joi.string().required(), + + // 3. Security (JWT) + // āļ•āđ‰āļ­āļ‡āļĄāļĩāļ„āđˆāļē āđāļĨāļ°āļ„āļ§āļĢāļĒāļēāļ§āļžāļ­ (āļ•āļĢāļ§āļˆāļŠāļ­āļšāļ„āļ§āļēāļĄāļĒāļēāļ§āđ„āļ”āđ‰āļ–āđ‰āļēāļĢāļ°āļšāļļ min) + JWT_SECRET: Joi.string().required().min(32).message('JWT_SECRET must be at least 32 characters long for security.'), + JWT_EXPIRATION: Joi.string().default('8h'), +}); +``` + +### 3. āļ­āļąāļ›āđ€āļ”āļ• `AppModule` āđƒāļŦāđ‰āđƒāļŠāđ‰ Validation + +āļāļĨāļąāļšāđ„āļ›āđāļāđ‰āđ„āļ‚āđ„āļŸāļĨāđŒ `src/app.module.ts` āđ€āļžāļ·āđˆāļ­āļ™āļģ Schema āļ—āļĩāđˆāđ€āļĢāļēāļŠāļĢāđ‰āļēāļ‡āļĄāļēāđƒāļŠāđ‰āļ‡āļēāļ™āļ„āļĢāļąāļš + +```typescript +// File: src/app.module.ts +import { Module } from '@nestjs/common'; +import { ConfigModule, ConfigService } from '@nestjs/config'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { AppController } from './app.controller'; +import { AppService } from './app.service'; +import { envValidationSchema } from './common/config/env.validation.js'; // āļŠāļąāļ‡āđ€āļāļ• .js āļŠāļģāļŦāļĢāļąāļš ESM + +@Module({ + imports: [ + // 1. Setup Config Module āļžāļĢāđ‰āļ­āļĄ Validation + ConfigModule.forRoot({ + isGlobal: true, // āđ€āļĢāļĩāļĒāļāđƒāļŠāđ‰āđ„āļ”āđ‰āļ—āļąāđˆāļ§āļ—āļąāđ‰āļ‡ App āđ„āļĄāđˆāļ•āđ‰āļ­āļ‡ import āļ‹āđ‰āļģ + envFilePath: '.env', // āļ­āđˆāļēāļ™āđ„āļŸāļĨāđŒ .env (āļŠāļģāļŦāļĢāļąāļš Dev) + validationSchema: envValidationSchema, // āđƒāļŠāđ‰ Schema āļ—āļĩāđˆāđ€āļĢāļēāļŠāļĢāđ‰āļēāļ‡āđ€āļžāļ·āđˆāļ­āļ•āļĢāļ§āļˆāļŠāļ­āļš + validationOptions: { + // āļ–āđ‰āļēāļĄāļĩāļ„āđˆāļēāđ„āļŦāļ™āđ„āļĄāđˆāļœāđˆāļēāļ™ Validation āđƒāļŦāđ‰ Error āđāļĨāļ°āļŦāļĒāļļāļ”āļ—āļģāļ‡āļēāļ™āļ—āļąāļ™āļ—āļĩ + abortEarly: true, + }, + }), + + // 2. Setup TypeORM (MariaDB) + TypeOrmModule.forRootAsync({ + imports: [ConfigModule], + inject: [ConfigService], + useFactory: async (configService: ConfigService) => ({ + type: 'mariadb', + host: configService.get('DB_HOST'), + port: configService.get('DB_PORT'), + username: configService.get('DB_USERNAME'), + password: configService.get('DB_PASSWORD'), + database: configService.get('DB_DATABASE'), + autoLoadEntities: true, + // synchronize: true āđ€āļ‰āļžāļēāļ°āļ•āļ­āļ™ Dev āđ€āļ—āđˆāļēāļ™āļąāđ‰āļ™ āļŦāđ‰āļēāļĄāđƒāļŠāđ‰āļšāļ™ Prod + synchronize: configService.get('NODE_ENV') === 'development', + }), + }), + ], + controllers: [AppController], + providers: [AppService], +}) +export class AppModule {} +``` + +### 4\. āļŠāļĢāđ‰āļēāļ‡āđ„āļŸāļĨāđŒ Template āļŠāļģāļŦāļĢāļąāļš Docker Override (āļ•āļēāļĄāđāļœāļ™ T0.1) + +āļ•āļēāļĄāđāļœāļ™āļ‡āļēāļ™ āđ€āļĢāļēāļ•āđ‰āļ­āļ‡āđ€āļ•āļĢāļĩāļĒāļĄāđ„āļŸāļĨāđŒ `docker-compose.override.yml.example` āđ€āļžāļ·āđˆāļ­āđƒāļŦāđ‰āļ™āļąāļāļžāļąāļ’āļ™āļēāļ„āļ™āļ­āļ·āđˆāļ™āļĢāļđāđ‰āļ§āđˆāļēāļ•āđ‰āļ­āļ‡ Inject Secrets āļ­āļĒāđˆāļēāļ‡āđ„āļĢ āđ‚āļ”āļĒāđ„āļĄāđˆāđ€āļ›āļīāļ”āđ€āļœāļĒāļ„āļ§āļēāļĄāļĨāļąāļšāđƒāļ™ `docker-compose.yml` āļŦāļĨāļąāļ + +āļŠāļĢāđ‰āļēāļ‡āđ„āļŸāļĨāđŒ: `docker-compose.override.yml.example` āļ—āļĩāđˆ root project: + +```yaml +version: '3.8' + +services: + # Override āļ„āđˆāļē Config āļ‚āļ­āļ‡ Service Backend (āđ€āļĄāļ·āđˆāļ­āđ€āļĢāļēāļŠāļĢāđ‰āļēāļ‡ Container Backend āđƒāļ™āļ­āļ™āļēāļ„āļ•) + backend: + environment: + # āđƒāļŠāđˆ Secrets āļˆāļĢāļīāļ‡āđƒāļ™āđ„āļŸāļĨāđŒ override āļ™āļĩāđ‰ (āđāļĨāļ°āļŦāđ‰āļēāļĄ commit āđ„āļŸāļĨāđŒāļ™āļĩāđ‰) + - DB_PASSWORD=secret_password_here + - JWT_SECRET=very_long_and_secure_secret_here + - NODE_ENV=development + + # Override āļŠāļģāļŦāļĢāļąāļš Database (Local Dev) + mariadb: + environment: + - MYSQL_ROOT_PASSWORD=secret_password_here + - MYSQL_PASSWORD=secret_password_here +``` + +### 5\. āļ—āļ”āļŠāļ­āļšāļ„āļ§āļēāļĄāļ›āļĨāļ­āļ”āļ āļąāļĒ (Validation Check) + +āļĨāļ­āļ‡āļ—āļ”āļŠāļ­āļšāļ§āđˆāļēāļĢāļ°āļšāļš Validation āļ—āļģāļ‡āļēāļ™āļ–āļđāļāļ•āđ‰āļ­āļ‡āļŦāļĢāļ·āļ­āđ„āļĄāđˆ āđ‚āļ”āļĒāļāļēāļĢ **āļĨāļš** āļŦāļĢāļ·āļ­ **āđ€āļ›āļĨāļĩāđˆāļĒāļ™āļŠāļ·āđˆāļ­** āļ•āļąāļ§āđāļ›āļĢāļŠāļģāļ„āļąāļāđƒāļ™āđ„āļŸāļĨāđŒ `.env` (āđ€āļŠāđˆāļ™ āļĨāļš `JWT_SECRET`) āđāļĨāđ‰āļ§āļĨāļ­āļ‡āļĢāļąāļ™: + +```bash +pnpm start:dev +``` + +**āļœāļĨāļĨāļąāļžāļ˜āđŒāļ—āļĩāđˆāļ„āļ§āļĢāđ„āļ”āđ‰:** +App **āļ•āđ‰āļ­āļ‡ Crash** āđāļĨāļ°āđāļŠāļ”āļ‡ Error Message āļŠāļąāļ”āđ€āļˆāļ™ āđ€āļŠāđˆāļ™: +`Config validation error: "JWT_SECRET" is required` + +āļ–āđ‰āļēāļ‚āļķāđ‰āļ™āđāļšāļšāļ™āļĩāđ‰āđāļŠāļ”āļ‡āļ§āđˆāļēāļĢāļ°āļšāļš **Secure Configuration** āļ‚āļ­āļ‡āđ€āļĢāļēāļ—āļģāļ‡āļēāļ™āļ–āļđāļāļ•āđ‰āļ­āļ‡āļ•āļēāļĄāđāļœāļ™ T0.1 āđāļĨāđ‰āļ§āļ„āļĢāļąāļš\! 🎉 + +----- + +**āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļ–āļąāļ”āđ„āļ›:** +āđ€āļĢāļēāļˆāļ°āđ„āļ›āļ•āđˆāļ­āļ—āļĩāđˆ **T0.2 Redis & Queue Infrastructure** āđ€āļžāļ·āđˆāļ­āđ€āļ•āļĢāļĩāļĒāļĄāļĢāļ°āļšāļš Caching āđāļĨāļ° Background Job āđ„āļŦāļĄāļ„āļĢāļąāļš? +