1
01-endpoints.md
hack_23031391_8ff9d8 edited this page 2026-05-23 02:36:32 +00:00
This file contains ambiguous Unicode characters

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 consultado
  • route_id — Ruta asignada al domicilio
  • status — Estado del camión: EN_RUTA, AVERIADA, RETRASADA
  • eta_minutos — Minutos estimados hasta llegar
  • ventana — Horario de llegada (inicio y fin)
  • mensaje — Texto para mostrar al usuario

Status codes:

  • 200 — ETA calculado correctamente
  • 404 — Domicilio no encontrado o sin ruta asignada
  • 500 — 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 enviada
  • 404 — Ruta no encontrada
  • 400 — 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 arrancado
  • 404 — Ruta no encontrada
  • 409 — 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 creado
  • 400 — Coordenadas fuera de zona de servicio
  • 401 — 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