Repository Public
1import { searchFilms } from "@/lib/films";2import { bad, json, localeOf } from "@/lib/api";3import { clientIpHash } from "@/lib/auth";4import { rateLimit } from "@/lib/ratelimit";56/** GET /api/search?q= — explainable hybrid search; every hit lists the signals that matched. */7export async function GET(req: Request) {8 const url = new URL(req.url);9 if (!(await rateLimit(`search:${await clientIpHash()}`, 60, 60))) return bad("rate_limited", 429);10 const q = (url.searchParams.get("q") ?? "").slice(0, 120);11 const hits = await searchFilms(localeOf(url), q);12 return json({ query: q, results: hits.map((h) => ({ slug: h.film.slug, title: h.film.title, synopsis: h.film.synopsis, thumb: h.film.thumb, signals: h.signals, score: Math.round(h.score * 1000) / 1000 })) });13}14