ERP-node/backend-node/scripts/migrate-input-type-to-web-t...

169 lines
4.9 KiB
TypeScript

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<string, string> = {
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();