Fix: Corregir pantalla blanca y mejorar carga masiva
- Fix error .toFixed() con valores DECIMAL de PostgreSQL (string vs number) - Fix modal de carga masiva que se cerraba sin mostrar resultados - Validar fechas antes de insertar en BD (evita error con "Installed") - Agregar mapeos de columnas comunes (device_status, device_name, etc.) - Normalizar valores de status (Installed -> ACTIVE, New_LoRa -> ACTIVE) - Actualizar documentación del proyecto Archivos modificados: - src/pages/meters/MetersTable.tsx - src/pages/consumption/ConsumptionPage.tsx - src/pages/meters/MeterPage.tsx - water-api/src/services/bulk-upload.service.ts - ESTADO_ACTUAL.md - CAMBIOS_SESION.md Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
365
ESTADO_ACTUAL.md
365
ESTADO_ACTUAL.md
@@ -1,7 +1,7 @@
|
||||
# Estado Actual del Proyecto Water Project
|
||||
# Estado Actual del Proyecto Water Project GRH
|
||||
|
||||
**Fecha:** 2026-01-23
|
||||
**Última sesión:** Migración de NocoDB a PostgreSQL + Node.js/Express
|
||||
**Última actualización:** Corrección de errores y mejoras en carga masiva
|
||||
|
||||
---
|
||||
|
||||
@@ -19,145 +19,165 @@ Projects → Concentrators → Meters → Readings
|
||||
|
||||
---
|
||||
|
||||
## Lo que se implementó
|
||||
## Arquitectura del Sistema
|
||||
|
||||
### 1. Backend API completo (`water-api/`)
|
||||
- Autenticación JWT con refresh tokens
|
||||
- CRUD completo para: Projects, Concentrators, Meters, Readings, Users, Roles
|
||||
- Carga masiva de medidores y lecturas via Excel
|
||||
- Endpoints de resumen/estadísticas
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ FRONTEND (React) │
|
||||
│ http://localhost:5173 │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ - React 18 + TypeScript + Vite │
|
||||
│ - Tailwind CSS + Material-UI │
|
||||
│ - Recharts para gráficos │
|
||||
│ - Cliente API con JWT automático │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ BACKEND (Node.js) │
|
||||
│ http://localhost:3000 │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ - Express + TypeScript │
|
||||
│ - Autenticación JWT con refresh tokens │
|
||||
│ - CRUD completo para todas las entidades │
|
||||
│ - Carga masiva via Excel (xlsx) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ BASE DE DATOS │
|
||||
│ PostgreSQL │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ Tablas: users, roles, projects, concentrators, │
|
||||
│ meters, meter_readings, refresh_tokens │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 2. Frontend adaptado
|
||||
- Cliente API con manejo automático de JWT (`src/api/client.ts`)
|
||||
- Transformación automática snake_case ↔ camelCase
|
||||
- Páginas: Home, Meters, Consumption, Projects, Users, Roles
|
||||
---
|
||||
|
||||
### 3. Carga Masiva
|
||||
- **Medidores:** Subir Excel con columnas: `serial_number`, `name`, `concentrator_serial`, `location`, `type`, `status`
|
||||
- **Lecturas:** Subir Excel con columnas: `meter_serial`, `reading_value`, `reading_type`, `battery_level`, `signal_strength`, `received_at`
|
||||
## Funcionalidades Implementadas
|
||||
|
||||
### 4. Credenciales actualizadas
|
||||
- **Usuario admin:** Ivan Alcaraz
|
||||
### 1. Autenticación
|
||||
- Login con JWT + refresh tokens
|
||||
- Manejo automático de renovación de tokens
|
||||
- Roles: ADMIN, USER
|
||||
|
||||
### 2. Gestión de Proyectos
|
||||
- CRUD completo
|
||||
- Estados: ACTIVE/INACTIVE
|
||||
|
||||
### 3. Gestión de Concentradores
|
||||
- CRUD completo
|
||||
- Vinculados a proyectos
|
||||
- Tipos: Gateway LoRa/LoRaWAN
|
||||
|
||||
### 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. Gestión de Lecturas (Consumo)
|
||||
- CRUD completo
|
||||
- Tipos: AUTOMATIC, MANUAL, SCHEDULED
|
||||
- **Carga masiva via Excel**
|
||||
- Filtros por proyecto, fecha
|
||||
- Exportación a CSV
|
||||
- Indicadores de batería y señal
|
||||
|
||||
### 6. Dashboard
|
||||
- KPIs: Total lecturas, medidores activos, consumo promedio
|
||||
- Gráficos por proyecto
|
||||
- Últimas alertas
|
||||
|
||||
---
|
||||
|
||||
## Carga Masiva
|
||||
|
||||
### Medidores (Excel)
|
||||
Columnas requeridas:
|
||||
- `serial_number` - Número de serie del medidor (único)
|
||||
- `name` - Nombre del medidor
|
||||
- `concentrator_serial` - Serial del concentrador existente
|
||||
|
||||
Columnas opcionales:
|
||||
- `meter_id` - ID del medidor
|
||||
- `location` - Ubicación
|
||||
- `type` - LORA, LORAWAN, GRANDES (default: LORA)
|
||||
- `status` - ACTIVE, INACTIVE, etc. (default: ACTIVE)
|
||||
- `installation_date` - Fecha de instalación (YYYY-MM-DD)
|
||||
|
||||
### Lecturas (Excel)
|
||||
Columnas requeridas:
|
||||
- `meter_serial` - Serial del medidor existente
|
||||
- `reading_value` - Valor de la lectura
|
||||
|
||||
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)
|
||||
|
||||
---
|
||||
|
||||
## Credenciales
|
||||
|
||||
### Usuario Admin
|
||||
- **Nombre:** Ivan Alcaraz
|
||||
- **Email:** ialcarazsalazar@consultoria-as.com
|
||||
- **Password:** Aasi940812
|
||||
|
||||
---
|
||||
|
||||
## Problema Actual: Pantalla en Blanco
|
||||
## Datos Actuales en BD
|
||||
|
||||
### Síntoma
|
||||
Al entrar a "Water Meters" o "Consumo", la pantalla se queda en blanco.
|
||||
### Proyectos
|
||||
- ADAMANT
|
||||
- OLE
|
||||
- LUZIA
|
||||
- ATELIER
|
||||
|
||||
### Causa identificada
|
||||
El cliente API (`src/api/client.ts`) fue modificado para manejar respuestas paginadas. Cuando el backend devuelve:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": [...],
|
||||
"pagination": {...}
|
||||
}
|
||||
```
|
||||
### Concentradores
|
||||
| Serial | Nombre | Proyecto |
|
||||
|--------|--------|----------|
|
||||
| 2024072612 | Adamant | ADAMANT |
|
||||
| 2024030601 | OLE | OLE |
|
||||
| 2024030402 | LUZIA | LUZIA |
|
||||
| 2024072602 | ATELIER | ATELIER |
|
||||
|
||||
El cliente ahora devuelve `{ data: [...], pagination: {...} }` en lugar de solo el array.
|
||||
|
||||
### Archivos modificados para manejar esto:
|
||||
1. ✅ `src/api/client.ts` - Detecta si hay `pagination` y devuelve el objeto completo
|
||||
2. ✅ `src/api/meters.ts` - Ya manejaba respuestas paginadas
|
||||
3. ✅ `src/api/readings.ts` - Ya manejaba respuestas paginadas
|
||||
4. ✅ `src/api/projects.ts` - Actualizado para manejar paginación
|
||||
5. ✅ `src/api/concentrators.ts` - Actualizado para manejar paginación
|
||||
|
||||
### Cambios en interfaces de readings.ts:
|
||||
- Eliminado `deviceId` (no existe en BD)
|
||||
- Cambiado `areaName` por `meterLocation`
|
||||
- Agregado `concentratorId`, `concentratorName`, `projectName`
|
||||
|
||||
### Cambios en ConsumptionPage.tsx:
|
||||
- Cambiado `areaName` por `meterLocation` en todas las referencias
|
||||
- Cambiado header de tabla "Área" por "Ubicación"
|
||||
### Medidores
|
||||
- ADAMANT: 201 medidores
|
||||
- OLE: 5 medidores
|
||||
|
||||
---
|
||||
|
||||
## Para Continuar Debugging
|
||||
## Correcciones Recientes (2026-01-23)
|
||||
|
||||
### 1. Verificar que los APIs funcionan
|
||||
```bash
|
||||
# Projects
|
||||
curl http://localhost:3000/api/projects
|
||||
### 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`
|
||||
|
||||
# Meters (requiere auth)
|
||||
curl http://localhost:3000/api/meters?pageSize=2
|
||||
### 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`
|
||||
|
||||
# Readings
|
||||
curl http://localhost:3000/api/readings?pageSize=2
|
||||
```
|
||||
### 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`
|
||||
|
||||
### 2. Ver errores en el navegador
|
||||
1. Abrir la aplicación en http://localhost:5173
|
||||
2. Abrir DevTools (F12)
|
||||
3. Ir a la pestaña "Console"
|
||||
4. Navegar a "Water Meters" o "Consumo"
|
||||
5. Copiar el error que aparezca
|
||||
### 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`
|
||||
|
||||
### 3. Posibles causas adicionales
|
||||
Si el error persiste, verificar:
|
||||
|
||||
a) **Error de transformación de datos:**
|
||||
- El `transformArray` puede estar recibiendo undefined
|
||||
- Verificar en `src/api/readings.ts` línea ~120
|
||||
|
||||
b) **Error en componentes React:**
|
||||
- Algún componente puede estar accediendo a propiedades que no existen
|
||||
- Verificar `src/pages/consumption/ConsumptionPage.tsx`
|
||||
- Verificar `src/pages/meters/MeterPage.tsx`
|
||||
|
||||
c) **Problema con el cliente API:**
|
||||
- El `parseResponse` en `src/api/client.ts` línea ~211
|
||||
- Verificar que la detección de pagination funcione correctamente
|
||||
|
||||
### 4. Test rápido del cliente
|
||||
Agregar console.log temporal en `src/api/client.ts`:
|
||||
```typescript
|
||||
// En la función parseResponse, después de línea 221
|
||||
console.log('API Response:', data);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Estructura de Archivos Clave
|
||||
|
||||
```
|
||||
water-project/
|
||||
├── src/
|
||||
│ ├── api/
|
||||
│ │ ├── client.ts # Cliente HTTP con JWT
|
||||
│ │ ├── readings.ts # API de lecturas
|
||||
│ │ ├── meters.ts # API de medidores
|
||||
│ │ ├── projects.ts # API de proyectos
|
||||
│ │ └── concentrators.ts # API de concentradores
|
||||
│ ├── pages/
|
||||
│ │ ├── meters/
|
||||
│ │ │ ├── MeterPage.tsx
|
||||
│ │ │ ├── useMeters.ts # Hook para cargar datos
|
||||
│ │ │ └── ...
|
||||
│ │ └── consumption/
|
||||
│ │ ├── ConsumptionPage.tsx
|
||||
│ │ └── ReadingsBulkUploadModal.tsx
|
||||
│ └── ...
|
||||
├── water-api/
|
||||
│ ├── src/
|
||||
│ │ ├── controllers/
|
||||
│ │ │ ├── reading.controller.ts
|
||||
│ │ │ ├── meter.controller.ts
|
||||
│ │ │ └── bulk-upload.controller.ts
|
||||
│ │ ├── services/
|
||||
│ │ │ ├── reading.service.ts
|
||||
│ │ │ ├── meter.service.ts
|
||||
│ │ │ └── bulk-upload.service.ts
|
||||
│ │ └── routes/
|
||||
│ └── ...
|
||||
└── ESTADO_ACTUAL.md (este archivo)
|
||||
```
|
||||
### 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`
|
||||
|
||||
---
|
||||
|
||||
@@ -172,83 +192,58 @@ npm run dev
|
||||
cd /home/GRH/water-project
|
||||
npm run dev
|
||||
|
||||
# Verificar TypeScript (ignorar TS6133 - variables no usadas)
|
||||
cd /home/GRH/water-project
|
||||
npx tsc --noEmit 2>&1 | grep -v "TS6133"
|
||||
# Compilar backend
|
||||
cd /home/GRH/water-project/water-api
|
||||
npm run build
|
||||
|
||||
# Ver logs del backend
|
||||
tail -f /tmp/water-api.log
|
||||
|
||||
# Conectar a PostgreSQL
|
||||
psql -U postgres -d water_project
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Esquema de Base de Datos Relevante
|
||||
## Estructura de Archivos
|
||||
|
||||
### Tabla `meter_readings`
|
||||
```sql
|
||||
- id (UUID)
|
||||
- meter_id (UUID, FK → meters)
|
||||
- reading_value (DECIMAL)
|
||||
- reading_type (VARCHAR) -- AUTOMATIC, MANUAL, SCHEDULED
|
||||
- battery_level (SMALLINT, nullable)
|
||||
- signal_strength (SMALLINT, nullable)
|
||||
- raw_payload (TEXT, nullable)
|
||||
- received_at (TIMESTAMP)
|
||||
- created_at (TIMESTAMP)
|
||||
```
|
||||
|
||||
**NOTA:** La columna `device_id` NO EXISTE en esta tabla. Fue removida del código.
|
||||
|
||||
### Respuesta del API `/api/readings`
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"id": "...",
|
||||
"meter_id": "...",
|
||||
"reading_value": "300.0000",
|
||||
"reading_type": "MANUAL",
|
||||
"battery_level": null,
|
||||
"signal_strength": null,
|
||||
"raw_payload": null,
|
||||
"received_at": "2026-01-23T21:07:28.726Z",
|
||||
"created_at": "2026-01-23T21:07:28.726Z",
|
||||
"meter_serial_number": "24300001",
|
||||
"meter_name": "D307_IB-113107",
|
||||
"meter_location": null,
|
||||
"concentrator_id": "...",
|
||||
"concentrator_name": "Adamant",
|
||||
"project_id": "...",
|
||||
"project_name": "ADAMANT"
|
||||
}
|
||||
],
|
||||
"pagination": {
|
||||
"page": 1,
|
||||
"pageSize": 100,
|
||||
"total": 206,
|
||||
"totalPages": 3
|
||||
}
|
||||
}
|
||||
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. **Resolver pantalla blanca** - Obtener el error específico de la consola del navegador
|
||||
2. **Probar carga masiva** - Una vez que las páginas funcionen
|
||||
3. **Integración TTS** - Webhooks para The Things Stack (pendiente)
|
||||
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
|
||||
|
||||
---
|
||||
|
||||
## Contacto del Plan Original
|
||||
|
||||
El plan completo de migración está en:
|
||||
```
|
||||
/home/GRH/.claude/plans/peaceful-napping-bumblebee.md
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user