SPB Git forge

spb/rareindex

Public
54commits 1branches 0releases
7.1 MBsize
maindefault branch
10 days agolast push
TypeScript 61.9% HTML 37.2% SQL 0.7%
2.7 KB · 59 lines typescript
Raw Blame History
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