Commit graph

47 commits

Author SHA1 Message Date
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
2ddd8ac350 Fix: alle funktionalen Inline-Event-Handler → addEventListener/Delegation (von CSP-Härtung 65cfa25 app-weit blockiert)
Chat (senden/öffnen/löschen/Foto), Tagebuch-Buch, KI-Berichte, Wiki-Moderation,
Events-Detail, Walks-Lightbox, Routen-Foto, Navigations-CTAs (data-page),
Presse-Copy + Züchter-Landing (externes JS). 35x UI.modal.close → data-modal-close,
28x totes event.stopPropagation entfernt. Verbleibend: kosmetische onerror/Hover. SW v1164
2026-06-04 13:59:27 +02:00
55b354e865 Freunde: Annehmen/Ablehnen-Buttons mit Text-Label (Icon-only war für Nutzer nicht erkennbar) + Fix /apifriends/same-breed Slash-Bug, SW v1162 2026-06-04 12:27:01 +02:00
6bc63e3818 dog-profile: 'Später erinnern'-Button auf Standalone-Anlage-Seite
Wer aus dem Onboarding (Schritt 1 'Los geht's' navigiert direkt auf
#dog-profile) keinen Hund anlegen will, war bisher in der Form
festgehängt — kein Skip, kein Zurück.

Jetzt: ghost-Button unter dem Submit, setzt by_onboarding_done und
schickt zurück auf die Welten/Welcome. Bumpe auf 1135.
2026-05-30 17:38:12 +02:00
1ff66a7083 Sicherheit + Tests + A11y, SW by-v1118
PYDANTIC max_length (38 Routen, ~400 Field-Constraints):
Schützt vor DoS durch Riesen-Payloads (10MB Thread-Titel etc.).
Pragmatische Limits:
- Titel/Name: 200 · Beschreibung/Body: 10000 · Notiz: 5000
- Email: 254 (RFC 5321) · URL: 500 · Slug/Kategorie: 100
- Hund-Name/Rasse: 80 · Hund-Bio: 2000

Top-betroffen: forum.py, diary.py, health.py, dogs.py, expenses.py,
notes.py, auth.py, profile.py. Manuelle len()-Checks in profile,
chat, ki entfernt (jetzt durch Field abgedeckt).

PYTEST COVERAGE (+19 Tests, 37 grün + 1 xfail):
- test_security.py: require_owner (Places GET/PATCH/DELETE mit
  Fremduser → 403), JWT-Blacklist (Logout invalidiert Token),
  Login-Lockout (5 Fehlversuche → 429 + Retry-After Header)
- test_race.py: Invoice-Counter (20 parallele Threads, alle unique),
  Founder-Number (atomare Vergabe, voll bei 100)
- test_validation.py: Forum-Titel 30k Zeichen → 422, Diary-Text
  50k → 422 (verifiziert Pydantic max_length-Sweep)

A11Y (Tap-Targets ≥44×44 + Dark-Mode-Kontrast):
- #header-user-btn 36→44px, .header-back 40→44, .header-menu-btn 40→44
- dog-profile Wrapped-Slider Prev/Next 40→44
- forum-Lightbox Close 40→44
- --c-text-muted Light: #B0A090 (2.37:1 FAIL) → #7F6B58 (4.74:1 PASS)
- --c-text-muted Dark:  #806A58 (3.58:1 FAIL) → #A08878 (5.46:1 PASS)
- Branding-Farben unangetastet
2026-05-27 13:40:30 +02:00
c517c9281d Refactor: 1167 _esc() → UI.escape() in 36 Dateien, SW by-v1113
Bündel 1 aus dem Duplikat-Audit: existierende zentrale Helper nutzen
statt lokale Duplikate.

Pure Migration ohne neuen Code:
- 1167 _esc()-Aufrufe in 36 Page-Modulen migriert auf UI.escape()
- 24 lokale _esc/_escape-Definitionen entfernt
- lost.js hatte _escape() (Variante) — 17 Aufrufe ebenfalls migriert
- jobs.js + breeder.js: tote Alias-Wrapper entfernt

UI.escape() existierte schon — wurde nur überall lokal nochmal
implementiert. Funktional identisch (gleiche 4-replace-chain für
& < > ").

Tests 19/19 grün. Frontend-LOC um ~120 Zeilen reduziert.

Hinweis: _emptyState (7 Stellen) und _icon (8 Stellen) wurden NICHT
migriert — sie haben abweichende Signaturen von UI.emptyState({...})
bzw. UI.icon(name). Eigener Sprint nötig.
2026-05-27 10:15:33 +02:00
459cd425f2 Design-System Sprint A: utilities.css + 948 Inline-Styles → Utility-Klassen, SW by-v1102
PHASE 1 — Sofort-Cleanup ohne Risiko:
- Neue Datei utilities.css mit ~25 Klassen für häufige Kombinationen:
  * text-xs-muted, text-xs-secondary, text-sm-muted, text-sm-secondary
  * flex-gap-2/3, flex-col-gap-2/3/4, flex-center-gap-1/2/3
  * flex-between, flex-1-min, mb-1/3, mt-1/3
  * icon-xs/sm/md/lg, label-block, caption
- index.html bindet utilities.css ein
- mb-3/mt-3 ergänzt (waren in design-system.css unvollständig)

PHASE 2 — .by-tab Modifier für Vereinheitlichung:
- .by-tabs.grid (mit --tab-cols Variable für Admin/Health/etc.)
- .by-tabs.sticky (Desktop vertikale Tabs für Admin)
- .by-tabs.wrap (Zuchthunde, flex-wrap statt scroll)
- .by-tabs.separated (Sitting, mit eigenem Hintergrund + Border)

PHASE 3 — Inline-Style → Klassen-Migration (Python-Script):
- 948 Inline-Styles entfernt (5101 → 4153, -18%)
- 962 Migrationen über 47 Page-Dateien
- Top-Treffer: admin.js (180), health.js (67), dog-profile.js (67),
  litters.js (62), settings.js (61), zuchthunde.js (51)
- Patterns: text-muted, text-secondary, text-danger, text-xs-muted,
  text-sm-muted, grid-2 (Duplikat-Bug behoben!), flex-col-gap-3,
  p-3/4, mb-2/3/4, hidden, w-full, flex-1, ...
- Bewahrt bestehende class-Attribute (mergt korrekt)

Alle 19 Tests grün. Kein visueller Diff erwartet (gleiche Property-Werte).
2026-05-27 07:11:27 +02:00
c03884cb81 Perf: 9 Performance-Fixes — SW by-v1072
Backend:
- DB: 3 neue Indizes (forum_posts thread+user, routes user) — Forum/Routen-Queries
- Caching: cache.py (TTL-Cache ohne neue Dependency) für 5 statische Listen
  (training_exercises, pflege_tipps, wiki_stats, wiki_gruppen, help_articles)
- diary.py + breeder_photos.py: Bildverarbeitung (ffmpeg/PIL/EXIF) per
  run_in_executor → blockiert Event-Loop nicht mehr
- scheduler.py: 11 kollidierende Jobs auf 5-Min-Intervalle gestaggert, coalesce=True
- social.py: ORDER BY RANDOM() ohne LIMIT in 2 Stellen gefixt
- alerts.py: Haversine-Loop bekommt SQL-Bounding-Box-Vorfilter

Frontend:
- sw.js: Tile-Cache mit LRU-Eviction (max 500 Einträge)
- admin.js: Event-Listener-Leak — Tab-Klicks per Delegation statt N Listener
- api.js: compressImage() Helper — Client-seitiges Resize auf max 2000px
  (HEIC/Videos/<500KB unverändert), integriert in 8 Upload-Stellen
  (diary, dog-profile×2, walks, poison, lost, health×2)

Bump APP_VER 1071 → 1072 (sw.js, app.js, main.py, index.html)
2026-05-26 06:30:36 +02:00
e397b9dff5 Fix: SW-Cache /api/dogs nach Foto-Upload löschen (SW by-v937)
_renderHund() liest Hunde aus _cachedGet('/dogs') — SW-gecacht mit altem foto_url.
Fix: swCacheDelete für /api/dogs, /api/dogs/{id} + welcome-dashboard, plus w3_dogs.
2026-05-14 12:34:26 +02:00
fbb070032a Fix: SW-Cache welcome-dashboard nach Foto-Upload löschen (SW by-v935)
Root cause: /api/dogs/{id}/welcome-dashboard ist SW-gecacht.
Nach Foto-Upload lieferte SW alten Response mit alter random_photo.url.
Fix: API.swCacheDelete() + localStorage-Key nach Upload invalidieren.
2026-05-14 12:18:48 +02:00
aa379d8e08 Fix: Foto-Upload → sofortiger Refresh von Profil + DogSwitcher + Welten (SW by-v934) 2026-05-14 12:11:59 +02:00
08f1806be3 Fix: Foto-Upload im Hunde-Profil Edit-Modal (SW by-v933)
Root cause: fotoFile-Referenz wurde NACH UI.modal.close() geholt — DOM-Element
#dp-form-foto existiert nach Modal-Close nicht mehr → files[0] = undefined → Upload übersprungen.
Fix: fotoFile VOR modal.close() sichern; File-Objekt bleibt gültig auch ohne DOM.
2026-05-14 12:03:25 +02:00
567478a866 Fix: Altes Hundeprofil-Foto wird beim Überschreiben gelöscht (SW by-v930)
- dogs.py /photo: alte foto_url vor Upload merken, nach Speichern von Disk löschen
- dog-profile.js: Hintergrund-Cache nach Foto-Wechsel invalidieren
2026-05-14 11:47:08 +02:00
00457f52f9 Fix: Datenschutz Hintergrundbild + Dog-Refresh nach Anlegen (SW by-v928)
- dogs.py: welcome-dashboard Foto-Queries filtern jetzt auch nach user_id
- worlds.js: Background Cache-Key enthält user_id (kein Cross-User Leakage)
- worlds.js: Worlds.refresh(appState) neu
- dog-profile.js: Worlds.refresh() nach Hund anlegen aufrufen
2026-05-14 11:35:53 +02:00
83034c0db0 Feature: Widerristhöhe im Hundeprofil + Ausweis-Fix (SW by-v873) 2026-05-11 21:30:07 +02:00
bda61a0e40 Feature: Trauer-Feature, Futter-Verträglichkeit, Multi-Hund-Fixes, Wetter-Ort (Sprint 47)
- dog-profile.js: Verstorben-Button, Gedenkseite, KI-Abschiedstext
- database.py: futter_eintraege/reaktionen, route_dogs, exercise_progress.dog_id
- routes/ernaehrung.py: Futter-Verträglichkeit mit 20 Reaktionstypen + Analyse
- routes/routen.py: route_dogs Many-to-Many, Routen editierbar
- routes/training.py: exercise_progress per dog_id
- routes/ki.py: /ki/abschied Trauer-KI
- weather.py: Nominatim Ortsname parallel geladen
- ui.js: dogChip/bindDogChip, visualViewport-Modal
- api.js: gedenken, gedenkseite, futter-Methoden, route_dogs
- worlds.js: Ortsname im Wetter-Chip
- uebungen.js: _progressLoaded-Flag, dog-spezifischer Fortschritt
- trainingsplaene.js: dog_id Unterstützung
- diary.js/health.js: P-Badge Cleanup
- map.js: Wetter-Ort-Anzeige entfernt
- wetter.js: Ort in Wetter-Detail
2026-05-11 19:28:38 +02:00
ce14bb1d2c Refactoring: Inline-Styles → CSS-Klassen (worlds.js, dog-profile.js, settings.js) — 20 neue w3-/by-Klassen (SW by-v773) 2026-05-08 12:22:04 +02:00
b6eaaad47a Fix: '+ Weiteren Hund anlegen' nur für Pro sichtbar, App.hasPro() public (SW by-v766) 2026-05-08 11:06:23 +02:00
2854c60ba8 Fix: Update-Button hängt nicht mehr (kein await update()), Wrapped-Modal × hinter Notch (safe-area) (SW by-v765) 2026-05-08 10:56:36 +02:00
aa4849d947 Feature: 3 Community-Features — Foto-Challenge, Stamm-Gassis, Rassen-Chip (SW by-v700)
- Foto-Challenge der Woche: DB-Tabellen, routes/challenges.py (current/submit/vote/winners),
  Scheduler-Job jeden Montag 08:00, walks.js Challenge-Tab mit Banner, Galerie, Voting-Herz
- Gassi-Zeiten-Pool: DB-Tabelle gassi_zeiten, routes/gassi_zeiten.py (CRUD + Umkreis),
  walks.js Stamm-Gassis-Tab mit Karten, Wochentag-Selector, Mitmachen→Chat
- Rassen-Treffen-Chip: GET /api/friends/same-breed, dog-profile.js zeigt Chip
  wenn andere User gleiche Rasse haben, Klick → Forum mit Rassen-Suche vorausgefüllt
2026-05-04 21:09:35 +02:00
c5030024b0 Feature: Hunde-Buch — druckbare HTML-Tagebuchansicht als PDF (SW by-v700)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 21:01:54 +02:00
20a4936397 Feature: Ban Yaro Wrapped + Jahrestags- und Monatsrückblick (SW by-v699)
- GET /api/dogs/{id}/wrapped?year= aggregiert km, Gassi-Tage, Fotos,
  Lieblingsmonat/-aktivität, Training, Gesundheit, Wetter-Stats aus SQLite
- Frontend: Wrapped-Fullscreen-Modal in dog-profile.js — 5 Cards mit
  Swipe/Klick-Navigation, Dots, ESC-Taste, Copy-to-Clipboard auf Share-Card
- Scheduler: _job_anniversary_reminders (täglich 09:00) sendet Push wenn
  heute ein Tagebucheintrag von vor 1+ Jahren existiert
- Scheduler: _job_monthly_recap (1. des Monats 10:00) sendet Vormonat-
  Zusammenfassung (km, Einträge, Training) per Push an alle User
- Beide Jobs im Status-Report-Log und Scheduler-Start-Log vermerkt
- SW by-v699, APP_VER 699
2026-05-04 20:54:12 +02:00
a4e97348ed Feature: Schnell-Gassi-Log + Hunde-Visitenkarte mit QR-Code (SW by-v698)
- Worlds-FAB: neuer 'Schnell-Gassi' Button im Gassi-Chip — öffnet schlankes
  Bottom-Sheet mit Dauer-Toggle (15/30/45/60 min), auto-Wetter aus Cache,
  postet direkt als Tagebucheintrag typ='gassi' ohne GPS-Tracking
- dog-profile.js: 'Visitenkarte teilen' Button öffnet Modal mit gestalteter
  Karte (Hundefoto, Name, Rasse/Alter, Wohnort) + QR-Code via qrserver.com,
  Link-kopieren und native Web-Share-API
2026-05-04 20:52:11 +02:00
af1508c0de Feature: Fell-Typ Einstellung am Hundeprofil — personalisierte Wetter-Hinweise (SW by-v693)
- DB-Migration: dogs.fell_typ (kurz|mittel|lang|drahtaar|doppel|nackt)
- Hund-Profil Formular: Dropdown "Felltyp" mit 6 Optionen, wird via PATCH /api/dogs/{id} gespeichert
- Wetter: _dogWeatherLabel(d, felltyp) mit fell-spezifischen Hitze-/Kälteschwellen
- Wetter: Fell-spezifische Hinweise (doppel + Hitze, nackt + Kälte, kurz + Frost)
2026-05-04 20:21:02 +02:00
fb1a9d27cd Feature: Hundepass — Ausweis integriert, Icons & Kontrast-Fix
- Ausweis-Button aus Profil-Ansicht entfernt; stattdessen "Ausweis öffnen"-Button im Hundepass-Modal-Footer
- Bearbeiten-Button in Gesundheits-Info von btn-link auf btn-secondary (besserer Kontrast)
- 7 fehlende Phosphor-Icons zum Sprite hinzugefügt: file-pdf, notebook, link, identification-card, wave-sine, list-checks, share-network
- Leere Sektionen (Impfungen, Medikamente) zeigen einladenden Empty-State mit Icon statt nacktem Text
2026-05-02 10:12:51 +02:00
b47a54db39 Fix: Media-Symlinks beim Start, Sitter-Datenschutztext, Recalls Dark-Mode, Ausweis neuer Tab, SW by-v600 2026-05-02 10:09:06 +02:00
2677cff882 Fix: Ausweis öffnet neuen Tab (kein iframe), Mein Tierarzt im Praxen-Tab integriert, SW by-v599 2026-05-02 09:57:12 +02:00
742ad189e8 Feature: Sprint31 — 9 Features merged (Streak, Ausgaben, KI-Tierarzt, Rückrufe, Adoption, Vet+Befunde, Hundepass, Playdate, Rassenerkennung)
- Trainings-Streak: streak.py, DB training_streaks, Scheduler 19:00, Widget in welcome.js, Ping in uebungen.js
- Ausgaben-Tracker: expenses.py, expenses.js, DB expenses-Tabelle
- KI-Tierarztfragen: ki.py /tierarzt, health.js Button+Modal, DB ki_tierarzt_log
- Rückruf-Alarm: recalls.py, recalls.js, DB feed_recalls, Scheduler 08:00 RASFF
- Adoption: adoption.py, adoption.js, DB adoption_cache
- Tierarzt-Favorit + Befunde: tieraerzte.py /my-favorite+/favorite, health_docs.py, health.js, api.js, DB favorite_vets+health_documents
- Digitaler Hundepass: passport.py, dog-profile.js, main.py /pass/{token}, DB vaccinations+medications+dog_passport_meta+passport_shares, requirements.txt fpdf2
- Playdate-Matching: playdate.py, playdate.js, DB playdate_listings+playdate_requests
- Rassen-Erkennung: ki.py /rasse-erkennung (Claude Vision), dog-profile.js+wiki.js, CSS .rasse-result-card, DB ki_rasse_log
2026-05-02 09:29:48 +02:00
ea2a83b29e Feature: Filme-Suche, HdM ins Forum + Gewinner-Badge im Profil, SW by-v594
- Filme-Seite: Suchfeld (filtert live nach Titel, Rasse, Genre, Beschreibung)
- Filme-Seite: Tab "Hund des Monats" entfernt
- Forum: kompakte HdM-Kachel über der Suche (Sieger + Stimmen), Klick öffnet Abstimmungs-Modal
- Hundeprofil: goldene Badges für jeden gewonnenen Monat (🏆 Mai 2026 …)
- DB: Tabelle hund_des_monats_wins (dauerhaft, dog_id + monat + stimmen)
- Scheduler: Job am 1. des Monats 00:05 — schreibt Vormonats-Sieger, Push an Besitzer
- Dogs-API: liefert hdm_wins[] pro Hund mit
2026-05-02 08:12:29 +02:00
fd76eddfb9 Icons: Emoji/Unicode → Phosphor in 8 Dateien + 16 neue Sprite-Icons — SW by-v415
Sprite: arrow-up/down, bug, check-circle, ear, fish, flask, flower,
        medal, question, scissors, tent, ticket, tooth, trend-up/down

poison.js:     TYPEN (🎣☠️⚗️⚠️) → question/fish/skull/flask/warning
events.js:     TYPEN (🎪🏆🎓🐕🛍️🥇📌) → ticket/trophy/graduation-cap/dog/shopping-bag/medal/push-pin
dog-profile.js: Pflege-Emojis (✂️💅🦷👂👁🐾🦟🌸❤️🐶) → Phosphor
trainingsplaene.js: (🐶🐕🦮) → dog mit SVG-Icon
health.js:     ▲▼→ → trend-up/trend-down/arrow-right
uebungen.js:   ↑↓→★ → trend-up/trend-down/arrow-right/star
admin.js:      ✓✗ → check/x in HTML-Templates
moderation.js: ✓✗ → check/x Buttons
2026-04-26 09:26:13 +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
22225d5717 Pflege: Fell schneiden vs. trimmen + Tagebuch Medien-Button nach oben
- dogs.py: Pflegeart-Filter (trimmen/schneiden) anhand Rassen-Beschreibung
- dog-profile.js: Badge '✂️ Schneiden' / ' Trimmen' bei Fell-Kategorie
- diary.js: Fotos/Videos-Button direkt nach Textfeld (vor Ort und Meilenstein)
- ki.py: Standardmodell auf claude-sonnet-4-6 umgestellt
2026-04-25 08:21:49 +02:00
ba5547f993 Pflege-System: Pflegetipps im Hundeprofil + Rassen-Autocomplete
- GET /api/dogs/{id}/pflege: rassenspezifische Pflegetipps
- pflege_tipps DB-Tabelle (43 Tipps, 10 Kategorien) geseedet
- dogs.rasse_id für Wiki-Verknüpfung (Migration)
- Hundeprofil: Tipp des Tages + alle Tipps aufklappbar
- Hundeprofil-Edit: Rassen-Autocomplete mit Wiki-Match-Badge
- Social: Post-Bestätigung (Gepostet!-Button, Quick-Mark, Pending-Banner)
- Social: Pflegetipp-Button (allg. + rassenspezifisch)
- Social: Diversitäts-Check, Kategorie-Tagging
- Social: 104 Übungen, Übungsübersicht-Modal
- Admin: Social-Media-Tracking-Sektion
- SW by-v356, APP_VER 343
2026-04-24 20:56:47 +02:00
44081a6b9d Session 2026-04-22: Training, Fixes, KI-Cloud, Dark-Mode
Training-System:
- Einheit-Dialog Bugs behoben (UI.toast callable, _dogId via _appState, activeDog.id)
- Virtueller Trainer (rein statistisch): üben/festigen/entdecken/levelup
  Empfehlungen auf Basis exercise_progress + sessions, Prognose bis 80%
- Stand erfassen Modal: alle Übungen auf einmal setzen (onboarding)
- Erfolgsindikatoren auf Karten: Ø-Quote + Trend-Pfeil + Anzahl Sessions
- exercise_progress → synthetische Stats im Trainer (ohne Sessions nutzbar)
- Levelup: Tricks empfehlen wenn ≥4 Grundkommandos sitzen
- Kommandos & Fähigkeiten im Hundeprofil + öffentlichem Profil
- 2 neue Problemverhalten-Übungen: Bellen/Kläffen, Enttriggern

Mobile/UI-Fixes:
- Übungskarten: Name + Difficulty oben, Buttons eigene Zeile (kein Umbruch)
- Trainingsgrundlagen: Padding in allen Karten, Hinweis-Boxen Dark-Mode-sicher
- Tab-Sichtbarkeit: Trainer/Suggestions nur auf Übungs-Tabs
- Tagebuch FAB (Neu-Eintrag Button) + Quick-Add Eintrag
- FAB Abstand fix (nav-bottom-height + safe-bottom)
- Suggestion-Karten rgba (Dark-Mode)
- routes.js + uebungen.js: alle Hellfarben → rgba (Dark-Mode-sicher)
- ui.js: UI.toast als callable Function-Object (war nur plain Object)

KI & Backend:
- KI_MODE=cloud + ANTHROPIC_API_KEY gesetzt
- ki.py: Cloud-Fallback wenn local nicht erreichbar + KI_MODE=cloud
- KI-Trainer Tageslimit 10 Anfragen/User + ki_daily_calls Tabelle
- Admin-Panel: KI-Nutzung (heute/Monat/User)
- Status-Report Fix (lost-Tabelle) → 06:00 + 18:00 täglich
- Wiki-Anreicherung läuft jetzt (50 Rassen Startup, 20/Nacht)
- landing.html: Trainings-Features in JSON-LD + Feature-Karten
2026-04-22 19:41:22 +02:00
289158b2cd Feature: Gasthund-Zugang für Sitter
- sitting_subscriptions Tabelle (dog_id, owner_id, sitter_id, valid_until)
- POST/DELETE/GET /api/sitting-access — Zugang gewähren/widerrufen/auflisten
- GET /api/dogs gibt Gasthunde zurück (is_guest=True, sitting_until, owner_name)
- Diary POST erlaubt Sitter-Schreibzugang; PATCH/DELETE nur für Besitzer
- Dog-Switcher: GAST-Badge bei fremden Hunden
- Dog-Profil: Sitter-Zugang-Sektion (nur für Besitzer), Freund auswählen + Datum
- Diary Detail-View: Bearbeiten-Button für Gasthunde ausgeblendet
2026-04-19 10:29: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
89d87030a2 Sprint 19: Social, UX-Verbesserungen, Nerd2Noob-Hilfe 2026-04-17 23:53:50 +02:00
5927d384bf Fix: Nav-Avatar mit Zoom/Offset, renderDogSwitcher nach Foto-Änderung, Button-Padding 2026-04-17 23:09:42 +02:00
4f12c8e6a4 Fix: Foto-Editor — Prozent-Offsets (Position-Bug), Long-press, Stift-Icon 2026-04-17 23:06:24 +02:00
913cebcba1 Feature: Foto-Editor im Hundeprofil — Zoom, Drag-to-pan, Löschen 2026-04-17 23:00:21 +02:00
cb8ac8cffd Fix: Ausweis als Fullscreen-Modal statt neuem Tab, UI.modal size-Parameter 2026-04-17 22:55:09 +02:00
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
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
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
d8b9561fff Frontend Sprint 3+4: Dog-Switcher, Health-Seite, Multi-Dog Tagebuch
- app.js: vollständiger Dog-Switcher (Avatar im Header/Sidebar, Quickpicker
  bei 3+ Hunden, setActiveDog, localStorage-Persistenz), iOS Ghost-Click Fix,
  Loading-Guard, Logout State Reset
- index.html: Dog-Switcher HTML, Favicon-Links, Sidebar "+ Neu erstellen",
  Navigation Tab Karte → Gesundheit
- health.js (neu): vollständiges Health-Frontend mit Tabs (Impfung, Entwurmung,
  Tierarzt, Medikament, Gewicht-Kurve, Allergie, Dokument), Ampel-System,
  KI-Zusammenfassung
- dog-profile.js: "+ Weiteren Hund anlegen" Button + _openCreateModal(),
  Event-Delegation statt direkter Listener (kein Doppelaufruf)
- diary.js: Dog-Picker im Formular, Avatar-Reihe auf Karten, Dog-Chips
  im Detail-Modal, dog_ids im API-Payload
- poison.js: Erledigt-Dialog mit Grundauswahl (beseitigt/fehlerhaft/anderes)
- api.js: health-Endpoints (list, create, update, delete, upload, ki)
- ui.js: confirm() Fix (resolve vor close)
- layout.css: Dog-Switcher Styles, scrollbare Sidebar-Nav, User-Item fix
- components.css: Health-Styles, Diary Dog-Picker, Ampel-Punkte, Gewicht-SVG
- icons/: Favicon-Set (ico, 16px, 32px, 180px, 192px, 512px)
2026-04-13 19:30:03 +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