Mi Ruta Limpia
Sistema de Notificación Inteligente y Privada de Recolección de Residuos Hackathon LINCEHACK · Gobierno de Celaya
📑 Tabla de contenidos
- Problemática
- Solución
- Características principales
- Stack tecnológico
- Arquitectura
- Instalación rápida
- Credenciales demo
- Estructura del proyecto
- Privacidad por diseño
- Documentación adicional
🎯 Problemática
En Celaya, la ciudadanía no sabe con certeza cuándo el camión recolector pasará por su domicilio. Esto provoca:
- Basura sacada demasiado temprano o tarde
- Acumulación cuando el camión ya pasó
- Problemas de salud pública: fauna nociva, malos olores, infecciones
- Molestias vecinales por basura en la calle
La solución no puede ser un GPS público: exponer la ruta completa del camión es un riesgo operativo (gente persigue al camión) y de privacidad.
💡 Solución
Una aplicación móvil que:
- Indica hora aproximada de llegada del camión a tu domicilio registrado
- Envía notificaciones sobre cambios operativos y retrasos
- Educa sobre separación de residuos
- Permite reportar incidencias con folio oficial
- Tiene 3 vistas: Ciudadano, Empleado operativo y Administrador
Todo bajo un principio innegociable de Privacidad por Diseño: el ciudadano solo ve la información de su zona, nunca el mapa completo del camión ni rutas de otros.
✨ Características principales
👤 Vista Ciudadano
- 🏠 Múltiples domicilios con etiquetas (Casa, Trabajo, etc.)
- ⏰ 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
- ✓ Confirmación "¿Ya pasó la basura?" con opción de deshacer
- ⭐ Calificación del servicio (1-5 estrellas)
- 📋 Reportes con folio único (
MRL-YYYYMMDD-XXXXXX) - 📤 Compartir reporte como comprobante
- 🌱 Educación ambiental con 4 categorías, datos de impacto y puntos de acopio
- 📅 Horarios por domicilio
👮 Vista Empleado Operativo
- 🚛 Reportes operativos (camión no arrancó, falla mecánica, accidente, obstáculo, etc.) con folio
OP-YYYYMMDD-XXXXXX - 🔥 Racha de puntualidad (días consecutivos)
- 💰 Bonos por puntualidad ($50 MXN/día puntual)
- 🏆 Próximo bono con cuenta regresiva
- 📅 Horario preestablecido con descansos técnicos
- 💬 Mensajes motivacionales rotativos
- ❌ Sin acceso a reportes ciudadanos (403 Forbidden)
🛡️ Vista Administrador
- 📊 Dashboard con KPIs en vivo (ciudadanos, domicilios, reportes 24h, calificación promedio)
- 📈 Gráficas de reportes por estado y por tipo
- 📋 Gestión de reportes ciudadanos (cambiar PENDIENTE → EN_PROCESO → RESUELTO → CERRADO)
- 👥 Gestión de usuarios y cambio de roles
- 🚛 Vista de flotilla (62 camiones)
- ⭐ Feedback ciudadano agregado
🛠️ Stack tecnológico
Backend
- Python 3.13 con FastAPI 0.115
- SQLAlchemy 2.0 + SQLite (escalable a PostgreSQL)
- JWT (python-jose) + bcrypt para autenticación
- Pydantic v2 para validación
- PyTZ para manejo correcto de zonas horarias (Celaya/CST)
Frontend
- React Native 0.74 con Expo SDK 51
- React 18.2 + React Navigation 6
- expo-linear-gradient, @expo/vector-icons, react-native-svg
- AsyncStorage para persistencia local
- react-native-url-polyfill para compatibilidad WHATWG URL
DevOps
- Watchman para file watching en macOS
- Metro bundler (Expo CLI)
- Migraciones manuales con SQL inline en seeds
🏗️ Arquitectura
┌─────────────────────────────────────────────────────────────────┐
│ FRONTEND (Expo) │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ CIUDADANO │ │ EMPLEADO │ │ ADMIN │ │
│ │ 5 tabs │ │ 3 tabs │ │ 4 tabs │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │ │
│ └────────────────┼──────────────────┘ │
│ │ │
│ fetch + AsyncStorage (JWT) │
└──────────────────────────┼───────────────────────────────────────┘
│ HTTPS REST
▼
┌─────────────────────────────────────────────────────────────────┐
│ BACKEND (FastAPI) │
│ │
│ Routers: │
│ /api/v1/auth — login, register, OAuth, /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 — endpoints restringidos a ADMIN │
│ /api/v1/staff — endpoints para EMPLEADO/ADMIN │
│ │
│ Middleware: │
│ - JWT auth (HTTPBearer) │
│ - RBAC (require_admin, require_staff) │
│ - CORS │
│ │
│ Services: │
│ - eta_service: simulación temporal de la flotilla │
│ - auth_service: hash, verify, JWT │
└──────────────────────────┼───────────────────────────────────────┘
│
┌──────────┴───────────┐
▼ ▼
┌──────────────┐ ┌───────────────┐
│ SQLite │ │ routes.json │
│ │ │ (mock GPS) │
│ 6 tablas: │ │ │
│ - users │ │ 15 rutas con │
│ - addresses │ │ waypoints + │
│ - reports │ │ timestamps │
│ - op_reports│ └───────────────┘
│ - ratings │
│ - trucks │
└──────────────┘
Ver detalles en docs/ARQUITECTURA.md.
🚀 Instalación rápida
Prerequisitos
- Node.js 20 LTS (NO usar 22+)
- Python 3.11+
- macOS o Linux (instrucciones probadas en macOS con Xcode + iOS Simulator)
Backend
cd backend
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
# Poblar BD con datos demo + masivos
python seed_massive.py
# Arrancar API
uvicorn main:app --reload --host 0.0.0.0 --port 8000
API disponible en http://localhost:8000 · Docs interactivos en http://localhost:8000/docs
Frontend
cd frontend
ulimit -n 65536 # macOS file descriptors
npm install
npx expo start --clear
# Presiona 'i' para iOS simulator | 'w' para web | escanea QR con Expo Go
⚠️ La URL del backend está en
frontend/src/constants/config.js. Cámbiala si tu IP local no es10.82.68.125.
Ver guía completa en docs/INSTALACION.md.
🔑 Credenciales demo
| Rol | Contraseña | Acceso | |
|---|---|---|---|
| 🧑 Ciudadano | demo@celaya.gob.mx |
Celaya2026 |
5 pestañas: Inicio, Horarios, Educación, Reportes, Perfil |
| 👮 Empleado | empleado@celaya.gob.mx |
Empleado2026 |
3 pestañas: Inicio (puntualidad), Reportes operativos, Cuenta |
| 🛡️ Admin | admin@celaya.gob.mx |
Admin2026 |
4 pestañas: Dashboard, Reportes ciudadanos, Usuarios, Cuenta |
La BD tiene además 202 usuarios totales, 302 domicilios, 280 reportes ciudadanos, 150 reportes operativos, 220 calificaciones y 62 camiones generados con seed_massive.py.
📂 Estructura del proyecto
mi-ruta-limpia/
├── README.md ← este archivo
├── docs/
│ ├── ARQUITECTURA.md ← decisiones técnicas
│ ├── MANUAL_USUARIO.md ← guía visual por pantalla
│ ├── API.md ← referencia REST
│ ├── INSTALACION.md ← guía paso a paso
│ └── PRESENTACION.md ← script de demo
│
├── backend/
│ ├── main.py ← entry point + CORS + routers
│ ├── requirements.txt
│ ├── seed.py ← seed básico (3 usuarios)
│ ├── seed_massive.py ← seed con 200+ usuarios y datos
│ └── app/
│ ├── config.py ← settings (JWT, DB)
│ ├── database.py ← SQLAlchemy session
│ ├── 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 ← polyfill + entry
├── package.json
├── babel.config.js
├── app.json
├── assets/ ← logos, hero-eco, splash, icons
└── 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 ← ciudadano (5 tabs)
├── SchedulesScreen.js
├── ReportsScreen.js
├── ProfileScreen.js
├── EducationScreen.js
├── staff/ ← empleado (3 tabs)
│ ├── StaffDashboard.js
│ └── StaffReports.js
└── admin/ ← admin (4 tabs)
├── AdminDashboard.js
├── AdminReports.js
├── AdminUsers.js
└── AdminProfile.js
🔒 Privacidad por diseño
Este es el principio innegociable del reto del hackathon. Cumplimos así:
| Riesgo | Mitigación |
|---|---|
| Ciudadanos persiguiendo camiones | El endpoint /eta/address/:id nunca devuelve coordenadas del camión. Solo: status, mensaje, eta_minutes, window_start/end, progress% |
| Snooping de otras rutas | El usuario solo puede consultar sus propios address_id. El backend valida Address.user_id == JWT.user_id |
| Exposición de información operativa | Las rutas de los demás camiones no son visibles ni siquiera con manipulación del request |
| Confianza en la app | La interfaz desalienta explícitamente perseguir al camión ("Por tu seguridad, no persigas al camión") |
| Datos sensibles | Contraseñas con bcrypt · JWT firmado con HS256 · ningún PII se expone en logs |
Ver docs/ARQUITECTURA.md#privacidad-por-diseño para el análisis completo.
📚 Documentación adicional
| Documento | Para quién | Contenido |
|---|---|---|
docs/ARQUITECTURA.md |
Jueces técnicos | Decisiones de diseño, algoritmo ETA, RBAC, BD, simulación |
docs/MANUAL_USUARIO.md |
Usuarios finales | Guía visual por pantalla y flujo |
docs/API.md |
Desarrolladores | Referencia REST completa con ejemplos |
docs/INSTALACION.md |
Equipo de operaciones | Setup paso a paso, troubleshooting |
docs/PRESENTACION.md |
Equipo presentador | Script de demo para los 5-10 min del pitch |
🏆 Equipo
LINCEHACK 2026 — Hackathon Gobierno de Celaya
📝 Licencia
Proyecto desarrollado para fines educativos en el marco del hackathon LINCEHACK. Datos de Celaya son referenciales.
🌱 Celaya, es la esperanza.