From d9188697423e97b11a74713e86c8876a5d1c6142 Mon Sep 17 00:00:00 2001 From: Semih Yesilyurt Date: Fri, 5 Jun 2026 15:01:50 +0300 Subject: [PATCH] fix(catalog): self-discover P5 model-list endpoint for unmapped backends MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fetchVehicleList fell back to /extern/vehicle/modelfamilies for any backend not in BACKEND_MODEL_PATH; p5fiat (Fiat) isn't mapped, so it returned 0 models and Fiat seeded nothing (0 catalog_vehicles on dev+prod). When the primary path yields nothing, try the other known P5 listing endpoints and use the first that returns models, logging which one worked so it can be pinned. Only runs on the empty path → mapped backends unaffected. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../api/src/integrations/pl24/pl24.service.ts | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/apps/api/src/integrations/pl24/pl24.service.ts b/apps/api/src/integrations/pl24/pl24.service.ts index 8fd940c..49172df 100644 --- a/apps/api/src/integrations/pl24/pl24.service.ts +++ b/apps/api/src/integrations/pl24/pl24.service.ts @@ -2058,6 +2058,37 @@ export class PL24Service { } } + // Fallback: the primary modelPath returned nothing (e.g. p5fiat is not mapped + // in BACKEND_MODEL_PATH yet). Try the other known P5 listing endpoints so an + // unmapped backend self-discovers its model list instead of silently seeding 0. + // Only runs when the primary yields nothing → no impact on mapped backends. + const candidatePaths = [ + "/extern/vehicle/modelfamilies", + "/extern/vehicle/models", + "/extern/vehicle/modelFamilies", + "/extern/vehicle/catalogs", + "/extern/vehicle/scope", + "/extern/vehicles/vehiclesOverview", + "/extern/model/categories", + ].filter((p) => p !== modelPath); + for (const candidate of candidatePaths) { + try { + const cu = `${this.baseUrl}${catalogBase}${candidate}?lang=${this.language}&serviceName=${serviceName}`; + const cr = await fetch(cu, { method: "GET", headers, signal: AbortSignal.timeout(15000) }); + if (!cr.ok) continue; + const cd = (await cr.json()) as Record; + const cv = this.parseVehicleListResponse(cd, serviceName); + if (cv.length > 0) { + this.logger.log( + `fetchVehicleList: ${serviceName} discovered via ${candidate} (${cv.length} models) — pin BACKEND_MODEL_PATH["${backendKey}"]="${candidate}"`, + ); + return cv; + } + } catch { + // try next candidate + } + } + this.logger.log(`No vehicle list available for ${serviceName} (HTTP ${response.status})`); return []; } catch (err) {