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
This commit is contained in:
rene 2026-04-28 18:25:21 +02:00
parent 58cb2b4ad3
commit 91340be5a3
24 changed files with 6660 additions and 27 deletions

View file

@ -1,18 +1,17 @@
"""
BAN YARO KI-Abstraktions-Layer
Drei Modi:
- "off" kein KI, Feature deaktiviert (Free-User ohne lokales Modell)
- "local" LM Studio auf DS1621 (OpenAI-kompatibler Endpunkt, kostenlos)
- "cloud" Claude API (nur für Premium-User, kostet Geld)
Routing-Logik:
1. Immer lokal (LM Studio) zuerst versuchen
2. Falls lokal nicht erreichbar Fallback auf Cloud (Claude), wenn ANTHROPIC_API_KEY gesetzt
3. Falls beides nicht geht KIUnavailableError
Wird über KI_MODE Umgebungsvariable gesteuert:
KI_MODE=local Entwicklung + Free-User auf DS
KI_MODE=cloud Production + Premium-User
Modi (KI_MODE Umgebungsvariable):
KI_MODE=local lokal + Cloud-Fallback wenn Key vorhanden
KI_MODE=cloud lokal + Cloud-Fallback (gleiche Logik, anderer Label)
KI_MODE=off kein KI verfügbar
Wichtig: cloud-Aufrufe IMMER mit requires_premium=True schützen.
Kein API-Geld ohne zahlenden User.
requires_premium=True schützt Features vor Free-Usern, ändert aber nicht das Routing.
"""
import os
@ -138,16 +137,7 @@ async def complete(
if requires_premium and not user_is_premium:
raise KIPremiumRequired("Dieses Feature ist Teil von Ban Yaro Premium.")
# Cloud-Aufruf: Premium UND cloud-Modus
if requires_premium and user_is_premium and KI_MODE == "cloud":
_check_weekly_cloud_limit(user_id)
text = await _cloud_complete(prompt, system, max_tokens, json_mode)
_track_usage(user_id, "cloud")
if return_model:
return (text, CLOUD_MODEL)
return (text, "cloud") if return_source else text
# Lokaler Aufruf + Cloud-Fallback
# Immer lokal zuerst — Cloud ist Fallback wenn lokal nicht erreichbar
if KI_MODE in ("local", "cloud"):
try:
text = await _local_complete(prompt, system, max_tokens, json_mode)
@ -157,7 +147,7 @@ async def complete(
return (text, "local") if return_source else text
except Exception as e:
logger.warning(f"Lokales KI-Modell nicht erreichbar: {e}")
if ANTHROPIC_KEY and (KI_MODE == "cloud" or (requires_premium and user_is_premium)):
if ANTHROPIC_KEY:
logger.info("Fallback auf Cloud-KI.")
_check_weekly_cloud_limit(user_id)
text = await _cloud_complete(prompt, system, max_tokens, json_mode)