Files
GRH/CAMBIOS_SESION.md
Exteban08 6c7d448b2f 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>
2026-01-23 23:13:48 +00:00

4.6 KiB

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)

// 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)

// 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:

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)

// 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):

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):

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):

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