!
Arquitectura e implementación
De 4 PDF oficiales del gobierno bonaerense a una tabla de horarios navegable: descarga, parsing y modelo de datos detrás de Lanchas.
Un horario nuevo del gobierno reemplaza al anterior, no convive con él. Cada ejecución vuelca el horario completo a lanchas_raw.horarios con WRITE_TRUNCATE en lugar de upsert por clave: la tabla queda igual al cronograma vigente, sin versiones acumuladas.
Un mismo horario de lancha pasa por varias vías durante el viaje, no por una sola. fact_horario repite ese horario una vez por cada vía de su recorrido, en lugar de una sola vez por servicio, para mostrar el horario real de paso en cualquier parada intermedia, no solo en el origen y destino.
BigQuery
lanchas_raw.horarios - full-refresh (WRITE_TRUNCATE)
EN NÚMEROS
- fact_horario: 7.100 filas (grano horario + vía)
- dim_via 72 filas, dim_tipo_dia 8, dim_empresa y dim_linea 3 cada una
- Cada ejecución reemplaza el dataset completo: no hay versión anterior que conservar
dbt
1 staging + 4 dimensiones + 1 fact, star schema
HACE
- stg_lanchas_horarios limpia formato (trim), sin lógica de negocio
- dim_empresa, dim_linea, dim_via, dim_tipo_dia + fact_horario (grano horario+vía)
TESTS
- 31 tests genéricos: not_null, unique, relationships, accepted_values
- accepted_values fija tipo_dia (8 valores), servicio_tipo y dirección
Airflow
Motor compartido con Mareas (repo hermano); el DAG vive en este repo
HACE
- actualizar_pdfs → cargar_bigquery → dbt_run → dbt_test, una vez al mes
- El repo hermano monta este código como volumen: código y credenciales, nada más
- El DAG viaja por script (sync_dags.sh), con symlink o copia según el entorno
Ministerio de Infraestructura (GBA)
4 PDF publicados por el gobierno bonaerense, mismo motor de generación
LINEA_450.pdf · LINEA_451.pdf · LINEA_452.pdf · LINEA_453.pdf
LA APP DESCARGA
- Jilguero (450), Interisleña (451+452 combinada) y Delta Argentino (453)
- Hash SHA-256 por archivo (combinado para el par 451/452) para detectar cambios reales
Un motor común, reglas explícitas
BaseGobiernoParser extrae los 3 PDF; cada ajuste sigue un criterio documentado, no una inferencia automática
Django ORM - PostgreSQL
Sin cache de archivos: los horarios se normalizan y persisten en modelos reales
Tecnologías aplicadas
ORM, views, service layer y management commands.
Mismo motor en dev y prod, vía DATABASE_URL.
Star schema full-refresh sobre lanchas_raw.horarios, en paralelo a la app.
Orquestación mensual en un repo hermano, compartido con Mareas.
Extracción de tablas por coordenadas, no texto plano.
Entorno de desarrollo reproducible: web + db con un solo comando.
CI en cada push/PR y smoke test semanal contra las fuentes reales.
Testing con foco en services y parsers.
Acordeón de líneas, buscador y filtros, sin dependencias.
Favoritos 100% client-side, sin cuentas ni sesión.
Temas Día / Noche en tiempo real.
Management commands
Actualización y validación del catálogo sin depender de la interfaz web.
lanchas_inicializar
Crea Empresa/Línea en la base - se corre una sola vez.
lanchas_descargar_pdfs [--linea N]
Descarga los PDF oficiales del gobierno.
lanchas_parsear_pdfs [--linea N] [--forzar]
Parsea y carga los horarios en la base.
lanchas_actualizar [--linea N] [--forzar]
Descarga + parseo en un solo paso - cron semanal.
lanchas_validar
Chequeo de integridad del catálogo cargado.
lanchas_listar [--empresa] [--via]
Exploración rápida de los datos cargados.
lanchas_cargar_bigquery
Sube el horario vigente a BigQuery (WRITE_TRUNCATE, sin histórico).
Cobertura sobre parsers y services
Suite automatizada ejecutada en cada cambio, separada del chequeo contra las fuentes reales
Un comando, datos reales incluidos
El primer boot corre migraciones y carga el fixture con datos reales automáticamente, sin pasos manuales adicionales.
cp .env.example .env
Variables de entorno de ejemplo, listas para levantar el proyecto.
docker compose up --build
Levanta web + db, corre migraciones y carga datos reales de ejemplo.
github.com/chipap-dev/lanchas
Repositorio público, standalone, clonable sin credenciales - instrucciones de instalación con Docker incluidas.