/** * TypeScript mirror of docs/API.md (public v1 + admin). Field names and shapes follow the contract exactly; * nothing here is invented — if the UI needs a field that is not in API.md it is listed in the README instead. */ export type LevelId = 'calm' | 'normal' | 'elevated' | 'stressed' | 'high' | 'severe' | 'extreme'; export type Trend = 'rising' | 'falling' | 'stable'; export type InternalStatus = 'ok' | 'degraded' | 'stale'; export type ComponentId = 'routing' | 'latency' | 'dns' | 'availability' | 'http_tls' | 'path' | 'corroboration'; export type IncidentStatus = 'detected' | 'developing' | 'active' | 'recovering' | 'resolved'; export type IncidentType = | 'regional_latency' | 'dns_disruption' | 'routing_instability' | 'service_degradation' | 'availability_loss' | 'path_instability' | 'global_pressure'; export type ScopeType = 'global' | 'region' | 'country' | 'asn' | 'service' | 'component' | 'bgp' | 'signal' | 'target'; export type HistoryRange = '1h' | '6h' | '24h' | '7d' | '30d' | '1y'; export interface Status { ok: boolean; ts: string; internal_status: InternalStatus; engine: { last_run: string; cycle_ms: number; cycle_seconds: number }; ingest: { last_batch: string; batches_5m: number; measurements_5m: number }; probes: { fresh: number; total: number; excluded: string[] }; bgp: { fresh: boolean; last_message: string; collectors: number }; stores: { clickhouse: boolean; postgres: boolean; redis: boolean }; version: string; } export interface Driver { label: string; points: number; scope_type: string; scope_id: string | null; } export interface Component { id: ComponentId; label: string; score: number; weight: number; contribution: number; trend: Trend; delta_1h: number; confidence: number; drivers: Driver[]; } export interface ExplainRow { text: string; points: number; component: ComponentId; scope_type: string; scope_id: string | null; } export interface Coverage { probes_active: number; probes_total: number; probe_regions: number; targets: number; measurements_5m: number; bgp_collectors: number; baseline_days: number; } export interface GlobalPressure { ts: string; pressure: number; level: LevelId; level_label: string; delta_1h: number; delta_24h: number; velocity_per_h: number; acceleration_per_h2: number; volatility_1h: number; trend: Trend; confidence: number; stale: boolean; internal_status: InternalStatus; coverage: Coverage; components: Component[]; explain: ExplainRow[]; sparkline_1h: (number | null)[]; } export type ComponentScores = Partial>; export interface HistoryPoint { ts: string; pressure: number; components: ComponentScores; confidence: number; } export interface History { scope_type: string; scope_id: string | null; range: HistoryRange; step_seconds: number; points: HistoryPoint[]; summary: { min: number; max: number; avg: number; max_ts: string }; } export interface SimpleSeries { step_seconds: number; points: { ts: string; pressure: number }[]; } export interface Region { id: string; name: string; continent: string; lat: number; lon: number; pressure: number; level: LevelId; level_label: string; delta_1h: number; trend: Trend; confidence: number; components: ComponentScores; probes: number; targets: number; incidents: number; coverage_ok: boolean; role: 'probe' | 'target' | 'both'; } export interface Probe { probe_id: string; name: string; region: string; country: string; city: string; provider: string; asn: number; lat: number; lon: number; status: 'online' | 'stale' | 'offline' | 'excluded'; last_seen: string; version: string; measurements_1h: number; uptime_24h: number; clock_offset_ms: number; capabilities: string[]; } export interface LatencyPair { from: string; to: string; rtt_ms: number; rtt_ms_baseline: number; ttfb_ms: number; loss_pct: number; z: number; pairs: number; } export interface Latency { ts: string; global: { rtt_ms_median: number; rtt_ms_baseline: number; ttfb_ms_median: number; ttfb_ms_baseline: number; packet_loss_pct: number }; matrix: LatencyPair[]; by_probe: { probe_id: string; rtt_ms_median: number; ttfb_ms_median: number; loss_pct: number; z: number }[]; } export interface TargetRow { target_id: string; name: string; pressure: number; ok_ratio_1h: number; ttfb_ms_median: number; } export interface CountryTargetRow extends TargetRow { category: string; } // `probes`/`incidents` are counts in the list object and lists in the detail object (API.md §region/{id}). export type RegionDetailResponse = Omit & { history_24h: SimpleSeries; baseline_7d: { median: number; p90: number }; incidents: Incident[]; top_asns: { asn: number; name: string; pressure: number }[]; top_services: { slug: string; name: string; pressure: number; observed_availability_24h: number }[]; probes: Probe[]; matrix: LatencyPair[]; }; export interface Country { cc: string; name: string; region: string; lat: number; lon: number; pressure: number; level: LevelId; level_label: string; delta_1h: number; trend: Trend; components: ComponentScores; probes: number; targets: number; role: 'probe' | 'target' | 'both'; coverage_ok: boolean; } export type CountryDetailResponse = Omit & { history_24h: SimpleSeries; baseline_7d: { median: number; p90: number }; incidents: Incident[]; asns: { asn: number; name: string; pressure: number }[]; services: { slug: string; name: string; pressure: number; observed_availability_24h: number }[]; probes: Probe[]; targets: CountryTargetRow[]; }; export interface AsnRow { asn: number; name: string; country: string; pressure: number; level: LevelId; routing: number; latency: number; availability: number; targets: number; prefixes_observed: number; importance: number; } export interface AsnDetail { asn: number; name: string; country: string; importance: number; ts: string; pressure: number; level: LevelId; level_label: string; delta_1h: number; trend: Trend; confidence: number; components: ComponentScores; bgp: { prefixes_observed_24h: number; announcements_1h: number; withdrawals_1h: number; churn_ratio: number; origin_changes_1h: number; path_stability: number; series_24h: { ts: string; announcements: number; withdrawals: number }[]; }; regions_observed: string[]; targets: TargetRow[]; history_24h: SimpleSeries; incidents: Incident[]; } export interface VendorStatus { indicator: string; incidents: number; source: string; checked_at: string; titles?: string[]; url?: string; } export interface ServiceRow { slug: string; name: string; category: string; pressure: number; level: LevelId; observed_availability_24h: number; targets: number; affected_regions: string[]; vendor_status: VendorStatus | null; } export interface MatrixCell { target_id: string; ok: boolean; ttfb_ms: number; z: number; ts: string; } export interface ServiceDetail extends Omit { observed: { availability_24h: number; availability_1h: number; ttfb_ms_median_1h: number; ttfb_ms_baseline: number; tls_ms_median_1h: number; failures_1h: number; }; affected_regions: { id: string; name: string; observation: string }[]; discrepancy: string | null; matrix: { probe_id: string; probe_region: string; targets: MatrixCell[] }[]; targets: TargetRow[]; history_24h: SimpleSeries; incidents: Incident[]; } export interface Target { target_id: string; name: string; hostname: string; category: string; provider: string; service_id: string; country: string; region: string; importance: number; tier: number; pressure: number; ok_ratio_1h: number; ttfb_ms_median_1h: number; } export interface TargetDetail extends Target { latest_by_probe: { probe_id: string; kind: string; ts: string; ok: boolean; error: string | null; dns_ms: number | null; tcp_ms: number | null; tls_ms: number | null; ttfb_ms: number | null; http_status: number | null; resolved_ip: string | null; packet_loss: number | null; rtt_avg_ms: number | null; z: number; }[]; series_24h: { step_seconds: number; points: { ts: string; ttfb_ms_p50: number; ok_ratio: number }[] }; dns: { resolvers: { resolver: string; rcode: string; answers: number; ms: number }[]; disagreement: boolean }; } export interface Hypothesis { text: string; confidence: number; evidence: string[]; } export interface Incident { event_id: string; slug: string; type: IncidentType; title: string; summary: string; status: IncidentStatus; scope_type: string; scope_id: string | null; scope_label: string; started_at: string; updated_at: string; ended_at: string | null; duration_s: number; peak_pressure: number; current_pressure: number; confidence: number; affected_probes: number; affected_targets: number; affected_asns: number[]; affected_services: string[]; hypotheses: Hypothesis[]; } export interface IncidentDetail extends Incident { timeline: { ts: string; status: IncidentStatus; pressure: number; note: string }[]; evidence: { signal_id: string; label: string; scope_type: string; scope_id: string | null; current: number; baseline: number; robust_z: number; samples: number; ts: string; }[]; series: { step_seconds: number; points: { ts: string; pressure: number; global_pressure: number }[] }; probes: { probe_id: string; region: string; observation: string }[]; targets: { target_id: string; name: string; service_id: string; observation: string }[]; bgp: { withdrawals_ratio: number; announcements_ratio: number; origin_changes: number } | null; annotations: { ts: string; author: string; text: string }[]; } export interface IncidentList { total: number; incidents: Incident[]; } export interface Front { id: string; name: string; status: string; intensity: number; confidence: number; direction: string; since: string; from: { region: string; name: string; lat: number; lon: number }; to: { region: string; name: string; lat: number; lon: number }; observed: { latency_pct: number; churn_x: number; loss_pct: number; pairs: number; targets: number; route_changes: number }; } export interface BgpCollector { id: string; location: string; announcements_per_s: number; withdrawals_per_s: number; peers: number; last_message: string; fresh: boolean; } export interface BgpStats { ts: string; fresh: boolean; updates_per_s: number; announcements_per_s: number; withdrawals_per_s: number; baseline: { announcements_per_s: number; withdrawals_per_s: number }; ratio: { announcements: number; withdrawals: number }; unique_prefixes_1m: number; unique_origins_1m: number; origin_changes_1m: number; peers: number; collectors: BgpCollector[]; series_1h: { ts: string; announcements: number; withdrawals: number }[]; top_origins_1h: { asn: number; name: string; announcements: number; withdrawals: number }[]; } export type BgpStatsEvent = Pick; export interface Ticker { ts: string; bgp_updates_per_s: number; bgp_withdrawals_per_s: number; bgp_updates_per_min: number; probes_active: number; probes_total: number; measurements_per_s: number; measurements_per_min: number; targets_degraded: number; targets_total: number; regions_elevated: number; regions_normal: number; regions_severe: number; dns_failures_per_min: number; median_global_rtt_ms: number; route_changes_per_min: number; active_incidents: number; internal_status: InternalStatus; } export interface Hop { n: number; ip: string; asn: number | null; asn_name: string | null; rtt_ms: number | null; private: boolean; } export interface RouteResponse { probe: { probe_id: string; name: string; asn: number }; target: { target_id: string; name: string; hostname: string; asn: number }; current: { ts: string; route_hash: string; reached: boolean; total_ms: number; hops: Hop[] }; baseline: { route_hash: string; share_7d: number; first_seen: string; last_seen: string; hops: Hop[] }; diff: { changed: boolean; added: { n: number; ip: string; asn: number | null }[]; removed: { n: number; ip: string; asn: number | null }[]; asn_path_current: number[]; asn_path_baseline: number[]; latency_shift_ms: number; hop_delta: number; }; history_24h: { ts: string; route_hash: string; hop_count: number; total_ms: number }[]; route_share_7d: { route_hash: string; share: number; asn_path: number[] }[]; } export interface RoutePair { probe_id: string; target_id: string; changed_24h: number; current_route_hash: string; stable: boolean; } export interface HistoryDay { date: string; min: number; max: number; avg: number; events: number; } export interface HistoryMonthRow { month: string; min: number; max: number; avg: number; events: number; } export interface HistorySummary { year?: number; month?: number; days?: HistoryDay[]; months?: HistoryMonthRow[]; top_events: Incident[]; top_asns: { asn: number; name: string; events: number; max_pressure: number }[]; top_regions: { id: string; name: string; events: number; max_pressure: number; hours_elevated: number }[]; largest: { pressure: Incident | null; routing: Incident | null; dns: Incident | null; latency: Incident | null }; available_months: string[]; } export interface ExplainSignal { signal_id: string; label: string; scope_type: string; scope_id: string | null; current: number; baseline_median: number; mad: number; robust_z: number; samples: number; stress: number; contribution: number; } export interface Explain { ts: string; pressure: number; components: { id: ComponentId; score: number; weight: number; contribution: number; signals: ExplainSignal[] }[]; excluded_probes: string[]; notes: string[]; } export interface Methodology { weights: Record; levels: { max: number; id: LevelId; label: string }[]; engine: Record; components?: Record; events?: Record; fronts?: Record; version: number; updated_at: string | null; source?: string; } export interface SearchResult { type: 'country' | 'asn' | 'service' | 'region' | 'target' | 'incident'; id: string; label: string; href: string; pressure: number | null; } // ---- SSE payloads export interface Snapshot { global: GlobalPressure; ticker: Ticker; regions: Region[]; fronts: Front[]; incidents: Incident[]; } export interface RegionalUpdate { ts: string; regions: Region[]; countries: { cc: string; pressure: number; level: LevelId; delta_1h: number }[]; } export interface ProbeStats { ts: string; probes_active: number; probes_total: number; measurements_per_s: number; excluded: string[]; } export interface InternalStatusEvent { ts: string; internal_status: InternalStatus; reason: string; } export interface ServiceDegradationEvent { ts: string; slug: string; name: string; pressure: number; regions: string[]; observation: string; } // ---- admin export interface AdminProbe extends Probe { enabled?: boolean; health?: { uptime_24h: number; clock_offset_ms: number; missing_ratio_1h: number; error_rate_1h: number; buffered: number; spool_bytes: number; version: string; last_health: string; }; key?: string; } export interface AdminOverview { probes: AdminProbe[]; ingest: { batches_per_min: number; measurements_per_min: number; rejected_per_min: number; last_batch: string }; stores: { clickhouse: { ok: boolean; inserts_per_s: number; tables: { name: string; rows: number; bytes: number; oldest: string; newest: string }[] }; postgres: { ok: boolean; size_bytes: number }; redis: { ok: boolean; used_memory_bytes: number; keys: number }; }; bgp: { collectors: BgpCollector[]; messages_per_s: number; fresh: boolean; reconnects_24h: number }; engine: { last_run: string; cycle_ms_p50: number; cycle_ms_max: number; runs_1h: number; errors_1h: number; internal_status: InternalStatus; excluded_probes: string[] }; corroboration: { id: string; name: string; ok: boolean; last_fetch: string; incidents: number }[]; } export interface AdminTarget extends Target { enabled?: boolean; } export interface AdminBaselines { signal_id: string; points: { ts: string; value: number; median: number; mad: number; z: number }[]; samples: number; baseline_days: number; } export interface AdminRaw { columns: string[]; rows: unknown[][]; } export interface AdminIncident extends Incident { review?: 'confirmed' | 'dismissed' | 'unreviewed'; note?: string | null; } export interface AdminAnnotation { id?: string; ts: string; author?: string; scope_type: string; scope_id: string | null; text: string; } export interface AdminReplay { step_seconds: number; points: { ts: string; pressure_original: number; pressure_replayed: number }[]; } export interface AdminConfig { version: number; pressure_weights: Record; levels: { max: number; id: string; label: string }[]; engine: Record; [key: string]: unknown; }