Commit graph

49 commits

Author SHA1 Message Date
572fbf642f Fix: Wetter-Chip ohne farbigen Rand, Update-Prüfung nutzt APP_VER+API+location.replace('/') (SW by-v769) 2026-05-08 11:22:55 +02:00
77795345b8 UX: Abmelden-Button als prominenter Outline-Button mit Trennlinie (SW by-v763) 2026-05-07 19:25:27 +02:00
e5e95efaed UX: Welcome-Seite — Anmelde-Einstieg vereinfacht, Install-Block prominent mit PWA-Erklärung (SW by-v755) 2026-05-07 17:15:19 +02:00
81bc0f50a0 Fix: Nach Login ohne Hund → Onboarding mit Skip-Option statt direkt zu dog-profile (SW by-v748) 2026-05-06 21:02:55 +02:00
a6c25cf0f0 Feature: Feature-Gating nach Tier — Pro-Seiten/Chips für Standard versteckt, Admin immer alles (SW by-v737) 2026-05-06 19:06:37 +02:00
05ecf3b94a Feature: Hilfe/FAQ, Übungen-Content, Navigation-Fixes (SW by-v727)
Hilfe & FAQ:
- Neue Seite /hilfe mit Akkordeon + Live-Suche (6 Kategorien, 25 Artikel)
- DB-Tabelle help_articles — Inhalte admin-seitig ohne Deploy änderbar
- Admin-Tab Hilfe/FAQ zum Bearbeiten aller Artikel
- Link in Einstellungen (unter Welten einrichten, über Abmelden)
- routes/help.py: GET (public), POST/PATCH/DELETE (Admin)

Übungen:
- 110 Übungen: beschreibung (kurz), schritte (JSON 4-6 Schritte), tipp — gutes Deutsch mit Umlauten
- Admin-Tab Übungen: Inline-Editor für alle drei Felder
- PUT /training/exercises/{id} (Admin) neu
- Übung-des-Tages Chip → scrollt jetzt korrekt zur Übung (exercise_id-Feldname-Fix)

Welten-Navigation:
- hide() stellt app-header + bottom-nav wieder her (worlds-hidden wurde nie entfernt)
- init() mit _setupDone-Guard (keine doppelten Event-Listener)
- Login ruft Worlds.init(_appState) statt show() — _state war null → falscher Render
- X-Button in Welten-Konfiguration: 30×30px, Icon 17px, besser sichtbar

Wetter:
- Motivation bei blockiertem Standort: 6-Schritte-iOS-Anleitung + Flugmodus-Tipp
- Auto-locate bleibt (kein Button-Only mehr)

achievements.py:
- my_achievements(): d.user_id → JOIN dogs (zweite Funktion war noch kaputt)
2026-05-05 21:46:16 +02:00
55069d246b Feature: Welten-Onboarding, Wetter-Motivation, UX-Fixes (SW by-v715)
Welten (worlds.js):
- Swipe-Hints beim ersten Öffnen (JETZT ← → WELT animiert, einmalig)
- Kein-Hund-Onboarding: Feature-Preview-Grid statt leerer Karte
- Hintergrund-Foto-Hint: Kamera-Karte wenn noch kein Tagebuchfoto
- worlds-back: navigiert zu Welcome wenn kein User eingeloggt
- Nach Logout: worlds-back Button sofort ausgeblendet

Wetter (wetter.js):
- Standort-Fehlerseite zu Motivations-Seite umgebaut
- Feature-Preview: Gassi-Score, 7-Tage, Regenradar, Rekorde
- CTA: Standort freigeben + Registrieren (nur für Gäste)

Settings (settings.js):
- Logo in Auth-Form: display:block + margin:0 auto zentriert
- Header bleibt sichtbar (FAB/Zurück-Navigation funktioniert)

Jobs (jobs.js):
- 2-Spalten-Grid auf Mobile: auto-fit statt festes 1fr 1fr
- Kein doppeltes Padding im Wrapper

