IA · Desarrollo · PosicionamientoHablemos

Herramienta · En producción

Radar de vuelos que compone la ruta

Vigila durante meses los vuelos de viajes ya decididos, compara maneras de llegar (directo, directo más coche, escala, ida y vuelta por sitios distintos) con el coste real del grupo y avisa solo cuando merece la pena.

Cómo se ve

  • Parte superior de un panel oscuro: un bloque de oportunidades pendientes vacío, un cuadro de indicadores con viajes activos, compañías cubiertas, suscripciones activas, correos y alertas, y una bandeja de ofertas por revisar vacía
    El centro de mando: indicadores arriba y bandeja de ofertas por revisar debajo
  • Cuadro de indicadores del mismo panel en un móvil de 390 píxeles de ancho, con los números en dos columnas
    El mismo panel en un móvil, sin desplazamiento lateral

Qué problema resuelve

El vuelo bueno para un viaje de dentro de meses aparece un día cualquiera y dura poco, y no siempre donde se mira. Las alertas de precio de las aplicaciones solo entienden «A → B»: no saben que volar a un aeropuerto grande cercano y seguir en coche puede salir mejor, ni calculan el precio de todo el grupo con maleta de cabina.

Cómo funciona

  1. 01

    Compara maneras de llegar, no solo vuelos

    Para cada viaje guarda el destino, las fechas, el número de personas, el presupuesto y la hora límite de llegada. Con eso compone cuatro estrategias: vuelo directo, directo a un aeropuerto grande cercano más coche (hasta 250 km), escala (solo si no hay ningún directo válido) y ida y vuelta por aeropuertos distintos, con compañías distintas. Cada estrategia se puntúa con el coste real de todo el grupo.

  2. 02

    Las reglas de decisión son los tests

    Los criterios de quien decide (el directo más coche gana a dos aviones, llegar antes de la hora límite puntúa más que llegar justo, la tarifa siempre con maleta de cabina, alargar la vuelta solo si el ahorro es excepcional) están escritos como pruebas automáticas. Si una regla choca con el código, se corrige el código. Una oferta entra en la bandeja cuando supera los 60 puntos sobre 100.

  3. 03

    Búsquedas desde casa, panel en un servidor

    El panel vive en un servidor privado. Las búsquedas las hace un programa aparte, en un contenedor ligero de un ordenador doméstico, con conexión residencial: pide trabajo a la API con una clave, busca y devuelve el resultado. El panel nunca abre puertos hacia ese programa; es el programa quien llama.

  4. 04

    Frenos para no molestar a las fuentes

    Tope de 150 peticiones al día en la fuente principal, esperas de 10 a 20 segundos entre búsquedas y una pausa de seis horas si la página no tiene el formato esperado. Por política, el sistema nunca se salta un control anti-robot, una cuenta ni un CAPTCHA: si una fuente se cierra, se aparta.

  5. 05

    Cada aviso se puede explicar

    El histórico de precios solo admite inserciones (una regla de la base de datos impide modificarlo) y cada puntuación guarda su desglose. Así se puede saber por qué se avisó, o no, de un precio. El sistema no compra nada: enlaza a la fuente y decide una persona.

El stack, explicado

«Stack» son las herramientas con las que algo está hecho. La aplicación es un único programa en Python con FastAPI (el servidor web), plantillas y htmx (que refresca partes de la pantalla sin escribir JavaScript propio). Los datos van en SQLite, una base de datos en un solo fichero, y un planificador decide cuándo toca buscar cada viaje: cuanto más cerca está la fecha, más a menudo. Se despliega con Docker (cada servicio en su caja aislada) detrás de un servidor web que gestiona el cifrado. Los avisos salen por Telegram, reutilizando el mismo módulo de notificación de otro radar de la casa.

Las búsquedas las hace un segundo programa, el «worker», en un contenedor de un ordenador doméstico. Se separó a propósito: desde la conexión de una vivienda las peticiones parecen las de una persona, y desde un servidor en un centro de datos muchas fuentes las bloquean.

