Table of Contents
- Endpoints REST
- Base URL
- Health Check
- ETA (Módulo B)
- Alertas (Módulo B + A)
- Admin — Simulador (Solo Módulo B)
- POST /admin/route/{route_id}/start
- POST /admin/route/{route_id}/stop
- POST /admin/route/{route_id}/delay
- GET /admin/route/{route_id}/status
- Auth (Módulo A — endpoints pendientes)
- Preferencias de notificaciones (Módulo A)
- Swagger UI (Documentación interactiva)
- Ejemplos de uso desde Flutter
- Siguiente paso
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Endpoints REST
Documentación completa de todos los endpoints HTTP del backend.
Base URL
http://localhost:8000
En producción o desde dispositivo físico, reemplaza con la IP/dominio correspondiente.
Health Check
GET /health
Verificar que el servidor está funcionando.
Request:
curl http://localhost:8000/health
Response:
{
"status": "ok"
}
Status codes:
200— Servidor OK
ETA (Módulo B)
GET /eta/{address_id}
Obtener el ETA y ventana horaria para un domicilio.
Request:
curl http://localhost:8000/eta/1
Response:
{
"address_id": 1,
"route_id": "RUTA-01",
"status": "EN_RUTA",
"eta_minutos": 22,
"ventana": {
"inicio": "7:20 pm",
"fin": "7:35 pm"
},
"mensaje": "El camión está en camino. Llegada estimada: 7:20 pm – 7:35 pm."
}
Campos:
address_id— ID del domicilio consultadoroute_id— Ruta asignada al domiciliostatus— Estado del camión:EN_RUTA,AVERIADA,RETRASADAeta_minutos— Minutos estimados hasta llegarventana— Horario de llegada (inicio y fin)mensaje— Texto para mostrar al usuario
Status codes:
200— ETA calculado correctamente404— Domicilio no encontrado o sin ruta asignada500— Error interno
Alertas (Módulo B + A)
POST /alerts/breakdown
Reportar una avería del camión. Detiene el simulador y notifica a todos los usuarios de la ruta.
Request:
curl -X POST http://localhost:8000/alerts/breakdown \
-H "Content-Type: application/json" \
-d '{
"route_id": "RUTA-01"
}'
Request body:
{
"route_id": "RUTA-01"
}
Response:
{
"message": "Alerta de avería enviada",
"route_id": "RUTA-01",
"notified_users": 3
}
Status codes:
200— Alerta enviada404— Ruta no encontrada400— Request body inválido
Admin — Simulador (Solo Módulo B)
POST /admin/route/{route_id}/start
Arrancar el simulador para una ruta.
Request:
curl -X POST http://localhost:8000/admin/route/RUTA-01/start
Response:
{
"message": "Ruta RUTA-01 iniciada",
"route_id": "RUTA-01",
"status": "EN_RUTA"
}
Status codes:
200— Simulador arrancado404— Ruta no encontrada409— Simulador ya está corriendo
POST /admin/route/{route_id}/stop
Detener el simulador.
Request:
curl -X POST http://localhost:8000/admin/route/RUTA-01/stop
Response:
{
"message": "Ruta RUTA-01 detenida",
"route_id": "RUTA-01"
}
POST /admin/route/{route_id}/delay
Forzar un retraso en la ruta (para probar notificaciones).
Request:
curl -X POST http://localhost:8000/admin/route/RUTA-01/delay \
-H "Content-Type: application/json" \
-d '{
"delay_minutes": 15
}'
Request body:
{
"delay_minutes": 15
}
Response:
{
"message": "Retraso aplicado a RUTA-01",
"route_id": "RUTA-01",
"delay_minutes": 15,
"new_status": "RETRASADA"
}
GET /admin/route/{route_id}/status
Obtener el estado actual del camión (debug).
Request:
curl http://localhost:8000/admin/route/RUTA-01/status
Response:
{
"route_id": "RUTA-01",
"current_position_id": 3,
"current_position_name": "Parque Xochipilli",
"status": "EN_RUTA",
"last_update": "2026-05-22T19:35:12.123456"
}
Auth (Módulo A — endpoints pendientes)
POST /register
Crear una cuenta de usuario.
Request:
{
"email": "usuario@ejemplo.com",
"phone": "+52 1234567890",
"password": "securepassword123",
"fcm_token": "firebase-device-token" // opcional
}
Response:
{
"user_id": 1,
"email": "usuario@ejemplo.com",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
POST /login
Iniciar sesión.
Request:
{
"email": "usuario@ejemplo.com",
"password": "securepassword123"
}
Response:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user_id": 1,
"email": "usuario@ejemplo.com"
}
POST /addresses
Dar de alta un domicilio y asignarle una ruta.
Headers:
Authorization: Bearer <JWT_TOKEN>
Request:
{
"alias": "Mi casa",
"lat": 20.5200,
"lng": -100.8157
}
Response:
{
"address_id": 1,
"alias": "Mi casa",
"lat": 20.5200,
"lng": -100.8157,
"route_id": "RUTA-01",
"created_at": "2026-05-22T19:00:00"
}
Status codes:
201— Domicilio creado400— Coordenadas fuera de zona de servicio401— Token inválido o expirado
GET /addresses
Listar todos los domicilios del usuario autenticado.
Headers:
Authorization: Bearer <JWT_TOKEN>
Response:
{
"addresses": [
{
"address_id": 1,
"alias": "Mi casa",
"lat": 20.5200,
"lng": -100.8157,
"route_id": "RUTA-01"
},
{
"address_id": 2,
"alias": "Trabajo",
"lat": 20.5300,
"lng": -100.8200,
"route_id": "RUTA-02"
}
]
}
Preferencias de notificaciones (Módulo A)
GET /preferences
Obtener preferencias de notificación del usuario.
Headers:
Authorization: Bearer <JWT_TOKEN>
Response:
{
"user_id": 1,
"notify_proximity": true,
"notify_breakdown": true,
"notify_delay": true,
"notify_route_start": false
}
PUT /preferences
Actualizar preferencias.
Headers:
Authorization: Bearer <JWT_TOKEN>
Request:
{
"notify_proximity": true,
"notify_breakdown": false,
"notify_delay": true,
"notify_route_start": true
}
Response:
{
"message": "Preferencias actualizadas",
"preferences": {
"notify_proximity": true,
"notify_breakdown": false,
"notify_delay": true,
"notify_route_start": true
}
}
Swagger UI (Documentación interactiva)
Abre en el navegador:
http://localhost:8000/docs
Puedes probar todos los endpoints directamente desde la interfaz.
Ejemplos de uso desde Flutter
Obtener ETA
// lib/features/eta/data/datasources/eta_remote_datasource.dart
import 'package:dio/dio.dart';
class ETARemoteDatasource {
final Dio _dio;
ETARemoteDatasource(this._dio);
Future<Map<String, dynamic>> getETA(int addressId) async {
try {
final response = await _dio.get('/eta/$addressId');
return response.data;
} on DioException catch (e) {
if (e.response?.statusCode == 404) {
throw Exception('Domicilio no encontrado');
}
throw Exception('Error al obtener ETA: ${e.message}');
}
}
}
Reportar avería
Future<void> reportBreakdown(String routeId) async {
try {
await _dio.post(
'/alerts/breakdown',
data: {'route_id': routeId},
);
} catch (e) {
throw Exception('Error al reportar avería');
}
}
Login con JWT
Future<String> login(String email, String password) async {
final response = await _dio.post(
'/login',
data: {
'email': email,
'password': password,
},
);
return response.data['token'];
}
// Guardar token y usarlo en requests siguientes
final token = await login('user@example.com', 'password');
_dio.options.headers['Authorization'] = 'Bearer $token';
Siguiente paso
- WebSocket protocol — recibir notificaciones en tiempo real
- Modelos de datos — schemas JSON completos
- Integración entre módulos — cómo conectar A, B, C, D