Update all project documentation to reflect current state

Rewrite README.md, DOCUMENTATION.md, ESTADO_ACTUAL.md and CAMBIOS_SESION.md
to accurately document the full-stack architecture, all modules, API endpoints,
JWT auth, database schema, and features added in February 2026.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Exteban08
2026-02-09 07:48:54 +00:00
parent e1d4db96fe
commit 61dafa83ac
4 changed files with 1127 additions and 1025 deletions

View File

@@ -1,171 +1,143 @@
# Cambios Realizados - Sesión 2026-01-23 # Historial de Cambios - Proyecto GRH
## Resumen Registro cronologico de cambios significativos realizados al proyecto.
Corrección de errores críticos que causaban pantalla blanca y mejoras en el sistema de carga masiva.
--- ---
## Problema 1: Pantalla Blanca en Water Meters y Consumo ## 2026-02-09: Actualizacion de documentacion
### Síntoma ### Resumen
Al navegar a "Water Meters" o "Consumo", la página se quedaba en blanco. Actualizacion completa de los 4 archivos de documentacion para reflejar el estado real del proyecto.
### Causa
PostgreSQL devuelve valores DECIMAL como strings (ej: `"300.0000"`). El código llamaba `.toFixed()` directamente sobre estos strings, pero `.toFixed()` es un método de números, no de strings.
### Solución
Convertir los valores a número con `Number()` antes de llamar `.toFixed()`.
### Archivos Modificados ### Archivos Modificados
| Archivo | Cambio |
|---------|--------|
| `README.md` | Reescrito completamente: arquitectura full-stack, backend Express, PostgreSQL, todos los modulos, endpoints API, variables de entorno, estructura de directorios actualizada |
| `DOCUMENTATION.md` | Reescrito completamente: documentacion tecnica con JWT real, todos los endpoints del backend, esquema relacional, hooks, sistema de temas, conectores, guia de desarrollo actualizada |
| `ESTADO_ACTUAL.md` | Actualizado con todas las funcionalidades implementadas en febrero 2026: Analytics, Conectores, Dark mode, Notificaciones, Auditoria, Upload Panel, historial de correcciones |
| `CAMBIOS_SESION.md` | Convertido a historial cronologico completo de cambios |
**`src/pages/meters/MetersTable.tsx` (línea 75)** ### Motivo
```typescript La documentacion previa describia una version temprana del proyecto (solo frontend, API externa NocoDB, auth con token simple) y no reflejaba el backend Express propio, JWT con refresh tokens, ni los modulos agregados en febrero 2026.
// ANTES:
r.lastReadingValue?.toFixed(2)
// DESPUÉS:
r.lastReadingValue != null ? Number(r.lastReadingValue).toFixed(2) : "-"
```
**`src/pages/consumption/ConsumptionPage.tsx` (líneas 133, 213, 432)**
```typescript
// ANTES:
r.readingValue.toFixed(2)
summary?.avgReading.toFixed(1)
reading.readingValue.toFixed(2)
// DESPUÉS:
Number(r.readingValue).toFixed(2)
summary?.avgReading != null ? Number(summary.avgReading).toFixed(1) : "0"
Number(reading.readingValue).toFixed(2)
```
--- ---
## Problema 2: Modal de Carga Masiva se Cerraba sin Mostrar Resultados ## 2026-02-05: Sincronizacion de conectores
### Síntoma ### Cambio
Al subir un archivo Excel para carga masiva, el modal se cerraba inmediatamente sin mostrar cuántos registros se insertaron o qué errores hubo. Cambio de hora de sincronizacion de conectores de 2:00 AM a 9:00 AM.
### Causa ### Archivos Modificados (2)
El callback `onSuccess` cerraba el modal automáticamente: - `src/pages/conectores/SHMetersPage.tsx`
```typescript - `src/pages/conectores/XMetersPage.tsx`
onSuccess={() => {
m.loadMeters();
setShowBulkUpload(false); // ← Cerraba antes de ver resultados
}}
```
### Solución
Separar la recarga de datos del cierre del modal. Ahora el modal solo se cierra cuando el usuario hace clic en "Cerrar".
### Archivo Modificado
**`src/pages/meters/MeterPage.tsx` (líneas 332-340)**
```typescript
// ANTES:
<MetersBulkUploadModal
onClose={() => setShowBulkUpload(false)}
onSuccess={() => {
m.loadMeters();
setShowBulkUpload(false);
}}
/>
// DESPUÉS:
<MetersBulkUploadModal
onClose={() => {
m.loadMeters();
setShowBulkUpload(false);
}}
onSuccess={() => {
m.loadMeters();
}}
/>
```
--- ---
## Problema 3: Error de Fecha Inválida en Carga Masiva ## 2026-02-04: Favicon y conectores
### Síntoma ### Cambios
Al subir medidores, aparecía el error: - Actualizacion de favicon del sistema
``` - Mejoras en la visualizacion de tiempo de ultima conexion en paginas de conectores
Fila X: invalid input syntax for type date: "Installed" - Agregado plan de implementacion para rol ORGANISMOS_OPERADORES
```
### Causa ### Archivos Modificados (4+1)
El archivo Excel tenía columnas con valores como "Installed" o "New_LoRa" que el sistema interpretaba como fechas porque no estaban mapeadas correctamente. - Favicon actualizado
- Paginas de conectores actualizadas
### Solución - `PLAN_ORGANISMOS_OPERADORES.md` (plan de implementacion)
1. **Validar fechas**: Verificar que `installation_date` sea realmente una fecha válida antes de usarla.
2. **Más mapeos de columnas**: Agregar mapeos para columnas comunes como `device_status`, `device_name`, etc.
3. **Normalizar status**: Convertir valores como "Installed", "New_LoRa" a "ACTIVE".
### Archivo Modificado
**`water-api/src/services/bulk-upload.service.ts`**
Validación de fechas (líneas 183-195):
```typescript
let installationDate: string | undefined = undefined;
if (row.installation_date) {
const dateStr = String(row.installation_date).trim();
if (/^\d{4}[-/]\d{1,2}[-/]\d{1,2}/.test(dateStr) || /^\d{1,2}[-/]\d{1,2}[-/]\d{2,4}/.test(dateStr)) {
const parsed = new Date(dateStr);
if (!isNaN(parsed.getTime())) {
installationDate = parsed.toISOString().split('T')[0];
}
}
}
```
Mapeos de columnas adicionales (líneas 65-90):
```typescript
const mappings: Record<string, string> = {
// Serial number
'device_s/n': 'serial_number',
'device_sn': 'serial_number',
// Name
'device_name': 'name',
'meter_name': 'name',
// Status
'device_status': 'status',
// ... más mapeos
};
```
Normalización de status (líneas 210-225):
```typescript
const statusMappings: Record<string, string> = {
'INSTALLED': 'ACTIVE',
'NEW_LORA': 'ACTIVE',
'NEW': 'ACTIVE',
'ENABLED': 'ACTIVE',
'DISABLED': 'INACTIVE',
// ...
};
```
--- ---
## Archivos Modificados en Esta Sesión ## 2026-02-03: Dark mode, Analytics, Conectores y CSV Upload
### Resumen
Sesion mayor con multiples funcionalidades nuevas implementadas en una serie de 12 commits.
### Nuevas Funcionalidades
**Dark Mode Completo**
- Toggle dark/light/system en configuracion
- Paleta Zinc de Tailwind aplicada a todas las paginas
- Soporte en tablas, modales, formularios, sidebars
- Cards de ConsumptionPage y tabla de AuditoriaPage
**Seccion Analytics (3 paginas)**
- `AnalyticsMapPage.tsx` - Mapa Leaflet con ubicaciones de medidores
- `AnalyticsReportsPage.tsx` - Dashboard de reportes y estadisticas
- `AnalyticsServerPage.tsx` - Metricas del servidor (CPU, memoria, requests)
- `MapComponents.tsx` - Componentes auxiliares del mapa
**Seccion Conectores (3 paginas)**
- `SHMetersPage.tsx` - Conector para sistema SH-Meters
- `XMetersPage.tsx` - Conector para sistema XMeters
- `TTSPage.tsx` - Conector para The Things Stack (LoRaWAN)
**Upload Panel (app separada)**
- Nueva aplicacion en `upload-panel/` con React + Vite + Tailwind
- `MetersUpload.tsx` - Carga de medidores via CSV (upsert)
- `ReadingsUpload.tsx` - Carga de lecturas via CSV
- `FileDropzone.tsx` - Componente de dropzone para archivos
- `ResultsDisplay.tsx` - Visualizacion de resultados
**Otros**
- Nuevos tipos de medidor: LORA, LORAWAN, GRANDES CONSUMIDORES
- Documentacion completa del proyecto (6 archivos)
### Archivos Modificados
Aproximadamente 50+ archivos en 12 commits.
---
## 2026-01-23: Fix pantalla blanca y carga masiva
### Resumen
Correccion de errores criticos que causaban pantalla blanca y mejoras en el sistema de carga masiva.
### Problema 1: Pantalla Blanca en Water Meters y Consumo
**Sintoma:** Al navegar a "Water Meters" o "Consumo", la pagina se quedaba en blanco.
**Causa:** PostgreSQL devuelve valores DECIMAL como strings (ej: `"300.0000"`). El codigo llamaba `.toFixed()` directamente sobre estos strings.
**Solucion:** Convertir a numero con `Number()` antes de `.toFixed()`.
**Archivos:**
- `src/pages/meters/MetersTable.tsx:75`
- `src/pages/consumption/ConsumptionPage.tsx:133, 213, 432`
### Problema 2: Modal de Carga Masiva se Cerraba sin Resultados
**Sintoma:** El modal se cerraba automaticamente despues de la carga sin mostrar resultados.
**Causa:** El callback `onSuccess` cerraba el modal automaticamente.
**Solucion:** Separar recarga de datos (`onSuccess`) del cierre del modal (`onClose`).
**Archivo:** `src/pages/meters/MeterPage.tsx:332-340`
### Problema 3: Error de Fecha Invalida en Carga Masiva
**Sintoma:** Error `invalid input syntax for type date: "Installed"` al subir medidores.
**Causa:** Columnas con valores como "Installed" o "New_LoRa" se interpretaban como fechas.
**Solucion:**
1. Validar formato de fecha con regex antes de usarla
2. Agregar mapeos de columnas comunes (`device_s/n``serial_number`, etc.)
3. Normalizar status ("Installed" → ACTIVE, "New_LoRa" → ACTIVE, etc.)
**Archivo:** `water-api/src/services/bulk-upload.service.ts`
### Archivos Modificados
| Archivo | Cambio | | Archivo | Cambio |
|---------|--------| |---------|--------|
| `src/pages/meters/MetersTable.tsx` | Fix `.toFixed()` en lastReadingValue | | `src/pages/meters/MetersTable.tsx` | Fix `.toFixed()` en lastReadingValue |
| `src/pages/consumption/ConsumptionPage.tsx` | Fix `.toFixed()` en readingValue y avgReading | | `src/pages/consumption/ConsumptionPage.tsx` | Fix `.toFixed()` en readingValue y avgReading |
| `src/pages/meters/MeterPage.tsx` | Fix modal de carga masiva | | `src/pages/meters/MeterPage.tsx` | Fix modal de carga masiva |
| `water-api/src/services/bulk-upload.service.ts` | Validación de fechas, mapeos de columnas, normalización de status | | `water-api/src/services/bulk-upload.service.ts` | Validacion de fechas, mapeos, normalizacion |
| `ESTADO_ACTUAL.md` | Documentación actualizada |
| `CAMBIOS_SESION.md` | Este archivo |
--- ### Verificacion
- La pagina de Water Meters carga correctamente
## Verificación - La pagina de Consumo carga correctamente
- El modal de carga masiva muestra resultados
1. ✅ La página de Water Meters carga correctamente - Errores de carga masiva se muestran claramente
2. ✅ La página de Consumo carga correctamente - Valores como "Installed" no causan error de fecha
3. ✅ El modal de carga masiva muestra resultados
4. ✅ Errores de carga masiva se muestran claramente
5. ✅ Valores como "Installed" no causan error de fecha

