- Pfeile: rotate als SVG-Pfad-Attribut statt CSS-transform am Element (maplibregl.Marker
überschrieb das transform → Pfeile zeigten alle nach Norden)
- Filter-Panel + Badge: doppeltes class-Attribut (class=X class=hidden) → Browser ignorierte
'hidden' → Filter immer offen + roter Badge immer an. Zu 'X hidden' gemergt.
- transportation nach class: Pfade/Tracks dünn+gestrichelt; Straßen weiß, Breite nach Klasse
(motorway/trunk breit … minor schmal) — Pfade sehen nicht mehr wie Straßen aus
- neue Label-Layer: poi (Kinderspielplatz/Schule… ab Z15) + housenumber (ab Z17), name:de
- Label-Reihenfolge = Kollisions-Priorität (Orte zuerst)
- main.py: /fonts-Mount (Glyph-PBFs aus data/tiles/fonts), Open Sans Regular self-hosted
- map-gl-style.js: glyphs-URL + Label-Layer (Ortsnamen/Straßen/Gewässer, name:de)
- map.js _initMapGL: ScaleControl entfernt (überdeckte die Zoom/Wetter/Zecken-Pill)
Ortsnamen für Orientierung (René), auch bei kleinem Zoom.
_loadOsmLayers verwarf Scan-Anfragen, die während eines laufenden Scans kamen (return).
Bei langsamem Overpass (Handy) ging so der finale Z14-Scan verloren → Marker leer.
Jetzt: _scanQueued merkt die Anfrage vor, finally holt sie nach → letzte Ansicht wird garantiert gescannt.
René: 'geclusterte Marker haben kein Symbol'. Jeder Cluster ist genau eine Kategorie →
weißes Phosphor-Icon in der Cluster-Mitte (icon-size skaliert mit point_count). Keine Glyphs nötig.
René: 'wo die Karten-Buttons auftauchen ist eine Zone die Kartenbedienung verhindert'.
.map-statusbar/.map-speed-dial/.map-crosshair/.map-search-wrap(inactive)/.map-rec-panel(inactive)
fingen Touch in ihrer Bounding-Box → tote Zonen. Jetzt pointer-events:none, nur Buttons auto.
Erklärt die 'reagiert nach kurzer Zeit'-Verzögerung (Drag startet tot, greift erst im Karten-Bereich).
Gilt für beide Engines (verbessert auch Leaflet).
- _loadOsmLayers: kein _map.resize() für GL (löste move→moveend→scan-Loop aus, 'pausenlos')
- _initMapGL: touchZoomRotate.disableRotation() + touchPitch.disable() + container touch-action:none
→ Pinch=reines Zoom, bleibt in der Karte (kein iOS-Page-Zoom), keine ungewollte Drehung
Eigenständiges Modul: per-Kategorie GeoJSON-Cluster, rasterisierte Phosphor-Icons,
Danger-Polygone, Sichtbarkeit, Click→Popup. /maplibre-markers-test zum headless-Verifizieren
VOR dem Einbau in map.js (auth-gated).
map.js: _useGL()/loadMapLibre()/_initMapGL() + engine-neutrale Facade
(_mapFlyTo/_mapSetView/_mapGetZoom/_mapResize/_mapGetCenter/_mapPaddedBounds, kapselt
[lat,lon]↔[lng,lat]). init() verzweigt auf GL bei Flag 'by_map_gl'/?mapgl=1. Basemap+
Controls+Dark(setStyle)+Scan-Wiring+Crosshair. POI-Layer/Marker = Runde 2. Flag default AUS.
Main-Thread-Rendering von protomaps-leaflet + App-Map-Logik blockiert UI-Thread.
Greift auch bei localStorage-Flag=1. Performance erst lösen, dann reaktivieren.
Spike-Befund: app-weit kommen nur 200 ohne Accept-Ranges zurück, FileResponse-Range
wird von der BaseHTTPMiddleware gebrochen. MapLibre/pmtiles braucht aber Byte-Ranges.
Route gibt 206 als normales Response (Byte-Slice) zurück. Produktion: nginx/NPM direkt.
Der alte delete_account löschte nur ~6 Tabellen und scheiterte am finalen
DELETE FROM users, sobald der User Zeilen in Non-Cascade-Tabellen hatte
(routes, places, walks, events, forum_threads, invoices …). Jetzt:
PRAGMA defer_foreign_keys + foreign_key_list-Introspektion (CASCADE automatisch,
NO-ACTION-Eigentum löschen, Actor/SET-NULL-Spalten nullen) plus user_id/owner_id-
Scan für Tabellen ohne formale FK. Regressionstest test_account_deletion.py.
Relevant für App-Store-Gl. 4 (In-App-Konto-Löschung muss zuverlässig funktionieren).
Statischer Hinweis präzisiert + Toast beim ersten Ausblenden: Funktion bleibt
über 'Weitere Funktionen' (Ausgeblendete Funktionen) abrufbar, wird nicht gelöscht. SW v1173
Falsche Feldnamen: dog.gewicht/dog.alter existieren nicht. Korrekt: gewicht_kg,
und Alter aus geburtstag berechnen (_alterJahre). Beide werden jetzt im Kalorien-
Rechner vorbefüllt. SW v1171
ernaehrung.js: Das Profil (Marke, Portionen, Notizen, Futter-Typ) wird beim Laden
direkt angezeigt, wenn gespeicherte Daten existieren — vorher nur nach Klick auf
'Kalorienbedarf berechnen'. Gespeicherter Tagesbedarf (kcal_tag) wird 1:1 wieder
gezeigt (kein Neu-Rechnen). _berechne → _showResult refaktoriert. SW v1170
Werben-Zuordnung ging verloren, wenn die geworbene Person den ?ref=-Link öffnete,
die App schloss und sich erst später registrierte (sessionStorage flüchtig, v.a.
iOS-PWA). Jetzt: Code früh in boot.js nach localStorage (vor evtl. SW-Reload, der
die URL ersetzt), 30-Tage-Ablauf, Löschung nach Registrierung. SW v1169
Datenkorrektur separat: nacho_sarah Angie (id=4) als 2. Werbung zugeordnet.
UI.ratingStars lud die Bewertungen via API, speicherte/renderte das ratings-Array
aber nie — nur Durchschnitt+Anzahl. Jetzt wird die Liste aller Bewertungen mit
Kommentar (Name + Sterne + Text) angezeigt; nach dem Speichern neu geladen.
Backend war korrekt. SW v1168
Stufe 1 (Guard): Während aktiver Aufzeichnung wird der SW-/Force-Update-Reload
aufgeschoben (window._byRecording → boot.js/_bySwReload + app.js force-update);
nach Stop/Speichern via window._byReloadIfPending() nachgeholt.
Stufe 2 (Persistenz): Track wird gedrosselt nach localStorage (RecStore) gesichert
und beim nächsten Öffnen der Karten-/Routen-Seite als 'Aufzeichnung fortsetzen?'
angeboten (Resume seedet Track+km+Startzeit). Schützt auch bei Crash/OS-Kill/
manuellem Reload. Greift in map.js UND routes.js. SW v1167
_check_post_limits verglich datetime.utcnow() (UTC) mit created_at, das aber
als Client-Lokalzeit (CEST=UTC+2) gespeichert wird → diff negativ → immer 429.
Jetzt rechnen Cooldown + Stunden-Limit in derselben Zeitbasis (Client-Zeit des
Requests). Backend-only, kein SW-Bump.