34f29f9d0a
Sprint 15: Suche, Ausweis, Teilen, Widget
...
- Volltext-Suche im Tagebuch (LIKE über Titel/Text/Tags, Debounce 350ms)
- Digitaler Heimtierausweis als druckbare HTML-Seite (/ausweis/{dog_id})
Enthält Impfungen, Medikamente, Allergien, Tierärzte, Chip-Nr.
- Hund teilen: Einladungslink-System (dog_shares-Tabelle, /teilen/{token})
Geteilte Hunde erscheinen in der Hundeliste, Tagebuch/Gesundheit lesbar
- Widget-Seite /#widget: zufälliges Tagebuchbild + nächste Erinnerung
Als PWA-Shortcut im Manifest verankert
- SW-Cache by-v144, APP_VER 117
2026-04-17 15:51:09 +02:00
d5f09cd16b
Fix: UI.escape definieren + Transponder-Karte immer im Profil anzeigen
...
- UI.escape() fehlte im Public-API von ui.js (crash nach Profil speichern)
- Chip-Nr.-Karte im Hunde-Profil immer sichtbar, auch ohne Wert
- "Eintragen"-Button öffnet Inline-Edit-Modal direkt im Profil
- SW-Cache by-v143
2026-04-17 15:29:57 +02:00
94e0ed3daa
Feature: Tagebuch-Import (NoteStation .nsx + CSV) + Transponder in Gesundheitsdaten
...
- Import-Endpoint für Synology NoteStation (.nsx): HTML→Text, GPS, Bilder, Unix-Timestamp→Datum
- Import-Endpoint für CSV (Komma/Semikolon, BOM-safe, DE-Datumsformat)
- Import-Modal im Tagebuch mit Format-Auswahl-Karten und Ergebnis-Anzeige
- Transpondernummer in Gesundheitsdaten: Anzeige + Inline-Edit via Modal
- SW-Cache by-v142
2026-04-17 15:17:56 +02:00
6fcf841594
Sprint 14: Map-Fixes, City-Prewarm, Dog-Animation, Scan-Flash
...
Karte:
- Frankfurt-Fallback (Zoom 10→14 flyTo) mit _frankfurtTimer-Cancel
wenn echter Standort eintrifft
- OSM-Tile-Fetch parallelisiert (asyncio.Semaphore(3))
- Bounds-Fix: invalidateSize() + pad(0.15) vor getBounds()
- map-pin-slash Icon für gesperrten Standort
- Scan-Done-Flash: Statusbar-Pill grün bei 100%
- Schnüffelhund: outer div (by-wander X) + inner SVG (by-sniff Y)
für natürlichere zweiachsige Bewegung
Backend:
- City-Prewarm-Job: ~70 deutsche Großstädte beim Start (+90s) und
wöchentlich (So 01:00), Fortschritts-Mails alle 5h an ADMIN_EMAIL
- ADMIN_EMAIL Env-Var in .env.example dokumentiert
Bugfixes:
- Profil-Edit: /api/profile → /profile (doppelter Prefix)
- Friends: Mobile-Portrait-Layout (flex-wrap, overflow-x:hidden)
- Trainingspläne: Pills text-wrap (flex + white-space:normal)
2026-04-17 14:06:10 +02:00
cd3f118113
Feature: Scan-Fortschritt als SVG-Ring um das Zoom-Statusfeld
2026-04-17 10:44:52 +02:00
49d129e00c
Feature: Scan-Fortschrittsbalken während OSM-Daten geladen werden
2026-04-17 10:39:58 +02:00
7096ba8fea
Feature: Telefonnummer für Orte (DB-Migration + API + Formular + Detailansicht)
2026-04-17 10:32:04 +02:00
abc7e6628a
Fix: FAB-Buttons orange, Kotbeutel-Tüten-Icon + grün, Mülleimer grau
2026-04-17 10:26:59 +02:00
7fddfdba0b
Fix: map-fab Buttons explizit weiß (#fff) — Dark Mode machte sie schwarz
2026-04-17 10:19:09 +02:00
50ec181dba
Fix: Karte — Locate-Button CSS explizit (#fff, Inline-SVG statt Sprite-Use)
2026-04-17 10:16:09 +02:00
a0e1a26bd2
Fix: Kalender-Abo — UI.escape entfernt (existiert nicht in UI)
2026-04-17 10:06:18 +02:00
0ba9354475
Fix: SW-Cache by-v116 + index.html Skript-Versionen auf v=91 bumpen
2026-04-17 10:04:38 +02:00
6698543d14
Sprint 14: Impressum, Datenschutz, Google Analytics (cookieless)
...
- Impressum-Seite (§5 TMG / §18 MStV) mit René Degelmanns Daten
- Datenschutzerklärung (DSGVO) mit GA-Erläuterung und Opt-out
- Google Analytics G-YLG780DV3Z, Option B (cookieless, kein Consent nötig)
- Sidebar-Footer-Links Impressum / Datenschutz
- APP_VER → 86, SW-Cache → by-v110
2026-04-17 09:05:32 +02:00
21e50c6c7b
Fix: friends.js Auth-Guards für nicht eingeloggte User
2026-04-16 22:48:44 +02:00
a4f74b6c64
Sprint 13: WebCal-Abo / Kalender-Integration
...
- GET /api/webcal/token: erzeugt personl. Kalender-Token (einmalig)
- GET /api/webcal/{token}.ics: iCal-Feed mit Health-Erinnerungen,
eigenen Events, Gassi-Treffen (erstellt + beigetreten), angenommenen Sittings
- RRULE für wiederkehrende Health-Einträge (intervall_tage)
- Migration: users.calendar_token (TEXT UNIQUE)
- Settings: "Kalender abonnieren" öffnet webcal://-Link + Kopier-Button
- api.js: API.webcal.getToken() / resetToken()
- SW-Cache: by-v104, APP_VER: 80
2026-04-16 22:39:50 +02:00
b58789373c
Sprint 12: UI-Vereinheitlichung + Läufigkeits-Tracker
...
- by-tabs/by-tab: einheitliche Tab/Pill-Navigation in allen Seiten
- by-section-label, by-toolbar: einheitliche Section-Labels und Toolbars
- Design-Tokens: fehlende --c-amber, --c-primary-soft ergänzt, Fallback-Werte entfernt
- sitting.js: sitting-layout für konsistentes flush-Layout (wie walks)
- Läufigkeits-Tracker: neuer Health-Tab für Hündinnen mit Zyklusvorhersage,
Timeline vergangener Läufigkeiten, Erinnerungen und auto-berechnetem Nächst-Datum
- emptyState-Bug: icon-Parameter muss SVG sein, nicht Icon-Name (dog/bell/warning gefixt)
- SW-Cache: by-v103, APP_VER: 79
2026-04-16 22:31:33 +02:00
32d630d5a1
Sprint 11b: Wiki-Foto-Einreichungen + Wikipedia-Foto-Scraper
...
- User können Fotos für Rassen vorschlagen (Upload-Modal in Rassen-Detail)
- Mod/Admin-Review-Tab im Wiki mit Freischalten/Ablehnen + Push-Notification
- wikipedia_photos.py: holt Fotos über Wikidata-QID → Wikipedia-API
- Foto-Status: 578 lokal, 186 extern, 238 ohne Foto
- DB: wiki_foto_submissions Tabelle
- SW by-v90
2026-04-15 22:01:58 +02:00
097295c628
Sprint 11: Freunde & Chat + Phosphor-Icon-Vollmigration
...
- Freundschaften (pending/accepted), Nutzersuche, Anfragen per Push
- Direktnachrichten mit Polling, iMessage-Stil, Deep-Links aus Push
- Alle Seiten (map, places, diary, health, dog-profile, sitting, knigge,
forum, wiki, walks) vollständig auf Phosphor-Icons migriert
- Wikidata-Rassen-Scraper (~833 neue Rassen, lokal gespiegelte Fotos)
- TheDogAPI lokal gespiegelt (169 Rassen + Fotos)
- Quiz-Result-Cards horizontal (korrekte Bildproportionen)
- SW by-v89
2026-04-15 21:33:53 +02:00
ebe4ce20cf
Sprint 10: OSM-POI-Cache, Karten-Clustering, Routen-Redesign
...
Karte (map.js):
- OSM Overpass API: Restaurants, Tierärzte, Parkplätze, Bänke, Wasserstellen
- Leaflet.markercluster für alle OSM-Layer
- Standort-Dot mit GPS-Genauigkeitskreis, Wake-Lock bei Aufzeichnung
- Community-Pins setzen/löschen, Meldungen, Crosshair-Placement
- Layer-Sichtbarkeit in localStorage (by_map_visible_v1)
Routen (routes.js + routen.py):
- Komoot-Stil: SVG-Track-Preview, Foto-Upload, Nearby-POIs im Detail-Modal
- Neue Felder: is_public, hunde_tauglichkeit, foto_urls
- Rate-Endpoint (POST /api/routes/{id}/rate)
- Foto-Upload (POST /api/routes/{id}/photo)
- Fix: json_extract $[-1] → $[#-1] (SQLite-kompatibler Pfad für letztes Element)
Backend (osm.py, database.py, scheduler.py):
- /api/osm/pois: OSM-Overpass-Cache mit Tile-Logik (14 Tage TTL)
- /api/osm/user-poi: Community-Marker CRUD
- /api/osm/report: Marker als ungültig melden
- Neue Tabellen: osm_pois, osm_tiles, user_map_pois, osm_reports
- Giftköder-Archiv-Job (täglich 03:00, soft-delete nach Ablauf)
- Giftköder-Archiv-Job als APScheduler-CronJob
UI: Orte-Menüpunkt entfernt (in Karte integriert), APP_VER auf 62
2026-04-15 16:30:10 +02:00
d399cb84cf
Fix: Sidebar/Backdrop aus #app raus, direkt in <body>
...
#sidebar und #sidebar-backdrop waren Kinder von #app (display:flex),
was auf iOS Safari Stacking-Context-Probleme verursacht. Beide Elemente
sind jetzt direkte Kinder von <body>. _openSidebar() zurueck zur
sauberen .open-Klassen-Methode. will-change:transform entfernt.
SW by-v32 -> by-v33.
2026-04-14 17:44:46 +02:00
1c6ec6f17e
Fix: /update-Endpunkt zum manuellen SW-Cache-Reset + STATIC_ASSETS bereinigt
...
/update loescht SW + alle Caches via JS und leitet zur App zurueck.
Alter SW hat /update nie gecacht -> immer frisch vom Server.
STATIC_ASSETS ohne ?v= (verhindert fehlerhafte cache.addAll()-Fehler).
2026-04-14 17:33:12 +02:00
619ff559e6
Fix: SW Network-First für Navigation + versionierte CSS/JS-URLs (v=32)
...
- sw.js: index.html nie aus Cache (navigation → network-first)
- index.html: ?v=32 an layout.css, components.css, api/ui/app.js
- sw.js STATIC_ASSETS: versionierte URLs gecacht
- app.js: Sidebar-Background per getComputedStyle statt CSS-Variable-String
- SW by-v31 → by-v32
2026-04-14 17:26:02 +02:00
b6fae96334
Fix: Sidebar via JS-Inline-Styles (SW-Cache-unabhängig) + SW force-navigate
...
_openSidebar() setzt nun direkt style.cssText statt CSS-Klassen,
damit stale CSS-Cache keinen Einfluss hat. SW by-v30 → by-v31 mit
clients.navigate() im activate-Handler für automatischen Reload.
2026-04-14 17:22:13 +02:00
40b802ae86
Fix: Mobile Sidebar z-index 1000 + display:flex !important
...
Backdrop lag bei z-index 499 über der Sidebar (z-index 300 Base).
Sidebar bekommt auf Mobile z-index:1000, display:flex !important
und will-change:transform. SW by-v29 → by-v30.
2026-04-14 17:16:54 +02:00
1c8ed88dac
Fix: Karte position:fixed + Mobile-Sidebar CSS-Kaskade
...
- .map-full-layout: position:fixed statt absolute;inset:0 mit
expliziten Offsets (header/nav/sidebar) — unabhängig von
height-Kette, überdeckt Sidebar nicht mehr
- layout.css: Mobile Drawer-CSS nach Base-#sidebar-Regel verschoben
(vorher: display:none hat gewonnen weil später im File)
- map.js: zweites invalidateSize() nach 600ms
- SW by-v28 → by-v29
2026-04-14 17:09:00 +02:00
e5bf841d45
Fix: Karte-Seite erhält definite Höhe für Leaflet-Tiles
...
#page-map bekommt height:100% (statt min-height), damit .page-body und
.map-full-layout eine auflösbare Höhe haben. SW by-v27 → by-v28.
2026-04-14 17:02:03 +02:00
01081fcd75
Fix: Sidebar-Drawer transform:translateX statt left (kein Konflikt mit base-rule)
2026-04-14 16:54:29 +02:00
2ff439a4e3
Fix: Karte — position:absolute;inset:0 statt height:100% (kein parent-height Problem)
2026-04-14 16:51:47 +02:00
d4c3f159d5
Fix: Karte-Höhe via JS, events Leaflet-Pfad, Hamburger-Menü mobile Drawer
2026-04-14 16:47:21 +02:00
0438bd6bfe
Fix: SW controllerchange → Reload erzwingen bei SW-Update (stale api.js im Memory)
2026-04-14 06:30:22 +02:00
86dfe50013
Fix: Page_events + Page_sitting auf window registrieren (waren mit const deklariert)
2026-04-14 06:24:30 +02:00
5f8fd3bd51
Sprint 8: Events + Hundesitting
...
Events:
- Backend events.py: CRUD, Typen (ausstellung/training/treffen/markt/wettkampf/sonstiges)
Haversine-Filter, Monats-Gruppierung in der Liste
- Frontend events.js: Liste/Karte-Toggle, Typ-Filter-Chips, farbige Marker,
Detail-Modal, Erstellen/Bearbeiten-Formular mit GPS-Button
Hundesitting:
- Backend sitting.py: Sitter-Profile (create/update/me), Anfragen (send/accept/decline/cancel),
Inbox für Sitter, Haversine-Sortierung, Service-Filter
- Frontend sitting.js: 3 Tabs (Suchen/Profil/Anfragen), Sitter-Karten mit Distanz,
Detail-Modal + Anfrage-Formular, Profil-Verwaltung
DB: events, sitters, sitting_requests Tabellen hinzugefügt
SW-Cache: by-v21 → by-v22
2026-04-14 06:19:15 +02:00
ec17dfb029
Sprint 7: Gassi-Treffen — Meetup-Feature komplett
...
- Backend: walks.py mit allen Endpoints (CRUD, join/leave, Haversine-Filter)
- DB: walks, walk_participants, walk_participant_dogs Tabellen (bereits in database.py)
- Frontend: walks.js — Liste/Karte-Toggle, Heute/Demnächst-Gruppierung, Detail-Modal
mit Teilnehmerliste, Beitreten/Verlassen, Erstellen/Bearbeiten-Formulare
- CSS: Walks-Komponenten (Card, Date-Badge, Spots-Anzeige, Map-View)
- api.js: walks-Abschnitt (list, get, create, update, cancel, join, leave)
- SW-Cache: by-v20 → by-v21
2026-04-14 06:12:52 +02:00
b9df636535
Sprint 6: Karte / Orte / Routen mit GPS-Aufzeichnung
...
- backend/routes/places.py: CRUD für hundefreundliche Orte (6 Typen)
- backend/routes/routen.py: CRUD für Gassi-Routen mit GPS-Track (JSON)
- main.py: beide Router eingehängt (/api/places, /api/routes)
- api.js: places + routes erweitert (list, update, delete)
- pages/places.js: Karte + Liste, Typ-Filter, Ort anlegen/bearbeiten
- pages/routes.js: Routen entdecken + GPS-Aufzeichnung mit Stoppuhr
- pages/map.js: zentrale Übersichtskarte (Orte + Giftköder, Layer-Toggle)
- components.css: Styles für alle drei neuen Seiten
- sw.js: by-v19 → by-v20
2026-04-14 06:03:37 +02:00
956e34db88
UX: Formular-Buttons in Modal-Footer + Kalender-Icons amber
...
- Alle Formular-Buttons (health, praxen, diary, dog-profile, poison)
aus dem scrollbaren Body in den festen Modal-Footer verschoben
(form="form-id" Attribut, btn-Suche via document.querySelector)
- Kalender-Icon Filter korrigiert: brightness(0)+invert(0.55) vermeidet
Channel-Clipping bei sepia auf Weiß → ergibt echtes Amber (~#C4843A)
- SW-Cache: by-v18 → by-v19
2026-04-13 21:12:15 +02:00
e5492841ec
Fix: Modal-Scroll nur im Body — Header/Footer bleiben fest
2026-04-13 20:56:04 +02:00
1ad77b4366
UX: Modal-Scrollbar im Primärfarben-Stil (wie Sidebar)
2026-04-13 20:54:02 +02:00
b8a5dc7a66
Feat: Gesundheits-Erinnerungen mit Wiederkehrend-Intervall
...
- intervall_tage Feld (monatlich/vierteljährlich/jährlich etc.)
- Impfung, Entwurmung, Medikament: Intervall-Auswahl im Formular
- Erinnerungs-Banner über den Tabs: zeigt alle Einträge die in ≤60 Tagen fällig sind
- Ampel-Farbe am linken Rand (rot=überfällig, gelb=bald, grün=ok)
- "✓ Erledigt"-Button öffnet neues Formular vorausgefüllt mit heute + nächstem Termin
- Nav-Badge (Zahl) auf Gesundheit-Icon wenn Einträge überfällig/bald fällig
- _showForm: isEdit prüft entry?.id statt !!entry (Reminder-Flow)
- SW-Cache → by-v16
2026-04-13 20:45:52 +02:00
5c178f812b
Feat: Praxis-Auswahl bei Impfung/Entwurmung/Medikament + Dokumente funktional
...
- Praxis-Dropdown als wiederverwendbare Funktion _praxisSelectField()
- Impfung, Entwurmung, Medikament: Praxis auswählbar statt Freitext
- Impfpass-Karte: zeigt Praxisname mit 🏥 Icon
- Dokumente: Öffnen-Button direkt auf der Karte (stopPropagation),
Bild-Vorschau 64px, "Noch keine Datei" wenn kein Upload
- SW-Cache → by-v15
2026-04-13 20:38:30 +02:00
40fa47efca
Fix: Tab 'Tierarzt' → 'Besuche' (Tierarzt = Praxen)
2026-04-13 20:34:08 +02:00
fc6a2db744
Fix: Kalender-Icon amber — color-scheme:light erzwingt schwarzes Icon für Filter
2026-04-13 20:33:02 +02:00
e9587d4ecd
UX: Tierarztbesuch-Tab — Praxis-Verknüpfung als Kernfunktion
...
- Formular: Praxis-Dropdown ersetzt Freitext wenn Praxen vorhanden
- Kein redundantes Freitext-Feld mehr, Ort in der Option angezeigt
- "Praxis anlegen"-Link navigiert direkt zum Praxen-Tab
- tierarzt_name wird zusätzlich als Sicherheitskopie gespeichert
- Karte: zeigt Praxisname + Ort unter dem Besuchsgrund
- Detail-Modal: Praxis mit Adresse und anklickbarer Telefonnummer
- SW-Cache → by-v12
2026-04-13 20:30:36 +02:00
d9f2e85263
Fix: Gewicht auf 2 Nachkommastellen (step 0.1 → 0.01)
2026-04-13 20:26:54 +02:00
1a5f1f7ee2
Fix: Gewicht-Eintrag schlug fehl (bezeichnung Pflichtfeld + Komma-Dezimal)
...
- health.py: bezeichnung Optional statt required (Gewicht braucht keinen Titel)
- _buildPayload: Komma → Punkt bei wert und kosten (deutsche Lokalisierung)
- Gewicht-Einträge setzen automatisch bezeichnung = "9.9 kg"
- SW-Cache → by-v10
2026-04-13 20:25:25 +02:00
75529cbdab
UX: Gewicht-Tab mit großem Chart und ohne Bezeichnungsfeld
...
- Aktuelles Gewicht groß prominent oben angezeigt
- Delta zur letzten Messung mit ▲/▼ und Farbe (grün/orange)
- SVG-Diagramm: glatte Bezier-Kurve, Gradient-Füllung, Rastlinien
- Formular: kein "Bezeichnung"-Feld mehr bei Gewicht-Einträgen
- Detail-Modal-Titel zeigt Gewichtswert statt leerer Bezeichnung
- SW-Cache → by-v9
2026-04-13 20:22:23 +02:00
dee8d10496
UX: Modal-Rand, Icon-Farben, Adresse aufgeteilt
...
- Tierarzt-Adresse: strasse / plz / ort statt einzeiligem Freitext
- Modal: Rand in Primärfarbe + kein versehentliches Schließen beim Klick auf Hintergrund
- Nav/Sidebar-Icons: inaktiv gedämpft, aktiv amber-getönt (CSS filter)
- Datums-Kalender-Icon: ebenfalls amber statt Schwarz
- SW-Cache → by-v8
2026-04-13 20:16:36 +02:00
fc0f48c6d0
Feat: Tierärzte-Verwaltung (Sprint 4)
...
Neue Praxen-Tab in Gesundheit: Tierarzt-Stammdaten (Name, Adresse,
Telefon, Notfall-Nr, E-Mail, Website, Notizen), Anruf- und
Notfall-Schnellzugriff via tel:-Links, Soft-Delete (aktiv=0) für
Praxiswechsel ohne Datenverlust. Tierarzt-Dropdown beim Eintragen
von Tierarzt-Besuchen. SW-Cache → by-v7.
2026-04-13 20:06:59 +02:00
c06d9e24a7
Fix: Klick auf aktiven Hund im Picker lädt Inhalt (setActiveDog war no-op)
2026-04-13 19:55:42 +02:00
e59b6e6e88
sw.js: Cache-Bust v5 (Gesundheit Hunde-Picker)
2026-04-13 19:50:17 +02:00
1352c2f54f
sw.js: Cache-Version auf v4 (erzwingt Re-Fetch nach Picker-Feature)
2026-04-13 19:45:52 +02:00