diff --git a/backend/src/tools/koepi/routes.js b/backend/src/tools/koepi/routes.js index 61d61a0..382e790 100644 --- a/backend/src/tools/koepi/routes.js +++ b/backend/src/tools/koepi/routes.js @@ -116,11 +116,35 @@ async function fetchOffersViaApi() { } const json = await res.json(); - // Diagnose: rohe Struktur des ersten Treffers loggen, damit sich Feldnamen - // (z.B. für eine echte Store-Adresse) im Zweifel nachträglich anpassen lassen console.log('🍺 KöPi API: totalResults=', json.totalResults, '| results.length=', json.results?.length); if (json.results?.[0]) { - console.log('🍺 KöPi API Rohdaten (erster Treffer):', JSON.stringify(json.results[0]).slice(0, 1500)); + console.log('🍺 KöPi API Rohdaten (erster Treffer, VOLLSTÄNDIG):', JSON.stringify(json.results[0])); + } + + // Reine Diagnose (rein informativ, wirft bei Fehlschlag keinen Fehler für den + // Hauptablauf): probiert, ob der leafletflights-Endpoint zusätzliche + // Store-/Adressinfos zu den gefundenen Prospekt-Kampagnen liefert + try { + const flightIds = [...new Set((json.results || []).map(r => r.leafletFlightId).filter(Boolean))]; + if (flightIds.length) { + const flightUrl = `https://api.marktguru.de/api/v1/leafletflights?as=mobile&limit=8&zipCode=${MG_ZIP}`; + const flightRes = await fetch(flightUrl, { + headers: { + 'x-clientkey': MARKTGURU_CLIENT_KEY, + 'x-apikey': MARKTGURU_API_KEY, + 'Accept': 'application/json', + }, + }); + console.log('🍺 KöPi leafletflights-Diagnose: HTTP', flightRes.status); + if (flightRes.ok) { + const flightJson = await flightRes.json(); + console.log('🍺 KöPi leafletflights-Diagnose Rohdaten (VOLLSTÄNDIG):', JSON.stringify(flightJson).slice(0, 4000)); + } else { + console.log('🍺 KöPi leafletflights-Diagnose Body:', (await flightRes.text().catch(()=>'')).slice(0, 500)); + } + } + } catch (diagErr) { + console.log('🍺 KöPi leafletflights-Diagnose fehlgeschlagen (ignoriert):', diagErr.message); } return (json.results || []).map(r => { @@ -130,18 +154,21 @@ async function fetchOffersViaApi() { const oldPriceNum = typeof r.oldPrice === 'number' ? r.oldPrice : parseFloat(r.oldPrice); const realAddress = [store.street, store.streetNumber].filter(Boolean).join(' ').trim() || store.address || advertiser.address || ''; + const validity0 = r.validityDates?.[0] || {}; return { name: r.description || r.title || advertiser.name || '', brand: r.brand?.name || '', price: Number.isFinite(priceNum) ? `€ ${priceNum.toFixed(2).replace('.', ',')}` : (r.price || ''), oldPrice: Number.isFinite(oldPriceNum) ? `€ ${oldPriceNum.toFixed(2).replace('.', ',')}` : (r.oldPrice || ''), retailer: advertiser.name || '', - dateRange: r.validFrom && r.validUntil ? `${formatIsoDate(r.validFrom)} - ${formatIsoDate(r.validUntil)}` : formatIsoDate(r.validUntil), + dateRange: validity0.from && validity0.to ? `${formatIsoDate(validity0.from)} - ${formatIsoDate(validity0.to)}` : formatIsoDate(validity0.to), validity: '', description: r.description || '', badge: '', address: '', realAddress, + leafletFlightId: r.leafletFlightId || null, + offerId: r.id || null, image: r.image?.url || r.images?.[0]?.url || null, }; });