Files
flowdeck/app/routers/search.py
Spark 463dd7b752
FlowDeck CI / test (push) Failing after 0s
FlowDeck CI / docker (push) Skipped
FlowDeck CI / lint (pull_request) Failing after 1s
FlowDeck CI / test (pull_request) Failing after 1s
FlowDeck CI / docker (pull_request) Skipped
FlowDeck CI / lint (push) Failing after 11s
Flowdeck 7.85.3 — HUB-21 : consommation des réglages généraux du Hub (bannière + drapeau recherche_partout)
2026-11-06 16:57:05 +00:00

83 lines
3.5 KiB
Python

"""FlowDeck — unified search router (v5.0.0).
``GET /api/search?q=`` backs the Ctrl+K command palette. Returns matching
editor pages and databases scoped to the current user's accessible workspaces.
Recherche partout (fusion-trois-apps #68) : la même route sert la page
unifiée (``GET /recherche``, coquille dont les résultats sont chargés
côté client) et accepte, en plus de la session native, le jeton SSO
``draco_session`` (validateur local ``app.services.draco``). Sans
session ni jeton valide, 401 — avant cette livraison, l'absence de
session donnait une recherche SANS périmètre (``user_id=None`` → ``1=1``
dans ``_scope_where``) : corrigé ici.
"""
from __future__ import annotations
from fastapi import APIRouter, HTTPException, Query, Request
from fastapi.responses import HTMLResponse
from app.auth.session import SessionManager
from app.services.search import search as search_service
router = APIRouter(tags=["search"])
@router.get("/api/search")
def search(request: Request, q: str = Query(default="")):
user = SessionManager.decode_session(request.cookies.get("flowdeck_session", ""))
user_id = user.get("id") if user and user.get("id") else None
if user_id is None:
# Repli SSO draco_session : un jeton valide désigne l'utilisateur
# lié, ou l'unique utilisateur actif (cas mono-utilisateur).
try:
from app.services import draco as draco_service
draco_user = draco_service.user_for_draco(request)
user_id = draco_user.get("id") if draco_user else None
except Exception:
user_id = None
if user_id is None:
raise HTTPException(status_code=401, detail="Authentication required")
data = search_service(q, user_id=user_id)
return {
"query": q,
"pages": data["pages"],
"collections": data["collections"],
"total": len(data["pages"]) + len(data["collections"]),
}
@router.get("/recherche", response_class=HTMLResponse)
def recherche_page(request: Request, q: str = Query(default="")):
"""Page de résultats unifiée « Rechercher partout » (fusion #68).
Coquille seule : les résultats sont chargés côté client par
static/js/recherche.js (API de recherche de chaque app, en
parallèle, états par application). La palette Ctrl+K native et
``GET /api/search`` restent inchangés par ailleurs.
HUB-21 : le drapeau ``recherche_partout`` des réglages
généraux du Hub est rendu dans l'attribut
``data-recherche-partout`` de la coquille (cache serveur de
60 s de ``app.services.hub_reglages`` ; Hub muet → « true »,
comportement actuel) — quand il est faux, recherche.js
n'interroge que la section locale Flowdeck.
"""
from app.services import draco_urls, hub_reglages
from app.templating import ENV
user = SessionManager.decode_session(request.cookies.get("flowdeck_session", ""))
bases = draco_urls.toutes()
template = ENV.get_template("recherche.html")
# Defaut 6 : la base agent est exposee explicitement (data-base-console
# dans recherche.html), comme les 3 autres hotes — recherche.js ne doit
# plus la deviner (derivation -dev / href d'onglet de barre) pour
# l'onglet Console Spark (GET /api/v1/recherche, alignement #36).
return HTMLResponse(template.render(
request=request, q=q.strip(), user=user,
recherche_partout=hub_reglages.recherche_partout(),
bases={k: bases[k] for k in ("obsigate", "flowdeck", "tiktak",
"kanbante", "shaarit", "agent")},
))