Files
trenes/FASE1-MVP.md
Millaguie 34c0cb50c7
Some checks failed
Auto Tag on Merge to Main / auto-tag (push) Successful in 27s
CI - Lint and Build / lint-backend (push) Failing after 30s
CI - Lint and Build / lint-frontend (push) Failing after 2s
CI - Lint and Build / build-frontend (push) Has been skipped
CI - Lint and Build / docker-build-test (push) Has been skipped
feat: Initial commit - Train tracking system
Complete real-time train tracking system for Spanish railways (Renfe/Cercanías):

- Backend API (Node.js/Express) with GTFS-RT polling workers
- Frontend dashboard (React/Vite) with Leaflet maps
- Real-time updates via Socket.io WebSocket
- PostgreSQL/PostGIS database with Flyway migrations
- Redis caching layer
- Docker Compose configuration for development and production
- Gitea CI/CD workflows (lint, auto-tag, release)
- Production deployment with nginx + Let's Encrypt SSL

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 00:21:15 +01:00

486 lines
10 KiB
Markdown

# 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