-- ==========================================================
-- DMS v1.9.0 Schema Part 2/3: CREATE TABLE Statements
-- รัน: mysql < 01-schema-drop.sql แล้วจึงรัน 02-schema-tables.sql
-- ==========================================================
SET NAMES utf8mb4;

SET time_zone = '+07:00';

SET FOREIGN_KEY_CHECKS = 0;

-- =====================================================
-- 1. 🏢 Core & Master Data (องค์กร, โครงการ, สัญญา)
-- =====================================================
-- ตาราง Master เก็บประเภทบทบาทขององค์กร
CREATE TABLE organization_roles (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
  role_name VARCHAR(20) NOT NULL UNIQUE COMMENT 'ชื่อบทบาท (OWNER, DESIGNER, CONSULTANT, CONTRACTOR, THIRD PARTY)',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่สร้าง',
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'วันที่แก้ไขล่าสุด',
  deleted_at DATETIME NULL COMMENT 'วันที่ลบ (Soft Delete)'
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตาราง Master เก็บประเภทบทบาทขององค์กร';

-- ตาราง Master เก็บข้อมูลองค์กรทั้งหมดที่เกี่ยวข้องในระบบ
CREATE TABLE organizations (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
  uuid UUID NOT NULL DEFAULT UUID() COMMENT 'UUID Public Identifier (ADR-019)',
  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 'วันที่แก้ไขล่าสุด',
  deleted_at DATETIME NULL COMMENT 'วันที่ลบ (Soft Delete)',
  FOREIGN KEY (role_id) REFERENCES organization_roles (id) ON DELETE
  SET NULL,
    UNIQUE INDEX idx_organizations_uuid (uuid)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตาราง Master เก็บข้อมูลองค์กรทั้งหมดที่เกี่ยวข้องในระบบ';

-- ตาราง Master เก็บข้อมูลโครงการ
CREATE TABLE projects (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
  uuid UUID NOT NULL DEFAULT UUID() COMMENT 'UUID Public Identifier (ADR-019)',
  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
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่สร้าง',
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'วันที่แก้ไขล่าสุด',
  deleted_at DATETIME NULL COMMENT 'วันที่ลบ (Soft Delete)',
  UNIQUE INDEX idx_projects_uuid (uuid)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตาราง Master เก็บข้อมูลโครงการ';

-- ตาราง Master เก็บข้อมูลสัญญา
CREATE TABLE contracts (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
  uuid UUID NOT NULL DEFAULT UUID() COMMENT 'UUID Public Identifier (ADR-019)',
  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 'วันที่แก้ไขล่าสุด',
  deleted_at DATETIME NULL COMMENT 'วันที่ลบ (Soft Delete)',
  FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE,
  UNIQUE INDEX idx_contracts_uuid (uuid)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตาราง Master เก็บข้อมูลสัญญา';

-- =====================================================
-- 2. 👥 Users & RBAC (ผู้ใช้, สิทธิ์, บทบาท)
-- =====================================================
-- ตาราง Master เก็บข้อมูลผู้ใช้งาน (User)
CREATE TABLE users (
  user_id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
  uuid UUID NOT NULL DEFAULT UUID() COMMENT 'UUID Public Identifier (ADR-019)',
  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,
    UNIQUE INDEX idx_users_uuid (uuid)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตาราง Master เก็บข้อมูลผู้ใช้งาน (User)';

-- ตารางเก็บ Refresh Tokens สำหรับ Authentication
CREATE TABLE refresh_tokens (
  token_id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
  user_id INT NOT NULL COMMENT 'เจ้าของ Token',
  token_hash VARCHAR(255) NOT NULL COMMENT 'Hash ของ Refresh Token',
  expires_at DATETIME NOT NULL COMMENT 'วันหมดอายุ',
  is_revoked TINYINT(1) DEFAULT 0 COMMENT 'สถานะยกเลิก (1=Revoked)',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่สร้าง',
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'วันที่แก้ไขล่าสุด',
  replaced_by_token VARCHAR(255) NULL COMMENT 'Token ใหม่ที่มาแทนที่ (Rotation)',
  FOREIGN KEY (user_id) REFERENCES users (user_id) ON DELETE CASCADE
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเก็บ Refresh Tokens สำหรับ Authentication';

-- ตารางเก็บข้อมูลการตั้งค่าระบบไดนามิก (ADR-027)
CREATE TABLE system_settings (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
  setting_key VARCHAR(100) NOT NULL UNIQUE COMMENT 'คีย์การตั้งค่าระบบ (เช่น AI_FEATURES_ENABLED, MAX_UPLOAD_SIZE)',
  setting_value TEXT NOT NULL COMMENT 'ค่าที่บันทึก (stringified)',
  data_type ENUM('string', 'number', 'boolean', 'json') NOT NULL DEFAULT 'string' COMMENT 'ประเภทข้อมูลสำหรับ validation',
  category VARCHAR(50) COMMENT 'หมวดหมู่ (เช่น ai, security, storage, notification)',
  is_encrypted TINYINT(1) DEFAULT 0 COMMENT 'เข้ารหัสค่า sensitive',
  validation_rules JSON COMMENT 'กฎ validation (min, max, allowed_values)',
  description TEXT COMMENT 'คำอธิบายข้อมูลการตั้งค่า',
  is_public TINYINT(1) DEFAULT 0 COMMENT 'เผยแพร่ให้ frontend อ่านได้หรือ admin only',
  updated_by INT COMMENT 'ผู้แก้ไขล่าสุด',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  FOREIGN KEY (updated_by) REFERENCES users(user_id) ON DELETE
  SET NULL,
    INDEX idx_system_settings_category (category),
    INDEX idx_system_settings_is_public (is_public)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเก็บข้อมูลการตั้งค่าระบบไดนามิก';

-- ตาราง Master เก็บ "บทบาท" ของผู้ใช้ในระบบ
CREATE TABLE roles (
  role_id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
  uuid UUID NOT NULL DEFAULT UUID() COMMENT 'UUID Public Identifier (ADR-019)',
  -- 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 = บทบาทของระบบ ลบไม่ได้)',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่สร้าง',
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'วันที่แก้ไขล่าสุด',
  deleted_at DATETIME NULL COMMENT 'วันที่ลบ (Soft Delete)'
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตาราง Master เก็บ "บทบาท" ของผู้ใช้ในระบบ';

-- ตาราง Master เก็บ "สิทธิ์" (Permission) หรือ "การกระทำ" ทั้งหมดในระบบ
CREATE TABLE permissions (
  permission_id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
  permission_name VARCHAR(100) NOT NULL UNIQUE COMMENT 'รหัสสิทธิ์ (เช่น rfas.create, rfas.view)',
  description TEXT COMMENT 'คำอธิบายสิทธิ์',
  module VARCHAR(50) COMMENT 'โมดูลที่เกี่ยวข้อง',
  scope_level ENUM('GLOBAL', 'ORG', 'PROJECT') COMMENT 'ระดับขอบเขตของสิทธิ์',
  is_active TINYINT(1) DEFAULT 1 COMMENT 'สถานะการใช้งาน',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่สร้าง',
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'วันที่แก้ไขล่าสุด',
  deleted_at DATETIME NULL COMMENT 'วันที่ลบ (Soft Delete)'
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตาราง Master เก็บ "สิทธิ์" (Permission) หรือ "การกระทำ" ทั้งหมดในระบบ';

-- ตารางเชื่อมระหว่าง roles และ permissions (M:N)
CREATE TABLE role_permissions (
  role_id INT COMMENT 'ID ของบทบาท',
  permission_id INT COMMENT 'ID ของสิทธิ์',
  PRIMARY KEY (role_id, permission_id),
  FOREIGN KEY (role_id) REFERENCES roles (role_id) ON DELETE CASCADE,
  FOREIGN KEY (permission_id) REFERENCES permissions (permission_id) ON DELETE CASCADE
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเชื่อมระหว่าง roles และ permissions (M :N)';

-- search.advanced
-- ตารางเชื่อมผู้ใช้ (users)
CREATE TABLE user_assignments (
  id INT AUTO_INCREMENT PRIMARY KEY,
  user_id INT NOT NULL,
  role_id INT NOT NULL,
  -- คอลัมน์สำหรับกำหนดขอบเขต (จะใช้เพียงอันเดียวต่อแถว)
  organization_id INT NULL,
  project_id INT NULL,
  contract_id INT NULL,
  assigned_by_user_id INT,
  -- ผู้ที่มอบหมายบทบาทนี้
  assigned_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (user_id) REFERENCES users (user_id) ON DELETE CASCADE,
  FOREIGN KEY (role_id) REFERENCES roles (role_id) ON DELETE CASCADE,
  FOREIGN KEY (organization_id) REFERENCES organizations (id) ON DELETE CASCADE,
  FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE,
  FOREIGN KEY (contract_id) REFERENCES contracts (id) ON DELETE CASCADE,
  FOREIGN KEY (assigned_by_user_id) REFERENCES users (user_id),
  -- Constraint เพื่อให้แน่ใจว่ามีเพียงขอบเขตเดียวที่ถูกกำหนดในแต่ละแถว
  CONSTRAINT chk_scope CHECK (
    (
      organization_id IS NOT NULL
      AND project_id IS NULL
      AND contract_id IS NULL
    )
    OR (
      organization_id IS NULL
      AND project_id IS NOT NULL
      AND contract_id IS NULL
    )
    OR (
      organization_id IS NULL
      AND project_id IS NULL
      AND contract_id IS NOT NULL
    )
    OR (
      organization_id IS NULL
      AND project_id IS NULL
      AND contract_id IS NULL
    ) -- สำหรับ Global scope
  )
);

CREATE TABLE project_organizations (
  project_id INT NOT NULL,
  organization_id INT NOT NULL,
  PRIMARY KEY (project_id, organization_id),
  FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE,
  FOREIGN KEY (organization_id) REFERENCES organizations (id) ON DELETE CASCADE
);

CREATE TABLE contract_organizations (
  contract_id INT NOT NULL,
  organization_id INT NOT NULL,
  role_in_contract VARCHAR(100),
  -- เช่น 'Owner', 'Designer', 'Consultant', 'Contractor '
  PRIMARY KEY (contract_id, organization_id),
  FOREIGN KEY (contract_id) REFERENCES contracts (id) ON DELETE CASCADE,
  FOREIGN KEY (organization_id) REFERENCES organizations (id) ON DELETE CASCADE
);

-- =====================================================
-- 3. ✉️ Correspondences (เอกสารหลัก, Revisions)
-- =====================================================
-- ตารางเก็บข้อมูลสาขางาน (Disciplines) แยกตามสัญญา
CREATE TABLE disciplines (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
  contract_id INT NOT NULL COMMENT 'ผูกกับสัญญา',
  discipline_code VARCHAR(10) NOT NULL COMMENT 'รหัสสาขา (เช่น GEN, STR)',
  code_name_th VARCHAR(255) COMMENT 'ชื่อไทย',
  code_name_en VARCHAR(255) COMMENT 'ชื่ออังกฤษ',
  is_active TINYINT(1) DEFAULT 1 COMMENT 'สถานะการใช้งาน',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  FOREIGN KEY (contract_id) REFERENCES contracts (id) ON DELETE CASCADE,
  UNIQUE KEY uk_discipline_contract (contract_id, discipline_code)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเก็บข้อมูลสาขางาน (Disciplines) ตาม Req 6B';

-- ตาราง 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 'สถานะการใช้งาน ',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่สร้าง',
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'วันที่แก้ไขล่าสุด',
  deleted_at DATETIME NULL COMMENT 'วันที่ลบ (Soft Delete)'
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตาราง Master เก็บประเภทเอกสารโต้ตอบ';

-- ตารางเก็บประเภทหนังสือย่อย (Sub Types) สำหรับ Mapping เลขรหัส
CREATE TABLE correspondence_sub_types (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
  contract_id INT NOT NULL COMMENT 'ผูกกับสัญญา',
  correspondence_type_id INT NOT NULL COMMENT 'ผูกกับประเภทเอกสารหลัก (เช่น RFA)',
  sub_type_code VARCHAR(20) NOT NULL COMMENT 'รหัสย่อย (เช่น MAT, SHP)',
  sub_type_name VARCHAR(255) COMMENT 'ชื่อประเภทหนังสือย่อย',
  sub_type_number VARCHAR(10) COMMENT 'เลขรหัสสำหรับ Running Number (เช่น 11, 22)',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (contract_id) REFERENCES contracts (id) ON DELETE CASCADE,
  FOREIGN KEY (correspondence_type_id) REFERENCES correspondence_types (id) ON DELETE CASCADE
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเก็บประเภทหนังสือย่อย (Sub Types) ตาม Req 6B';

-- ตาราง Master เก็บสถานะของเอกสาร
CREATE TABLE correspondence_status (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
  status_code VARCHAR(50) NOT NULL UNIQUE COMMENT 'รหัสสถานะหนังสือ (เช่น DRAFT, SUBOWN)',
  status_name VARCHAR(255) NOT NULL COMMENT 'ชื่อสถานะหนังสือ',
  sort_order INT DEFAULT 0 COMMENT 'ลำดับการแสดงผล',
  is_active TINYINT(1) DEFAULT 1 COMMENT 'สถานะการใช้งาน '
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตาราง Master เก็บสถานะของเอกสาร';

-- ตาราง "แม่" ของเอกสารโต้ตอบ เก็บข้อมูลที่ไม่เปลี่ยนตาม Revision
CREATE TABLE correspondences (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง (นี่คือ "Master ID" ที่ใช้เชื่อมโยง)',
  uuid UUID NOT NULL DEFAULT UUID() COMMENT 'UUID Public Identifier (ADR-019)',
  correspondence_type_id INT NOT NULL COMMENT 'ประเภทเอกสาร ใช้แบ่งแยกว่าเป็น RFA หรือ อื่นๆ',
  correspondence_number VARCHAR(100) NOT NULL COMMENT 'เลขที่เอกสาร (สร้างจาก DocumentNumberingModule)',
  discipline_id INT 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',
  INDEX idx_corr_number (correspondence_number),
  INDEX idx_deleted_at (deleted_at),
  INDEX idx_created_by (created_by),
  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,
    -- Foreign Key ที่รวมเข้ามาจาก ALTER (ระบุชื่อ Constraint ตามที่ต้องการ)
    CONSTRAINT fk_corr_discipline FOREIGN KEY (discipline_id) REFERENCES disciplines (id) ON DELETE
  SET NULL,
    UNIQUE KEY uq_corr_no_per_project (project_id, correspondence_number),
    UNIQUE INDEX idx_correspondences_uuid (uuid)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตาราง "แม่" ของเอกสารโต้ตอบ เก็บข้อมูลที่ไม่เปลี่ยนตาม Revision';

-- ตารางเชื่อมผู้รับ (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 correspondences (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)';

-- ตาราง "ลูก" เก็บประวัติการแก้ไข (Revisions) ของ correspondences (1:N)
CREATE TABLE correspondence_revisions (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของ Revision',
  uuid UUID NOT NULL DEFAULT UUID() COMMENT 'UUID Public Identifier (ADR-019)',
  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 นี้',
  subject VARCHAR(500) NOT NULL COMMENT 'หัวข้อเรื่อง',
  description TEXT COMMENT 'คำอธิบายการแก้ไขใน Revision นี้',
  body TEXT NULL COMMENT 'เนื้อความ (ถ้ามี)',
  remarks TEXT COMMENT 'หมายเหตุ',
  document_date DATE COMMENT 'วันที่ในเอกสาร',
  issued_date DATETIME COMMENT 'วันที่ออกเอกสาร',
  received_date DATETIME COMMENT 'วันที่ลงรับเอกสาร',
  due_date DATETIME COMMENT 'วันที่ครบกำหนด',
  -- Standard Meta Columns
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่สร้างเอกสาร',
  created_by INT COMMENT 'ผู้สร้าง',
  updated_by INT COMMENT 'ผู้แก้ไขล่าสุด',
  -- ส่วนของ JSON และ Schema Version
  details JSON COMMENT 'ข้อมูลเฉพาะ (เช่น LETTET details)',
  schema_version INT DEFAULT 1 COMMENT 'เวอร์ชันของ Schema ที่ใช้กับ details',
  -- Generated Virtual Columns (ดึงค่าจาก JSON โดยอัตโนมัติ)
  v_ref_project_id INT GENERATED ALWAYS AS (
    CAST(
      JSON_UNQUOTE(JSON_EXTRACT(details, '$.projectId')) AS UNSIGNED
    )
  ) VIRTUAL COMMENT 'Virtual Column: Project ID จาก JSON',
  v_doc_subtype VARCHAR(50) GENERATED ALWAYS AS (
    JSON_UNQUOTE(JSON_EXTRACT(details, '$.subType'))
  ) VIRTUAL COMMENT 'Virtual Column: Document Subtype จาก JSON',
  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),
    INDEX idx_corr_rev_v_project (v_ref_project_id),
    INDEX idx_corr_rev_v_subtype (v_doc_subtype),
    UNIQUE INDEX idx_correspondence_revisions_uuid (uuid)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตาราง "ลูก" เก็บประวัติการแก้ไข (Revisions) ของ correspondences (1 :N)';

-- ตาราง Master เก็บ Tags ทั้งหมดที่ใช้ในระบบ
CREATE TABLE tags (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
  public_id CHAR(36) NOT NULL UNIQUE COMMENT 'UUIDv7 สำหรับการใช้งานภายนอก (ADR-019)',
  project_id INT NULL COMMENT 'ID โครงการ (NULL = Global Tag)',
  tag_name VARCHAR(100) NOT NULL COMMENT 'ชื่อแท็ก',
  color_code VARCHAR(30) DEFAULT 'default' COMMENT 'รหัสสีสำหรับ UI',
  description TEXT COMMENT 'คำอธิบายเพิ่มเติม',
  created_by INT COMMENT 'ผู้สร้างแท็ก',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่สร้าง',
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'วันที่แก้ไขล่าสุด',
  deleted_at TIMESTAMP NULL COMMENT 'วันที่ลบ (Soft Delete)',
  FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE,
  FOREIGN KEY (created_by) REFERENCES users (user_id) ON DELETE
  SET NULL,
    UNIQUE KEY uq_tag_project (project_id, tag_name),
    INDEX idx_tags_deleted_at (deleted_at)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเก็บข้อมูลแท็กจัดหมวดหมู่เอกสาร';

-- ตารางเชื่อมระหว่าง correspondences และ tags (M:N)
CREATE TABLE correspondence_tags (
  correspondence_id INT NOT NULL COMMENT 'ID ของเอกสาร',
  tag_id INT NOT NULL COMMENT 'ID ของแท็ก',
  is_ai_suggested BOOLEAN DEFAULT FALSE COMMENT 'แท็กนี้แนะนำโดย AI หรือไม่',
  confidence DECIMAL(4, 3) NULL COMMENT 'ค่าความมั่นใจของ AI (0.000–1.000)',
  created_by INT COMMENT 'ผู้เชื่อมโยงแท็ก',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่เชื่อมโยง',
  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,
  FOREIGN KEY (created_by) REFERENCES users (user_id) ON DELETE
  SET NULL,
    INDEX idx_correspondence_tags_lookup (tag_id)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเชื่อมโยงความสัมพันธ์แบบ M:N ระหว่างเอกสารและแท็ก';

-- ตารางเชื่อมการอ้างอิงระหว่างเอกสาร (M:N)
CREATE TABLE correspondence_references (
  src_correspondence_id INT COMMENT 'ID เอกสารต้นทาง',
  tgt_correspondence_id INT COMMENT 'ID เอกสารเป้าหมาย',
  PRIMARY KEY (
    src_correspondence_id,
    tgt_correspondence_id
  ),
  FOREIGN KEY (src_correspondence_id) REFERENCES correspondences (id) ON DELETE CASCADE,
  FOREIGN KEY (tgt_correspondence_id) REFERENCES correspondences (id) ON DELETE CASCADE
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเชื่อมการอ้างอิงระหว่างเอกสาร (M :N)';

-- =====================================================
-- 4. 📐 approval: RFA (เอกสารขออนุมัติ, Workflows)
-- =====================================================
-- ตาราง Master สำหรับประเภท RFA
CREATE TABLE rfa_types (
  id INT PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT 'ID ของตาราง',
  contract_id INT NOT NULL COMMENT 'ผูกกับสัญญา',
  type_code VARCHAR(20) NOT NULL COMMENT 'รหัสประเภท RFA (เช่น DWG, DOC, MAT)',
  type_name_th VARCHAR(100) NOT NULL COMMENT 'ชื่อประเภท RFA th',
  type_name_en VARCHAR(100) NOT NULL COMMENT 'ชื่อประเภท RFA en',
  remark TEXT COMMENT 'หมายเหตุ',
  -- sort_order INT DEFAULT 0 COMMENT 'ลำดับการแสดงผล',
  is_active TINYINT(1) DEFAULT 1 COMMENT 'สถานะการใช้งาน ',
  UNIQUE KEY uk_rfa_types_contract_code (contract_id, type_code),
  FOREIGN KEY (contract_id) REFERENCES contracts (id) ON DELETE CASCADE
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตาราง Master สำหรับประเภท RFA';

-- ตาราง Master สำหรับสถานะ RFA
CREATE TABLE rfa_status_codes (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
  status_code VARCHAR(20) NOT NULL UNIQUE COMMENT 'รหัสสถานะ RFA (เช่น DFT - Draft, FAP - For Approve)',
  status_name VARCHAR(100) NOT NULL COMMENT 'ชื่อสถานะ',
  description TEXT COMMENT 'คำอธิบาย',
  sort_order INT DEFAULT 0 COMMENT 'ลำดับการแสดงผล',
  is_active TINYINT(1) DEFAULT 1 COMMENT 'สถานะการใช้งาน '
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตาราง Master สำหรับสถานะ RFA';

-- ตาราง Master สำหรับรหัสผลการอนุมัติ RFA
CREATE TABLE rfa_approve_codes (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
  approve_code VARCHAR(20) NOT NULL UNIQUE COMMENT 'รหัสผลการอนุมัติ (
        เช่น 1A - Approved,
        3R - Revise
        and Resubmit
    )',
  approve_name VARCHAR(100) NOT NULL COMMENT 'ชื่อผลการอนุมัติ',
  description TEXT COMMENT 'คำอธิบาย',
  sort_order INT DEFAULT 0 COMMENT 'ลำดับการแสดงผล',
  is_active TINYINT(1) DEFAULT 1 COMMENT 'สถานะการใช้งาน '
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตาราง Master สำหรับรหัสผลการอนุมัติ RFA';

CREATE TABLE rfas (
  id INT PRIMARY KEY COMMENT 'ID ของตาราง (RFA Master ID)',
  -- ❌ ไม่มี AUTO_INCREMENT
  rfa_type_id INT NOT NULL COMMENT 'ประเภท RFA',
  -- discipline_id INT NULL COMMENT 'สาขางาน (ถ้ามี)',
  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,
    -- CONSTRAINT fk_rfa_discipline FOREIGN KEY (discipline_id) REFERENCES disciplines (id) ON DELETE SET NULL,
    CONSTRAINT fk_rfas_parent FOREIGN KEY (id) REFERENCES correspondences (id) ON DELETE CASCADE
) 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 COMMENT 'ID (แชร์กับ correspondence_revisions)',
  rfa_status_code_id INT NOT NULL COMMENT 'สถานะ RFA',
  rfa_approve_code_id INT COMMENT 'ผลการอนุมัติ',
  approved_date DATE COMMENT 'วันที่อนุมัติ',
  details JSON NULL COMMENT 'RFA Specific Details',
  schema_version INT DEFAULT 1 COMMENT 'Version ของ JSON Schema',
  v_ref_drawing_count INT GENERATED ALWAYS AS (
    JSON_UNQUOTE(
      JSON_EXTRACT(details, '$.drawingCount')
    )
  ) VIRTUAL,
  FOREIGN KEY (id) REFERENCES correspondence_revisions (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
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางขยายของ correspondence_revisions สำหรับ RFA (1:1)';

-- ตารางรายการอ้างอิง Drawing Revision ของ RFA (รองรับ Shop Drawing และ As-Built Drawing)
CREATE TABLE rfa_items (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
  rfa_revision_id INT NOT NULL COMMENT 'ID ของ RFA Revision',
  item_type ENUM('SHOP', 'AS_BUILT') NOT NULL COMMENT 'ประเภท Drawing Revision ที่ถูกอ้างอิง',
  shop_drawing_revision_id INT NULL COMMENT 'ID ของ Shop Drawing Revision',
  asbuilt_drawing_revision_id INT NULL COMMENT 'ID ของ As-Built Drawing Revision',
  FOREIGN KEY (rfa_revision_id) REFERENCES rfa_revisions (id) ON DELETE CASCADE,
  FOREIGN KEY (shop_drawing_revision_id) REFERENCES shop_drawing_revisions (id) ON DELETE CASCADE,
  FOREIGN KEY (asbuilt_drawing_revision_id) REFERENCES asbuilt_drawing_revisions (id) ON DELETE CASCADE,
  UNIQUE KEY uq_rfa_items_shop (rfa_revision_id, shop_drawing_revision_id),
  UNIQUE KEY uq_rfa_items_asbuilt (rfa_revision_id, asbuilt_drawing_revision_id),
  INDEX idx_rfa_items_type (item_type),
  INDEX idx_rfa_items_shop (shop_drawing_revision_id),
  INDEX idx_rfa_items_asbuilt (asbuilt_drawing_revision_id)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางรายการอ้างอิง Drawing Revision ของ RFA โดย 1 แถวต้องอ้างอิง Shop Drawing Revision หรือ As-Built Drawing Revision อย่างใดอย่างหนึ่ง';

-- =====================================================
-- 5. 📐 Drawings (แบบ, หมวดหมู่)
-- =====================================================
-- ตาราง Master สำหรับ "เล่ม" ของแบบคู่สัญญา
CREATE TABLE contract_drawing_volumes (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
  project_id INT NOT NULL COMMENT 'โครงการ',
  volume_code VARCHAR(50) NOT NULL COMMENT 'รหัสเล่ม',
  volume_name VARCHAR(255) NOT NULL COMMENT 'ชื่อเล่ม',
  description TEXT COMMENT 'คำอธิบาย',
  sort_order INT DEFAULT 0 COMMENT 'ลำดับการแสดงผล',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่สร้าง',
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'วันที่แก้ไขล่าสุด',
  FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE,
  UNIQUE KEY ux_volume_project (project_id, volume_code)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตาราง Master สำหรับ "เล่ม" ของแบบคู่สัญญา';

-- ตาราง Master สำหรับ "หมวดหมู่หลัก" ของแบบคู่สัญญา
CREATE TABLE contract_drawing_cats (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
  project_id INT NOT NULL COMMENT 'โครงการ',
  cat_code VARCHAR(50) NOT NULL COMMENT 'รหัสหมวดหมู่หลัก',
  cat_name VARCHAR(255) NOT NULL COMMENT 'ชื่อหมวดหมู่หลัก',
  description TEXT COMMENT 'คำอธิบาย',
  sort_order INT DEFAULT 0 COMMENT 'ลำดับการแสดงผล',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่สร้าง',
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'วันที่แก้ไขล่าสุด',
  FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE,
  UNIQUE KEY ux_cat_project (project_id, cat_code)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตาราง Master สำหรับ "หมวดหมู่หลัก" ของแบบคู่สัญญา';

-- ตาราง Master สำหรับ "หมวดหมู่ย่อย" ของแบบคู่สัญญา
CREATE TABLE contract_drawing_sub_cats (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
  project_id INT NOT NULL COMMENT 'โครงการ',
  sub_cat_code VARCHAR(50) NOT NULL COMMENT 'รหัสหมวดหมู่ย่อย',
  sub_cat_name VARCHAR(255) NOT NULL COMMENT 'ชื่อหมวดหมู่ย่อย',
  description TEXT COMMENT 'คำอธิบาย',
  sort_order INT DEFAULT 0 COMMENT 'ลำดับการแสดงผล',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่สร้าง',
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'วันที่แก้ไขล่าสุด',
  FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE,
  UNIQUE KEY ux_subcat_project (project_id, sub_cat_code)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตาราง Master สำหรับ "หมวดหมู่ย่อย" ของแบบคู่สัญญา';

-- ตารางเชื่อมระหว่าง หมวดหมู่หลัก-ย่อย (M:N)
CREATE TABLE contract_drawing_subcat_cat_maps (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
  project_id INT COMMENT 'ID ของโครงการ',
  sub_cat_id INT COMMENT 'ID ของหมวดหมู่ย่อย',
  cat_id INT COMMENT 'ID ของหมวดหมู่หลัก',
  UNIQUE KEY ux_map_unique (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 ของตาราง',
  uuid UUID NOT NULL DEFAULT UUID() COMMENT 'UUID Public Identifier (ADR-019)',
  project_id INT NOT NULL COMMENT 'โครงการ',
  condwg_no VARCHAR(255) NOT NULL COMMENT 'เลขที่แบบสัญญา',
  title VARCHAR(255) NOT NULL COMMENT 'ชื่อแบบสัญญา',
  map_cat_id INT COMMENT 'หมวดหมู่ย่อย',
  volume_id INT COMMENT 'เล่ม',
  volume_page 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 (map_cat_id) REFERENCES contract_drawing_subcat_cat_maps (id) ON DELETE RESTRICT,
  FOREIGN KEY (volume_id) REFERENCES contract_drawing_volumes (id) ON DELETE RESTRICT,
  UNIQUE KEY ux_condwg_no_project (project_id, condwg_no),
  UNIQUE INDEX idx_contract_drawings_uuid (uuid)
) 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 ของตาราง',
  project_id INT NOT NULL COMMENT 'โครงการ',
  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 'วันที่แก้ไขล่าสุด ',
  FOREIGN KEY (project_id) REFERENCES projects (id)
) 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 ของตาราง',
  project_id INT NOT NULL COMMENT 'โครงการ',
  sub_category_code VARCHAR(50) NOT NULL UNIQUE COMMENT 'รหัสหมวดหมู่ย่อย (เช่น STR - COLUMN)',
  sub_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 'วันที่แก้ไขล่าสุด',
  FOREIGN KEY (project_id) REFERENCES projects (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 ของตาราง',
  uuid UUID NOT NULL DEFAULT UUID() COMMENT 'UUID Public Identifier (ADR-019)',
  project_id INT NOT NULL COMMENT 'โครงการ',
  drawing_number VARCHAR(100) NOT NULL COMMENT 'เลขที่ Shop Drawing',
  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),
  UNIQUE KEY ux_shop_dwg_no_project (project_id, drawing_number),
  UNIQUE INDEX idx_shop_drawings_uuid (uuid)
) 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',
  uuid UUID NOT NULL DEFAULT UUID() COMMENT 'UUID Public Identifier (ADR-019)',
  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)',
  is_current BOOLEAN DEFAULT NULL COMMENT '(TRUE = Revision ปัจจุบัน, NULL = ไม่ใช่ปัจจุบัน)',
  revision_date DATE COMMENT 'วันที่ของ Revision',
  title VARCHAR(500) NOT NULL COMMENT 'ชื่อแบบ',
  description TEXT COMMENT 'คำอธิบายการแก้ไข',
  legacy_drawing_number VARCHAR(100) NULL COMMENT 'เลขที่เดิมของ Shop Drawing',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่สร้าง',
  created_by INT COMMENT 'ผู้สร้าง',
  updated_by INT COMMENT 'ผู้แก้ไขล่าสุด',
  FOREIGN KEY (shop_drawing_id) REFERENCES shop_drawings (id) ON DELETE CASCADE,
  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 ux_sd_rev_drawing_revision (shop_drawing_id, revision_number),
    UNIQUE KEY uq_sd_current (shop_drawing_id, is_current),
    UNIQUE INDEX idx_shop_drawing_revisions_uuid (uuid)
) 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)';

-- ตาราง Master เก็บข้อมูล "AS Built"
CREATE TABLE asbuilt_drawings (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
  uuid UUID NOT NULL DEFAULT UUID() COMMENT 'UUID Public Identifier (ADR-019)',
  project_id INT NOT NULL COMMENT 'โครงการ',
  drawing_number VARCHAR(100) NOT NULL COMMENT 'เลขที่ AS Built Drawing',
  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),
  UNIQUE KEY ux_asbuilt_no_project (project_id, drawing_number),
  UNIQUE INDEX idx_asbuilt_drawings_uuid (uuid)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตาราง Master เก็บข้อมูล "แบบ AS Built"';

-- ตาราง "ลูก" เก็บประวัติ (Revisions) ของ AS Built (1:N)
CREATE TABLE asbuilt_drawing_revisions (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของ Revision',
  uuid UUID NOT NULL DEFAULT UUID() COMMENT 'UUID Public Identifier (ADR-019)',
  asbuilt_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)',
  is_current BOOLEAN DEFAULT NULL COMMENT '(TRUE = Revision ปัจจุบัน, NULL = ไม่ใช่ปัจจุบัน)',
  revision_date DATE COMMENT 'วันที่ของ Revision',
  title VARCHAR(500) NOT NULL COMMENT 'ชื่อแบบ',
  description TEXT COMMENT 'คำอธิบายการแก้ไข',
  legacy_drawing_number VARCHAR(100) NULL COMMENT 'เลขที่เดิมของ AS Built Drawing',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่สร้าง',
  created_by INT COMMENT 'ผู้สร้าง',
  updated_by INT COMMENT 'ผู้แก้ไขล่าสุด',
  FOREIGN KEY (asbuilt_drawing_id) REFERENCES asbuilt_drawings (id) ON DELETE CASCADE,
  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 ux_asbuilt_rev_drawing_revision (asbuilt_drawing_id, revision_number),
    UNIQUE KEY uq_asbuilt_current (asbuilt_drawing_id, is_current),
    UNIQUE INDEX idx_asbuilt_drawing_revisions_uuid (uuid)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตาราง "ลูก" เก็บประวัติ (Revisions) ของ asbuilt_drawings (1:N)';

-- ตารางเชื่อมระหว่าง asbuilt_drawing_revisions กับ shop_drawing_revisions (M:N)
CREATE TABLE asbuilt_revision_shop_revisions_refs (
  asbuilt_drawing_revision_id INT COMMENT 'ID ของ AS Built Drawing Revision',
  shop_drawing_revision_id INT COMMENT 'ID ของ Shop Drawing Revision',
  PRIMARY KEY (
    asbuilt_drawing_revision_id,
    shop_drawing_revision_id
  ),
  FOREIGN KEY (asbuilt_drawing_revision_id) REFERENCES asbuilt_drawing_revisions (id) ON DELETE CASCADE,
  FOREIGN KEY (shop_drawing_revision_id) REFERENCES shop_drawing_revisions (id) ON DELETE CASCADE
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเชื่อมระหว่าง asbuilt_drawing_revisions กับ shop_drawing_revisions (M :N)';

-- =====================================================
-- View: Shop Drawing พร้อม Current Revision
-- =====================================================
CREATE OR REPLACE VIEW vw_shop_drawing_current AS
SELECT sd.id,
  sd.project_id,
  sd.drawing_number,
  sd.main_category_id,
  sd.sub_category_id,
  sd.created_at,
  sd.updated_at,
  sd.deleted_at,
  sd.updated_by,
  sdr.id AS revision_id,
  sdr.revision_number,
  sdr.revision_label,
  sdr.revision_date,
  sdr.title AS revision_title,
  sdr.description AS revision_description,
  sdr.legacy_drawing_number,
  sdr.created_by AS revision_created_by,
  sdr.updated_by AS revision_updated_by
FROM shop_drawings sd
  LEFT JOIN shop_drawing_revisions sdr ON sd.id = sdr.shop_drawing_id
  AND sdr.is_current = TRUE;

-- =====================================================
-- View: As Built Drawing พร้อม Current Revision
-- =====================================================
CREATE OR REPLACE VIEW vw_asbuilt_drawing_current AS
SELECT ad.id,
  ad.project_id,
  ad.drawing_number,
  ad.main_category_id,
  ad.sub_category_id,
  ad.created_at,
  ad.updated_at,
  ad.deleted_at,
  ad.updated_by,
  adr.id AS revision_id,
  adr.revision_number,
  adr.revision_label,
  adr.revision_date,
  adr.title AS revision_title,
  adr.description AS revision_description,
  adr.legacy_drawing_number,
  adr.created_by AS revision_created_by,
  adr.updated_by AS revision_updated_by
FROM asbuilt_drawings ad
  LEFT JOIN asbuilt_drawing_revisions adr ON ad.id = adr.asbuilt_drawing_id
  AND adr.is_current = TRUE;

-- =====================================================
-- 6. 🔄 Circulations (ใบเวียนภายใน)
-- =====================================================
-- ตาราง Master เก็บสถานะใบเวียน
CREATE TABLE circulation_status_codes (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
  code VARCHAR(20) NOT NULL UNIQUE COMMENT 'รหัสสถานะการดำเนินงาน',
  description VARCHAR(50) NOT NULL COMMENT 'คำอธิบายสถานะการดำเนินงาน',
  sort_order INT DEFAULT 0 COMMENT 'ลำดับการแสดงผล',
  is_active TINYINT(1) DEFAULT 1 COMMENT 'สถานะการใช้งาน '
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตาราง Master เก็บสถานะใบเวียน';

-- ตาราง "แม่" ของใบเวียนเอกสารภายใน
CREATE TABLE circulations (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตารางใบเวียน',
  uuid UUID NOT NULL DEFAULT UUID() COMMENT 'UUID Public Identifier (ADR-019)',
  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 'วันที่ปิดใบเวียน',
  deadline_date DATE 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),
  UNIQUE INDEX idx_circulations_uuid (uuid)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตาราง "แม่" ของใบเวียนเอกสารภายใน';

-- ตารางเก็บ Routing/Workflow ของใบเวียน (ขั้นตอนการดำเนินงาน)
CREATE TABLE circulation_routings (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของรายการ routing',
  circulation_id INT NOT NULL COMMENT 'ID ของใบเวียน',
  step_number INT NOT NULL COMMENT 'ลำดับขั้นตอน',
  organization_id INT NOT NULL COMMENT 'ID ขององค์กรในขั้นตอนนี้',
  assigned_to INT NULL COMMENT 'ID ของผู้ใช้ที่ได้รับมอบหมาย (NULL = ยังไม่มอบหมาย)',
  STATUS ENUM(
    'PENDING',
    'IN_PROGRESS',
    'COMPLETED',
    'REJECTED'
  ) DEFAULT 'PENDING' COMMENT 'สถานะขั้นตอน',
  comments TEXT NULL COMMENT 'ความคิดเห็น/หมายเหตุ',
  completed_at DATETIME NULL 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) ON DELETE
  SET NULL,
    INDEX idx_circulation_routing_circulation (circulation_id),
    INDEX idx_circulation_routing_status (STATUS)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเก็บ Routing/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)';

-- ตารางเชื่อมระหว่าง transmittals และเอกสารที่นำส่ง (M:N)
CREATE TABLE transmittal_items (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของรายการ',
  transmittal_id INT NOT NULL COMMENT 'ID ของ Transmittal',
  item_correspondence_id INT NOT NULL COMMENT 'ID ของเอกสารที่แนบไป',
  quantity INT DEFAULT 1 COMMENT 'จำนวน',
  remarks VARCHAR(255) COMMENT 'หมายเหตุสำหรับรายการนี้',
  FOREIGN KEY (transmittal_id) REFERENCES transmittals (correspondence_id) ON DELETE CASCADE,
  FOREIGN KEY (item_correspondence_id) REFERENCES correspondences (id) ON DELETE CASCADE,
  UNIQUE KEY ux_transmittal_item (
    transmittal_id,
    item_correspondence_id
  )
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเชื่อมระหว่าง transmittals และเอกสารที่นำส่ง (M :N)';

-- =====================================================
-- 8. 📎 File Management (ไฟล์แนบ)
-- =====================================================
-- ตาราง "กลาง" เก็บไฟล์แนบทั้งหมดของระบบ
-- 2.2 Attachments - Two-Phase Storage & Security
-- รองรับ: Backend Plan T2.2, Req 3.9.1
-- เหตุผล: จัดการไฟล์ขยะ (Orphan Files) และตรวจสอบความถูกต้องไฟล์
CREATE TABLE attachments (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของไฟล์แนบ',
  uuid UUID NOT NULL DEFAULT UUID() COMMENT 'UUID Public Identifier (ADR-019)',
  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',
  reference_date DATE NULL COMMENT 'Date used for folder structure (e.g. Issue Date) to prevent broken paths',
  workflow_history_id CHAR(36) NULL COMMENT 'FK to workflow_histories.id  for step-specific attachments (ADR-021). NULL = main document',
  ai_processing_status ENUM('PENDING', 'PROCESSING', 'DONE', 'FAILED') NOT NULL DEFAULT 'PENDING' COMMENT 'สถานะ AI job ของไฟล์เอกสารตาม ADR-023A',
  rag_status ENUM('PENDING', 'PROCESSING', 'INDEXED', 'FAILED') NOT NULL DEFAULT 'PENDING' COMMENT 'สถานะ RAG ingestion ระดับ file (ADR-022)',
  rag_last_error TEXT NULL COMMENT 'Error message ล่าสุดเมื่อ rag_status = FAILED',
  FOREIGN KEY (uploaded_by_user_id) REFERENCES users (user_id) ON DELETE CASCADE,
  FOREIGN KEY (workflow_history_id) REFERENCES workflow_histories (id) ON DELETE
  SET NULL ON UPDATE CASCADE,
    INDEX idx_attachments_reference_date (reference_date),
    INDEX idx_att_wfhist_created (workflow_history_id, created_at),
    INDEX idx_attachments_ai_status (ai_processing_status),
    INDEX idx_attachments_rag_status (rag_status),
    UNIQUE INDEX idx_attachments_uuid (uuid)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ตาราง "กลาง" เก็บไฟล์แนบทั้งหมดของระบบ';

-- =====================================================
-- 14. 📄 Document Chunks (ADR-022 RAG)
-- =====================================================
-- ตารางเก็บ vector metadata สำหรับ RAG ingestion
CREATE TABLE document_chunks (
  id CHAR(36) NOT NULL PRIMARY KEY COMMENT 'UUID = Qdrant point ID',
  document_id CHAR(36) NOT NULL COMMENT 'FK → attachments.public_id (UUIDv7)',
  chunk_index INT NOT NULL COMMENT 'ลำดับ chunk ภายใน document',
  content TEXT NOT NULL COMMENT 'เนื้อหา chunk หลัง PyThaiNLP normalize',
  doc_type VARCHAR(20) NOT NULL COMMENT 'CORR, RFA, DRAWING, CONTRACT, RPT, TRANS',
  doc_number VARCHAR(100) NULL COMMENT 'หมายเลขเอกสาร เช่น REF-2026-001',
  revision VARCHAR(20) NULL COMMENT 'Revision เช่น Rev.A',
  project_code VARCHAR(50) NOT NULL COMMENT 'รหัสโครงการ (ใช้ filter)',
  project_public_id CHAR(36) NOT NULL COMMENT 'UUIDv7 ของโครงการ (Qdrant tenant key)',
  version VARCHAR(20) NULL COMMENT 'เวอร์ชันเอกสาร เช่น 1.0, 2.1 (ถ้ามี)',
  classification ENUM('PUBLIC', 'INTERNAL', 'CONFIDENTIAL') NOT NULL DEFAULT 'INTERNAL',
  embedding_model VARCHAR(100) NOT NULL DEFAULT 'nomic-embed-text',
  created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
  INDEX idx_chunks_document_id (document_id),
  INDEX idx_chunks_doc_number_rev (doc_number, revision),
  INDEX idx_chunks_project (project_public_id),
  FULLTEXT INDEX ft_chunks_content (content)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ตาราง Document Chunks สำหรับ RAG (ADR-022)';

-- ตารางเชื่อม correspondence_revisions กับ attachments (M:N)
-- [FIX] FK เปลี่ยนจาก correspondences.id → correspondence_revisions.id
-- เหตุผล: ไฟล์แนบผูกกับ revision ไม่ใช่ correspondence master (แต่ละ revision มีไฟล์ต่างกัน)
CREATE TABLE correspondence_revision_attachments (
  correspondence_revision_id INT NOT NULL COMMENT 'ID ของ Revision ที่ผูกไฟล์แนบนี้',
  attachment_id INT NOT NULL COMMENT 'ID ของไฟล์แนบ',
  is_main_document BOOLEAN DEFAULT FALSE COMMENT '(1 = ไฟล์หลักของ Revision นี้)',
  PRIMARY KEY (correspondence_revision_id, attachment_id),
  FOREIGN KEY (correspondence_revision_id) REFERENCES correspondence_revisions (id) ON DELETE CASCADE,
  FOREIGN KEY (attachment_id) REFERENCES attachments (id) ON DELETE CASCADE,
  INDEX idx_corr_rev_att_revision (correspondence_revision_id)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเชื่อม correspondence_revisions กับ attachments (M:N)';

-- ตารางเชื่อม circulations กับ attachments (M:N)
CREATE TABLE circulation_attachments (
  circulation_id INT COMMENT 'ID ของใบเวียน',
  attachment_id INT COMMENT 'ID ของไฟล์แนบ',
  is_main_document BOOLEAN DEFAULT FALSE COMMENT '(1 = ไฟล์หลักของใบเวียน)',
  PRIMARY KEY (circulation_id, attachment_id),
  FOREIGN KEY (circulation_id) REFERENCES circulations (id) ON DELETE CASCADE,
  FOREIGN KEY (attachment_id) REFERENCES attachments (id) ON DELETE CASCADE
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเชื่อม circulations กับ attachments (M :N)';

-- ตารางเชื่อม shop_drawing_revisions กับ attachments (M:N)
CREATE TABLE asbuilt_drawing_revision_attachments (
  asbuilt_drawing_revision_id INT COMMENT 'ID ของ asbuilt 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 (
    asbuilt_drawing_revision_id,
    attachment_id
  ),
  FOREIGN KEY (asbuilt_drawing_revision_id) REFERENCES asbuilt_drawing_revisions (id) ON DELETE CASCADE,
  FOREIGN KEY (attachment_id) REFERENCES attachments (id) ON DELETE CASCADE
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเชื่อม asbuilt_drawing_revisions กับ attachments (M :N)';

-- ตารางเชื่อม shop_drawing_revisions กับ attachments (M:N)
CREATE TABLE shop_drawing_revision_attachments (
  shop_drawing_revision_id INT COMMENT 'ID ของ Shop Drawing Revision',
  attachment_id INT COMMENT 'ID ของไฟล์แนบ',
  file_type ENUM(
    'PDF',
    'DWG',
    'SOURCE',
    'OTHER '
  ) COMMENT 'ประเภทไฟล์',
  is_main_document BOOLEAN DEFAULT FALSE COMMENT '(1 = ไฟล์หลัก)',
  PRIMARY KEY (
    shop_drawing_revision_id,
    attachment_id
  ),
  FOREIGN KEY (shop_drawing_revision_id) REFERENCES shop_drawing_revisions (id) ON DELETE CASCADE,
  FOREIGN KEY (attachment_id) REFERENCES attachments (id) ON DELETE CASCADE
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเชื่อม shop_drawing_revisions กับ attachments (M :N)';

-- ตารางเชื่อม contract_drawings กับ attachments (M:N)
CREATE TABLE contract_drawing_attachments (
  contract_drawing_id INT COMMENT 'ID ของ Contract Drawing',
  attachment_id INT COMMENT 'ID ของไฟล์แนบ',
  file_type ENUM(
    'PDF',
    'DWG',
    'SOURCE',
    'OTHER '
  ) COMMENT 'ประเภทไฟล์',
  is_main_document BOOLEAN DEFAULT FALSE COMMENT '(1 = ไฟล์หลัก)',
  PRIMARY KEY (contract_drawing_id, attachment_id),
  FOREIGN KEY (contract_drawing_id) REFERENCES contract_drawings (id) ON DELETE CASCADE,
  FOREIGN KEY (attachment_id) REFERENCES attachments (id) ON DELETE CASCADE
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเชื่อม contract_drawings กับ attachments (M :N)';

-- =====================================================
-- 9. 🔢 Document Numbering (การสร้างเลขที่เอกสาร)
-- =====================================================
-- ตาราง Master เก็บ "รูปแบบ" Template ของเลขที่เอกสาร
CREATE TABLE document_number_formats (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
  project_id INT NOT NULL COMMENT 'โครงการ',
  correspondence_type_id INT NULL COMMENT 'ประเภทเอกสาร',
  discipline_id INT DEFAULT 0 COMMENT 'สาขางาน (0 = ทุกสาขา/ไม่ระบุ)',
  format_string VARCHAR(100) NOT NULL COMMENT 'Format pattern (e.g., {ORG}-{TYPE}-{YYYY}-#)',
  description TEXT COMMENT 'Format description',
  reset_annually BOOLEAN DEFAULT TRUE 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 (project_id) REFERENCES projects (id) ON DELETE CASCADE,
  FOREIGN KEY (correspondence_type_id) REFERENCES correspondence_types (id) ON DELETE CASCADE,
  UNIQUE KEY unique_format (project_id, correspondence_type_id)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตาราง Master เก็บ "รูปแบบ" Template ของเลขที่เอกสาร';

-- ==========================================================
-- [v1.5.1 UPDATE] ตารางเก็บ "ตัวนับ" (Running Number) ล่าสุด
-- เปลี่ยนแปลงหลัก:
--   - PRIMARY KEY: เปลี่ยนจาก 5 คอลัมน์เป็น 8 คอลัมน์
--   - เพิ่มคอลัมน์: recipient_organization_id, sub_type_id, rfa_type_id
--   - เพิ่ม INDEXES สำหรับ performance
--   - เพิ่ม CONSTRAINTS สำหรับ data validation
-- เหตุผล: รองรับ 10 token types และ granular counter management
-- รองรับ: Backend Plan T2.3, Req 3.11.5, specs v1.5.1
-- ==========================================================
CREATE TABLE document_number_counters (
  -- [v1.5.1] Composite Primary Key Columns (8 columns total)
  project_id INT NOT NULL COMMENT 'โครงการ',
  correspondence_type_id INT NULL COMMENT 'ประเภทเอกสาร (LETTER, RFA, TRANSMITTAL, etc.) NULL = default format for project',
  originator_organization_id INT NOT NULL COMMENT 'องค์กรผู้ส่ง',
  -- เปลี่ยนจาก NULL เป็น DEFAULT 0
  recipient_organization_id INT NOT NULL DEFAULT 0 COMMENT '[v1.7.0] องค์กรผู้รับ 0 = no recipient (RFA)',
  sub_type_id INT DEFAULT 0 COMMENT '[v1.5.1 NEW] ประเภทย่อย สำหรับ TRANSMITTAL (0 = ไม่ระบุ)',
  rfa_type_id INT DEFAULT 0 COMMENT '[v1.5.1 NEW] ประเภท RFA เช่น SHD, RPT, MAT (0 = ไม่ใช่ RFA)',
  discipline_id INT DEFAULT 0 COMMENT 'สาขางาน เช่น TER, STR, GEO (0 = ไม่ระบุ)',
  reset_scope VARCHAR(20) NOT NULL COMMENT 'Scope of reset (PROJECT, ORGANIZATION, etc.)',
  -- Counter Data
  last_number INT DEFAULT 0 NOT NULL COMMENT 'เลขที่ล่าสุดที่ใช้ไปแล้ว (auto-increment)',
  version INT DEFAULT 0 NOT NULL COMMENT 'Optimistic Lock Version (TypeORM @VersionColumn)',
  -- Metadata
  created_at DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
  updated_at DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
  -- [v1.7.0 UPDATE] Primary Key: 5 columns -> 8 columns
  PRIMARY KEY (
    project_id,
    originator_organization_id,
    recipient_organization_id,
    correspondence_type_id,
    sub_type_id,
    rfa_type_id,
    discipline_id,
    reset_scope
  ),
  -- Foreign Keys
  FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE,
  FOREIGN KEY (originator_organization_id) REFERENCES organizations (id) ON DELETE CASCADE,
  FOREIGN KEY (correspondence_type_id) REFERENCES correspondence_types (id) ON DELETE CASCADE,
  -- Performance Indexes
  INDEX idx_counter_lookup (project_id, correspondence_type_id, reset_scope),
  INDEX idx_counter_org (originator_organization_id, reset_scope),
  -- Constraints
  CONSTRAINT chk_last_number_positive CHECK (last_number >= 0),
  CONSTRAINT chk_reset_scope_format CHECK (
    reset_scope IN ('NONE')
    OR reset_scope LIKE 'YEAR_%'
    OR reset_scope LIKE 'MONTH_%'
    OR reset_scope LIKE 'CONTRACT_%'
  )
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเก็บ Running Number Counters - รองรับ 8-column composite PK';

-- ==========================================================
-- ตารางเก็บ Audit Trail สำหรับการสร้างเลขที่เอกสาร
-- เพิ่มตาราง: document_number_audit
-- เหตุผล: บันทึกประวัติการสร้างเลขที่ รองรับ audit requirement ≥ 7 ปี
-- ==========================================================
CREATE TABLE document_number_audit (
  id INT AUTO_INCREMENT PRIMARY KEY COMMENT 'ID ของ audit record',
  -- Document Info
  document_id INT NULL COMMENT 'ID ของเอกสารที่สร้างเลขที่ (correspondences.id) - NULL if failed/reserved',
  document_type VARCHAR(50),
  document_number VARCHAR(100) NOT NULL COMMENT 'เลขที่เอกสารที่สร้าง (ผลลัพธ์)',
  operation ENUM(
    'RESERVE',
    'CONFIRM',
    'MANUAL_OVERRIDE',
    'VOID_REPLACE',
    'CANCEL',
    'VOID',
    'GENERATE'
  ) NOT NULL DEFAULT 'CONFIRM' COMMENT 'ประเภทการดำเนินการ',
  STATUS ENUM(
    'RESERVED',
    'CONFIRMED',
    'CANCELLED',
    'VOID',
    'MANUAL'
  ) NOT NULL DEFAULT 'RESERVED' COMMENT 'สถานะเลขที่เอกสาร',
  counter_key JSON NOT NULL COMMENT 'Counter key ที่ใช้ (JSON format) - 8 fields',
  reservation_token VARCHAR(36) NULL,
  idempotency_key VARCHAR(128) NULL COMMENT 'Idempotency Key from request',
  originator_organization_id INT NULL,
  recipient_organization_id INT NULL,
  template_used VARCHAR(200) NOT NULL COMMENT 'Template ที่ใช้ในการสร้าง',
  old_value TEXT NULL COMMENT 'Previous value for audit',
  new_value TEXT NULL COMMENT 'New value for audit',
  -- User Info
  user_id INT NULL COMMENT 'ผู้ขอสร้างเลขที่',
  ip_address VARCHAR(45) COMMENT 'IP address ของผู้ขอ (IPv4/IPv6)',
  user_agent TEXT COMMENT 'User agent string (browser info)',
  is_success BOOLEAN DEFAULT TRUE,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่/เวลาที่สร้าง',
  -- Performance & Error Tracking
  retry_count INT DEFAULT 0 COMMENT 'จำนวนครั้งที่ retry ก่อนสำเร็จ',
  lock_wait_ms INT COMMENT 'เวลารอ Redis lock (milliseconds)',
  total_duration_ms INT COMMENT 'เวลารวมทั้งหมดในการสร้าง (milliseconds)',
  fallback_used ENUM('NONE', 'DB_LOCK', 'RETRY') DEFAULT 'NONE' COMMENT 'Fallback strategy ที่ถูกใช้ (NONE=normal, DB_LOCK=Redis down, RETRY=conflict)',
  metadata JSON COMMENT 'Additional context data',
  -- Indexes for performance
  INDEX idx_document_id (document_id),
  INDEX idx_user_id (user_id),
  INDEX idx_status (STATUS),
  INDEX idx_operation (operation),
  INDEX idx_document_number (document_number),
  INDEX idx_reservation_token (reservation_token),
  INDEX idx_idempotency_key (idempotency_key),
  INDEX idx_created_at (created_at),
  -- Foreign Keys
  FOREIGN KEY (document_id) REFERENCES correspondences (id) ON DELETE CASCADE,
  FOREIGN KEY (user_id) REFERENCES users (user_id)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '[v1.5.1 NEW] Audit Trail สำหรับการสร้างเลขที่เอกสาร - เก็บ ≥ 7 ปี';

-- ==========================================================
-- [v1.5.1 NEW] ตารางเก็บ Error Logs สำหรับ Document Numbering
-- เพิ่มตาราง: document_number_errors
-- เหตุผล: ติดตาม errors, troubleshooting, monitoring
-- รองรับ: Req 3.11.6, Ops monitoring requirements
-- ==========================================================
CREATE TABLE document_number_errors (
  id INT AUTO_INCREMENT PRIMARY KEY COMMENT 'ID ของ error record',
  -- Error Classification
  error_type ENUM(
    'LOCK_TIMEOUT',
    -- Redis lock timeout
    'VERSION_CONFLICT',
    -- Optimistic lock version mismatch
    'DB_ERROR',
    -- Database connection/query error
    'REDIS_ERROR',
    -- Redis connection error
    'VALIDATION_ERROR',
    -- Template/input validation error
    'SEQUENCE_EXHAUSTED',
    -- Counter reached maximum value
    'RESERVATION_EXPIRED',
    -- Reservation token expired
    'DUPLICATE_NUMBER',
    -- Duplicate document number detected
    'GENERATE_ERROR' -- General generation error
  ) NOT NULL COMMENT 'ประเภท error (9 types)',
  -- Error Details
  error_message TEXT COMMENT 'ข้อความ error (stack top)',
  stack_trace TEXT COMMENT 'Stack trace แบบเต็ม (สำหรับ debugging)',
  context_data JSON COMMENT 'Context ของ request (user, project, counter_key, etc.)',
  -- User Info
  user_id INT COMMENT 'ผู้ที่เกิด error',
  ip_address VARCHAR(45) COMMENT 'IP address',
  -- Timestamps
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่เกิด error',
  resolved_at TIMESTAMP NULL COMMENT 'วันที่แก้ไขแล้ว (NULL = ยังไม่แก้)',
  -- Indexes for troubleshooting
  INDEX idx_error_type (error_type),
  INDEX idx_created_at (created_at),
  INDEX idx_user_id (user_id),
  INDEX idx_unresolved (resolved_at) -- Find unresolved errors
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '[v1.5.1 NEW] Error Log สำหรับ Document Numbering System';

-- =====================================================
CREATE TABLE document_number_reservations (
  id INT AUTO_INCREMENT PRIMARY KEY,
  -- Reservation Details
  token VARCHAR(36) NOT NULL UNIQUE COMMENT 'UUID v4',
  document_number VARCHAR(100) NOT NULL UNIQUE,
  document_number_status ENUM('RESERVED', 'CONFIRMED', 'CANCELLED', 'VOID') NOT NULL DEFAULT 'RESERVED',
  -- Linkage
  document_id INT NULL COMMENT 'FK to documents (NULL until confirmed)',
  -- Context (for debugging)
  project_id INT NOT NULL,
  correspondence_type_id INT NOT NULL,
  originator_organization_id INT NOT NULL,
  recipient_organization_id INT DEFAULT 0,
  user_id INT NOT NULL,
  -- Timestamps
  reserved_at DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
  expires_at DATETIME(6) NOT NULL,
  confirmed_at DATETIME(6) NULL,
  cancelled_at DATETIME(6) NULL,
  -- Audit
  ip_address VARCHAR(45),
  user_agent TEXT,
  metadata JSON NULL COMMENT 'Additional context',
  -- Indexes
  INDEX idx_token (token),
  INDEX idx_status (document_number_status),
  INDEX idx_status_expires (document_number_status, expires_at),
  INDEX idx_document_id (document_id),
  INDEX idx_user_id (user_id),
  INDEX idx_reserved_at (reserved_at),
  -- Foreign Keys
  FOREIGN KEY (document_id) REFERENCES correspondence_revisions(id) ON DELETE
  SET NULL,
    FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
    FOREIGN KEY (correspondence_type_id) REFERENCES correspondence_types(id) ON DELETE CASCADE,
    FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'Document Number Reservations - Two-Phase Commit';

-- =====================================================
-- 10. ⚙️ System & Logs (ระบบและ Log)
-- =====================================================
-- 1.1 JSON Schemas Registry
-- รองรับ: Backend Plan T2.5.1, Req 6.11.1
-- เหตุผล: เพื่อ Validate โครงสร้าง JSON Details ของเอกสารแต่ละประเภทแบบ Centralized
CREATE TABLE json_schemas (
  id INT AUTO_INCREMENT PRIMARY KEY,
  schema_code VARCHAR(100) NOT NULL COMMENT 'รหัส Schema (เช่น RFA_DWG)',
  version INT NOT NULL DEFAULT 1 COMMENT 'เวอร์ชันของ Schema',
  table_name VARCHAR(100) NOT NULL COMMENT 'ชื่อตารางเป้าหมาย (เช่น rfa_revisions)',
  schema_definition JSON NOT NULL COMMENT 'โครงสร้าง Data Schema (AJV Standard)',
  ui_schema JSON NULL COMMENT 'โครงสร้าง UI Schema สำหรับ Frontend',
  virtual_columns JSON NULL COMMENT 'Config สำหรับสร้าง Virtual Columns',
  migration_script JSON NULL COMMENT 'Script สำหรับแปลงข้อมูลจากเวอร์ชันก่อนหน้า',
  is_active BOOLEAN DEFAULT TRUE COMMENT 'สถานะการใช้งาน',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  -- ป้องกัน Schema Code ซ้ำกันใน Version เดียวกัน
  UNIQUE KEY uk_schema_version (schema_code, version)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ตารางเก็บ JSON Schema และ Configuration';

-- 1.2 User Preferences
-- รองรับ: Req 5.5, 6.8.3
-- เหตุผล: แยกการตั้งค่า Notification และ UI ออกจากตาราง Users หลัก
CREATE TABLE user_preferences (
  user_id INT PRIMARY KEY,
  notify_email BOOLEAN DEFAULT TRUE,
  notify_line BOOLEAN DEFAULT TRUE,
  digest_mode BOOLEAN DEFAULT FALSE COMMENT 'รับแจ้งเตือนแบบรวม (Digest) แทน Real - time',
  ui_theme VARCHAR(20) DEFAULT 'light',
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  CONSTRAINT fk_user_prefs_user FOREIGN KEY (user_id) REFERENCES users (user_id) ON DELETE CASCADE
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

-- ตารางเก็บบันทึกการกระทำของผู้ใช้
-- 4.1 Audit Logs Enhancements
-- รองรับ: Req 6.1
-- เหตุผล: รองรับ Distributed Tracing และระบุความรุนแรง
CREATE TABLE audit_logs (
  audit_id BIGINT NOT NULL AUTO_INCREMENT COMMENT 'ID ของ Log',
  request_id VARCHAR(100) NULL COMMENT 'Trace ID linking to app logs',
  user_id INT COMMENT 'ผู้กระทำ',
  ACTION VARCHAR(100) NOT NULL COMMENT 'การกระทำ (
        เช่น rfa.create,
        correspondence.update,
        login.success
    )',
  severity ENUM(
    'INFO',
    'WARN',
    'ERROR',
    'CRITICAL '
  ) DEFAULT 'INFO',
  entity_type VARCHAR(50) COMMENT 'ตาราง / โมดูล (เช่น ''rfa '', ''correspondence '')',
  entity_id VARCHAR(50) COMMENT 'Primary ID ของระเบียนที่ได้รับผลกระทำ',
  details_json JSON COMMENT 'ข้อมูลบริบท',
  ip_address VARCHAR(45) COMMENT 'IP Address',
  user_agent VARCHAR(255) COMMENT 'User Agent',
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 'เวลาที่กระทำ',
  -- [แก้ไข] รวม created_at เข้ามาใน Primary Key เพื่อรองรับ Partition
  PRIMARY KEY (audit_id, created_at),
  -- [แก้ไข] ใช้ Index ธรรมดาแทน Foreign Key เพื่อไม่ให้ติดข้อจำกัดของ Partition Table
  INDEX idx_audit_user (user_id),
  INDEX idx_audit_action (ACTION),
  INDEX idx_audit_entity (entity_type, entity_id),
  INDEX idx_audit_created (created_at)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเก็บบันทึกการกระทำของผู้ใช้' -- [เพิ่ม] คำสั่ง Partition
PARTITION BY RANGE (YEAR(created_at)) (
  PARTITION p_old
  VALUES LESS THAN (2024),
    PARTITION p2024
  VALUES LESS THAN (2025),
    PARTITION p2025
  VALUES LESS THAN (2026),
    PARTITION p2026
  VALUES LESS THAN (2027),
    PARTITION p2027
  VALUES LESS THAN (2028),
    PARTITION p2028
  VALUES LESS THAN (2029),
    PARTITION p2029
  VALUES LESS THAN (2030),
    PARTITION p2030
  VALUES LESS THAN (2031),
    PARTITION p_future
  VALUES LESS THAN MAXVALUE
);

-- ตารางสำหรับจัดการการแจ้งเตือน (Email/Line/System)
CREATE TABLE notifications (
  id INT NOT NULL AUTO_INCREMENT COMMENT 'ID ของการแจ้งเตือน',
  uuid UUID NOT NULL DEFAULT UUID() COMMENT 'UUID Public Identifier (ADR-019)',
  user_id INT NOT NULL COMMENT 'ID ผู้ใช้',
  title VARCHAR(255) NOT NULL COMMENT 'หัวข้อการแจ้งเตือน',
  message TEXT NOT NULL COMMENT 'รายละเอียดการแจ้งเตือน',
  notification_type ENUM('EMAIL', 'LINE', 'SYSTEM ') NOT NULL COMMENT 'ประเภท (EMAIL, LINE, SYSTEM)',
  is_read BOOLEAN DEFAULT FALSE COMMENT 'สถานะการอ่าน',
  entity_type VARCHAR(50) COMMENT 'เช่น ''rfa '',
    ''circulation ''',
  entity_id INT COMMENT 'ID ของเอนทิตีที่เกี่ยวข้อง',
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่สร้าง',
  -- [แก้ไข] รวม created_at เข้ามาใน Primary Key
  PRIMARY KEY (id, created_at),
  -- [แก้ไข] ใช้ Index ธรรมดาแทน Foreign Key
  INDEX idx_notif_user (user_id),
  INDEX idx_notif_type (notification_type),
  INDEX idx_notif_read (is_read),
  INDEX idx_notif_created (created_at),
  INDEX idx_notifications_uuid (uuid)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางสำหรับจัดการการแจ้งเตือน (Email / Line / System)' -- [เพิ่ม] คำสั่ง Partition
PARTITION BY RANGE (YEAR(created_at)) (
  PARTITION p_old
  VALUES LESS THAN (2024),
    PARTITION p2024
  VALUES LESS THAN (2025),
    PARTITION p2025
  VALUES LESS THAN (2026),
    PARTITION p2026
  VALUES LESS THAN (2027),
    PARTITION p2027
  VALUES LESS THAN (2028),
    PARTITION p2028
  VALUES LESS THAN (2029),
    PARTITION p2029
  VALUES LESS THAN (2030),
    PARTITION p2030
  VALUES LESS THAN (2031),
    PARTITION p_future
  VALUES LESS THAN MAXVALUE
);

-- ตารางสำหรับจัดการดัชนีการค้นหาขั้นสูง (Full-text Search)
CREATE TABLE search_indices (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของดัชนี',
  entity_type VARCHAR(50) NOT NULL COMMENT 'ชนิดเอนทิตี (เช่น ''correspondence '', ''rfa '')',
  entity_id INT NOT NULL COMMENT 'ID ของเอนทิตี',
  content TEXT NOT NULL COMMENT 'เนื้อหาที่จะค้นหา',
  indexed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่สร้าง / อัปเดตัชนี '
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางสำหรับจัดการดัชนีการค้นหาขั้นสูง (Full - text Search)';

-- ตารางสำหรับบันทึกประวัติการสำรองข้อมูล
CREATE TABLE backup_logs (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของการสำรอง',
  backup_type ENUM('DATABASE', 'FILES', 'FULL') NOT NULL COMMENT 'ประเภท (DATABASE, FILES, FULL)',
  backup_path VARCHAR(500) NOT NULL COMMENT 'ตำแหน่งไฟล์สำรอง',
  file_size BIGINT COMMENT 'ขนาดไฟล์',
  STATUS ENUM('STARTED', 'COMPLETED', 'FAILED') NOT NULL COMMENT 'สถานะ',
  started_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'เวลาเริ่มต้น',
  completed_at TIMESTAMP NULL COMMENT 'เวลาเสร็จสิ้น',
  error_message TEXT COMMENT 'ข้อความผิดพลาด (ถ้ามี)'
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางสำหรับบันทึกประวัติการสำรองข้อมูล';

-- ============================================================
-- ส่วนที่ 11: Unified Workflow Engine (Phase 6A/Phase 3)
-- ============================================================
DROP TABLE IF EXISTS workflow_histories;

DROP TABLE IF EXISTS workflow_instances;

DROP TABLE IF EXISTS workflow_definitions;

-- 1. ตารางเก็บนิยาม Workflow (Definition / DSL)
CREATE TABLE workflow_definitions (
  id CHAR(36) NOT NULL PRIMARY KEY COMMENT 'UUID ของ Workflow Definition',
  workflow_code VARCHAR(50) NOT NULL COMMENT 'รหัส Workflow เช่น RFA_FLOW_V1, CORRESPONDENCE_FLOW_V1',
  version INT NOT NULL DEFAULT 1 COMMENT 'หมายเลข Version',
  description TEXT NULL COMMENT 'คำอธิบาย Workflow',
  dsl JSON NOT NULL COMMENT 'นิยาม Workflow ต้นฉบับ (YAML/JSON Format)',
  compiled JSON NOT NULL COMMENT 'โครงสร้าง Execution Tree ที่ Compile แล้ว',
  is_active BOOLEAN DEFAULT TRUE COMMENT 'สถานะการใช้งาน',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่สร้าง',
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'วันที่แก้ไขล่าสุด',
  -- ป้องกันการมี Workflow Code และ Version ซ้ำกัน
  UNIQUE KEY uq_workflow_version (workflow_code, version)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ตารางเก็บนิยามกฎการเดินเอกสาร (Workflow DSL)';

-- 2. ตารางเก็บ Workflow Instance (สถานะเอกสารจริง)
CREATE TABLE workflow_instances (
  id CHAR(36) NOT NULL PRIMARY KEY COMMENT 'UUID ของ Instance',
  definition_id CHAR(36) NOT NULL COMMENT 'อ้างอิง Definition ที่ใช้',
  contract_id INT NULL COMMENT 'Contract ที่ Workflow นี้เป็นส่วนหนึ่ง (NULL = org-scoped หรือ legacy)',
  -- [delta-07]
  entity_type VARCHAR(50) NOT NULL COMMENT 'ประเภทเอกสาร (rfa_revision, correspondence_revision, circulation)',
  entity_id VARCHAR(50) NOT NULL COMMENT 'ID ของเอกสาร (String/Int)',
  current_state VARCHAR(50) NOT NULL COMMENT 'สถานะปัจจุบัน',
  STATUS ENUM(
    'ACTIVE',
    'COMPLETED',
    'CANCELLED',
    'TERMINATED'
  ) DEFAULT 'ACTIVE' COMMENT 'สถานะภาพรวม',
  context JSON NULL COMMENT 'ตัวแปร Context สำหรับตัดสินใจ',
  version_no INT NOT NULL DEFAULT 1 COMMENT 'Optimistic lock counter — incremented on every successful transition (ADR-001 v1.1 FR-002). Client sends current value; server rejects with 409 if mismatch.',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  CONSTRAINT fk_wf_inst_def FOREIGN KEY (definition_id) REFERENCES workflow_definitions (id) ON DELETE CASCADE,
  CONSTRAINT fk_wf_inst_contract FOREIGN KEY (contract_id) REFERENCES contracts (id) ON DELETE
  SET NULL -- [delta-07]
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ตารางเก็บสถานะการเดินเรื่องของเอกสาร';

-- 3. ตารางเก็บประวัติ (Audit Log / History)
CREATE TABLE workflow_histories (
  id CHAR(36) NOT NULL PRIMARY KEY COMMENT 'UUID',
  instance_id CHAR(36) NOT NULL COMMENT 'อ้างอิง Instance',
  from_state VARCHAR(50) NOT NULL COMMENT 'สถานะต้นทาง',
  to_state VARCHAR(50) NOT NULL COMMENT 'สถานะปลายทาง',
  ACTION VARCHAR(50) NOT NULL COMMENT 'Action ที่กระทำ',
  action_by_user_id INT NULL COMMENT 'User ID ผู้กระทำ',
  action_by_user_uuid VARCHAR(36) NULL COMMENT 'UUID ของ User ผู้ดำเนินการ — ใช้ใน API Response แทน INT FK (ADR-019). NULL = System Action หรือ Pre-migration record',
  COMMENT TEXT NULL COMMENT 'ความเห็น',
  metadata JSON NULL COMMENT 'Snapshot ข้อมูล ณ ขณะนั้น',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT fk_wf_hist_inst FOREIGN KEY (instance_id) REFERENCES workflow_instances (id) ON DELETE CASCADE
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ตารางประวัติการเปลี่ยนสถานะ Workflow';

-- =====================================================
-- 11. 🤖 AI Gateway (ตาราง AI Integration - ADR-018, ADR-020)
-- =====================================================
-- ตารางเก็บบันทึก Migration เอกสารที่ผ่าน AI Processing
CREATE TABLE migration_logs (
  id INT AUTO_INCREMENT PRIMARY KEY COMMENT 'Internal PK (ห้าม expose ใน API)',
  uuid UUID NOT NULL DEFAULT UUID() COMMENT 'UUID Public Identifier (ADR-019)',
  source_file VARCHAR(255) NOT NULL COMMENT 'Path ของไฟล์ต้นทาง',
  source_metadata JSON NULL COMMENT 'Metadata จาก Excel/แหล่งข้อมูลต้นทาง',
  ai_extracted_metadata JSON NULL COMMENT 'Metadata ที่ AI สกัดได้',
  confidence_score DECIMAL(3, 2) NULL COMMENT 'คะแนนความมั่นใจ AI (0.00-1.00)',
  STATUS ENUM(
    'PENDING_REVIEW',
    'VERIFIED',
    'IMPORTED',
    'FAILED'
  ) NOT NULL DEFAULT 'PENDING_REVIEW' COMMENT 'สถานะ: PENDING_REVIEW=รอตรวจ, VERIFIED=ตรวจแล้ว, IMPORTED=นำเข้าแล้ว, FAILED=ล้มเหลว',
  admin_feedback TEXT NULL COMMENT 'ความเห็นจาก Admin ผู้ตรวจสอบ',
  reviewed_by INT NULL COMMENT 'User ID ของ Admin ที่ตรวจสอบ (FK users.id)',
  reviewed_at TIMESTAMP NULL COMMENT 'เวลาที่ตรวจสอบ',
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่สร้าง',
  updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'วันที่แก้ไขล่าสุด',
  UNIQUE INDEX idx_migration_logs_uuid (uuid),
  INDEX idx_migration_logs_status (STATUS),
  INDEX idx_migration_logs_confidence (confidence_score),
  FOREIGN KEY (reviewed_by) REFERENCES users (user_id) ON DELETE
  SET NULL
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ตารางเก็บบันทึก Migration เอกสารที่ผ่าน AI Processing (Task BE-AI-02)';

-- =====================================================
-- 12. 🤖 AI Migration Review Queue (ADR-023, ADR-023A)
-- =====================================================
-- ตาราง staging queue สำหรับ AI migration ตาม ADR-023A
CREATE TABLE migration_review_queue (
  id INT NOT NULL AUTO_INCREMENT COMMENT 'Internal PK (ห้าม expose ใน API)',
  uuid UUID NOT NULL DEFAULT UUID() COMMENT 'UUID Public Identifier (ADR-019)',
  batch_id VARCHAR(100) NOT NULL COMMENT 'n8n batch identifier',
  idempotency_key VARCHAR(200) NOT NULL COMMENT 'Idempotency-Key สำหรับป้องกัน queue ซ้ำ',
  original_filename VARCHAR(500) NOT NULL COMMENT 'ชื่อไฟล์ต้นฉบับจาก legacy source',
  storage_temp_path VARCHAR(1000) NOT NULL COMMENT 'temp storage path ก่อน import',
  ai_job_id VARCHAR(36) NULL COMMENT 'BullMQ Job ID สำหรับงานประมวลผล AI',
  ai_metadata_json LONGTEXT NOT NULL COMMENT 'AI suggestion payload เต็มสำหรับ human review' CHECK (json_valid(`ai_metadata_json`)),
  confidence_score DECIMAL(5, 4) NOT NULL COMMENT 'AI confidence score 0.0000-1.0000',
  ocr_used TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'ระบุว่าใช้ OCR path หรือไม่',
  STATUS ENUM(
    'PENDING',
    'PENDING_REVIEW',
    'IMPORTED',
    'REJECTED'
  ) NOT NULL DEFAULT 'PENDING',
  temp_attachment_id INT NULL COMMENT 'Temporary attachment ID referencing attachments.id (ADR-028)',
  reviewed_by INT NULL COMMENT 'Internal users.user_id ของผู้ review',
  reviewed_at DATETIME NULL COMMENT 'เวลาที่ review record',
  rejection_reason VARCHAR(500) NULL COMMENT 'เหตุผลเมื่อ reject',
  version INT NOT NULL DEFAULT 1 COMMENT 'Optimistic locking version',
  created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id),
  UNIQUE KEY uq_migration_review_uuid (uuid),
  UNIQUE KEY uq_migration_review_idempotency (idempotency_key),
  KEY idx_migration_review_status_created (STATUS, created_at),
  KEY idx_migration_review_batch (batch_id),
  KEY idx_migration_review_reviewed_by (reviewed_by),
  CONSTRAINT fk_migration_review_reviewed_by FOREIGN KEY (reviewed_by) REFERENCES users (user_id) ON DELETE
  SET NULL
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ADR-023A AI migration review staging queue';

-- ตาราง Audit Log สำหรับการทำงานของ AI ทุกครั้ง (ADR-023, ADR-023A)
CREATE TABLE ai_audit_logs (
  id INT AUTO_INCREMENT PRIMARY KEY COMMENT 'Internal PK (ห้าม expose ใน API)',
  uuid UUID NOT NULL DEFAULT UUID() COMMENT 'UUID Public Identifier (ADR-019)',
  document_public_id UUID NULL COMMENT 'Imported document publicId when available',
  ai_model VARCHAR(50) NOT NULL DEFAULT 'gemma4' COMMENT 'Legacy AI model column used by current gateway service',
  model_name VARCHAR(100) NOT NULL COMMENT 'Local model name used by ADR-023 AI pipeline',
  effective_profile VARCHAR(50) NULL COMMENT 'ExecutionProfile ที่ backend กำหนด: interactive|standard|quality|deep-analysis (Feature-235)',
  canonical_model VARCHAR(50) NULL COMMENT 'Canonical model identity: np-dms-ai หรือ np-dms-ocr (Feature-235, ADR-023)',
  snapshot_params_json LONGTEXT NULL COMMENT 'Runtime parameters snapshot ณ เวลา dispatch — ใช้จริงใน Ollama call (FR-A09, Feature-235)' CHECK (json_valid(`snapshot_params_json`)),
  model_type VARCHAR(50) NULL COMMENT 'ประเภท OCR/LLM model ที่ใช้ เช่น tesseract, typhoon-ocr-3b',
  vram_usage_mb INT NULL COMMENT 'VRAM ที่ใช้จริง (MB) ณ เวลาประมวลผล',
  cache_hit TINYINT(1) NOT NULL DEFAULT 0 COMMENT '1 = ผลลัพธ์มาจาก Redis cache, 0 = OCR ใหม่',
  ai_suggestion_json LONGTEXT NULL COMMENT 'AI suggested metadata' CHECK (json_valid(`ai_suggestion_json`)),
  human_override_json LONGTEXT NULL COMMENT 'Human approved or overridden metadata' CHECK (json_valid(`human_override_json`)),
  processing_time_ms INT NULL COMMENT 'Legacy processing duration field',
  confidence_score DECIMAL(4, 3) NULL COMMENT 'AI confidence score 0.000-1.000',
  input_hash VARCHAR(64) NULL COMMENT 'Legacy SHA-256 input hash',
  output_hash VARCHAR(64) NULL COMMENT 'Legacy SHA-256 output hash',
  STATUS ENUM('SUCCESS', 'FAILED', 'TIMEOUT') NOT NULL DEFAULT 'SUCCESS' COMMENT 'Legacy processing status field',
  error_message TEXT NULL COMMENT 'Legacy processing error field',
  confirmed_by_user_id INT NULL COMMENT 'Internal users.user_id that confirmed the record',
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  UNIQUE KEY idx_ai_audit_logs_uuid (uuid),
  KEY idx_ai_audit_document (document_public_id),
  KEY idx_ai_audit_model (ai_model),
  KEY idx_ai_audit_model_name (model_name),
  KEY idx_ai_audit_status (STATUS),
  KEY idx_ai_audit_confirmed_by (confirmed_by_user_id),
  KEY idx_ai_audit_model_type (model_type),
  KEY idx_ai_audit_effective_profile (effective_profile),
  KEY idx_ai_audit_canonical_model (canonical_model),
  CONSTRAINT fk_ai_audit_confirmed_by_user FOREIGN KEY (confirmed_by_user_id) REFERENCES users (user_id) ON DELETE
  SET NULL
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ADR-023 AI development feedback log';

-- =====================================================
-- 13. 🤖 AI Available Models (ADR-027, ADR-034)
-- =====================================================
-- ตารางเก็บรายการโมเดล AI ที่ให้เลือกใช้งานในระบบ
CREATE TABLE ai_available_models (
  id INT AUTO_INCREMENT PRIMARY KEY COMMENT 'ID ของตาราง',
  model_name VARCHAR(100) NOT NULL UNIQUE COMMENT 'ชื่อโมเดล เช่น gemma4:e2b, gemma4:e4b',
  model_version VARCHAR(50) NOT NULL COMMENT 'เวอร์ชั่นของโมเดล',
  description VARCHAR(500) NULL COMMENT 'รายละเอียดโมเดล',
  vram_gb DECIMAL(4, 2) NULL COMMENT 'VRAM ที่ใช้โดยประมาณ (GB)',
  is_active TINYINT(1) DEFAULT 1 COMMENT 'สถานะใช้งาน',
  is_default TINYINT(1) DEFAULT 0 COMMENT 'โมเดลเริ่มต้น',
  created_by INT NULL,
  updated_by INT NULL,
  created_at DATETIME(3) DEFAULT CURRENT_TIMESTAMP(3),
  updated_at DATETIME(3) DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
  deleted_at DATETIME(3) NULL,
  UNIQUE KEY uk_model_name (model_name),
  KEY idx_is_active (is_active),
  KEY idx_is_default (is_default)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ตารางเก็บรายการโมเดล AI ที่ให้เลือกใช้งานในระบบ (ADR-027)';

-- =====================================================
-- 14. 🤖 AI Prompts (ADR-029)
-- =====================================================
-- ตาราง versioned prompt templates สำหรับ OCR extraction
CREATE TABLE ai_prompts (
  id INT AUTO_INCREMENT PRIMARY KEY COMMENT 'ID ภายใน (ไม่ expose ใน API)',
  public_id UUID NOT NULL UNIQUE COMMENT 'UUID Public Identifier (ADR-019)',
  prompt_type VARCHAR(50) NOT NULL COMMENT 'ประเภท prompt เช่น ocr_extraction',
  version_number INT NOT NULL COMMENT 'เลข version ต่อเนื่องต่อ prompt_type (1, 2, 3...)',
  template TEXT NOT NULL COMMENT 'prompt template ที่มี {{ocr_text}} placeholder บังคับ',
  field_schema LONGTEXT NULL COMMENT 'definition ของ fields ที่คาดหวังในผลลัพธ์ JSON' CHECK (json_valid(`field_schema`)),
  is_active TINYINT(1) NOT NULL DEFAULT 0 COMMENT '1 = version นี้ใช้งานจริงทั้ง sandbox และ migrate-document (1 per prompt_type)',
  test_result_json LONGTEXT NULL COMMENT 'ผลลัพธ์ JSON จาก sandbox run ล่าสุด (auto-save โดย processor)' CHECK (json_valid(`test_result_json`)),
  manual_note TEXT NULL COMMENT 'หมายเหตุ/annotation จาก admin (manual input)',
  last_tested_at TIMESTAMP NULL COMMENT 'เวลาที่ sandbox รันครั้งล่าสุดสำหรับ version นี้',
  activated_at TIMESTAMP NULL COMMENT 'เวลาที่ version นี้ถูก activate เป็น active',
  created_by INT NOT NULL COMMENT 'user_id ของผู้สร้าง version นี้',
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  context_config LONGTEXT NULL COMMENT 'Configuration สำหรับ context ที่ backend ต้องส่งให้ AI (filter, pageSize, language, etc.)' CHECK (json_valid(`context_config`)),
  version INT NOT NULL DEFAULT 1,
  UNIQUE KEY uk_type_version (prompt_type, version_number),
  KEY idx_prompt_type_active (prompt_type, is_active),
  KEY created_by (created_by),
  CONSTRAINT ai_prompts_ibfk_1 FOREIGN KEY (created_by) REFERENCES users (user_id)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ตาราง versioned prompt templates สำหรับ OCR extraction (ADR-029)';

-- =====================================================
-- 15. 🤖 AI Execution Profiles (ADR-025, ADR-027)
-- =====================================================
-- ตาราง execution profile parameters สำหรับ np-dms-ai
CREATE TABLE ai_execution_profiles (
  id INT AUTO_INCREMENT PRIMARY KEY COMMENT 'ID ภายใน',
  profile_name VARCHAR(50) NOT NULL UNIQUE COMMENT 'ชื่อ profile',
  canonical_model VARCHAR(20) NOT NULL DEFAULT 'np-dms-ai' COMMENT 'Model identity',
  temperature DECIMAL(4, 3) NOT NULL COMMENT 'LLM temperature',
  top_p DECIMAL(4, 3) NOT NULL COMMENT 'LLM top_p',
  max_tokens INT NULL COMMENT 'Maximum tokens',
  num_ctx INT NULL COMMENT 'Context window size',
  repeat_penalty DECIMAL(5, 3) NOT NULL COMMENT 'Repeat penalty',
  keep_alive_seconds INT NOT NULL COMMENT 'Model keep_alive in seconds',
  is_active TINYINT(1) NOT NULL DEFAULT 1 COMMENT '1 = active; 0 = disabled',
  updated_by INT NULL COMMENT 'user_id',
  updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  KEY idx_profile_active (profile_name, is_active),
  KEY updated_by (updated_by),
  CONSTRAINT ai_execution_profiles_ibfk_1 FOREIGN KEY (updated_by) REFERENCES users (user_id)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ตาราง execution profile parameters สำหรับ np-dms-ai';

-- ตาราง sandbox profile parameters
CREATE TABLE ai_sandbox_profiles (
  id INT AUTO_INCREMENT PRIMARY KEY COMMENT 'ID ภายใน',
  profile_name VARCHAR(50) NOT NULL UNIQUE COMMENT 'ชื่อ profile',
  canonical_model VARCHAR(20) NOT NULL DEFAULT 'np-dms-ai' COMMENT 'Model identity',
  temperature DECIMAL(4, 3) NOT NULL COMMENT 'LLM temperature',
  top_p DECIMAL(4, 3) NOT NULL COMMENT 'LLM top_p',
  max_tokens INT NULL COMMENT 'Maximum tokens',
  num_ctx INT NOT NULL COMMENT 'Context window size',
  repeat_penalty DECIMAL(5, 3) NOT NULL COMMENT 'Repeat penalty',
  keep_alive_seconds INT NOT NULL COMMENT 'Model keep_alive in seconds',
  updated_by INT NULL COMMENT 'user_id',
  updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  KEY idx_ai_sandbox_profile_model (canonical_model),
  KEY updated_by (updated_by),
  CONSTRAINT ai_sandbox_profiles_ibfk_1 FOREIGN KEY (updated_by) REFERENCES users (user_id)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ตาราง sandbox profile parameters';

-- =====================================================
-- 16. 🤖 Migration Errors (ADR-028)
-- =====================================================
-- ตาราง Error Log สำหรับ Migration (ลบได้หลัง Migration เสร็จ)
CREATE TABLE migration_errors (
  id INT AUTO_INCREMENT PRIMARY KEY,
  batch_id VARCHAR(50) NULL,
  document_number VARCHAR(100) NULL,
  error_type ENUM(
    'FILE_NOT_FOUND',
    'MISSING_FILENAME',
    'FILE_ERROR',
    'AI_PARSE_ERROR',
    'API_ERROR',
    'DB_ERROR',
    'SECURITY',
    'UNKNOWN'
  ) NULL,
  error_message TEXT NULL,
  job_id VARCHAR(100) NULL,
  raw_ai_response TEXT NULL,
  created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
  KEY idx_batch_id (batch_id),
  KEY idx_job_id (job_id),
  KEY idx_error_type (error_type)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'Migration: Error Log (ลบได้หลัง Migration เสร็จ)';

-- =====================================================
-- 17. 🤖 Intent Classification (ADR-024)
-- =====================================================
-- Intent Definitions Table
CREATE TABLE IF NOT EXISTS ai_intent_definitions (
  id INT AUTO_INCREMENT PRIMARY KEY COMMENT 'Internal PK (ห้าม expose ใน API)',
  public_id UUID NOT NULL DEFAULT UUID() COMMENT 'UUID Public Identifier (ADR-019)',
  intent_code VARCHAR(50) NOT NULL COMMENT 'รหัส Intent เช่น RAG_QUERY, GET_RFA',
  description_th VARCHAR(255) NOT NULL COMMENT 'คำอธิบายภาษาไทย',
  description_en VARCHAR(255) NOT NULL COMMENT 'คำอธิบายภาษาอังกฤษ',
  category ENUM('read', 'suggest', 'utility') NOT NULL COMMENT 'ประเภท Intent',
  is_active BOOLEAN NOT NULL DEFAULT TRUE COMMENT 'สถานะการใช้งาน',
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่สร้าง',
  updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'วันที่แก้ไขล่าสุด',
  UNIQUE KEY uk_intent_public_id (public_id),
  UNIQUE KEY uk_intent_code (intent_code),
  INDEX idx_intent_active (is_active, category)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ตาราง Intent Definitions สำหรับ Hybrid Intent Classifier (ADR-024)';

-- Intent Patterns Table
CREATE TABLE IF NOT EXISTS ai_intent_patterns (
  id INT AUTO_INCREMENT PRIMARY KEY COMMENT 'Internal PK (ห้าม expose ใน API)',
  public_id UUID NOT NULL DEFAULT UUID() COMMENT 'UUID Public Identifier (ADR-019)',
  intent_code VARCHAR(50) NOT NULL COMMENT 'รหัส Intent (FK to ai_intent_definitions)',
  language ENUM('th', 'en', 'any') NOT NULL DEFAULT 'any' COMMENT 'ภาษาของ pattern',
  pattern_type ENUM('keyword', 'regex') NOT NULL DEFAULT 'keyword' COMMENT 'ประเภท pattern',
  pattern_value VARCHAR(255) NOT NULL COMMENT 'ค่า pattern (keyword หรือ regex)',
  priority INT NOT NULL DEFAULT 100 COMMENT 'ลำดับความสำคัญ (ยิ่งน้อยยิ่งสำคัญ)',
  is_active BOOLEAN NOT NULL DEFAULT TRUE COMMENT 'สถานะการใช้งาน',
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่สร้าง',
  updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'วันที่แก้ไขล่าสุด',
  UNIQUE KEY uk_pattern_public_id (public_id),
  INDEX idx_pattern_intent_code (intent_code),
  INDEX idx_pattern_active_priority (is_active, priority ASC),
  CONSTRAINT fk_intent_pattern_definition FOREIGN KEY (intent_code) REFERENCES ai_intent_definitions(intent_code) ON UPDATE CASCADE ON DELETE RESTRICT
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'ตาราง Intent Patterns สำหรับ Hybrid Intent Classifier (ADR-024)';

-- =============================================================================
-- 20. RFA Approval System (v1.9.0)
-- =============================================================================
-- -----------------------------------------------------------------------------
-- 20.1 review_teams — ทีมตรวจสอบแยกตาม Discipline
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `review_teams` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `uuid` UUID NOT NULL DEFAULT (UUID()),
  `project_id` INT NOT NULL,
  `name` VARCHAR(100) NOT NULL,
  `description` VARCHAR(255) NULL,
  `default_for_rfa_types` TEXT NULL COMMENT 'Comma-separated RFA type codes e.g. SDW,DDW',
  `is_active` TINYINT(1) NOT NULL DEFAULT 1,
  `created_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
  `updated_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
  PRIMARY KEY (`id`),
  UNIQUE KEY `uq_review_teams_uuid` (`uuid`),
  KEY `idx_review_teams_project` (`project_id`, `is_active`),
  CONSTRAINT `fk_review_teams_project` FOREIGN KEY (`project_id`) REFERENCES `projects` (`id`) ON DELETE CASCADE
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

-- -----------------------------------------------------------------------------
-- 20.2 review_team_members — สมาชิกในทีมแยกตาม Discipline
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `review_team_members` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `uuid` UUID NOT NULL DEFAULT (UUID()),
  `team_id` INT NOT NULL,
  `user_id` INT NOT NULL,
  `discipline_id` INT NOT NULL,
  `role` ENUM('REVIEWER', 'LEAD', 'MANAGER') NOT NULL DEFAULT 'REVIEWER',
  `priority_order` INT NOT NULL DEFAULT 0,
  `created_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
  PRIMARY KEY (`id`),
  UNIQUE KEY `uq_review_team_members_uuid` (`uuid`),
  UNIQUE KEY `uq_team_user_discipline` (`team_id`, `user_id`, `discipline_id`),
  KEY `idx_rtm_team` (`team_id`),
  KEY `idx_rtm_user` (`user_id`),
  CONSTRAINT `fk_rtm_team` FOREIGN KEY (`team_id`) REFERENCES `review_teams` (`id`) ON DELETE CASCADE,
  CONSTRAINT `fk_rtm_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`) ON DELETE CASCADE,
  CONSTRAINT `fk_rtm_discipline` FOREIGN KEY (`discipline_id`) REFERENCES `disciplines` (`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

-- -----------------------------------------------------------------------------
-- 20.3 response_codes — รหัสตอบกลับมาตรฐาน (Master Approval Matrix)
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `response_codes` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `uuid` UUID NOT NULL DEFAULT (UUID()),
  `code` VARCHAR(10) NOT NULL COMMENT '1A, 1B, 1C, 1D, 1E, 1F, 1G, 2, 3, 4',
  `sub_status` VARCHAR(10) NULL,
  `category` ENUM(
    'ENGINEERING',
    'MATERIAL',
    'CONTRACT',
    'TESTING',
    'ESG'
  ) NOT NULL,
  `description_th` TEXT NOT NULL,
  `description_en` TEXT NOT NULL,
  `implications` JSON NULL COMMENT '{"affectsSchedule":bool,"affectsCost":bool,"requiresContractReview":bool}',
  `notify_roles` TEXT NULL COMMENT 'Comma-separated roles e.g. CONTRACT_MANAGER,QS_MANAGER',
  `is_active` TINYINT(1) NOT NULL DEFAULT 1,
  `is_system` TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'System default — cannot delete',
  `created_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
  PRIMARY KEY (`id`),
  UNIQUE KEY `uq_response_codes_uuid` (`uuid`),
  UNIQUE KEY `uq_response_code_category` (`code`, `category`),
  KEY `idx_rc_category_active` (`category`, `is_active`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

-- -----------------------------------------------------------------------------
-- 20.4 response_code_rules — กฎการใช้รหัสต่อโครงการ/ประเภทเอกสาร
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `response_code_rules` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `uuid` UUID NOT NULL DEFAULT (UUID()),
  `project_id` INT NULL COMMENT 'NULL = global default',
  `document_type_id` INT NOT NULL,
  `response_code_id` INT NOT NULL,
  `is_enabled` TINYINT(1) NOT NULL DEFAULT 1,
  `requires_comments` TINYINT(1) NOT NULL DEFAULT 0,
  `triggers_notification` TINYINT(1) NOT NULL DEFAULT 0,
  `parent_rule_id` INT NULL COMMENT 'For inheritance tracking',
  `created_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
  `updated_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
  PRIMARY KEY (`id`),
  UNIQUE KEY `uq_response_code_rules_uuid` (`uuid`),
  UNIQUE KEY `uq_rule_per_project_doctype_code` (
    `project_id`,
    `document_type_id`,
    `response_code_id`
  ),
  KEY `idx_response_rules_lookup` (`project_id`, `document_type_id`, `is_enabled`),
  CONSTRAINT `fk_rcr_response_code` FOREIGN KEY (`response_code_id`) REFERENCES `response_codes` (`id`),
  CONSTRAINT `fk_rcr_parent` FOREIGN KEY (`parent_rule_id`) REFERENCES `response_code_rules` (`id`) ON DELETE
  SET NULL
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

-- -----------------------------------------------------------------------------
-- 20.5 review_tasks — งานตรวจสอบสำหรับแต่ละ Discipline (Parallel Review)
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `review_tasks` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `uuid` UUID NOT NULL DEFAULT (UUID()),
  `rfa_revision_id` INT NOT NULL,
  `team_id` INT NOT NULL,
  `discipline_id` INT NOT NULL,
  `assigned_to_user_id` INT NULL COMMENT 'NULL = auto-assign by discipline',
  `status` ENUM(
    'PENDING',
    'IN_PROGRESS',
    'COMPLETED',
    'DELEGATED',
    'EXPIRED',
    'CANCELLED'
  ) NOT NULL DEFAULT 'PENDING',
  `due_date` DATE NULL,
  `response_code_id` INT NULL,
  `comments` TEXT NULL,
  `attachments` JSON NULL COMMENT 'Array of attachment publicIds',
  `delegated_from_user_id` INT NULL COMMENT 'Original assignee when delegated',
  `completed_at` TIMESTAMP NULL,
  `version` INT NOT NULL DEFAULT 1 COMMENT 'Optimistic locking (ADR-002)',
  `created_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
  `updated_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
  PRIMARY KEY (`id`),
  UNIQUE KEY `uq_review_tasks_uuid` (`uuid`),
  UNIQUE KEY `uq_review_task_per_revision_discipline` (`rfa_revision_id`, `team_id`, `discipline_id`),
  KEY `idx_review_tasks_rfa_revision` (`rfa_revision_id`),
  KEY `idx_review_tasks_status` (`status`),
  KEY `idx_review_tasks_assigned` (`assigned_to_user_id`, `status`),
  CONSTRAINT `fk_rt_rfa_revision` FOREIGN KEY (`rfa_revision_id`) REFERENCES `rfa_revisions` (`id`) ON DELETE CASCADE,
  CONSTRAINT `fk_rt_team` FOREIGN KEY (`team_id`) REFERENCES `review_teams` (`id`),
  CONSTRAINT `fk_rt_discipline` FOREIGN KEY (`discipline_id`) REFERENCES `disciplines` (`id`),
  CONSTRAINT `fk_rt_user` FOREIGN KEY (`assigned_to_user_id`) REFERENCES `users` (`user_id`) ON DELETE
  SET NULL,
    CONSTRAINT `fk_rt_response_code` FOREIGN KEY (`response_code_id`) REFERENCES `response_codes` (`id`) ON DELETE
  SET NULL
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

-- -----------------------------------------------------------------------------
-- 20.6 delegations — การมอบหมายงาน
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `delegations` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `uuid` UUID NOT NULL DEFAULT (UUID()),
  `delegator_user_id` INT NOT NULL COMMENT 'ผู้มอบหมาย (FK → users.user_id)',
  `delegate_user_id` INT NOT NULL COMMENT 'ผู้รับมอบหมาย (FK → users.user_id)',
  `start_date` DATE NOT NULL,
  `end_date` DATE NULL COMMENT 'BullMQ job flips is_active=0 when end_date < NOW() (ADR-008)',
  `scope` ENUM(
    'ALL',
    'RFA_ONLY',
    'CORRESPONDENCE_ONLY',
    'SPECIFIC_TYPES'
  ) NOT NULL DEFAULT 'ALL',
  `document_types` TEXT NULL COMMENT 'Comma-separated doc type codes when scope=SPECIFIC_TYPES',
  `is_active` TINYINT(1) NOT NULL DEFAULT 1 COMMENT 'Managed by BullMQ scheduler — do not flip manually',
  `reason` TEXT NULL,
  `created_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
  `updated_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
  PRIMARY KEY (`id`),
  UNIQUE KEY `uq_delegations_uuid` (`uuid`),
  KEY `idx_delegations_active` (
    `delegator_user_id`,
    `is_active`,
    `start_date`,
    `end_date`
  ),
  KEY `idx_delegations_delegate` (`delegate_user_id`, `is_active`),
  CONSTRAINT `fk_del_delegator` FOREIGN KEY (`delegator_user_id`) REFERENCES `users` (`user_id`),
  CONSTRAINT `fk_del_delegate` FOREIGN KEY (`delegate_user_id`) REFERENCES `users` (`user_id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

-- -----------------------------------------------------------------------------
-- 20.7 reminder_rules — กฎการแจ้งเตือน
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `reminder_rules` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `uuid` UUID NOT NULL DEFAULT (UUID()),
  `name` VARCHAR(100) NOT NULL,
  `project_id` INT NULL COMMENT 'NULL = global',
  `document_type_id` INT NULL COMMENT 'NULL = all types',
  `trigger_days_before_due` INT NOT NULL DEFAULT 2,
  `escalation_days_after_due` INT NOT NULL DEFAULT 1,
  `reminder_type` ENUM(
    'DUE_SOON',
    'ON_DUE',
    'OVERDUE',
    'ESCALATION_L1',
    'ESCALATION_L2'
  ) NOT NULL,
  `recipients` TEXT NOT NULL COMMENT 'Comma-separated: ASSIGNEE,MANAGER,PROJECT_MANAGER',
  `message_template_th` TEXT NOT NULL,
  `message_template_en` TEXT NOT NULL,
  `is_active` TINYINT(1) NOT NULL DEFAULT 1,
  `created_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
  `updated_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
  PRIMARY KEY (`id`),
  UNIQUE KEY `uq_reminder_rules_uuid` (`uuid`),
  KEY `idx_reminder_rules_active` (`is_active`, `project_id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

-- -----------------------------------------------------------------------------
-- 20.8 distribution_matrices — ตารางกระจายเอกสาร
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `distribution_matrices` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `uuid` UUID NOT NULL DEFAULT (UUID()),
  `name` VARCHAR(100) NOT NULL,
  `project_id` INT NULL COMMENT 'NULL = global',
  `document_type_id` INT NOT NULL,
  `response_code_id` INT NULL COMMENT 'NULL = applies to all codes',
  `conditions` JSON NULL COMMENT '{"codes":["1A","1B"],"excludeCodes":["3","4"]}',
  `is_active` TINYINT(1) NOT NULL DEFAULT 1,
  `created_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
  PRIMARY KEY (`id`),
  UNIQUE KEY `uq_distribution_matrices_uuid` (`uuid`),
  KEY `idx_distribution_lookup` (
    `document_type_id`,
    `response_code_id`,
    `is_active`
  ),
  CONSTRAINT `fk_dm_response_code` FOREIGN KEY (`response_code_id`) REFERENCES `response_codes` (`id`) ON DELETE
  SET NULL
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

-- -----------------------------------------------------------------------------
-- 20.9 distribution_recipients — ผู้รับเอกสารใน Distribution Matrix
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `distribution_recipients` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `uuid` UUID NOT NULL DEFAULT (UUID()) COMMENT 'UUID Public Identifier (ADR-019)',
  `matrix_id` INT NOT NULL,
  `recipient_type` ENUM('USER', 'ORGANIZATION', 'TEAM', 'ROLE') NOT NULL,
  `recipient_public_id` UUID NOT NULL COMMENT 'publicId of target: USER=users.uuid | ORGANIZATION=organizations.uuid | TEAM=review_teams.uuid | ROLE=roles.uuid',
  `delivery_method` ENUM('EMAIL', 'IN_APP', 'BOTH') NOT NULL DEFAULT 'BOTH',
  `sequence` INT NULL COMMENT 'For ordered delivery',
  `created_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
  PRIMARY KEY (`id`),
  UNIQUE KEY `uq_distribution_recipients_uuid` (`uuid`),
  KEY `idx_dr_matrix` (`matrix_id`),
  KEY `idx_dr_type_recipient` (`recipient_type`, `recipient_public_id`),
  CONSTRAINT `fk_dr_matrix` FOREIGN KEY (`matrix_id`) REFERENCES `distribution_matrices` (`id`) ON DELETE CASCADE
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'Polymorphic recipients — no FK on recipient_public_id (by design). ROLE type uses roles.uuid (ADR-019)';

-- =============================================================================
-- END OF SCHEMA v1.9.0
-- =============================================================================