Cómo se construyó

Primero, un documento de «choques con la realidad»: el planteamiento inicial lo había escrito un asistente de chat sin conocer las herramientas disponibles, y varias de sus piezas no existían (por ejemplo, una API de precios para particulares). Después, un análisis de amenazas antes de la primera línea de código y cuatro planes por fases, cada uno ejecutado con un asistente que implementa cada tarea, otro que la revisa y una revisión final de la rama completa por otro modelo distinto.

Qué aprendimos

Un resultado vacío no es un fallo. Una ruta sin vuelos devolvía una página sin resultados y el sistema la contaba como «formato roto»; tres seguidas pausaban todo el programa seis horas, y volvía a pasar al despertar. Durante un día entero el programa no hizo nada y el registro lo daba por caído. El arreglo: contar rutas distintas vacías (no peticiones seguidas) y reiniciar los contadores al salir de una pausa. Tras el cambio, once búsquedas seguidas salieron bien. Regla: ante «no hace nada», mirar primero el fichero de estado del programa antes de suponer que está parado.

Cerrar un plan contra la especificación, no contra sí mismo. Un formulario del diseño original desapareció porque el plan lo apuntó como «fuera de esta fase» y nadie volvió a cruzar esa línea con el diseño.

Las reglas de quien decide, escritas como tests. Obliga a precisarlas, y deja claro cuándo una preferencia es un tope y cuándo un objetivo.

Límites

Es una herramienta privada de un solo usuario: no hay capturas de oferta reales en esta ficha porque el panel incluye datos de viajes personales, y por eso las imágenes son recortes de la estructura. No compra, no reserva y no garantiza que el mejor precio esté entre los que ve: solo cubre las fuentes que se pueden consultar sin saltarse controles. Las cifras de arriba son las del registro del proyecto en el momento de escribir esta ficha.

Con qué está hecho

  • Python
  • FastAPI
  • htmx
  • SQLite
  • Docker
  • Telegram

Qué hicimos

  • En producción con panel privado, inicio de sesión y avisos por Telegram; 320 pruebas automáticas, y las pruebas fallan si el código emite cualquier advertencia nueva.
  • Se investigaron 24 fuentes una a una, con una ficha por fuente. Resultado: solo dos compañías low cost ofrecen datos directos accesibles; las de red están protegidas contra automatización; una API pública conocida se había descontinuado. Por eso las fuentes que funcionan hoy son Google Flights con una librería de código abierto y las alertas de precio que Google envía por correo.
  • Un lector de correo en modo solo lectura procesa esas alertas y las newsletters de 33 dominios de remitentes; no sigue ningún enlace de forma automática.
  • Seguridad pensada antes de escribir código: claves comparadas en tiempo constante, contraseñas con scrypt, bloqueo tras varios intentos fallidos, protección contra falsificación de formularios, política de contenido estricta sin código incrustado y copia nocturna de la base con retención limitada.
  • Comprobado con una revisión independiente antes de salir a producción y con una prueba manual en navegador, en escritorio y a 390 píxeles.

Qué no entraba

  • No hay alta ni edición de viajes desde el panel: hoy se hacen con una orden de línea de comandos. Estaba en el diseño y se cayó al cerrar un plan, porque el cierre se revisó contra el propio plan y no contra el diseño original.
  • No se puede exigir una hora de salida para la vuelta: se elige a ojo entre las que muestra el panel.
  • No avisa si el programa de búsqueda lleva horas sin pedir trabajo. Estaba previsto y no está implementado.
  • Los datos directos de las dos compañías low cost que los ofrecen están pendientes de conectar.
  • Depende de que Google no cambie el formato de su página de resultados; ya hubo un día en que dejó de entenderla.

¿Tienes un proyecto parecido?

Cuéntanos qué necesitas y te decimos cómo lo haríamos y si te sale a cuenta.

Hablemos

Más en el LAB