Commit graph

1106 commits

Author SHA1 Message Date
21f54f478b Fix: partner_profiles Alt-Schema-Migration — Tabelle aus verlorener v1102-Session existiert auf Staging/Prod (photos statt photos_json); Umbau mit Datenübernahme 2026-06-07 17:22:59 +02:00
ce8aa2b699 Feature: Partner-Profile Backend + Pro-Zugang für Partner
Die Partner-Showcase-Seite (#partner) und der Profil-Editor (#partner-profil)
existierten seit v1102 nur als Frontend — /api/partners/public und
/api/partner/my-profile gab es nie (vermutlich Worktree-Merge-Verlust).

Backend neu:
- partner_profiles-Tabelle (user_id PK, ON DELETE CASCADE → DSGVO-Delete greift)
- GET/PUT /partner/my-profile (Texte, Website-Normalisierung, @-Instagram)
- Logo-Upload (≤5 MB → WebP 512px, altes Logo wird geräumt)
- Foto/Video-Upload (max 6, 200-MB-Budget, HEIC→JPEG, MOV→MP4 via ffmpeg,
  Bilder→WebP 1600px) + Lösch-Endpoint
- Submit-Workflow (approved 0/1/-1) + Admin-Mail (best effort)
- GET /partners/public (nur freigegebene, JOIN users für Name/Avatar)
- Admin: GET /admin/partner/profiles + POST .../review

Pro für Partner: has_pro_access() + App._hasPro() prüfen jetzt is_partner —
Multiplikatoren bekommen Pro gratis (mehrere Hunde, KI-Trainer etc.).

UI: Admin-Partner-Tab mit Freigabe-Sektion (offen-Badge, ✓/✗),
Settings zeigt Partnern eine Karte mit Link zum Profil-Editor.

Tests: tests/test_partner_profile.py — 5 Smoke-Tests (403, Voll-Flow
inkl. Freigabe/Ablehnung, Pflicht-Anzeigename, Logo+Foto-Upload, Pro-Zugang).
Suite: 44 passed.
2026-06-07 17:20:20 +02:00
178aef7fb0 Fix: Design-System-Regression v1102 — .hidden(!important) vs style.display app-weit
Rene: 'Tagebuch Kalenderansicht/Karte nicht mehr da' — Root-Cause: 459cd42
ersetzte style="display:none" durch class="hidden", aber die Show-Pfade
setzten weiter style.display. .hidden hat !important und gewinnt immer
(gleiche Klasse wie Filter-Panel-Hotfix v1242). Prod-Logs bewiesen: kein
einziger /diary/calendar- oder /locations-Request kam je an.

Unsichtbar seit v1102, jetzt per classList gefixt:
- diary: Stats-Bar mit View-Switcher (Liste/Medien/Kalender/Karte) + Medien-Grid neuer Eintrag
- health: KI-Tierarzt-Ergebnis erschien nie
- walks: Challenge-/Stamm-Gassi-Tabs leer
- welcome: iOS-Panel der Desktop-Install-Anleitung
- wiki: Fotos-Mod-Badge + Foto-Fallback (via app.js data-fb show-el/sibling-Handler)
- routes: Filter-Badge; breeder: Fotos-Section

Zweite Fehlerklasse aus demselben Sprint: doppelte class-Attribute
(class="x" id=… class="hidden") — Browser verwirft das zweite Attribut.
87 Vorkommen in 23 Dateien zusammengeführt; betroffene Show/Hide-Pfade
(ev-map, rk-mine/nearby-group, chat-partner-dot, eh-panel, zh-section)
auf classList umgestellt.
2026-06-07 15:09:43 +02:00
5acbaaa97b Landing: 'ohne App Store'-Formulierungen entschärft (3.1.1-Trigger) — PWA-Pitch jetzt 'direkt im Browser' 2026-06-07 11:03:36 +02:00
6d9a04fd10 Navi: Fenster-Index statt globaler Suche — Loop-Routen brachen Bellen/Fortschritt/Gruen
Praxistest Rene (Gassirunde Siegenhofen, Loop Start=Ende): _closestIdx suchte
GLOBAL -> am Start war der END-Index genauso nah -> Fortschritt sprang ans
Track-Ende: nie Abbiege-Bellen (keine Turns mehr 'vor' einem), done-Linie
malte sofort alles gruen, 99%.
- _closestIdx: Fenster um den aktuellen Index (-15/+80), global nur beim
  ersten Fix (mit Start-Praeferenz bei Quasi-Gleichstand <25m) oder wenn
  verloren (>300m). Simulation auf der echten Route: 13/13 Turns feuern
  bei 41-49m Vorlauf.
- Gelaufener Weg als BREADCRUMB: gruen = auf der Route, rot = daneben
  (Segment-Wechsel nahtlos); done-Linie (Track-Slice-Malen) entfernt —
  nie gelaufene Abschnitte bleiben jetzt orange
- Off-Route-Schwelle 50->35m (Klaeffen kam ~5m zu spaet), Abbiege-Ansage 45->50m
Bump v1250
2026-06-07 08:22:02 +02:00
a31d08a2dc Karte: Blickrichtungs-Kegel (Kompass) + ruhigeres Folgen (Rene: 'weiss nicht wo es ist/hinschaut')
- Standort-Punkt zeigt jetzt einen Kompass-KEGEL (wie Google Maps): CSS-Kegel
  im loc-icon (GL + Leaflet), deviceorientation mit webkitCompassHeading (iOS)
  bzw. 360-alpha (Android), Glaettung ueber kuerzesten Winkelweg, rAF-throttled.
  iOS-Permission via User-Geste (Follow-/Standort-Button startet den Kompass).
- Follow pant nur noch bei brauchbarem Fix (accuracy < 75m) — ungenaue
  Positionen liessen die Karte zappeln; GPS-Fixes frischer (maximumAge 2s
  statt 5s). Marker aktualisiert weiterhin jeden Fix.
Bump v1249
2026-06-06 20:30:22 +02:00
85d578874a Navi-Sounds: zurueck zu HTMLAudio mit Gesten-Priming — WebAudio war stummschalter-stumm
Prod-Befund Rene: kein Ton. Ursache: v1244-Umbau auf AudioBuffer/WebAudio —
der respektiert den iOS-STUMMSCHALTER (= Gassi-Normalzustand) -> Stille.
HTMLAudio spielt wie Medien trotz Stummschalter (deshalb klang Staging v1243
richtig). Den urspruenglichen Lazy-Load-Bug loest jetzt GESTEN-PRIMING:
im unlock() stumm anspielen (play+pause, muted) = Wiedergabe-Erlaubnis fuer
spaetere gestenlose Ansagen + erzwingt das Laden. readyState>=2-Check,
Synthese bleibt Fallback.
Bump v1248
2026-06-06 20:24:35 +02:00
0d976b90b7 Karte: Bewegungs-Gate fuer den POI-Scanner — Follow-Mode triggerte ihn laufend
Rene: aktiviertes Crosshair pannt alle paar Sekunden -> jedes moveend
startete den Scan. Scans aus KARTENBEWEGUNG laufen jetzt erst, wenn sich
das Zentrum >= 20% der Viewport-Breite bewegt hat oder der Zoom wechselt
(bei Z16 ~ alle 100-150m Fussweg). Alle anderen Trigger (Marker
gespeichert, Layer-Toggle, Retry, Init, Scan-Queue) ungebremst.
Bump v1247
2026-06-06 20:07:23 +02:00
fc55943e90 Karte: Follow-Crosshair zwischen Zoom-Reglern und Offline-Puls-Icon (Rene)
position:fixed + safe-area (+70px) wie das Offline-Icon (+110px) statt
absolute im Karten-Container — sitzt jetzt exakt in der Luecke; Offline-
Puls bleibt unveraendert an seinem Platz.
Bump v1246
2026-06-06 20:04:49 +02:00
f4f597edf8 Karte: Follow-Button (Crosshair) wie in Routen — ein Tipp folgt dem Standort
Wunsch Rene: sichtbarer Follow-Schalter direkt auf der Karte statt nur ueber
das Speed-Dial. Crosshair links unter den Zoom-Reglern (unterhalb des
Offline-Puls-Icons): Tipp = zentrieren + folgen (Button farbig), Karte
ziehen = pausiert (grau). Synchron mit Standort-Speed-Dial-Button und
Aufzeichnungs-Start (beide aktivieren Follow ebenfalls).
Bump v1245
2026-06-06 19:58:56 +02:00
448066567d Navi-Sounds: AudioBuffer statt HTMLAudio — echtes Gebell zuverlaessig ab dem ersten Wuff
HTMLAudio+preload laedt auf iOS lazy (canplaythrough feuert nie) und verlor
beim ersten Einschalten das Rennen gegen den Probe-Wuff -> Game-Boy-Fallback.
Jetzt: fetch + decodeAudioData in den bestehenden AudioContext (praezises
Timing via BufferSource, offline via SW-Precache); Probe-Wuff 450ms verzoegert.
Synthese bleibt Fallback bei 404/Decode-Fehler.
Bump v1244
2026-06-06 19:55:44 +02:00
2042a3f513 Routenvorschlaege: Schwierigkeit aus Distanz+Hoehenmetern + Yaro-Navi mit echtem Gebell
Schwierigkeit (Wunsch Rene): ORS elevation=true -> ascent; leicht <4km & <50hm,
mittel <=7km & <150hm, sonst anspruchsvoll (vorher NUR km — flache 6km galten
als 'anspruchsvoll'). ACHTUNG: elevation=true codiert die Polyline 3D —
eigener _decode_polyline3d (Roundtrip-getestet), Track enthaelt jetzt alt;
Hoehenmeter im Vorschlag als Pill ('X hm') + in der API (hoehenmeter).

Navi-Sounds: echtes Schaeferhund-Gebell (Renes Aufnahme zugeschnitten):
/sounds/wuff.mp3 (0,34s Einzel-Beller, 2x=links 1x=rechts) +
/sounds/klaeffen.mp3 (2,8s Sequenz, falscher Weg — spielt 1x statt 4x);
mono, loudnorm -14 LUFS, Fades. /sounds-Mount (main.py), SW-Precache
(bellt auch im Funkloch). Synthese bleibt Fallback.
pytest 39 passed. Bump v1243
2026-06-06 19:51:20 +02:00
0967623342 Hotfix: Routen-Filter oeffnete nicht — .hidden hat !important, style.display verlor immer
Kaputt seit 27a3f95 (2026-06-05, 'Filter standardmaessig zu' setzte die
hidden-KLASSE ins Markup, der Toggle blieb aber auf style.display='').
.hidden = display:none !important (design-system.css) -> Klick wirkte nie.
Import funktionierte weiter (Label+File-Input nativ) — dadurch gemeldet
als 'Filter geht nicht mehr' (Angie + Rene).
Fix: classList.toggle('hidden') im Toggle + konsistent im Suggest-Tab.
Bump v1242
2026-06-06 19:05:34 +02:00
ca23b3ec46 Navi-Sounds: 2x Wuff = links, 1x Wuff = rechts, Klaeffen = falscher Weg (Idee Rene)
- NavSound (routes.js): WebAudio-Wuff-Synthese (Saegezahn-Sweep + Tiefpass,
  kein Asset, laeuft offline); echte Aufnahmen unter /sounds/wuff.mp3 +
  klaeffen.mp3 (z.B. von Yaro) werden automatisch bevorzugt
- Abbiege-Erkennung: Turns einmalig aus dem Track (Peilung ueber 15-m-
  Stuetzpunkte gegen GPS-Zickzack, >=40 Grad), Ansage bei <=45 m davor,
  einmal pro Abbiegepunkt
- Falscher Weg (>50 m, bestehende Warnung): Klaeffen beim Abkommen +
  Erinnerung alle 30 s; zurueck auf Route reset
- Toggle im Navi-Header (Lautsprecher-Icon, by_nav_sound, Default AN),
  iOS-Audio-Unlock beim Navi-Start + Toggle (Probe-Wuff als Bestaetigung)
Bump v1241
2026-06-06 18:57:20 +02:00
a1b2644cce DWD-PoC: Binaer-Artefakte aus dem Repo (nur decode_poc.py bleibt) 2026-06-06 18:34:41 +02:00
502f0f4921 DWD-Compose: container_name entfernt — Staging+Prod teilen den Docker-Host (Namenskonflikt) 2026-06-06 18:33:05 +02:00
6565d6a999 DWD-Pipeline: Dauer-Container mit 5-Min-Schleife statt DSM-Cron
DSM-Aufgabenplaner kann minimal stuendlich (Rene) — Container laeuft jetzt
dauerhaft (restart: unless-stopped) mit interner Schleife (loop.sh, idle =
sh+sleep, Python/GDAL nur waehrend des Laufs). Einmal 'up -d --build',
ueberlebt Reboots. make_radar_tiles.py ist idempotent, Fehler brechen die
Schleife nicht.
2026-06-06 18:21:52 +02:00
e6558b64d3 DWD-Plan: Umsetzungsstand dokumentiert (Staging v1240, Cron + Geraetetest offen) 2026-06-06 18:13:30 +02:00
5330681059 DWD-Regenvorhersage: Pipeline + /radar-Route + Timeline-Integration + Settings-Toggle
PoC BESTANDEN (tools/dwd-radar/poc): Anker (9E,51N) = Pixel-Mitte (470/600),
Ecken decken sich mit der DWD-DE1200-Spec — Georeferenzierung bewiesen.
- tools/dwd-radar: RV-Komposit (25 Frames, 0-120min) -> kolorierte RGBA-
  PMTiles z4-7 je Frame (MapLibre overzoomt darueber) + manifest.json,
  atomarer Swap, KEEP_RUNS-Aufraeumen; 25 Frames in ~14s lokal
- docker-compose.dwd.yml (DSM-Cron alle 5 min, NIE --remove-orphans)
- main.py: /radar/manifest.json (no-store) + /radar/{run}/{file} (Range/206,
  immutable — Run-Id im Pfad); sw.js: /radar/ pass-through
- map.js: Radar-Frames heterogen ({url,time,dwd}) — DWD ersetzt RainViewer-
  Nowcast (0-120min, 5-min-Schritte) wenn Toggle an + GL + Karte in DE +
  Manifest frisch (<30min); sonst RainViewer-Fallback; Label '+X Min - DWD'
- settings.js: Toggle 'DWD-Regenvorhersage' (by_dwd_radar, Default AN)
- pytest 39 passed
Bump v1240
2026-06-06 18:08:57 +02:00
6a06c9be7e POI-Bewertung: Live-Praesenz zaehlt als GPS-Beleg (Rene stand am Ort, wurde abgewiesen)
Vorher zaehlte NUR eine aufgezeichnete Tour der letzten 48h (<=50m am POI,
>=2 Punkte) — die aktuelle Geraeteposition floss gar nicht ein.
- DogFriendlyIn: optional user_lat/user_lon (Frontend schickt _userPos mit)
- Beleg-Weg a): Geraetestandort <= 75m am POI (50m Radius + GPS-Toleranz)
  -> route_id=None markiert Live-Beleg; Weg b) Tour-Beleg unveraendert
