/** * After purge+reimport: print rule-check summary for each mail. */ import { prisma } from "@/services/db"; import { extractMailInstructions } from "@/services/parse/split-instructions"; import { isInstructionNoiseRow } from "@/services/parse/packing-list"; async function main() { const mails = await prisma.mailMessage.findMany({ orderBy: { id: "asc" }, include: { parseResult: true, attachments: true }, }); console.log(`\n=== reimport check: ${mails.length} mails ===\n`); for (const m of mails) { const ships = (m.parseResult?.shipments as any[]) || []; const invalid = ships.filter((s) => s.row_status === "INVALID"); const noteLike = ships.filter( (s) => String(s.F_FBACode || "").includes("注意") || String(s.F_Address || "").includes("注意") || String(s.F_Transporter || "").includes("注意"), ); const units = extractMailInstructions({ subject: m.subject, body: m.bodyText || "", filenames: m.attachments.map((a) => a.filename), }); const lineage = m.parseResult?.lineage as { mail_record?: { modules?: { customer_name?: string } } } | null; const customer = lineage?.mail_record?.modules?.customer_name || (m.parseResult?.containerHeader as { F_MemoRemark?: string } | null) ?.F_MemoRemark || ""; console.log( JSON.stringify( { id: String(m.id), type: m.mailType, status: m.status, subject: m.subject.slice(0, 48), body_chars: (m.bodyText || "").length, att: m.attachments.length, shipments: ships.length, invalid: invalid.length, note_rows_in_shipments: noteLike.length, ui_kinds: units.map((u) => `${u.uiKind}${u.isCurrent ? "*" : ""}`), customer_hint: String(customer).slice(0, 40), url: `http://localhost:3100/mails/${m.id}`, }, null, 2, ), ); } // sanity: instruction noise helper still works const noise = isInstructionNoiseRow({ F_Transporter: "注意�?.ups和fedex Truck", F_FBACode: "注意�?.ups", }); console.log("\nisInstructionNoiseRow smoke:", noise); } main() .catch((e) => { console.error(e); process.exit(1); }) .finally(() => prisma.$disconnect());