satellite-tracker

🏗️ Satellite Tracker System Architecture

This document provides a comprehensive overview of the Satellite TLE Tracker & AI Orbital Discovery platform architecture, data flows, components, and security mechanisms.


1. System Overview

The application is a modular Flask 3 app. Persistence is SQLAlchemy 2 against either SQLite or PostgreSQL (psycopg 3, URI scheme postgresql+psycopg://). Engine choice is stored in instance/datastore.json so it can survive database wipes and be changed from Admin. Orbit math runs in Python (sgp4) and in the browser (satellite.js). Admin access uses Google OAuth2 with a fail-closed local bypass. Text-to-SQL runs in-process via llama-cpp-python and Qwen2.5-Coder-1.5B.

+-----------------------------------------------------------------------------------+
|                                 User Interface                                    |
|  Keyword Search (default) | Country Proximity + prefixes | Offline AI | Tracker   |
|  First-launch /setup      | Admin datastore + SQL explorer | Fullscreen maps      |
+-----------------------------------------------------------------------------------+
                                          |
                                    HTTP / JSON API
                                          v
+-----------------------------------------------------------------------------------+
|                                 Flask Application                                 |
|  setup_bp   upload_bp   report_bp   admin_bp   auth_bp                             |
|  - wizard   - GET form  - keyword   - reset    - OAuth                             |
|  - bind     - ingest    - proximity - SQL      - is_local_dev() fail-closed        |
|                         - Text-to-SQL - datastore switch                           |
|  Geo / LLM / sql_console / datastore / overlay (EONET, USGS, Open-Meteo, CNBC, OpenSky, GDACS, Digitraffic) |
+-----------------------------------------------------------------------------------+
                                          |
                         SQLAlchemy ORM  (rebind on datastore.json change)
                                          v
+-----------------------------------------------------------------------------------+
|  SQLite (instance/*.db)  or  PostgreSQL 18.6                                      |
|  uploads | satellites | tle_elements | saved_queries | system_settings            |
+-----------------------------------------------------------------------------------+
|  instance/datastore.json  (engine + URI; not stored inside the satellite tables)  |
+-----------------------------------------------------------------------------------+

2. Component Architecture

2.1 Ingestion & Parsing Engine (app/services/tle_parser.py)

2.2 Datastore & Persistence (app/services/datastore.py, app/services/db_service.py)

2.3 Search (app/routes/report.py)

2.4 Offline AI Text-to-SQL Engine (app/routes/report.py)

2.5 Maps (app/static/js/basemap.js)

2.6 Web analytics (PostHog)

2.7 Admin Control & Google OAuth (app/routes/admin.py, app/routes/auth.py)


3. Database Schema

erDiagram
    Uploads ||--o{ TLEElements : contains
    Satellites ||--o{ TLEElements : owns

    Uploads {
        int id PK
        string filename
        datetime upload_time
        int total_records_in_file
        int new_satellites
        int updated_satellites
        int duplicate_epochs
        string source
        boolean is_seed
        string label
    }

    Satellites {
        int id PK
        int norad_cat_id UK
        string name
        string classification
        string int_designator
        datetime first_seen
        datetime last_updated
    }

    TLEElements {
        int id PK
        int satellite_id FK
        int upload_id FK
        int epoch_year
        float epoch_day
        datetime epoch_datetime
        float mean_motion_dot
        float mean_motion_ddot
        float bstar_drag
        float inclination_deg
        float raan_deg
        float eccentricity
        float arg_of_perigee_deg
        float mean_anomaly_deg
        float mean_motion_rev_day
        int rev_number
        string raw_line1
        string raw_line2
    }

    SavedQueries {
        int id PK
        string name
        string sql
        int row_limit
        datetime created_at
        datetime last_run_at
        float last_run_ms
        int last_run_row_count
        int run_count
        float latency_p50_ms
        float latency_p95_ms
        float latency_p99_ms
        float latency_p100_ms
        string latency_samples_json
    }

saved_queries lives in the active datastore so saved SQL and latency percentiles survive process restarts and migrate with an engine switch.


4. Security Infrastructure

  1. Read-Only Text-to-SQL and Admin SQL:
    • AI search: SELECT only; mutation keywords blocked.
    • Admin console: single statement, no stacked ;, SELECT / WITH / EXPLAIN only, same mutation blocklist.
  2. Session Authentication:
    • Google OAuth 2.0 with ADMIN_ALLOWED_EMAILS. Production images set FLASK_ENV=production so the local bypass cannot be reached on advertised 1-click/cloud deploys.
  3. Environment Security:
    • Secrets in .env. instance/datastore.json is host-owned (0o600). Unreadable files are DATASTORE_UNREADABLE, not treated as first-launch.
  4. Uploads:
    • MAX_CONTENT_LENGTH 16 MB; TLE checksum and line-length checks.