import { createHash } from "crypto"; import type { NormalizedCargo } from "@/modules/quote/types"; export type CargoHashInput = { pickupSerialized: string; deliverySerialized: string; weightLb: number; dimLIn: number; dimWIn: number; dimHIn: number; palletCount: number; cargoType: string; }; /** 地址序列化为含 place_id 的标准 JSON(BR-4.4) */ export function serializeAddress(addr: { street: string; city: string; state: string; zip: string; place_id: string; mothership_option_id?: string; }): string { return JSON.stringify({ street: addr.street.trim(), city: addr.city.trim(), state: addr.state.trim().toUpperCase(), zip: addr.zip.trim(), place_id: addr.mothership_option_id?.trim() || addr.place_id, }); } /** cargo_hash = MD5(pickup+delivery+weight_lb+dims+pallet_count+cargo_type) */ export function buildCargoHash(input: CargoHashInput): string { const raw = [ input.pickupSerialized, input.deliverySerialized, input.weightLb.toFixed(2), input.dimLIn.toFixed(2), input.dimWIn.toFixed(2), input.dimHIn.toFixed(2), String(input.palletCount), input.cargoType, ].join("|"); return createHash("md5").update(raw).digest("hex"); } export function buildCargoHashFromNormalized(cargo: NormalizedCargo): string { return buildCargoHash({ pickupSerialized: cargo.pickupSerialized, deliverySerialized: cargo.deliverySerialized, weightLb: cargo.weightLb, dimLIn: cargo.dimLIn, dimWIn: cargo.dimWIn, dimHIn: cargo.dimHIn, palletCount: cargo.palletCount, cargoType: cargo.cargoType, }); }