/** * 고정 데이터셋 정책 위반분 정리. * npx tsx scripts/purge-nondataset.ts [--apply] * * 사전(keyword)에는 큐레이션된 데이터셋만 남아야 한다. 과거 generate 테스트가 * 만든 source='llm' 행이 섞여 있으면 다른 업종 키워드가 매칭 후보에 들어온다. */ import { createSql } from '../src/db/db'; async function main() { const apply = process.argv.includes('--apply'); const sql = createSql(); const rows = await sql>` SELECT source, count(*)::int AS n, (array_agg(canonical ORDER BY canonical))[1:6] AS sample FROM keyword GROUP BY source ORDER BY n DESC`; console.log('출처별 현황'); for (const r of rows) console.log(` ${r.source.padEnd(10)} ${String(r.n).padStart(5)} ${r.sample.join(', ')}`); const doomed = await sql>` SELECT count(*)::int AS n FROM keyword WHERE source NOT IN ('dataset', 'manual')`; const n = doomed[0]?.n ?? 0; if (n === 0) { console.log('\n정리 대상 없음'); await sql.end(); return; } if (!apply) { console.log(`\n정리 대상 ${n}건. 실제로 지우려면 --apply 를 붙일 것.`); await sql.end(); return; } const del = await sql`DELETE FROM keyword WHERE source NOT IN ('dataset', 'manual') RETURNING id`; console.log(`\n✅ ${del.length}건 삭제 (merchant_keyword 는 CASCADE)`); await sql.end(); } main().catch((e) => { console.error('❌', e); process.exit(1); });