- Fehlermeldung nennt jetzt beide Wege (hin gehen ODER Standort aktivieren)
- pytest 39 passed
Bump v1239
2026-06-06 17:26:20 +02:00
abd7447d29 Karte: Follow-Mode + Live-Strecke bei Routen-Aufzeichnung (Wunsch Rene)
- MapGLMini-Polyline hatte KEIN addLatLng (nur setLatLngs) -> TypeError im
  Rec-Overlay: Strecke unsichtbar, Marker fror ein, kein Folgen. Facade
  ergaenzt (Leaflet-kompatibel).
- Rec-Overlay (routes.js): Follow-Mode default AN — Karte wandert mit dem
  Standort, Drag pausiert, Crosshair-Button (unten rechts) reaktiviert;
  erster Fix setzt Zoom 16, danach bleibt der Zoom erhalten
- Zentrale Karte (map.js): Standort-Button aktiviert Follow (+Toast),
  dragstart beendet es (beide Engines); GPS-Tracking folgt sanft (easeTo);
  Aufzeichnung startet im Follow-Mode, _updateRecMap pant nur noch im Follow
Bump v1238
2026-06-06 17:20:38 +02:00
2cdb743ce7 Selektives Loeschen: auch Funkloch-Gebiete bleiben + Keep-Set haertung
Rene: Funkloecher + Routen waren nach 'Alles loeschen' weiter weg.
- Funkloch-Regionen jetzt im Keep-Set (geloescht wird NUR Manuelles);
  Zonen behalten ihren Fuellstatus (Komplett-Wipe setzt weiter zurueck)
