Command Palette lud bisher beim Öffnen ALLE Objekte und filterte nur clientseitig per .includes() - unscharf und würde bei mehr Objekten langsam werden. Jetzt: GIN-Trigram-Index auf objekt.name/code (Migration 0023), neuer GET /suche?q=-Endpunkt (Ähnlichkeits-Ranking per pg_trgm similarity()), Frontend debounced (250ms) statt vollständiger Objektliste. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
39 lines
1.3 KiB
Python
39 lines
1.3 KiB
Python
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()]
|