Backend:
- weather.py, achievements.py: diary JOIN fix (d.user_id → dogs JOIN)
- Neue Wetter-Badges: wetter_tapfer, jahreszeiten, schnee
- Ernährungs-, Reise-, Ausgaben-Seite: diverse UX-Verbesserungen
- Presse-Seite erweitert
- Ban Yaro Foto-Assets (WebP + HIRES JPG)
2026-05-05 17:32:03 +02:00
0fdc32eaf4 Feature: Hunde-Persönlichkeitstest + Kilometer-Lebenswerk-Badge (SW by-v698)
- personality.js: 10-Fragen-Quiz mit 4 Typen (Abenteurer/Entdecker/Kuschler/Denker), Ergebnis-Speicherung in localStorage, Share-Funktion
- achievements.py: neue Badge-Kategorie km_lebenswerk (Bronze 100 km bis Platin 5000 km)
- settings.js: Lifetime-km-Balken mit Meilenstein-Markierungen bei 100/500/1000/5000 km
- app.js + index.html: personality-Seite registriert
2026-05-04 20:52:51 +02:00
6bf088df56 Feature: Goldene Gassi-Stunde — täglicher Push mit bestem Wetterfenster (SW by-v693)
- Scheduler-Job täglich 07:00: berechnet bestes 2h-Fenster via Open-Meteo
- Score-System (max. 10 Pkt): Temperatur, Niederschlag, Wind, Tageszeit
- User-Fallback auf letzten bekannten Standort (push_subscriptions.last_lat/lon) oder München
- Nur Push wenn score >= 3 (kein sinnloser Push bei schlechtem Wetter)
- DB-Migration: users.gassi_stunde_push (Boolean, default 0)
- settings.js: Toggle "Goldene Gassi-Stunde täglich" in App-Einstellungen
- PATCH /api/profile + auth.py /me: gassi_stunde_push Feld
2026-05-04 20:22:02 +02:00
eca8d1455d Fix: Nach Login direkt in HUND-Welt landen statt Welcome-Seite (SW by-v658) 2026-05-03 20:41:20 +02:00
747c353444 Chore: Sprint32-36 Zwischenstand — alle Änderungen aus dieser Session committen 2026-05-03 11:09:39 +02:00
de1677154f Security + E-Mail-HTML + Quartalsbericht + Registrierungspflicht
Registrierung & Login:
- E-Mail-Verifikation jetzt Pflicht vor erstem Login
- Register gibt keinen Token mehr zurück → "Postfach prüfen"-Screen
- Login blockt mit EMAIL_NOT_VERIFIED (403) wenn unverifiziert
- Resend-Verification ohne Auth (email-basiert)
- Frontend: _renderVerifyPending() nach Register und Login-Fehler
- Account-Lockout: 5 Fehlversuche → 15 Min gesperrt (ratelimit.py)
- Login Rate-Limit zusätzlich per E-Mail-Adresse (5/5 Min)
- Fehler-Tracking wird bei erfolgreichem Login zurückgesetzt

E-Mail-Templates (alle Mails jetzt HTML):
- email_html() Shared-Template in mailer.py (Gradient-Header, Warm-Beige)
- Verifikations-Mail, Passwort-Reset → HTML mit CTA-Button
- Admin-Outreach: plain text auto-wrapped in HTML
- Züchter-Mails (Antrag/Genehmigung/Ablehnung) → Template
- Tierschutz-Alert (litters.py) → Template
- send_support_mail → HTML
- outreach._build_message() + _send_smtp() unterstützen jetzt html= Parameter

Forum-Schutz:
- Post-Cooldown: 30 Sek zwischen beliebigen Posts (DB-Check)
- Stunden-Limit: 5 Threads / 20 Antworten pro User/Stunde
- Duplikat-Erkennung: gleicher Text in 5 Min blockiert (in-memory)
- content_filter.py: Spam-Keywords, URL-Sperre für Accounts < 7 Tage,
  Sonderzeichen-Ratio-Check

Security-Headers:
- HSTS: max-age=31536000; includeSubDomains
- Content-Security-Policy: frame-ancestors none, base-uri self, …
- X-Frame-Options entfernt (CSP frame-ancestors ist moderner)

