"""BAN YARO — Hund teilen (Familie/Partner)""" import secrets from fastapi import APIRouter, Depends, HTTPException from pydantic import BaseModel from database import db from auth import get_current_user # Hunde-spezifische Routen → eingebunden unter /api/dogs dog_router = APIRouter() # Token-basierte Routen → eingebunden unter /api/share share_router = APIRouter() class ShareInvite(BaseModel): role: str = "editor" # viewer | editor # ------------------------------------------------------------------ # POST /api/dogs/{dog_id}/share → Einladungs-Link erzeugen # ------------------------------------------------------------------ @dog_router.post("/{dog_id}/share", status_code=201) async def create_share(dog_id: int, data: ShareInvite, user=Depends(get_current_user)): if data.role not in ("viewer", "editor"): raise HTTPException(400, "Rolle muss 'viewer' oder 'editor' sein.") with db() as conn: dog = conn.execute( "SELECT id, name FROM dogs WHERE id=? AND user_id=?", (dog_id, user["id"]) ).fetchone() if not dog: raise HTTPException(404, "Hund nicht gefunden.") token = secrets.token_urlsafe(24) conn.execute( """INSERT INTO dog_shares (dog_id, owner_id, invite_token, role) VALUES (?, ?, ?, ?)""", (dog_id, user["id"], token, data.role), ) return {"token": token, "invite_path": f"/teilen/{token}"} # ------------------------------------------------------------------ # GET /api/dogs/{dog_id}/shares → aktive Einladungen auflisten # ------------------------------------------------------------------ @dog_router.get("/{dog_id}/shares") async def list_shares(dog_id: int, user=Depends(get_current_user)): with db() as conn: dog = conn.execute( "SELECT id FROM dogs WHERE id=? AND user_id=?", (dog_id, user["id"]) ).fetchone() if not dog: raise HTTPException(404, "Nicht gefunden.") rows = conn.execute( """SELECT ds.id, ds.invite_token, ds.role, ds.accepted_at, u.name AS shared_with_name, u.email AS shared_with_email FROM dog_shares ds LEFT JOIN users u ON u.id = ds.shared_with_id WHERE ds.dog_id = ? ORDER BY ds.created_at DESC""", (dog_id,) ).fetchall() return [dict(r) for r in rows] # ------------------------------------------------------------------ # DELETE /api/dogs/{dog_id}/share/{share_id} → Freigabe widerrufen # ------------------------------------------------------------------ @dog_router.delete("/{dog_id}/share/{share_id}", status_code=204) async def revoke_share(dog_id: int, share_id: int, user=Depends(get_current_user)): with db() as conn: dog = conn.execute( "SELECT id FROM dogs WHERE id=? AND user_id=?", (dog_id, user["id"]) ).fetchone() if not dog: raise HTTPException(404, "Nicht gefunden.") conn.execute( "DELETE FROM dog_shares WHERE id=? AND dog_id=?", (share_id, dog_id) ) # ------------------------------------------------------------------ # POST /api/share/accept/{token} → Einladung annehmen # ------------------------------------------------------------------ @share_router.post("/accept/{token}") async def accept_share(token: str, user=Depends(get_current_user)): with db() as conn: share = conn.execute( """SELECT ds.*, d.name AS dog_name, u.name AS owner_name FROM dog_shares ds JOIN dogs d ON d.id = ds.dog_id JOIN users u ON u.id = ds.owner_id WHERE ds.invite_token = ?""", (token,) ).fetchone() if not share: raise HTTPException(404, "Einladungslink ungültig oder abgelaufen.") if share["owner_id"] == user["id"]: raise HTTPException(400, "Das ist dein eigener Hund.") if share["accepted_at"]: return {"message": "Bereits angenommen.", "dog_name": share["dog_name"]} conn.execute( """UPDATE dog_shares SET shared_with_id = ?, accepted_at = datetime('now') WHERE invite_token = ?""", (user["id"], token), ) return { "message": "Einladung angenommen!", "dog_name": share["dog_name"], "owner_name": share["owner_name"], } # ------------------------------------------------------------------ # GET /api/share/info/{token} → Info vor dem Annehmen (kein Auth nötig) # ------------------------------------------------------------------ @share_router.get("/info/{token}") async def share_info(token: str): with db() as conn: share = conn.execute( """SELECT d.name AS dog_name, d.foto_url, d.rasse, u.name AS owner_name, ds.role, ds.accepted_at FROM dog_shares ds JOIN dogs d ON d.id = ds.dog_id JOIN users u ON u.id = ds.owner_id WHERE ds.invite_token = ?""", (token,) ).fetchone() if not share: raise HTTPException(404, "Einladungslink ungültig.") return dict(share)