fix(pl24): Volvo drill — keep openVinDialog=false links + image-board leaves
Some checks failed
QA Gate (P0/P1) / Test affected app (pull_request) Has been cancelled

Two bugs in the vin-group.action subgroup scrape: (1) the filter dropped any
href containing "openVinDialog", but the real sub-group links carry
openVinDialog=false (only the VIN-dialog crumb is =true) — so every child was
discarded; (2) the deepest group level lists its illustration leaves as
vin-image-board.action links, which weren't extracted. Now match both deeper
vin-group.action?groupN= and vin-image-board.action anchors, and only drop the
openVinDialog=true crumb. Completes Volvo group1→group2→illustration→parts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-02 02:24:59 +03:00
parent f5c3198a6e
commit c46695d320

View File

@@ -131,11 +131,13 @@ export class PL24FordLegacyService {
if (!html) return [];
// Volvo (VIN-indexed legacy catalog): vin-group.action?group1=…[&group2=…]
// HTML pages list the next group level as <a href="vin-group.action?…&
// groupN=…"> links. PL24's old JSON json-vin-*-group.action endpoints now
// 404, so we scrape the HTML here. Keep only links with MORE groupN=
// params than the current path (one level deeper); drop sibling/parent nav
// and the VIN-dialog crumb. An empty result ⇒ this node is a leaf (parts).
// HTML pages list the next tree level as <a href> links — either a deeper
// vin-group.action?…&groupN=… (sub-group) or a vin-image-board.action?… leaf
// (the illustration that carries the BOM). PL24's old JSON
// json-vin-*-group.action endpoints now 404, so we scrape the HTML here.
// For sub-groups keep only links one group-level deeper than the current
// path; drop sibling/parent nav and the open-VIN-dialog crumb
// (openVinDialog=true — note the real links carry openVinDialog=false).
if (linkPath.includes("vin-group.action")) {
const cfg = getServiceConfig(serviceName);
const basePath = cfg ? `${cfg.basePath}/${serviceName}` : `/volvo/${serviceName}`;
@@ -143,12 +145,15 @@ export class PL24FordLegacyService {
const seenHref = new Set<string>();
const subs: PL24MainGroup[] = [];
const anchorRe =
/<a[^>]+href="([^"]*vin-group\.action\?[^"]*group\d+=[^"]*)"[^>]*>([\s\S]*?)<\/a>/gi;
/<a[^>]+href="((?:[^"]*vin-group\.action\?[^"]*group\d+=|[^"]*vin-image-board\.action\?)[^"]*)"[^>]*>([\s\S]*?)<\/a>/gi;
for (const m of html.matchAll(anchorRe)) {
const href = m[1].replace(/&amp;/g, "&");
if (href.includes("openVinDialog")) continue;
const childDepth = [...href.matchAll(/\bgroup\d+=/g)].length;
if (childDepth <= parentDepth) continue; // sibling/parent nav, not a child
if (href.includes("openVinDialog=true")) continue;
const isImageBoard = href.includes("vin-image-board.action");
if (!isImageBoard) {
const childDepth = [...href.matchAll(/\bgroup\d+=/g)].length;
if (childDepth <= parentDepth) continue; // sibling/parent group nav
}
if (seenHref.has(href)) continue;
seenHref.add(href);
const name = m[2]
@@ -161,9 +166,6 @@ export class PL24FordLegacyService {
const lp = href.startsWith("/") ? href : `${basePath}/${href}`;
subs.push({ id: href, code: href, name, linkPath: lp });
}
this.logger.log(
`Volvo vin-group drill: htmlLen=${html.length} groupParamLinks=${(html.match(/group\d+=/g) || []).length} subs=${subs.length}${html.includes("NOT_LOGGED_IN_DEMO") ? " [DEMO]" : ""}`,
);
if (subs.length > 0) {
await this.redis.setJson(cacheKey, subs, 86400);
}