import { ApiError } from "@/lib/api/errors"; import { createQsirchProvider } from "@/lib/search/providers/qsirch"; import { createFsProvider } from "@/lib/search/providers/fs"; /** * Provider selection. * * We keep provider selection in one place: * - SEARCH_PROVIDER=qsirch | fs * * This allows: * - local dev: fs fallback * - production: qsirch (fast, indexed) */ let cachedProvider = null; function normalizeProviderName(value) { return String(value || "") .trim() .toLowerCase(); } function normalizeLower(value, fallback) { const raw = String(value ?? "").trim(); return raw ? raw.toLowerCase() : fallback; } function normalizeTrim(value, fallback) { const raw = String(value ?? "").trim(); return raw ? raw : fallback; } export function getSearchProvider() { if (cachedProvider) return cachedProvider; const providerName = normalizeProviderName( process.env.SEARCH_PROVIDER || "fs" ); if (providerName === "fs") { cachedProvider = createFsProvider(); return cachedProvider; } if (providerName === "qsirch") { // Important: normalize runtime env values so behavior matches validateEnv(). // - validateEnv() accepts values case-insensitively. // - runtime must not accidentally pass "Modified"/"ASYNC" etc. to the provider. cachedProvider = createQsirchProvider({ baseUrl: process.env.QSIRCH_BASE_URL, account: process.env.QSIRCH_ACCOUNT, password: process.env.QSIRCH_PASSWORD, pathPrefix: normalizeTrim( process.env.QSIRCH_PATH_PREFIX, "/Niederlassungen" ), dateField: normalizeLower(process.env.QSIRCH_DATE_FIELD, "modified"), mode: normalizeLower(process.env.QSIRCH_MODE, "sync"), }); return cachedProvider; } throw new ApiError({ status: 500, code: "SEARCH_BACKEND_UNAVAILABLE", message: "Internal server error", }); } /** * Unified search entrypoint used by route handlers. * * @param {{ * mode: "branch"|"multi"|"all", * branches: string[]|null, * q: string|null, * from: string|null, * to: string|null, * limit: number, * cursor: string|null * }} input */ export async function search(input) { const provider = getSearchProvider(); return provider.search(input); }