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