- Korridor-Migration beim Loeschen: keepTracks=[{name,track}] schreibt
  Tracks in Alt-Eintraege ohne r.track (Bestand vor v1236) bzw. legt
  fehlende Korridor-Regionen an — kein Warten auf Self-Healing
- clear() liefert Summary; Toast zeigt 'behalten: Standort, X Routen,
  Y Funkloch-Gebiete' — Diagnose-Sichtbarkeit fuer Geraetetests
Bump v1237
2026-06-06 13:55:37 +02:00
ca97613938 Fix: Selektives Loeschen griff auf Geraet nicht — Keep-Set jetzt selbsttragend aus der Meta
Renes Befund: 'Alles loeschen' wischte weiter alles. Ursachen: (a) Bestands-
Gebiete hatten keine standort-Region (ensureHomeArea legt nur bei FEHLENDER
Kachel los), (b) Korridor-Keys waren nur aus API-Tracks ableitbar -> leeres
Keep-Set = Komplett-Wipe.
- downloadCorridor speichert vereinfachten Track (<=60 Pkt) in der Region-Meta;
  clear() baut Korridor-Keep daraus — ohne API/Login/GPS
- Standort-ADOPTION: clear() mit center legt fehlende standort-Region
  synthetisch an (Bestandsdaten vor Runde 6)
