forked from Yara724/api
YARA-1177
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
ClaimVehicleTypeV2,
|
||||
FANAVARAN_CAR_PARTS_CATALOG,
|
||||
OUTER_PARTS_BY_CAR_TYPE,
|
||||
OuterPartCatalogItem,
|
||||
OuterPartSideV2,
|
||||
@@ -93,12 +94,14 @@ export function sameCatalogPartId(
|
||||
return na != null && nb != null && na === nb;
|
||||
}
|
||||
|
||||
/** API part id: numeric catalog id only (`null` for internal / non-catalog lines). */
|
||||
/** API part id: numeric catalog id only (`null` for free-text / non-catalog lines). */
|
||||
export function catalogPartIdFromSelectedPart(
|
||||
sp: DamageSelectedPartV2,
|
||||
): number | null {
|
||||
if (isInternalDamageSide(sp.side)) return null;
|
||||
// Parts from the Fanavaran catalog always carry a numeric id regardless of side.
|
||||
if (sp.id != null && Number.isFinite(sp.id)) return sp.id;
|
||||
// Legacy parts without an id and with an internal/unknown side are free-text only.
|
||||
if (isInternalDamageSide(sp.side)) return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -153,12 +156,13 @@ export function disambiguateOuterPartLabelFa(
|
||||
return `${t} (${sideFa})`;
|
||||
}
|
||||
|
||||
const CATALOG_ITEM_BY_ID = new Map<number, OuterPartCatalogItem>();
|
||||
for (const list of Object.values(OUTER_PARTS_BY_CAR_TYPE)) {
|
||||
for (const it of list) {
|
||||
CATALOG_ITEM_BY_ID.set(it.id, it);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Static id → item map for legacy DB part resolution.
|
||||
* Built from the Fanavaran snapshot; unique because all car types share the same list.
|
||||
*/
|
||||
const CATALOG_ITEM_BY_ID = new Map<number, OuterPartCatalogItem>(
|
||||
FANAVARAN_CAR_PARTS_CATALOG.map((it) => [it.id, it]),
|
||||
);
|
||||
|
||||
function findCatalogItemByKey(key: string): OuterPartCatalogItem | undefined {
|
||||
for (const list of Object.values(OUTER_PARTS_BY_CAR_TYPE)) {
|
||||
@@ -681,7 +685,7 @@ export function normalizeCarPartDamageForExpertReply(
|
||||
? o.side.trim().toLowerCase()
|
||||
: "";
|
||||
|
||||
if (name && sideIn) {
|
||||
if (name) {
|
||||
const id = toNum(o.id);
|
||||
const ck =
|
||||
typeof o.catalogKey === "string" && o.catalogKey.trim()
|
||||
@@ -689,36 +693,28 @@ export function normalizeCarPartDamageForExpertReply(
|
||||
: undefined;
|
||||
const catalog = carType ? OUTER_PARTS_BY_CAR_TYPE[carType] : undefined;
|
||||
let catItem: OuterPartCatalogItem | undefined;
|
||||
if (catalog) {
|
||||
// Try id-based lookup first (works for Fanavaran parts which have no side)
|
||||
if (id != null) {
|
||||
catItem = catalog?.find((c) => c.id === id) ?? CATALOG_ITEM_BY_ID.get(id) ?? undefined;
|
||||
}
|
||||
if (!catItem && catalog) {
|
||||
const byKey = new Map(catalog.map((c) => [c.key, c]));
|
||||
if (ck) catItem = byKey.get(ck);
|
||||
if (!catItem && id != null) catItem = catalog.find((c) => c.id === id);
|
||||
if (!catItem) {
|
||||
if (!catItem && sideIn) {
|
||||
catItem = byKey.get(catalogLikeKeyFromPart({ side: sideIn, name }));
|
||||
}
|
||||
}
|
||||
if (!catItem && id != null) {
|
||||
catItem = CATALOG_ITEM_BY_ID.get(id!) ?? undefined;
|
||||
}
|
||||
const list = catalog?.length
|
||||
? catalog
|
||||
: catItem
|
||||
? outerCatalogListForItem(catItem)
|
||||
: [];
|
||||
if (catItem && list.length) {
|
||||
if (!catItem && ck) catItem = findCatalogItemByKey(ck);
|
||||
if (catItem) {
|
||||
return selectedPartToStoredRecord(
|
||||
catalogItemToSelectedPart(catItem, list),
|
||||
catalogItemToSelectedPart(catItem, outerCatalogListForItem(catItem)),
|
||||
);
|
||||
}
|
||||
const label_fa =
|
||||
typeof o.label_fa === "string" && o.label_fa.trim()
|
||||
? o.label_fa.trim()
|
||||
: name;
|
||||
const out: Record<string, unknown> = {
|
||||
name,
|
||||
side: sideIn,
|
||||
label_fa,
|
||||
};
|
||||
const out: Record<string, unknown> = { name, side: sideIn, label_fa };
|
||||
if (id != null) out.id = id;
|
||||
if (ck) out.catalogKey = ck;
|
||||
return out;
|
||||
@@ -731,9 +727,8 @@ export function normalizeCarPartDamageForExpertReply(
|
||||
carType,
|
||||
);
|
||||
if (catItem) {
|
||||
const list = outerCatalogListForItem(catItem);
|
||||
return selectedPartToStoredRecord(
|
||||
catalogItemToSelectedPart(catItem, list),
|
||||
catalogItemToSelectedPart(catItem, outerCatalogListForItem(catItem)),
|
||||
);
|
||||
}
|
||||
const sideFa = SIDE_LABEL_FA[legacySide] || legacySide;
|
||||
@@ -744,7 +739,7 @@ export function normalizeCarPartDamageForExpertReply(
|
||||
};
|
||||
}
|
||||
|
||||
throw new Error("carPartDamage must include side and (name or part)");
|
||||
throw new Error("carPartDamage must include a name or part field");
|
||||
}
|
||||
|
||||
/** Best-effort migration for API output; never throws. */
|
||||
|
||||
Reference in New Issue
Block a user