"""BAN YARO — Notification Center Routes""" import logging from fastapi import APIRouter, Depends, HTTPException from database import db from auth import get_current_user router = APIRouter() logger = logging.getLogger(__name__) # ------------------------------------------------------------------ # GET /api/notifications — letzte 50 Benachrichtigungen des Users # ------------------------------------------------------------------ @router.get("") async def list_notifications(user=Depends(get_current_user)): with db() as conn: rows = conn.execute( """SELECT id, type, title, body, data, read_at, created_at FROM notifications WHERE user_id = ? ORDER BY created_at DESC LIMIT 50""", (user["id"],), ).fetchall() return [dict(r) for r in rows] # ------------------------------------------------------------------ # GET /api/notifications/unread-count — Anzahl ungelesener Einträge # ------------------------------------------------------------------ @router.get("/unread-count") async def unread_count(user=Depends(get_current_user)): with db() as conn: row = conn.execute( "SELECT COUNT(*) FROM notifications WHERE user_id=? AND read_at IS NULL", (user["id"],), ).fetchone() return {"count": row[0]} # ------------------------------------------------------------------ # GET /api/notifications/badge — Dot-Indikatoren für Header # personal: Chat, Freunde, Trainer, Sitting, Gesundheit, Meilensteine # general: Gassi-Treffen, Giftköder, Verlorene Hunde, Wetter # ------------------------------------------------------------------ _PERSONAL = { 'chat_message', 'friend_request', 'weekly_praise', 'health_reminder', 'milestone', 'sitting_request', 'sitting_confirmed', 'sitting_cancelled', } _GENERAL = { 'walk_invite', 'lost_dog_alert', 'poison_alert', 'weather_heat', 'weather_thunder', } @router.get("/badge") async def badge_status(user=Depends(get_current_user)): with db() as conn: rows = conn.execute( "SELECT DISTINCT type FROM notifications WHERE user_id=? AND read_at IS NULL", (user["id"],), ).fetchall() types = {r["type"] for r in rows} return { "personal": bool(types & _PERSONAL), "general": bool(types & _GENERAL), } # ------------------------------------------------------------------ # PATCH /api/notifications/read-all — alle als gelesen markieren # ------------------------------------------------------------------ @router.patch("/read-all") async def read_all(user=Depends(get_current_user)): with db() as conn: conn.execute( """UPDATE notifications SET read_at = datetime('now') WHERE user_id = ? AND read_at IS NULL""", (user["id"],), ) return {"ok": True} # ------------------------------------------------------------------ # PATCH /api/notifications/{id}/read — einzelne als gelesen markieren # ------------------------------------------------------------------ @router.patch("/{notif_id}/read") async def read_one(notif_id: int, user=Depends(get_current_user)): with db() as conn: row = conn.execute( "SELECT id FROM notifications WHERE id=? AND user_id=?", (notif_id, user["id"]), ).fetchone() if not row: raise HTTPException(404, "Benachrichtigung nicht gefunden.") conn.execute( "UPDATE notifications SET read_at = datetime('now') WHERE id=?", (notif_id,), ) return {"ok": True} # ------------------------------------------------------------------ # DELETE /api/notifications/{id} — löschen # ------------------------------------------------------------------ @router.delete("/{notif_id}") async def delete_one(notif_id: int, user=Depends(get_current_user)): with db() as conn: row = conn.execute( "SELECT id FROM notifications WHERE id=? AND user_id=?", (notif_id, user["id"]), ).fetchone() if not row: raise HTTPException(404, "Benachrichtigung nicht gefunden.") conn.execute("DELETE FROM notifications WHERE id=?", (notif_id,)) return {"ok": True}