import { withUser, json } from "@/lib/api"; import { searchAll, SEARCH_GROUPS, type SearchGroup } from "@/lib/search/service"; import { LIMITS } from "@/lib/rate-limit"; export const dynamic = "force-dynamic"; /** * GET /api/search?q=&limit=12&cursor=&groups=conversations,messages * * Query language (see src/lib/search/query.ts): free text, "quoted phrases", model:, provider:, project:, folder:, * after:, before:, role:user|assistant, is:pinned|archived|shared. Response: SearchResponse (grouped hits, * `query.terms` for client-side highlighting, `nextCursor` for conversations/messages pagination). */ export const GET = withUser( async ({ req, user }) => { const sp = new URL(req.url).searchParams; const q = (sp.get("q") ?? "").trim().slice(0, 300); const limitRaw = Number(sp.get("limit") ?? 12); const limit = Number.isFinite(limitRaw) ? limitRaw : 12; const cursor = sp.get("cursor"); const groups = (sp.get("groups") ?? "") .split(",") .map((g) => g.trim()) .filter((g): g is SearchGroup => (SEARCH_GROUPS as readonly string[]).includes(g)); const res = await searchAll(user.id, q, { limit, cursor, groups }); return json(res); }, { limit: { ...LIMITS.search, key: "search" } }, );