- map.js: center-Fallback auf by_last_position wenn GPS noch keinen Fix hat
- Test r7 erweitert (clear ohne Optionen haelt Korridor aus Meta), alle gruen
Bump v1236
2026-06-06 13:44:01 +02:00
29cd489287 Offline-Karten Runde 7: 'Alles loeschen' selektiv — Standort + Routen-Korridore bleiben
Idee Rene (spart Vorladezeit + Daten): statt loeschen-und-neu-laden bleiben
- Standort-Gebiete (Regionen type 'standort')
- Korridore der gespeicherten Routen (clear({keepTracks}) aus preview_track)
- 5-km-Umkreis der aktuellen Position + Basis-Zooms 0-9
- Marker/Warnungen (p/) + Glyphs (f/)
Geloescht: manuelle Gebiete/Ausschnitte + Funkloch-Kacheln (Zonen bleiben
gemerkt, Nahe laden automatisch neu). Ohne Keep-Kandidaten: Komplett-Wipe.
Batch-Delete in einer Transaktion. Tests r7 neu, r6 angepasst, Regression gruen.
Bump v1235
2026-06-06 13:35:18 +02:00
94a6ce49ba Offline-Karten Runde 6: Standort-Grundversorgung — aktuelles Gebiet bleibt immer geladen
Renes Modell Punkt 1 war zu eng interpretiert (nur Funkloecher): das Gebiet
um die aktuelle Position gehoert zur Grundversorgung.
- ensureHomeArea(lat,lon): Zentrums-Kachel-Check -> bei Luecke Budget-Download
  (type 'standort', Cap-gated)
