# GRH - Sistema de Gestion de Recursos Hidricos Sistema full-stack de gestion y monitoreo de infraestructura hidrica. Permite administrar medidores de agua, concentradores, proyectos, consumo, lecturas y conectarse con sistemas IoT (LoRaWAN / The Things Stack). --- ## Descripcion General El **Sistema GRH** es una aplicacion web completa para organismos operadores de agua (CESPT Tijuana, Tecate, Mexicali, etc.) que incluye: - **Dashboard interactivo** con KPIs, graficos y alertas - **Gestion de Medidores** - CRUD completo con carga masiva Excel/CSV - **Gestion de Concentradores** - Configuracion de gateways LoRa/LoRaWAN - **Gestion de Proyectos** - Administracion de proyectos de infraestructura - **Consumo y Lecturas** - Seguimiento historico de lecturas con filtros y exportacion - **Analytics** - Mapa de medidores, reportes y metricas del servidor - **Conectores** - Integracion con SH-Meters, XMeters y The Things Stack - **Usuarios y Roles** - Control de acceso basado en roles (ADMIN, OPERATOR, VIEWER) - **Auditoria** - Registro completo de actividad del sistema - **Notificaciones** - Alertas en tiempo real (flujo negativo, etc.) - **Tema claro/oscuro** - Personalizacion de la interfaz - **Diseno responsive** - Compatible con desktop, tablet y movil --- ## Arquitectura ``` ┌─────────────────────────────────────────────────────────────┐ │ FRONTEND (React SPA) │ │ http://localhost:5173 │ │ React 18 + TypeScript + Vite + Tailwind CSS + MUI │ └──────────────────────────┬──────────────────────────────────┘ │ REST API (JWT) ▼ ┌─────────────────────────────────────────────────────────────┐ │ BACKEND (Express API) │ │ http://localhost:3000 │ │ Express + TypeScript + Zod + Winston + node-cron │ └──────────────────────────┬──────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ PostgreSQL │ │ 10 tablas + 2 vistas + triggers + indices │ └─────────────────────────────────────────────────────────────┘ ``` Adicionalmente existe un **Upload Panel** (`upload-panel/`) como aplicacion separada para carga masiva de datos via CSV. --- ## Stack Tecnologico ### Frontend | Tecnologia | Version | Proposito | |------------|---------|-----------| | React | 18.2.0 | Framework UI | | TypeScript | 5.2.2 | Type safety | | Vite | 5.2.0 | Build tool y dev server | | Tailwind CSS | 4.1.18 | Estilos utility-first | | Material-UI (MUI) | 7.3.6 | Componentes UI | | MUI X Data Grid | 8.21.0 | Tablas de datos avanzadas | | Recharts | 3.6.0 | Visualizacion de datos | | Leaflet / React-Leaflet | 1.9.4 / 4.2.1 | Mapas interactivos | | Lucide React | 0.559.0 | Iconos SVG | ### Backend | Tecnologia | Version | Proposito | |------------|---------|-----------| | Express.js | 4.18.2 | Framework HTTP | | TypeScript | 5.3.3 | Type safety | | PostgreSQL (pg) | 8.11.3 | Driver de base de datos | | JWT (jsonwebtoken) | 9.0.2 | Autenticacion con tokens | | Bcrypt | 5.1.1 | Hash de contrasenas | | Zod | 3.22.4 | Validacion de datos | | Helmet | 7.1.0 | Headers de seguridad | | Winston | 3.11.0 | Logging | | Multer | 2.0.2 | Subida de archivos | | XLSX | 0.18.5 | Parseo de archivos Excel | | node-cron | 3.0.3 | Tareas programadas | --- ## Instalacion ### Prerrequisitos - Node.js >= 18.x - npm >= 9.x - PostgreSQL >= 14.x ### 1. Clonar el repositorio ```bash git clone https://git.consultoria-as.com/consultoria-as/GRH.git cd GRH ``` ### 2. Configurar la base de datos ```bash # Crear la base de datos createdb water_project # Ejecutar el schema principal psql -d water_project -f water-api/sql/schema.sql # Ejecutar migraciones adicionales psql -d water_project -f water-api/sql/add_audit_logs.sql psql -d water_project -f water-api/sql/add_notifications.sql psql -d water_project -f water-api/sql/add_meter_extended_fields.sql psql -d water_project -f water-api/sql/create_meter_types.sql psql -d water_project -f water-api/sql/add_meter_project_relation.sql psql -d water_project -f water-api/sql/add_user_project_relation.sql ``` ### 3. Configurar el backend ```bash cd water-api cp .env.example .env # Editar .env con las credenciales de PostgreSQL y secretos JWT npm install ``` ### 4. Configurar el frontend ```bash cd .. cp .env.example .env # Editar .env con la URL del backend npm install ``` ### 5. Iniciar en desarrollo ```bash # Terminal 1 - Backend cd water-api npm run dev # Terminal 2 - Frontend cd .. npm run dev ``` El frontend estara disponible en `http://localhost:5173` y el backend en `http://localhost:3000`. --- ## Variables de Entorno ### Frontend (`.env`) | Variable | Descripcion | Ejemplo | |----------|-------------|---------| | `VITE_API_BASE_URL` | URL base del backend | `http://localhost:3000` | ### Backend (`water-api/.env`) | Variable | Descripcion | Ejemplo | |----------|-------------|---------| | `PORT` | Puerto del servidor | `3000` | | `NODE_ENV` | Entorno | `development` | | `DB_HOST` | Host de PostgreSQL | `localhost` | | `DB_PORT` | Puerto de PostgreSQL | `5432` | | `DB_NAME` | Nombre de la base de datos | `water_project` | | `DB_USER` | Usuario de PostgreSQL | `postgres` | | `DB_PASSWORD` | Contrasena de PostgreSQL | `your_password` | | `JWT_ACCESS_SECRET` | Secreto para access tokens | `random_string` | | `JWT_REFRESH_SECRET` | Secreto para refresh tokens | `random_string` | | `JWT_ACCESS_EXPIRES` | Expiracion access token | `15m` | | `JWT_REFRESH_EXPIRES` | Expiracion refresh token | `7d` | | `CORS_ORIGIN` | Origenes permitidos | `http://localhost:5173` | | `TTS_ENABLED` | Habilitar The Things Stack | `false` | | `TTS_BASE_URL` | URL de TTS | `https://...` | | `TTS_WEBHOOK_SECRET` | Secreto para webhooks TTS | `random_string` | --- ## Scripts Disponibles ### Frontend | Comando | Descripcion | |---------|-------------| | `npm run dev` | Servidor de desarrollo (puerto 5173) | | `npm run build` | Compilar TypeScript + build de produccion | | `npm run preview` | Previsualizar build de produccion | | `npm run lint` | Ejecutar ESLint | ### Backend (`water-api/`) | Comando | Descripcion | |---------|-------------| | `npm run dev` | Servidor de desarrollo con hot-reload | | `npm run build` | Compilar TypeScript | | `npm run start` | Ejecutar build compilado | | `npm run watch` | Desarrollo con nodemon | ### Upload Panel (`upload-panel/`) | Comando | Descripcion | |---------|-------------| | `npm run dev` | Servidor de desarrollo | | `npm run build` | Build de produccion | --- ## Estructura del Proyecto ``` GRH/ ├── src/ # Frontend React SPA │ ├── api/ # Cliente API (14 modulos) │ │ ├── client.ts # Cliente HTTP con JWT y refresh automatico │ │ ├── auth.ts # Autenticacion y gestion de tokens │ │ ├── meters.ts # CRUD de medidores │ │ ├── readings.ts # Lecturas de consumo │ │ ├── projects.ts # Proyectos │ │ ├── concentrators.ts # Concentradores │ │ ├── users.ts # Usuarios │ │ ├── roles.ts # Roles │ │ ├── analytics.ts # Analytics y metricas │ │ ├── notifications.ts # Notificaciones │ │ ├── audit.ts # Auditoria │ │ ├── me.ts # Perfil de usuario │ │ ├── meterTypes.ts # Tipos de medidor │ │ └── types.ts # Tipos compartidos │ │ │ ├── components/ # Componentes reutilizables │ │ ├── layout/ │ │ │ ├── Sidebar.tsx # Menu lateral (colapsable, pin) │ │ │ ├── TopMenu.tsx # Barra superior con breadcrumb │ │ │ └── common/ │ │ │ ├── ProfileModal.tsx # Editar perfil y avatar │ │ │ ├── ConfirmModal.tsx # Confirmacion de acciones │ │ │ ├── Watermark.tsx # Marca de agua GRH │ │ │ └── ProjectBadge.tsx # Badge de proyecto │ │ ├── SettingsModals.tsx # Configuracion de tema/UI │ │ └── NotificationDropdown.tsx # Panel de notificaciones │ │ │ ├── pages/ │ │ ├── Home.tsx # Dashboard con KPIs y graficos │ │ ├── LoginPage.tsx # Inicio de sesion │ │ ├── UsersPage.tsx # Gestion de usuarios │ │ ├── RolesPage.tsx # Gestion de roles │ │ ├── AuditoriaPage.tsx # Visor de logs de auditoria │ │ ├── projects/ │ │ │ └── ProjectsPage.tsx │ │ ├── meters/ # Modulo de medidores │ │ │ ├── MeterPage.tsx │ │ │ ├── MetersTable.tsx │ │ │ ├── MetersModal.tsx │ │ │ ├── MetersSidebar.tsx │ │ │ ├── MetersBulkUploadModal.tsx │ │ │ └── useMeters.ts │ │ ├── concentrators/ # Modulo de concentradores │ │ │ ├── ConcentratorsPage.tsx │ │ │ ├── ConcentratorsTable.tsx │ │ │ ├── ConcentratorsModal.tsx │ │ │ ├── ConcentratorsSidebar.tsx │ │ │ └── useConcentrators.ts │ │ ├── consumption/ # Modulo de consumo │ │ │ ├── ConsumptionPage.tsx │ │ │ └── ReadingsBulkUploadModal.tsx │ │ ├── analytics/ # Modulo de analytics │ │ │ ├── AnalyticsMapPage.tsx │ │ │ ├── AnalyticsReportsPage.tsx │ │ │ ├── AnalyticsServerPage.tsx │ │ │ └── MapComponents.tsx │ │ └── conectores/ # Conectores externos │ │ ├── SHMetersPage.tsx │ │ ├── XMetersPage.tsx │ │ └── TTSPage.tsx │ │ │ ├── hooks/ │ │ └── useNotifications.ts │ ├── App.tsx # Componente raiz (routing + auth) │ ├── main.tsx # Punto de entrada React │ └── index.css # Estilos globales (Tailwind) │ ├── water-api/ # Backend Express API │ ├── src/ │ │ ├── index.ts # Setup del servidor Express │ │ ├── config/ │ │ │ ├── index.ts # Carga de configuracion │ │ │ └── database.ts # Pool de conexiones PostgreSQL │ │ ├── routes/ # 17 archivos de rutas │ │ ├── controllers/ # Controladores REST │ │ ├── services/ # Logica de negocio (18 modulos) │ │ ├── middleware/ │ │ │ ├── auth.middleware.ts # Verificacion JWT │ │ │ ├── audit.middleware.ts # Logging de actividad │ │ │ └── ttsWebhook.middleware.ts │ │ ├── validators/ # Validacion con Zod │ │ ├── utils/ │ │ │ ├── jwt.ts # Generacion/verificacion de tokens │ │ │ ├── password.ts # Wrappers de bcrypt │ │ │ └── logger.ts # Configuracion Winston │ │ ├── jobs/ │ │ │ └── negativeFlowDetection.ts # Tarea programada │ │ └── types/ # Interfaces TypeScript │ │ │ ├── sql/ # Schema y migraciones │ │ ├── schema.sql # Schema principal (10 tablas + 2 vistas) │ │ ├── add_audit_logs.sql │ │ ├── add_notifications.sql │ │ ├── add_meter_extended_fields.sql │ │ ├── create_meter_types.sql │ │ ├── add_meter_project_relation.sql │ │ └── add_user_project_relation.sql │ │ │ ├── package.json │ ├── tsconfig.json │ └── .env.example │ ├── upload-panel/ # App separada para carga CSV │ ├── src/ │ │ ├── App.tsx │ │ ├── components/ │ │ │ ├── MetersUpload.tsx │ │ │ ├── ReadingsUpload.tsx │ │ │ ├── FileDropzone.tsx │ │ │ └── ResultsDisplay.tsx │ │ └── api/upload.ts │ ├── package.json │ └── vite.config.ts │ ├── package.json # Dependencias frontend ├── vite.config.ts # Configuracion Vite ├── tsconfig.json # Configuracion TypeScript ├── index.html # HTML de entrada ├── DOCUMENTATION.md # Documentacion tecnica ├── ESTADO_ACTUAL.md # Estado actual del proyecto └── CAMBIOS_SESION.md # Historial de cambios ``` --- ## Base de Datos ### Jerarquia de datos ``` Projects → Concentrators → Meters → Readings → Gateways → Devices ↗ ``` ### Tablas principales | Tabla | Descripcion | |-------|-------------| | `roles` | Roles del sistema (ADMIN, OPERATOR, VIEWER) con permisos JSONB | | `users` | Usuarios con email, password hash, rol y estado | | `projects` | Proyectos de infraestructura hidrica | | `concentrators` | Concentradores de datos vinculados a proyectos | | `gateways` | Gateways LoRaWAN con integracion TTS | | `devices` | Dispositivos LoRaWAN (sensores/transmisores) | | `meters` | Medidores de agua con ubicacion y ultima lectura | | `meter_readings` | Historial de lecturas con bateria y senal | | `tts_uplink_logs` | Logs de mensajes uplink de The Things Stack | | `refresh_tokens` | Tokens de refresco JWT para sesiones | ### Vistas - `meter_stats_by_project` - Estadisticas agregadas de medidores por proyecto - `device_status_summary` - Resumen de estados de dispositivos por proyecto --- ## API Endpoints Todos los endpoints estan bajo el prefijo `/api/`. La mayoria requieren autenticacion JWT. | Grupo | Prefijo | Descripcion | |-------|---------|-------------| | Auth | `/api/auth` | Login, refresh, logout, perfil | | Projects | `/api/projects` | CRUD de proyectos + estadisticas | | Meters | `/api/meters` | CRUD de medidores + lecturas | | Meter Types | `/api/meter-types` | Tipos de medidor | | Concentrators | `/api/concentrators` | CRUD de concentradores | | Gateways | `/api/gateways` | CRUD de gateways + dispositivos | | Devices | `/api/devices` | CRUD de dispositivos LoRaWAN | | Users | `/api/users` | Gestion de usuarios (admin) | | Roles | `/api/roles` | Gestion de roles | | Readings | `/api/readings` | Lecturas y resumen de consumo | | Notifications | `/api/notifications` | Notificaciones del usuario | | Audit | `/api/audit-logs` | Logs de auditoria (admin) | | Bulk Upload | `/api/bulk-upload` | Carga masiva Excel | | CSV Upload | `/api/csv-upload` | Carga masiva CSV | | TTS Webhooks | `/api/webhooks/tts` | Webhooks The Things Stack | | System | `/api/system` | Metricas y salud del servidor (admin) | --- ## Autenticacion El sistema usa **JWT con refresh tokens**: 1. El usuario envia email/password a `POST /api/auth/login` 2. El backend valida credenciales con bcrypt y genera: - **Access token** (15 minutos) - **Refresh token** (7 dias) 3. Los tokens se almacenan en `localStorage` 4. El cliente HTTP envia el access token en `Authorization: Bearer ` 5. Al expirar, el cliente automaticamente llama a `POST /api/auth/refresh` ### Roles y permisos | Rol | Descripcion | |-----|-------------| | `ADMIN` | Acceso completo al sistema | | `OPERATOR` | Gestiona proyectos, dispositivos, medidores (sin configuracion del sistema) | | `VIEWER` | Solo lectura de datos y reportes | --- ## Despliegue ### Build de produccion ```bash # Frontend npm run build # Genera dist/ # Backend cd water-api npm run build # Genera dist/ npm run start # Ejecuta el build ``` ### URLs de produccion - **Frontend:** `https://sistema.gestionrecursoshidricos.com` - **Backend:** `https://api.gestionrecursoshidricos.com` --- ## Repositorios | Remote | URL | |--------|-----| | Gitea | `https://git.consultoria-as.com/consultoria-as/GRH` | | GitHub | `git@github.com:luanngel/water-project.git` | --- ## Licencia Este proyecto es privado y pertenece a GRH - Gestion de Recursos Hidricos / Consultoria AS.