- users.founder_number: sequentielle Nummer #1-#100 (bei Registrierung mit Code oder Admin-Grant)
- Globaler Cap: max. 100 Gründer über alle Partner-Codes zusammen
- GET /api/partner/founders/stats: öffentlich — Slots, Partner-Ranking nach uses, Gründer-Galerie
- Öffentliche Seite /gruender: Fortschrittsbalken, Partner-Challenge-Leaderboard (🥇🥈🥉), Gründer-Grid
- Forum: "Gründer #42"-Badge (lila) neben Autorenname bei Threads + Antworten
- Settings: Badge zeigt "Gründer #N" statt nur "Gründer", klickbar zur /gruender-Seite
- Sidebar: "🏆 100 Gründer"-Link im Footer
- Admin-Grant: Vergabe von founder_number beim manuellen is_founder=1-Setzen
- SW by-v516, APP_VER 493
- client_time: Browser-Lokalzeit bei allen Creates mitschicken (Tagebuch, Notizen,
Forum, Verlorener Hund, Routen) — kein UTC-Versatz mehr bei Einträgen
- Gewicht-Sync: health typ=gewicht schreibt dogs.gewicht_kg, einmalige Migration
- Praxen: opening_hours + lat/lon/osm_id in tieraerzte-Tabelle, OSM-Nearby-Lookup,
Öffnungszeiten in Karte und Detailansicht
- KI-Gesundheitsbericht: alle 2 Wochen automatisch, ki_health_reports-Tabelle,
Frontend-Banner mit Archiv (letzten 5 Berichte)
- POI-Korrekturen: User schlägt Öffnungszeiten-Änderung vor, Moderatoren-Tab
genehmigt/lehnt ab, user_edited-Flag schützt vor Overpass-Überschreibung
- timeutils.py: safe_client_time() zentral für alle Routen
KI/Symptom-Check: JSON-Code-Fence stripping in ki.py, Dringlichkeit-Map mit Phosphor-Icons
Gewicht-Sync: health.js aktualisiert appState.activeDog.gewicht_kg auch bei Bearbeitung
Giftköder: icon:'check-circle' → UI.icon('check-circle') in emptyState-Call
Forum-Pills: overflow:hidden + text-overflow:ellipsis auf Desktop und Mobile
Moderation: Admins für Moderatoren unsichtbar, keine Aktions-Buttons auf Admins
Notizblock: Filter-Chips wrap 2-zeilig auf Desktop (min-width:1024px)
Tagebuch: Datenschutz-Hinweis "nur du kannst sie sehen", Sitter sieht keine bestehenden Einträge
diary.py: Sitter-Zugriff gibt leere Liste zurück (GET), Erstellen bleibt erlaubt
Retry-Limit verhindert Endlos-Loop. Delay wächst (30s→60s→90s) damit
mehr Tiles gecacht sein können. Kartenbewegung setzt Counter zurück.
_fetching-Set im Backend verhindert parallele Doppel-Requests pro Tile.
SW by-v407, APP_VER 387
406 von overpass-api.de wird durch fehlenden Referer-Header ausgelöst,
nicht durch einen zeitbasierten IP-Ban. Mit Referer: https://banyaro.app/
antwortet der Server sofort mit 200. OVERPASS_HEADERS enthält jetzt
User-Agent + Referer.
asyncio.create_task ohne gespeicherte Referenz wird vom Garbage Collector
sofort gelöscht bevor der Task läuft (dokumentiertes Python-Verhalten).
Fix: _bg_tasks-Set hält Referenz bis done_callback sie wieder entfernt.
BackgroundTasks wurde nicht ausgeführt (Bug in der Starlette-Integration).
asyncio.create_task() plant den Overpass-Fetch direkt im Event-Loop ein,
Argumente explizit übergeben statt Closure um Capture-Probleme zu vermeiden.
Stale-Tile-Fetches blockierten den HTTP-Request minutenlang → _overpassActive
blieb auf true → Frontend-Scan konnte nicht neu starten.
Fix: BackgroundTasks statt await — /pois antwortet sofort mit DB-Daten,
Overpass-Fetch läuft im Hintergrund. Beim nächsten Kartenschwenk sind
die frisch gecachten Tiles dann verfügbar.
Semaphore 2→1 (nur 1 gleichzeitige Anfrage), 2s Mindestabstand,
User-Agent mit App-Name und Kontakt — Standard-Höflichkeit für
Community-Dienste wie kumi.systems.
23.500 Overpass-Anfragen täglich haben die Server-IP geblockt (406).
Fix: OSM-Cache füllt sich nur noch on-demand wenn Nutzer die Karte benutzen.
CACHE_DAYS auf 90 erhöht damit selten besuchte Bereiche länger frisch bleiben.
overpass-api.de und lz4.overpass-api.de blockieren die Server-IP mit 406.
OVERPASS_URLS-Liste mit Fallback: kumi → lz4 → overpass-api.de.
_fetch_overpass probiert jede Instanz, springt bei 4xx-Fehler zur nächsten.
- ki_daily_calls: PK auf (user_id, date, source) erweitert + Index; Migration
baut Tabelle mit neuer Struktur neu auf, behält Altdaten als 'cloud'
- ki.py: return_source=True-Parameter gibt (text, 'cloud'|'local') zurück
- training.py: ki_source aus ki.complete() auslesen, in DB speichern
- social.py: _ki_complete_tracked() zählt Luna-Anfragen mit source='luna';
alle Content-Endpoints (generate, evaluate, training-tip, breed-of-day,
pflege-tipp) nutzen tracking-Variante
- admin.py: Stats aufgeteilt in ki_cloud/ki_local/ki_luna je heute+Monat
- admin.js: KI-Karte zeigt 9 Zeilen mit ☁️ Claude / 🖥️ LM Studio / 🌙 Luna
- SW by-v359, APP_VER 344
- Backend: routes/moderation.py mit GET /stats, /reports, /users, /fotos
und PATCH-Endpoints für Ban/Unban und Foto-Review
- Frontend: pages/moderation.js mit 4 Tabs (Übersicht, Fotos, User, Forum)
- Sidebar-Eintrag (nur für Moderatoren/Admins sichtbar, gelb)
- Page in index.html registriert, pages-Objekt in app.js ergänzt
- Router in main.py eingebunden (/api/moderation)
- SW-Cache by-v357, app.js/ui.js/api.js auf v=94