Honeypot-Fallen (13 Scanner-Pfade → 24h IP-Sperre):
- /api/admin/users, /api/v1/users, /api/.env, /api/config,
  /api/setup, /api/install, /api/phpinfo, /api/debug,
  /api/actuator, /api/swagger, /api/graphql u.a.

Quartalsbericht-System:
- backend/scripts/generate_reports.py: 6 Sections
  (Sicherheit, Funktionsumfang, Dateien, Nutzer, Partner, Server)
- make reports: generiert alle Berichte aus dem Container, committed
- Scheduler: quarterly_report Job (1. Feb/Mai/Aug/Nov 07:00)
  → vollständige HTML-Mail an ADMIN_EMAIL
- quarterly_report erscheint im täglichen Status-Report

Admin-Panel:
- "Forum & Meldungen" → "Forum"
2026-05-01 08:20:53 +02:00
526ff42215 Security: Passwort-Minimum, Rate Limits, Headers, Passwort-vergessen, email_verified
- Passwort-Minimum 8 Zeichen bei Register + Reset
- Rate Limit auf /resend-verification (3/h) und /forgot-password (3/h)
- Security-Headers: X-Frame-Options, X-Content-Type-Options, Referrer-Policy etc.
- email_verified in get_current_user SELECT ergänzt
- Forum: create_thread + create_post erfordern email_verified
- POST /auth/forgot-password + /auth/reset-password (2h-Token, via support@)
- DB-Migration: password_reset_token + password_reset_expires
- Frontend: Passwort-vergessen-Modal im Login, Reset-Formular mit Passphrase-Generator
- SW by-v576, APP_VER 553
2026-04-30 20:23:43 +02:00
b9ee67b8dd Feature: E-Mail-Verifikation + Forum öffentlich lesbar + Launch-Vorbereitung
- Forum ohne requiresAuth: öffentlich lesbar, Schreiben weiter via API-Guard
- E-Mail-Verifikation: Token bei Registrierung, support@-Mail, /verify-email/{token}
- Verifikations-Banner (orange, dismissible) wenn email_verified=0
- Grüner Haken / "Nicht bestätigt"-Chip in Settings
- POST /auth/resend-verification für Chip und Banner
- DB-Migration: users.verification_token TEXT
- SW by-v575, APP_VER 552
2026-04-30 19:51:07 +02:00
230455c250 Feature: Gründer-Aktivierung nach Hunde-Profil mit Plausibilitätsprüfung
- is_founder_pending: bei Registrierung mit Code gesetzt (statt sofort is_founder)
- dogs.py: erstes Hunde-Profil → Plausibilitätsprüfung → is_founder aktivieren
- Prüfung: Name min. 2 Zeichen + Buchstaben, Rasse gültig, Geburtsjahr realistisch
- Settings: gelbes 'Gründer-Platz reserviert' Badge mit Link zu Hunde-Profil
- Onboarding-Toast informiert über nötiges Hunde-Profil
- SW by-v566, APP_VER 543
2026-04-30 18:59:20 +02:00
c657ac6ab8 Fix: Update-Check vergleicht Server-Version mit lokaler — lädt Seite neu wenn Update gefunden, SW by-v561 2026-04-30 16:48:37 +02:00
105262eff3 Fix: Settings refresh() lädt auch frischen /me-State, SW by-v557 2026-04-30 15:31:47 +02:00
f31f219ad6 Fix: Settings lädt frischen /me-State beim Init — Badges immer aktuell ohne Re-Login, SW by-v556 2026-04-30 15:18:02 +02:00
c2a5fbba7d Fix: /api/-Prefix in gruender.js+settings.js entfernt; Grant-Fehler sichtbar, SW by-v553 2026-04-30 14:45:16 +02:00
6ae6806baf Fix: Referral-Card Header zeigt Rabattstufen — SW by-v518, APP_VER 495 2026-04-29 21:36:29 +02:00
e7e4adaa70 Feature: Referral-Rabattstufen — 10→20%, 20→30%, 50→50% lebenslang
- auth.py: _referral_tier() + _referral_next() Tier-Logik, GET /api/auth/referral gibt discount_pct + next_tier zurück
- settings.js: Referral-UI komplett neu — Tier-Kacheln, Fortschrittsbalken, Zähler, Rabatt-Hinweis
- SW by-v517, APP_VER 494
2026-04-29 21:34:23 +02:00
ab41af470d Feature: 100 Gründer-Challenge — Leaderboard, Ranking, founder_number
- 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
2026-04-29 21:30:52 +02:00
e57c6db013 Feature: Partner-Codes + Gründer-Lizenz-System für Influencer-Kooperationen
- partner_codes Tabelle: Code, Label, max_uses, grants_founder, uses-Counter
- users: is_founder + is_partner Flags (DB-Migration + auth.py SELECT)
- Registrierung: Partner-Code löst Gründer-Lizenz aus (vor User-Referral geprüft)
- API: GET/POST/DELETE /api/admin/partner/codes, POST /api/admin/partner/users/{id}/grant
- API: GET /api/partner/codes/{code}/info (öffentlich, für Registrierungsvalidierung)
- API: GET /api/admin/users/search (Name-Suche für Admin-UI)
- Admin-Tab "Partner & Codes": Code anlegen, Stats, User-Status vergeben
- Registrierungsformular: Einladungscode-Feld mit Live-Validierung
- Settings: Gründer (lila) + Partner (blau) Badge neben Kostenlos/Plus
- SW by-v515, APP_VER 492
2026-04-29 21:20:16 +02:00
041af92306 Feature: Staging-Workflow — develop-Branch, make staging/release, APP_VERSION 1.0.0, Staging-Banner — SW by-v513 2026-04-29 19:57:33 +02:00
b4de0aa27c UX: Login → Welcome statt Diary; Landing-Features flacher (kein Box-Icon, einheitlicher Hintergrund) — SW by-v504, APP_VER 481 2026-04-29 16:53:17 +02:00
a4da7144d6 Feature: App-Version in Einstellungen + manueller Update-Check — SW by-v488, APP_VER 465 2026-04-29 10:54:56 +02:00
c8ae514c01 Feature: Tierschutz-Check, KI-Züchter-Features, Export, SEO-Update
Tierschutz-System (immer aktiv, nicht abschaltbar):
- welfare_check.py: regelbasierte Prüfung IK, Alter, Deckpause, Wurfanzahl, Genetik
- Grün/Gelb/Rot-Modal bei Wurf anlegen + Probeverpaarung
- Bei kritischem Befund + "Trotzdem fortfahren" → automatische Admin-Mail
- Tierschutz-Check nie durch Nutzer deaktivierbar

