/** * Flock Direct 10 组样例探针 * * 用法: * FLOCK_QUOTE_MODE=direct npm run batch:flock-direct-10 */ import fs from "node:fs"; import path from "node:path"; import { runFlockQuoteRpa } from "@/workers/rpa/flock/run-quote"; import type { FlockQuoteInput } from "@/workers/rpa/flock/types"; function tomorrowMmDdYyyy(offsetDays = 1): string { const d = new Date(); d.setDate(d.getDate() + offsetDays); const mm = String(d.getMonth() + 1).padStart(2, "0"); const dd = String(d.getDate()).padStart(2, "0"); return `${mm}/${dd}/${d.getFullYear()}`; } /** 10 组差异化:跨区 ZIP + 不同托盘/总重/尺寸(硬限内) */ const CASES: Array & { label: string }> = [ { label: "LA→Dallas 6pl/10k", pickupZip: "90001", deliveryZip: "75201", palletCount: 6, totalWeightLb: 10_000, lengthIn: 48, widthIn: 40, heightIn: 48, }, { label: "SF→Chicago 4pl/2.8k", pickupZip: "94102", deliveryZip: "60611", palletCount: 4, totalWeightLb: 2_800, lengthIn: 48, widthIn: 40, heightIn: 48, }, { label: "Boston→Atlanta 8pl/9.2k", pickupZip: "02109", deliveryZip: "30326", palletCount: 8, totalWeightLb: 9_200, lengthIn: 48, widthIn: 40, heightIn: 60, }, { label: "Austin→Philly 10pl/14k", pickupZip: "78701", deliveryZip: "19106", palletCount: 10, totalWeightLb: 14_000, lengthIn: 48, widthIn: 40, heightIn: 72, }, { label: "Seattle→Miami 12pl/18.5k", pickupZip: "98101", deliveryZip: "33130", palletCount: 12, totalWeightLb: 18_500, lengthIn: 48, widthIn: 48, heightIn: 96, }, { label: "Denver→NYC 5pl/6k", pickupZip: "80202", deliveryZip: "10001", palletCount: 5, totalWeightLb: 6_000, lengthIn: 48, widthIn: 40, heightIn: 60, }, { label: "Phoenix→Houston 16pl/28k", pickupZip: "85004", deliveryZip: "77002", palletCount: 16, totalWeightLb: 28_000, lengthIn: 48, widthIn: 40, heightIn: 96, }, { label: "Portland→Dallas 4pl/8k long", pickupZip: "97201", deliveryZip: "75201", palletCount: 4, totalWeightLb: 8_000, lengthIn: 96, widthIn: 48, heightIn: 72, }, { label: "Detroit→LA 7pl/12k", pickupZip: "48226", deliveryZip: "90012", palletCount: 7, totalWeightLb: 12_000, lengthIn: 48, widthIn: 40, heightIn: 84, }, { label: "Chicago→SF 20pl/38k", pickupZip: "60611", deliveryZip: "94102", palletCount: 20, totalWeightLb: 38_000, lengthIn: 48, widthIn: 40, heightIn: 96, }, ]; type Row = { index: number; label: string; ok: boolean; ms: number; reference: string | null; prices: string | null; error: string | null; }; async function main(): Promise { process.env.RPA_MOCK_MODE = "false"; process.env.FLOCK_QUOTE_MODE ??= "direct"; process.env.FLOCK_MIN_QUOTES ??= "1"; const delayMs = Number(process.env.FLOCK_BATCH_DELAY_MS ?? "1500"); const outDir = path.join(process.cwd(), ".rpa", "flock-network-poc"); fs.mkdirSync(outDir, { recursive: true }); console.log( `[flock-direct-10] mode=${process.env.FLOCK_QUOTE_MODE} cases=${CASES.length}`, ); const rows: Row[] = []; for (let i = 0; i < CASES.length; i += 1) { const c = CASES[i]!; const input: FlockQuoteInput = { pickupDate: tomorrowMmDdYyyy(1 + (i % 3)), pickupZip: c.pickupZip, deliveryZip: c.deliveryZip, palletCount: c.palletCount, totalWeightLb: c.totalWeightLb, lengthIn: c.lengthIn, widthIn: c.widthIn, heightIn: c.heightIn, }; console.log( `\n[${i + 1}/${CASES.length}] ${c.label} ` + `${input.pickupZip}→${input.deliveryZip} ${input.palletCount}pl ${input.totalWeightLb}lb`, ); const t0 = Date.now(); const result = await runFlockQuoteRpa(input); const ms = Date.now() - t0; const ok = result.ok && result.quotes.length >= 1; const prices = ok ? result.quotes.map((q) => `${q.label}:$${q.totalUsd}`).join(", ") : null; rows.push({ index: i + 1, label: c.label, ok, ms, reference: result.reference ?? null, prices, error: ok ? null : (result.errorMessage ?? "unknown"), }); if (ok) { console.log(`[OK] ${ms}ms ref=${result.reference ?? "-"} ${prices}`); } else { console.error(`[FAIL] ${ms}ms ${result.errorMessage ?? "unknown"}`); } if (i < CASES.length - 1 && delayMs > 0) { await new Promise((r) => setTimeout(r, delayMs)); } } const passed = rows.filter((r) => r.ok).length; const summary = { capturedAt: new Date().toISOString(), mode: process.env.FLOCK_QUOTE_MODE, passed, total: rows.length, rows, }; const outPath = path.join(outDir, `direct-10-${Date.now()}.json`); fs.writeFileSync(outPath, JSON.stringify(summary, null, 2), "utf8"); console.log(`\n========== 汇总 ${passed}/${rows.length} ==========`); for (const r of rows) { console.log( r.ok ? ` ✓ #${r.index} ${r.label} (${r.ms}ms) ${r.prices}` : ` ✗ #${r.index} ${r.label} (${r.ms}ms) ${r.error}`, ); } console.log(`结果文件: ${outPath}`); if (passed < rows.length) process.exitCode = 1; } main().catch((error) => { console.error("[flock-direct-10] fatal:", error); process.exit(1); });