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
This commit is contained in:
rene 2026-04-28 19:49:54 +02:00
parent 91340be5a3
commit c8ae514c01
20 changed files with 2129 additions and 200 deletions

View file

@ -356,10 +356,53 @@ async def trial_mating(body: TrialMatingBody, user=Depends(_require_breeder)):
gemeinsame_vorfahren.sort(key=lambda x: x["gen_vater"] + x["gen_mutter"])
# Genetische Risiken für Welfare-Check
genetic_risks = []
try:
vater_gen = conn.execute(
"SELECT marker_name, ergebnis_klasse FROM dog_genetic_tests WHERE hund_id=?", (body.vater_id,)
).fetchall()
mutter_gen = conn.execute(
"SELECT marker_name, ergebnis_klasse FROM dog_genetic_tests WHERE hund_id=?", (body.mutter_id,)
).fetchall()
mutter_map = {r["marker_name"]: r["ergebnis_klasse"] for r in mutter_gen}
RISIKO = {
("carrier","carrier"): "25% betroffen, 50% Träger",
("carrier","affected"): "50% betroffen, 50% Träger",
("affected","carrier"): "50% betroffen, 50% Träger",
("affected","affected"): "100% betroffen",
("clear","affected"): "0% betroffen, 100% Träger",
("affected","clear"): "0% betroffen, 100% Träger",
}
for vg in vater_gen:
ms = mutter_map.get(vg["marker_name"])
if ms:
risk = RISIKO.get((vg["ergebnis_klasse"], ms))
if risk:
genetic_risks.append({"marker": vg["marker_name"], "offspring_risk": risk})
except Exception:
pass
# Züchter-Profil für Welfare
profile = conn.execute(
"SELECT id FROM breeder_profiles WHERE user_id=?", (user["id"],)
).fetchone()
bid = profile["id"] if profile else None
from welfare_check import check_welfare
welfare = check_welfare(
conn, bid or 0,
vater_id=body.vater_id,
mutter_id=body.mutter_id,
ik_prozent=ik_prozent,
genetic_risks=genetic_risks,
)
return {
"ik_prozent": ik_prozent,
"ik_rating": rating,
"ik_prozent": ik_prozent,
"ik_rating": rating,
"gemeinsame_vorfahren": gemeinsame_vorfahren,
"welfare": welfare,
}