Merge pull request 'Fixed unstable parts fetching from fanavaran' (#336) from s.yahyaee/yara724-api:main into main

Reviewed-on: Yara724/api#336
This commit is contained in:
2026-09-21 10:44:24 +03:30
2 changed files with 48 additions and 0 deletions

View File

@@ -2,6 +2,7 @@ import { ClaimVehicleTypeV2 } from "src/static/outer-car-parts-catalog";
import { buildCoefficientsFromPartSeverities } from "./claim-price-drop"; import { buildCoefficientsFromPartSeverities } from "./claim-price-drop";
import { import {
catalogPartIdFromSelectedPart, catalogPartIdFromSelectedPart,
normalizeDamageSelectedParts,
resolveCatalogPartByPartId, resolveCatalogPartByPartId,
resolvePartForExpertReply, resolvePartForExpertReply,
resolveSelectedPartByPartId, resolveSelectedPartByPartId,
@@ -86,6 +87,31 @@ describe("resolveSelectedPartByPartId", () => {
expect(catalogPartIdFromSelectedPart(row)).toBeNull(); expect(catalogPartIdFromSelectedPart(row)).toBeNull();
}); });
it("preserves a live Fanavaran id that is newer than the static snapshot", () => {
const [row] = normalizeDamageSelectedParts(
[{
id: 96,
name: "96",
side: "",
label_fa: "تیوتر",
catalogKey: "96",
}],
ClaimVehicleTypeV2.SEDAN,
);
expect(row).toEqual({
id: 96,
name: "96",
side: "",
label_fa: "تیوتر",
catalogKey: "96",
});
expect(catalogPartIdFromSelectedPart(row)).toBe(96);
expect(resolvePartForExpertReply(96, [row], ClaimVehicleTypeV2.SEDAN)).toBe(
row,
);
});
it("recovers outer part wrongly stored as internal with Persian label", () => { it("recovers outer part wrongly stored as internal with Persian label", () => {
const fixed = sanitizeDamageSelectedPartV2( const fixed = sanitizeDamageSelectedPartV2(
{ {

View File

@@ -466,6 +466,28 @@ export function sanitizeDamageSelectedPartV2(
} }
} }
// Fanavaran serves this catalog live and can add ids that do not exist in
// our fallback snapshot yet. Live rows are persisted with their numeric id
// repeated as `name`/`catalogKey` and an empty side. Preserve that identity
// instead of downgrading the row to an internal free-text part. Otherwise a
// newly-added Fanavaran part (for example id 96) disappears from the expert
// reply payload and later fails with PART_NOT_ON_CLAIM.
const numericCatalogIdentity =
id != null &&
Number.isFinite(id) &&
Number(id) > 0 &&
sideTrim === "" &&
(nameTrim === String(id) || String(catalogKey ?? "").trim() === String(id));
if (numericCatalogIdentity) {
return {
id: Number(id),
name: String(id),
side: "",
label_fa: labelTrim || nameTrim || String(id),
catalogKey: String(id),
};
}
if (isInternalDamageSide(side)) { if (isInternalDamageSide(side)) {
return { return {
id: null, id: null,