import { query } from "../src/database/db"; import { logger } from "../src/utils/logger"; /** * input_type을 web_type으로 마이그레이션하는 스크립트 * * 목적: * - column_labels 테이블의 input_type 값을 읽어서 * - 해당하는 기본 web_type 값으로 변환 * - web_type이 null인 경우에만 업데이트 */ // input_type → 기본 web_type 매핑 const INPUT_TYPE_TO_WEB_TYPE: Record = { text: "text", // 일반 텍스트 number: "number", // 정수 date: "date", // 날짜 code: "code", // 코드 선택박스 entity: "entity", // 엔티티 참조 select: "select", // 선택박스 checkbox: "checkbox", // 체크박스 radio: "radio", // 라디오버튼 direct: "text", // direct는 text로 매핑 }; async function migrateInputTypeToWebType() { try { logger.info("=".repeat(60)); logger.info("input_type → web_type 마이그레이션 시작"); logger.info("=".repeat(60)); // 1. 현재 상태 확인 const stats = await query<{ total: string; has_input_type: string; has_web_type: string; needs_migration: string; }>( `SELECT COUNT(*) as total, COUNT(input_type) FILTER (WHERE input_type IS NOT NULL) as has_input_type, COUNT(web_type) FILTER (WHERE web_type IS NOT NULL) as has_web_type, COUNT(*) FILTER (WHERE input_type IS NOT NULL AND web_type IS NULL) as needs_migration FROM column_labels` ); const stat = stats[0]; logger.info("\n📊 현재 상태:"); logger.info(` - 전체 컬럼: ${stat.total}개`); logger.info(` - input_type 있음: ${stat.has_input_type}개`); logger.info(` - web_type 있음: ${stat.has_web_type}개`); logger.info(` - 마이그레이션 필요: ${stat.needs_migration}개`); if (parseInt(stat.needs_migration) === 0) { logger.info("\n✅ 마이그레이션이 필요한 데이터가 없습니다."); return; } // 2. input_type별 분포 확인 const distribution = await query<{ input_type: string; count: string; }>( `SELECT input_type, COUNT(*) as count FROM column_labels WHERE input_type IS NOT NULL AND web_type IS NULL GROUP BY input_type ORDER BY input_type` ); logger.info("\n📋 input_type별 분포:"); distribution.forEach((item) => { const webType = INPUT_TYPE_TO_WEB_TYPE[item.input_type] || item.input_type; logger.info(` - ${item.input_type} → ${webType}: ${item.count}개`); }); // 3. 마이그레이션 실행 logger.info("\n🔄 마이그레이션 실행 중..."); let totalUpdated = 0; for (const [inputType, webType] of Object.entries(INPUT_TYPE_TO_WEB_TYPE)) { const result = await query( `UPDATE column_labels SET web_type = $1, updated_date = NOW() WHERE input_type = $2 AND web_type IS NULL RETURNING id, table_name, column_name`, [webType, inputType] ); if (result.length > 0) { logger.info( ` ✓ ${inputType} → ${webType}: ${result.length}개 업데이트` ); totalUpdated += result.length; // 처음 5개만 출력 result.slice(0, 5).forEach((row: any) => { logger.info(` - ${row.table_name}.${row.column_name}`); }); if (result.length > 5) { logger.info(` ... 외 ${result.length - 5}개`); } } } // 4. 결과 확인 const afterStats = await query<{ total: string; has_web_type: string; }>( `SELECT COUNT(*) as total, COUNT(web_type) FILTER (WHERE web_type IS NOT NULL) as has_web_type FROM column_labels` ); const afterStat = afterStats[0]; logger.info("\n" + "=".repeat(60)); logger.info("✅ 마이그레이션 완료!"); logger.info("=".repeat(60)); logger.info(`📊 최종 통계:`); logger.info(` - 전체 컬럼: ${afterStat.total}개`); logger.info(` - web_type 설정됨: ${afterStat.has_web_type}개`); logger.info(` - 업데이트된 컬럼: ${totalUpdated}개`); logger.info("=".repeat(60)); // 5. 샘플 데이터 출력 logger.info("\n📝 샘플 데이터 (check_report_mng 테이블):"); const samples = await query<{ column_name: string; input_type: string; web_type: string; detail_settings: string; }>( `SELECT column_name, input_type, web_type, detail_settings FROM column_labels WHERE table_name = 'check_report_mng' ORDER BY column_name LIMIT 10` ); samples.forEach((sample) => { logger.info( ` ${sample.column_name}: ${sample.input_type} → ${sample.web_type}` ); }); process.exit(0); } catch (error) { logger.error("❌ 마이그레이션 실패:", error); process.exit(1); } } // 스크립트 실행 migrateInputTypeToWebType();