KI-Züchter-Features (pro User an/abschaltbar außer Tierschutz):
- routes/zucht_ki.py: 5 Endpunkte — Wurfankündigung, Genetik-Erklärung,
  Paarungsanalyse, Hund-Beschreibung, Jahresbericht
- Toggles in Einstellungen (ki_zucht_* Felder)
- KI-Buttons in litters.js + zuchthunde.js

KI-Routing: Privilegierte Rollen (Admin, Züchter, Moderator, Manager)
nutzen Claude Sonnet primär, lokales LLM als Fallback

Datenexport: routes/breeder_export.py — ZIP mit HTML-Dossier + ODS
(odfpy hinzugefügt in requirements.txt)

Admin-Profil: POST /admin/breeder/create-profile für Schnellprofil ohne
Antragsprozess; Admin-Rolle bleibt erhalten

Wurfformular: Dropdown aus Zuchtkartei für Vater/Mutter mit Auto-Fill;
litters.vater_id + mutter_id als FK auf zucht_hunde

Probeverpaarung: heart-fill Icon + Welfare-Block im Ergebnis

Landing Page: Züchter-Section + Feature-Gruppe, Meta-Tags, JSON-LD,
keywords, softwareVersion 2.1

SEO: llms.txt vollständig überarbeitet, robots.txt Züchter-Pfade,
sitemap.xml um Wurfbörse + Züchter-Profile erweitert

