From 99ac6cf0683b6702c8604bcc288edc2593e46d76 Mon Sep 17 00:00:00 2001 From: Dicken Date: Mon, 20 Jul 2026 17:31:40 +0200 Subject: [PATCH] fix: KoePi trinkgut bekommt eigene, praezise Koordinaten statt gemeinsamem Referenzpunkt --- backend/src/tools/koepi/routes.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/backend/src/tools/koepi/routes.js b/backend/src/tools/koepi/routes.js index 0291933..a60e677 100644 --- a/backend/src/tools/koepi/routes.js +++ b/backend/src/tools/koepi/routes.js @@ -75,7 +75,7 @@ const RETAILER_FAMILIES = { const LOCAL_STORE_TARGETS = [ { retailer: 'Netto Marken-Discount', uniqueName: 'netto-marken-discount', addressMatch: 'Im Bonnefeld 19' }, { retailer: 'Netto Getränke-Discount', uniqueName: 'netto-getraenke-discount', addressMatch: 'Im Bonnefeld 21' }, - { retailer: 'trinkgut', uniqueName: 'trinkgut', addressMatch: 'Keniastraße 39' }, + { retailer: 'trinkgut', uniqueName: 'trinkgut', addressMatch: 'Keniastraße 39', lat: '51.377915761179864', lon: '6.773658722208071' }, { retailer: 'REWE', uniqueName: 'rewe', addressMatch: 'Fischerstr. 110-112' }, { retailer: 'Kaufland', uniqueName: 'kaufland', addressMatch: 'Auf der Höhe 20' }, { retailer: 'Penny', uniqueName: 'penny', addressMatch: 'Sittardsberger Allee 10' }, @@ -181,13 +181,14 @@ async function fetchLeafletFlightToLeafletMap(extraSearchKeys = []) { // closestStore (id/address/distanceInMeters — Grundlage der Filial-Whitelist), // name (enthält oft "(KW29 Do-Sa)" o.ä.) und children (Liste aller Angebote // mit ihrem pageIndex, für den seiten-genauen Direktlink). -async function fetchLeafletDetail(leafletId, cache) { - if (cache.has(leafletId)) return cache.get(leafletId); +async function fetchLeafletDetail(leafletId, cache, lat = MG_LAT, lon = MG_LON) { + const cacheKey = `${leafletId}:${lat}:${lon}`; + if (cache.has(cacheKey)) return cache.get(cacheKey); const empty = { id: leafletId, name: '', closestStore: { id: null, address: '', distanceMeters: null }, children: [] }; try { - const url = `https://api.marktguru.de/api/v1/leaflets/${leafletId}?as=mobiledetailed&latitude=${MG_LAT}&longitude=${MG_LON}&zipCode=${MG_ZIP}`; + const url = `https://api.marktguru.de/api/v1/leaflets/${leafletId}?as=mobiledetailed&latitude=${lat}&longitude=${lon}&zipCode=${MG_ZIP}`; const res = await fetch(url, { headers: mgHeaders }); - if (!res.ok) { cache.set(leafletId, empty); return empty; } + if (!res.ok) { cache.set(cacheKey, empty); return empty; } const json = await res.json(); const store = json.closestStore; const result = { @@ -199,11 +200,11 @@ async function fetchLeafletDetail(leafletId, cache) { children: json.children || [], }; console.log(`🍺 KöPi: Leaflet ${leafletId} ("${result.name}") → closestStore: ${store ? `id=${store.id} "${store.address}" (${Math.round(store.distanceInMeters||0)}m entfernt)` : 'keine'}`); - cache.set(leafletId, result); + cache.set(cacheKey, result); return result; } catch (e) { console.log(`🍺 KöPi: Leaflet-Detail-Abruf für ${leafletId} fehlgeschlagen: ${e.message}`); - cache.set(leafletId, empty); + cache.set(cacheKey, empty); return empty; } } @@ -276,7 +277,7 @@ async function resolveLocalStores() { let found = null; for (const l of leaflets) { if (!l.mainLeafletId) continue; - const detail = await fetchLeafletDetail(l.mainLeafletId, cache); + const detail = await fetchLeafletDetail(l.mainLeafletId, cache, target.lat || MG_LAT, target.lon || MG_LON); const store = detail.closestStore; if (store.id != null && addressesMatch(store.address, target.addressMatch)) { found = store; @@ -587,7 +588,7 @@ async function scrapeProspekte() { const leaflets = await fetchLeafletsForRetailer(target.uniqueName); for (const f of leaflets) { if (!f.mainLeafletId) continue; - const detail = await fetchLeafletDetail(f.mainLeafletId, leafletCache); + const detail = await fetchLeafletDetail(f.mainLeafletId, leafletCache, target.lat || MG_LAT, target.lon || MG_LON); const store = detail.closestStore; const weekInfo = weekInfoWithFallback(detail.name, f.validFrom); // Store-spezifische Bezeichnung aus der Whitelist bevorzugen (z.B. "Netto