import { compareUiTierSortOrder } from "@/lib/constants/quote"; import { filterQuotesForMotherShipUiDisplay } from "@/lib/constants/mothership-ui-tiers"; import { RpaDataInvalidError } from "@/modules/quote/types"; type QuoteTierKey = { service_level: string; rate_option: string; }; function tierKey(serviceLevel: string, rateOption: string): string { return `${serviceLevel}/${rateOption}`; } /** 保留 MotherShip 实际返回的全部档位,仅去重 + 排序(不作固定档位白名单) */ export function normalizeToFourTiers( quotes: T[], ): T[] { const map = new Map(); for (const quote of quotes) { map.set(tierKey(quote.service_level, quote.rate_option), quote); } const normalized = [...map.values()].sort((a, b) => compareUiTierSortOrder( a.service_level, a.rate_option, b.service_level, b.rate_option, ), ); if (normalized.length < 1) { throw new RpaDataInvalidError("报价档位数不足"); } return normalized; } /** 至少 1 档;具体组合随 MotherShip 实际返回 */ export function assertFourTiers(quotes: QuoteTierKey[]): void { normalizeToFourTiers(quotes); } /** API 全量档位 → 展示/入库格式(去重排序,不删档不补档) */ export function toMotherShipUiQuotes(quotes: T[]): T[] { const ui = filterQuotesForMotherShipUiDisplay(quotes); if (ui.length < 1) { throw new RpaDataInvalidError("官网展示档位为空"); } const hasStandardEntry = ui.some((q) => q.service_level === "standard"); if (!hasStandardEntry) { throw new RpaDataInvalidError("缺少标准档报价"); } return ui; } /** 校验 API 全量档位后,转为官网展示档位(入库 / 缓存 / 响应统一入口) */ export function prepareMotherShipStorageQuotes( quotes: T[], ): T[] { assertFourTiers(quotes); return toMotherShipUiQuotes(quotes); }