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:
@@ -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
|
|
||||||
|
|||||||
969
DOCUMENTATION.md
969
DOCUMENTATION.md
File diff suppressed because it is too large
Load Diff
327
ESTADO_ACTUAL.md
327
ESTADO_ACTUAL.md
@@ -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
|
|
||||||
|
|||||||
598
README.md
598
README.md
@@ -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
|
│ │ ├── meters.ts # CRUD de medidores
|
||||||
│ │ ├── me.ts # Endpoints de perfil
|
│ │ ├── readings.ts # Lecturas de consumo
|
||||||
│ │ ├── meters.ts # CRUD de medidores
|
│ │ ├── projects.ts # Proyectos
|
||||||
│ │ ├── concentrators.ts # CRUD de concentradores
|
│ │ ├── concentrators.ts # Concentradores
|
||||||
│ │ └── projects.ts # CRUD de proyectos
|
│ │ ├── 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.
|
|
||||||
|
|||||||
Reference in New Issue
Block a user