erp-transportistas-v2/docs/20-frontend/MAPA-TRACKING-RT.md
Adrian Flores Cortes 6ed7f9e2ec [BACKUP] Pre-restructure workspace backup 2026-01-29
- Updated docs and inventory files
- Added new architecture docs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 17:35:54 -06:00

324 lines
6.9 KiB
Markdown

# Mapa de Tracking en Tiempo Real - Documentacion Tecnica
**Feature:** tracking
**Sprint:** S7
**Estado:** Funcional (mapas pendientes)
**Fecha:** 2026-01-28
---
## 1. Vision General
El sistema de tracking en tiempo real permite:
- Visualizar posicion actual de unidades en mapa
- Ver historial de ruta recorrida
- Monitorear eventos y alertas
- Calcular y mostrar ETA dinamico
- Recibir actualizaciones via WebSocket
---
## 2. Arquitectura de Componentes
```
ViajeTrackingView
├── MapSection (mapa con ruta)
│ ├── RoutePolyline (ruta planificada)
│ ├── HistoryPolyline (ruta recorrida)
│ ├── CurrentPositionMarker
│ ├── OriginMarker
│ └── DestinationMarker
├── ETAProgressBar
│ ├── MilestoneIndicators
│ └── ProgressLine
└── EventTimeline
├── EventCards (17 tipos)
└── TimelineConnector
```
---
## 3. Tipos Principales
### 3.1 ENUMs
```typescript
enum TipoEventoTracking {
// GPS
POSICION = 'POSICION',
GPS_POSICION = 'GPS_POSICION',
// Geocercas
GEOCERCA_ENTRADA = 'GEOCERCA_ENTRADA',
GEOCERCA_SALIDA = 'GEOCERCA_SALIDA',
// Flujo de viaje
INICIO_VIAJE = 'INICIO_VIAJE',
ARRIBO_ORIGEN = 'ARRIBO_ORIGEN',
INICIO_CARGA = 'INICIO_CARGA',
FIN_CARGA = 'FIN_CARGA',
SALIDA = 'SALIDA',
ARRIBO_DESTINO = 'ARRIBO_DESTINO',
INICIO_DESCARGA = 'INICIO_DESCARGA',
FIN_DESCARGA = 'FIN_DESCARGA',
ENTREGA_POD = 'ENTREGA_POD',
FIN_VIAJE = 'FIN_VIAJE',
// Incidentes
PARADA = 'PARADA',
DESVIO = 'DESVIO',
INCIDENTE = 'INCIDENTE'
}
enum FuenteEvento {
GPS = 'GPS',
APP_OPERADOR = 'APP_OPERADOR',
SISTEMA = 'SISTEMA',
MANUAL = 'MANUAL',
GEOCERCA = 'GEOCERCA'
}
```
### 3.2 Interfaces
```typescript
interface PosicionActual {
lat: number;
lng: number;
velocidad: number;
rumbo: number;
timestamp: string;
precision: number;
}
interface EventoTracking {
id: string;
viajeId: string;
tipo: TipoEventoTracking;
fuente: FuenteEvento;
timestampEvento: string;
ubicacion: { lat: number; lng: number } | null;
descripcion: string;
metadata: Record<string, unknown>;
}
interface TrackingData {
viajeId: string;
posicionActual: PosicionActual;
rutaPlanificada: [number, number][];
rutaRecorrida: [number, number][];
eventos: EventoTracking[];
eta: {
llegadaEstimada: string;
distanciaRestante: number;
tiempoRestante: string;
};
}
```
---
## 4. WebSocket Integration
### 4.1 Hook useTrackingWebSocket
```typescript
// hooks/useTrackingWebSocket.ts
export function useTrackingWebSocket(viajeId: string) {
const [isConnected, setIsConnected] = useState(false);
const [lastPosition, setLastPosition] = useState<PosicionActual | null>(null);
const [eventos, setEventos] = useState<EventoTracking[]>([]);
useEffect(() => {
const ws = new WebSocket(`${WS_URL}/tracking/${viajeId}`);
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'position') {
setLastPosition(data.payload);
} else if (data.type === 'event') {
setEventos(prev => [...prev, data.payload]);
}
};
// Auto-reconnect logic included
}, [viajeId]);
return { isConnected, lastPosition, eventos };
}
```
### 4.2 Mensajes WebSocket
```typescript
// Posicion
{
type: 'position',
payload: {
lat: 19.4326,
lng: -99.1332,
velocidad: 85,
rumbo: 45,
timestamp: '2026-01-28T10:30:00Z'
}
}
// Evento
{
type: 'event',
payload: {
id: 'evt-123',
tipo: 'ARRIBO_DESTINO',
fuente: 'GPS',
timestamp: '2026-01-28T10:30:00Z',
descripcion: 'Unidad arribo a destino'
}
}
```
---
## 5. ETAProgressBar Component
### 5.1 Milestones
```typescript
const milestones = [
{ id: 'origin', label: 'Origen', icon: 'MapPin' },
{ id: 'loaded', label: 'Cargado', icon: 'Package' },
{ id: 'transit', label: 'En Transito', icon: 'Truck' },
{ id: 'destination', label: 'Destino', icon: 'Flag' },
{ id: 'delivered', label: 'Entregado', icon: 'CheckCircle' }
];
```
### 5.2 Progress Calculation
```typescript
function calculateProgress(eventos: EventoTracking[]): number {
const weights = {
INICIO_VIAJE: 0,
ARRIBO_ORIGEN: 10,
FIN_CARGA: 25,
SALIDA: 30,
EN_TRANSITO: 50, // Interpolado por distancia
ARRIBO_DESTINO: 80,
FIN_DESCARGA: 90,
ENTREGA_POD: 100
};
const lastEvent = eventos[eventos.length - 1];
return weights[lastEvent?.tipo] || 0;
}
```
---
## 6. EventTimeline Component
### 6.1 Iconos por Tipo
```typescript
const eventIcons: Record<TipoEventoTracking, React.ComponentType> = {
POSICION: MapPin,
GPS_POSICION: Satellite,
GEOCERCA_ENTRADA: LogIn,
GEOCERCA_SALIDA: LogOut,
INICIO_VIAJE: PlayCircle,
ARRIBO_ORIGEN: MapPin,
INICIO_CARGA: Package,
FIN_CARGA: PackageCheck,
SALIDA: Truck,
ARRIBO_DESTINO: Flag,
INICIO_DESCARGA: PackageOpen,
FIN_DESCARGA: PackageCheck,
ENTREGA_POD: FileCheck,
FIN_VIAJE: CheckCircle,
PARADA: PauseCircle,
DESVIO: AlertTriangle,
INCIDENTE: AlertOctagon
};
```
### 6.2 Colores por Tipo
```typescript
const eventColors: Record<TipoEventoTracking, string> = {
INICIO_VIAJE: 'bg-green-500',
FIN_VIAJE: 'bg-green-600',
INCIDENTE: 'bg-red-500',
PARADA: 'bg-yellow-500',
DESVIO: 'bg-orange-500',
// ... otros
default: 'bg-blue-500'
};
```
---
## 7. API Endpoints
| Endpoint | Metodo | Descripcion |
|----------|--------|-------------|
| `/api/v1/tracking/viajes/:id` | GET | Datos de tracking de viaje |
| `/api/v1/tracking/viajes/:id/eventos` | GET | Historial de eventos |
| `/api/v1/tracking/viajes/:id/ruta` | GET | Ruta planificada y recorrida |
| `/api/v1/gps/posiciones/ultima/:dispositivoId` | GET | Ultima posicion |
| `WS /tracking/:viajeId` | WS | Streaming de posiciones |
---
## 8. Integracion con Mapas (Pendiente)
### 8.1 Estado Actual
- Mapa placeholder con CSS gradient
- Polylines simplificados con SVG
- Marcadores posicionados con % relativo
### 8.2 Implementacion con Leaflet
```typescript
import { MapContainer, Polyline, Marker, Popup } from 'react-leaflet';
const TrackingMap = ({ data }: { data: TrackingData }) => (
<MapContainer center={data.posicionActual} zoom={12}>
<TileLayer url="..." />
{/* Ruta planificada */}
<Polyline
positions={data.rutaPlanificada}
color="blue"
dashArray="5,10"
/>
{/* Ruta recorrida */}
<Polyline
positions={data.rutaRecorrida}
color="green"
weight={4}
/>
{/* Posicion actual */}
<Marker position={[data.posicionActual.lat, data.posicionActual.lng]}>
<Popup>
<span>Velocidad: {data.posicionActual.velocidad} km/h</span>
</Popup>
</Marker>
</MapContainer>
);
```
---
## 9. Performance Considerations
1. **Throttle WebSocket updates**: Maximo 1 update por segundo en UI
2. **Virtualized EventTimeline**: Para viajes con 100+ eventos
3. **Route simplification**: Usar Douglas-Peucker para rutas largas
4. **Map tile caching**: Service worker para tiles frecuentes
---
*Sprint S7 - TASK-007 | Sistema SIMCO v4.0.0*