-- migration-purchase-safety.sql -- 협력업체/일용직 관리 및 안전교육 테이블 마이그레이션 -- MariaDB용, 재실행 안전 (IF NOT EXISTS / ADD COLUMN IF NOT EXISTS) -- 생성일: 2026-03-12 -- ============================================================ -- 1. sso_users 테이블에 협력업체 관련 컬럼 추가 -- ============================================================ ALTER TABLE sso_users ADD COLUMN IF NOT EXISTS partner_company_id INT DEFAULT NULL COMMENT '협력업체 소속 시 partner_companies.id, 내부직원은 NULL'; ALTER TABLE sso_users ADD COLUMN IF NOT EXISTS account_expires_at DATETIME DEFAULT NULL COMMENT '협력업체 계정 만료일, 내부직원은 NULL'; -- 외래키는 IF NOT EXISTS 구문이 없으므로 프로시저로 안전하게 추가 DELIMITER // DROP PROCEDURE IF EXISTS __add_fk_sso_users_partner_company// CREATE PROCEDURE __add_fk_sso_users_partner_company() BEGIN IF NOT EXISTS ( SELECT 1 FROM information_schema.TABLE_CONSTRAINTS WHERE CONSTRAINT_SCHEMA = DATABASE() AND TABLE_NAME = 'sso_users' AND CONSTRAINT_NAME = 'fk_sso_users_partner_company' ) THEN ALTER TABLE sso_users ADD CONSTRAINT fk_sso_users_partner_company FOREIGN KEY (partner_company_id) REFERENCES partner_companies(id) ON DELETE SET NULL; END IF; END// DELIMITER ; CALL __add_fk_sso_users_partner_company(); DROP PROCEDURE IF EXISTS __add_fk_sso_users_partner_company; -- ============================================================ -- 2. day_labor_requests (일용직 작업 요청) -- ============================================================ CREATE TABLE IF NOT EXISTS day_labor_requests ( id INT AUTO_INCREMENT PRIMARY KEY, requester_id INT NOT NULL COMMENT 'sso_users.user_id', department_id INT, work_date DATE NOT NULL, worker_count INT NOT NULL DEFAULT 1, work_description TEXT, workplace_name VARCHAR(100), status ENUM('pending','approved','rejected','completed') DEFAULT 'pending', approved_by INT, approved_at DATETIME, safety_reported BOOLEAN DEFAULT FALSE, notes TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_day_labor_work_date (work_date), INDEX idx_day_labor_status (status) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- ============================================================ -- 3. partner_schedules (협력업체 작업 일정) -- ============================================================ CREATE TABLE IF NOT EXISTS partner_schedules ( id INT AUTO_INCREMENT PRIMARY KEY, company_id INT NOT NULL, work_date DATE NOT NULL, work_description TEXT, workplace_name VARCHAR(100), expected_workers INT DEFAULT 1, registered_by INT NOT NULL, status ENUM('scheduled','in_progress','completed','cancelled') DEFAULT 'scheduled', notes TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_partner_sched_work_date (work_date), INDEX idx_partner_sched_company_date (company_id, work_date), CONSTRAINT fk_partner_schedules_company FOREIGN KEY (company_id) REFERENCES partner_companies(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- ============================================================ -- 4. partner_work_checkins (협력업체 출퇴근 체크) -- ============================================================ CREATE TABLE IF NOT EXISTS partner_work_checkins ( id INT AUTO_INCREMENT PRIMARY KEY, schedule_id INT NOT NULL, company_id INT NOT NULL, checked_by INT NOT NULL, check_in_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, check_out_time DATETIME, worker_names TEXT, actual_worker_count INT, notes TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX idx_checkin_schedule_time (schedule_id, check_in_time), CONSTRAINT fk_checkins_schedule FOREIGN KEY (schedule_id) REFERENCES partner_schedules(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- ============================================================ -- 5. partner_work_reports (협력업체 일일 작업 보고) -- ============================================================ CREATE TABLE IF NOT EXISTS partner_work_reports ( id INT AUTO_INCREMENT PRIMARY KEY, schedule_id INT NOT NULL, checkin_id INT NOT NULL, company_id INT NOT NULL, report_date DATE NOT NULL, reporter_id INT NOT NULL, actual_workers INT, work_content TEXT, progress_rate TINYINT CHECK (progress_rate BETWEEN 0 AND 100), issues TEXT, next_plan TEXT, confirmed_by INT, confirmed_at DATETIME, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_daily_report_date (report_date), INDEX idx_daily_report_schedule (schedule_id), UNIQUE INDEX uq_schedule_report_date (schedule_id, report_date), CONSTRAINT fk_daily_reports_schedule FOREIGN KEY (schedule_id) REFERENCES partner_schedules(id), CONSTRAINT fk_daily_reports_checkin FOREIGN KEY (checkin_id) REFERENCES partner_work_checkins(id), CONSTRAINT fk_daily_reports_company FOREIGN KEY (company_id) REFERENCES partner_companies(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- ============================================================ -- 6. safety_education_reports (안전교육 보고) -- ============================================================ CREATE TABLE IF NOT EXISTS safety_education_reports ( id INT AUTO_INCREMENT PRIMARY KEY, target_type ENUM('day_labor','partner_schedule','manual') NOT NULL, target_id INT, education_date DATE NOT NULL, educator VARCHAR(50), attendees JSON, status ENUM('planned','completed','cancelled') DEFAULT 'planned', notes TEXT, registered_by INT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_safety_edu_date (education_date), INDEX idx_safety_edu_target (target_type, target_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;