/** * 删除 TEST_MODE / fixture 注入的邮件(ops@example.com、@p3.fixtures.local)。 * 不碰 IMAP 真实邮件、不碰 sample-mail* 金样。 * 用法: pnpm exec tsx scripts/cleanup-test-fixture-mails.ts */ import fs from "fs/promises"; import path from "path"; import { prisma } from "@/services/db"; async function main() { const rows = await prisma.mailMessage.findMany({ where: { OR: [ { messageId: { contains: "@p3.fixtures.local" } }, { fromAddr: "ops@example.com" }, ], }, select: { id: true, messageId: true, subject: true, status: true }, }); const samples = await prisma.mailMessage.findMany({ where: { messageId: { contains: "@local.test" } }, select: { id: true, messageId: true, subject: true, status: true, fromAddr: true }, }); console.log(`fixture mails to delete: ${rows.length}`); for (const r of rows) { console.log(` #${r.id} ${r.status} ${r.messageId} ${r.subject.slice(0, 60)}`); } console.log(`sample-mail* still in db: ${samples.length}`); for (const s of samples) { console.log(` #${s.id} ${s.status} ${s.fromAddr} ${s.subject.slice(0, 60)}`); } if (!rows.length) { console.log("nothing to delete"); return; } const ids = rows.map((r) => r.id); await prisma.importCompensation.deleteMany({ where: { import: { mailId: { in: ids } } }, }); await prisma.containerActiveLock.deleteMany({ where: { mailId: { in: ids } } }); await prisma.containerImport.deleteMany({ where: { mailId: { in: ids } } }); await prisma.parseResult.deleteMany({ where: { mailId: { in: ids } } }); await prisma.mailAttachment.deleteMany({ where: { mailId: { in: ids } } }); await prisma.imapPullLog.deleteMany({ where: { mailId: { in: ids } } }); await prisma.mailMessage.deleteMany({ where: { id: { in: ids } } }); for (const id of ids) { const dir = path.join(process.cwd(), "data", "mails", String(id)); await fs.rm(dir, { recursive: true, force: true }).catch(() => undefined); } console.log(`deleted ${ids.length} fixture mails`); } main() .catch((e) => { console.error(e); process.exit(1); }) .finally(() => prisma.$disconnect());