import type { FlightReportRequest, FlightSearchPlan, FlightSearchSourceFinding, FlightSearchSourceName, FlightSearchSourceViability } from "./types.js"; export const SOURCE_SILENT_TIMEOUT_MS = 45_000; export const SOURCE_TOTAL_TIMEOUT_MS = 180_000; export const RUN_TOTAL_TIMEOUT_MS = 900_000; export const VPN_CONNECT_TIMEOUT_MS = 30_000; export const VPN_DISCONNECT_TIMEOUT_MS = 15_000; const DEFAULT_SOURCE_ORDER: FlightSearchSourceName[] = [ "kayak", "skyscanner", "expedia", "airline-direct" ]; function findingFor( source: FlightSearchSourceName, findings: FlightSearchSourceFinding[] ): FlightSearchSourceFinding | undefined { return findings.find((entry) => entry.source === source); } function sourceStatus( source: FlightSearchSourceName, findings: FlightSearchSourceFinding[] ): FlightSearchSourceViability { return findingFor(source, findings)?.status || "viable"; } export function buildFlightSearchPlan( request: FlightReportRequest, findings: FlightSearchSourceFinding[] = [] ): FlightSearchPlan { const sourceOrder = DEFAULT_SOURCE_ORDER.map((source) => { const status = sourceStatus(source, findings); const finding = findingFor(source, findings); const required = source !== "airline-direct"; const enabled = status !== "blocked"; const reason = finding?.notes[0] || (source === "airline-direct" ? "Best-effort airline direct cross-check." : "Primary bounded search source."); return { source, enabled, required, status, silentTimeoutMs: SOURCE_SILENT_TIMEOUT_MS, totalTimeoutMs: SOURCE_TOTAL_TIMEOUT_MS, reason }; }); const degradedReasons = sourceOrder .filter((source) => source.status !== "viable") .map((source) => source.enabled ? `${source.source} is degraded for this run: ${source.reason}` : `${source.source} is blocked for this run: ${source.reason}` ); return { sourceOrder, vpn: { enabled: Boolean(request.preferences.marketCountry), marketCountry: request.preferences.marketCountry || null, connectTimeoutMs: VPN_CONNECT_TIMEOUT_MS, disconnectTimeoutMs: VPN_DISCONNECT_TIMEOUT_MS, fallbackMode: "default-market" }, degradedReasons }; }