marianesaldana 80dbd947e5 Initial commit
2026-05-23 08:59:34 -06:00
2026-05-23 08:59:34 -06:00
2026-05-23 08:59:34 -06:00
2026-05-23 08:59:34 -06:00
2026-05-23 08:59:34 -06:00
2026-05-23 08:59:34 -06:00

Mi Ruta Limpia

Sistema de Notificación Inteligente y Privada de Recolección de Residuos Hackathon LINCEHACK · Gobierno de Celaya


📑 Tabla de contenidos

  1. Problemática
  2. Solución
  3. Características principales
  4. Stack tecnológico
  5. Arquitectura
  6. Instalación rápida
  7. Credenciales demo
  8. Estructura del proyecto
  9. Privacidad por diseño
  10. 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 es 10.82.68.125.

Ver guía completa en docs/INSTALACION.md.


🔑 Credenciales 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

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.

Description
Repositorio del equipo V-Escape: Velocidad mínima requerida para que un objeto venza la fuerza gravitacional de un planeta y logre salir al espacio. Impulso, Energía y Éxito.
Readme 97 MiB
Languages
JavaScript 74%
Python 26%