FlotillasGPS - Sistema completo de monitoreo de flotillas GPS
Sistema completo para monitoreo y gestion de flotas de vehiculos con: - Backend FastAPI con PostgreSQL/TimescaleDB - Frontend React con TypeScript y TailwindCSS - App movil React Native con Expo - Soporte para dispositivos GPS, Meshtastic y celulares - Video streaming en vivo con MediaMTX - Geocercas, alertas, viajes y reportes - Autenticacion JWT y WebSockets en tiempo real Documentacion completa y guias de usuario incluidas.
This commit is contained in:
742
docs/guias/api-reference.md
Normal file
742
docs/guias/api-reference.md
Normal file
@@ -0,0 +1,742 @@
|
||||
# Referencia de API
|
||||
|
||||
Documentacion de la API REST de FlotillasGPS.
|
||||
|
||||
## Informacion General
|
||||
|
||||
- **Base URL**: `https://flotillas.tudominio.com/api/v1`
|
||||
- **Autenticacion**: JWT Bearer Token
|
||||
- **Formato**: JSON
|
||||
- **Documentacion interactiva**: `https://flotillas.tudominio.com/api/docs`
|
||||
|
||||
## Autenticacion
|
||||
|
||||
### Login
|
||||
|
||||
```http
|
||||
POST /auth/login
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"email": "admin@ejemplo.com",
|
||||
"password": "tu_password"
|
||||
}
|
||||
```
|
||||
|
||||
**Respuesta**:
|
||||
```json
|
||||
{
|
||||
"access_token": "eyJ...",
|
||||
"refresh_token": "eyJ...",
|
||||
"token_type": "bearer",
|
||||
"expires_in": 86400
|
||||
}
|
||||
```
|
||||
|
||||
### Refresh Token
|
||||
|
||||
```http
|
||||
POST /auth/refresh
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"refresh_token": "eyJ..."
|
||||
}
|
||||
```
|
||||
|
||||
### Usar Token
|
||||
|
||||
Incluir en todas las peticiones:
|
||||
```http
|
||||
Authorization: Bearer eyJ...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Vehiculos
|
||||
|
||||
### Listar Vehiculos
|
||||
|
||||
```http
|
||||
GET /vehiculos
|
||||
```
|
||||
|
||||
**Parametros query**:
|
||||
- `activo`: boolean - Filtrar por activos
|
||||
- `grupo_id`: integer - Filtrar por grupo
|
||||
- `search`: string - Buscar por nombre/placa
|
||||
- `page`: integer - Pagina (default: 1)
|
||||
- `per_page`: integer - Items por pagina (default: 20)
|
||||
|
||||
**Respuesta**:
|
||||
```json
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"id": 1,
|
||||
"nombre": "Camion-01",
|
||||
"placa": "ABC-123",
|
||||
"marca": "Kenworth",
|
||||
"modelo": "T680",
|
||||
"ano": 2021,
|
||||
"tipo": "camion",
|
||||
"conductor": {
|
||||
"id": 1,
|
||||
"nombre": "Juan Perez"
|
||||
},
|
||||
"grupo": {
|
||||
"id": 1,
|
||||
"nombre": "Ruta Norte"
|
||||
},
|
||||
"estado": "en_ruta",
|
||||
"ultima_ubicacion": {
|
||||
"lat": 19.4326,
|
||||
"lng": -99.1332,
|
||||
"velocidad": 45,
|
||||
"tiempo": "2026-01-21T10:30:00Z"
|
||||
}
|
||||
}
|
||||
],
|
||||
"total": 12,
|
||||
"page": 1,
|
||||
"per_page": 20
|
||||
}
|
||||
```
|
||||
|
||||
### Obtener Vehiculo
|
||||
|
||||
```http
|
||||
GET /vehiculos/{id}
|
||||
```
|
||||
|
||||
### Crear Vehiculo
|
||||
|
||||
```http
|
||||
POST /vehiculos
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"nombre": "Camion-02",
|
||||
"placa": "DEF-456",
|
||||
"marca": "Freightliner",
|
||||
"modelo": "Cascadia",
|
||||
"ano": 2022,
|
||||
"tipo": "camion",
|
||||
"color": "Blanco",
|
||||
"capacidad_carga": 20000,
|
||||
"capacidad_combustible": 400,
|
||||
"grupo_id": 1,
|
||||
"conductor_id": 2
|
||||
}
|
||||
```
|
||||
|
||||
### Actualizar Vehiculo
|
||||
|
||||
```http
|
||||
PUT /vehiculos/{id}
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"nombre": "Camion-02 Actualizado",
|
||||
"conductor_id": 3
|
||||
}
|
||||
```
|
||||
|
||||
### Eliminar Vehiculo
|
||||
|
||||
```http
|
||||
DELETE /vehiculos/{id}
|
||||
```
|
||||
|
||||
### Obtener Ubicacion Actual
|
||||
|
||||
```http
|
||||
GET /vehiculos/{id}/ubicacion
|
||||
```
|
||||
|
||||
**Respuesta**:
|
||||
```json
|
||||
{
|
||||
"vehiculo_id": 1,
|
||||
"lat": 19.4326,
|
||||
"lng": -99.1332,
|
||||
"velocidad": 45,
|
||||
"rumbo": 180,
|
||||
"altitud": 2240,
|
||||
"motor_encendido": true,
|
||||
"bateria": 85,
|
||||
"combustible": 72,
|
||||
"tiempo": "2026-01-21T10:30:00Z",
|
||||
"direccion": "Av. Insurgentes Sur 1234, CDMX"
|
||||
}
|
||||
```
|
||||
|
||||
### Obtener Historial de Ubicaciones
|
||||
|
||||
```http
|
||||
GET /vehiculos/{id}/historial
|
||||
```
|
||||
|
||||
**Parametros query**:
|
||||
- `desde`: datetime - Fecha inicio (ISO 8601)
|
||||
- `hasta`: datetime - Fecha fin
|
||||
- `intervalo`: integer - Segundos entre puntos (para reducir datos)
|
||||
|
||||
---
|
||||
|
||||
## Conductores
|
||||
|
||||
### Listar Conductores
|
||||
|
||||
```http
|
||||
GET /conductores
|
||||
```
|
||||
|
||||
### Crear Conductor
|
||||
|
||||
```http
|
||||
POST /conductores
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"nombre": "Maria",
|
||||
"apellido": "Garcia",
|
||||
"telefono": "+525512345678",
|
||||
"email": "maria@ejemplo.com",
|
||||
"licencia_numero": "LIC-123456",
|
||||
"licencia_tipo": "C",
|
||||
"licencia_vencimiento": "2027-06-15"
|
||||
}
|
||||
```
|
||||
|
||||
### Generar Codigo de Acceso
|
||||
|
||||
```http
|
||||
POST /conductores/{id}/generar-codigo
|
||||
```
|
||||
|
||||
**Respuesta**:
|
||||
```json
|
||||
{
|
||||
"codigo": "123456",
|
||||
"expira": "2026-01-22T10:30:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Obtener Estadisticas
|
||||
|
||||
```http
|
||||
GET /conductores/{id}/estadisticas
|
||||
```
|
||||
|
||||
**Parametros query**:
|
||||
- `periodo`: string - "hoy", "semana", "mes", "ano"
|
||||
|
||||
---
|
||||
|
||||
## Ubicaciones
|
||||
|
||||
### Enviar Ubicacion (desde app/dispositivo)
|
||||
|
||||
```http
|
||||
POST /ubicaciones
|
||||
X-Device-ID: device_123
|
||||
X-API-Key: api_key_xxx
|
||||
|
||||
{
|
||||
"lat": 19.4326,
|
||||
"lng": -99.1332,
|
||||
"velocidad": 45,
|
||||
"rumbo": 180,
|
||||
"altitud": 2240,
|
||||
"precision": 10,
|
||||
"bateria": 85
|
||||
}
|
||||
```
|
||||
|
||||
### Enviar Batch de Ubicaciones
|
||||
|
||||
```http
|
||||
POST /ubicaciones/batch
|
||||
X-Device-ID: device_123
|
||||
X-API-Key: api_key_xxx
|
||||
|
||||
{
|
||||
"ubicaciones": [
|
||||
{
|
||||
"lat": 19.4326,
|
||||
"lng": -99.1332,
|
||||
"velocidad": 45,
|
||||
"tiempo": "2026-01-21T10:30:00Z"
|
||||
},
|
||||
{
|
||||
"lat": 19.4327,
|
||||
"lng": -99.1333,
|
||||
"velocidad": 47,
|
||||
"tiempo": "2026-01-21T10:30:10Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Viajes
|
||||
|
||||
### Listar Viajes
|
||||
|
||||
```http
|
||||
GET /viajes
|
||||
```
|
||||
|
||||
**Parametros query**:
|
||||
- `vehiculo_id`: integer
|
||||
- `conductor_id`: integer
|
||||
- `desde`: datetime
|
||||
- `hasta`: datetime
|
||||
- `estado`: string - "en_curso", "completado"
|
||||
|
||||
### Obtener Viaje
|
||||
|
||||
```http
|
||||
GET /viajes/{id}
|
||||
```
|
||||
|
||||
**Respuesta**:
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"vehiculo_id": 1,
|
||||
"conductor_id": 1,
|
||||
"inicio_tiempo": "2026-01-21T06:30:00Z",
|
||||
"fin_tiempo": "2026-01-21T11:45:00Z",
|
||||
"inicio_lat": 19.4326,
|
||||
"inicio_lng": -99.1332,
|
||||
"inicio_direccion": "Base Central",
|
||||
"fin_lat": 19.5000,
|
||||
"fin_lng": -99.2000,
|
||||
"fin_direccion": "Cliente Norte",
|
||||
"distancia_km": 89.3,
|
||||
"duracion_minutos": 315,
|
||||
"velocidad_promedio": 48,
|
||||
"velocidad_maxima": 82,
|
||||
"paradas": 3
|
||||
}
|
||||
```
|
||||
|
||||
### Obtener Datos para Replay
|
||||
|
||||
```http
|
||||
GET /viajes/{id}/replay
|
||||
```
|
||||
|
||||
**Respuesta**:
|
||||
```json
|
||||
{
|
||||
"viaje_id": 1,
|
||||
"puntos": [
|
||||
{
|
||||
"lat": 19.4326,
|
||||
"lng": -99.1332,
|
||||
"velocidad": 0,
|
||||
"tiempo": "2026-01-21T06:30:00Z"
|
||||
},
|
||||
{
|
||||
"lat": 19.4330,
|
||||
"lng": -99.1335,
|
||||
"velocidad": 25,
|
||||
"tiempo": "2026-01-21T06:30:10Z"
|
||||
}
|
||||
],
|
||||
"eventos": [
|
||||
{
|
||||
"tipo": "alerta",
|
||||
"tiempo": "2026-01-21T08:45:00Z",
|
||||
"descripcion": "Exceso de velocidad: 82 km/h"
|
||||
}
|
||||
],
|
||||
"paradas": [
|
||||
{
|
||||
"inicio": "2026-01-21T07:15:00Z",
|
||||
"fin": "2026-01-21T07:30:00Z",
|
||||
"lat": 19.4500,
|
||||
"lng": -99.1500,
|
||||
"tipo": "programada"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Alertas
|
||||
|
||||
### Listar Alertas
|
||||
|
||||
```http
|
||||
GET /alertas
|
||||
```
|
||||
|
||||
**Parametros query**:
|
||||
- `atendida`: boolean
|
||||
- `severidad`: string - "info", "media", "critica"
|
||||
- `tipo`: string
|
||||
- `vehiculo_id`: integer
|
||||
- `desde`: datetime
|
||||
- `hasta`: datetime
|
||||
|
||||
### Obtener Alertas Pendientes
|
||||
|
||||
```http
|
||||
GET /alertas/pendientes
|
||||
```
|
||||
|
||||
### Marcar como Atendida
|
||||
|
||||
```http
|
||||
PUT /alertas/{id}/atender
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"notas": "Contactado conductor, todo OK"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Geocercas
|
||||
|
||||
### Listar Geocercas
|
||||
|
||||
```http
|
||||
GET /geocercas
|
||||
```
|
||||
|
||||
### Crear Geocerca
|
||||
|
||||
```http
|
||||
POST /geocercas
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"nombre": "Zona Norte",
|
||||
"tipo": "poligono",
|
||||
"coordenadas": [
|
||||
{"lat": 19.5, "lng": -99.2},
|
||||
{"lat": 19.5, "lng": -99.1},
|
||||
{"lat": 19.4, "lng": -99.1},
|
||||
{"lat": 19.4, "lng": -99.2}
|
||||
],
|
||||
"color": "#22c55e",
|
||||
"alerta_entrada": false,
|
||||
"alerta_salida": true,
|
||||
"velocidad_maxima": 60,
|
||||
"vehiculos": [1, 2, 3]
|
||||
}
|
||||
```
|
||||
|
||||
### Crear Geocerca Circular
|
||||
|
||||
```http
|
||||
POST /geocercas
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"nombre": "Cliente ABC",
|
||||
"tipo": "circulo",
|
||||
"coordenadas": [{"lat": 19.4326, "lng": -99.1332}],
|
||||
"radio_metros": 500,
|
||||
"alerta_entrada": true,
|
||||
"alerta_salida": true
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Video
|
||||
|
||||
### Listar Camaras
|
||||
|
||||
```http
|
||||
GET /video/camaras
|
||||
```
|
||||
|
||||
### Obtener URL de Stream
|
||||
|
||||
```http
|
||||
GET /video/camaras/{id}/stream
|
||||
```
|
||||
|
||||
**Respuesta**:
|
||||
```json
|
||||
{
|
||||
"camara_id": 1,
|
||||
"webrtc_url": "http://servidor:8889/cam_1_frontal",
|
||||
"hls_url": "http://servidor:8888/cam_1_frontal/index.m3u8",
|
||||
"estado": "online"
|
||||
}
|
||||
```
|
||||
|
||||
### Listar Grabaciones
|
||||
|
||||
```http
|
||||
GET /video/grabaciones
|
||||
```
|
||||
|
||||
**Parametros query**:
|
||||
- `camara_id`: integer
|
||||
- `vehiculo_id`: integer
|
||||
- `tipo`: string - "continua", "evento", "manual"
|
||||
- `desde`: datetime
|
||||
- `hasta`: datetime
|
||||
|
||||
### Solicitar Video Historico
|
||||
|
||||
```http
|
||||
POST /video/grabaciones/solicitar
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"camara_id": 1,
|
||||
"desde": "2026-01-21T10:00:00Z",
|
||||
"hasta": "2026-01-21T10:30:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Combustible
|
||||
|
||||
### Registrar Carga
|
||||
|
||||
```http
|
||||
POST /combustible
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"vehiculo_id": 1,
|
||||
"litros": 45.5,
|
||||
"precio_litro": 23.50,
|
||||
"odometro": 45678,
|
||||
"estacion": "Pemex Centro"
|
||||
}
|
||||
```
|
||||
|
||||
### Obtener Consumo
|
||||
|
||||
```http
|
||||
GET /combustible/consumo
|
||||
```
|
||||
|
||||
**Parametros query**:
|
||||
- `vehiculo_id`: integer
|
||||
- `desde`: datetime
|
||||
- `hasta`: datetime
|
||||
|
||||
---
|
||||
|
||||
## Mantenimiento
|
||||
|
||||
### Listar Mantenimientos
|
||||
|
||||
```http
|
||||
GET /mantenimiento
|
||||
```
|
||||
|
||||
### Obtener Proximos Vencimientos
|
||||
|
||||
```http
|
||||
GET /mantenimiento/pendientes
|
||||
```
|
||||
|
||||
### Programar Mantenimiento
|
||||
|
||||
```http
|
||||
POST /mantenimiento
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"vehiculo_id": 1,
|
||||
"tipo_mantenimiento_id": 1,
|
||||
"fecha_programada": "2026-02-01",
|
||||
"odometro_programado": 50000,
|
||||
"notas": "Cambio de aceite y filtros"
|
||||
}
|
||||
```
|
||||
|
||||
### Completar Mantenimiento
|
||||
|
||||
```http
|
||||
PUT /mantenimiento/{id}/completar
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"fecha_realizada": "2026-02-01",
|
||||
"odometro_realizado": 49850,
|
||||
"costo": 1500.00,
|
||||
"proveedor": "Taller AutoServ",
|
||||
"notas": "Se cambio aceite sintetico"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Reportes
|
||||
|
||||
### Obtener Datos de Dashboard
|
||||
|
||||
```http
|
||||
GET /reportes/dashboard
|
||||
```
|
||||
|
||||
**Respuesta**:
|
||||
```json
|
||||
{
|
||||
"vehiculos": {
|
||||
"total": 12,
|
||||
"en_ruta": 8,
|
||||
"detenidos": 2,
|
||||
"offline": 1,
|
||||
"con_alerta": 1
|
||||
},
|
||||
"hoy": {
|
||||
"km_recorridos": 847,
|
||||
"viajes_completados": 8,
|
||||
"alertas": 5,
|
||||
"combustible_cargado": 250
|
||||
},
|
||||
"tendencias": {
|
||||
"km_vs_ayer": 12,
|
||||
"alertas_vs_ayer": -5
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Generar Reporte
|
||||
|
||||
```http
|
||||
POST /reportes/generar
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"tipo": "recorridos",
|
||||
"desde": "2026-01-01",
|
||||
"hasta": "2026-01-21",
|
||||
"vehiculos": [1, 2, 3],
|
||||
"formato": "pdf"
|
||||
}
|
||||
```
|
||||
|
||||
**Respuesta**:
|
||||
```json
|
||||
{
|
||||
"reporte_id": 1,
|
||||
"estado": "procesando",
|
||||
"url": null
|
||||
}
|
||||
```
|
||||
|
||||
### Descargar Reporte
|
||||
|
||||
```http
|
||||
GET /reportes/{id}/descargar
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## WebSocket
|
||||
|
||||
### Conexion
|
||||
|
||||
```javascript
|
||||
const ws = new WebSocket('wss://flotillas.tudominio.com/ws/v1/ubicaciones');
|
||||
|
||||
ws.onopen = () => {
|
||||
// Autenticar
|
||||
ws.send(JSON.stringify({
|
||||
type: 'auth',
|
||||
token: 'eyJ...'
|
||||
}));
|
||||
};
|
||||
|
||||
ws.onmessage = (event) => {
|
||||
const data = JSON.parse(event.data);
|
||||
console.log(data);
|
||||
};
|
||||
```
|
||||
|
||||
### Eventos de Ubicacion
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "vehiculo_ubicacion",
|
||||
"vehiculo_id": 1,
|
||||
"lat": 19.4326,
|
||||
"lng": -99.1332,
|
||||
"velocidad": 45,
|
||||
"rumbo": 180,
|
||||
"tiempo": "2026-01-21T10:30:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Eventos de Alerta
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "nueva_alerta",
|
||||
"alerta": {
|
||||
"id": 123,
|
||||
"vehiculo_id": 1,
|
||||
"tipo": "exceso_velocidad",
|
||||
"severidad": "media",
|
||||
"mensaje": "Exceso de velocidad: 87 km/h",
|
||||
"tiempo": "2026-01-21T10:30:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Codigos de Error
|
||||
|
||||
| Codigo | Descripcion |
|
||||
|--------|-------------|
|
||||
| 400 | Bad Request - Datos invalidos |
|
||||
| 401 | Unauthorized - Token invalido o expirado |
|
||||
| 403 | Forbidden - Sin permisos |
|
||||
| 404 | Not Found - Recurso no existe |
|
||||
| 422 | Validation Error - Error de validacion |
|
||||
| 429 | Too Many Requests - Rate limit excedido |
|
||||
| 500 | Internal Server Error |
|
||||
|
||||
**Formato de error**:
|
||||
```json
|
||||
{
|
||||
"detail": "Mensaje de error",
|
||||
"code": "ERROR_CODE",
|
||||
"errors": [
|
||||
{
|
||||
"field": "email",
|
||||
"message": "Email invalido"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Rate Limits
|
||||
|
||||
| Endpoint | Limite |
|
||||
|----------|--------|
|
||||
| General | 100 req/min |
|
||||
| Auth | 5 req/min |
|
||||
| Ubicaciones | 60 req/min |
|
||||
| Video Stream | 10 req/min |
|
||||
|
||||
Headers de respuesta:
|
||||
```
|
||||
X-RateLimit-Limit: 100
|
||||
X-RateLimit-Remaining: 95
|
||||
X-RateLimit-Reset: 1642771200
|
||||
```
|
||||
Reference in New Issue
Block a user