Commit graph

72 commits

Author SHA1 Message Date
b54d9fda99 Fix: users.geburtstag Migration + Format TT.MM statt MM-DD
- database.py: ALTER TABLE users ADD COLUMN geburtstag TEXT (fehlte!)
- profile.py: Validierung auf \d{2}\.\d{2} (TT.MM Format)
- settings.js: Placeholder/Pattern auf TT.MM geändert
- worlds.js: Birthday-Check auf DD.MM Format angepasst
SW by-v1029, APP_VER 1029
2026-05-16 12:02:52 +02:00
a4377033ec Feature: User-Geburtstag im Profil + Glückwunsch in JETZT-Welt
Settings:
- Feld 'Dein Geburtstag (optional)' im Profil-Formular (Format MM-TT)
- Hinweis: nur für Geburtstagsgrüße, kein Jahr nötig
- profile.py: geburtstag gespeichert + Format-Validierung MM-DD

JETZT-Welt wenn heute User-Geburtstag:
- Greet-Text: 'Herzlichen Glückwunsch' statt Tageszeit-Gruß
- Animiertes Geburtstags-Reminder-Card (confetti + cake Icons)
- 'Alles Gute zum Geburtstag, [Name]!'

SW by-v1028, APP_VER 1028
2026-05-16 11:55:34 +02:00
d20e63496c Feat: AGB-Link im Footer (Welt-Welt) + AGB-Checkbox im Upgrade-Modal
- worlds.js: 'Datenschutz · AGB' in der Welt-Welt-Fußzeile
- settings.js: AGB-Checkbox über Widerrufs-Checkbox; beide müssen gecheckt sein bevor 'Anfrage senden' aktiv wird
2026-05-15 16:19:46 +02:00
9a7f100855 Legal: Widerrufs-Checkbox im Upgrade-Modal + AGB-Abschnitt in Datenschutz
- Upgrade-Modal: Checkbox §356 Abs.4 BGB muss aktiv bestätigt werden,
  "Anfrage senden" bleibt bis dahin deaktiviert
- Akzeptanz-Zeitstempel wird mit der upgradeRequest-Message mitgeschickt
- datenschutz.js: neuer Abschnitt "Abonnement & Kündigung" mit Laufzeit,
  Verlängerung, Zahlung, Kündigung, Erstattung und Widerrufsrecht
2026-05-15 12:06:14 +02:00
0a466ef6ce Feat: Rechnungsadresse — Profil, Upgrade-Modal Hinweis, Rechnung-erstellen-Button in Upgrade-Cards (SW by-v967) 2026-05-15 10:59:12 +02:00
c8f9bd4c09 Fix: Konto-Löschen-Dialog body→message (SW by-v951) 2026-05-14 16:51:39 +02:00
da4879b4c4 Fix: Kündigung-Anzeige auch ohne Ablaufdatum (SW by-v950) 2026-05-14 16:45:36 +02:00
959fff4651 UX: Kündigung-Toast zeigt Ablaufdatum (SW by-v949) 2026-05-14 16:41:52 +02:00
3b666c545f Feature: Abo-Kündigung + Ablaufdatum + Dog-Auswahl nach Downgrade (SW by-v945) 2026-05-14 13:56:55 +02:00
2a3afa0604 Fix: KI-Notiz-Assistent Toggle nur für Pro-Nutzer sichtbar (SW by-v927) 2026-05-14 11:29:59 +02:00
3b37c14600 UX: Upgrade-Modal mit vollständigen Feature-Listen (SW by-v926)
Pro (29€/Jahr): 3 Gruppen — Hunde (bis 10, getrennte Daten),
  Community (Gassi-Treffen, Chat, Playdate), Tools (Ernährung, Reise, Notizblock, Karten)
Züchter (49€/Jahr): Pro-Inklusive-Badge + 3 Züchter-Gruppen —
  Zucht-Management (Kartei, Wurf, Warteliste, Läufigkeit, Wurf-Rang),
  KI & Analyse (KI-Assistent, Stammbaum, IK-Rechner, Tierschutz-Check, Jahresbericht),
  Sichtbarkeit & Export (Profil, Wurfbörse, Datenexport, Privater Bereich)
2026-05-14 11:23:39 +02:00
4332b1195e Refactor: Züchter-Antrag in Upgrade-Flow integriert (SW by-v925)
- /breeder/apply: Dokument jetzt optional (File(None)), kann per Mail nachgereicht werden
- _showUpgradeModal('breeder'): enthält jetzt Zwinger-Formular (Zwingername*, Rasse*,
  Verein, Stadt, VDH-Checkbox, optionales Dokument)
  → sendet /breeder/apply + /auth/upgrade-request in einem Schritt
- Züchter-Profil-Karte in Settings: 'Züchter werden'-Button entfernt
  → für neue User ohne Antrag wird die Card vollständig ausgeblendet
  → 'Neu beantragen' bei Ablehnung öffnet jetzt _showUpgradeModal('breeder')
