/** * 删除前后端均不使用的死字段 * * GroupChat: guid, lastActivityAt, hasDocument (avatarUrl 已在 test-delete-field 中删除) * Store: managerId, managerName, status * * 用法: cd backend && npx tsx scripts/cleanup-dead-fields.ts */ import 'dotenv/config'; import Parse from '../src/db/parse-client.js'; interface CleanupTask { className: string; fields: string[]; } const TASKS: CleanupTask[] = [ { className: 'GroupChat', fields: ['guid', 'lastActivityAt', 'hasDocument'], }, { className: 'Store', fields: ['managerId', 'managerName', 'status'], }, ]; async function main(): Promise { console.log('=== 清理死字段 ===\n'); // 先打印当前 Schema const beforeSchemas = await Parse.Schema.all({ useMasterKey: true }); for (const task of TASKS) { const before = beforeSchemas.find((s: any) => s.className === task.className); if (!before) { console.log(`⚠️ ${task.className} 表不存在,跳过`); continue; } const existingFields = Object.keys(before.fields).filter((k: string) => !k.startsWith('_')); const deletable = task.fields.filter(f => existingFields.includes(f)); if (deletable.length === 0) { console.log(`${task.className}: 目标字段均不存在,跳过`); continue; } const schema = new Parse.Schema(task.className); for (const field of deletable) { schema.deleteField(field); } await schema.update({ useMasterKey: true }); console.log(`${task.className}: ✅ 已删除 ${deletable.join(', ')}`); } // 验证 console.log('\n--- 验证 ---'); const afterSchemas = await Parse.Schema.all({ useMasterKey: true }); for (const task of TASKS) { const after = afterSchemas.find((s: any) => s.className === task.className); if (!after) continue; const remaining = Object.keys(after.fields).filter((k: string) => !k.startsWith('_')).sort(); const stillThere = task.fields.filter(f => remaining.includes(f)); console.log(`${task.className}: ${stillThere.length > 0 ? '❌ 残留 ' + stillThere.join(', ') : '✅ 全部清除'} — 现有字段: ${remaining.join(', ')}`); } console.log('\n✅ 清理完成!'); } main().catch((err) => { console.error('❌ 失败:', err); process.exit(1); });