import { NextResponse } from 'next/server'; import { connectorsOverview } from '@/lib/admin/queries'; export const runtime = 'nodejs'; export const dynamic = 'force-dynamic'; const LABEL: Record = { healthy: 'UP', degraded: 'DEGRADED', failing: 'BROKEN', paused: 'DISABLED', disabled: 'DISABLED', maintenance: 'MAINTENANCE', unknown: 'UNKNOWN' }; /** Connector health API (SPEC ยง12): one object per connector with status, usage, errors, freshness and backfill progress. */ export async function GET() { const rows = await connectorsOverview(); return NextResponse.json({ as_of: new Date().toISOString(), connectors: rows.map((r) => { const h = (r.health ?? {}) as Record; const m = (r.meta ?? {}) as Record; return { id: r.id, name: r.display_name, source: r.source_id, domain: m.domain ?? null, country: m.country ?? null, categories: r.categories, capabilities: m.capabilities ?? [], acquisition: m.acquisitionMethod ?? (r.engine_priority as string[]).join('>'), engines: r.engine_priority, priority: r.priority, refresh_minutes: r.refresh_frequency_minutes, refresh_class: m.refreshClass ?? null, status: r.status, health: r.health_status ?? 'unknown', health_label: LABEL[String(r.health_status ?? 'unknown')] ?? 'UNKNOWN', health_at: r.health_at, success_rate_24h: h.success_rate_24h ?? null, requests_24h: h.requests_24h ?? null, items_24h: r.records_24h ?? 0, normalized_24h: r.normalized_24h ?? 0, duplicates_24h: r.duplicates_24h ?? 0, latest_success: r.last_success_at, last_run: r.last_started_at, last_run_status: r.last_run_status, last_error: r.last_error, http_errors: h.http_errors ?? {}, parse_failure_rate: h.parse_failure_rate ?? null, schema_drift: h.schema_drift ?? [], latency_ms_avg: h.latency_ms_avg ?? null, rate_limited_24h: h.rate_limited_24h ?? 0, challenges_24h: h.challenges_24h ?? 0, data_freshness: h.data_freshness ?? null, firecrawl: { credits_24h: r.fc_credits_24h ?? 0, success_rate: h.firecrawl_success_rate ?? null }, scrapfly: { credits_24h: r.sf_credits_24h ?? 0, fallback_rate: h.scrapfly_fallback_rate ?? null }, missing_requirements: h.missing_requirements ?? [], backfill: r.backfill_id ? { id: r.backfill_id, status: r.backfill_status, percent: r.backfill_percent, pages: r.backfill_pages, items: r.backfill_items, reached_date: r.backfill_reached_date, updated_at: r.backfill_updated_at } : null, anomalies: r.last_anomalies ?? [], }; }), }); }