- Updated docs and inventory files - Added new architecture docs Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
98 lines
6.2 KiB
Markdown
98 lines
6.2 KiB
Markdown
# 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_gps` particionada por mes (campo `fecha_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 `PositionIngestionService` con metodo `ingestPosition()` que: 1) Identifica unidad por IMEI, 2) Valida posicion, 3) Asocia a viaje activo si existe, 4) Almacena en BD, 5) Emite via WebSocket. Crear `WebhookController` con endpoint POST `/api/webhooks/gps/:provider`. Implementar adaptadores para cada proveedor (Traccar, Wialon, Samsara, Geotab).
|
|
- **WebSocket:** Implementar gateway WebSocket (`TrackingGateway`) con canal `/ws/tracking/flota` segregado por tenant_id. Emitir eventos `position.updated` con 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 `CheckDeviceConnectivity` que 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/traccar`
|
|
- `POST /api/webhooks/gps/wialon`
|
|
- `POST /api/webhooks/gps/samsara`
|
|
- `POST /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*
|