From 86a6d21a08f0c77334e816a2cd46c4648e48ea5e Mon Sep 17 00:00:00 2001 From: hyungi Date: Sat, 8 Nov 2025 15:40:35 +0900 Subject: [PATCH] =?UTF-8?q?feat:=205=EC=9E=A5=20=EC=82=AC=EC=A7=84=20?= =?UTF-8?q?=EC=A7=80=EC=9B=90=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=EB=B2=A0=EC=9D=B4=EC=8A=A4=20=EC=8A=A4?= =?UTF-8?q?=ED=82=A4=EB=A7=88=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - photo_path3, photo_path4, photo_path5 컬럼 추가 - completion_photo_path2~5 컬럼 추가 - completion_rejected_at, completion_rejected_by_id, completion_rejection_reason 컬럼 추가 - last_exported_at, export_count 컬럼 추가 - 021_add_5_photo_support.sql 마이그레이션 생성 - 백엔드 재시작으로 새로운 스키마 적용 완료 --- .../migrations/021_add_5_photo_support.sql | 177 ++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 backend/migrations/021_add_5_photo_support.sql diff --git a/backend/migrations/021_add_5_photo_support.sql b/backend/migrations/021_add_5_photo_support.sql new file mode 100644 index 0000000..df8f39c --- /dev/null +++ b/backend/migrations/021_add_5_photo_support.sql @@ -0,0 +1,177 @@ +-- 021_add_5_photo_support.sql +-- 5장 사진 지원을 위한 추가 컬럼들 +-- 작성일: 2025-11-08 +-- 목적: photo_path3, photo_path4, photo_path5 및 completion_photo_path2~5 컬럼 추가 + +BEGIN; + +DO $$ +DECLARE + migration_name VARCHAR(255) := '021_add_5_photo_support.sql'; + migration_notes TEXT := '5장 사진 지원: photo_path3~5, completion_photo_path2~5 컬럼 추가'; + 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(), + started_at TIMESTAMP WITH TIME ZONE, + completed_at TIMESTAMP WITH TIME ZONE + ); + + SELECT status INTO current_status FROM migration_log WHERE migration_file = migration_name; + + IF current_status IS NULL THEN + RAISE NOTICE '--- 마이그레이션 % 시작 ---', migration_name; + + -- 기본 사진 경로 3~5 추가 + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'issues' AND column_name = 'photo_path3') THEN + ALTER TABLE issues ADD COLUMN photo_path3 VARCHAR(500); + RAISE NOTICE '✅ issues.photo_path3 컬럼이 추가되었습니다.'; + ELSE + RAISE NOTICE 'ℹ️ issues.photo_path3 컬럼이 이미 존재합니다.'; + END IF; + + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'issues' AND column_name = 'photo_path4') THEN + ALTER TABLE issues ADD COLUMN photo_path4 VARCHAR(500); + RAISE NOTICE '✅ issues.photo_path4 컬럼이 추가되었습니다.'; + ELSE + RAISE NOTICE 'ℹ️ issues.photo_path4 컬럼이 이미 존재합니다.'; + END IF; + + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'issues' AND column_name = 'photo_path5') THEN + ALTER TABLE issues ADD COLUMN photo_path5 VARCHAR(500); + RAISE NOTICE '✅ issues.photo_path5 컬럼이 추가되었습니다.'; + ELSE + RAISE NOTICE 'ℹ️ issues.photo_path5 컬럼이 이미 존재합니다.'; + END IF; + + -- 완료 사진 경로 2~5 추가 + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'issues' AND column_name = 'completion_photo_path2') THEN + ALTER TABLE issues ADD COLUMN completion_photo_path2 VARCHAR(500); + RAISE NOTICE '✅ issues.completion_photo_path2 컬럼이 추가되었습니다.'; + ELSE + RAISE NOTICE 'ℹ️ issues.completion_photo_path2 컬럼이 이미 존재합니다.'; + END IF; + + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'issues' AND column_name = 'completion_photo_path3') THEN + ALTER TABLE issues ADD COLUMN completion_photo_path3 VARCHAR(500); + RAISE NOTICE '✅ issues.completion_photo_path3 컬럼이 추가되었습니다.'; + ELSE + RAISE NOTICE 'ℹ️ issues.completion_photo_path3 컬럼이 이미 존재합니다.'; + END IF; + + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'issues' AND column_name = 'completion_photo_path4') THEN + ALTER TABLE issues ADD COLUMN completion_photo_path4 VARCHAR(500); + RAISE NOTICE '✅ issues.completion_photo_path4 컬럼이 추가되었습니다.'; + ELSE + RAISE NOTICE 'ℹ️ issues.completion_photo_path4 컬럼이 이미 존재합니다.'; + END IF; + + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'issues' AND column_name = 'completion_photo_path5') THEN + ALTER TABLE issues ADD COLUMN completion_photo_path5 VARCHAR(500); + RAISE NOTICE '✅ issues.completion_photo_path5 컬럼이 추가되었습니다.'; + ELSE + RAISE NOTICE 'ℹ️ issues.completion_photo_path5 컬럼이 이미 존재합니다.'; + END IF; + + -- 추가 필드들 (최신 버전에서 필요한 것들) + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'issues' AND column_name = 'completion_rejected_at') THEN + ALTER TABLE issues ADD COLUMN completion_rejected_at TIMESTAMP WITH TIME ZONE; + RAISE NOTICE '✅ issues.completion_rejected_at 컬럼이 추가되었습니다.'; + ELSE + RAISE NOTICE 'ℹ️ issues.completion_rejected_at 컬럼이 이미 존재합니다.'; + END IF; + + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'issues' AND column_name = 'completion_rejected_by_id') THEN + ALTER TABLE issues ADD COLUMN completion_rejected_by_id INTEGER REFERENCES users(id); + RAISE NOTICE '✅ issues.completion_rejected_by_id 컬럼이 추가되었습니다.'; + ELSE + RAISE NOTICE 'ℹ️ issues.completion_rejected_by_id 컬럼이 이미 존재합니다.'; + END IF; + + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'issues' AND column_name = 'completion_rejection_reason') THEN + ALTER TABLE issues ADD COLUMN completion_rejection_reason TEXT; + RAISE NOTICE '✅ issues.completion_rejection_reason 컬럼이 추가되었습니다.'; + ELSE + RAISE NOTICE 'ℹ️ issues.completion_rejection_reason 컬럼이 이미 존재합니다.'; + END IF; + + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'issues' AND column_name = 'last_exported_at') THEN + ALTER TABLE issues ADD COLUMN last_exported_at TIMESTAMP WITH TIME ZONE; + RAISE NOTICE '✅ issues.last_exported_at 컬럼이 추가되었습니다.'; + ELSE + RAISE NOTICE 'ℹ️ issues.last_exported_at 컬럼이 이미 존재합니다.'; + END IF; + + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'issues' AND column_name = 'export_count') THEN + ALTER TABLE issues ADD COLUMN export_count INTEGER DEFAULT 0; + RAISE NOTICE '✅ issues.export_count 컬럼이 추가되었습니다.'; + ELSE + RAISE NOTICE 'ℹ️ issues.export_count 컬럼이 이미 존재합니다.'; + END IF; + + -- 인덱스 추가 (성능 향상) + IF NOT EXISTS (SELECT 1 FROM pg_indexes WHERE tablename = 'issues' AND indexname = 'idx_issues_photo_path3') THEN + CREATE INDEX idx_issues_photo_path3 ON issues (photo_path3) WHERE photo_path3 IS NOT NULL; + RAISE NOTICE '✅ idx_issues_photo_path3 인덱스가 생성되었습니다.'; + ELSE + RAISE NOTICE 'ℹ️ idx_issues_photo_path3 인덱스가 이미 존재합니다.'; + END IF; + + IF NOT EXISTS (SELECT 1 FROM pg_indexes WHERE tablename = 'issues' AND indexname = 'idx_issues_photo_path4') THEN + CREATE INDEX idx_issues_photo_path4 ON issues (photo_path4) WHERE photo_path4 IS NOT NULL; + RAISE NOTICE '✅ idx_issues_photo_path4 인덱스가 생성되었습니다.'; + ELSE + RAISE NOTICE 'ℹ️ idx_issues_photo_path4 인덱스가 이미 존재합니다.'; + END IF; + + IF NOT EXISTS (SELECT 1 FROM pg_indexes WHERE tablename = 'issues' AND indexname = 'idx_issues_photo_path5') THEN + CREATE INDEX idx_issues_photo_path5 ON issues (photo_path5) WHERE photo_path5 IS NOT NULL; + RAISE NOTICE '✅ idx_issues_photo_path5 인덱스가 생성되었습니다.'; + ELSE + RAISE NOTICE 'ℹ️ idx_issues_photo_path5 인덱스가 이미 존재합니다.'; + END IF; + + -- 마이그레이션 검증 + DECLARE + col_count INTEGER; + idx_count INTEGER; + BEGIN + SELECT COUNT(*) INTO col_count FROM information_schema.columns + WHERE table_name = 'issues' AND column_name IN ( + 'photo_path3', 'photo_path4', 'photo_path5', + 'completion_photo_path2', 'completion_photo_path3', 'completion_photo_path4', 'completion_photo_path5', + 'completion_rejected_at', 'completion_rejected_by_id', 'completion_rejection_reason', + 'last_exported_at', 'export_count' + ); + + SELECT COUNT(*) INTO idx_count FROM pg_indexes + WHERE tablename = 'issues' AND indexname IN ( + 'idx_issues_photo_path3', 'idx_issues_photo_path4', 'idx_issues_photo_path5' + ); + + RAISE NOTICE '=== 마이그레이션 검증 결과 ==='; + RAISE NOTICE '추가된 컬럼: %/11개', col_count; + RAISE NOTICE '생성된 인덱스: %/3개', idx_count; + + IF col_count = 11 AND idx_count = 3 THEN + RAISE NOTICE '✅ 마이그레이션이 성공적으로 완료되었습니다!'; + INSERT INTO migration_log (migration_file, status, notes, completed_at) VALUES (migration_name, 'SUCCESS', migration_notes, NOW()); + ELSE + RAISE EXCEPTION '❌ 마이그레이션 검증 실패!'; + END IF; + END; + + ELSIF current_status = 'SUCCESS' THEN + RAISE NOTICE 'ℹ️ 마이그레이션 %는 이미 성공적으로 실행되었습니다. 스킵합니다.', migration_name; + ELSE + RAISE NOTICE '⚠️ 마이그레이션 %는 이전에 실패했습니다. 수동 확인이 필요합니다.', migration_name; + END IF; +END $$; + +COMMIT;