Reflect current project state across all 8 docs: ADMIN/ORGANISMO_OPERADOR/OPERATOR role hierarchy, scope filtering, organismos_operadores table, Histórico de Tomas page, new SQL migrations, and updated API endpoints with auth requirements. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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
- Organismos Operadores - Gestion de organismos operadores de agua (ADMIN)
- Historico de Tomas - Consulta de historial de lecturas por medidor con grafica y estadisticas
- Usuarios y Roles - Control de acceso basado en roles con jerarquia de 3 niveles
- Auditoria - Registro completo de actividad del sistema (ADMIN)
- 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 │
│ 11 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
git clone https://git.consultoria-as.com/consultoria-as/GRH.git
cd GRH
2. Configurar la base de datos
# 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
psql -d water_project -f water-api/sql/add_organismos_operadores.sql
psql -d water_project -f water-api/sql/add_user_meter_fields.sql
3. Configurar el backend
cd water-api
cp .env.example .env
# Editar .env con las credenciales de PostgreSQL y secretos JWT
npm install
4. Configurar el frontend
cd ..
cp .env.example .env
# Editar .env con la URL del backend
npm install
5. Iniciar en desarrollo
# 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 + lecturas historicas
│ │ ├── readings.ts # Lecturas de consumo
│ │ ├── projects.ts # Proyectos
│ │ ├── concentrators.ts # Concentradores
│ │ ├── users.ts # Usuarios
│ │ ├── roles.ts # Roles
│ │ ├── organismos.ts # CRUD organismos operadores
│ │ ├── 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
│ │ ├── OrganismosPage.tsx # Gestion de organismos operadores
│ │ ├── 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
│ │ ├── historico/ # Modulo de historico de tomas
│ │ │ └── HistoricoPage.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
│ │ │ └── scope.ts # Filtrado por scope de rol
│ │ ├── jobs/
│ │ │ └── negativeFlowDetection.ts # Tarea programada
│ │ └── types/ # Interfaces TypeScript
│ │
│ ├── sql/ # Schema y migraciones
│ │ ├── schema.sql # Schema principal + migraciones (11 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
│ │ ├── add_organismos_operadores.sql
│ │ └── add_user_meter_fields.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, ORGANISMO_OPERADOR, OPERATOR) con permisos JSONB |
users |
Usuarios con email, password hash, rol, proyecto y organismo |
organismos_operadores |
Organismos operadores de agua (CESPT Tijuana, Tecate, etc.) |
projects |
Proyectos de infraestructura hidrica (vinculados a organismo) |
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 proyectodevice_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 |
| Organismos | /api/organismos-operadores |
CRUD de organismos operadores (ADMIN) |
| Projects | /api/projects |
CRUD de proyectos + estadisticas |
| Meters | /api/meters |
CRUD de medidores + lecturas historicas |
| 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:
- El usuario envia email/password a
POST /api/auth/login - El backend valida credenciales con bcrypt y genera:
- Access token (15 minutos)
- Refresh token (7 dias)
- Los tokens se almacenan en
localStorage - El cliente HTTP envia el access token en
Authorization: Bearer <token> - Al expirar, el cliente automaticamente llama a
POST /api/auth/refresh
Roles y permisos (Jerarquia de 3 niveles)
| Rol | Descripcion | Scope |
|---|---|---|
ADMIN |
Acceso completo al sistema | Ve todos los datos |
ORGANISMO_OPERADOR |
Gestiona proyectos de su organismo | Ve datos de proyectos de su organismo |
OPERATOR |
Opera medidores de su proyecto | Ve datos de su proyecto asignado |
Despliegue
Build de produccion
# 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.