여러 줄 주석이 설명보다 경위(예전·실측·지적)를 적고 있어 읽는 사람이 결론을 찾기 어려웠다. - ts·tsx·js·mjs·css·py 478개: 여러 줄 주석은 첫 문장 한 줄로, 과거형·날짜 문장은 삭제 - 주석 위치는 TypeScript 파서·파이썬 tokenize/ast 로 찾는다 — 문자열 안의 # · /* 는 건드리지 않는다 - eslint·ts·noqa·type: ignore 같은 지시 주석은 그대로 둔다 파이썬 275개 정리 전후 AST 동일, TS 298개 주석 뺀 토큰 동일(빈 JSX 주석 10곳만 차이). site·frontend·admin tsc, site vitest 105 passed Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
30 lines
1.2 KiB
TypeScript
30 lines
1.2 KiB
TypeScript
/** 고정 데이터셋 정책 위반분 정리. */
|
|
import { createSql } from '../src/db/db';
|
|
|
|
async function main() {
|
|
const apply = process.argv.includes('--apply');
|
|
const sql = createSql();
|
|
|
|
const rows = await sql<Array<{ source: string; n: number; sample: string[] }>>`
|
|
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<Array<{ n: number }>>`
|
|
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); });
|