fix(catalog): route Hyundai/Kia/Nissan to de account (licensed; tr is demo)
Verified on dev: the tr account serves NOT_LOGGED_IN_DEMO for Hyundai/Kia/Nissan parts (browse-only), while the de (account 2) subscription is licensed and returns real data (de: 266 Hyundai / 169 Kia models, non-demo, ~88/64 drill rows). Route every P4 fetch for these brands to de in fetchP4Page (+ resolveAccount), and ensure the de service token is authorized. Existing tr-coded catalog_vehicles must be re-seeded so they carry de catalog codes (ops step on deploy). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -46,6 +46,11 @@ export interface P4BrandHooks {
|
||||
parseVehicleInfo?(html: string, vin: string): P4VehicleInfo | null;
|
||||
}
|
||||
|
||||
// Brands whose parts are licensed only on the de (account 2) PL24 subscription —
|
||||
// the tr account serves a NOT_LOGGED_IN_DEMO page for these. All P4 fetches for
|
||||
// these services are routed to de (see fetchP4Page + resolveAccount).
|
||||
const HYUNDAI_KIA_NISSAN_DE = new Set(["hyundai_parts", "kia_parts", "nissan_parts"]);
|
||||
|
||||
@Injectable()
|
||||
export class PL24FordLegacyService {
|
||||
private readonly logger = new Logger(PL24FordLegacyService.name);
|
||||
@@ -148,37 +153,6 @@ export class PL24FordLegacyService {
|
||||
|
||||
this.logger.log(`Ford legacy: fetching sub-groups from ${linkPath}`);
|
||||
|
||||
// TEMP DE-PROBE: run the FULL de-account flow with de's OWN catalog codes
|
||||
// (de group.action → de vehicle.action → de drill) to definitively test
|
||||
// whether the de account is licensed (non-demo) for Hyundai/Kia/Nissan parts.
|
||||
if (["hyundai_parts", "kia_parts", "nissan_parts"].includes(serviceName)) {
|
||||
try {
|
||||
const cfg = getServiceConfig(serviceName);
|
||||
const bp = cfg
|
||||
? `${cfg.basePath}/${serviceName}`
|
||||
: `/hyundai-kia-automotive-group/${serviceName}`;
|
||||
await this.authService.authorizeServiceForAccount(serviceName, "de");
|
||||
const gh = await this.fetchP4Page(`${this.baseUrl}${bp}/group.action?lang=tr`, serviceName, true, "de");
|
||||
const ghDemo = !!gh && gh.includes("NOT_LOGGED_IN_DEMO");
|
||||
const mu = gh ? this.extractModeUpdsFromHtml(gh) : { mode: "", upds: "" };
|
||||
const vh = await this.fetchP4Page(`${this.baseUrl}${bp}/vehicle.action?lang=tr&startup=true&mode=${mu.mode}&upds=${mu.upds}`, serviceName, true, "de");
|
||||
const vhDemo = !!vh && vh.includes("NOT_LOGGED_IN_DEMO");
|
||||
const rows = vh ? this.parseHyundaiKiaCatalogRows(vh) : [];
|
||||
this.logger.warn(`DE-FULL ${serviceName}: groupDemo=${ghDemo} vehDemo=${vhDemo} deRows=${rows.length} first=${JSON.stringify(rows[0])}`);
|
||||
if (rows.length) {
|
||||
const mu2 = this.extractModeUpdsFromHtml(vh as string);
|
||||
const em = mu2.mode || mu.mode;
|
||||
const eu = mu2.upds || mu.upds;
|
||||
const du = `${this.baseUrl}${bp}/group.action?catalog=${encodeURIComponent(rows[0].id)}&lang=tr&localMarketOnly=true&mainGroup=EN&spec=e30%3D&startup=false&mode=${em}&upds=${eu}`;
|
||||
const dh = await this.fetchP4Page(du, serviceName, true, "de");
|
||||
const dDemo = !!dh && dh.includes("NOT_LOGGED_IN_DEMO");
|
||||
this.logger.warn(`DE-FULL ${serviceName} drill cat=${rows[0].id}: demo=${dDemo} tcRows=${dh ? (dh.match(/tc-data-row/g) || []).length : 0} len=${dh?.length}`);
|
||||
}
|
||||
} catch (e) {
|
||||
this.logger.warn(`DE-FULL ${serviceName} probe failed: ${(e as Error).message}`);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const account = await this.resolveAccount(userId, serviceName);
|
||||
const html = await this.fetchP4Page(linkPath, serviceName, false, account);
|
||||
@@ -397,36 +371,6 @@ export class PL24FordLegacyService {
|
||||
|
||||
this.logger.log(`Ford legacy: fetching parts from ${linkPath}`);
|
||||
|
||||
// TEMP DE-PROBE: full de-account flow with de's OWN catalog codes to test
|
||||
// whether de is licensed (non-demo) for Hyundai/Kia/Nissan parts.
|
||||
if (["hyundai_parts", "kia_parts", "nissan_parts"].includes(serviceName)) {
|
||||
try {
|
||||
const cfg = getServiceConfig(serviceName);
|
||||
const bp = cfg
|
||||
? `${cfg.basePath}/${serviceName}`
|
||||
: `/hyundai-kia-automotive-group/${serviceName}`;
|
||||
await this.authService.authorizeServiceForAccount(serviceName, "de");
|
||||
const gh = await this.fetchP4Page(`${this.baseUrl}${bp}/group.action?lang=tr`, serviceName, true, "de");
|
||||
const ghDemo = !!gh && gh.includes("NOT_LOGGED_IN_DEMO");
|
||||
const mu = gh ? this.extractModeUpdsFromHtml(gh) : { mode: "", upds: "" };
|
||||
const vh = await this.fetchP4Page(`${this.baseUrl}${bp}/vehicle.action?lang=tr&startup=true&mode=${mu.mode}&upds=${mu.upds}`, serviceName, true, "de");
|
||||
const vhDemo = !!vh && vh.includes("NOT_LOGGED_IN_DEMO");
|
||||
const rows = vh ? this.parseHyundaiKiaCatalogRows(vh) : [];
|
||||
this.logger.warn(`DE-FULL ${serviceName}: groupDemo=${ghDemo} vehDemo=${vhDemo} deRows=${rows.length} first=${JSON.stringify(rows[0])}`);
|
||||
if (rows.length) {
|
||||
const mu2 = this.extractModeUpdsFromHtml(vh as string);
|
||||
const em = mu2.mode || mu.mode;
|
||||
const eu = mu2.upds || mu.upds;
|
||||
const du = `${this.baseUrl}${bp}/group.action?catalog=${encodeURIComponent(rows[0].id)}&lang=tr&localMarketOnly=true&mainGroup=EN&spec=e30%3D&startup=false&mode=${em}&upds=${eu}`;
|
||||
const dh = await this.fetchP4Page(du, serviceName, true, "de");
|
||||
const dDemo = !!dh && dh.includes("NOT_LOGGED_IN_DEMO");
|
||||
this.logger.warn(`DE-FULL ${serviceName} drill cat=${rows[0].id}: demo=${dDemo} tcRows=${dh ? (dh.match(/tc-data-row/g) || []).length : 0} len=${dh?.length}`);
|
||||
}
|
||||
} catch (e) {
|
||||
this.logger.warn(`DE-FULL ${serviceName} probe failed: ${(e as Error).message}`);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const account = await this.resolveAccount(userId, serviceName);
|
||||
const isImageBoard = linkPath.includes("image-board.action");
|
||||
@@ -1946,10 +1890,13 @@ export class PL24FordLegacyService {
|
||||
* Fiat services always use 'de'; others use round-robin via Redis.
|
||||
*/
|
||||
private async resolveAccount(userId?: string, serviceName?: string): Promise<"tr" | "de"> {
|
||||
// Fiat always needs de account
|
||||
// Fiat always needs de account; Hyundai/Kia/Nissan parts are licensed only on de.
|
||||
if (serviceName && ["fiatp_parts", "fiatt_parts"].includes(serviceName)) {
|
||||
return "de";
|
||||
}
|
||||
if (serviceName && HYUNDAI_KIA_NISSAN_DE.has(serviceName)) {
|
||||
return "de";
|
||||
}
|
||||
|
||||
// No userId → tr (catalog browser / prefetch)
|
||||
if (!userId) return "tr";
|
||||
@@ -3266,6 +3213,15 @@ export class PL24FordLegacyService {
|
||||
account: "tr" | "de" = "tr",
|
||||
retried = false,
|
||||
): Promise<string | null> {
|
||||
// Hyundai/Kia/Nissan parts are licensed ONLY on the de account — the tr
|
||||
// account returns a NOT_LOGGED_IN_DEMO page (browse-only). Route every P4
|
||||
// fetch for these brands to de (which carries the Korean/Japanese license),
|
||||
// and ensure the de service token is authorized. Verified on dev: de yields
|
||||
// 266 Hyundai / 169 Kia models, non-demo, with real drill content.
|
||||
if (HYUNDAI_KIA_NISSAN_DE.has(serviceName)) {
|
||||
account = "de";
|
||||
await this.authService.authorizeServiceForAccount(serviceName, "de");
|
||||
}
|
||||
// Some catalogs (Volvo vin-group.action) store hrefs relative to the catalog
|
||||
// directory (e.g. "vin-group.action?group1=…"). Prefix the service basePath
|
||||
// so `${baseUrl}${path}` doesn't collapse into "partslink24.comvin-group…".
|
||||
|
||||
Reference in New Issue
Block a user