cleanup-utils.ts 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /**
  2. * 测试数据清理工具
  3. *
  4. * 用途:在测试后自动清理创建的测试数据
  5. */
  6. import { and, inArray, isNull, like, or, sql } from "drizzle-orm";
  7. import { db } from "@/drizzle/db";
  8. import { keys as keysTable, users } from "@/drizzle/schema";
  9. /**
  10. * 清理所有测试用户及其关联数据
  11. *
  12. * 匹配规则:
  13. * - 名称包含"测试用户"
  14. * - 名称包含"test"或"Test"
  15. * - 创建时间在最近 1 小时内(可选)
  16. */
  17. export async function cleanupTestUsers(options?: {
  18. onlyRecent?: boolean; // 只清理最近创建的
  19. recentMinutes?: number; // 最近多少分钟(默认 60)
  20. }) {
  21. const recentMinutes = options?.recentMinutes ?? 60;
  22. const cutoffTime = new Date(Date.now() - recentMinutes * 60 * 1000);
  23. try {
  24. // 1. 找到要删除的测试用户 ID
  25. const testUserConditions = [
  26. like(users.name, "测试用户%"),
  27. like(users.name, "%test%"),
  28. like(users.name, "Test%"),
  29. ];
  30. const whereConditions = [or(...testUserConditions), isNull(users.deletedAt)];
  31. if (options?.onlyRecent) {
  32. // 将 Date 转换为 ISO 字符串,避免 postgres 库报错
  33. whereConditions.push(sql`${users.createdAt} > ${cutoffTime.toISOString()}`);
  34. }
  35. const testUsers = await db
  36. .select({ id: users.id, name: users.name })
  37. .from(users)
  38. .where(and(...whereConditions));
  39. if (testUsers.length === 0) {
  40. console.log("✅ 没有找到测试用户");
  41. return { deletedUsers: 0, deletedKeys: 0 };
  42. }
  43. console.log(`🔍 找到 ${testUsers.length} 个测试用户`);
  44. const testUserIds = testUsers.map((u) => u.id);
  45. // 2. 软删除关联的 Keys
  46. const now = new Date();
  47. const deletedKeys = await db
  48. .update(keysTable)
  49. .set({ deletedAt: now, updatedAt: now })
  50. .where(and(inArray(keysTable.userId, testUserIds), isNull(keysTable.deletedAt)))
  51. .returning({ id: keysTable.id });
  52. // 3. 软删除测试用户
  53. await db
  54. .update(users)
  55. .set({ deletedAt: now, updatedAt: now })
  56. .where(and(inArray(users.id, testUserIds), isNull(users.deletedAt)))
  57. .returning({ id: users.id });
  58. console.log(`✅ 清理完成:删除 ${testUsers.length} 个用户和对应的 Keys`);
  59. return {
  60. deletedUsers: testUsers.length,
  61. deletedKeys: deletedKeys.length,
  62. userNames: testUsers.map((u) => u.name),
  63. };
  64. } catch (error) {
  65. console.error("❌ 清理测试用户失败:", error);
  66. throw error;
  67. }
  68. }
  69. /**
  70. * 在测试中使用的清理函数
  71. */
  72. export async function cleanupRecentTestData() {
  73. return cleanupTestUsers({ onlyRecent: true, recentMinutes: 10 });
  74. }