- Start-Check: Standort raw pruefen (ohne GL-Stack) und bei Bedarf laden
- 'Alles loeschen': Standort-Gebiet wird SOFORT neu geladen (+ Toast) —
  vorher war die Offline-Funktionalitaet genau am wichtigsten Ort weg
- Pfote Segment 5: Standort-Kachel da UND Zonen im 50-km-Umkreis gefuellt
  (ferne Zonen zaehlen nicht mehr — sie laden erst vor Ort)
- Tests r6 + Regression r1/r3/r4/r5 gruen
Bump v1234
2026-06-06 13:23:33 +02:00
97f0518c54 SW: Versions-Update reisst kein Offline-Loch mehr (Cache-Carry-Over + GL-Stack-Precache)
Geraetetest: Karte offline 'nicht verfuegbar' obwohl Pfote ready zeigte —
activate loeschte die alten Static-Caches, waehrend der neue erst im
Hintergrund befuellt wurde; der GL-Stack (maplibre/pmtiles/map-offline)
war zudem nie im Precache, nur nach erster Online-Kartenoeffnung.
- activate: _migrateStaticCaches uebernimmt fehlende Eintraege der alten
  Caches unter nacktem Key (Online-Refresh ueberschreibt sie sauber),
  DANN erst loeschen
- PRIORITY_PAGES + GL-Karten-Stack (maplibre-gl.js/.css, pmtiles,
  map-gl-style, map-offline, map-gl-markers, map-gl-mini)
- generischer Cache-First-Pfad: ignoreSearch-Fallback fuer eigene /js/+/css/
  (?v=APP_VER zeigt sonst am Carry-Over/bare-Bestand vorbei)
Bump v1233
2026-06-06 13:14:37 +02:00
a914101c5b SW: Shell-Assets nach 2,5s aus dem Cache statt endlos aufs Netz warten
Bei schwachem Empfang blieb die App beim Start SEHR LANGE weiss: CSS +
Kern-JS + index.html waren Network-First OHNE Timeout — der Cache griff
nur bei hartem Fetch-Fehler, nicht bei troepfelnder Verbindung.
Jetzt: Promise.race(Netz, 2,5s) -> Cache-Fallback (stale-while-revalidate,
Netz aktualisiert den Cache im Hintergrund weiter). Versions-Updates laufen
weiter ueber x-app-version + controllerchange.
Bump v1232
2026-06-06 13:05:34 +02:00
6c313aca05 Offline-Karten Runde 5: Geraetetest-Feedback (Indikator, Flugmodus-Signal, Ent-Funklochen, Warnungs-Aktualitaet, Routen-Start-Check)
- Indikator links unter die Zoom-Regler (rechts verdeckte Legenden-Chips)
- Flugmodus bei offener App -> Position raw als Funkloch-Zone (offline-Event)
- Ent-Funklochen: Zonen-Liste im Offline-Modal mit X (removeDeadZone)
- Warnungs-Aktualitaet: _mergeStore Bbox-Replace (aufgehobene Giftkoeder/
  gefundene Hunde verschwinden; Fetch-Kreis deckt Bbox via sqrt2 ab;
  fresh=null merged nie) + 24h-Refresh im 50km-Umkreis beim Start
- Routen offline nutzbar halten: ensureRouteCorridors beim Start-Check
  (Stichproben-Verify, Re-Download aus preview_track, Region-Dedupe)
