spb/toit-ka Public
Toit-Ka — louer ou acheter un toit au Québec, un seul endroit (fusion Lou-Ka × Immo-Ka) — www.toit-ka.com
Python 40.2%
TypeScript 39%
CSS 20.2%
HTML 0.7%
1# Author: Simon-Pierre Boucher2# Contact: contact@spboucher.ai3# Project: Toit-Ka4# -----------------------------------------------------------------------------5# favorites.py : routes API des favoris (♥) — session Groupe KA requise.6# AUCUN stockage local : lecture et écriture passent par le hub Groupe KA7# (magasin central « Mon univers Ka »), voir toitka/hubfav.py.8# GET /api/favorites -> {ids:[item_id…], items:[…]}9# POST /api/favorites/toggle {on:bool, item:{item_id,title,…}} -> {ok,on}10# 401 si pas de session, ou si le compte n'est pas relié au hub.11# -----------------------------------------------------------------------------12from __future__ import annotations1314from fastapi import APIRouter, Request15from fastapi.responses import JSONResponse1617from .auth import current_user18from .hubfav import hub_list, hub_toggle, invalidate1920router = APIRouter(prefix="/api/favorites")2122_ITEM_FIELDS = {"item_id": 120, "title": 200, "subtitle": 200,23 "price_label": 60, "image_url": 500, "url": 500}242526def _ka_id(request: Request) -> str | None:27 user = current_user(request)28 if not user:29 return None30 ka_id = str(user.get("ka_id") or "")31 return ka_id if ka_id.startswith("ka-") else None323334@router.get("")35def list_favorites(request: Request):36 ka_id = _ka_id(request)37 if not ka_id:38 return JSONResponse({"error": "non connecté"}, status_code=401)39 items = hub_list(ka_id)40 return {"ids": [it.get("item_id") for it in items if it.get("item_id")],41 "items": items}424344@router.post("/toggle")45async def toggle_favorite(request: Request):46 ka_id = _ka_id(request)47 if not ka_id:48 return JSONResponse({"error": "non connecté"}, status_code=401)49 try:50 body = await request.json()51 assert isinstance(body, dict)52 except Exception:53 return JSONResponse({"error": "corps JSON attendu"}, status_code=400)54 on = bool(body.get("on"))55 raw = body.get("item") or {}56 item = {k: str(raw.get(k) or "")[:n] for k, n in _ITEM_FIELDS.items()}57 if not item["item_id"]:58 return JSONResponse({"error": "item.item_id requis"}, status_code=400)59 ok = hub_toggle(ka_id, "add" if on else "remove", item)60 invalidate(ka_id)61 return {"ok": ok, "on": on}62