Files
admin 5137bf87a1
CI (SIAX Cloud) / integration (push) Skipped
CI (SIAX Cloud) / sonar (push) Skipped
masterplan-lock / check (push) Successful in 4s
CI (SIAX Cloud) / sonar (pull_request) Skipped
CI (SIAX Cloud) / security (push) Successful in 15s
masterplan-lock / check (pull_request) Successful in 7s
Security Scan (SIAX Cloud) / security (push) Successful in 18s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 17s
CI (SIAX Cloud) / security (pull_request) Successful in 20s
CI (SIAX Cloud) / integration (pull_request) Successful in 35s
CI (SIAX Cloud) / quality (pull_request) Successful in 39s
CI (SIAX Cloud) / quality (push) Successful in 48s
fix: distinguish failed sources from empty results
2026-11-02 06:58:15 +01:00

31 lines
1.8 KiB
TypeScript

import { NextRequest, NextResponse } from "next/server";
import { engineFetch, hasEngine } from "@/lib/engine";
// An unavailable or malformed screening source is never evidence of no match.
export async function GET(req: NextRequest) {
const q = req.nextUrl.searchParams.get("q")?.trim() ?? "";
if (!q) return NextResponse.json({ error: { code: "bad_request", message: "q krävs" } }, { status: 400 });
const unavailable = () => NextResponse.json({ error: { code: "source_unavailable", message: "Screeningkällan är inte tillgänglig" } }, { status: 503 });
try {
if (hasEngine()) {
const eng = await engineFetch(`/screen?q=${encodeURIComponent(q)}`);
if (!eng?.ok) return unavailable();
const data: unknown = await eng.json();
if (!data || typeof data !== "object" || (!Array.isArray((data as { matches?: unknown }).matches) || (data as { source_status?: unknown }).source_status !== "ok")) return unavailable();
return NextResponse.json(data);
}
const r = await fetch(`https://api.opensanctions.org/search/default?q=${encodeURIComponent(q)}&limit=5`, {
headers: { "User-Agent": "0pt/0.1 (+https://0pt.app; SIAX)" }, cache: "no-store",
});
if (!r.ok) return unavailable();
const data: unknown = await r.json();
if (!data || typeof data !== "object" || !Array.isArray((data as { results?: unknown }).results)) return unavailable();
const results = (data as { results: unknown[] }).results;
if (results.some((item) => !item || typeof item !== "object" || Array.isArray(item))) return unavailable();
return NextResponse.json({ source: "opensanctions", matches: results.map((item) => {
const x = item as { caption?: unknown; score?: unknown; schema?: unknown };
return { name: x.caption ?? null, score: x.score ?? null, schema: x.schema ?? null };
}) });
} catch { return unavailable(); }
}