- Stub-Tests ins Repo: tests/js/ (r1/r3/r4/r5, alle gruen)
Bump v1231
2026-06-06 13:00:20 +02:00
53bc27faa3 Offline-Karten Runde 4: Minimal-Speicher-Modell (Modell Rene)
Funkloch-Gedaechtnis = Quelle der Wahrheit, Kacheln = ableitbarer Cache:
- Ephemeres Vorausladen: Prefetch-Kacheln werden bei Aufzeichnungsende
  geloescht, wenn die Runde kein Funkloch hatte (nur neue Keys)
- Netz-Probe bei Aufzeichnung (~2min, 6s-Timeout): erkennt Funkloecher auch
  in bereits gespeicherten Gebieten (dort kein Remote-Miss als Signal)
- clear() behaelt Zonen (filled=false) -> naechster Online-Start laedt
  Funkloch-Gebiete automatisch neu, auch nach 'Alles loeschen'
- Start-Check mit Position: nur Zonen im 50-km-Umkreis, naechste zuerst,
  Coverage-Verify (faengt Eviction ab); Pfote Segment 5 = alle Zonen gefuellt
- Coverage-Layer zweifarbig: Funkloch orange, manuell blau + Modal-Legende
- Stub-Tests Runde 4 (Prune/Probe/clear/Naehe/Verify/Faerbung) bestanden
Bump v1230
2026-06-06 12:46:12 +02:00
763108fa7c Offline-Karten Runde 3: Puls-Icon, rollendes Vorausladen, Ausschnitt-Download, Speicher-Cap
- Offline-Indikator: pulsierendes 32px-Icon oben rechts (unter Kopfzeilen-Hoehe)
  statt Leiste ueber die volle Breite — verdeckte '<- Zurueck' in der
  Routennavigation (Geraetetest Rene)
- Rollendes Vorausladen: setGps laedt alle ~400m still fehlende z14+-2-Kacheln
  um die Position — deckt den Weg schon beim ERSTEN Funkloch-Besuch ab
- Bereichsauswahl light: 'Sichtbaren Ausschnitt speichern' im Offline-Modal
  (downloadBbox, Cap 40 MB, Zu-gross-Schutz)
- Speicher-Cap 250 MB als Soft-Guard fuer automatische Pfade + totalBytes-Zaehler
  + navigator.storage.persist() best-effort; echte LRU vertagt (Refcounting noetig)
- Auto-OSM-Raster-Prefetch entfernt (manueller Leaflet-Pfad bleibt)
- Logik-Tests (Node-Stubs) fuer Bbox/Cap/Throttle/persist bestanden
Bump v1229
2026-06-06 12:34:48 +02:00
3426d2b7c8 Bump v1228 (Offline-Karten Prod-Release) 2026-06-06 12:21:15 +02:00
c18e24524a Offline-Karten: Prod-Freigabe — Flag-Default AN auf allen deployten Hosts
Geraetetests Runde 1+2 bestanden (Basemap, Marker, Giftkoeder/Lost,
Funkloch-Lernen, Korridor, Coverage). Default analog by_map_gl:
banyaro.app/.de AN, localhost AUS, localStorage/?tilesoffline uebersteuert.
2026-06-06 12:21:11 +02:00
c0561c14b2 Offline-Plan: Geraetetest-Befunde Runde 2 dokumentiert (v1227) 2026-06-06 12:17:04 +02:00
a600ca1dec Offline: Giftkoeder + vermisste Hunde offline sichtbar, Korridor auf Detailkarte
Geraetetest-Befunde Runde 2:
- Giftkoeder verschwanden offline: /api/places kam aus dem SW-Cache (feste URL)
  und verhinderte den allFailed-Fallback, waehrend /api/poison?lat=... (Bbox-URL)
  scheiterte -> jetzt faellt jede Quelle EINZELN auf den letzten guten Stand
  zurueck (localStorage) + Merge aus dem Offline-Region-Snapshot
- Region-Download speichert jetzt auch /api/poison + /api/lost der Gegend
  (p/_poison, p/_lost, anonym; MapOffline.alerts(kind,bbox) als Reader) —
  Sicherheitsdaten muessen auch am vorab gespeicherten Urlaubsort da sein
- lost.js Offline-Pfad merged den Region-Snapshot in Cache- und Leer-Fall
- Routen-Korridor war 'unsichtbar' (lag im schon gespeicherten Gebiet):
  nach dem Speichern werden die gespeicherten Bereiche blau auf der
  Detailkarte eingeblendet; Logik per Node-Stub-Test verifiziert
