/** API contract (FastAPI /api/v1). Numbers coming from Postgres aggregates may arrive as strings — use `num()` from format.ts. */ export type Num = number | string | null; export interface Meta { request_id: string; generated_at: string; [k: string]: unknown; } export interface Envelope { data: T; meta: Meta; } export interface Paginated { data: T[]; pagination: { page: number; page_size: number; total: number; pages: number }; meta: Meta; [k: string]: unknown; } export interface Problem { title: string; detail?: string | null; status: number; } export type OrbitClass = 'LEO' | 'MEO' | 'GEO' | 'HEO' | 'OTHER'; export type ObjectType = 'PAYLOAD' | 'ROCKET_BODY' | 'DEBRIS' | 'STATION' | 'UNKNOWN' | 'CREWED'; export type SatStatus = 'ACTIVE' | 'INACTIVE' | 'DECAYED' | 'LOST' | 'FAILED' | 'UNKNOWN' | 'PLANNED'; export interface SatelliteRow { id: string; slug: string; name: string; norad_id: number | null; cospar_id: string | null; object_type: ObjectType; status: SatStatus; ops_status_code: string | null; mission_type: string | null; orbit_class: OrbitClass | null; period_minutes: Num; inclination_deg: Num; apogee_km: Num; perigee_km: Num; rcs_m2: Num; launch_date: string | null; decay_date: string | null; launch_site_code: string | null; has_gp: boolean; latest_epoch: string | null; country_code: string | null; country_name: string | null; country_slug: string | null; owner_code: string | null; owner_name: string | null; operator_id: string | null; operator_name: string | null; operator_slug: string | null; constellation_id: string | null; constellation_name: string | null; constellation_slug: string | null; launch_id: string | null; cospar_launch_id: string | null; launch_site_name: string | null; launch_site_slug: string | null; first_seen_at: string; last_seen_at: string; updated_at: string; } export interface OrbitalState { epoch: string; mean_motion: number; eccentricity: number; inclination: number; raan: number; arg_of_perigee: number; mean_anomaly: number; bstar: number | null; mean_motion_dot: number | null; semi_major_axis_km: number | null; perigee_km: number | null; apogee_km: number | null; period_minutes: number | null; orbit_class: OrbitClass | null; source_id: string; updated_at: string; } export interface LivePosition { lat: number; lon: number; altitude_km: number; velocity_km_s: number; timestamp: string; source_epoch: string; epoch_age_hours?: number; error?: string | null; } export interface Freshness { orbit: { updated_at: string | null; epoch: string | null; status: 'fresh' | 'aging' | 'stale' | 'unavailable' }; metadata: { updated_at: string | null; status: 'fresh' | 'aging' | 'stale' | 'unavailable' }; } export interface SatelliteDetail extends SatelliteRow { redirected_from?: string; orbital_state: OrbitalState | null; live: LivePosition | null; aliases: { alias: string; source_id: string | null }[]; tags: { tag: string; source_id: string | null; last_seen_at: string }[]; identifiers: { identifier_type: string; identifier_value: string; source_id: string | null; verified: boolean }[]; history: { field: string; old_value: string | null; new_value: string | null; source_id: string | null; changed_at: string }[]; constellation_memberships: { constellation_id: string; slug: string; name: string; method: string; since: string; until: string | null }[]; provenance: { field_name: string; source_id: string; source_name: string; observed_at: string; confidence: number }[]; events: EventRow[]; quality_flags: { flag: string; detail: string | null; created_at: string }[]; launch_siblings: Pick[]; related: Pick[]; sources: { id: string; name: string; official: boolean; attribution_text: string | null; last_success_at: string | null }[]; freshness: Freshness; } export interface TrackPoint { t: string; lat: number; lon: number; alt: number; future: boolean; } export interface Track { t0: string; points: TrackPoint[]; source_epoch: string; } export interface OrbitalElementRow { epoch: string; mean_motion: number; eccentricity: number; inclination: number; raan: number; arg_of_perigee: number; mean_anomaly: number; bstar: number | null; semi_major_axis_km: number | null; perigee_km: number | null; apogee_km: number | null; period_minutes: number | null; source_id: string; received_at: string; } export interface SatelliteHistory { changes: { field: string; old_value: string | null; new_value: string | null; source_id: string | null; changed_at: string }[]; altitude_series: { day: string; perigee_km: Num; apogee_km: Num; period_minutes: Num; inclination: Num }[]; } export interface FacetValue { value: string; count: Num; label?: string; slug?: string; } export interface Facets { status: FacetValue[]; object_type: FacetValue[]; orbit_class: FacetValue[]; mission_type: FacetValue[]; country: FacetValue[]; constellation: FacetValue[]; } export interface ConstellationRow { id: string; slug: string; name: string; service_type: string | null; orbit_class: string | null; lifecycle_stage: string; description: string | null; official_url: string | null; planned_count: number | null; authorized_count: number | null; country_code: string | null; country_name: string | null; country_slug: string | null; operator_id: string | null; operator_name: string | null; operator_slug: string | null; active: Num; inactive: Num; decayed: Num; on_orbit: Num; total: Num; launched_last_365d: Num; launched_last_30d: Num; launches: Num; first_launch: string | null; last_launch: string | null; median_perigee_km: Num; median_inclination_deg: Num; activity_score: Num; } export interface ConstellationDetail extends ConstellationRow { status_distribution: { status: string; count: Num }[]; growth: { month: string; launched: Num; cumulative: Num }[]; shells: { perigee_km: Num; inclination_deg: Num; satellites: Num }[]; altitude_histogram: { alt_km: Num; satellites: Num }[]; inclination_histogram: { incl_deg: Num; satellites: Num }[]; launches_list: { id: string; cospar_launch_id: string; launch_date: string | null; site_name: string | null; site_slug: string | null; satellites: Num; active: Num }[]; launch_sites: { code: string; name: string; slug: string; country_code: string | null; launches: Num; satellites: Num }[]; countries: { code: string; name: string; slug: string; satellites: Num }[]; recent_satellites: { id: string; slug: string; name: string; norad_id: number | null; status: string; launch_date: string | null; perigee_km: Num; apogee_km: Num; inclination_deg: Num }[]; events: EventRow[]; decays_by_month: { month: string; decayed: Num }[]; membership_methods: { method: string; satellites: Num }[]; match_patterns: string[]; celestrak_groups: string[]; } export interface OperatorRow { id: string; slug: string; name: string; kind: string; official_url: string | null; description: string | null; country_code: string | null; country_name: string | null; country_slug: string | null; active_payloads: Num; on_orbit_payloads: Num; total_payloads: Num; decayed: Num; constellations: Num; launches: Num; payloads_last_365d: Num; first_launch: string | null; last_launch: string | null; } export interface OperatorDetail extends OperatorRow { aliases: string[]; constellations_list: { id: string; slug: string; name: string; service_type: string | null; orbit_class: string | null; active: Num; total: Num; launched_last_365d: Num }[]; launches_list: { id: string; cospar_launch_id: string; launch_date: string | null; site_name: string | null; site_slug: string | null; satellites: Num }[]; status_distribution: { status: string; count: Num }[]; orbit_distribution: { orbit_class: string; count: Num }[]; mission_distribution: { mission_type: string; count: Num }[]; growth: { year: number; launched: Num; still_active: Num }[]; fleet_sample: { id: string; slug: string; name: string; norad_id: number | null; status: string; orbit_class: string | null; launch_date: string | null; perigee_km: Num; mission_type: string | null }[]; events: EventRow[]; launch_sites: { code: string; name: string; slug: string; country_code: string | null; launches: Num }[]; } export interface CountryRow { code: string; name: string; slug: string; iso3?: string | null; region?: string | null; active_payloads: Num; on_orbit_payloads: Num; total_payloads: Num; debris_on_orbit: Num; rocket_bodies_on_orbit: Num; objects_on_orbit: Num; total_objects: Num; launches: Num; operators: Num; payloads_last_365d: Num; rank_active?: Num; } export interface CountryDetail extends CountryRow { rank_objects: Num; rank_debris: Num; operators_list: { id: string; slug: string; name: string; kind: string; active_payloads: Num; total_payloads: Num; payloads_last_365d: Num }[]; constellations_list: { id: string; slug: string; name: string; service_type: string | null; orbit_class: string | null; active: Num; total: Num }[]; owner_codes: { code: string; name: string; kind: string }[]; orbit_distribution: { orbit_class: string; count: Num }[]; mission_distribution: { mission_type: string; count: Num }[]; object_type_distribution: { object_type: string; on_orbit: Num; total: Num }[]; growth: { year: number; payloads: Num; still_active: Num; launches: Num }[]; launch_sites: { code: string; name: string; slug: string; latitude: number | null; longitude: number | null; launches: Num; last_launch: string | null }[]; recent_satellites: { id: string; slug: string; name: string; norad_id: number | null; status: string; object_type: string; orbit_class: string | null; launch_date: string | null }[]; recent_launches: LaunchRow[]; events: EventRow[]; } export interface LaunchRow { id: string; cospar_launch_id: string; launch_date: string | null; launch_year?: number | null; payload_count: Num; object_count?: Num; on_orbit_count?: Num; primary_name: string | null; owner_codes?: string[]; site_code?: string | null; site_name: string | null; site_slug: string | null; site_country?: string | null; site_lat?: number | null; site_lon?: number | null; } export interface LaunchDetail extends LaunchRow { objects: (Pick)[]; owners: { code: string; name: string; kind: string; country_code: string | null }[]; events: EventRow[]; } export interface LaunchSiteRow { code: string; name: string; slug: string; country_code: string | null; country_name?: string | null; latitude: number | null; longitude: number | null; launches: Num; launches_last_365d: Num; payloads?: Num; first_launch?: string | null; last_launch: string | null; } export interface EventEntity { type: string; id: string; relationship?: string; slug: string | null; name: string | null; norad_id?: number | null; } export interface EventRow { id: string; type: string; title: string; summary: string | null; event_time: string; detected_at?: string; confidence: number; source_id: string | null; source_name?: string | null; source_url?: string | null; metadata?: Record; entities?: EventEntity[] | null; } export interface GlobalStats { active_satellites: Num; objects_on_orbit: Num; objects_catalogued: Num; payloads_total: Num; payloads_on_orbit: Num; debris_on_orbit: Num; rocket_bodies_on_orbit: Num; decayed_objects: Num; decayed_last_30d: Num; decayed_last_365d: Num; with_elements: Num; payloads_launched_30d: Num; payloads_launched_365d: Num; payloads_launched_ytd: Num; active_operators: Num; active_countries: Num; active_constellations: Num; latest_epoch: string | null; } export interface LaunchTotals { total: Num; last_365d: Num; ytd: Num; last_30d: Num; } export interface BucketStat { bucket: string; objects: Num; active_payloads: Num; payloads: Num; debris: Num; rocket_bodies: Num; } export interface StatsSnapshot { computed_at: string; global: GlobalStats; launches: LaunchTotals; by_orbit_class: { orbit_class: string; active: Num; on_orbit: Num }[]; by_object_type: { object_type: string; on_orbit: Num; total: Num }[]; by_mission_type: { mission_type: string; active: Num }[]; launches_by_year: { year: number; launches: Num; payloads: Num }[]; payloads_by_launch_year: { year: number; payloads: Num; still_active: Num }[]; decays_by_year: { year: number; decayed: Num }[]; top_countries: CountryRow[]; top_operators: { id: string; slug: string; name: string; country_code: string | null; active_payloads: Num; total_payloads: Num; payloads_last_365d: Num }[]; top_constellations: { id: string; slug: string; name: string; operator_id: string | null; service_type: string | null; orbit_class: string | null; active: Num; on_orbit: Num; total: Num; launched_last_365d: Num; launched_last_30d: Num }[]; orbital_buckets: BucketStat[]; connectors: { name: string; source_id: string; last_success_at: string | null; last_attempt_at: string | null; interval_seconds: number; enabled: boolean; circuit_open_until: string | null; consecutive_failures: number }[]; } export interface HomePayload { stats: GlobalStats; launches: LaunchTotals; by_orbit_class: StatsSnapshot['by_orbit_class']; top_constellations: StatsSnapshot['top_constellations']; top_countries: CountryRow[]; top_operators: StatsSnapshot['top_operators']; orbital_buckets: BucketStat[]; latest_launches: LaunchRow[]; events: EventRow[]; reentries: { id: string; slug: string; name: string; norad_id: number | null; object_type: string; decay_date: string; country_code: string | null; country_name: string | null }[]; trending: { id: string; slug: string; name: string; norad_id: number | null; status: string; orbit_class: string | null; perigee_km: Num; constellation_name: string | null; operator_name: string | null; views: Num }[]; sources: { id: string; name: string; official: boolean; attribution_text: string | null; connector: string | null; last_success_at: string | null; interval_seconds: number | null; enabled: boolean }[]; computed_at: string; } export interface PositionsSnapshot { t0: string; t1: string; step_s: number; count: number; total_tracked: number; fields: string[]; norad: number[]; cls: number[]; mission: number[]; active: number[]; pos: number[]; // lat0, lon0, alt0, lat1, lon1, alt1 per object vel: number[]; legend: { cls: string[]; mission: string[] }; } export interface SearchResult { entity_type: 'satellite' | 'operator' | 'constellation' | 'country' | 'launch' | 'launch_site'; entity_id: string; slug: string; title: string; subtitle: string | null; norad_id?: number | null; score: number; href: string; } export interface SearchPayload { query: string; results: SearchResult[]; shortcuts: { label: string; href: string; filter: Record }[]; } export interface SourceRow { id: string; name: string; type: string; base_url: string | null; official: boolean; country_code: string | null; authority_type: string | null; license: string | null; attribution_required: boolean; attribution_text: string | null; update_frequency_seconds: number | null; enabled: boolean; priority: number; connectors: { name: string; description: string | null; interval_seconds: number; enabled: boolean; last_success_at: string | null; last_attempt_at: string | null; last_duration_ms: number | null; consecutive_failures: number; circuit_open_until: string | null; next_run_at: string | null }[] | null; provenance_rows: Num; raw_snapshots: Num; last_snapshot_at: string | null; freshness: 'fresh' | 'aging' | 'stale' | 'unavailable' | 'not_enabled'; } export interface ConnectorStatus { name: string; source_id: string; source_name: string; enabled: boolean; interval_seconds: number; last_success_at: string | null; last_attempt_at: string | null; last_duration_ms: number | null; consecutive_failures: number; circuit_open_until: string | null; next_run_at: string | null; last_status: string | null; last_error: string | null; freshness: string; } export interface SourcesStatus { connectors: ConnectorStatus[]; orbit: { latest_epoch: string | null; median_element_age_hours: number | null; propagator_objects: number }; } export interface HealthPayload { status: string; version: string; time: string; components: Record; } export interface MethodologyPayload { metrics: { key: string; name: string; version: string; methodology: string; inputs: string[]; updated_at: string }[]; constellation_rules: { slug: string; name: string; match_patterns: string[]; celestrak_groups: string[]; service_type: string | null }[]; owner_codes: { code: string; name: string; kind: string; country_code: string | null }[]; } export interface DensityPayload { buckets: BucketStat[]; leo_profile_25km: { alt_km: Num; objects: Num; active_payloads: Num; debris: Num; rocket_bodies: Num }[]; inclination_profile_5deg: { incl_deg: Num; objects: Num; active_payloads: Num }[]; methodology: string; } export interface DebrisPayload { totals: { debris: Num; rocket_bodies: Num; unknown: Num; inactive_payloads: Num }; by_country: { code: string; name: string; slug: string; debris: Num; rocket_bodies: Num }[]; by_altitude: { alt_km: Num; debris: Num; rocket_bodies: Num }[]; by_launch: { cospar_launch_id: string; launch_date: string | null; primary_name: string | null; site_name: string | null; debris_on_orbit: Num; owner_codes: string[] }[]; debris_growth: { year: number; debris_catalogued: Num; debris_still_on_orbit: Num }[]; decays_by_year: { year: number; debris: Num; rocket_bodies: Num; payloads: Num }[]; largest_objects: { id: string; slug: string; name: string; norad_id: number | null; object_type: string; rcs_m2: Num; perigee_km: Num; apogee_km: Num; launch_date: string | null; country_code: string | null }[]; disclaimer: string; } export interface ReentryRow { id: string; slug: string; name: string; norad_id: number | null; cospar_id: string | null; object_type: string; decay_date: string; launch_date: string | null; country_code: string | null; country_name: string | null; rcs_m2: Num; perigee_km: Num; apogee_km: Num; operator_name: string | null; constellation_name: string | null; constellation_slug: string | null; } export interface ReentriesPayload extends Paginated { summary: { last_7d: Num; last_30d: Num; last_365d: Num }; monthly: { month: string; decayed: Num; payloads: Num; debris: Num; rocket_bodies: Num }[]; low_perigee_watch: { id: string; slug: string; name: string; norad_id: number | null; object_type: string; perigee_km: Num; apogee_km: Num; epoch: string; country_code: string | null; constellation_name: string | null }[]; disclaimer: string; } export interface LaunchTimeline { years: { year: number; launches: Num; payloads: Num; us: Num; russia_cis: Num; china: Num; other: Num }[]; months: { month: string; launches: Num; payloads: Num }[]; sites: LaunchSiteRow[]; } export interface RankingsPayload { metric: string; rows: Record[]; }