-- 016_add_management_fields.sql -- 관리함에서 사용할 추가 필드들과 완료 사진 업로드 기능 추가 BEGIN; DO $$ DECLARE migration_name VARCHAR(255) := '016_add_management_fields.sql'; migration_notes TEXT := '관리함 필드 추가: 원인/해결방안, 담당부서/담당자, 조치예상일, 완료확인일, 원인부서, 의견, 완료사진, 프로젝트별 No 등'; current_status VARCHAR(50); BEGIN -- migration_log 테이블이 없으면 생성 (멱등성) CREATE TABLE IF NOT EXISTS migration_log ( id SERIAL PRIMARY KEY, migration_file VARCHAR(255) NOT NULL UNIQUE, executed_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), status VARCHAR(50), notes TEXT, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); SELECT status INTO current_status FROM migration_log WHERE migration_file = migration_name; IF current_status IS NULL THEN RAISE NOTICE '--- 마이그레이션 % 시작 ---', migration_name; -- issues 테이블에 관리함 관련 컬럼들 추가 -- 완료 사진 경로 IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'issues' AND column_name = 'completion_photo_path') THEN ALTER TABLE issues ADD COLUMN completion_photo_path VARCHAR(255); RAISE NOTICE '✅ issues.completion_photo_path 컬럼이 추가되었습니다.'; ELSE RAISE NOTICE 'ℹ️ issues.completion_photo_path 컬럼이 이미 존재합니다.'; END IF; -- 해결방안 (관리함에서 입력) IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'issues' AND column_name = 'solution') THEN ALTER TABLE issues ADD COLUMN solution TEXT; RAISE NOTICE '✅ issues.solution 컬럼이 추가되었습니다.'; ELSE RAISE NOTICE 'ℹ️ issues.solution 컬럼이 이미 존재합니다.'; END IF; -- 담당부서 (관리함에서 선택) IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'issues' AND column_name = 'responsible_department') THEN ALTER TABLE issues ADD COLUMN responsible_department department_type; RAISE NOTICE '✅ issues.responsible_department 컬럼이 추가되었습니다.'; ELSE RAISE NOTICE 'ℹ️ issues.responsible_department 컬럼이 이미 존재합니다.'; END IF; -- 담당자 (관리함에서 입력) IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'issues' AND column_name = 'responsible_person') THEN ALTER TABLE issues ADD COLUMN responsible_person VARCHAR(100); RAISE NOTICE '✅ issues.responsible_person 컬럼이 추가되었습니다.'; ELSE RAISE NOTICE 'ℹ️ issues.responsible_person 컬럼이 이미 존재합니다.'; END IF; -- 조치 예상일 (관리함에서 입력) IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'issues' AND column_name = 'expected_completion_date') THEN ALTER TABLE issues ADD COLUMN expected_completion_date DATE; RAISE NOTICE '✅ issues.expected_completion_date 컬럼이 추가되었습니다.'; ELSE RAISE NOTICE 'ℹ️ issues.expected_completion_date 컬럼이 이미 존재합니다.'; END IF; -- 완료 확인일 (완료 상태로 변경 시 자동 입력) IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'issues' AND column_name = 'actual_completion_date') THEN ALTER TABLE issues ADD COLUMN actual_completion_date DATE; RAISE NOTICE '✅ issues.actual_completion_date 컬럼이 추가되었습니다.'; ELSE RAISE NOTICE 'ℹ️ issues.actual_completion_date 컬럼이 이미 존재합니다.'; END IF; -- 원인부서 (관리함에서 입력) IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'issues' AND column_name = 'cause_department') THEN ALTER TABLE issues ADD COLUMN cause_department department_type; RAISE NOTICE '✅ issues.cause_department 컬럼이 추가되었습니다.'; ELSE RAISE NOTICE 'ℹ️ issues.cause_department 컬럼이 이미 존재합니다.'; END IF; -- ISSUE에 대한 의견 (관리함에서 입력) IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'issues' AND column_name = 'management_comment') THEN ALTER TABLE issues ADD COLUMN management_comment TEXT; RAISE NOTICE '✅ issues.management_comment 컬럼이 추가되었습니다.'; ELSE RAISE NOTICE 'ℹ️ issues.management_comment 컬럼이 이미 존재합니다.'; END IF; -- 프로젝트별 순번 (No) - 프로젝트 내에서 1, 2, 3... 순으로 증가 IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'issues' AND column_name = 'project_sequence_no') THEN ALTER TABLE issues ADD COLUMN project_sequence_no INTEGER; RAISE NOTICE '✅ issues.project_sequence_no 컬럼이 추가되었습니다.'; ELSE RAISE NOTICE 'ℹ️ issues.project_sequence_no 컬럼이 이미 존재합니다.'; END IF; -- 최종 내용 (수정된 내용이 있으면 수정본, 없으면 원본) IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'issues' AND column_name = 'final_description') THEN ALTER TABLE issues ADD COLUMN final_description TEXT; RAISE NOTICE '✅ issues.final_description 컬럼이 추가되었습니다.'; ELSE RAISE NOTICE 'ℹ️ issues.final_description 컬럼이 이미 존재합니다.'; END IF; -- 최종 카테고리 (수정된 카테고리가 있으면 수정본, 없으면 원본) IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'issues' AND column_name = 'final_category') THEN ALTER TABLE issues ADD COLUMN final_category issuecategory; RAISE NOTICE '✅ issues.final_category 컬럼이 추가되었습니다.'; ELSE RAISE NOTICE 'ℹ️ issues.final_category 컬럼이 이미 존재합니다.'; END IF; -- 인덱스 추가 IF NOT EXISTS (SELECT 1 FROM pg_indexes WHERE tablename = 'issues' AND indexname = 'idx_issues_project_sequence') THEN CREATE INDEX idx_issues_project_sequence ON issues (project_id, project_sequence_no); RAISE NOTICE '✅ idx_issues_project_sequence 인덱스가 생성되었습니다.'; ELSE RAISE NOTICE 'ℹ️ idx_issues_project_sequence 인덱스가 이미 존재합니다.'; END IF; IF NOT EXISTS (SELECT 1 FROM pg_indexes WHERE tablename = 'issues' AND indexname = 'idx_issues_responsible_department') THEN CREATE INDEX idx_issues_responsible_department ON issues (responsible_department) WHERE responsible_department IS NOT NULL; RAISE NOTICE '✅ idx_issues_responsible_department 인덱스가 생성되었습니다.'; ELSE RAISE NOTICE 'ℹ️ idx_issues_responsible_department 인덱스가 이미 존재합니다.'; END IF; IF NOT EXISTS (SELECT 1 FROM pg_indexes WHERE tablename = 'issues' AND indexname = 'idx_issues_expected_completion') THEN CREATE INDEX idx_issues_expected_completion ON issues (expected_completion_date) WHERE expected_completion_date IS NOT NULL; RAISE NOTICE '✅ idx_issues_expected_completion 인덱스가 생성되었습니다.'; ELSE RAISE NOTICE 'ℹ️ idx_issues_expected_completion 인덱스가 이미 존재합니다.'; END IF; -- 프로젝트별 순번 자동 생성 함수 CREATE OR REPLACE FUNCTION generate_project_sequence_no(p_project_id BIGINT) RETURNS INTEGER AS $func$ DECLARE next_no INTEGER; BEGIN -- 해당 프로젝트의 최대 순번 + 1 SELECT COALESCE(MAX(project_sequence_no), 0) + 1 INTO next_no FROM issues WHERE project_id = p_project_id; RETURN next_no; END; $func$ LANGUAGE plpgsql; RAISE NOTICE '✅ generate_project_sequence_no 함수가 생성되었습니다.'; -- 기존 이슈들에 대해 프로젝트별 순번 설정 DO $update_sequence$ DECLARE issue_record RECORD; seq_no INTEGER; BEGIN FOR issue_record IN SELECT id, project_id FROM issues WHERE project_sequence_no IS NULL ORDER BY project_id, report_date LOOP SELECT generate_project_sequence_no(issue_record.project_id) INTO seq_no; UPDATE issues SET project_sequence_no = seq_no WHERE id = issue_record.id; END LOOP; END $update_sequence$; RAISE NOTICE '✅ 기존 이슈들의 프로젝트별 순번이 설정되었습니다.'; -- 기존 이슈들의 final_description과 final_category 초기화 UPDATE issues SET final_description = description, final_category = category WHERE final_description IS NULL OR final_category IS NULL; RAISE NOTICE '✅ 기존 이슈들의 final_description과 final_category가 초기화되었습니다.'; -- 마이그레이션 검증 DECLARE col_count INTEGER; idx_count INTEGER; func_count INTEGER; BEGIN SELECT COUNT(*) INTO col_count FROM information_schema.columns WHERE table_name = 'issues' AND column_name IN ( 'completion_photo_path', 'solution', 'responsible_department', 'responsible_person', 'expected_completion_date', 'actual_completion_date', 'cause_department', 'management_comment', 'project_sequence_no', 'final_description', 'final_category' ); SELECT COUNT(*) INTO idx_count FROM pg_indexes WHERE tablename = 'issues' AND indexname IN ( 'idx_issues_project_sequence', 'idx_issues_responsible_department', 'idx_issues_expected_completion' ); SELECT COUNT(*) INTO func_count FROM pg_proc WHERE proname = 'generate_project_sequence_no'; RAISE NOTICE '=== 마이그레이션 검증 결과 ==='; RAISE NOTICE '추가된 컬럼: %/11개', col_count; RAISE NOTICE '생성된 인덱스: %/3개', idx_count; RAISE NOTICE '생성된 함수: %/1개', func_count; IF col_count = 11 AND idx_count = 3 AND func_count = 1 THEN RAISE NOTICE '✅ 마이그레이션이 성공적으로 완료되었습니다!'; INSERT INTO migration_log (migration_file, status, notes) VALUES (migration_name, 'SUCCESS', migration_notes); ELSE RAISE EXCEPTION '❌ 마이그레이션 검증 실패!'; END IF; END; ELSIF current_status = 'SUCCESS' THEN RAISE NOTICE 'ℹ️ 마이그레이션 %는 이미 성공적으로 실행되었습니다. 스킵합니다.', migration_name; ELSE RAISE NOTICE '⚠️ 마이그레이션 %는 이전에 실패했습니다. 수동 확인이 필요합니다.', migration_name; END IF; END $$; COMMIT;