import { createHash } from "node:crypto"; import type { AddressLookupInput, MothershipAddressCandidate, } from "@/modules/address/types"; import { getAddressCandidatesCache, setAddressCandidatesCache, } from "@/modules/cache/redis-cache"; export type AddressCandidatesCachePayload = { pickup_candidates: MothershipAddressCandidate[]; delivery_candidates: MothershipAddressCandidate[]; }; function normalizeAddressLookup(input: AddressLookupInput): string { return JSON.stringify({ street: input.street.trim(), city: input.city.trim(), state: input.state.trim().toUpperCase(), zip: input.zip.trim(), country: (input.country ?? "USA").trim().toUpperCase(), }); } /** pickup + delivery 草稿地址 MD5,用于 addr-cand 缓存键 */ export function buildAddressCandidatesCacheHash(input: { pickup: AddressLookupInput; delivery: AddressLookupInput; }): string { const raw = [ normalizeAddressLookup(input.pickup), normalizeAddressLookup(input.delivery), ].join("|"); return createHash("md5").update(raw).digest("hex"); } export async function loadAddressCandidatesCache(input: { pickup: AddressLookupInput; delivery: AddressLookupInput; }): Promise { try { const hash = buildAddressCandidatesCacheHash(input); return await getAddressCandidatesCache(hash); } catch { return null; } } export async function saveAddressCandidatesCache( input: { pickup: AddressLookupInput; delivery: AddressLookupInput; }, payload: AddressCandidatesCachePayload, ): Promise { try { const hash = buildAddressCandidatesCacheHash(input); await setAddressCandidatesCache(hash, payload); } catch { // Redis 不可用时跳过缓存,不影响主流程 } }