Bump v1227
2026-06-06 12:15:34 +02:00
42a04ec405 Offline-Karten Runde 2: adaptives Modell (Budget, Funkloch-Gedaechtnis, Korridor, Coverage)
Design Rene 2026-06-06:
- Budget-Download: z14-Ringe um den Standort bis 5 MB gespeicherte Bytes
  (Stadt klein, Land gross — passend zur Funknetzdichte); client-seitig,
  Server-Region-Extract entfaellt
- Funkloch-Gedaechtnis: Tile-Miss bei aktivem GPS-Recording -> Zone gemerkt
  (lokal, nie hochgeladen); Auto-Download offener Zonen sobald online
- Routen-Korridor: 'Offline'-Button im Routen-Detail, Kacheln +-1km um den
  Track + Marker (Cap 50 MB) — fuer mehrtaegige Unternehmungen
- Coverage-Layer: gespeicherte Bereiche als blauer Layer; Offline-Button
  oeffnet Verwaltungs-Modal (Stats, speichern, anzeigen, loeschen)
- Flag-Logik zentral in boot.js BY.offlineTiles() (war 3x dupliziert)
Bump v1226
2026-06-06 12:00:43 +02:00
45534aa8ee Sweep: r.ok-Check bei allen direkten fetch('/api/...')-Aufrufen (SW-503-JSON-Falle)
5 Fundstellen nach dem Marker-Bug-Muster (v1224) gefixt:
- landing-init.js: Stats-Zahlen waeren offline NaN geworden
- social.js: Medien-Upload-Fehler wurde verschluckt (kein ok-Check, kein catch)
- routes.js: Unterwegs-POIs — {detail:...}.filter warf statt sauber []
- map.js: Marker-Melden zeigte Erfolgs-Toast obwohl Request fehlschlug
- settings.js: Update-Check meldete offline faelschlich 'ist aktuell'
Rest geprueft: api.js-Wrapper, wiki/uebungen/trainingsplaene-Helper checken ok,
externe Dienste (Nominatim etc.) laufen nicht ueber den SW-/api/-Zweig.
Bump v1225
2026-06-06 11:42:05 +02:00
e6d6a3e697 Fix: Marker verschwanden offline beim Kartenbewegen — SW-503-JSON als Fehler werten
Der SW beantwortet nicht-cachebare API-GETs offline mit 503 + JSON-Body,
r.json() wirft dann NICHT -> Erfolgs-Pfad ersetzte Marker durch {detail:...}.
_fetchPois prueft jetzt r.ok + Array.isArray, dadurch greift der
IndexedDB-Fallback (MapOffline.pois) in Phase 1 und Phase 2 behaelt den Bestand.
Bump v1224
2026-06-06 11:35:03 +02:00
6af08ab543 Offline-Plan: Geraetetest bestanden, Befunde (Marker offline, Banner) dokumentiert 2026-06-06 11:27:31 +02:00
e2c75f04bc Offline-Karten: POI-Marker offlinetauglich + Offline-Banner klappt ein (Geraetetest-Befunde)
- MapOffline.downloadAround speichert zusaetzlich /api/osm/pois je Typ fuer die
  Region-Bbox in IndexedDB (Key-Praefix p/, Merge per id — zweite Region loescht
  die erste nicht); MapOffline.pois(type,bbox) filtert fuer den Ausschnitt
- map.js Phase-1-Fallback: Fetch fehlgeschlagen (offline) -> gespeicherte
  Region-POIs statt leerer Karte; Download-Toast zeigt Marker-Anzahl
- Offline-Banner: nach 5s auf schmale Icon-Leiste eingeklappt (verdeckte die
  Karten-Legende); Inline-Styles nach components.css konsolidiert
- Bump v1223
2026-06-06 11:25:40 +02:00
c5bdad2d86 Offline-Plan: Follow-ups Runde 1 dokumentiert (Staging-AN v1222, Runde 2 offen) 2026-06-06 11:07:42 +02:00
8e623d8909 Bump v1222 (SW-Cache fuer Offline-Follow-ups + Impressum-Fix) 2026-06-06 11:05:35 +02:00
de25901fa2 Rechtsseiten-Hash-Links bleiben in der SPA statt /info-Redirect fuer anonyme Besucher
#impressum/#datenschutz/#agb setzen jetzt by_stay_in_app — vorher schlug
_checkAuth anonym fehl und welcome.js leitete auf /info um (blitzte kurz auf).
Betraf iOS-App-Links, App-Store-Metadaten und /impressum-Pfad-Redirects.
Fix uebernommen aus banyaro-ios-Handoff (relevant fuer Build-6-Resubmit).
2026-06-06 11:05:22 +02:00
70a1f5856a Offline-Karten Follow-ups: Staging-Default AN, Karten-Download-Button, Glyph-Persistenz
- by_offline_tiles Default AN auf staging.banyaro.app (localStorage/?tilesoffline=1/0 uebersteuert)
- Speed-Dial 'Karte offline speichern': GL -> MapOffline.downloadAround(Kartenmitte, 5km),
  Leaflet -> alter Raster-Prefetch (_cacheTiles war seit FAB-Redesign verwaist)
