Añadir 01-backend.md
356
01-backend.md.-.md
Normal file
356
01-backend.md.-.md
Normal file
@@ -0,0 +1,356 @@
|
|||||||
|
# Configurar el Backend (Módulo B)
|
||||||
|
|
||||||
|
Guía paso a paso para levantar el servidor FastAPI.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Clonar o descargar el módulo
|
||||||
|
|
||||||
|
Si el backend ya está en el repo:
|
||||||
|
```bash
|
||||||
|
cd hackathon-acapulquitos-boys
|
||||||
|
git pull origin dev
|
||||||
|
cd basura_backend
|
||||||
|
```
|
||||||
|
|
||||||
|
Si descargaste el ZIP del módulo B:
|
||||||
|
```bash
|
||||||
|
unzip basura_backend.zip
|
||||||
|
cd basura_backend
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Crear entorno virtual (recomendado)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Crear venv
|
||||||
|
python -m venv venv
|
||||||
|
|
||||||
|
# Activar
|
||||||
|
# Linux/macOS:
|
||||||
|
source venv/bin/activate
|
||||||
|
|
||||||
|
# Windows:
|
||||||
|
venv\Scripts\activate
|
||||||
|
|
||||||
|
# Tu terminal ahora debe mostrar (venv) al inicio
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Instalar dependencias
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
Esto instala:
|
||||||
|
- `fastapi` — framework web
|
||||||
|
- `uvicorn` — servidor ASGI
|
||||||
|
- `websockets` — soporte WebSocket
|
||||||
|
- `apscheduler` — scheduler para el simulador
|
||||||
|
- `python-jose` — JWT (para cuando Persona A integre auth)
|
||||||
|
- `passlib` — hashing de passwords
|
||||||
|
- `pydantic` — validación de datos
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Verificar la estructura
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tree -L 3 app/
|
||||||
|
```
|
||||||
|
|
||||||
|
Deberías ver:
|
||||||
|
```
|
||||||
|
app/
|
||||||
|
├── core/
|
||||||
|
│ └── config.py
|
||||||
|
├── db/
|
||||||
|
│ └── database.py
|
||||||
|
├── domain/
|
||||||
|
│ ├── entities/
|
||||||
|
│ └── interfaces/
|
||||||
|
├── data/
|
||||||
|
│ └── repositories/
|
||||||
|
├── services/
|
||||||
|
│ ├── simulador.py
|
||||||
|
│ └── ws_manager.py
|
||||||
|
├── use_cases/
|
||||||
|
│ └── obtener_eta.py
|
||||||
|
├── api/routes/
|
||||||
|
│ └── eta_router.py
|
||||||
|
└── main.py
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Configurar variables de entorno (opcional)
|
||||||
|
|
||||||
|
Crea un archivo `.env` en la raíz de `basura_backend/`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# .env
|
||||||
|
SIM_TICK_SECONDS=10 # Intervalo del simulador (segundos)
|
||||||
|
SIM_ETA_ALERT_MINUTES=10 # Umbral para notificar proximidad
|
||||||
|
SIM_SPEED_MULTIPLIER=1.0 # Velocidad del simulador (1.0 = normal)
|
||||||
|
|
||||||
|
DATABASE_PATH=./basura.db # Ruta del SQLite
|
||||||
|
HOST=0.0.0.0
|
||||||
|
PORT=8000
|
||||||
|
RELOAD=True # Hot reload en desarrollo
|
||||||
|
```
|
||||||
|
|
||||||
|
Si no creas `.env`, se usan los valores por defecto del código.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Inicializar la base de datos
|
||||||
|
|
||||||
|
El backend **autocrea la BD y el seed** al arrancar por primera vez.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Primera vez — crea basura.db y tablas
|
||||||
|
uvicorn app.main:app --reload
|
||||||
|
```
|
||||||
|
|
||||||
|
Verás en la consola:
|
||||||
|
```
|
||||||
|
INFO: Base de datos inicializada
|
||||||
|
INFO: Seed de demo creado: RUTA-01 con 5 waypoints
|
||||||
|
INFO: Uvicorn running on http://127.0.0.1:8000
|
||||||
|
```
|
||||||
|
|
||||||
|
**La BD se crea con:**
|
||||||
|
- 1 usuario demo
|
||||||
|
- 1 domicilio asignado a RUTA-01
|
||||||
|
- 5 puntos de ruta (waypoints) en Celaya, Guanajuato
|
||||||
|
- 4 templates de notificaciones
|
||||||
|
- Preferencias de notificación por defecto
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Verificar que el servidor funciona
|
||||||
|
|
||||||
|
### Health check
|
||||||
|
```bash
|
||||||
|
curl http://localhost:8000/health
|
||||||
|
# Respuesta: {"status": "ok"}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Documentación interactiva
|
||||||
|
Abre en el navegador:
|
||||||
|
```
|
||||||
|
http://localhost:8000/docs
|
||||||
|
```
|
||||||
|
|
||||||
|
Deberías ver **Swagger UI** con todos los endpoints.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Probar el simulador
|
||||||
|
|
||||||
|
### Arrancar el camión
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:8000/admin/route/RUTA-01/start
|
||||||
|
```
|
||||||
|
|
||||||
|
Respuesta:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "Ruta RUTA-01 iniciada",
|
||||||
|
"route_id": "RUTA-01",
|
||||||
|
"status": "EN_RUTA"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Verificar estado del camión
|
||||||
|
```bash
|
||||||
|
curl http://localhost:8000/admin/route/RUTA-01/status
|
||||||
|
```
|
||||||
|
|
||||||
|
Respuesta:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"route_id": "RUTA-01",
|
||||||
|
"current_position_id": 2,
|
||||||
|
"status": "EN_RUTA",
|
||||||
|
"last_update": "2026-05-22T19:30:00"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
El `current_position_id` incrementa cada 10 segundos (configurable en `.env`).
|
||||||
|
|
||||||
|
### Consultar ETA de un domicilio
|
||||||
|
```bash
|
||||||
|
curl http://localhost:8000/eta/1
|
||||||
|
```
|
||||||
|
|
||||||
|
Respuesta:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"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."
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Probar WebSocket
|
||||||
|
|
||||||
|
### Opción A: Con wscat (línea de comandos)
|
||||||
|
|
||||||
|
Instalar:
|
||||||
|
```bash
|
||||||
|
npm install -g wscat
|
||||||
|
```
|
||||||
|
|
||||||
|
Conectar:
|
||||||
|
```bash
|
||||||
|
wscat -c ws://localhost:8000/ws/1
|
||||||
|
```
|
||||||
|
|
||||||
|
Deberías empezar a recibir eventos cada vez que el ETA cambia:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"tipo": "aproximandose",
|
||||||
|
"address_id": 1,
|
||||||
|
"eta_minutos": 8,
|
||||||
|
"mensaje": "El camión llega en ~8 minutos. Saca tu basura ahora.",
|
||||||
|
"hora_utc": "2026-05-22T19:35:00"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Opción B: Con Postman
|
||||||
|
|
||||||
|
1. Nueva pestaña → selecciona **WebSocket Request**
|
||||||
|
2. URL: `ws://localhost:8000/ws/1`
|
||||||
|
3. Conectar
|
||||||
|
4. Los mensajes aparecen en el panel inferior
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. Probar notificación de avería
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:8000/alerts/breakdown \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"route_id": "RUTA-01"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Si tienes `wscat` conectado, recibes:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"tipo": "falla_mecanica",
|
||||||
|
"address_id": 1,
|
||||||
|
"eta_minutos": null,
|
||||||
|
"mensaje": "El camión de tu zona presenta una falla mecánica. Te avisaremos cuando se resuelva.",
|
||||||
|
"hora_utc": "2026-05-22T19:40:00"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
El simulador se **detiene automáticamente** cuando hay avería.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. Ver la base de datos (opcional)
|
||||||
|
|
||||||
|
### Con DB Browser for SQLite
|
||||||
|
|
||||||
|
1. Descarga [sqlitebrowser.org](https://sqlitebrowser.org/)
|
||||||
|
2. Abre `basura.db`
|
||||||
|
3. Navega por las tablas
|
||||||
|
|
||||||
|
### Con línea de comandos
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sqlite3 basura.db
|
||||||
|
|
||||||
|
# Dentro de sqlite3:
|
||||||
|
.tables # Lista todas las tablas
|
||||||
|
SELECT * FROM rutas; # Ver rutas
|
||||||
|
SELECT * FROM truck_status; # Ver estado del camión
|
||||||
|
SELECT * FROM notificaciones; # Ver log de notificaciones
|
||||||
|
.quit
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 12. Detener el servidor
|
||||||
|
|
||||||
|
En la terminal donde corre `uvicorn`:
|
||||||
|
```
|
||||||
|
Ctrl + C
|
||||||
|
```
|
||||||
|
|
||||||
|
El simulador se detiene automáticamente.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 13. Troubleshooting
|
||||||
|
|
||||||
|
### "Address already in use"
|
||||||
|
El puerto 8000 ya está ocupado.
|
||||||
|
|
||||||
|
**Solución:**
|
||||||
|
```bash
|
||||||
|
# Cambiar puerto
|
||||||
|
uvicorn app.main:app --reload --port 8001
|
||||||
|
|
||||||
|
# O matar el proceso en el puerto
|
||||||
|
# Linux/macOS:
|
||||||
|
lsof -ti:8000 | xargs kill -9
|
||||||
|
|
||||||
|
# Windows:
|
||||||
|
netstat -ano | findstr :8000
|
||||||
|
taskkill /PID <PID> /F
|
||||||
|
```
|
||||||
|
|
||||||
|
### "No module named 'app'"
|
||||||
|
Estás corriendo `uvicorn` desde la carpeta incorrecta.
|
||||||
|
|
||||||
|
**Solución:**
|
||||||
|
```bash
|
||||||
|
# Debes estar en basura_backend/
|
||||||
|
cd basura_backend
|
||||||
|
uvicorn app.main:app --reload
|
||||||
|
```
|
||||||
|
|
||||||
|
### "Table already exists"
|
||||||
|
La BD ya fue creada y el código intenta recrearla.
|
||||||
|
|
||||||
|
**Solución:**
|
||||||
|
```bash
|
||||||
|
# Borrar la BD y dejar que se recree
|
||||||
|
rm basura.db
|
||||||
|
uvicorn app.main:app --reload
|
||||||
|
```
|
||||||
|
|
||||||
|
### WebSocket se desconecta inmediatamente
|
||||||
|
CORS o problema de red.
|
||||||
|
|
||||||
|
**Solución:**
|
||||||
|
Verifica que Flutter esté usando la IP correcta:
|
||||||
|
```dart
|
||||||
|
// Si estás en emulador Android, usa:
|
||||||
|
ws://10.0.2.2:8000/ws/1
|
||||||
|
|
||||||
|
// Si estás en dispositivo físico, usa la IP de tu PC:
|
||||||
|
ws://192.168.x.x:8000/ws/1
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Siguiente paso
|
||||||
|
|
||||||
|
- [Configurar Flutter](02-frontend.md) — integrar los módulos C y D
|
||||||
|
- [Endpoints REST completos](../api/01-endpoints.md)
|
||||||
|
- [WebSocket protocol](../api/02-websocket.md)
|
||||||
Reference in New Issue
Block a user