Hero mit Farbverlauf, großer Headline, primärer CTA-Button. 4 Feature-Abschnitte
(Tagebuch, Gesundheit, Community, Training). Privacy-Block in Primärfarbe.
Feature-Grid als "und noch mehr". Zweiter CTA am Ende. Eingeloggte sehen
weiterhin die kompakte Ansicht.
qrcode.min.js (qrcodejs) lazy geladen; QRCode.CorrectLevel.H damit Logo-Overlay
(icon-180.png, 36px) den Code noch lesbar lässt; App.loadScript() public gemacht.
Klick auf "Installationsanleitung" in Settings navigiert jetzt mit params
{ install: true }, welcome.js zeigt die Karte auch bei bereits installierter
PWA und scrollt direkt dorthin.
- 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
Neue Notiz-Buttons:
- Tagebuch: in der Detail-Ansicht (nicht Edit-Form)
- Trainingspläne: im Plan-Header pro Plan
- Freunde: in jedem Freund-Karten-Bereich
- Giftköder: in jedem Meldungs-Karten (private Umstände)
- Verlorener Hund: in jedem Eintrag
Notizblock:
- 4 neue RUBRIKEN: trainingsplan, friends, poison, lost
- Datenschutz-Hinweis: "Alle Notizen sind privat"
- lock-simple Icon zum Sprite hinzugefügt
Alle <i class="ph ph-..."> durch <svg class="ph-icon"><use href="...">
ersetzt. Neue Icons: magnifying-glass, spinner-gap, warning-circle, note.
Spin-Animation für Ladeindikator. Search-Icon-CSS auf width/height.
poison.js: nur noch Polizei 110 + Button → Erste Hilfe (Tab lebensgefahr)
erste-hilfe.js: init() akzeptiert params.tab zum direkten Tab-Sprung
SW by-v414, APP_VER 393
Cache-First für app.js führte dazu dass iOS im normalen Safari-Tab
den alten APP_VER servierte → alte Seiten-Skripte wurden geladen.
Alle Kern-JS-Dateien sind jetzt Network-First wie CSS und Seiten-Module.
SW by-v413, APP_VER 392
iOS prüft im Standalone-Modus nicht automatisch ob ein neuer SW vorliegt.
reg.update() erzwingt die Prüfung beim App-Öffnen und beim Zurückkehren
aus dem Hintergrund — der bestehende controllerchange→reload greift dann.
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
Wenn der erste Scan 0 OSM-Marker liefert (Cache leer, Hintergrund-Fetch
läuft), automatisch nach 20 Sekunden nochmal scannen. User muss die
Karte nicht manuell verschieben um Marker zu sehen.
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.