"use client"; import { useCallback, useEffect, useState } from "react"; import { Page, PageHeader, Stat } from "@/components/ui/section"; import { RightsBadge, StatusBadge } from "@/components/ui/status-badge"; import { RelativeTime } from "@/components/ui/freshness"; import { clientApi } from "@/lib/client-api"; import { cx, formatCompact, formatDateTime, formatDuration } from "@/lib/format"; const TOKEN_KEY = "ma-admin-token"; type Tab = "overview" | "connectors" | "schema" | "divergence" | "storage" | "discovery"; interface Overview { version: string; role: string; uptime_s: number; memory: { rss: number; heapUsed: number }; observations_total: number; events_total: number; queue_depth: number; rates: { observations_per_sec: number; events_per_min: number; http_per_min: number }; tables: Array<{ relname: string; bytes: number }>; rate_limiter: Array<{ host: string; ratePerSec: number; pending: number }>; } interface ConnectorRow { metadata: Record; health: Record; paused: boolean; running: boolean; symbols: string[]; schedule: Record | null; consecutive_failures?: number; drift_strikes?: number; sockets: Array<{ url: string; open: boolean; reconnects: number }>; } /** Token-gated admin console (token kept in localStorage, sent as x-ma-admin-token; never rendered). */ export function AdminConsole() { const [token, setToken] = useState(""); const [input, setInput] = useState(""); const [tab, setTab] = useState("overview"); const [error, setError] = useState(null); useEffect(() => { try { setToken(localStorage.getItem(TOKEN_KEY) ?? ""); } catch { /* ignore */ } }, []); const call = useCallback( async (path: string, init?: RequestInit) => { try { setError(null); return await clientApi(path, { ...init, adminToken: token }); } catch (e) { const msg = e instanceof Error ? e.message : "request failed"; setError(msg); if (/token|unauthor/i.test(msg)) { localStorage.removeItem(TOKEN_KEY); setToken(""); } throw e; } }, [token], ); if (!token) { return (
{ e.preventDefault(); if (!input.trim()) return; localStorage.setItem(TOKEN_KEY, input.trim()); setToken(input.trim()); }} > setInput(e.target.value)} placeholder="admin token" className="mono h-11 flex-1 rounded-md border border-rule bg-surface px-3 text-sm outline-none focus:border-rule-strong" autoComplete="off" />
{error &&

{error}

}
); } return ( { localStorage.removeItem(TOKEN_KEY); setToken(""); }} className="h-9 rounded-md border border-rule px-3 text-xs text-ink-2 hover:text-ink" > Lock } /> {error &&

{error}

} {tab === "overview" && } {tab === "connectors" && } {tab === "schema" && } {tab === "divergence" && } {tab === "storage" && } {tab === "discovery" && }
); } type Call = (path: string, init?: RequestInit) => Promise; function OverviewTab({ call }: { call: Call }) { const [o, setO] = useState(null); useEffect(() => { const load = () => call("/v1/admin/overview").then(setO).catch(() => {}); load(); const t = setInterval(load, 5000); return () => clearInterval(t); }, [call]); if (!o) return

Loading…

; return (
50_000 ? "warn" : undefined} />
{o.tables.map((t) => ( ))}
Table Size
{t.relname} {formatCompact(t.bytes)}B
{o.rate_limiter.map((r) => ( ))}
Rate-limited host req / s Pending
{r.host} {r.ratePerSec} {r.pending}
); } function ConnectorsTab({ call }: { call: Call }) { const [rows, setRows] = useState([]); const [sel, setSel] = useState(null); const [detail, setDetail] = useState | null>(null); const [busy, setBusy] = useState(null); const [testResult, setTestResult] = useState(null); const load = useCallback(() => call("/v1/admin/connectors").then(setRows).catch(() => {}), [call]); useEffect(() => { load(); const t = setInterval(load, 5000); return () => clearInterval(t); }, [load]); useEffect(() => { if (!sel) return; call>(`/v1/admin/connectors/${sel}`).then(setDetail).catch(() => {}); }, [sel, call]); const action = async (id: string, a: string) => { setBusy(`${id}:${a}`); setTestResult(null); try { const r = await call>(`/v1/admin/connectors/${id}/${a}`, { method: "POST", body: "{}" }); if (a === "test") setTestResult(JSON.stringify(r)); await load(); } finally { setBusy(null); } }; return (
{rows.map((r) => { const id = r.metadata.id as string; return ( ); })}
Connector State Msg/min Errors Score Last message Actions
{r.paused && paused} {r.health.messages1m} {r.health.errorsTotal} {r.health.reliabilityScore ?? "—"} {r.health.lastMessageAt ? : "—"}
{(r.paused ? ["resume"] : ["pause", "restart"]).concat(["test"]).map((a) => ( ))}
{testResult &&
{testResult}
}
{!sel &&

Select a connector to inspect health history, schema fingerprints, recent observations and persisted state.

} {sel && detail && (
{sel}
{detail.metadata?.name}
{detail.metadata?.description}
{[ ["State", detail.health?.state], ["Messages", detail.health?.messagesTotal], ["Errors", detail.health?.errorsTotal], ["Reconnects", detail.health?.reconnects], ["p50 latency", detail.health?.medianLatencyMs != null ? formatDuration(detail.health.medianLatencyMs) : "—"], ["Instruments", detail.health?.instrumentsCovered], ["Parse success", detail.health?.parseSuccessRate != null ? `${Math.round(detail.health.parseSuccessRate * 100)}%` : "—"], ["Last error", detail.health?.lastError ?? "—"], ].map(([k, v]) => (
{String(k)} {String(v ?? "—")}
))}
Schema fingerprints
{JSON.stringify(detail.fingerprints ?? {}, null, 1)}
Schema changes
{(detail.schema_changes ?? []).length === 0 ? (

None recorded.

) : (
    {(detail.schema_changes as Array>).map((c) => (
  • {c.kind}: {c.old_fingerprint ?? "∅"} → {c.new_fingerprint} {c.acknowledged ? ( ack ) : ( )}
  • ))}
)}
Recent observations
{(detail.recent_observations as Array> | undefined)?.map((o, i) => ( ))}
{formatDateTime(o.received_at, { seconds: true })} {o.instrument_id} {o.field} {o.value}
Persisted state (redacted)
{JSON.stringify(detail.state ?? {}, null, 1)}
)}
); } function SchemaTab({ call }: { call: Call }) { const [rows, setRows] = useState>>([]); useEffect(() => { call>>("/v1/admin/schema-changes").then(setRows).catch(() => {}); }, [call]); return (
{rows.length === 0 && ( )} {rows.map((r) => ( ))}
Detected Connector Kind Old New
No unacknowledged schema changes.
{formatDateTime(r.detected_at, { seconds: true })} {r.connector_id} {r.kind} {r.old_fingerprint ?? "∅"} {r.new_fingerprint}
); } function DivergenceTab({ call }: { call: Call }) { const [rows, setRows] = useState>>([]); useEffect(() => { call>>("/v1/admin/divergence").then(setRows).catch(() => {}); }, [call]); return (
{rows.length === 0 && ( )} {rows.map((r) => ( ))}
Time Instruments Title Dispersion Sources
No divergence events recorded.
{formatDateTime(r.ts, { seconds: true })} {(r.instrument_ids as string[]).join(", ")} {r.title} {r.data?.dispersionBps?.toFixed?.(0) ?? "—"} bps {(r.data?.contributions as Array<{ source: string; value: number }> | undefined)?.map((c) => `${c.source}=${c.value}`).join(" · ")}
); } function StorageTab({ call }: { call: Call }) { const [s, setS] = useState | null>(null); useEffect(() => { call>("/v1/admin/storage").then(setS).catch(() => {}); }, [call]); if (!s) return

Loading…

; return (
{(s.partitions as Array>).map((p) => ( ))}
Partition Size ≈ rows
{p.relname} {formatCompact(p.bytes)}B {formatCompact(Math.max(0, Number(p.est_rows)))}
{(s.archives as Array>).length === 0 && ( )} {(s.archives as Array>).map((a) => ( ))}
Archived day Rows Bytes
Nothing archived yet.
{String(a.day).slice(0, 10)} {formatCompact(a.rows_archived)} {formatCompact(a.bytes)}B
); } function DiscoveryTab({ call }: { call: Call }) { const [url, setUrl] = useState(""); const [report, setReport] = useState | null>(null); const [busy, setBusy] = useState(false); return (
{ e.preventDefault(); setBusy(true); setReport(null); try { setReport(await call>("/v1/admin/discovery", { method: "POST", body: JSON.stringify({ url }) })); } catch { /* error shown above */ } finally { setBusy(false); } }} > setUrl(e.target.value)} placeholder="https://example.com/markets/AAPL" className="mono h-11 flex-1 rounded-md border border-rule bg-surface px-3 text-sm outline-none focus:border-rule-strong" />

Network-level prototype: fetches the public page unauthenticated (SSRF-guarded), inventories referenced JSON/WebSocket/SSE endpoints and embedded state, and scores candidate quote sources. Output is a candidate report for rights review — nothing is activated.

{report && (
{report.websocket_urls?.length > 0 && (
WebSocket endpoints
    {(report.websocket_urls as string[]).map((u) =>
  • {u}
  • )}
)} {report.json_endpoints?.length > 0 && (
{(report.json_endpoints as Array>).map((e) => ( ))}
Candidate endpoint Score Hints
{e.url} {e.score} {(e.hints as string[]).join(", ")}
)} {report.embedded_state?.length > 0 && (
Embedded state
{(report.embedded_state as Array>).map((s) => (
{s.kind} · fingerprint {s.fingerprint} {s.price_like_fields?.length > 0 &&
price-like: {s.price_like_fields.join(", ")}
} {s.symbol_like_fields?.length > 0 &&
symbol-like: {s.symbol_like_fields.join(", ")}
}
))}
)}
    {(report.notes as string[]).map((n) =>
  • {n}
  • )}
)}
); }