SW by-v474, APP_VER 451
2026-04-28 19:49:54 +02:00
91340be5a3 Feature: Vollständige Züchter-Rolle — Antrag, Würfe, Stammbaum, Genetik
Basis-Features (Schritte 1–11):
- Züchter-Antrag mit Dokument-Upload, Admin-Prüfung, E-Mail-Benachrichtigungen
- Öffentliches Züchter-Profil + Karten-Marker (lila, certificate-Icon)
- Wurfverwaltung: Würfe, Welpen, Gewichtsverlauf, Foto-System
- Wurfbörse (öffentlich) mit Filtersuche nach Rasse/Status
- Läufigkeits-Tracker: Deckdatum + Wurftermin (+63 Tage, nur für Züchter)
- Interessenten-Chat: Kontakt-Button in Wurfbörse und Züchter-Profil
- Sidebar-Einträge: Zuchtkartei + Wurfverwaltung für Züchter/Admin

Stammbaum & Genetik (Schritte 1–8):
- Zuchtkartei: Hunde-Stammdaten mit Vater/Mutter-Verknüpfung
- Stammbaum-Visualisierung: 4 Generationen, horizontales CSS-Grid
- Gesundheitstests (HD, ED, OCD, Augen…) mit farbigen Ergebnis-Badges
- Genetische Tests (MDR1, PRA, DM…): clear/carrier/affected
- Titel & Auszeichnungen (CAC, CACIB, IPO…)
- Probeverpaarung: IK-Berechnung nach Wright + Ampel-Bewertung
- Teilen-Link für öffentliche Hunde-Profile
- Kaufvertrag: druckbares HTML-Dokument pro Welpe

Technisch: 4 neue Route-Dateien, 5 neue Page-Module, 11 neue DB-Tabellen,
icons shield-check + certificate + tree-structure im Sprite — SW by-v465, APP_VER 444
2026-04-28 18:25:21 +02:00
e35a7a2692 Feature: QR-Code mit Logo im Referral-Block — SW by-v441, APP_VER 420
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.
2026-04-27 06:23:01 +02:00
b4c3698a3a Fix: Installationsanleitung scrollt direkt zur Install-Karte — SW by-v440, APP_VER 419
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.
2026-04-27 06:16:39 +02:00
a698bec817 Desktop: Settings max-width 640→860px via page-container — SW by-v410 2026-04-26 08:30:06 +02:00
553e9e7854 Sprint 12+13: Tagebuch Day-One-Redesign, Notiz-Feature, Icon-Fixes, SW by-v405
Tagebuch:
- Day-One-Listenansicht: Wochentag + Tageszahl + Meta-Zeile (Zeit/Ort/Wetter)
- 4 Ansichten: Liste, Medien-Mosaik, Kalender (mit Sprungbuttons), Karte (GPS-Marker)
- Detail-Ansicht inline im Content-Bereich (kein Fullscreen-Overlay mehr)
- Hero-Bild vollständig sichtbar (object-fit:contain), Lightbox mit Safe-Area
- 2-Spalten-Layout Desktop: Text + Leaflet-Karte + POI-Liste
- EXIF-GPS-Extraktion bei Foto-Upload, historisches Wetter via Archive-API
- NoteStation-Import: Fotos in diary_media (80 Einträge migriert, 94 Medien)
- Stats-Endpoints: /diary/stats, /diary/calendar, /diary/locations

Notiz-Feature:
- Generische notes-Tabelle (parent_type + parent_id + meta_json)
- 📝-Button in 8 Bereichen, Notizblock-Seite mit KI-Analyse
- KI-Toggle in Einstellungen, notes_ki_enabled in User-Profil

Icons & Design:
- fill:currentColor Fix für welcome/onboarding/friends.js
- --c-icon Variable, --c-text-muted Dark Mode aufgehellt
- 15+ neue Phosphor-Icons aus lokaler Kopie
- CSS Network-First im SW, Cache-Control-Middleware

