Worktree-Verlust-Audit: alle Geister-Endpoints gefunden + Regressions-Test

Systematischer Abgleich aller 528 Frontend-API-Aufrufe gegen 576 Backend-
Routen (methodengenau, Wildcard-Matching für Parameter):

Echte Opfer (zusätzlich zu partner/* und breeder/my-editor):
- worlds.js Nearby-Alerts riefen /poison/nearby + /lost/nearby auf — beide
  existierten NIE; doppeltes catch verschluckte die 404s → die Welten zeigten
  seit jeher keine Giftköder-/Vermisst-Warnungen. Fix: bestehende Listen-
  Endpoints mit Geo-Filter nutzen (/poison?radius=Meter, /lost?radius_km).
- API.weather.alerts → /weather/alerts existierte nie, hatte aber auch keinen
  Aufrufer — toter Wrapper entfernt.

False Positives geprüft: invoices (Router bringt eigenen Prefix mit, alle 9
Routen ok), Seiten↔Dateien↔window.Page_*↔index.html-Sections alle konsistent.

Neu: tests/test_api_surface.py — statischer API-Oberflächen-Abgleich als
Dauertest; Geister-Aufrufe sind ab jetzt Build-Fehler. Suite: 59 passed.
This commit is contained in:
rene 2026-06-07 20:22:20 +02:00
parent 487dacc7c7
commit 8c76263ea0
8 changed files with 136 additions and 19 deletions

View file

@ -492,7 +492,7 @@ const API = (() => {
// WETTER
// ----------------------------------------------------------
const weather = {
alerts(lat, lon) { return get(`/weather/alerts?lat=${lat}&lon=${lon}`); },
// alerts() entfernt — /weather/alerts existierte im Backend nie (459cd42), kein Aufrufer
get(lat, lon) { return get(`/weather?lat=${lat}&lon=${lon}`); },
forecast(lat, lon) { return get(`/weather/forecast?lat=${lat}&lon=${lon}`); },
};

View file

@ -3,7 +3,7 @@
Router, State-Management, Navigation, Initialisierung.
============================================================ */
const APP_VER = '1267'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
const APP_VER = '1268'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
const APP_VERSION = '1.6.0'; // ← semantische Version, wird bei make release gesetzt
window.APP_VER = APP_VER; // global verfügbar für andere Module (z.B. offline-indicator)
window.APP_VERSION = APP_VERSION;

View file

@ -1857,9 +1857,12 @@ window.Worlds = (() => {
const out = [];
try {
const pos = await API.getLocation({ timeout: 4000, maximumAge: 600_000 });
// /poison + /lost filtern per lat/lon serverseitig (poison: Radius in METERN,
// lost: radius_km). Die früheren /nearby-Pfade existierten nie (459cd42-Verlust)
// — das doppelte catch hat den 404 jahrelang verschluckt.
const [p, l] = await Promise.allSettled([
API.get(`/poison/nearby?lat=${pos.lat}&lon=${pos.lon}&radius=5`).catch(() => []),
API.get(`/lost/nearby?lat=${pos.lat}&lon=${pos.lon}&radius=20`).catch(() => []),
API.get(`/poison?lat=${pos.lat}&lon=${pos.lon}&radius=5000`).catch(() => []),
API.get(`/lost?lat=${pos.lat}&lon=${pos.lon}&radius_km=20`).catch(() => []),
]);
if (p.value?.length) out.push({ icon:'skull', color:'#EF4444', title:'Giftköder in der Nähe', sub:`${p.value.length} Meldung${p.value.length>1?'en':''}`, page:'poison' });
if (l.value?.length) out.push({ icon:'dog', color:'#3B82F6', title:'Verlorener Hund', sub:`${l.value.length} Meldung${l.value.length>1?'en':''}`, page:'lost' });