145 lines
5.2 KiB
Python
145 lines
5.2 KiB
Python
"""BAN YARO — Ernährungs-Routes"""
|
|
|
|
import logging
|
|
from fastapi import APIRouter, Depends, HTTPException, Request
|
|
from pydantic import BaseModel
|
|
from typing import Optional
|
|
from database import db
|
|
from auth import get_current_user
|
|
import ki as ki_module
|
|
|
|
router = APIRouter()
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
# ------------------------------------------------------------------
|
|
# Schemas
|
|
# ------------------------------------------------------------------
|
|
class FutterProfilUpdate(BaseModel):
|
|
futter_typ: Optional[str] = None # trocken|nass|barf|mix
|
|
marke: Optional[str] = None
|
|
kcal_tag: Optional[int] = None
|
|
portionen: Optional[int] = None
|
|
notizen: Optional[str] = None
|
|
|
|
|
|
class KiBeratungRequest(BaseModel):
|
|
frage: str
|
|
dog_name: Optional[str] = None
|
|
rasse: Optional[str] = None
|
|
alter: Optional[str] = None
|
|
gewicht: Optional[float] = None
|
|
aktiv: Optional[bool] = None
|
|
|
|
|
|
# ------------------------------------------------------------------
|
|
# Hilfsfunktion: Zugriffsprüfung
|
|
# ------------------------------------------------------------------
|
|
def _check_dog_access(conn, dog_id: int, user_id: int):
|
|
row = conn.execute(
|
|
"SELECT id FROM dogs WHERE id=? AND user_id=?", (dog_id, user_id)
|
|
).fetchone()
|
|
if not row:
|
|
raise HTTPException(404, "Hund nicht gefunden.")
|
|
|
|
|
|
# ------------------------------------------------------------------
|
|
# GET /dogs/{dog_id}/ernaehrung
|
|
# ------------------------------------------------------------------
|
|
@router.get("/{dog_id}/ernaehrung")
|
|
async def get_ernaehrung(dog_id: int, user=Depends(get_current_user)):
|
|
with db() as conn:
|
|
_check_dog_access(conn, dog_id, user["id"])
|
|
row = conn.execute(
|
|
"SELECT * FROM futter_profil WHERE dog_id=?", (dog_id,)
|
|
).fetchone()
|
|
if not row:
|
|
return {}
|
|
return dict(row)
|
|
|
|
|
|
# ------------------------------------------------------------------
|
|
# PUT /dogs/{dog_id}/ernaehrung
|
|
# ------------------------------------------------------------------
|
|
@router.put("/{dog_id}/ernaehrung")
|
|
async def put_ernaehrung(dog_id: int, body: FutterProfilUpdate,
|
|
user=Depends(get_current_user)):
|
|
with db() as conn:
|
|
_check_dog_access(conn, dog_id, user["id"])
|
|
existing = conn.execute(
|
|
"SELECT id FROM futter_profil WHERE dog_id=?", (dog_id,)
|
|
).fetchone()
|
|
if existing:
|
|
conn.execute("""
|
|
UPDATE futter_profil
|
|
SET futter_typ=COALESCE(?, futter_typ),
|
|
marke=COALESCE(?, marke),
|
|
kcal_tag=COALESCE(?, kcal_tag),
|
|
portionen=COALESCE(?, portionen),
|
|
notizen=COALESCE(?, notizen),
|
|
updated_at=datetime('now')
|
|
WHERE dog_id=?
|
|
""", (body.futter_typ, body.marke, body.kcal_tag,
|
|
body.portionen, body.notizen, dog_id))
|
|
else:
|
|
conn.execute("""
|
|
INSERT INTO futter_profil
|
|
(dog_id, futter_typ, marke, kcal_tag, portionen, notizen)
|
|
VALUES (?, ?, ?, ?, ?, ?)
|
|
""", (dog_id, body.futter_typ, body.marke, body.kcal_tag,
|
|
body.portionen or 2, body.notizen))
|
|
row = conn.execute(
|
|
"SELECT * FROM futter_profil WHERE dog_id=?", (dog_id,)
|
|
).fetchone()
|
|
return dict(row)
|
|
|
|
|
|
# ------------------------------------------------------------------
|
|
# POST /dogs/{dog_id}/ernaehrung/ki-beratung
|
|
# ------------------------------------------------------------------
|
|
@router.post("/{dog_id}/ernaehrung/ki-beratung")
|
|
async def ki_ernaehrung(dog_id: int, body: KiBeratungRequest,
|
|
request: Request,
|
|
user=Depends(get_current_user)):
|
|
if not body.frage or len(body.frage.strip()) < 3:
|
|
raise HTTPException(400, "Bitte stelle eine Frage.")
|
|
if len(body.frage) > 800:
|
|
raise HTTPException(400, "Frage zu lang (max. 800 Zeichen).")
|
|
|
|
with db() as conn:
|
|
_check_dog_access(conn, dog_id, user["id"])
|
|
|
|
dog_name = body.dog_name or "unbekannt"
|
|
rasse = body.rasse or "unbekannt"
|
|
alter = body.alter or "unbekannt"
|
|
gewicht = f"{body.gewicht} kg" if body.gewicht else "unbekannt"
|
|
aktiv_str = "aktiv" if body.aktiv else "normal aktiv"
|
|
|
|
system = (
|
|
"Du bist Ernährungsberater für Hunde. "
|
|
"Antworte immer auf Deutsch, kurz und praktisch. "
|
|
"Keine unnötigen Füllsätze. "
|
|
"Weise bei ernsthaften Gesundheitsfragen immer auf den Tierarzt hin. "
|
|
"Stelle keine medizinischen Diagnosen."
|
|
)
|
|
|
|
prompt = (
|
|
f"Hund: {dog_name}, Rasse: {rasse}, Alter: {alter}, "
|
|
f"Gewicht: {gewicht}, Aktivität: {aktiv_str}.\n\n"
|
|
f"Frage: {body.frage.strip()}\n\n"
|
|
"Antworte konkret und praktisch, maximal 200 Wörter."
|
|
)
|
|
|
|
try:
|
|
antwort = await ki_module.complete(
|
|
prompt=prompt,
|
|
system=system,
|
|
max_tokens=500,
|
|
requires_premium=False,
|
|
user_id=user["id"],
|
|
)
|
|
return {"antwort": antwort}
|
|
except ki_module.KIUnavailableError as e:
|
|
raise HTTPException(503, str(e))
|
|
except Exception:
|
|
raise HTTPException(500, "KI momentan nicht verfügbar.")
|