Infrastruktur:
- Wiki-Anreicherungs-Scheduler-Jobs entfernt (abgeschlossen)
- auth.py: notes_ki_enabled + is_social_media im User-Response
2026-04-25 20:44:46 +02:00
af4b1a4a55 Registrierung: Hundepassphrase-Generator (3 Wörter + Zahl, 60+ Hundewörter), SW by-v367 2026-04-25 10:08:42 +02:00
5141ba9969 Session 2026-04-20: Medien-Konvertierung, Umami Analytics, Username/Privacy
- HEIC→JPEG, MOV/AVI→MP4 Konvertierung bei allen Upload-Endpoints (media_utils.py)
- ffmpeg im Docker-Image, Video-Thumbnails (extract_video_thumb, poster-Attribut)
- Google Analytics entfernt, Umami self-hosted eingebunden (index.html, datenschutz.js)
- Admin-Panel Analytics-Tab: Stat-Cards, Sparkline 7 Tage, Top-Seiten (Umami-API-Proxy)
- Admin-Panel Tab-Icons korrigiert (aus vorhandenem Phosphor-Sprite)
- users.real_name Spalte: Username öffentlich, echter Name privat und optional
- Registrierung: Label "Benutzername", Leerzeichen verboten, Profanity-Blockliste
- Datenschutzerklärung: GA-Abschnitt durch Umami-Text ersetzt
2026-04-20 18:36:58 +02:00
9a78121a3e Session 2026-04-19: Navigation, Kompass, Übungsfortschritt
Routen-Navigation:
- POI-Marker: farbige Kreise mit Phosphor-Icons (wie Hauptkarte)
- Screensaver: Navi-Pfeil dreht sich via DeviceOrientationEvent (iOS+Android)
- Pfeil-Dämpfung: EMA α=0.12 mit Wrap-Around
- GPS-Distanz-Bug: Fortschritt nur wenn <500m zur Route
- fitBounds: User-Position nur wenn <20km von Route
- Screensaver: "zur Route" vs "verbleibend" kontextabhängig
- Richtungspfeile entlang Route (blau, max 7 Stück)
- Umkehren ins Route-Detail verschoben, Detail-Map rebuildet sich
- rk-header z-index:10 (Leaflet-Tiles liefen drüber)
- 2-Sek. Screensaver-Entsperrung

km-Tracking:
- route_walks Tabelle
- POST /api/routes/{id}/walked (≥50%)
- total_km = erstellte Routes + gelaufene route_walks
- Toast bei neuem Badge

Übungsfortschritt:
- exercise_progress + training_plan_progress Tabellen
- GET/POST /api/training/progress, /plan-progress, /suggestions
- uebungen.js: API-first + localStorage-Fallback + Auto-Migration
- Empfehlungs-Banner (regelbasiert)
- Toast bei "sitzt"
2026-04-19 20:33:01 +02:00
6d757b86c2 Feature: Referral-System — User wirbt User
- DB: referral_code (8-stellig, eindeutig) + referred_by zu users
  Bestehende User erhalten automatisch einen Code
- GET /api/auth/referral: Code, Link und Anzahl geworbener User
- POST /api/auth/register: ref_code Parameter für Zuordnung
- Settings: 'App empfehlen'-Karte mit Link, Teilen-Button und Botschafter-Badges
  (Botschafter ab 1, Super ab 5, Top ab 10 Einladungen)
