apsis
PublicadoPredicción de pases de satélite sobre datos orbitales reales - open source.
apsis es un pequeño backend open source que responde a una pregunta operativa: cuándo será visible un satélite dado desde una estación terrestre dada, y por dónde pasará. Toma elementos orbitales reales (TLE) de CelesTrak, los propaga con SGP4 a través de skyfield y devuelve los próximos pases visibles junto al ground track sub-satélite como GeoJSON. Corre sobre FastAPI y PostgreSQL/PostGIS, con jobs programados y un outbox transaccional dentro del propio Postgres - sin broker de mensajes.
Mapa interactivo (requiere JavaScript). Los pases se describen en el texto.
El problema: visibilidad del segmento terreno
Una estación terrestre solo puede comunicarse con un satélite mientras está por encima del horizonte local. Planificar esa ventana de contacto implica propagar la órbita, encontrar los eventos de orto / culminación / ocaso por encima de una elevación mínima y proyectar la traza sobre el suelo. Es la misma familia de problema en la que trabajo en el segmento terreno europeo - tooling de segmento terreno de satélites en Telespazio alrededor de SIBA y Sentinel/Copernicus. apsis lo destila en una referencia pública limpia, sin nada confidencial.
La tesis: sin broker
apsis tiene dos clases de trabajo en segundo plano: recurrente (refrescar los TLE cada un par de horas) y reactivo (cuando una órbita cambia, recalcular sus pases). La respuesta refleja es un broker de mensajes más un framework de workers. apsis usa PostgreSQL para ambas: una tabla scheduled_jobs con un lease para lo recurrente, y un outbox transaccional (LISTEN/NOTIFY más SELECT ... FOR UPDATE SKIP LOCKED) para que un evento se dispare si y solo si la escritura en base de datos se confirmó. Una pieza móvil menos que desplegar, asegurar y monitorizar.
La geometría: PostGIS
Las estaciones son puntos, los ground tracks son linestrings, todo en WGS84 (longitud/latitud, SRID 4326). PostGIS los almacena e indexa; la API serializa cada traza directamente a GeoJSON - que es exactamente lo que pinta el mapa de arriba, sin tocar nada. Preguntar qué pases cruzan un bounding box queda entonces a un índice GiST de distancia.
Cuándo NO lo haría
La parte honesta. Una cola nativa en Postgres es la decisión correcta para un servicio que ya es dueño de su base de datos y necesita trabajo en segundo plano fiable y transaccional a escala humana. Es la decisión equivocada con throughput muy alto, para fan-out a muchos consumidores independientes, o para integración entre lenguajes y servicios - ahí toca un broker de verdad. El trade-off completo está en una nota.
Arquitectura
Por capas y por contexto: API a casos de uso a servicios y repositorios a modelos. El núcleo de cálculo - propagación orbital, búsqueda de pases, geometría - es puro, síncrono y sin efectos, sacado del event loop asíncrono con un pequeño helper run_blocking. Las decisiones de diseño están registradas como ADRs en el repositorio.