File diff suppressed because it is too large Load Diff

View File

@@ -1,55 +1,72 @@
# Estado Actual del Proyecto Water Project GRH # Estado Actual del Proyecto GRH
**Fecha:** 2026-01-23 **Fecha:** 2026-02-09
**Última actualización:** Corrección de errores y mejoras en carga masiva **Ultima actualizacion:** Documentacion actualizada para reflejar el estado completo del proyecto
--- ---
## Resumen del Proyecto ## Resumen del Proyecto
Sistema de gestión de medidores de agua con: Sistema full-stack de gestion de medidores de agua con:
- **Frontend:** React + TypeScript + Vite (puerto 5173) - **Frontend:** React 18 + TypeScript + Vite (puerto 5173)
- **Backend:** Node.js + Express + TypeScript (puerto 3000) - **Backend:** Node.js + Express + TypeScript (puerto 3000)
- **Base de datos:** PostgreSQL - **Base de datos:** PostgreSQL
- **Upload Panel:** App separada para carga CSV masiva
### Jerarquía de datos: ### Jerarquia de datos:
``` ```
Projects → Concentrators → Meters → Readings Projects → Concentrators → Meters → Readings
→ Gateways → Devices ↗
``` ```
### URLs de produccion:
- **Frontend:** https://sistema.gestionrecursoshidricos.com
- **Backend:** https://api.gestionrecursoshidricos.com
### Repositorios:
- **Gitea:** https://git.consultoria-as.com/consultoria-as/GRH
- **GitHub:** git@github.com:luanngel/water-project.git
--- ---
## Arquitectura del Sistema ## Arquitectura del Sistema
``` ```
┌─────────────────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────────┐
│ FRONTEND (React) │ FRONTEND (React SPA)
│ http://localhost:5173 │ │ http://localhost:5173 │
├─────────────────────────────────────────────────────────────┤ ├─────────────────────────────────────────────────────────────┤
- React 18 + TypeScript + Vite │ │ React 18 + TypeScript + Vite
- Tailwind CSS + Material-UI │ Tailwind CSS (paleta Zinc) + Material-UI 7
- Recharts para gráficos │ Recharts (graficos) + Leaflet (mapas)
- Cliente API con JWT automático │ Cliente API con JWT + refresh automatico │
└─────────────────────────────────────────────────────────────┘ │ Dark mode / Light mode / System │
└──────────────────────────┬──────────────────────────────────┘
│ REST API + JWT Bearer
┌─────────────────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────────┐
│ BACKEND (Node.js) │ │ BACKEND (Express) │
│ http://localhost:3000 │ │ http://localhost:3000 │
├─────────────────────────────────────────────────────────────┤ ├─────────────────────────────────────────────────────────────┤
- Express + TypeScript │ Express + TypeScript + Zod (validacion)
- Autenticación JWT con refresh tokens │ JWT access (15m) + refresh (7d) tokens
- CRUD completo para todas las entidades 17 archivos de rutas, 18 servicios
- Carga masiva via Excel (xlsx) Helmet, CORS, Bcrypt, Winston logging
└─────────────────────────────────────────────────────────────┘ │ node-cron (deteccion flujo negativo) │
│ Multer + XLSX (carga masiva) │
│ Webhooks TTS (The Things Stack / LoRaWAN) │
└──────────────────────────┬──────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────────┐
│ BASE DE DATOS │
│ PostgreSQL │ │ PostgreSQL │
├─────────────────────────────────────────────────────────────┤ ├─────────────────────────────────────────────────────────────┤
Tablas: users, roles, projects, concentrators, 10 tablas: roles, users, projects, concentrators, │
meters, meter_readings, refresh_tokens gateways, devices, meters, meter_readings,
│ tts_uplink_logs, refresh_tokens │
│ 2 vistas: meter_stats_by_project, device_status_summary │
│ 7 archivos SQL (schema + 6 migraciones) │
│ Triggers de updated_at, indices compuestos, JSONB │
└─────────────────────────────────────────────────────────────┘ └─────────────────────────────────────────────────────────────┘
``` ```
@@ -57,58 +74,128 @@ Projects → Concentrators → Meters → Readings
## Funcionalidades Implementadas ## Funcionalidades Implementadas
### 1. Autenticación ### 1. Autenticacion y Autorizacion
- Login con JWT + refresh tokens - Login con JWT: access token (15 min) + refresh token (7 dias)
- Manejo automático de renovación de tokens - Refresh automatico de tokens en el cliente (cola de peticiones)
- Roles: ADMIN, USER - 3 roles con permisos JSONB: ADMIN, OPERATOR, VIEWER
- Relacion usuario-proyecto para acceso por scope
- Hash de contrasenas con bcrypt (12 rounds)
- Proteccion de rutas por rol en backend y frontend
### 2. Gestión de Proyectos ### 2. Dashboard (Home)
- KPIs: Total medidores, medidores activos, consumo promedio, alertas
- Grafico de barras: Medidores por proyecto (Recharts)
- Selector de organismos operadores (CESPT Tijuana, Tecate, Mexicali)
- Historial reciente de actividades
- Panel de ultimas alertas
- Soporte por rol (ADMIN, OPERATOR, VIEWER)
### 3. Gestion de Proyectos
- CRUD completo - CRUD completo
- Estados: ACTIVE/INACTIVE - Estados: ACTIVE, INACTIVE, COMPLETED
- Estadisticas por proyecto (medidores, lecturas, areas)
### 3. Gestión de Concentradores ### 4. Gestion de Concentradores
- CRUD completo - CRUD completo
- Vinculados a proyectos - Vinculados a proyectos
- Tipos: Gateway LoRa/LoRaWAN - Estado: ACTIVE, INACTIVE, OFFLINE, MAINTENANCE, ERROR
- IP, firmware, ultima comunicacion
### 4. Gestión de Medidores ### 5. Gestion de Medidores
- CRUD completo - CRUD completo con tabla, sidebar de detalle y modal de edicion
- Tipos: LORA, LORAWAN, GRANDES - Tipos de medidor: WATER, GAS, ELECTRIC
- Estados: ACTIVE, INACTIVE, MAINTENANCE, FAULTY, REPLACED - Protocolos: GENERAL, LORA, LORAWAN
- **Carga masiva via Excel** - Estados: ACTIVE, INACTIVE, OFFLINE, MAINTENANCE, ERROR
- Última lectura visible en tabla - Carga masiva via Excel y CSV
- Busqueda, filtros por proyecto/tipo/estado
- Ultima lectura visible en tabla
- Campos extendidos: protocolo, MAC, gateway, voltaje, senal, flujo, coordenadas
- Tipos adicionales: LORA, LORAWAN, GRANDES CONSUMIDORES
### 5. Gestión de Lecturas (Consumo) ### 6. Consumo y Lecturas
- CRUD completo - CRUD de lecturas
- Tipos: AUTOMATIC, MANUAL, SCHEDULED - Tipos: AUTOMATIC, MANUAL, SCHEDULED
- **Carga masiva via Excel** - Carga masiva via Excel y CSV
- Filtros por proyecto, fecha - Filtros por proyecto, medidor, rango de fechas
- Exportación a CSV - Resumen de consumo (total, promedio, min, max)
- Indicadores de batería y señal - Indicadores de bateria y senal
- Exportacion
### 6. Dashboard ### 7. Analytics
- KPIs: Total lecturas, medidores activos, consumo promedio - **Mapa:** Visualizacion de medidores con coordenadas en mapa Leaflet interactivo
- Gráficos por proyecto - **Reportes:** Dashboard de estadisticas y reportes de consumo
- Últimas alertas - **Servidor:** Metricas del sistema (CPU, memoria, uptime, requests)
### 8. Conectores Externos
- **SH-Meters:** Integracion con sistema de medidores SH
- **XMeters:** Integracion con sistema XMeters
- **The Things Stack (TTS):** Webhooks LoRaWAN para uplink, join y downlink/ack
- Sincronizacion programada a las 9:00 AM
- Seguimiento de ultima conexion y estado
### 9. Gestion de Usuarios
- CRUD completo (solo ADMIN)
- Asignacion de roles
- Asignacion de proyecto
- Estados: activo/inactivo
- Cambio de contrasena
### 10. Gestion de Roles
- 3 roles predefinidos: ADMIN, OPERATOR, VIEWER
- Permisos granulares JSONB por recurso
- CRUD de roles (solo ADMIN)
- Conteo de usuarios por rol
### 11. Auditoria
- Registro automatico de todas las acciones via middleware
- Visor de logs con filtros (solo ADMIN)
- Actividad del usuario actual (todos los roles)
- Estadisticas de auditoria
- Busqueda por registro especifico
### 12. Notificaciones
- Notificaciones in-app
- Conteo de no leidas en tiempo real
- Marcar como leida (individual y masiva)
- Generacion automatica por flujo negativo (cron job)
- Dropdown en TopMenu
### 13. Dark Mode
- Soporte completo: Dark / Light / System
- Paleta Zinc de Tailwind
- Aplicado a todas las paginas, modales, tablas, formularios
- Persistencia en localStorage
### 14. Upload Panel
- Aplicacion separada (`upload-panel/`) para carga CSV
- Dropzone para archivos
- Carga de medidores (upsert)
- Carga de lecturas
- Descarga de plantillas
- Visualizacion de resultados y errores
--- ---
## Carga Masiva ## Carga Masiva
### Medidores (Excel) ### Medidores (Excel / CSV)
Columnas requeridas: Columnas requeridas:
- `serial_number` - Número de serie del medidor (único) - `serial_number` - Numero de serie del medidor (unico)
- `name` - Nombre del medidor - `name` - Nombre del medidor
- `concentrator_serial` - Serial del concentrador existente - `concentrator_serial` - Serial del concentrador existente
Columnas opcionales: Columnas opcionales:
- `meter_id` - ID del medidor - `meter_id` - ID del medidor
- `location` - Ubicación - `location` - Ubicacion
- `type` - LORA, LORAWAN, GRANDES (default: LORA) - `type` - LORA, LORAWAN, GRANDES (default: LORA)
- `status` - ACTIVE, INACTIVE, etc. (default: ACTIVE) - `status` - ACTIVE, INACTIVE, etc. (default: ACTIVE)
- `installation_date` - Fecha de instalación (YYYY-MM-DD) - `installation_date` - Fecha de instalacion (YYYY-MM-DD)
### Lecturas (Excel) Mapeos automaticos de columnas: `device_s/n``serial_number`, `device_name``name`, `device_status``status`, etc.
Normalizacion de status: "Installed" → ACTIVE, "New_LoRa" → ACTIVE, "Enabled" → ACTIVE, "Disabled" → INACTIVE.
### Lecturas (Excel / CSV)
Columnas requeridas: Columnas requeridas:
- `meter_serial` - Serial del medidor existente - `meter_serial` - Serial del medidor existente
- `reading_value` - Valor de la lectura - `reading_value` - Valor de la lectura
@@ -116,21 +203,12 @@ Columnas requeridas:
Columnas opcionales: Columnas opcionales:
- `reading_type` - AUTOMATIC, MANUAL, SCHEDULED (default: MANUAL) - `reading_type` - AUTOMATIC, MANUAL, SCHEDULED (default: MANUAL)
- `received_at` - Fecha/hora (default: ahora) - `received_at` - Fecha/hora (default: ahora)
- `battery_level` - Nivel de batería (%) - `battery_level` - Nivel de bateria (%)
- `signal_strength` - Intensidad de señal (dBm) - `signal_strength` - Intensidad de senal (dBm)
--- ---
## Credenciales ## Datos en Base de Datos
### Usuario Admin
- **Nombre:** Ivan Alcaraz
- **Email:** ialcarazsalazar@consultoria-as.com
- **Password:** Aasi940812
---
## Datos Actuales en BD
### Proyectos ### Proyectos
- ADAMANT - ADAMANT
@@ -152,98 +230,65 @@ Columnas opcionales:
--- ---
## Correcciones Recientes (2026-01-23) ## Historial de Correcciones
### 1. Error `.toFixed()` con valores string ### 2026-01-23: Fix pantalla blanca y carga masiva
**Problema:** PostgreSQL devuelve DECIMAL como string, causando error al llamar `.toFixed()`. 1. **Fix `.toFixed()` con strings** - PostgreSQL devuelve DECIMAL como string. Se envuelve con `Number()`.
**Solución:** Convertir a número con `Number()` antes de llamar `.toFixed()`. 2. **Fix modal de carga masiva** - Separar recarga de datos del cierre del modal.
**Archivos:** 3. **Fix fechas invalidas en carga masiva** - Validacion de formato con regex + mapeos de columnas + normalizacion de status.
- `src/pages/meters/MetersTable.tsx:75`
- `src/pages/consumption/ConsumptionPage.tsx:133, 213, 432`
### 2. Modal de carga masiva se cerraba sin mostrar resultados ### 2026-02-03: Dark mode, Analytics, Conectores, CSV Upload
**Problema:** El modal se cerraba automáticamente después de la carga. - Implementacion completa de dark mode con paleta Zinc
**Solución:** El modal ahora permanece abierto para mostrar resultados y errores. - Seccion Analytics: mapa, reportes, servidor
**Archivo:** `src/pages/meters/MeterPage.tsx:332-340` - Seccion Conectores: SH-Meters, XMeters, TTS
- Toggle dark/light theme
- Panel CSV para carga masiva
- Nuevos tipos de medidor: LORA, LORAWAN, GRANDES CONSUMIDORES
- Documentacion completa del proyecto
### 3. Validación de fechas en carga masiva ### 2026-02-04: Favicon y conectores
**Problema:** Valores como "Installed" en columnas no mapeadas causaban error de fecha inválida. - Actualizacion de favicon
**Solución:** Validar que `installation_date` sea realmente una fecha antes de insertarla. - Mejoras en tiempo de ultima conexion de conectores
**Archivo:** `water-api/src/services/bulk-upload.service.ts:183-195` - Plan de implementacion para rol ORGANISMOS_OPERADORES
### 4. Mapeo de columnas mejorado ### 2026-02-05: Sincronizacion de conectores
**Mejora:** Agregados más mapeos de columnas comunes (device_status, device_name, etc.) - Cambio de hora de sincronizacion de 2:00 AM a 9:00 AM
**Archivo:** `water-api/src/services/bulk-upload.service.ts:65-90`
### 5. Normalización de status
**Mejora:** Valores como "Installed", "New_LoRa" se convierten automáticamente a "ACTIVE".
**Archivo:** `water-api/src/services/bulk-upload.service.ts:210-225`
--- ---
## Comandos Útiles ## Comandos Utiles
```bash ```bash
# Iniciar backend # Iniciar backend (desarrollo)
cd /home/GRH/water-project/water-api cd /home/GRH/water-project/water-api
npm run dev npm run dev
# Iniciar frontend # Iniciar frontend (desarrollo)
cd /home/GRH/water-project cd /home/GRH/water-project
npm run dev npm run dev
# Compilar backend # Iniciar upload panel (desarrollo)
cd /home/GRH/water-project/upload-panel
npm run dev
# Compilar backend para produccion
cd /home/GRH/water-project/water-api cd /home/GRH/water-project/water-api
npm run build && npm run start
# Compilar frontend para produccion
cd /home/GRH/water-project
npm run build npm run build
# Ver logs del backend # Ejecutar schema de base de datos
tail -f /tmp/water-api.log psql -d water_project -f water-api/sql/schema.sql
``` ```
--- ---
## Estructura de Archivos ## Proximos Pasos Sugeridos
``` 1. **Rol ORGANISMOS_OPERADORES** - Implementar nuevo rol segun plan existente
water-project/ 2. **Reportes PDF** - Generacion y descarga de reportes en PDF
├── src/ # Frontend React 3. **Tests** - Suite de tests con Vitest (frontend) y Supertest (backend)
│ ├── api/ # Cliente API 4. **CI/CD** - Pipeline de integracion continua
│ │ ├── client.ts # Cliente HTTP con JWT 5. **Docker** - Containerizacion del proyecto completo
│ │ ├── meters.ts # API de medidores
│ │ ├── readings.ts # API de lecturas
│ │ ├── projects.ts # API de proyectos
│ │ └── concentrators.ts # API de concentradores
│ ├── pages/ # Páginas
│ │ ├── meters/ # Módulo de medidores
│ │ │ ├── MeterPage.tsx
│ │ │ ├── MetersTable.tsx
│ │ │ ├── MetersModal.tsx
│ │ │ ├── MetersSidebar.tsx
│ │ │ ├── MetersBulkUploadModal.tsx
│ │ │ └── useMeters.ts
│ │ ├── consumption/ # Módulo de consumo
│ │ │ ├── ConsumptionPage.tsx
│ │ │ └── ReadingsBulkUploadModal.tsx
│ │ └── ...
│ └── components/ # Componentes reutilizables
└── water-api/ # Backend Node.js
├── src/
│ ├── controllers/ # Controladores REST
│ ├── services/ # Lógica de negocio
│ │ ├── bulk-upload.service.ts
│ │ └── ...
│ ├── routes/ # Definición de rutas
│ ├── middleware/ # Middlewares (auth, etc.)
│ └── config/ # Configuración (DB, etc.)
└── sql/ # Scripts SQL
```
---
## Próximos Pasos Sugeridos
1. **Integración TTS** - Webhooks para The Things Stack
2. **Alertas automáticas** - Notificaciones por consumo anormal
3. **Reportes** - Generación de reportes PDF
4. **Despliegue** - Configurar para producción

