7.1 KiB
API REST — Referencia
Base URL:
http://10.82.68.125:8000/api/v1· Docs interactivos:http://localhost:8000/docs
Todos los endpoints (excepto /auth/*) requieren header:
Authorization: Bearer <JWT_TOKEN>
🔐 Autenticación
POST /auth/register
Crea un usuario nuevo (rol CIUDADANO por defecto).
Request:
{ "full_name": "Juan Pérez", "email": "juan@example.com", "password": "secret123" }
Response 201:
{ "access_token": "eyJ...", "token_type": "bearer", "role": "CIUDADANO" }
POST /auth/login
Request:
{ "email": "demo@celaya.gob.mx", "password": "Celaya2026" }
Response 200:
{ "access_token": "eyJ...", "token_type": "bearer", "role": "CIUDADANO" }
Response 401: {"detail": "Credenciales inválidas"}
POST /auth/oauth
Login/registro vía OAuth (Google, Facebook, Apple).
{ "provider": "google", "oauth_id": "abc123", "email": "juan@gmail.com", "full_name": "Juan", "push_token": "..." }
GET /me
Devuelve el usuario actual.
Response: { "id": 1, "full_name": "...", "email": "...", "role": "CIUDADANO" }
🏠 Domicilios (/addresses)
GET /addresses/
Lista tus domicilios.
Response: [{"id":1, "label":"Casa", "street":"...", "lat":20.5, "lng":-100.8, "route_id":"RUTA-01", "is_default":true}, ...]
POST /addresses/
Crea un domicilio. Si pasas lat/lng, se asigna ruta automáticamente.
{ "label": "Casa", "street": "Hidalgo 245", "colony": "Centro", "lat": 20.5215, "lng": -100.8142, "is_default": true }
PATCH /addresses/{id}
Actualiza un domicilio. Solo campos modificados.
{ "is_default": true }
DELETE /addresses/{id} → 204
⏰ ETA (/eta)
GET /eta/address/{id} — núcleo del sistema
Privacy-by-design: nunca devuelve coordenadas del camión.
Response 200:
{
"status": "EN_CAMINO",
"message": "El camión llegará a tu zona entre las 7:20 y 7:35",
"eta_minutes": 12,
"window_start": "07:20",
"window_end": "07:35",
"progress": 45.2,
"route_name": "Zona Centro - Las Arboledas",
"passes_today": true
}
Estados posibles:
PROGRAMADO— la ruta aún no empieza hoyEN_CAMINO— el camión va en rutaLLEGANDO— faltan ≤10 minutosPASO— ya pasó por la zonaNO_SERVICIO— no aplica hoy
GET /eta/schedule/{address_id}
Devuelve días y horario aproximado.
{ "route_id":"RUTA-01", "route_name":"Zona Centro - Las Arboledas",
"days_of_week":["Lunes","Miércoles","Viernes"], "approximate_time":"06:00 - 07:40",
"truck_id": 101 }
POST /eta/rate
Califica el servicio.
{ "address_id": 1, "rating": 5, "comment": "Excelente puntualidad" }
📋 Reportes ciudadanos (/reports)
POST /reports/
Crea un reporte con folio único.
{ "address_id": 1, "report_type": "NO_PASO", "description": "El camión no pasó hoy" }
Response 201:
{ "id":5, "folio":"MRL-20260523-F6EC92", "status":"PENDIENTE",
"report_type":"NO_PASO", "description":"...", "created_at":"...", "address_label":"Casa" }
Tipos: NO_PASO · RETRASO · ACUMULACION · OTRO
GET /reports/
Tus reportes (no los de otros usuarios).
GET /reports/{id}
Detalle con la etiqueta del domicilio.
👮 Staff (/staff) — solo EMPLEADO o ADMIN
GET /staff/dashboard
Métricas motivacionales del empleado.
{
"employee_name": "Carlos Hernández",
"streak_days": 19,
"punctuality_pct": 88,
"bonus_accumulated_mxn": 950,
"next_milestone_days": 11,
"next_milestone_mxn": 500,
"reports_generated": 5,
"motivation_quote": "Tu puntualidad permite que miles de familias planifiquen su día",
"rating_label": "BUENO"
}
GET /staff/schedule
Horario preestablecido con descansos.
GET /staff/categories
Las 8 categorías disponibles para reportes operativos.
POST /staff/operational-reports
Crea un reporte operativo (folio OP-...).
{ "category": "FALLA_MECANICA", "severity": "MEDIA", "description": "Frenos haciendo ruido", "route_id": "RUTA-01", "truck_id": 12 }
Categorías: NO_ARRANQUE · FALLA_MECANICA · ACCIDENTE · OBSTACULO · TRAFICO · COMBUSTIBLE · CLIMA · OTRO
GET /staff/operational-reports
Lista tus reportes operativos.
🛡️ Admin (/admin) — solo ADMIN
GET /admin/stats
KPIs globales del sistema.
{
"total_ciudadanos": 185, "total_domicilios": 302, "total_reportes": 280,
"reportes_24h": 8, "promedio_calificacion": 4.07,
"reportes_por_estado": {"PENDIENTE": 84, "EN_PROCESO": 56, "RESUELTO": 112, "CERRADO": 28},
"reportes_por_tipo": {"NO_PASO": 98, "RETRASO": 84, ...},
"rutas_activas": 15
}
GET /admin/reports?status=PENDIENTE&report_type=NO_PASO
Lista TODOS los reportes ciudadanos (no solo los tuyos). Filtros opcionales.
PATCH /admin/reports/{id}/status?status=EN_PROCESO
Cambia el estado de un reporte. Estados válidos: PENDIENTE | EN_PROCESO | RESUELTO | CERRADO.
GET /admin/routes
Lista todas las rutas con su estado actual.
GET /admin/users?role=CIUDADANO
Lista usuarios con conteos de domicilios y reportes.
PATCH /admin/users/{id}/role?role=EMPLEADO
Cambia el rol de un usuario. Roles: CIUDADANO | EMPLEADO | ADMIN.
GET /admin/feedback
Últimas 50 calificaciones del servicio.
🔒 Códigos de respuesta
| Código | Significado |
|---|---|
| 200 | OK |
| 201 | Creado |
| 204 | Sin contenido (DELETE exitoso) |
| 400 | Bad request (validación falló) |
| 401 | No autenticado / token inválido |
| 403 | Sin permisos para este recurso |
| 404 | Recurso no encontrado o no te pertenece |
| 500 | Error del servidor |
🧪 Ejemplos con curl
Flujo completo: ciudadano → reporte → admin lo resuelve
BASE=http://10.82.68.125:8000/api/v1
# 1. Login ciudadano
CTOKEN=$(curl -s -X POST $BASE/auth/login -H "Content-Type: application/json" \
-d '{"email":"demo@celaya.gob.mx","password":"Celaya2026"}' | jq -r .access_token)
# 2. Listar domicilios
curl -s $BASE/addresses/ -H "Authorization: Bearer $CTOKEN" | jq
# 3. Ver ETA del domicilio 1
curl -s $BASE/eta/address/1 -H "Authorization: Bearer $CTOKEN" | jq
# 4. Crear reporte
REPORT=$(curl -s -X POST $BASE/reports/ -H "Authorization: Bearer $CTOKEN" \
-H "Content-Type: application/json" \
-d '{"address_id":1,"report_type":"NO_PASO","description":"Hoy no pasó"}')
echo $REPORT | jq
REPORT_ID=$(echo $REPORT | jq -r .id)
# 5. Login admin
ATOKEN=$(curl -s -X POST $BASE/auth/login -H "Content-Type: application/json" \
-d '{"email":"admin@celaya.gob.mx","password":"Admin2026"}' | jq -r .access_token)
# 6. Admin ve TODOS los reportes
curl -s $BASE/admin/reports -H "Authorization: Bearer $ATOKEN" | jq '. | length'
# 7. Admin cambia el estado a EN_PROCESO
curl -s -X PATCH "$BASE/admin/reports/$REPORT_ID/status?status=EN_PROCESO" \
-H "Authorization: Bearer $ATOKEN" | jq
# 8. El ciudadano vuelve a consultar y ve el cambio
curl -s $BASE/reports/$REPORT_ID -H "Authorization: Bearer $CTOKEN" | jq .status
# → "EN_PROCESO" ✓