237 lines
11 KiB
Markdown
237 lines
11 KiB
Markdown
# Mi Ruta Limpia
|
||
|
||
**Sistema de notificación inteligente y privada de recolección de residuos**
|
||
Hackathon LINCEHACK · Gobierno de Celaya · 2026
|
||
|
||
---
|
||
|
||
## Descripción
|
||
|
||
Mi Ruta Limpia es una aplicación móvil que resuelve un problema cotidiano en Celaya: la ciudadanía no sabe con certeza cuándo pasará el camión recolector por su domicilio, lo que genera basura acumulada en la vía pública, problemas de salud y molestias vecinales.
|
||
|
||
La solución ofrece estimaciones de llegada por ventana horaria, notificaciones de cambios operativos, reportes ciudadanos con folio oficial y educación ambiental integrada — todo bajo un principio innegociable de **privacidad por diseño**: el ciudadano solo ve la información de su zona, nunca la ubicación del camión ni las rutas de terceros.
|
||
|
||
---
|
||
|
||
## Roles y funcionalidades
|
||
|
||
### Ciudadano
|
||
- Registro de múltiples domicilios con etiquetas personalizadas
|
||
- ETA por ventana horaria (ej. "Entre 7:20 y 7:35") sin coordenadas del camión
|
||
- Barra de progreso de ruta sin exponer ubicación exacta
|
||
- Confirmación de paso del camión con opción de deshacer
|
||
- Calificación del servicio (1–5 estrellas)
|
||
- Reportes ciudadanos con folio único (`MRL-YYYYMMDD-XXXXXX`) exportables como comprobante
|
||
- Módulo de educación ambiental: 4 categorías, datos de impacto y puntos de acopio
|
||
|
||
### Empleado operativo
|
||
- Registro de incidencias operativas (falla mecánica, obstáculo, accidente, etc.) con folio `OP-YYYYMMDD-XXXXXX`
|
||
- Seguimiento de racha de puntualidad con sistema de bonos ($50 MXN/día puntual)
|
||
- Horario preestablecido con descansos técnicos
|
||
- Sin acceso a reportes ciudadanos (403 Forbidden por diseño)
|
||
|
||
### Administrador
|
||
- Dashboard con KPIs en tiempo real: usuarios activos, domicilios, reportes en 24 h, calificación promedio
|
||
- Gestión del ciclo de vida de reportes: `PENDIENTE → EN_PROCESO → RESUELTO → CERRADO`
|
||
- Administración de usuarios y cambio de roles
|
||
- Vista de flotilla (62 camiones) y feedback ciudadano agregado
|
||
|
||
---
|
||
|
||
## Stack tecnológico
|
||
|
||
| Capa | Tecnologías |
|
||
|------|-------------|
|
||
| Backend | Python 3.13, FastAPI 0.115, SQLAlchemy 2.0, SQLite, JWT (python-jose), bcrypt, Pydantic v2, PyTZ |
|
||
| Frontend | React Native 0.74, Expo SDK 51, React Navigation 6, expo-linear-gradient, AsyncStorage |
|
||
| DevOps | Watchman, Metro bundler (Expo CLI) |
|
||
|
||
La base de datos es SQLite con capacidad de migración a PostgreSQL sin cambios en la capa de servicio.
|
||
|
||
---
|
||
|
||
## Arquitectura
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────────────┐
|
||
│ FRONTEND (Expo) │
|
||
│ │
|
||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||
│ │ Ciudadano │ │ Empleado │ │ Admin │ │
|
||
│ │ 5 tabs │ │ 3 tabs │ │ 4 tabs │ │
|
||
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||
│ │ │
|
||
│ fetch + AsyncStorage (JWT) │
|
||
└──────────────────────────┼───────────────────────────────────────┘
|
||
│ HTTPS REST
|
||
▼
|
||
┌──────────────────────────────────────────────────────────────────┐
|
||
│ BACKEND (FastAPI) │
|
||
│ │
|
||
│ /api/v1/auth — login, registro, /me │
|
||
│ /api/v1/addresses — CRUD de domicilios + geo-routing │
|
||
│ /api/v1/eta — cálculo de ETA privado │
|
||
│ /api/v1/reports — reportes ciudadanos │
|
||
│ /api/v1/admin — restringido a ADMIN │
|
||
│ /api/v1/staff — restringido a EMPLEADO/ADMIN │
|
||
│ │
|
||
│ Middleware: JWT (HTTPBearer) · RBAC · CORS │
|
||
└──────────────────────────┬───────────────────────────────────────┘
|
||
│
|
||
┌───────────┴────────────┐
|
||
▼ ▼
|
||
┌──────────────┐ ┌────────────────┐
|
||
│ SQLite │ │ routes.json │
|
||
│ │ │ (mock GPS) │
|
||
│ users │ │ │
|
||
│ addresses │ │ 15 rutas con │
|
||
│ reports │ │ waypoints + │
|
||
│ op_reports │ │ timestamps │
|
||
│ ratings │ └────────────────┘
|
||
│ trucks │
|
||
└──────────────┘
|
||
```
|
||
|
||
Para el análisis completo de decisiones técnicas, ver [`docs/ARQUITECTURA.md`](docs/ARQUITECTURA.md).
|
||
|
||
---
|
||
|
||
## Instalación
|
||
|
||
### Requisitos previos
|
||
|
||
- Node.js 20 LTS (no compatible con Node 22+)
|
||
- Python 3.11 o superior
|
||
- macOS o Linux (probado en macOS con Xcode + iOS Simulator)
|
||
|
||
### Backend
|
||
|
||
```bash
|
||
cd backend
|
||
python3 -m venv venv
|
||
source venv/bin/activate
|
||
pip install -r requirements.txt
|
||
cp .env.example .env
|
||
|
||
# Poblar la base de datos con datos demo
|
||
python seed_massive.py
|
||
|
||
# Iniciar el servidor
|
||
uvicorn main:app --reload --host 0.0.0.0 --port 8000
|
||
```
|
||
|
||
La API queda disponible en `http://localhost:8000`. La documentación interactiva en `http://localhost:8000/docs`.
|
||
|
||
### Frontend
|
||
|
||
```bash
|
||
cd frontend
|
||
ulimit -n 65536 # macOS: ampliar límite de file descriptors
|
||
npm install
|
||
npx expo start --clear
|
||
```
|
||
|
||
Presiona `i` para iOS Simulator, `w` para web, o escanea el QR con Expo Go.
|
||
|
||
> La URL del backend se configura en [`frontend/src/constants/config.js`](frontend/src/constants/config.js). Actualízala si tu IP local difiere de `10.82.68.125`.
|
||
|
||
Para la guía paso a paso y troubleshooting, ver [`docs/INSTALACION.md`](docs/INSTALACION.md).
|
||
|
||
---
|
||
|
||
## Credenciales de demo
|
||
|
||
| Rol | Email | Contraseña |
|
||
|-----|-------|-----------|
|
||
| Ciudadano | `demo@celaya.gob.mx` | `Celaya2026` |
|
||
| Empleado | `empleado@celaya.gob.mx` | `Empleado2026` |
|
||
| Administrador | `admin@celaya.gob.mx` | `Admin2026` |
|
||
|
||
La base de datos de demo incluye 202 usuarios, 302 domicilios, 280 reportes ciudadanos, 150 reportes operativos, 220 calificaciones y 62 camiones generados con `seed_massive.py`.
|
||
|
||
---
|
||
|
||
## Privacidad por diseño
|
||
|
||
Este principio es el núcleo del proyecto y responde directamente al reto planteado en el hackathon.
|
||
|
||
| Riesgo | Mitigación implementada |
|
||
|--------|------------------------|
|
||
| Ciudadanos persiguiendo camiones | El endpoint `/eta/address/:id` devuelve únicamente: status, mensaje, eta_minutes, window_start/end y progress%. Sin coordenadas. |
|
||
| Acceso a rutas de otros usuarios | El backend valida que `Address.user_id == JWT.user_id` en cada solicitud. |
|
||
| Exposición de información operativa | Las rutas de otros camiones son inaccesibles incluso con manipulación del request. |
|
||
| Incentivo a perseguir camiones | La interfaz incluye el aviso explícito: "Por tu seguridad, no persigas al camión." |
|
||
| Datos sensibles | Contraseñas con bcrypt · JWT firmado con HS256 · sin PII en logs. |
|
||
|
||
---
|
||
|
||
## Estructura del proyecto
|
||
|
||
```
|
||
mi-ruta-limpia/
|
||
├── README.md
|
||
├── docs/
|
||
│ ├── ARQUITECTURA.md # Decisiones técnicas y algoritmo ETA
|
||
│ ├── MANUAL_USUARIO.md # Guía visual por pantalla
|
||
│ ├── API.md # Referencia REST completa
|
||
│ ├── INSTALACION.md # Setup y troubleshooting
|
||
│ └── PRESENTACION.md # Script de demo para el pitch
|
||
│
|
||
├── backend/
|
||
│ ├── main.py # Entry point, CORS y routers
|
||
│ ├── requirements.txt
|
||
│ ├── seed.py # Seed básico (3 usuarios)
|
||
│ ├── seed_massive.py # Seed completo (200+ usuarios)
|
||
│ └── app/
|
||
│ ├── config.py
|
||
│ ├── database.py
|
||
│ ├── models/ # User, Address, Report, OperationalReport, Truck, ServiceRating
|
||
│ ├── schemas/ # Pydantic v2
|
||
│ ├── routers/ # auth, addresses, eta, reports, admin, staff
|
||
│ ├── services/ # auth_service, eta_service
|
||
│ └── data/routes.json # 15 rutas mock
|
||
│
|
||
└── frontend/
|
||
├── App.js
|
||
├── index.js
|
||
├── package.json
|
||
├── app.json
|
||
├── assets/
|
||
└── src/
|
||
├── constants/ # colors, config
|
||
├── context/ # AuthContext (JWT + role)
|
||
├── navigation/ # AppNavigator (routing por rol)
|
||
├── components/ # AppHeader, GoogleGIcon
|
||
├── services/api.js # fetch + interceptors
|
||
└── screens/
|
||
├── auth/ # Login, Register
|
||
├── HomeScreen.js
|
||
├── SchedulesScreen.js
|
||
├── ReportsScreen.js
|
||
├── ProfileScreen.js
|
||
├── EducationScreen.js
|
||
├── staff/ # StaffDashboard, StaffReports
|
||
└── admin/ # AdminDashboard, AdminReports, AdminUsers, AdminProfile
|
||
```
|
||
|
||
---
|
||
|
||
## Documentación
|
||
|
||
| Documento | Audiencia | Contenido |
|
||
|-----------|-----------|-----------|
|
||
| [`docs/ARQUITECTURA.md`](docs/ARQUITECTURA.md) | Jueces técnicos | Decisiones de diseño, algoritmo ETA, RBAC, simulación de flotilla |
|
||
| [`docs/MANUAL_USUARIO.md`](docs/MANUAL_USUARIO.md) | Usuarios finales | Guía visual por pantalla y flujo completo |
|
||
| [`docs/API.md`](docs/API.md) | Desarrolladores | Referencia REST con ejemplos |
|
||
| [`docs/INSTALACION.md`](docs/INSTALACION.md) | Operaciones | Setup paso a paso y troubleshooting |
|
||
| [`docs/PRESENTACION.md`](docs/PRESENTACION.md) | Equipo presentador | Script de demo para los 5–10 min del pitch |
|
||
|
||
---
|
||
|
||
## Licencia
|
||
|
||
Proyecto desarrollado con fines educativos en el marco del hackathon LINCEHACK 2026. Los datos de Celaya son referenciales.
|
||
|
||
---
|
||
|
||
*Celaya, es la esperanza.* |