590
README.md
View File

@@ -1,23 +1,55 @@
# Water Project - Sistema de Gestion de Recursos Hidricos (GRH) # GRH - Sistema de Gestion de Recursos Hidricos
Sistema de gestion y monitoreo de infraestructura hidrica desarrollado con React, TypeScript y Vite. 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 ## Descripcion General
El **Sistema de Gestion de Recursos Hidricos (GRH)** es una aplicacion web frontend disenada para el monitoreo, administracion y control de infraestructura de toma de agua. Permite gestionar medidores, concentradores, proyectos, usuarios y roles a traves de una interfaz moderna y responsiva. El **Sistema GRH** es una aplicacion web completa para organismos operadores de agua (CESPT Tijuana, Tecate, Mexicali, etc.) que incluye:
### Caracteristicas Principales - **Dashboard interactivo** con KPIs, graficos y alertas
- **Gestion de Medidores** - CRUD completo con carga masiva Excel/CSV
- **Dashboard interactivo** con KPIs, alertas e historial de actividades
- **Gestion de Medidores (Tomas de Agua)** - CRUD completo con filtros por proyecto
- **Gestion de Concentradores** - Configuracion de gateways LoRa/LoRaWAN - **Gestion de Concentradores** - Configuracion de gateways LoRa/LoRaWAN
- **Gestion de Proyectos** - Administracion de proyectos de infraestructura - **Gestion de Proyectos** - Administracion de proyectos de infraestructura
- **Gestion de Usuarios y Roles** - Control de acceso al sistema - **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 - **Tema claro/oscuro** - Personalizacion de la interfaz
- **Diseno responsive** - Compatible con desktop, tablet y movil - **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 ## Stack Tecnologico
### Frontend ### Frontend
@@ -27,13 +59,26 @@ El **Sistema de Gestion de Recursos Hidricos (GRH)** es una aplicacion web front
| TypeScript | 5.2.2 | Type safety | | TypeScript | 5.2.2 | Type safety |
| Vite | 5.2.0 | Build tool y dev server | | Vite | 5.2.0 | Build tool y dev server |
| Tailwind CSS | 4.1.18 | Estilos utility-first | | Tailwind CSS | 4.1.18 | Estilos utility-first |
| Material-UI | 7.3.6 | Componentes UI | | 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 | | 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 | | Lucide React | 0.559.0 | Iconos SVG |
### Herramientas de Desarrollo ### Backend
- **ESLint** - Linting de codigo | Tecnologia | Version | Proposito |
- **TypeScript ESLint** - Analisis estatico |------------|---------|-----------|
| 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 |
--- ---
@@ -42,334 +87,357 @@ El **Sistema de Gestion de Recursos Hidricos (GRH)** es una aplicacion web front
### Prerrequisitos ### Prerrequisitos
- Node.js >= 18.x - Node.js >= 18.x
- npm >= 9.x o yarn >= 1.22 - npm >= 9.x
- PostgreSQL >= 14.x
### Pasos de Instalacion ### 1. Clonar el repositorio
1. **Clonar el repositorio**
```bash ```bash
git clone <url-del-repositorio> git clone https://git.consultoria-as.com/consultoria-as/GRH.git
cd water-project cd GRH
``` ```
2. **Instalar dependencias** ### 2. Configurar la base de datos
```bash ```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 npm install
``` ```
3. **Configurar variables de entorno** ### 4. Configurar el frontend
```bash ```bash
cd ..
cp .env.example .env cp .env.example .env
# Editar .env con la URL del backend
npm install
``` ```
Editar el archivo `.env`: ### 5. Iniciar en desarrollo
```env
VITE_API_BASE_URL=https://tu-api-url.com
VITE_API_TOKEN=tu-token-de-api
```
4. **Iniciar servidor de desarrollo**
```bash ```bash
# Terminal 1 - Backend
cd water-api
npm run dev
# Terminal 2 - Frontend
cd ..
npm run dev npm run dev
``` ```
La aplicacion estara disponible en `http://localhost:5173` 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 ## Scripts Disponibles
### Frontend
| Comando | Descripcion | | Comando | Descripcion |
|---------|-------------| |---------|-------------|
| `npm run dev` | Inicia el servidor de desarrollo | | `npm run dev` | Servidor de desarrollo (puerto 5173) |
| `npm run build` | Compila TypeScript y genera build de produccion | | `npm run build` | Compilar TypeScript + build de produccion |
| `npm run preview` | Previsualiza el build de produccion | | `npm run preview` | Previsualizar build de produccion |
| `npm run lint` | Ejecuta ESLint en el codigo | | `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 ## Estructura del Proyecto
``` ```
water-project/ GRH/
├── public/ # Assets estaticos ├── src/ # Frontend React SPA
── grhWatermark.jpg ── api/ # Cliente API (14 modulos)
│ ├── client.ts # Cliente HTTP con JWT y refresh automatico
├── src/ │ │ ├── auth.ts # Autenticacion y gestion de tokens
│ ├── api/ # Capa de comunicacion con API
│ │ ├── me.ts # Endpoints de perfil
│ │ ├── meters.ts # CRUD de medidores │ │ ├── meters.ts # CRUD de medidores
│ │ ├── concentrators.ts # CRUD de concentradores │ │ ├── readings.ts # Lecturas de consumo
│ │ ── projects.ts # CRUD de proyectos │ │ ── 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/ │ ├── components/ # Componentes reutilizables
│ │ ├── layout/ # Componentes de layout │ │ ├── layout/
│ │ │ ├── Sidebar.tsx # Menu lateral │ │ │ ├── Sidebar.tsx # Menu lateral (colapsable, pin)
│ │ │ ├── TopMenu.tsx # Barra superior │ │ │ ├── TopMenu.tsx # Barra superior con breadcrumb
│ │ │ └── common/ # Componentes reutilizables │ │ │ └── common/
│ │ │ ├── ProfileModal.tsx │ │ │ ├── ProfileModal.tsx # Editar perfil y avatar
│ │ │ ├── ConfirmModal.tsx │ │ │ ├── ConfirmModal.tsx # Confirmacion de acciones
│ │ │ ── Watermark.tsx │ │ │ ── Watermark.tsx # Marca de agua GRH
│ │ └── SettingsModals.tsx │ │ │ └── ProjectBadge.tsx # Badge de proyecto
│ │ ├── SettingsModals.tsx # Configuracion de tema/UI
│ │ └── NotificationDropdown.tsx # Panel de notificaciones
│ │ │ │
│ ├── pages/ # Paginas principales │ ├── pages/
│ │ ├── Home.tsx # Dashboard │ │ ├── Home.tsx # Dashboard con KPIs y graficos
│ │ ├── LoginPage.tsx # Login │ │ ├── LoginPage.tsx # Inicio de sesion
│ │ ├── UsersPage.tsx # Gestion de usuarios │ │ ├── UsersPage.tsx # Gestion de usuarios
│ │ ├── RolesPage.tsx # Gestion de roles │ │ ├── RolesPage.tsx # Gestion de roles
│ │ ├── AuditoriaPage.tsx # Visor de logs de auditoria
│ │ ├── projects/ │ │ ├── projects/
│ │ │ └── ProjectsPage.tsx │ │ │ └── ProjectsPage.tsx
│ │ ├── meters/ # Modulo de medidores │ │ ├── meters/ # Modulo de medidores
│ │ │ ├── MeterPage.tsx │ │ │ ├── MeterPage.tsx
│ │ │ ├── useMeters.ts # Hook personalizado
│ │ │ ├── MetersTable.tsx │ │ │ ├── MetersTable.tsx
│ │ │ ├── MetersModal.tsx │ │ │ ├── MetersModal.tsx
│ │ │ ── MetersSidebar.tsx │ │ │ ── MetersSidebar.tsx
│ │ └── concentrators/ # Modulo de concentradores │ │ │ ├── MetersBulkUploadModal.tsx
│ │ ── ConcentratorsPage.tsx │ │ ── useMeters.ts
│ │ ├── useConcentrators.ts │ │ ├── concentrators/ # Modulo de concentradores
│ │ ├── ConcentratorsTable.tsx │ │ ├── ConcentratorsPage.tsx
│ │ ├── ConcentratorsModal.tsx │ │ ├── ConcentratorsTable.tsx
│ │ ── ConcentratorsSidebar.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
│ │ │ │
│ ├── assets/ │ ├── hooks/
│ │ └── images/ │ │ └── useNotifications.ts
├── App.tsx # Componente raiz (routing + auth)
│ ├── App.tsx # Componente raiz │ ├── main.tsx # Punto de entrada React
── main.tsx # Punto de entrada ── index.css # Estilos globales (Tailwind)
│ └── index.css # Estilos globales
├── index.html ├── water-api/ # Backend Express API
├── package.json │ ├── src/
├── tsconfig.json │ │ ├── index.ts # Setup del servidor Express
├── vite.config.ts │ │ ├── config/
└── .env.example │ │ │ ├── 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
``` ```
--- ---
## Modulos Funcionales ## Base de Datos
### 1. Dashboard (Home) ### Jerarquia de datos
```
Projects → Concentrators → Meters → Readings
→ Gateways → Devices ↗
```
El dashboard principal ofrece: ### Tablas principales
- Selector de organismos operadores (CESPT TIJUANA, TECATE, MEXICALI)
- Grafico de barras: "Numero de Medidores por Proyecto"
- Tarjetas de acceso rapido: Tomas, Alertas, Mantenimiento, Reportes
- Historial reciente de actividades
- Panel de ultimas alertas
### 2. Gestion de Medidores | 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 |
Modulo completo para administrar medidores/tomas de agua: ### Vistas
- `meter_stats_by_project` - Estadisticas agregadas de medidores por proyecto
**Funcionalidades:** - `device_status_summary` - Resumen de estados de dispositivos por proyecto
- Listado con busqueda y filtros
- Filtrado por proyecto
- Tipos de toma: GENERAL, LORA, LORAWAN, GRANDES
- CRUD completo (Crear, Leer, Actualizar, Eliminar)
**Campos principales:**
- Area, Numero de cuenta, Usuario, Direccion
- Serial del medidor, Nombre, Estado
- Tipo de protocolo, Particion DMA
- Configuracion de dispositivo (Device EUI, AppKey, etc.)
### 3. Gestion de Concentradores
Administracion de concentradores y gateways:
**Funcionalidades:**
- Listado con filtros por proyecto
- Configuracion de Gateway (ID, EUI, Nombre)
- Seleccion de ubicacion de antena (Indoor/Outdoor)
- CRUD completo
### 4. Gestion de Proyectos
Administracion de proyectos de infraestructura:
- Tabla con busqueda integrada
- Estados: ACTIVE/INACTIVE
- Informacion de operador y tiempos
### 5. Gestion de Usuarios
Control de usuarios del sistema:
- Listado de usuarios
- Asignacion de roles
- Estados: ACTIVE/INACTIVE
### 6. Gestion de Roles
Administracion de roles de acceso:
- Roles predefinidos: SUPER_ADMIN, USER
- Descripcion de permisos
--- ---
## API y Comunicacion ## API Endpoints
### Configuracion Todos los endpoints estan bajo el prefijo `/api/`. La mayoria requieren autenticacion JWT.
La aplicacion se conecta a una API REST externa. Configurar en `.env`: | Grupo | Prefijo | Descripcion |
|-------|---------|-------------|
```env | Auth | `/api/auth` | Login, refresh, logout, perfil |
VITE_API_BASE_URL=https://tu-api.com | Projects | `/api/projects` | CRUD de proyectos + estadisticas |
VITE_API_TOKEN=tu-token | Meters | `/api/meters` | CRUD de medidores + lecturas |
``` | Meter Types | `/api/meter-types` | Tipos de medidor |
| Concentrators | `/api/concentrators` | CRUD de concentradores |
### Endpoints Principales | Gateways | `/api/gateways` | CRUD de gateways + dispositivos |
| Devices | `/api/devices` | CRUD de dispositivos LoRaWAN |
| Recurso | Endpoint Base | | Users | `/api/users` | Gestion de usuarios (admin) |
|---------|---------------| | Roles | `/api/roles` | Gestion de roles |
| Medidores | `/api/v3/data/.../m4hzpnopjkppaav/records` | | Readings | `/api/readings` | Lecturas y resumen de consumo |
| Concentradores | `/api/v3/data/.../mheif1vdgnyt8x2/records` | | Notifications | `/api/notifications` | Notificaciones del usuario |
| Proyectos | `/api/v3/data/.../m9882vn3xb31e29/records` | | Audit | `/api/audit-logs` | Logs de auditoria (admin) |
| Bulk Upload | `/api/bulk-upload` | Carga masiva Excel |
### Estructura de Respuesta | CSV Upload | `/api/csv-upload` | Carga masiva CSV |
| TTS Webhooks | `/api/webhooks/tts` | Webhooks The Things Stack |
```typescript | System | `/api/system` | Metricas y salud del servidor (admin) |
interface ApiResponse<T> {
records: Array<{
id: string;
fields: T;
}>;
next?: string;
prev?: string;
}
```
---
## Modelos de Datos
### Meter (Medidor)
```typescript
interface Meter {
id: string;
createdAt: string;
updatedAt: string;
areaName: string;
accountNumber: string | null;
userName: string | null;
userAddress: string | null;
meterSerialNumber: string;
meterName: string;
meterStatus: string;
protocolType: string;
priceNo: string | null;
priceName: string | null;
dmaPartition: string | null;
supplyTypes: string;
deviceId: string;
deviceName: string;
deviceType: string;
usageAnalysisType: string;
installedTime: string;
}
```
### Concentrator
```typescript
interface Concentrator {
id: string;
"Area Name": string;
"Device S/N": string;
"Device Name": string;
"Device Time": string;
"Device Status": string;
"Operator": string;
"Installed Time": string;
"Communication Time": string;
"Instruction Manual": string;
}
```
### Project
```typescript
interface Project {
id: string;
areaName: string;
deviceSN: string;
deviceName: string;
deviceType: string;
deviceStatus: "ACTIVE" | "INACTIVE";
operator: string;
installedTime: string;
communicationTime: string;
}
```
--- ---
## Autenticacion ## Autenticacion
### Flujo de Login El sistema usa **JWT con refresh tokens**:
1. Usuario ingresa credenciales 1. El usuario envia email/password a `POST /api/auth/login`
2. Validacion del checkbox "No soy un robot" 2. El backend valida credenciales con bcrypt y genera:
3. Token almacenado en `localStorage` (`grh_auth`) - **Access token** (15 minutos)
4. Redireccion al Dashboard - **Refresh token** (7 dias)
3. Los tokens se almacenan en `localStorage`
4. El cliente HTTP envia el access token en `Authorization: Bearer <token>`
5. Al expirar, el cliente automaticamente llama a `POST /api/auth/refresh`
### Almacenamiento ### Roles y permisos
| Rol | Descripcion |
```javascript |-----|-------------|
// localStorage keys | `ADMIN` | Acceso completo al sistema |
grh_auth: { token: string, ts: number } | `OPERATOR` | Gestiona proyectos, dispositivos, medidores (sin configuracion del sistema) |
water_project_settings_v1: { theme: string, compactMode: boolean } | `VIEWER` | Solo lectura de datos y reportes |
```
---
## Configuracion de Temas
El sistema soporta tres modos de tema:
- **Sistema** - Detecta preferencia del OS
- **Claro** - Tema light
- **Oscuro** - Tema dark
Configuracion persistida en `localStorage` bajo `water_project_settings_v1`.
--- ---
## Despliegue ## Despliegue
### Build de Produccion ### Build de produccion
```bash ```bash
npm run build # Frontend
npm run build # Genera dist/
# Backend
cd water-api
npm run build # Genera dist/
npm run start # Ejecuta el build
``` ```
Los archivos compilados se generan en la carpeta `dist/`. ### URLs de produccion
- **Frontend:** `https://sistema.gestionrecursoshidricos.com`
### Configuracion de Vite - **Backend:** `https://api.gestionrecursoshidricos.com`
El servidor de desarrollo esta configurado para:
- Puerto: 5173
- Host: habilitado para acceso remoto
- Hosts permitidos: localhost, 127.0.0.1, dominios personalizados
--- ---
## Contribucion ## Repositorios
1. Fork del repositorio | Remote | URL |
2. Crear rama feature (`git checkout -b feature/nueva-funcionalidad`) |--------|-----|
3. Commit de cambios (`git commit -m 'Agregar nueva funcionalidad'`) | Gitea | `https://git.consultoria-as.com/consultoria-as/GRH` |
4. Push a la rama (`git push origin feature/nueva-funcionalidad`) | GitHub | `git@github.com:luanngel/water-project.git` |
5. Crear Pull Request
--- ---
## Licencia ## Licencia
Este proyecto es privado y pertenece a GRH - Gestion de Recursos Hidricos. Este proyecto es privado y pertenece a GRH - Gestion de Recursos Hidricos / Consultoria AS.
---
## Contacto
Para soporte o consultas sobre el sistema, contactar al equipo de desarrollo.