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
Corrección de errores críticos que causaban pantalla blanca y mejoras en el sistema de carga masiva.
Registro cronologico de cambios significativos realizados al proyecto.
---
## Problema 1: Pantalla Blanca en Water Meters y Consumo
## 2026-02-09: Actualizacion de documentacion
### Síntoma
Al navegar a "Water Meters" o "Consumo", la página se quedaba en blanco.
### 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()`.
### Resumen
Actualizacion completa de los 4 archivos de documentacion para reflejar el estado real del proyecto.
### 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)**
```typescript
// 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)
```
### Motivo
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.
---
## Problema 2: Modal de Carga Masiva se Cerraba sin Mostrar Resultados
## 2026-02-05: Sincronizacion de conectores
### Síntoma
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
Cambio de hora de sincronizacion de conectores de 2:00 AM a 9:00 AM.
### Causa
El callback `onSuccess` cerraba el modal automáticamente:
```typescript
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();
}}
/>
```
### Archivos Modificados (2)
- `src/pages/conectores/SHMetersPage.tsx`
- `src/pages/conectores/XMetersPage.tsx`
---
## Problema 3: Error de Fecha Inválida en Carga Masiva
## 2026-02-04: Favicon y conectores
### Síntoma
Al subir medidores, aparecía el error:
```
Fila X: invalid input syntax for type date: "Installed"
```
### Cambios
- Actualizacion de favicon del sistema
- Mejoras en la visualizacion de tiempo de ultima conexion en paginas de conectores
- Agregado plan de implementacion para rol ORGANISMOS_OPERADORES
### Causa
El archivo Excel tenía columnas con valores como "Installed" o "New_LoRa" que el sistema interpretaba como fechas porque no estaban mapeadas correctamente.
### Solución
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 (4+1)
- Favicon actualizado
- Paginas de conectores actualizadas
- `PLAN_ORGANISMOS_OPERADORES.md` (plan de implementacion)
---
## 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 |
|---------|--------|
| `src/pages/meters/MetersTable.tsx` | Fix `.toFixed()` en lastReadingValue |
| `src/pages/consumption/ConsumptionPage.tsx` | Fix `.toFixed()` en readingValue y avgReading |
| `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 |
| `ESTADO_ACTUAL.md` | Documentación actualizada |
| `CAMBIOS_SESION.md` | Este archivo |
| `water-api/src/services/bulk-upload.service.ts` | Validacion de fechas, mapeos, normalizacion |
---
## Verificación
1. ✅ La página de Water Meters carga correctamente
2. ✅ La página de Consumo carga correctamente
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
### Verificacion
- La pagina de Water Meters carga correctamente
- La pagina de Consumo carga correctamente
- El modal de carga masiva muestra resultados
- Errores de carga masiva se muestran claramente
- 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
**Última actualización:** Corrección de errores y mejoras en carga masiva
**Fecha:** 2026-02-09
**Ultima actualizacion:** Documentacion actualizada para reflejar el estado completo del proyecto
---
## Resumen del Proyecto
Sistema de gestión de medidores de agua con:
- **Frontend:** React + TypeScript + Vite (puerto 5173)
Sistema full-stack de gestion de medidores de agua con:
- **Frontend:** React 18 + TypeScript + Vite (puerto 5173)
- **Backend:** Node.js + Express + TypeScript (puerto 3000)
- **Base de datos:** PostgreSQL
- **Upload Panel:** App separada para carga CSV masiva
### Jerarquía de datos:
### Jerarquia de datos:
```
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
```
┌─────────────────────────────────────────────────────────────┐
│ FRONTEND (React)
│ FRONTEND (React SPA)
│ http://localhost:5173 │
├─────────────────────────────────────────────────────────────┤
- React 18 + TypeScript + Vite │
- Tailwind CSS + Material-UI
- Recharts para gráficos
- Cliente API con JWT automático
└─────────────────────────────────────────────────────────────┘
│ React 18 + TypeScript + Vite
│ Tailwind CSS (paleta Zinc) + Material-UI 7
│ Recharts (graficos) + Leaflet (mapas)
│ Cliente API con JWT + refresh automatico │
│ Dark mode / Light mode / System │
└──────────────────────────┬──────────────────────────────────┘
│ REST API + JWT Bearer
┌─────────────────────────────────────────────────────────────┐
│ BACKEND (Node.js) │
│ BACKEND (Express) │
│ http://localhost:3000 │
├─────────────────────────────────────────────────────────────┤
- Express + TypeScript
- Autenticación JWT con refresh tokens │
- CRUD completo para todas las entidades
- Carga masiva via Excel (xlsx)
└─────────────────────────────────────────────────────────────┘
│ Express + TypeScript + Zod (validacion)
JWT access (15m) + refresh (7d) tokens
17 archivos de rutas, 18 servicios
Helmet, CORS, Bcrypt, Winston logging
│ node-cron (deteccion flujo negativo) │
│ Multer + XLSX (carga masiva) │
│ Webhooks TTS (The Things Stack / LoRaWAN) │
└──────────────────────────┬──────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ BASE DE DATOS │
│ PostgreSQL │
├─────────────────────────────────────────────────────────────┤
Tablas: users, roles, projects, concentrators,
meters, meter_readings, refresh_tokens
10 tablas: roles, users, projects, concentrators, │
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
### 1. Autenticación
- Login con JWT + refresh tokens
- Manejo automático de renovación de tokens
- Roles: ADMIN, USER
### 1. Autenticacion y Autorizacion
- Login con JWT: access token (15 min) + refresh token (7 dias)
- Refresh automatico de tokens en el cliente (cola de peticiones)
- 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
- Estados: ACTIVE/INACTIVE
- Estados: ACTIVE, INACTIVE, COMPLETED
- Estadisticas por proyecto (medidores, lecturas, areas)
### 3. Gestión de Concentradores
### 4. Gestion de Concentradores
- CRUD completo
- Vinculados a proyectos
- Tipos: Gateway LoRa/LoRaWAN
- Estado: ACTIVE, INACTIVE, OFFLINE, MAINTENANCE, ERROR
- IP, firmware, ultima comunicacion
### 4. Gestión de Medidores
- CRUD completo
- Tipos: LORA, LORAWAN, GRANDES
- Estados: ACTIVE, INACTIVE, MAINTENANCE, FAULTY, REPLACED
- **Carga masiva via Excel**
- Última lectura visible en tabla
### 5. Gestion de Medidores
- CRUD completo con tabla, sidebar de detalle y modal de edicion
- Tipos de medidor: WATER, GAS, ELECTRIC
- Protocolos: GENERAL, LORA, LORAWAN
- Estados: ACTIVE, INACTIVE, OFFLINE, MAINTENANCE, ERROR
- 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)
- CRUD completo
### 6. Consumo y Lecturas
- CRUD de lecturas
- Tipos: AUTOMATIC, MANUAL, SCHEDULED
- **Carga masiva via Excel**
- Filtros por proyecto, fecha
- Exportación a CSV
- Indicadores de batería y señal
- Carga masiva via Excel y CSV
- Filtros por proyecto, medidor, rango de fechas
- Resumen de consumo (total, promedio, min, max)
- Indicadores de bateria y senal
- Exportacion
### 6. Dashboard
- KPIs: Total lecturas, medidores activos, consumo promedio
- Gráficos por proyecto
- Últimas alertas
### 7. Analytics
- **Mapa:** Visualizacion de medidores con coordenadas en mapa Leaflet interactivo
- **Reportes:** Dashboard de estadisticas y reportes de consumo
- **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
### Medidores (Excel)
### Medidores (Excel / CSV)
Columnas requeridas:
- `serial_number` - Número de serie del medidor (único)
- `serial_number` - Numero de serie del medidor (unico)
- `name` - Nombre del medidor
- `concentrator_serial` - Serial del concentrador existente
Columnas opcionales:
- `meter_id` - ID del medidor
- `location` - Ubicación
- `location` - Ubicacion
- `type` - LORA, LORAWAN, GRANDES (default: LORA)
- `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:
- `meter_serial` - Serial del medidor existente
- `reading_value` - Valor de la lectura
@@ -116,21 +203,12 @@ Columnas requeridas:
Columnas opcionales:
- `reading_type` - AUTOMATIC, MANUAL, SCHEDULED (default: MANUAL)
- `received_at` - Fecha/hora (default: ahora)
- `battery_level` - Nivel de batería (%)
- `signal_strength` - Intensidad de señal (dBm)
- `battery_level` - Nivel de bateria (%)
- `signal_strength` - Intensidad de senal (dBm)
---
## Credenciales
### Usuario Admin
- **Nombre:** Ivan Alcaraz
- **Email:** ialcarazsalazar@consultoria-as.com
- **Password:** Aasi940812
---
## Datos Actuales en BD
## Datos en Base de Datos
### Proyectos
- ADAMANT
@@ -152,98 +230,65 @@ Columnas opcionales:
---
## Correcciones Recientes (2026-01-23)
## Historial de Correcciones
### 1. Error `.toFixed()` con valores string
**Problema:** PostgreSQL devuelve DECIMAL como string, causando error al llamar `.toFixed()`.
**Solución:** Convertir a número con `Number()` antes de llamar `.toFixed()`.
**Archivos:**
- `src/pages/meters/MetersTable.tsx:75`
- `src/pages/consumption/ConsumptionPage.tsx:133, 213, 432`
### 2026-01-23: Fix pantalla blanca y carga masiva
1. **Fix `.toFixed()` con strings** - PostgreSQL devuelve DECIMAL como string. Se envuelve con `Number()`.
2. **Fix modal de carga masiva** - Separar recarga de datos del cierre del modal.
3. **Fix fechas invalidas en carga masiva** - Validacion de formato con regex + mapeos de columnas + normalizacion de status.
### 2. Modal de carga masiva se cerraba sin mostrar resultados
**Problema:** El modal se cerraba automáticamente después de la carga.
**Solución:** El modal ahora permanece abierto para mostrar resultados y errores.
**Archivo:** `src/pages/meters/MeterPage.tsx:332-340`
### 2026-02-03: Dark mode, Analytics, Conectores, CSV Upload
- Implementacion completa de dark mode con paleta Zinc
- Seccion Analytics: mapa, reportes, servidor
- 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
**Problema:** Valores como "Installed" en columnas no mapeadas causaban error de fecha inválida.
**Solución:** Validar que `installation_date` sea realmente una fecha antes de insertarla.
**Archivo:** `water-api/src/services/bulk-upload.service.ts:183-195`
### 2026-02-04: Favicon y conectores
- Actualizacion de favicon
- Mejoras en tiempo de ultima conexion de conectores
- Plan de implementacion para rol ORGANISMOS_OPERADORES
### 4. Mapeo de columnas mejorado
**Mejora:** Agregados más mapeos de columnas comunes (device_status, device_name, etc.)
**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`
### 2026-02-05: Sincronizacion de conectores
- Cambio de hora de sincronizacion de 2:00 AM a 9:00 AM
---
## Comandos Útiles
## Comandos Utiles
```bash
# Iniciar backend
# Iniciar backend (desarrollo)
cd /home/GRH/water-project/water-api
npm run dev
# Iniciar frontend
# Iniciar frontend (desarrollo)
cd /home/GRH/water-project
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
npm run build && npm run start
# Compilar frontend para produccion
cd /home/GRH/water-project
npm run build
# Ver logs del backend
tail -f /tmp/water-api.log
# Ejecutar schema de base de datos
psql -d water_project -f water-api/sql/schema.sql
```
---
## Estructura de Archivos
## Proximos Pasos Sugeridos
```
water-project/
├── src/ # Frontend React
│ ├── api/ # Cliente API
│ │ ├── client.ts # Cliente HTTP con JWT
│ │ ├── 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
1. **Rol ORGANISMOS_OPERADORES** - Implementar nuevo rol segun plan existente
2. **Reportes PDF** - Generacion y descarga de reportes en PDF
3. **Tests** - Suite de tests con Vitest (frontend) y Supertest (backend)
4. **CI/CD** - Pipeline de integracion continua
5. **Docker** - Containerizacion del proyecto completo

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
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, alertas e historial de actividades
- **Gestion de Medidores (Tomas de Agua)** - CRUD completo con filtros por proyecto
- **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
- **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
- **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
@@ -27,13 +59,26 @@ El **Sistema de Gestion de Recursos Hidricos (GRH)** es una aplicacion web front
| 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 | 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 |
| Leaflet / React-Leaflet | 1.9.4 / 4.2.1 | Mapas interactivos |
| Lucide React | 0.559.0 | Iconos SVG |
### Herramientas de Desarrollo
- **ESLint** - Linting de codigo
- **TypeScript ESLint** - Analisis estatico
### 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 |
---
@@ -42,334 +87,357 @@ El **Sistema de Gestion de Recursos Hidricos (GRH)** es una aplicacion web front
### Prerrequisitos
- 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
git clone <url-del-repositorio>
cd water-project
git clone https://git.consultoria-as.com/consultoria-as/GRH.git
cd GRH
```
2. **Instalar dependencias**
### 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
```
3. **Configurar variables de entorno**
### 4. Configurar el frontend
```bash
cd ..
cp .env.example .env
# Editar .env con la URL del backend
npm install
```
Editar el archivo `.env`:
```env
VITE_API_BASE_URL=https://tu-api-url.com
VITE_API_TOKEN=tu-token-de-api
```
### 5. Iniciar en desarrollo
4. **Iniciar servidor de desarrollo**
```bash
# Terminal 1 - Backend
cd water-api
npm run dev
# Terminal 2 - Frontend
cd ..
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
### Frontend
| Comando | Descripcion |
|---------|-------------|
| `npm run dev` | Inicia el servidor de desarrollo |
| `npm run build` | Compila TypeScript y genera build de produccion |
| `npm run preview` | Previsualiza el build de produccion |
| `npm run lint` | Ejecuta ESLint en el codigo |
| `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
```
water-project/
├── public/ # Assets estaticos
── grhWatermark.jpg
├── src/
│ ├── api/ # Capa de comunicacion con API
│ │ ├── me.ts # Endpoints de perfil
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
│ │ ├── concentrators.ts # CRUD de concentradores
│ │ ── projects.ts # CRUD de proyectos
│ │ ├── 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/
│ │ ├── layout/ # Componentes de layout
│ │ │ ├── Sidebar.tsx # Menu lateral
│ │ │ ├── TopMenu.tsx # Barra superior
│ │ │ └── common/ # Componentes reutilizables
│ │ │ ├── ProfileModal.tsx
│ │ │ ├── ConfirmModal.tsx
│ │ │ ── Watermark.tsx
│ │ └── SettingsModals.tsx
│ ├── 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/ # Paginas principales
│ │ ├── Home.tsx # Dashboard
│ │ ├── LoginPage.tsx # Login
│ ├── 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
│ │ │ ├── useMeters.ts # Hook personalizado
│ │ │ ├── MetersTable.tsx
│ │ │ ├── MetersModal.tsx
│ │ │ ── MetersSidebar.tsx
│ │ └── concentrators/ # Modulo de concentradores
│ │ ── ConcentratorsPage.tsx
│ │ ├── useConcentrators.ts
│ │ ├── ConcentratorsTable.tsx
│ │ ├── ConcentratorsModal.tsx
│ │ ── ConcentratorsSidebar.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
│ │
│ ├── assets/
│ │ └── images/
│ ├── App.tsx # Componente raiz
── main.tsx # Punto de entrada
│ └── index.css # Estilos globales
│ ├── hooks/
│ │ └── useNotifications.ts
├── App.tsx # Componente raiz (routing + auth)
│ ├── main.tsx # Punto de entrada React
── index.css # Estilos globales (Tailwind)
├── index.html
├── package.json
├── tsconfig.json
├── vite.config.ts
└── .env.example
├── 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
```
---
## Modulos Funcionales
## Base de Datos
### 1. Dashboard (Home)
### Jerarquia de datos
```
Projects → Concentrators → Meters → Readings
→ Gateways → Devices ↗
```
El dashboard principal ofrece:
- 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
### Tablas principales
### 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:
**Funcionalidades:**
- 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
### Vistas
- `meter_stats_by_project` - Estadisticas agregadas de medidores por proyecto
- `device_status_summary` - Resumen de estados de dispositivos por proyecto
---
## 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`:
```env
VITE_API_BASE_URL=https://tu-api.com
VITE_API_TOKEN=tu-token
```
### Endpoints Principales
| Recurso | Endpoint Base |
|---------|---------------|
| Medidores | `/api/v3/data/.../m4hzpnopjkppaav/records` |
| Concentradores | `/api/v3/data/.../mheif1vdgnyt8x2/records` |
| Proyectos | `/api/v3/data/.../m9882vn3xb31e29/records` |
### Estructura de Respuesta
```typescript
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;
}
```
| 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
### Flujo de Login
El sistema usa **JWT con refresh tokens**:
1. Usuario ingresa credenciales
2. Validacion del checkbox "No soy un robot"
3. Token almacenado en `localStorage` (`grh_auth`)
4. Redireccion al Dashboard
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 <token>`
5. Al expirar, el cliente automaticamente llama a `POST /api/auth/refresh`
### Almacenamiento
```javascript
// localStorage keys
grh_auth: { token: string, ts: number }
water_project_settings_v1: { theme: string, compactMode: boolean }
```
---
## 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`.
### 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
### Build de produccion
```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/`.
### Configuracion de Vite
El servidor de desarrollo esta configurado para:
- Puerto: 5173
- Host: habilitado para acceso remoto
- Hosts permitidos: localhost, 127.0.0.1, dominios personalizados
### URLs de produccion
- **Frontend:** `https://sistema.gestionrecursoshidricos.com`
- **Backend:** `https://api.gestionrecursoshidricos.com`
---
## Contribucion
## Repositorios
1. Fork del repositorio
2. Crear rama feature (`git checkout -b feature/nueva-funcionalidad`)
3. Commit de cambios (`git commit -m 'Agregar nueva funcionalidad'`)
4. Push a la rama (`git push origin feature/nueva-funcionalidad`)
5. Crear Pull Request
| 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.
---
## Contacto
Para soporte o consultas sobre el sistema, contactar al equipo de desarrollo.
Este proyecto es privado y pertenece a GRH - Gestion de Recursos Hidricos / Consultoria AS.