diff --git a/README.md b/README.md index c762d52d..2865f353 100644 --- a/README.md +++ b/README.md @@ -1,171 +1,108 @@ # Mi Ruta Limpia -> **Sistema de Notificación Inteligente y Privada de Recolección de Residuos** -> Hackathon LINCEHACK · Gobierno de Celaya +**Sistema de notificación inteligente y privada de recolección de residuos** +Hackathon LINCEHACK · Gobierno de Celaya · 2026 --- -## 📑 Tabla de contenidos +## Descripción -1. [Problemática](#-problemática) -2. [Solución](#-solución) -3. [Características principales](#-características-principales) -4. [Stack tecnológico](#-stack-tecnológico) -5. [Arquitectura](#-arquitectura) -6. [Instalación rápida](#-instalación-rápida) -7. [Credenciales demo](#-credenciales-demo) -8. [Estructura del proyecto](#-estructura-del-proyecto) -9. [Privacidad por diseño](#-privacidad-por-diseño) -10. [Documentación adicional](#-documentación-adicional) +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. --- -## 🎯 Problemática +## Roles y funcionalidades -En Celaya, la ciudadanía no sabe con certeza cuándo el camión recolector pasará por su domicilio. Esto provoca: +### 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 -- 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 +### 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) -**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. +### 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 --- -## 💡 Solución +## Stack tecnológico -Una aplicación móvil que: +| 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) | -- 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.** +La base de datos es SQLite con capacidad de migración a PostgreSQL sin cambios en la capa de servicio. --- -## ✨ 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 +## Arquitectura ``` -┌─────────────────────────────────────────────────────────────────┐ -│ FRONTEND (Expo) │ +┌──────────────────────────────────────────────────────────────────┐ +│ FRONTEND (Expo) │ │ │ -│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ -│ │ CIUDADANO │ │ EMPLEADO │ │ ADMIN │ │ -│ │ 5 tabs │ │ 3 tabs │ │ 4 tabs │ │ -│ └─────────────┘ └─────────────┘ └─────────────┘ │ -│ │ │ │ │ -│ └────────────────┼──────────────────┘ │ +│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ +│ │ 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 │ +│ /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 auth (HTTPBearer) │ -│ - RBAC (require_admin, require_staff) │ -│ - CORS │ -│ │ -│ Services: │ -│ - eta_service: simulación temporal de la flotilla │ -│ - auth_service: hash, verify, JWT │ -└──────────────────────────┼───────────────────────────────────────┘ +│ Middleware: JWT (HTTPBearer) · RBAC · CORS │ +└──────────────────────────┬───────────────────────────────────────┘ │ - ┌──────────┴───────────┐ - ▼ ▼ - ┌──────────────┐ ┌───────────────┐ - │ SQLite │ │ routes.json │ - │ │ │ (mock GPS) │ - │ 6 tablas: │ │ │ - │ - users │ │ 15 rutas con │ - │ - addresses │ │ waypoints + │ - │ - reports │ │ timestamps │ - │ - op_reports│ └───────────────┘ - │ - ratings │ - │ - trucks │ - └──────────────┘ + ┌───────────┴────────────┐ + ▼ ▼ + ┌──────────────┐ ┌────────────────┐ + │ SQLite │ │ routes.json │ + │ │ │ (mock GPS) │ + │ users │ │ │ + │ addresses │ │ 15 rutas con │ + │ reports │ │ waypoints + │ + │ op_reports │ │ timestamps │ + │ ratings │ └────────────────┘ + │ trucks │ + └──────────────┘ ``` -Ver detalles en [`docs/ARQUITECTURA.md`](docs/ARQUITECTURA.md). +Para el análisis completo de decisiones técnicas, ver [`docs/ARQUITECTURA.md`](docs/ARQUITECTURA.md). --- -## 🚀 Instalación rápida +## Instalación -### Prerequisitos -- **Node.js 20 LTS** (NO usar 22+) -- **Python 3.11+** -- **macOS** o **Linux** (instrucciones probadas en macOS con Xcode + iOS Simulator) +### 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 @@ -176,140 +113,125 @@ source venv/bin/activate pip install -r requirements.txt cp .env.example .env -# Poblar BD con datos demo + masivos +# Poblar la base de datos con datos demo python seed_massive.py -# Arrancar API +# Iniciar el servidor uvicorn main:app --reload --host 0.0.0.0 --port 8000 ``` -API disponible en `http://localhost:8000` · Docs interactivos en `http://localhost:8000/docs` +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 file descriptors +ulimit -n 65536 # macOS: ampliar límite de 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`](frontend/src/constants/config.js). Cámbiala si tu IP local no es `10.82.68.125`. +Presiona `i` para iOS Simulator, `w` para web, o escanea el QR con Expo Go. -Ver guía completa en [`docs/INSTALACION.md`](docs/INSTALACION.md). +> 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 demo +## Credenciales de demo -| Rol | Email | 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 | +| Rol | Email | Contraseña | +|-----|-------|-----------| +| Ciudadano | `demo@celaya.gob.mx` | `Celaya2026` | +| Empleado | `empleado@celaya.gob.mx` | `Empleado2026` | +| Administrador | `admin@celaya.gob.mx` | `Admin2026` | -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`. +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`. --- -## 📂 Estructura del proyecto +## 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 ← este archivo +├── README.md ├── 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 +│ ├── 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 + routers +│ ├── main.py # Entry point, CORS y routers │ ├── requirements.txt -│ ├── seed.py ← seed básico (3 usuarios) -│ ├── seed_massive.py ← seed con 200+ usuarios y datos +│ ├── seed.py # Seed básico (3 usuarios) +│ ├── seed_massive.py # Seed completo (200+ usuarios) │ └── 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 +│ ├── 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 ← polyfill + entry + ├── index.js ├── package.json - ├── babel.config.js ├── app.json - ├── assets/ ← logos, hero-eco, splash, icons + ├── assets/ └── src/ - ├── constants/ ← colors, config - ├── context/ ← AuthContext (JWT + role) - ├── navigation/ ← AppNavigator (routing por rol) - ├── components/ ← AppHeader, GoogleGIcon - ├── services/api.js ← fetch + interceptors + ├── 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) + ├── auth/ # Login, Register + ├── HomeScreen.js ├── 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 + ├── staff/ # StaffDashboard, StaffReports + └── admin/ # AdminDashboard, AdminReports, AdminUsers, AdminProfile ``` --- -## 🔒 Privacidad por diseño +## Documentación -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`](docs/ARQUITECTURA.md) para el análisis completo. +| 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 | --- -## 📚 Documentación adicional +## Licencia -| Documento | Para quién | Contenido | -|-----------|------------|-----------| -| [`docs/ARQUITECTURA.md`](docs/ARQUITECTURA.md) | Jueces técnicos | Decisiones de diseño, algoritmo ETA, RBAC, BD, simulación | -| [`docs/MANUAL_USUARIO.md`](docs/MANUAL_USUARIO.md) | Usuarios finales | Guía visual por pantalla y flujo | -| [`docs/API.md`](docs/API.md) | Desarrolladores | Referencia REST completa con ejemplos | -| [`docs/INSTALACION.md`](docs/INSTALACION.md) | Equipo de operaciones | Setup paso a paso, troubleshooting | -| [`docs/PRESENTACION.md`](docs/PRESENTACION.md) | Equipo presentador | Script de demo para los 5-10 min del pitch | +Proyecto desarrollado con fines educativos en el marco del hackathon LINCEHACK 2026. Los datos de Celaya son referenciales. --- -## 🏆 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.* +*Celaya, es la esperanza.* \ No newline at end of file