cleanup-groupchat-dead-fields.ts 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. /**
  2. * 删除 GroupChat 表中前端不再读取的死字段
  3. *
  4. * - lastActivityAt: 前端完全不读,后端已停止写入
  5. * - avatarUrl: 前端完全不读,后端已停止写入(企微头像 URL 无用)
  6. * - ownerName: 前端从 ResponsibilityAssignment 读取负责人,不再读此字段
  7. *
  8. * 保留字段说明:
  9. * - status: 仅群解散 webhook 写入 'dismissed',前端用于判定健康分(不删)
  10. * - messageCountToday / messageCountTotal / memberCount: 前端暂时仍读取,后续改为纯计算后再删
  11. *
  12. * 用法: cd backend && npx tsx scripts/cleanup-groupchat-dead-fields.ts
  13. */
  14. import 'dotenv/config';
  15. import Parse from '../src/db/parse-client.js';
  16. const DEAD_FIELDS = ['lastActivityAt', 'avatarUrl', 'ownerName', 'memberCount', 'messageCountToday', 'messageCountTotal'];
  17. async function main(): Promise<void> {
  18. console.log('=== 清理 GroupChat 死字段 ===\n');
  19. const schemas = await Parse.Schema.all({ useMasterKey: true });
  20. const groupChat = schemas.find((s: any) => s.className === 'GroupChat');
  21. if (!groupChat) {
  22. console.error('❌ GroupChat 表不存在');
  23. process.exit(1);
  24. }
  25. const existingFields = Object.keys(groupChat.fields).filter((k: string) => !k.startsWith('_'));
  26. console.log(`当前 GroupChat 字段: ${existingFields.join(', ')}\n`);
  27. const deletable = DEAD_FIELDS.filter(f => existingFields.includes(f));
  28. if (deletable.length === 0) {
  29. console.log('目标字段均已不存在,无需操作');
  30. return;
  31. }
  32. console.log(`准备删除: ${deletable.join(', ')}\n`);
  33. const schema = new Parse.Schema('GroupChat');
  34. for (const field of deletable) {
  35. schema.deleteField(field);
  36. console.log(` ✅ 已标记删除: ${field}`);
  37. }
  38. await schema.update({ useMasterKey: true });
  39. // 验证
  40. console.log('\n--- 验证 ---');
  41. const afterSchemas = await Parse.Schema.all({ useMasterKey: true });
  42. const after = afterSchemas.find((s: any) => s.className === 'GroupChat');
  43. if (after) {
  44. const remaining = Object.keys(after.fields).filter((k: string) => !k.startsWith('_')).sort();
  45. const stillThere = deletable.filter(f => remaining.includes(f));
  46. if (stillThere.length > 0) {
  47. console.log(`❌ 残留字段: ${stillThere.join(', ')}`);
  48. } else {
  49. console.log(`✅ 全部清除成功`);
  50. }
  51. console.log(`现有字段 (${remaining.length}): ${remaining.join(', ')}`);
  52. }
  53. console.log('\n✅ 清理完成!');
  54. }
  55. main().catch((err) => {
  56. console.error('❌ 失败:', err);
  57. process.exit(1);
  58. });