- Verifizierte Züchter: Card unverändert (Profil, Edit, KI-Settings)
2026-05-14 11:17:49 +02:00
f6b37717b4 Feature: Upgrade-Anfragen-System — User-Flow + Admin-Panel (SW by-v920)
- DB: upgrade_requests-Tabelle (user_id, tier, message, fulfilled_at)
- POST /api/upgrade-request: Anfrage speichern + Admin-Benachrichtigungsmail
- GET/POST /api/admin/upgrade-requests[/{id}/fulfill]: Admin-Endpunkte
  — fulfill setzt subscription_tier + sendet Bestätigungsmail an User
- action-items: upgrades_pending zählt offene Anfragen → Badge im Admin
- Admin-Tab "Upgrades": Tabelle offener/erledigter Anfragen, Freischalten-Button
  mit Confirm-Modal, automatischer Tier-Setzung und Bestätigungsmail
- Settings: Upgrade-Modal sendet echte API-Anfrage statt nur mailto
  — doppelte Anfrage wird erkannt (already:true → Toast statt Fehler)
- api.js: API.auth.upgradeRequest(tier, message) hinzugefügt
- SW by-v920, APP_VER 920
2026-05-14 09:59:11 +02:00
d61fd155c5 Feature: Abo & Tarif in Einstellungen — Upgrade-UI für Pro + Züchter (SW by-v919)
- /api/me gibt subscription_tier jetzt zurück (fehlte im SELECT)
- settings.js: "Pro kommt bald" durch echte Abo-Karte ersetzt
  - Zeigt aktuellen Tarif mit farbigem Badge (Kostenlos/Pro/Züchter/Admin)
  - Standard-Nutzer: zwei Upgrade-Buttons (Pro 29€/Jahr, Züchter 49€/Jahr)
  - Pro-Nutzer: Pro-Badge + optionaler Züchter-Upgrade
  - Züchter/Admin: Status-Badge, keine Upgrade-Buttons
- Upgrade-Modal: Features-Liste + ehrlicher Hinweis auf manuelle Freischaltung
  + mailto-Button mit vorausgefülltem Betreff und Account-E-Mail
- SW by-v919, APP_VER 919
2026-05-14 09:48:01 +02:00
bf1087c5e1 Feature+Security: DSGVO-Datenexport, auth-geschützte Media, Datenschutzerklärung v2 (SW by-v880) 2026-05-12 17:28:16 +02:00
1ce802c8dc Fix: Ernährung Hund-spezifisch, Erinnerungen in Settings, Übung des Tages per Hund (SW by-v872)
- ernaehrung.js: onDogChange setzt activeTab zurück, Hund klar sichtbar
- settings.js: Erinnerungen-Sektion lädt verstorbene Hunde + öffnet Gedenkseite
- dogs.py: GET /dogs/verstorben Endpoint (korrekte Route-Reihenfolge vor /{dog_id})
- dogs.py: Übung des Tages filtert jetzt nach dog_id statt user_id (sitzt-Übungen korrekt ausgeschlossen)
- Routen zeigen verstorbene Hunde korrekt als Teilnehmer (route_dogs ohne verstorben-Filter)
2026-05-11 19:25:00 +02:00
70af387147 Feature: User-Feedback, Regen-Uhrzeit im Wetter-Chip, Admin-Karten klickbar (SW by-v833)
- Feedback-Modal im Settings (Kategorie + Text → E-Mail an support@banyaro.app)
- Wetter-Chip (Karte + Gassi-Score): zeigt nächste Regenstunde ab ≥20% Wahrscheinlichkeit
- Gassi-Score-Chip: zweizeilige Wetter-Info, linksbündig, volle Chipbreite
- Admin-Übersicht: Stat-Karten anklickbar → navigiert direkt zum jeweiligen Tab
- ui.js: visualViewport-Listener hebt Modal über Tastatur (alle Modals)
- api.js: Pydantic v2 Array-Detail korrekt als Fehlermeldung extrahiert
- map.js: Wetter-Fallback über watchPosition wenn getCurrentPosition scheitert
- Update-Loop-Fix: index.html ?v= synchron mit APP_VER halten (alle 4 Stellen)
2026-05-10 12:52:55 +02:00
1fdd7d4ed0 Fix: theme-color JS-Fallback für Samsung, Wischgesten-Tipp in Settings, _syncThemeColor bei init (SW by-v811) 2026-05-09 22:07:01 +02:00
209d6703ad Fix: Media-Uploads direkt ans Netz (kein SW-Clone), SW _nocache-Bypass, Samsung-Dark-Mode-Hint, Update-Button fire-and-forget (SW by-v796) 2026-05-09 19:07:52 +02:00
e4b170d45b Feature: Konto löschen (Play Store Pflicht) — DELETE /profile/account + Button in Settings (SW by-v786) 2026-05-08 21:03:05 +02:00
e8cf742911 Feature: App-Einstellungen in DB (preferred_theme neu, notes_ki+gassi_stunde schon drin) — geräteübergreifend sync (SW by-v785) 2026-05-08 19:06:29 +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
a1e5364f25 Fix: iOS bfcache — ?_t=timestamp bei Update-Reload, wird sofort aus URL entfernt (SW by-v770) 2026-05-08 11:27:06 +02:00
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