chore(debug): TEMP recursive Ford selection-chain mapping (revert after)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-05 15:25:56 +03:00
parent ce297893ee
commit 9772ce1ef4

View File

@@ -1789,27 +1789,51 @@ export class PL24FordLegacyService {
`Ford: ${groups.length} groups for ${serviceName}/${familyId} catCode=${catCode ?? "none"} arch=${arch}`, `Ford: ${groups.length} groups for ${serviceName}/${familyId} catCode=${catCode ?? "none"} arch=${arch}`,
); );
// TEMP DEBUG: map the Ford catCode→vehicle-select→groups flow // TEMP DEBUG: recursively map the Ford selection chain → groups depth.
if (groups.length === 0 && arch === "LEGACY_FORD") { if (groups.length === 0 && arch === "LEGACY_FORD") {
const vrows: Array<{ url: string; cap?: string }> = []; const famBase = String(familyId).split("/")[0].trim(); // "C-MAX/Grand C-MAX" → "C-MAX"
for (const seg of html.split(/<tr\s/)) { const rowsOf = (h: string) => {
if (!seg.includes("tc-data-row")) continue; const out: Array<{ url: string; cap?: string; kind: string }> = [];
const m = seg.match(/\burl="([^"]+)"/); for (const seg of h.split(/<tr\s/)) {
if (m?.[1].includes("vehicle.action")) { if (!seg.includes("tc-data-row")) continue;
vrows.push({ url: m[1], cap: seg.match(/\bcaption="([^"]+)"/)?.[1]?.slice(0, 40) }); const m = seg.match(/\burl="([^"]+)"/) || seg.match(/\bjsonUrl="([^"]+)"/i);
if (!m) continue;
const cap = seg.match(/\bcaption="([^"]+)"/)?.[1]?.slice(0, 30);
const kind = m[1].includes("vehicle.action")
? "vehicle"
: m[1].includes("group")
? "group"
: "other";
out.push({ url: m[1], cap, kind });
} }
} return out;
this.logger.warn( };
`Ford VSEL ${familyId} cc=${catCode}: ${vrows.length} vehicle rows; first3=${JSON.stringify(vrows.slice(0, 3))}`, let curHtml: string | null = html;
); for (let lvl = 0; lvl < 5 && curHtml; lvl++) {
if (vrows.length) { const rows = rowsOf(curHtml);
const vhtml = await this.fetchP4Page(vrows[0].url, serviceName, false); const title = curHtml.match(/<title>([^<]*)<\/title>/i)?.[1];
const vtc = vhtml ? (vhtml.match(/tc-data-row/g) || []).length : 0; const kinds = rows.reduce<Record<string, number>>((a, r) => {
const vgroups = vhtml ? this.parseFordGroupsFromHtml(vhtml, serviceName, familyId) : []; a[r.kind] = (a[r.kind] || 0) + 1;
const vtitle = vhtml?.match(/<title>([^<]*)<\/title>/i)?.[1]; return a;
}, {});
this.logger.warn( this.logger.warn(
`Ford VSEL child: len=${vhtml?.length} title="${vtitle}" tcRows=${vtc} parsedGroups=${vgroups.length} names=${JSON.stringify(vgroups.slice(0, 6).map((g) => g.nameTr))}`, `Ford CHAIN L${lvl} title="${title}" rows=${rows.length} kinds=${JSON.stringify(kinds)} sample=${JSON.stringify(rows.slice(0, 4).map((r) => `${r.kind}:${r.cap}`))}`,
); );
if (kinds.group) {
this.logger.warn(`Ford CHAIN L${lvl}: GROUPS FOUND — sample url=${rows.find((r) => r.kind === "group")?.url}`);
break;
}
// follow the row matching our family base, else the first vehicle row
const next =
rows.find((r) => r.kind === "vehicle" && r.cap && famBase.includes(r.cap)) ||
rows.find((r) => r.kind === "vehicle" && r.cap && r.cap.includes(famBase)) ||
rows.find((r) => r.kind === "vehicle");
if (!next) {
this.logger.warn(`Ford CHAIN L${lvl}: no vehicle row to follow, stop`);
break;
}
this.logger.warn(`Ford CHAIN L${lvl}: following "${next.cap}" → ${next.url.slice(0, 70)}`);
curHtml = await this.fetchP4Page(next.url, serviceName, false);
} }
} }