# Author: Simon-Pierre Boucher # Contact: contact@spboucher.ai # Project: Toit-Ka # ----------------------------------------------------------------------------- # favorites.py : routes API des favoris (♥) — session Groupe KA requise. # AUCUN stockage local : lecture et écriture passent par le hub Groupe KA # (magasin central « Mon univers Ka »), voir toitka/hubfav.py. # GET /api/favorites -> {ids:[item_id…], items:[…]} # POST /api/favorites/toggle {on:bool, item:{item_id,title,…}} -> {ok,on} # 401 si pas de session, ou si le compte n'est pas relié au hub. # ----------------------------------------------------------------------------- from __future__ import annotations from fastapi import APIRouter, Request from fastapi.responses import JSONResponse from .auth import current_user from .hubfav import hub_list, hub_toggle, invalidate router = APIRouter(prefix="/api/favorites") _ITEM_FIELDS = {"item_id": 120, "title": 200, "subtitle": 200, "price_label": 60, "image_url": 500, "url": 500} def _ka_id(request: Request) -> str | None: user = current_user(request) if not user: return None ka_id = str(user.get("ka_id") or "") return ka_id if ka_id.startswith("ka-") else None @router.get("") def list_favorites(request: Request): ka_id = _ka_id(request) if not ka_id: return JSONResponse({"error": "non connecté"}, status_code=401) items = hub_list(ka_id) return {"ids": [it.get("item_id") for it in items if it.get("item_id")], "items": items} @router.post("/toggle") async def toggle_favorite(request: Request): ka_id = _ka_id(request) if not ka_id: return JSONResponse({"error": "non connecté"}, status_code=401) try: body = await request.json() assert isinstance(body, dict) except Exception: return JSONResponse({"error": "corps JSON attendu"}, status_code=400) on = bool(body.get("on")) raw = body.get("item") or {} item = {k: str(raw.get(k) or "")[:n] for k, n in _ITEM_FIELDS.items()} if not item["item_id"]: return JSONResponse({"error": "item.item_id requis"}, status_code=400) ok = hub_toggle(ka_id, "add" if on else "remove", item) invalidate(ka_id) return {"ok": ok, "on": on}