# Fase 1: MVP - Sistema de Tracking de Trenes en Tiempo Real ## Estado: ✅ COMPLETADO La Fase 1 del roadmap ha sido implementada exitosamente. Este documento describe lo que se ha construido y cómo probarlo. --- ## ✨ Características Implementadas ### Backend - ✅ Worker GTFS-RT que recolecta posiciones cada 30 segundos - ✅ API REST con endpoints para trenes, rutas, estaciones y estadísticas - ✅ WebSocket server para actualizaciones en tiempo real - ✅ Integración con PostgreSQL + PostGIS - ✅ Cache Redis para posiciones actuales - ✅ Sistema de logs con Pino - ✅ Gestión de errores y reconexión automática ### Frontend - ✅ Mapa interactivo con Leaflet.js y OpenStreetMap - ✅ Visualización de trenes en tiempo real - ✅ Panel de información detallada de cada tren - ✅ Conexión WebSocket con reconexión automática - ✅ Timeline básico (UI preparado, funcionalidad fase 2) - ✅ Estadísticas en header (trenes activos, última actualización) - ✅ Diseño responsivo --- ## 📁 Estructura del Proyecto ``` trenes/ ├── backend/ │ ├── src/ │ │ ├── api/ │ │ │ ├── routes/ │ │ │ │ ├── trains.js # Endpoints de trenes │ │ │ │ ├── routes.js # Endpoints de rutas │ │ │ │ ├── stations.js # Endpoints de estaciones │ │ │ │ └── stats.js # Endpoints de estadísticas │ │ │ └── server.js # Servidor API + WebSocket │ │ ├── worker/ │ │ │ └── gtfs-poller.js # Worker GTFS-RT │ │ ├── lib/ │ │ │ ├── db.js # Cliente PostgreSQL │ │ │ ├── redis.js # Cliente Redis │ │ │ └── logger.js # Logger Pino │ │ └── config/ │ │ └── index.js # Configuración │ ├── package.json │ ├── Dockerfile │ └── .env.example │ ├── frontend/ │ ├── src/ │ │ ├── components/ │ │ │ ├── TrainMap.jsx # Mapa Leaflet │ │ │ ├── TrainInfo.jsx # Panel de información │ │ │ └── Timeline.jsx # Timeline (UI) │ │ ├── hooks/ │ │ │ └── useTrains.js # Hook WebSocket │ │ ├── styles/ │ │ │ └── index.css # Estilos globales │ │ ├── App.jsx # Componente principal │ │ └── main.jsx # Entry point │ ├── package.json │ ├── Dockerfile │ └── vite.config.js │ ├── database/ │ ├── init/ # Scripts iniciales │ └── migrations/ # Migraciones Flyway │ ├── docker-compose.yml ├── Makefile └── README.md ``` --- ## 🚀 Cómo Ejecutar el MVP ### Prerrequisitos - Docker y Docker Compose instalados - Puerto 80, 3000, 5432, 6379 disponibles - (Opcional) Make para comandos simplificados ### Opción 1: Usando Make (Recomendado) ```bash # 1. Configurar variables de entorno cp .env.example .env # Editar .env si es necesario # 2. Ejecutar migraciones make migrate # 3. Iniciar todos los servicios make start # 4. Ver logs make logs ``` ### Opción 2: Docker Compose Manual ```bash # 1. Configurar variables de entorno cp .env.example .env # 2. Ejecutar migraciones docker-compose --profile migration up flyway # 3. Iniciar servicios docker-compose up -d # 4. Ver logs docker-compose logs -f ``` ### Opción 3: Desarrollo Local (sin Docker) #### Backend ```bash cd backend # Instalar dependencias npm install # Configurar .env cp .env.example .env # Ajustar DATABASE_URL y REDIS_URL a localhost # Ejecutar worker en una terminal npm run dev:worker # Ejecutar API en otra terminal npm run dev ``` #### Frontend ```bash cd frontend # Instalar dependencias npm install # Ejecutar en modo desarrollo npm run dev ``` --- ## 🌐 Acceder a la Aplicación Una vez iniciados los servicios: - **Aplicación Web**: http://localhost - **API REST**: http://localhost/api o http://localhost:3000 - **Health Check**: http://localhost/health o http://localhost:3000/health --- ## 📡 Endpoints de la API ### Trenes ```bash # Obtener todos los trenes activos GET /trains/current # Obtener información de un tren específico GET /trains/:id # Obtener histórico de un tren GET /trains/:id/history?from=2025-11-27T00:00:00Z&to=2025-11-27T23:59:59Z&limit=100 # Obtener trayectoria de un tren GET /trains/:id/path?from=2025-11-27T10:00:00Z&to=2025-11-27T11:00:00Z # Obtener trenes en un área geográfica GET /trains/area?minLat=40.0&minLon=-4.0&maxLat=41.0&maxLon=-3.0 ``` ### Rutas ```bash # Obtener todas las rutas GET /routes # Obtener ruta específica GET /routes/:id ``` ### Estaciones ```bash # Obtener todas las estaciones GET /stations # Obtener estaciones por tipo GET /stations?type=MAJOR # Obtener estación específica GET /stations/:id ``` ### Estadísticas ```bash # Obtener estadísticas del sistema GET /stats # Obtener estadísticas de un tren GET /stats/train/:id?from=2025-11-27T00:00:00Z&to=2025-11-27T23:59:59Z ``` --- ## 🔌 WebSocket Events ### Cliente → Servidor ```javascript // Suscribirse a un tren específico socket.emit('subscribe:train', trainId); // Desuscribirse de un tren socket.emit('unsubscribe:train', trainId); ``` ### Servidor → Cliente ```javascript // Actualización de todos los trenes (cada 2 segundos) socket.on('trains:update', (positions) => { console.log('Posiciones actualizadas:', positions); }); // Actualización de un tren específico (si estás suscrito) socket.on('train:update', (position) => { console.log('Tren actualizado:', position); }); ``` --- ## 🧪 Probar el Sistema ### 1. Verificar que el Worker está funcionando ```bash # Ver logs del worker make logs-worker # O con docker-compose docker-compose logs -f worker # Deberías ver mensajes como: # "Polling GTFS-RT feed..." # "Processed vehicle positions: {trains: 50, duration: 1234}" ``` ### 2. Verificar API ```bash # Health check curl http://localhost:3000/health # Obtener trenes actuales curl http://localhost:3000/trains/current | jq # Obtener estadísticas curl http://localhost:3000/stats | jq ``` ### 3. Verificar Base de Datos ```bash # Conectar a PostgreSQL make psql # Ver trenes almacenados SELECT COUNT(*) FROM trains; # Ver posiciones de las últimas 24 horas SELECT COUNT(*) FROM train_positions WHERE recorded_at > NOW() - INTERVAL '24 hours'; # Ver estaciones SELECT * FROM stations LIMIT 10; ``` ### 4. Verificar Redis ```bash # Conectar a Redis make redis-cli # Ver trenes activos SMEMBERS trains:active # Ver posición actual de un tren GET trains:current:TRAIN_ID ``` --- ## 🐛 Troubleshooting ### No se ven trenes en el mapa **Causa**: El feed GTFS-RT puede no tener datos o el worker no está corriendo. **Solución**: ```bash # Verificar logs del worker make logs-worker # Verificar si hay trenes en Redis make redis-cli > SMEMBERS trains:active # Si Redis está vacío, verificar PostgreSQL make psql > SELECT COUNT(*) FROM train_positions WHERE recorded_at > NOW() - INTERVAL '1 hour'; ``` ### Error de conexión WebSocket **Causa**: CORS o URL incorrecta. **Solución**: ```bash # Verificar que VITE_WS_URL está configurado correctamente # En .env.testing o variables de entorno del frontend # Debería ser: http://localhost:3000 (desarrollo) o ws://localhost/ws (producción) ``` ### La base de datos no tiene datos **Causa**: Migraciones no ejecutadas o feed GTFS-RT sin datos. **Solución**: ```bash # Ejecutar migraciones make migrate # Verificar estado de migraciones make migrate-info # Ver datos iniciales make psql > SELECT * FROM stations LIMIT 5; ``` ### Error "PostgreSQL not connected" **Causa**: PostgreSQL no está corriendo o configuración incorrecta. **Solución**: ```bash # Verificar que PostgreSQL está corriendo docker-compose ps postgres # Reiniciar PostgreSQL docker-compose restart postgres # Verificar logs docker-compose logs postgres ``` --- ## 📊 Métricas y Monitorización ### Logs del Sistema ```bash # Ver todos los logs make logs # Ver logs específicos make logs-api # API make logs-worker # Worker make logs-db # PostgreSQL ``` ### Estadísticas del Worker El worker registra estadísticas cada 60 segundos: ```json { "totalPolls": 120, "successfulPolls": 118, "failedPolls": 2, "totalTrains": 45, "lastPollTime": "2025-11-27T10:30:00.000Z", "successRate": "98.33%" } ``` ### Panel de Administración Para acceder a herramientas de administración: ```bash # Iniciar con modo debug make debug-start # Acceder a: # - Adminer (PostgreSQL): http://localhost:8080 # - Redis Commander: http://localhost:8081 ``` --- ## 🎯 Próximos Pasos (Fase 2) La Fase 2 incluirá: - [ ] Integración GTFS Static (rutas, horarios) - [ ] Trip Updates (retrasos, cancelaciones) - [ ] Service Alerts (incidencias) - [ ] Timeline funcional con reproducción histórica - [ ] Monitor de puntualidad - [ ] Panel de incidencias Para más información, consultar el [roadmap completo](arquitectura-sistema-tracking-trenes.md#roadmap-de-features). --- ## 📝 Notas Técnicas ### Fuente de Datos El sistema consume el feed GTFS-RT de Renfe: - **URL**: https://gtfsrt.renfe.com/vehicle_positions.pb - **Formato**: Protocol Buffer (GTFS Realtime) - **Frecuencia**: 30 segundos - **Cobertura**: Principalmente Cercanías ### Almacenamiento - **PostgreSQL**: Histórico completo de posiciones (particionado por mes) - **Redis**: Cache de últimas posiciones (TTL 5 minutos) - **WebSocket**: Broadcast en tiempo real (cada 2 segundos) ### Rendimiento - **Polling**: 30 segundos (configurable via `POLLING_INTERVAL`) - **Broadcast WS**: 2 segundos - **Particiones DB**: Mensuales (nov 2025 - mar 2027) - **Retención**: 90 días (configurable, usar `cleanup_old_positions()`) --- ## 📚 Documentación Adicional - [Arquitectura Completa](arquitectura-sistema-tracking-trenes.md) - [Fuentes de Datos](FUENTES_DATOS.md) - [README Principal](README.md) - [Makefile Commands](Makefile) - Ver `make help` --- ## 🤝 Contribuir Si encuentras bugs o quieres proponer mejoras: 1. Crea un issue describiendo el problema/mejora 2. Haz un fork del proyecto 3. Crea una rama para tu feature 4. Envía un pull request --- **Estado**: Fase 1 MVP Completada ✅ **Fecha**: 27 noviembre 2025 **Próxima Fase**: Fase 2 - Enriquecimiento