# **สรุปตารางฐานข้อมูล (Data Dictionary) - LCBP3-DMS (V1.4.0)** เอกสารนี้สรุปโครงสร้างตาราง, Foreign Keys (FK), และ Constraints ที่สำคัญทั้งหมดในฐานข้อมูล LCBP3-DMS (v1.4.0) เพื่อใช้เป็นเอกสารอ้างอิงสำหรับทีมพัฒนา Backend (NestJS) และ Frontend (Next.js) โดยอิงจาก Requirements และ SQL Script ล่าสุด ## **1. 🏢 Core & Master Data (องค์กร, โครงการ, สัญญา)** #### **1.1. organization_roles** ตาราง Master เก็บประเภทบทบาทขององค์กร (เช่น OWNER, CONTRACTOR) | Column | Type | Key | Description | | :-------- | :---------- | :----- | :--------------------------------------------------------------- | | id | INT | **PK** | ID ของตาราง | | role_name | VARCHAR(20) | UK | ชื่อบทบาท (OWNER, DESIGNER, CONSULTANT, CONTRACTOR, THIRD PARTY) | - **Unique Keys (UK):** ux_roles_name (role_name) --- #### **1.2. organizations** ตาราง Master เก็บข้อมูลองค์กรทั้งหมดที่เกี่ยวข้องในระบบ | Column | Type | Key | Description | | :---------------- | :----------- | :----- | :--------------------------------------------- | | id | INT | **PK** | ID ของตาราง | | organization_code | VARCHAR(20) | UK | รหัสองค์กร | | organization_name | VARCHAR(255) | | ชื่อองค์กร | | role_id | INT | FK | บทบาทขององค์กร (FK \-> organization_roles(id)) | | is_active | BOOLEAN | | สถานะการใช้งาน | | created_at | TIMESTAMP | | วันที่สร้าง | | updated_at | TIMESTAMP | | วันที่แก้ไขล่าสุด | - **Foreign Keys (FK):** - role_id -> organization_roles(id) (ON DELETE SET NULL) - **Unique Keys (UK):** ux_organizations_code (organization_code) --- #### **1.3. projects** ตาราง Master เก็บข้อมูลโครงการ (เช่น LCBP3C1, LCBP3C2) | Column | Type | Key | Description | | :------------------------- | :----------- | :----- | :------------------------------------------------------ | | id | INT | **PK** | ID ของตาราง | | project_code | VARCHAR(50) | UK | รหัสโครงการ | | project_name | VARCHAR(255) | | ชื่อโครงการ | | parent_project_id | INT | FK | รหัสโครงการหลัก (ถ้ามี) (FK \-> projects(id)) | | contractor_organization_id | INT | FK | รหัสองค์กรผู้รับเหมา (ถ้ามี) (FK \-> organizations(id)) | | is_active | TINYINT(1) | | สถานะการใช้งาน | - **Foreign Keys (FK):** - parent_project_id -> projects(id) (ON DELETE SET NULL) - contractor_organization_id -> organizations(id) (ON DELETE SET NULL) - **Unique Keys (UK):** uq_pro_code (project_code) --- #### **1.4. contracts** ตาราง Master เก็บข้อมูลสัญญา | Column | Type | Key | Description | | :------------ | :----------- | :----- | :----------------- | | id | INT | **PK** | ID ของตาราง | | contract_code | VARCHAR(50) | UK | รหัสสัญญา | | contract_name | VARCHAR(255) | | ชื่อสัญญา | | description | TEXT | | คำอธิบายสัญญา | | start_date | DATE | | วันที่เริ่มสัญญา | | end_date | DATE | | วันที่สิ้นสุดสัญญา | | created_at | TIMESTAMP | | วันที่สร้าง | | updated_at | TIMESTAMP | | วันที่แก้ไขล่าสุด | - **Unique Keys (UK):** ux_contracts_code (contract_code) --- ## **2. 👥 Users & RBAC (ผู้ใช้, สิทธิ์, บทบาท)** #### **2.1. users** ตาราง Master เก็บข้อมูลผู้ใช้งาน (User) | Column | Type | Key | Description | | :-------------- | :----------- | :----- | :-------------------------------------- | | user_id | INT | **PK** | ID ของตาราง | | username | VARCHAR(50) | UK | ชื่อผู้ใช้งาน | | password_hash | VARCHAR(255) | | รหัสผ่าน (Hashed) | | first_name | VARCHAR(50) | | ชื่อจริง | | last_name | VARCHAR(50) | | นามสกุล | | email | VARCHAR(100) | UK | อีเมล | | line_id | VARCHAR(100) | | LINE ID | | organization_id | INT | FK | สังกัดองค์กร (FK \-> organizations(id)) | | is_active | TINYINT(1) | | สถานะการใช้งาน | | failed_attempts | INT | | จำนวนครั้งที่ล็อกอินล้มเหลว | | locked_until | DATETIME | | ล็อกอินไม่ได้จนถึงเวลา | | last_login_at | TIMESTAMP | | วันที่และเวลาที่ล็อกอินล่าสุด | | created_at | TIMESTAMP | | วันที่สร้าง | | updated_at | TIMESTAMP | | วันที่แก้ไขล่าสุด | - **Foreign Keys (FK):** - organization_id -> organizations(id) (ON DELETE SET NULL) - **Unique Keys (UK):** ux_users_username (username), ux_users_email (email) --- #### **2.2. roles** ตาราง Master เก็บ "บทบาท" ของผู้ใช้ในระบบ (เช่น SUPER_ADMIN, ADMIN, EDITOR) | Column | Type | Key | Description | | :---------- | :----------- | :----- | :-------------------------------------------------- | | role_id | INT | **PK** | ID ของตาราง | | role_code | VARCHAR(50) | UK | รหัสบทบาท (เช่น SUPER_ADMIN, ADMIN, EDITOR, VIEWER) | | role_name | VARCHAR(100) | | ชื่อบทบาท | | description | TEXT | | คำอธิบายบทบาท | | is_system | BOOLEAN | | (1 = บทบาทของระบบ ลบไม่ได้) | - **Unique Keys (UK):** role_code --- #### **2.3. permissions** ตาราง Master เก็บ "สิทธิ์" (Permission) หรือ "การกระทำ" ทั้งหมดในระบบ | Column | Type | Key | Description | | :-------------- | :----------- | :----- | :------------------------------------------ | | permission_id | INT | **PK** | ID ของตาราง | | permission_code | VARCHAR(100) | UK | รหัสสิทธิ์ (เช่น rfas.create, rfas.view) | | description | TEXT | | คำอธิบายสิทธิ์ | | module | VARCHAR(50) | | โมดูลที่เกี่ยวข้อง | | scope_level | ENUM(...) | | ระดับขอบเขตของสิทธิ์ (GLOBAL, ORG, PROJECT) | | is_active | TINYINT(1) | | สถานะการใช้งาน | - **Unique Keys (UK):** ux_permissions_code (permission_code) --- #### **2.4. role_permissions (ตารางเชื่อม)** ตารางเชื่อมระหว่าง roles และ permissions (M:N) | Column | Type | Key | Description | | :------------ | :--- | :--------- | :----------------------------------------------- | | role_id | INT | **PK**, FK | ID ของบทบาท (FK \-> roles(role_id)) | | permission_id | INT | **PK**, FK | ID ของสิทธิ์ (FK \-> permissions(permission_id)) | - **Foreign Keys (FK):** - role_id -> roles(role_id) (ON DELETE CASCADE) - permission_id -> permissions(permission_id) (ON DELETE CASCADE) --- #### **2.5. user_roles (ตารางเชื่อม)** ตารางเชื่อมผู้ใช้ (users) กับบทบาท (roles) ในระดับ **Global** (M:N) | Column | Type | Key | Description | | :------ | :--- | :--------- | :----------------------------------- | | user_id | INT | **PK**, FK | ID ของผู้ใช้ (FK \-> users(user_id)) | | role_id | INT | **PK**, FK | ID ของบทบาท (FK \-> roles(role_id)) | - **Foreign Keys (FK):** - user_id -> users(user_id) (ON DELETE CASCADE) - role_id -> roles(role_id) (ON DELETE CASCADE) --- #### **2.6. user_project_roles (ตารางเชื่อม)** ตารางเชื่อมผู้ใช้ (users) กับบทบาท (roles) ในระดับ **Project-Specific** (M:N) | Column | Type | Key | Description | | :--------- | :--- | :--------- | :----------------------------------- | | user_id | INT | **PK**, FK | ID ของผู้ใช้ (FK \-> users(user_id)) | | project_id | INT | **PK**, FK | ID ของโครงการ (FK \-> projects(id)) | | role_id | INT | **PK**, FK | ID ของบทบาท (FK \-> roles(role_id)) | - **Foreign Keys (FK):** - user_id -> users(user_id) (ON DELETE CASCADE) - project_id -> projects(id) (ON DELETE CASCADE) - role_id -> roles(role_id) (ON DELETE CASCADE) --- ## **3. ✉️ Correspondences (เอกสารหลัก, Revisions)** #### **3.1. correspondence_types** ตาราง Master เก็บประเภทเอกสารโต้ตอบ (เช่น RFA, RFI, LETTER, MOM) | Column | Type | Key | Description | | :--------- | :----------- | :----- | :------------------------- | | id | INT | **PK** | ID ของตาราง | | type_code | VARCHAR(50) | UK | รหัสประเภท (เช่น RFA, RFI) | | type_name | VARCHAR(255) | | ชื่อประเภท | | sort_order | INT | | ลำดับการแสดงผล | | is_active | TINYINT(1) | | สถานะการใช้งาน | - **Unique Keys (UK):** type_code --- #### **3.2. correspondence_status** ตาราง Master เก็บสถานะของเอกสาร (เช่น DRAFT, SUBMITTED, CLOSED) | Column | Type | Key | Description | | :---------- | :----------- | :----- | :------------------------------------ | | id | INT | **PK** | ID ของตาราง | | status_code | VARCHAR(50) | UK | รหัสสถานะหนังสือ (เช่น DRAFT, SUBOWN) | | status_name | VARCHAR(255) | | ชื่อสถานะหนังสือ | | sort_order | INT | | ลำดับการแสดงผล | | is_active | TINYINT(1) | | สถานะการใช้งาน | - **Unique Keys (UK):** status_code --- #### **3.3. correspondences (Master)** ตาราง "แม่" ของเอกสารโต้ตอบ เก็บข้อมูลที่ไม่เปลี่ยนตาม Revision (เช่น เลขที่เอกสาร) | Column | Type | Key | Description | | :------------------------ | :----------- | :----- | :----------------------------------------------- | | id | INT | **PK** | ID ของตาราง (นี่คือ "Master ID" ที่ใช้เชื่อมโยง) | | correspondence_number | VARCHAR(100) | UK | เลขที่เอกสาร (สร้างจาก DocumentNumberingModule) | | correspondence_type_id | INT | FK | ประเภทเอกสาร (FK \-> correspondence_types(id)) | | is_internal_communication | TINYINT(1) | | (1 = ภายใน, 0 = ภายนอก) | | project_id | INT | FK | อยู่ในโครงการ (FK \-> projects(id)) | | originator_id | INT | FK | องค์กรผู้ส่ง (FK \-> organizations(id)) | | created_at | DATETIME | | วันที่สร้าง | | created_by | INT | FK | ผู้สร้าง (FK \-> users(user_id)) | | deleted_at | DATETIME | | สำหรับ Soft Delete | - **Foreign Keys (FK):** - correspondence_type_id -> correspondence_types(id) (ON DELETE RESTRICT) - project_id -> projects(id) (ON DELETE CASCADE) - originator_id -> organizations(id) (ON DELETE SET NULL) - created_by -> users(user_id) (ON DELETE SET NULL) - **Unique Keys (UK):** uq_corr_no_per_project (project_id, correspondence_number) --- #### **3.4. correspondence_revisions (Revisions)** ตาราง "ลูก" เก็บประวัติการแก้ไข (Revisions) ของ correspondences (1:N) **(ปรับปรุง V1.4.0)** | Column | Type | Key | Description | | :----------------------- | :----------- | :----- | :------------------------------------------------------- | | id | INT | **PK** | **ID ของ Revision** | | correspondence_id | INT | FK, UK | Master ID (FK \-> correspondences(id)) | | revision_number | INT | UK | หมายเลข Revision (0, 1, 2...) | | revision_label | VARCHAR(10) | | **(ใหม่)** Revision ที่แสดง (เช่น A, B, 1.1) | | is_current | BOOLEAN | UK | (1 = Revision ปัจจุบัน) | | correspondence_status_id | INT | FK | สถานะของ Revision นี้ (FK \-> correspondence_status(id)) | | title | VARCHAR(255) | | เรื่อง | | document_date | DATE | | วันที่ในเอกสาร | | issued_date | DATETIME | | วันที่ออกเอกสาร | | received_date | DATETIME | | วันที่ลงรับเอกสาร | | due_date | DATETIME | | **(ใหม่)** วันที่ครบกำหนด (ตาม Requirements 3.2.5) | | description | TEXT | | **(ใหม่)** คำอธิบายการแก้ไขใน Revision นี้ | | details | JSON | | ข้อมูลเฉพาะ (เช่น RFI details) | | created_at | DATETIME | | **(ใหม่)** วันที่สร้างเอกสาร | | created_by | INT | FK | ผู้สร้าง (FK \-> users(user_id)) | | updated_by | INT | **FK** | **(ใหม่)** ผู้แก้ไขล่าสุด (FK \-> users(user_id)) | - **Foreign Keys (FK):** - correspondence_id -> correspondences(id) (ON DELETE CASCADE) - correspondence_status_id -> correspondence_status(id) (ON DELETE RESTRICT) - created_by -> users(user_id) (ON DELETE SET NULL) - updated_by -> users(user_id) (ON DELETE SET NULL) - **Unique Keys (UK):** - uq_master_revision_number (correspondence_id, revision_number) (ป้องกัน Rev ซ้ำใน Master เดียว) - uq_master_current (correspondence_id, is_current) (ป้องกัน is_current = TRUE ซ้ำใน Master เดียว) - **Check Constraints (CHK):** chk_rev_format (ตรวจสอบรูปแบบ revision_label) --- #### **3.5. correspondence_recipients (ตารางเชื่อม)** ตารางเชื่อมผู้รับ (TO/CC) สำหรับเอกสารแต่ละฉบับ (M:N) | Column | Type | Key | Description | | :------------------------ | :--------------- | :--------- | :---------------------------------------------------------------- | | correspondence_id | INT | **PK**, FK | ID ของเอกสาร (FK \-> correspondence_revisions(correspondence_id)) | | recipient_organization_id | INT | **PK**, FK | ID องค์กรผู้รับ (FK \-> organizations(id)) | | recipient_type | ENUM('TO', 'CC') | **PK** | ประเภทผู้รับ (TO หรือ CC) | - **Foreign Keys (FK):** - correspondence_id -> correspondence_revisions(correspondence_id) (ON DELETE CASCADE) - recipient_organization_id -> organizations(id) (ON DELETE RESTRICT) --- #### **3.6. correspondence_tags (ตารางเชื่อม)** ตารางเชื่อมระหว่าง correspondences และ tags (M:N) | Column | Type | Key | Description | | :---------------- | :--- | :--------- | :---------------------------------------- | | correspondence_id | INT | **PK**, FK | ID ของเอกสาร (FK \-> correspondences(id)) | | tag_id | INT | **PK**, FK | ID ของ Tag (FK \-> tags(id)) | - **Foreign Keys (FK):** - correspondence_id -> correspondences(id) (ON DELETE CASCADE) - tag_id -> tags(id) (ON DELETE CASCADE) --- #### **3.7. correspondence_references (ตารางเชื่อม)** ตารางเชื่อมการอ้างอิงระหว่างเอกสาร (M:N) | Column | Type | Key | Description | | :-------------------- | :--- | :--------- | :--------------------------------------------- | | src_correspondence_id | INT | **PK**, FK | ID เอกสารต้นทาง (FK \-> correspondences(id)) | | tgt_correspondence_id | INT | **PK**, FK | ID เอกสารเป้าหมาย (FK \-> correspondences(id)) | - **Foreign Keys (FK):** - src_correspondence_id -> correspondences(id) (ON DELETE CASCADE) - tgt_correspondence_id -> correspondences(id) (ON DELETE CASCADE) --- ## **4. 📐 approval: RFA (เอกสารขออนุมัติ, Workflows)** #### **4.1. rfa_types / ...\_status_codes / ...\_approve_codes** ตาราง Master สำหรับ RFA - **rfa_types:** ประเภท RFA (เช่น DWG, DOC, MAT) - **rfa_status_codes:** สถานะ RFA (เช่น DFT \- Draft, FAP \- For Approve) - **rfa_approve_codes:** รหัสผลการอนุมัติ (เช่น 1A \- Approved, 3R \- Revise and Resubmit) --- #### **4.2. rfas (Master)** ตาราง "แม่" ของ RFA (มีความสัมพันธ์ 1:N กับ rfa_revisions) | Column | Type | Key | Description | | :---------- | :------- | :----- | :-------------------------------- | | id | INT | **PK** | ID ของตาราง (RFA Master ID) | | rfa_type_id | INT | FK | ประเภท RFA (FK \-> rfa_types(id)) | | created_at | DATETIME | | วันที่สร้าง | | created_by | INT | FK | ผู้สร้าง (FK \-> users(user_id)) | | deleted_at | DATETIME | | สำหรับ Soft Delete | - **Foreign Keys (FK):** - rfa_type_id -> rfa_types(id) - created_by -> users(user_id) (ON DELETE SET NULL) --- #### **4.3. rfa_revisions (Revisions)** ตาราง "ลูก" เก็บประวัติ (Revisions) ของ rfas (1:N) **(ปรับปรุง V1.4.0)** | Column | Type | Key | Description | | :------------------ | :----------- | :----- | :-------------------------------------------------------- | | id | INT | **PK** | **ID ของ Revision** | | correspondence_id | INT | FK | Master ID ของ Correspondence (FK \-> correspondences(id)) | | rfa_id | INT | FK, UK | Master ID ของ RFA (FK \-> rfas(id)) | | revision_number | INT | UK | หมายเลข Revision (0, 1, 2...) | | revision_label | VARCHAR(10) | | **(ใหม่)** Revision ที่แสดง (เช่น A, B, 1.1) | | is_current | BOOLEAN | UK | (1 = Revision ปัจจุบัน) | | rfa_status_code_id | INT | FK | สถานะ RFA (FK \-> rfa_status_codes(id)) | | rfa_approve_code_id | INT | FK | ผลการอนุมัติ (FK \-> rfa_approve_codes(id)) | | title | VARCHAR(255) | | เรื่อง | | document_date | DATE | | **(ใหม่)** วันที่ในเอกสาร | | issued_date | DATE | | **(ใหม่)** วันที่ส่งขออนุมัติ | | received_date | DATETIME | | **(ใหม่)** วันที่ลงรับเอกสาร | | approved_date | DATE | | **(ใหม่)** วันที่อนุมัติ | | description | TEXT | | **(ใหม่)** คำอธิบายการแก้ไขใน Revision นี้ | | created_at | DATETIME | | **(ใหม่)** วันที่สร้างเอกสาร | | created_by | INT | FK | ผู้สร้าง (FK \-> users(user_id)) | | updated_by | INT | **FK** | **(ใหม่)** ผู้แก้ไขล่าสุด (FK \-> users(user_id)) | - **Foreign Keys (FK):** - correspondence_id -> correspondences(id) (ON DELETE CASCADE) - rfa_id -> rfas(id) (ON DELETE CASCADE) - rfa_status_code_id -> rfa_status_codes(id) - rfa_approve_code_id -> rfa_approve_codes(id) (ON DELETE SET NULL) - created_by -> users(user_id) (ON DELETE SET NULL) - updated_by -> users(user_id) (ON DELETE SET NULL) - **Unique Keys (UK):** - uq_rr_rev_number (rfa_id, revision_number) (ป้องกัน Rev ซ้ำใน Master เดียว) - uq_rr_current (rfa_id, is_current) (ป้องกัน is_current=TRUE ซ้ำใน Master เดียว) --- #### **4.4. rfa_items (ตารางเชื่อม)** ตารางเชื่อมระหว่าง rfa_revisions (ที่เป็นประเภท DWG) กับ shop_drawing_revisions (M:N) | Column | Type | Key | Description | | :----------------------- | :--- | :------------- | :--------------------------------------------------------------- | | rfarev_correspondence_id | INT | **PK**, FK | ID ของ RFA Revision (FK \-> rfa_revisions(correspondence_id)) | | shop_drawing_revision_id | INT | **PK**, UK, FK | ID ของ Shop Drawing Revision (FK \-> shop_drawing_revisions(id)) | - **Foreign Keys (FK):** - rfarev_correspondence_id -> rfa_revisions(correspondence_id) (ON DELETE CASCADE) - shop_drawing_revision_id -> shop_drawing_revisions(id) (ON DELETE CASCADE) --- #### **4.5. rfa_workflow_templates / ...\_steps / ...\_workflows** ตารางที่เกี่ยวข้องกับ Workflow การอนุมัติ RFA - **rfa_workflow_templates:** ตาราง Master เก็บแม่แบบสายอนุมัติ (เช่น "สายอนุมัติ 3 ขั้นตอน") - **rfa_workflow_template_steps:** ตารางลูก เก็บขั้นตอนในแม่แบบ (เช่น Step 1: Org A (Review), Step 2: Org B (Approve)) - **rfa_workflows:** ตารางประวัติ (Log) การอนุมัติของ RFA จริงตามสายงงาน --- ## **5. 📐 Drawings (แบบ, หมวดหมู่)** #### **5.1. contract_drawing_volumes / ...\_cats / ...\_sub_cats** ตาราง Master สำหรับ "แบบคู่สัญญา" (Contract Drawings) - **contract_drawing_volumes:** เก็บ "เล่ม" ของแบบ - **contract_drawing_cats:** เก็บ "หมวดหมู่หลัก" ของแบบ - **contract_drawing_sub_cats:** เก็บ "หมวดหมู่ย่อย" ของแบบ --- #### **5.2. contract_drawing_subcat_cat_maps (ตารางเชื่อม - ใหม่)** **(ใหม่)** ตารางเชื่อมระหว่าง หมวดหมู่หลัก-ย่อย (M:N) | Column | Type | Key | Description | | :--------- | :--- | :--------- | :----------------- | | project_id | INT | **PK**, FK | ID ของโครงการ | | sub_cat_id | INT | **PK**, FK | ID ของหมวดหมู่ย่อย | | cat_id | INT | **PK**, FK | ID ของหมวดหมู่หลัก | - **Foreign Keys (FK) (ตามเจตนา):** - (project_id, sub_cat_id) -> contract_drawing_sub_cats(project_id, id) - (project_id, cat_id) -> contract_drawing_cats(project_id, id) - **Unique Keys (UK):** - ux_map_unique (project_id, sub_cat_id, cat_id) --- #### **5.3. contract_drawings (Master)** ตาราง Master เก็บข้อมูล "แบบคู่สัญญา" | Column | Type | Key | Description | | :--------- | :----------- | :----- | :-------------------------------------------------- | | id | INT | **PK** | ID ของตาราง | | project_id | INT | FK, UK | โครงการ (FK \-> projects(id)) | | condwg_no | VARCHAR(255) | UK | เลขที่แบบสัญญา | | title | VARCHAR(255) | | ชื่อแบบสัญญา | | sub_cat_id | INT | FK | หมวดหมู่ย่อย (FK \-> contract_drawing_sub_cats(id)) | | volume_id | INT | FK | เล่ม (FK \-> contract_drawing_volumes(id)) | | created_at | TIMESTAMP | | วันที่สร้าง | | updated_at | TIMESTAMP | | วันที่แก้ไขล่าสุด | | deleted_at | DATETIME | | **(ใหม่)** วันที่ลบ | | updated_by | INT | FK | **(ใหม่)** ผู้แก้ไขล่าสุด | - **Foreign Keys (FK):** - fk_condwg_project (project_id) -> projects(id) (ON DELETE CASCADE) - fk_condwg_subcat_same_project (project_id, sub_cat_id) -> contract_drawing_sub_cats(project_id, id) (ON DELETE RESTRICT) - fk_condwg_volume_same_project (project_id, volume_id) -> contract_drawing_volumes(project_id, id) (ON DELETE RESTRICT) - **Unique Keys (UK):** ux_condwg_no_project (project_id, condwg_no) --- #### **5.4. shop_drawing_main_categories / ...\_sub_categories** ตาราง Master สำหรับ "แบบก่อสร้าง" (Shop Drawings) - **shop_drawing_main_categories:** เก็บ "หมวดหมู่หลัก" (เช่น ARCH, STR) - **shop_drawing_sub_categories:** เก็บ "หมวดหมู่ย่อย" (เช่น STR-COLUMN) --- #### **5.5. shop_drawings (Master)** ตาราง Master เก็บข้อมูล "แบบก่อสร้าง" | Column | Type | Key | Description | | :--------------- | :----------- | :----- | :----------------------------------------------------- | | id | INT | **PK** | ID ของตาราง | | project_id | INT | FK | โครงการ (FK \-> projects(id)) | | drawing_number | VARCHAR(100) | UK | เลขที่ Shop Drawing | | title | VARCHAR(500) | | ชื่อแบบ | | main_category_id | INT | FK | หมวดหมู่หลัก (FK \-> shop_drawing_main_categories(id)) | | sub_category_id | INT | FK | หมวดหมู่ย่อย (FK \-> shop_drawing_sub_categories(id)) | | created_at | TIMESTAMP | | วันที่สร้าง | | updated_at | TIMESTAMP | | วันที่แก้ไขล่าสุด | | deleted_at | DATETIME | | **(ใหม่)** วันที่ลบ | | updated_by | INT | FK | **(ใหม่)** ผู้แก้ไขล่าสุด | - **Foreign Keys (FK):** project_id, main_category_id, sub_category_id - **Unique Keys (UK):** ux_sd_drawing_number (drawing_number) --- #### **5.6. shop_drawing_revisions (Revisions)** ตาราง "ลูก" เก็บประวัติ (Revisions) ของ shop_drawings (1:N) | Column | Type | Key | Description | | :-------------- | :---------- | :----- | :------------------------------------------------ | | id | INT | **PK** | ID ของ Revision | | shop_drawing_id | INT | FK, UK | Master ID (FK \-> shop_drawings(id)) | | revision_number | INT | UK | **(ปรับปรุง)** หมายเลข Revision (เช่น 0, 1, 2...) | | revision_label | VARCHAR(10) | | **(ปรับปรุง)** Revision ที่แสดง (เช่น A, B, 1.1) | | revision_date | DATE | | วันที่ของ Revision | | description | TEXT | | คำอธิบายการแก้ไข | | created_at | TIMESTAMP | | วันที่สร้าง | - **Foreign Keys (FK):** - shop_drawing_id -> shop_drawings(id) (ON DELETE CASCADE) - **Unique Keys (UK):** ux_sd_rev_drawing_revision (shop_drawing_id, revision_number) --- #### **5.7. shop_drawing_revision_contract_refs (ตารางเชื่อม)** ตารางเชื่อมระหว่าง shop_drawing_revisions กับ contract_drawings (M:N) | Column | Type | Key | Description | | :----------------------- | :--- | :--------- | :--------------------------------------------------------------- | | shop_drawing_revision_id | INT | **PK**, FK | ID ของ Shop Drawing Revision (FK \-> shop_drawing_revisions(id)) | | contract_drawing_id | INT | **PK**, FK | ID ของ Contract Drawing (FK \-> contract_drawings(id)) | - **Foreign Keys (FK):** - shop_drawing_revision_id -> shop_drawing_revisions(id) (ON DELETE CASCADE) - contract_drawing_id -> contract_drawings(id) (ON DELETE CASCADE) --- ## **6. 🔄 Circulations (ใบเวียนภายใน)** #### **6.1. circulation_status_codes** ตาราง Master เก็บสถานะใบเวียน (เช่น OPEN, IN_REVIEW, COMPLETED) | Column | Type | Key | Description | | :---------- | :---------- | :----- | :------------------------ | | id | INT | **PK** | ID ของตาราง | | code | VARCHAR(20) | UK | รหัสสถานะการดำเนินงาน | | description | VARCHAR(50) | | คำอธิบายสถานะการดำเนินงาน | | sort_order | INT | | ลำดับการแสดงผล | | is_active | TINYINT(1) | | สถานะการใช้งาน | --- #### **6.2. circulations (Master)** ตาราง "แม่" ของใบเวียนเอกสารภายใน | Column | Type | Key | Description | | :---------------------- | :----------- | :----- | :---------------------------------------------------------------- | | id | INT | **PK** | ID ของตารางใบเวียน | | correspondence_id | INT | UNIQUE | ID ของเอกสาร (จากตาราง correspondences) | | organization_id | INT | FK | ID ขององค์กรณ์ที่เป็นเจ้าของใบเวียนนี้ (FK \-> organizations(id)) | | circulation_no | VARCHAR(100) | | เลขที่ใบเวียน | | circulation_subject | VARCHAR(500) | | เรื่องใบเวียน | | circulation_status_code | VARCHAR(20) | FK | รหัสสถานะใบเวียน (FK \-> circulation_status_codes(code)) | | created_by_user_id | INT | FK | ID ของผู้สร้างใบเวียน (FK \-> users(user_id)) | | submitted_at | TIMESTAMP | | วันที่ส่งใบเวียน | | closed_at | TIMESTAMP | | วันที่ปิดใบเวียน | | created_at | TIMESTAMP | | วันที่สร้าง | | updated_at | TIMESTAMP | | วันที่แก้ไขล่าสุด | - **Foreign Keys (FK):** - correspondence_id -> correspondences(id) - organization_id -> organizations(id) - circulation_status_code -> circulation_status_codes(code) - created_by_user_id -> users(user_id) --- #### **6.3. circulation_templates / ...\_assignees / ...\_routings** ตารางที่เกี่ยวข้องกับ Workflow การส่งต่อเอกสาร (Req 3.5.4) - **circulation_templates:** ตาราง Master เก็บแม่แบบสายงาน (เช่น "ส่งให้ CSC ตรวจสอบ") - **circulation_template_assignees:** ตารางลูก เก็บขั้นตอนในแม่แบบ (เช่น Step 1: ส่งไป Org A, Step 2: ส่งไป Org B) - **circulation_routings:** ตารางประวัติ (Log) การส่งต่อของเอกสารจริงตาม Workflow --- ## **7. 📤 Transmittals (เอกสารนำส่ง)** #### **7.1. transmittals** ตารางข้อมูลเฉพาะของเอกสารนำส่ง (เป็นตารางลูก 1:1 ของ correspondences) | Column | Type | Key | Description | | :---------------- | :-------- | :--------- | :------------------------------------------------ | | correspondence_id | INT | **PK**, FK | ID ของเอกสาร (FK \-> correspondences(id)) | | purpose | ENUM(...) | | วัตถุประสงค์ (FOR_APPROVAL, FOR_INFORMATION, ...) | | remarks | TEXT | | หมายเหตุ | - **Foreign Keys (FK):** correspondence_id -> correspondences(id) (ON DELETE CASCADE) --- #### **7.2. transmittal_items (ตารางเชื่อม)** ตารางเชื่อมระหว่าง transmittals และเอกสารที่นำส่ง (M:N) **(ปรับปรุง V1.4.0)** | Column | Type | Key | Description | | :------------------------- | :--------------- | :--------- | :-------------------------------------------------------------- | | **id** | **INT** | **PK** | **(ใหม่)** ID ของรายการ | | transmittal_id | INT | **FK**, UK | ID ของ Transmittal (FK \-> transmittals(correspondence_id)) | | **item_correspondence_id** | INT | **FK**, UK | **(เปลี่ยน)** ID ของเอกสารที่แนบไป (FK \-> correspondences(id)) | | **quantity** | **INT** | | **(ใหม่)** จำนวน | | **remarks** | **VARCHAR(255)** | | **(ใหม่)** หมายเหตุสำหรับรายการนี้ | - **Foreign Keys (FK):** - transmittal_id -> transmittals(correspondence_id) (ON DELETE CASCADE) - item_correspondence_id -> correspondences(id) (ON DELETE CASCADE) - **Unique Keys (UK):** ux_transmittal_item (transmittal_id, item_correspondence_id) --- ## **8. 📎 File Management (ไฟล์แนบ)** #### **8.1. attachments (Master)** ตาราง "กลาง" เก็บไฟล์แนบทั้งหมดของระบบ (ตาม Requirements 3.9) | Column | Type | Key | Description | | :------------------ | :----------- | :----- | :-------------------------------------------- | | id | INT | **PK** | ID ของไฟล์แนบ | | original_filename | VARCHAR(255) | | ชื่อไฟล์ดั้งเดิมตอนอัปโหลด | | stored_filename | VARCHAR(255) | | ชื่อไฟล์ที่เก็บจริงบน Server (ป้องกันชื่อซ้ำ) | | file_path | VARCHAR(500) | | Path ที่เก็บไฟล์ (บน QNAP /share/dms-data/) | | mime_type | VARCHAR(100) | | ประเภทไฟล์ (เช่น application/pdf) | | file_size | INT | | ขนาดไฟล์ (bytes) | | uploaded_by_user_id | INT | FK | ผู้อัปโหลดไฟล์ (FK \-> users(user_id)) | - **Foreign Keys (FK):** uploaded_by_user_id -> users(user_id) (ON DELETE CASCADE) --- #### **8.2. correspondence_attachments (ตารางเชื่อม - ใหม่)** ตารางเชื่อม correspondences กับ attachments (M:N) | Column | Type | Key | Description | | :---------------- | :------ | :--------- | :---------------------------------------- | | correspondence_id | INT | **PK**, FK | ID ของเอกสาร (FK \-> correspondences(id)) | | attachment_id | INT | **PK**, FK | ID ของไฟล์แนบ (FK \-> attachments(id)) | | is_main_document | BOOLEAN | | (1 = ไฟล์หลัก) | - **Foreign Keys (FK):** correspondence_id, attachment_id --- #### **8.3. circulation_attachments (ตารางเชื่อม - ใหม่)** ตารางเชื่อม circulations กับ attachments (M:N) | Column | Type | Key | Description | | :--------------- | :------ | :--------- | :-------------------------------------- | | circulation_id | INT | **PK**, FK | ID ของใบเวียน (FK \-> circulations(id)) | | attachment_id | INT | **PK**, FK | ID ของไฟล์แนบ (FK \-> attachments(id)) | | is_main_document | BOOLEAN | | (1 = ไฟล์หลักของใบเวียน) | - **Foreign Keys (FK):** circulation_id, attachment_id --- #### **8.4. shop_drawing_revision_attachments (ตารางเชื่อม - ใหม่)** ตารางเชื่อม shop_drawing_revisions กับ attachments (M:N) **(ปรับปรุง V1.2.0)** | Column | Type | Key | Description | | :----------------------- | :---------- | :--------- | :--------------------------------------------------------------- | | shop_drawing_revision_id | INT | **PK**, FK | ID ของ Shop Drawing Revision (FK \-> shop_drawing_revisions(id)) | | attachment_id | INT | **PK**, FK | ID ของไฟล์แนบ (FK \-> attachments(id)) | | file_type | ENUM(...) | | ประเภทไฟล์ (PDF, DWG, SOURCE, OTHER) | | **is_main_document** | **BOOLEAN** | | **(ใหม่)** (1 = ไฟล์หลัก) | - **Foreign Keys (FK):** shop_drawing_revision_id, attachment_id --- #### **8.5. contract_drawing_attachments (ตารางเชื่อม - ใหม่)** **(ใหม่)** ตารางเชื่อม contract_drawings กับ attachments (M:N) | Column | Type | Key | Description | | :------------------ | :-------- | :--------- | :----------------------------------------------------- | | contract_drawing_id | INT | **PK**, FK | ID ของ Contract Drawing (FK \-> contract_drawings(id)) | | attachment_id | INT | **PK**, FK | ID ของไฟล์แนบ (FK \-> attachments(id)) | | file_type | ENUM(...) | | ประเภทไฟล์ (PDF, DWG, SOURCE, OTHER) | | is_main_document | BOOLEAN | | (1 = ไฟล์หลัก) | - **Foreign Keys (FK):** - contract_drawing_id -> contract_drawings(id) (ON DELETE CASCADE) - attachment_id -> attachments(id) (ON DELETE CASCADE) --- ## **9. 🔢 Document Numbering (การสร้างเลขที่เอกสาร)** #### **9.1. document_number_formats (ตารางตั้งค่า - ใหม่)** ตาราง Master เก็บ "รูปแบบ" Template ของเลขที่เอกสาร (ตาม Requirements 3.10.3) | Column | Type | Key | Description | | :--------------------- | :----------- | :----- | :---------------------------------------------------- | | id | INT | **PK** | ID ของตาราง | | project_id | INT | FK, UK | โครงการ (FK \-> projects(id)) | | correspondence_type_id | INT | FK, UK | ประเภทเอกสาร (FK \-> correspondence_types(id)) | | format_template | VARCHAR(255) | | รูปแบบ Template (เช่น {ORG_CODE}-{TYPE_CODE}-{SEQ:4}) | | description | TEXT | | คำอธิบายรูปแบบนี้ | - **Foreign Keys (FK):** project_id, correspondence_type_id - **Unique Keys (UK):** uk_project_type (project_id, correspondence_type_id) --- #### **9.2. document_number_counters (ตารางตัวนับ - ใหม่)** ตารางเก็บ "ตัวนับ" (Running Number) ล่าสุด (ตาม Requirements 3.10.2) | Column | Type | Key | Description | | :------------------------- | :--- | :--------- | :--------------------------------------------- | | project_id | INT | **PK**, FK | โครงการ (FK \-> projects(id)) | | originator_organization_id | INT | **PK**, FK | องค์กรผู้ส่ง (FK \-> organizations(id)) | | correspondence_type_id | INT | **PK**, FK | ประเภทเอกสาร (FK \-> correspondence_types(id)) | | current_year | INT | **PK** | ปี ค.ศ. ของตัวนับ | | last_number | INT | | เลขที่ล่าสุดที่ใช้ไปแล้ว | - **Foreign Keys (FK):** project_id, originator_organization_id, correspondence_type_id --- ## **10. ⚙️ System & Logs (ระบบและ Log)** #### **10.1. tags** ตาราง Master เก็บ Tags ทั้งหมดที่ใช้ในระบบ | Column | Type | Key | Description | | :---------- | :----------- | :----- | :---------------- | | id | INT | **PK** | ID ของตาราง | | tag_name | VARCHAR(100) | UK | ชื่อ Tag | | description | TEXT | | คำอธิบายแท็ก | | created_at | TIMESTAMP | | วันที่สร้าง | | updated_at | TIMESTAMP | | วันที่แก้ไขล่าสุด | - **Unique Keys (UK):** ux_tag_name (tag_name) --- #### **10.2. correspondence_tags (ตารางเชื่อม)** ตารางเชื่อมระหว่าง correspondences และ tags (M:N) | Column | Type | Key | Description | | :---------------- | :--- | :--------- | :---------------------------------------- | | correspondence_id | INT | **PK**, FK | ID ของเอกสาร (FK \-> correspondences(id)) | | tag_id | INT | **PK**, FK | ID ของ Tag (FK \-> tags(id)) | - **Foreign Keys (FK):** correspondence_id, tag_id --- #### **10.3. audit_logs** ตารางเก็บบันทึกการกระทำของผู้ใช้ (ตาม Requirements 6.1) | Column | Type | Key | Description | | :----------- | :----------- | :----- | :--------------------------------------------------------------- | | audit_id | BIGINT | **PK** | ID ของ Log | | user_id | INT | FK | ผู้กระทำ (FK \-> users(user_id)) | | action | VARCHAR(100) | | การกระทำ (เช่น rfa.create, correspondence.update, login.success) | | entity_type | VARCHAR(50) | | ตาราง/โมดูล (เช่น 'rfa', 'correspondence') | | entity_id | VARCHAR(50) | | Primary ID ของระเบียนที่ได้รับผลกระทำ | | details_json | JSON | | ข้อมูลบริบที่ | | ip_address | VARCHAR(45) | | IP Address | | user_agent | VARCHAR(255) | | User Agent | | created_at | TIMESTAMP | | เวลาที่กระทำ | - **Foreign Keys (FK):** user_id -> users(user_id) (ON DELETE SET NULL) --- #### **10.4. notifications (ตารางใหม่ - ตาม Requirements 6.7)** ตารางสำหรับจัดการการแจ้งเตือน (Email/Line/System) | Column | Type | Key | Description | | :---------------- | :------------------------------ | :----- | :-------------------------------- | | id | INT | **PK** | ID ของการแจ้งเตือน | | user_id | INT | FK | ID ผู้ใช้ (FK \-> users(user_id)) | | title | VARCHAR(255) | | หัวข้อการแจ้งเตือน | | message | TEXT | | รายละเอียดการแจ้งเตือน | | notification_type | ENUM('EMAIL', 'LINE', 'SYSTEM') | | ประเภท (EMAIL, LINE, SYSTEM) | | is_read | BOOLEAN | | สถานะการอ่าน | | entity_type | VARCHAR(50) | | เช่น 'rfa', 'circulation' | | entity_id | INT | | ID ของเอนทิตีที่เกี่ยวข้อง | | created_at | TIMESTAMP | | วันที่สร้าง | - **Foreign Keys (FK):** user_id -> users(user_id) --- #### **10.5. search_indices (ตารางใหม่ - ตาม Requirements 6.2)** ตารางสำหรับจัดการดัชนีการค้นหาขั้นสูง (Full-text Search) | Column | Type | Key | Description | | :---------- | :---------- | :----- | :----------------------------------------- | | id | INT | **PK** | ID ของดัชนี | | entity_type | VARCHAR(50) | | ชนิดเอนทิตี (เช่น 'correspondence', 'rfa') | | entity_id | INT | | ID ของเอนทิตี | | content | TEXT | | เนื้อหาที่จะค้นหา | | indexed_at | TIMESTAMP | | วันที่สร้าง/อัปเดตัชนี | - **Indexes:** `idx_entity (entity_type, entity_id)`, `FULLTEXT INDEX idx_content (content)` --- #### **10.6. backup_logs (ตารางใหม่ - ตาม Requirements 6.6)** ตารางสำหรับบันทึกประวัติการสำรองข้อมูล | Column | Type | Key | Description | | :------------ | :------------------------------------- | :----- | :----------------------------- | | id | INT | **PK** | ID ของการสำรอง | | backup_type | ENUM('DATABASE', 'FILES', 'FULL') | | ประเภท (DATABASE, FILES, FULL) | | backup_path | VARCHAR(500) | | ตำแหน่งไฟล์สำรอง | | file_size | BIGINT | | ขนาดไฟล์ | | status | ENUM('STARTED', 'COMPLETED', 'FAILED') | | สถานะ | | started_at | TIMESTAMP | | เวลาเริ่มต้น | | completed_at | TIMESTAMP | | เวลาเสร็จสิ้น | | error_message | TEXT | | ข้อความผิดพลาด (ถ้ามี) | --- ## **11. 📊 Views & Procedures (วิว และ โปรซีเดอร์)** #### **11.1. sp_get_next_document_number (Procedure)** **(ใหม่)** Stored Procedure ดึงเดียวที่ใช้ในระบบ - **หน้าที่:** ดึงเลขที่เอกสารถัดไป (Next Running Number) จากตาราง document_number_counters - **ตรรกะ:** ใช้ `SELECT ... FOR UPDATE` เพื่อ "ล็อก" แถว ป้องกัน Race Condition (การที่ผู้ใช้ 2 คนได้เลขที่ซ้ำกัน) ตาม Requirement 3.10.2 --- #### **11.2. v_current_correspondences (View)** - **หน้าที่:** แสดง Revision "ปัจจุบัน" (is_current \= TRUE) ของ correspondences ทั้งหมด (ที่ไม่ใช่ RFA) --- #### **11.3. v_current_rfas (View)** - **หน้าที่:** แสดง Revision "ปัจจุบัน" (is_current \= TRUE) ของ rfa_revisions ทั้งหมด --- #### **11.4. v_contract_parties_all (View)** - **หน้าที่:** แสดงความสัมพันธ์ทั้งหมดระหว่าง Contract, Project, และ Organization --- #### **11.5. v_user_tasks (View - ใหม่)** **(ใหม่)** - **หน้าที่:** แสดงรายการ "งานของฉัน" (My Tasks) ที่ยังไม่เสร็จ (ตาม Requirement 5.3) - **ตรรกะ:** JOIN ตาราง circulations กับ circulation_assignees (ที่ is_completed \= FALSE) --- #### **11.6. v_audit_log_details (View - ใหม่)** **(ใหม่)** - **หน้าที่:** แสดง audit_logs พร้อมข้อมูล username และ email ของผู้กระทำ --- #### **11.7. v_user_all_permissions (View - ใหม่)** **(ใหม่)** - **หน้าที่:** รวมสิทธิ์ทั้งหมด (Global \+ Project) ของผู้ใช้ทุกคน เพื่อให้ Backend ตรวจสอบสิทธิ์ได้ง่าย - **ตรรกะ:** UNION ข้อมูลจาก user_roles และ user_project_roles ---