- 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>
172 lines
4.6 KiB
Markdown
172 lines
4.6 KiB
Markdown
# Cambios Realizados - Sesión 2026-01-23
|
|
|
|
## Resumen
|
|
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
|
|
|
|
### 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()`.
|
|
|
|
### Archivos Modificados
|
|
|
|
**`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)
|
|
```
|
|
|
|
---
|
|
|
|
## Problema 2: Modal de Carga Masiva se Cerraba sin Mostrar Resultados
|
|
|
|
### 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.
|
|
|
|
### 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();
|
|
}}
|
|
/>
|
|
```
|
|
|
|
---
|
|
|
|
## Problema 3: Error de Fecha Inválida en Carga Masiva
|
|
|
|
### Síntoma
|
|
Al subir medidores, aparecía el error:
|
|
```
|
|
Fila X: invalid input syntax for type date: "Installed"
|
|
```
|
|
|
|
### 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 en Esta Sesión
|
|
|
|
| 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 |
|
|
|
|
---
|
|
|
|
## 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
|