- Glyphs in IndexedDB (Key-Praefix f/) + byt://f/-Protokoll: ueberlebt App-Updates
- OSM-Raster-Prefetch im Offline-Tiles-Modus uebersprungen (GL nutzt das Raster nicht)
- Button-Sichtbarkeit gated: GL ohne Offline-Flag (= Production) zeigt ihn nicht
2026-06-06 11:03:46 +02:00
30e82b7931 POI-Refresh: Abdeckung auf alle 15 Tile-Laender erweitert (war nur DACH)
Der monatliche DSM-Job fragte nur germany/austria/switzerland ab, die Karte
deckt aber TILES_REGIONS (DACH + 12 Anrainer) ab -> POIs fehlten ausserhalb
DACH. Laenderliste jetzt in docker-compose.osm.yml als Env gesetzt (wirkt ohne
Image-Rebuild) und als Default in refresh.sh gespiegelt.
2026-06-06 10:13:56 +02:00
695908f937 Rechtsseiten oeffentlich erreichbar: Hash-Routing ohne Login + Pfad-Redirects
- app.js init(): Hash-Route wird auch ohne Login angesteuert — vorher wurden
  anonyme Besucher IMMER auf 'welcome' geworfen, #agb/#datenschutz/#impressum
  liefen damit ins Leere (DSGVO-Problem, broken Links aus iOS-App + SEO-Footer).
  Auth-pflichtige Seiten schuetzt weiterhin der requiresAuth-Guard in navigate().
- main.py: /agb, /datenschutz, /impressum -> 302 auf die SPA-Hash-Routen
  (vor dem SPA-Fallback registriert)
- make bump: v1221
2026-06-06 09:18:28 +02:00
939e48b0c7 Karten: GL als Default auf Production freigeschaltet (Hostname banyaro.app/.de)
MapLibre-GL-Migration ist verifiziert (Staging) → GL jetzt Default auf allen
deployten Hosts statt nur staging.banyaro.app. localhost/LAN bleibt OSM-Raster
(keine lokalen Tiles), by_map_gl=0 erzwingt weiterhin den Leaflet-Fallback.
Tiles (dach.pmtiles, 15 Länder) + Glyphs liegen nun auch im Prod-Data-Volume.
SW-Bump 1219→1220.
2026-06-05 21:12:24 +02:00
72ee339860 Docs: DWD-Regen-Vorhersage-Pipeline gescoppt (Datenformat verifiziert)
DWD RV (composite/rv, kostenlos, alle 5 Min, 25 Frames 0-120min). Format
verifiziert: 194-Byte-ASCII-Header + 1200×1100 uint16 LE, Wert=&0x0FFF×0.01mm,
&0x2000=kein-Daten (PoC: Decode trivial, kein wradlib nötig). Pipeline:
fetch→decode→kolorieren→reprojizieren(DE1200→3857)→Kacheln→PMTiles/Cron 5min;
Frontend hängt Forecast-Frames rechts von 'jetzt' in die Timeline. Knackpunkt:
Georeferenzierung (PoC nötig).
2026-06-05 20:53:51 +02:00
ac187dc740 Radar-Timeline: Slider-Scrubbing gefixt + Breite/Höhe an Status-Pill
- Scrub-Bug: _radarPause() setzte slider.value zurück, BEVOR der gezogene Wert
  gelesen wurde → sprang immer auf 'jetzt'. Jetzt Wert zuerst lesen. Scrubben
  stoppt Play + zeigt den Frame der Position (verifiziert: Klick 20%→Frame 2,
  Setter→5→Frame 5).
- Breite per JS an .map-statusbar angeglichen (gleiche linke + rechte Kante),
  Höhe/Optik an die Pill (kleinerer Play-Button, flacher).
2026-06-05 20:39:41 +02:00
ea2cdd4f89 Radar-Timeline: Optik an Status-Pill angeglichen (hell/Border/Blur, Dark-Mode) + tiefer (direkt über die Pill) 2026-06-05 20:23:32 +02:00
22b8ccb784 Radar-Timeline: rechts kürzen (Platz für Ecken-FABs) + tiefer setzen
Lief rechts unter die Speed-Dial/Zurück-FABs (Zeit-Text verdeckt). Jetzt
left:12/right:88 (statt zentriert) → endet vor den FABs; bottom 92→60px.
2026-06-05 20:18:02 +02:00