- Updated docs and inventory files - Added new architecture docs Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
6.2 KiB
US-MAI006-012: Recibir posiciones GPS en tiempo real
Metadata
| Campo | Valor |
|---|---|
| ID | US-MAI006-012 |
| Epica | EPIC-MAI-006 - Tracking en Tiempo Real |
| Modulo | tracking |
| Prioridad | P0 |
| Story Points | 8 |
| Sprint | Por asignar |
| Estado | Backlog |
Historia de Usuario
Como coordinador de trafico de una empresa transportista, quiero ver las posiciones GPS de las unidades actualizandose cada 30 segundos en el mapa, para monitorear la ubicacion de la flota en tiempo real y tomar decisiones operativas informadas.
Descripcion Detallada
La recepcion de posiciones GPS en tiempo real es la funcionalidad central del modulo de tracking. El sistema debe ser capaz de recibir posiciones desde multiples fuentes (webhooks de proveedores GPS, polling a APIs, ingesta manual) y procesarlas de manera eficiente para que se visualicen en el mapa de flota con minima latencia.
Cada posicion recibida se almacena en la tabla particionada tracking.posiciones_gps con todos los metadatos disponibles (velocidad, rumbo, altitud, odometro, estado del motor, precision GPS). El sistema identifica la unidad correspondiente a traves del IMEI del dispositivo y, si la unidad tiene un viaje activo, asocia la posicion al viaje.
Las actualizaciones se transmiten a los clientes web conectados a traves de WebSocket, permitiendo que el mapa se actualice sin necesidad de hacer polling. El intervalo de actualizacion configurado (por defecto 30 segundos) determina la frecuencia esperada de posiciones, y se generan alertas cuando un dispositivo deja de reportar.
Criterios de Aceptacion
Escenario 1: Recibir posicion via webhook del proveedor GPS
Dado que existe un dispositivo GPS activo con IMEI "352093088937641" asociado a la Unidad T-001,
Cuando el proveedor GPS (Traccar) envia un webhook con la posicion: lat 19.4326, lon -99.1332, velocidad 65 km/h, timestamp 2026-01-27T14:30:00Z,
Entonces el sistema crea un registro en tracking.posiciones_gps con todos los datos, asociado a la unidad correspondiente, y emite la actualizacion via WebSocket al canal /ws/tracking/flota.
Escenario 2: Asociar posicion a viaje activo
Dado que la Unidad T-001 tiene un viaje activo (estado EN_TRANSITO) y recibe una nueva posicion GPS,
Cuando se procesa la posicion,
Entonces el sistema asocia la posicion al viaje activo (viaje_id) permitiendo trazar el recorrido del viaje y calcular distancia recorrida.
Escenario 3: Actualizar mapa en tiempo real via WebSocket
Dado que el coordinador tiene abierto el dashboard de flota con el mapa, Cuando se recibe una nueva posicion de cualquier unidad del tenant, Entonces el marcador de la unidad en el mapa se mueve a la nueva posicion en menos de 2 segundos desde que se proceso la posicion, mostrando velocidad actual y direccion.
Escenario 4: Detectar dispositivo sin reportar
Dado que un dispositivo GPS tiene configurado intervalo de 30 segundos y no ha reportado en los ultimos 5 minutos, Cuando el sistema ejecuta la verificacion periodica de conectividad, Entonces se genera una alerta de tipo "SIN_SENAL" con severidad WARNING para la unidad correspondiente y se muestra indicador visual de "Sin conexion" en el mapa.
Escenario 5: Almacenar posicion con datos completos
Dado que se recibe una posicion GPS con todos los datos opcionales (altitud, rumbo, odometro, motor_encendido, hdop, satelites), Cuando se procesa la posicion, Entonces todos los campos se almacenan correctamente en la BD y estan disponibles para consulta en el historial de posiciones.
Escenario 6: Alta frecuencia de posiciones
Dado que el sistema recibe 100 posiciones por segundo de diferentes unidades, Cuando se procesan las posiciones, Entonces todas se almacenan correctamente sin perdida de datos y el tiempo de procesamiento por posicion es menor a 100ms.
Tareas Tecnicas
- Database: Verificar tabla
tracking.posiciones_gpsparticionada por mes (campofecha_particion). Verificar indices: idx_posicion_unidad_fecha, idx_posicion_viaje, idx_posicion_geo (GIST). Crear particion para el mes actual si no existe. - Backend: Crear
PositionIngestionServicecon metodoingestPosition()que: 1) Identifica unidad por IMEI, 2) Valida posicion, 3) Asocia a viaje activo si existe, 4) Almacena en BD, 5) Emite via WebSocket. CrearWebhookControllercon endpoint POST/api/webhooks/gps/:provider. Implementar adaptadores para cada proveedor (Traccar, Wialon, Samsara, Geotab). - WebSocket: Implementar gateway WebSocket (
TrackingGateway) con canal/ws/tracking/flotasegregado por tenant_id. Emitir eventosposition.updatedcon payload: {unidadId, lat, lon, velocidad, rumbo, timestamp}. - Frontend: Implementar hook
useFleetWebSocket()que conecta al canal de tracking. Actualizar estado del mapa cuando se reciben posiciones. Mostrar indicador de ultima actualizacion por unidad. - Monitoring: Implementar job cron
CheckDeviceConnectivityque se ejecuta cada minuto y genera alertas para dispositivos sin reportar. - Tests: Tests de ingestion de posiciones. Tests de emision WebSocket. Tests de carga (100+ posiciones/segundo).
Dependencias
- Depende de: US-MAI006-011 (configurar dispositivo GPS), MAI-011 (unidades), MAI-003 (viajes)
- Bloquea: US-MAI006-001 (ver posicion actual), US-MAI006-005 (historial), US-MAI006-003 (alertas geocerca)
Notas Tecnicas
- Webhook Endpoints:
POST /api/webhooks/gps/traccarPOST /api/webhooks/gps/wialonPOST /api/webhooks/gps/samsaraPOST /api/webhooks/gps/geotab
- WebSocket Gateway:
@WebSocketGateway({ namespace: '/tracking' }) - Canal WebSocket:
/ws/tracking/flota- segregado por tenant via query param o header - Particionamiento: Las posiciones se almacenan en particiones mensuales (
posiciones_gps_2026_01,posiciones_gps_2026_02, etc.) - Timeout sin senal: Generar alerta si no hay posiciones en
5 * intervalo_configurado(default: 150 segundos) - Bulk insert: Para alto volumen, usar insert en lotes de 100 posiciones
- Redis cache: Cachear ultima posicion conocida de cada unidad en Redis para consultas rapidas
US-MAI006-012 - ERP Transportistas v1.0.0