fix: ping real de BD + campo Host en ConxDb + reactividad Alpine

Problema raíz:
1. El ping TCP usaba Servidor.IpServidor → fallaba si la BD solo escucha
   en localhost del servidor remoto (comportamiento normal en producción)
2. La reactividad Alpine v3.13 no detectaba keys nuevas en objeto vacío {}
   dentro de x-for loops, spinner nunca aparecía

Cambios:
- pkg/models/conx_db.go: nuevo campo Host (vacío = usa Servidor.IpServidor)
  + método HostEfectivo() como fuente única de verdad para host
- pkg/services/query_runner_service.go: todos los puntos (openDynamicDB,
  openDynamicDBWithName, redisConnect, mongoURI) usan c.HostEfectivo()
- rest/controllers/servidor_controller.go: PingConexion reescrito —
  primero prueba conexión real a la BD (no solo TCP), si falla prueba TCP,
  devuelve host+puerto testeado y mensajes de error descriptivos
- servidor_dashboard.html: hacerPing usa spread-replace para forzar
  reactividad + $nextTick, resultado muestra host:puerto testeado y
  mensaje de error completo en múltiples líneas

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Lizandro Guarnizo
2026-05-21 11:56:12 -05:00
co-authored by Copilot
parent c3f19991c9
commit 2779c0a15d
4 changed files with 73 additions and 51 deletions
+34 -30
View File
@@ -235,7 +235,6 @@ func PingConexion(c *fiber.Ctx) error {
})
}
// Obtener conexión de BD
var conexion models.ConxDb
db := app.Http.Database.DB
if err := db.Preload("TipoDb").Preload("Servidor").First(&conexion, uid).Error; err != nil {
@@ -245,41 +244,46 @@ func PingConexion(c *fiber.Ctx) error {
})
}
// Realizar ping a la conexión
host := conexion.HostEfectivo()
puerto := conexion.Puerto
// Primero intentar conexión real a la BD (más fiable que solo TCP)
inicio := time.Now()
exitoso := false
var tiempoMs int64
testErr := services.TestDBConnection(conexion)
if testErr == nil {
return c.JSON(fiber.Map{
"exitoso": true,
"tiempo": time.Since(inicio).Milliseconds(),
"host": host,
"puerto": puerto,
"tipo": conexion.TipoDb.Nombre,
"error": "",
})
}
// Intentar conexión TCP
addr := fmt.Sprintf("%s:%s", conexion.Servidor.IpServidor, conexion.Puerto)
conn, err := net.DialTimeout("tcp", addr, 2*time.Second)
if err == nil {
// Si la BD no conecta, probar al menos TCP (puerto abierto)
tcpAddr := fmt.Sprintf("%s:%s", host, puerto)
inicioTCP := time.Now()
conn, errTCP := net.DialTimeout("tcp", tcpAddr, 3*time.Second)
if errTCP == nil {
conn.Close()
exitoso = true
tiempoMs = time.Since(inicio).Milliseconds()
}
// Si falla TCP, intentar con la BD específica
if !exitoso {
inicio = time.Now()
testErr := services.TestDBConnection(conexion)
if testErr == nil {
exitoso = true
tiempoMs = time.Since(inicio).Milliseconds()
}
}
errorMsg := ""
if !exitoso {
errorMsg = fmt.Sprintf("No se pudo conectar a %s:%s", conexion.Servidor.IpServidor, conexion.Puerto)
return c.JSON(fiber.Map{
"exitoso": false,
"tiempo": time.Since(inicioTCP).Milliseconds(),
"host": host,
"puerto": puerto,
"tipo": conexion.TipoDb.Nombre,
// Puerto abierto pero la BD rechaza la conexión
"error": fmt.Sprintf("Puerto %s abierto pero la BD no responde: %s", puerto, testErr.Error()),
})
}
return c.JSON(fiber.Map{
"exitoso": exitoso,
"tiempo": tiempoMs,
"host": conexion.Servidor.IpServidor,
"puerto": conexion.Puerto,
"exitoso": false,
"tiempo": int64(0),
"host": host,
"puerto": puerto,
"tipo": conexion.TipoDb.Nombre,
"error": errorMsg,
"error": fmt.Sprintf("No se puede alcanzar %s:%s — verifica que el host sea accesible desde este servidor. Tip: si el DB solo escucha en localhost del servidor, configura el campo 'Host' de la conexión.", host, puerto),
})
}