- app.js: ?ref=CODE aus URL in sessionStorage speichern
- APP_VER 222, SW by-v244
2026-04-19 11:09:24 +02:00
eb3f7b94b2 Feature: Dark Mode — System/Hell/Dunkel-Toggle in Einstellungen
CSS-Variablen für Dark Mode in design-system.css (system + manuell via
data-theme), Flash-freies Inline-Script in index.html, Toggle in
settings.js (by_theme in localStorage). SW by-v210, APP_VER 179.
2026-04-18 18:40:34 +02:00
8fdca1f211 Feature: Passwort-Sichtbarkeits-Toggle in Login- und Registrier-Formular
Eye/Eye-Slash-Button neben Passwort-Felder (Phosphor Icons), schaltet type password/text um. SW by-v199, APP_VER 167.
2026-04-18 13:34:21 +02:00
f8d354749d Feature: Tagebuch Ort/POI, Foto/Video-Edit, Modal-UX, iOS-Fixes
Tagebuch — Ort/POI (DayOne-ähnlich):
- diary.location_name Spalte, DiaryCreate/Update mit gps_lat/lon/location_name
- GET /api/dogs/{id}/diary/nearby: Overpass + Nominatim (vor {entry_id}-Route)
- Mini-Karte im Edit-Formular: Leaflet lazy, Edit-Modus, SVG-Pin
- Meilenstein-Toggle: Button statt Checkbox, Filter in Toolbar
- Datenmigration: 97 Ort-Einträge aus text → location_name

Tagebuch — Foto/Video:
- Foto/Video im Edit: Ersetzen + Löschen, DELETE media endpoint
- Media-Picker: Kamera/Mediathek/Datei Buttons
- Video-Wiedergabe (<video controls> in Detail + Edit)

Modal-UX (alle Edit-Karten vereinheitlicht):
- Footer-Pattern: [Speichern vollbreit] / [Löschen][Abbrechen]
- diary, dog-profile, events, health, places, walks, settings, sitting
- Löschen aus Detail-Modal → Edit-Form verschoben

iOS Mobile-Fixes:
- Auto-Zoom: input/select/textarea font-size 16px !important
- Scroll-Through: html.modal-open + touch-action:none auf Overlay
- Kein position:fixed mehr auf body (kein Scroll-Sprung)

PWA & Icons:
- icon-512-any.png + icon-192-any.png (quadratisch, maskable)
- manifest.json: purpose any/maskable getrennt
- Gesundheits-Icon: syringe → first-aid

Import-Fix:
- _HTMLStripper überspringt video/audio/script → kein "Video nicht gefunden" mehr
2026-04-18 11:56:54 +02:00
bf268e3ffd Fix: Mobile-Audit — Notifications Delete-Button, Health-Grid, Settings-Padding 2026-04-18 00:03:39 +02:00
92620c2c52 Sprint 18: Notification Center, Routen entdecken, Onboarding, Admin-Erweiterungen
- Notifications: History-Tabelle, /api/notifications Endpoints, push.py schreibt in DB
- Notifications: Page (notifications.js) mit Badge, Typen-Icons, gelesen-Markierung
- Routen: Entdecken-Modus mit Ersteller-Anzeige, Nearby-Filter, Mine/Discover Toggle
- Onboarding: Willkommens-Modal nach Registrierung, Push-Angebot nach Login
- Admin: Scheduler-Tab (Jobs anzeigen + manuell triggern), System-Health (DB/Disk/Uptime)
- Admin: Audit-Log (wer hat was wann gemacht), erweiterte Stats (Push-Abos, aktive User, Routen)
- SW: by-v152, APP_VER 125
2026-04-17 23:21:48 +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
a0e1a26bd2 Fix: Kalender-Abo — UI.escape entfernt (existiert nicht in UI) 2026-04-17 10:06:18 +02:00
21e634b409 Fix: Kalender-Abo — UI.escHtml → UI.escape (Methode existiert nicht) 2026-04-17 09:59:07 +02:00
a60db21782 Sprint 14: Profil-Editor in Settings — Avatar-Upload, Bio, Wohnort, Erfahrung, Social-Link, Sichtbarkeit 2026-04-17 09:20:42 +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
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
472e0dd63f Hunde-Profil + Login/Register + Auth-Redirect
dog-profile.js: Profil anlegen, anzeigen, bearbeiten, Foto-Upload,
  Alter-Berechnung, Löschen (mit Confirm).
settings.js: Login/Register-Tabs, Logout, Push-Subscription,
  nach Login → Tagebuch oder Profil anlegen.
app.js: _onLoggedOut() leitet direkt zur Settings-Seite weiter.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 17:57:51 +02:00