fix(catalog/ford): disambiguate identical catCode buttons + relabel "Model Yılı" → "Varyant"
Two visible defects when a user picks a Ford model (variant selector step):
1. **N identical buttons.** Ford's `modelFamilyToModelList` gives every sub-catCode
the same caption — just the family name. parseFordCatCodesForFamily returned
`[{code:CBV,name:Kuga},{code:CBS,name:Kuga},{code:CTD,name:Kuga}]` for Kuga
2012-2020. The UI rendered three indistinguishable "Kuga" pills with no way
for the user to tell them apart. Same on Galaxy ("Galaxy"/"Galaxy"), every
multi-catCode family.
Fix: detect duplicate baseNames per family and graft a disambiguator —
year first (friendliest), catCode as a last resort. Result:
"Kuga (2013-2016)" / "Kuga (2016-2020)" / "Kuga (CTD)" — or, when year is
present even for unique entries, always include it for a uniform look.
2. **Section title was lying.** UI label was `catalog.fordVariant.modelYear`
= "Model Yılı" ("Model Year") but for Ford LEGACY these are catCodes
(generation identifiers), not years. Rename the key value to "Varyant" /
"Variant" — semantically correct for both Ford catCodes and Volvo years
(Volvo flows through the same selector and its codes ARE years; "Varyant"
covers both).
Cleared the affected Redis cache (`pl24:ford:config:*`) on dev so the next
hit fetches fresh disambiguated data; prod cache will roll over on its own
TTL after promote.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1712,25 +1712,39 @@ export class PL24FordLegacyService {
|
||||
const models = familyKey ? familyMap[familyKey] : undefined;
|
||||
if (!Array.isArray(models) || models.length === 0) return [];
|
||||
|
||||
const results: { code: string; name: string }[] = [];
|
||||
// First pass: collect (catCode, baseCaption, year). Ford's modelFamilyToModelList
|
||||
// typically gives every sub-catCode the SAME caption (just the family name like
|
||||
// "Kuga" / "Galaxy"). Without disambiguation the UI shows N identical buttons.
|
||||
const raw: Array<{ code: string; baseName: string; year: string }> = [];
|
||||
for (const m2 of models) {
|
||||
if (m2.gray === true) continue; // Skip unavailable sub-models
|
||||
|
||||
// catCode may be in identifier OR embedded in the URL
|
||||
const catCode =
|
||||
m2.identifier?.trim() || "" || m2.url?.match(/[?&]catCode=([^&"]+)/)?.[1] || "";
|
||||
const catCode = m2.identifier?.trim() || m2.url?.match(/[?&]catCode=([^&"]+)/)?.[1] || "";
|
||||
if (!catCode) continue;
|
||||
|
||||
// Build display name: caption if available, else family+year range
|
||||
const caption = m2.caption?.trim();
|
||||
const yearStr = m2.year?.replace(/[()]/g, "").trim();
|
||||
const yearDisplay = yearStr ? ` (${yearStr.replace(",", "-")})` : "";
|
||||
const name = caption || `${familyId}${yearDisplay}`;
|
||||
|
||||
results.push({ code: catCode, name });
|
||||
const caption = m2.caption?.trim() || "";
|
||||
const yearStr = m2.year?.replace(/[()]/g, "").trim() || "";
|
||||
raw.push({ code: catCode, baseName: caption || familyId, year: yearStr });
|
||||
}
|
||||
|
||||
return results;
|
||||
// Count how many entries share each baseName — if the upstream uses the same
|
||||
// caption for multiple sub-codes, we have to graft a disambiguator on.
|
||||
const baseCounts = new Map<string, number>();
|
||||
for (const r of raw) baseCounts.set(r.baseName, (baseCounts.get(r.baseName) ?? 0) + 1);
|
||||
|
||||
return raw.map(({ code, baseName, year }) => {
|
||||
const isDup = (baseCounts.get(baseName) ?? 0) > 1;
|
||||
const yearDisplay = year ? year.replace(",", "-") : "";
|
||||
// Year is the friendliest disambiguator. catCode is the last-resort fallback
|
||||
// since it's an internal identifier ("CBV") — better than two identical buttons.
|
||||
if (isDup) {
|
||||
return {
|
||||
code,
|
||||
name: yearDisplay ? `${baseName} (${yearDisplay})` : `${baseName} (${code})`,
|
||||
};
|
||||
}
|
||||
return { code, name: yearDisplay ? `${baseName} (${yearDisplay})` : baseName };
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user