TypeScript 61.9%
HTML 37.2%
SQL 0.7%
1import { NextResponse } from 'next/server';2import { connectorsOverview } from '@/lib/admin/queries';34export const runtime = 'nodejs';5export const dynamic = 'force-dynamic';67const LABEL: Record<string, string> = { healthy: 'UP', degraded: 'DEGRADED', failing: 'BROKEN', paused: 'DISABLED', disabled: 'DISABLED', maintenance: 'MAINTENANCE', unknown: 'UNKNOWN' };89/** Connector health API (SPEC §12): one object per connector with status, usage, errors, freshness and backfill progress. */10export async function GET() {11 const rows = await connectorsOverview();12 return NextResponse.json({13 as_of: new Date().toISOString(),14 connectors: rows.map((r) => {15 const h = (r.health ?? {}) as Record<string, unknown>;16 const m = (r.meta ?? {}) as Record<string, unknown>;17 return {18 id: r.id,19 name: r.display_name,20 source: r.source_id,21 domain: m.domain ?? null,22 country: m.country ?? null,23 categories: r.categories,24 capabilities: m.capabilities ?? [],25 acquisition: m.acquisitionMethod ?? (r.engine_priority as string[]).join('>'),26 engines: r.engine_priority,27 priority: r.priority,28 refresh_minutes: r.refresh_frequency_minutes,29 refresh_class: m.refreshClass ?? null,30 status: r.status,31 health: r.health_status ?? 'unknown',32 health_label: LABEL[String(r.health_status ?? 'unknown')] ?? 'UNKNOWN',33 health_at: r.health_at,34 success_rate_24h: h.success_rate_24h ?? null,35 requests_24h: h.requests_24h ?? null,36 items_24h: r.records_24h ?? 0,37 normalized_24h: r.normalized_24h ?? 0,38 duplicates_24h: r.duplicates_24h ?? 0,39 latest_success: r.last_success_at,40 last_run: r.last_started_at,41 last_run_status: r.last_run_status,42 last_error: r.last_error,43 http_errors: h.http_errors ?? {},44 parse_failure_rate: h.parse_failure_rate ?? null,45 schema_drift: h.schema_drift ?? [],46 latency_ms_avg: h.latency_ms_avg ?? null,47 rate_limited_24h: h.rate_limited_24h ?? 0,48 challenges_24h: h.challenges_24h ?? 0,49 data_freshness: h.data_freshness ?? null,50 firecrawl: { credits_24h: r.fc_credits_24h ?? 0, success_rate: h.firecrawl_success_rate ?? null },51 scrapfly: { credits_24h: r.sf_credits_24h ?? 0, fallback_rate: h.scrapfly_fallback_rate ?? null },52 missing_requirements: h.missing_requirements ?? [],53 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,54 anomalies: r.last_anomalies ?? [],55 };56 }),57 });58}59