from fastapi import APIRouter, Depends from sqlalchemy import func, or_, select from sqlalchemy.ext.asyncio import AsyncSession from app.api.deps import get_current_user from app.db.session import get_db from app.models.objekt import Objekt from app.schemas.suche import SuchTreffer router = APIRouter() _TREFFER_LIMIT = 8 @router.get("/suche", response_model=list[SuchTreffer]) async def suche( q: str, db: AsyncSession = Depends(get_db), _=Depends(get_current_user), ) -> list[SuchTreffer]: """Globale Suche (Command Palette) über Objektname/-code, per pg_trgm- Index statt vollständig geladener Objektliste + Client-Filter (SEARCH-001). Kurze Eingaben (<2 Zeichen) liefern bewusst nichts - sonst zu viele Zufallstreffer über den Ähnlichkeits-Schwellenwert von pg_trgm.""" q = q.strip() if len(q) < 2: return [] muster = f"%{q}%" aehnlichkeit = func.greatest(func.similarity(Objekt.name, q), func.similarity(Objekt.code, q)) stmt = ( select(Objekt.id, Objekt.code, Objekt.name) .where(or_(Objekt.name.ilike(muster), Objekt.code.ilike(muster), aehnlichkeit > 0.2)) .order_by(aehnlichkeit.desc()) .limit(_TREFFER_LIMIT) ) result = await db.execute(stmt) return [SuchTreffer(id=r.id, code=r.code, name=r.name) for r in result.all()]