Agrega POST /api/sms/send autenticado con Bearer token (secret_key
auto-generado en WebSmsConfig). Recibe numero y mensaje, llama a
LabsMobile y registra el resultado en websms_log.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- CoolifyApplicationStart/Stop/Restart cambian GET → POST (Coolify API requiere POST)
- Nuevo endpoint público POST /webhooks/coolify para recibir notificaciones
de deployment/restart desde Coolify Settings → Notifications → Webhook
- UI: muestra URL del webhook en modal de config para fácil copia
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Cambia StatusBadGateway (502) → StatusBadRequest (400) en todos los
errores del proxy Coolify. Cloudflare intercepta respuestas 502 del
origen y muestra su propia pantalla, ocultando el error al frontend.
Con 400, el JSON de error llega al cliente y Alpine.js puede mostrarlo.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- rest/controllers/coolify_controller.go: proxy completo hacia API Coolify
- resources/views/coolify.html: interfaz Alpine.js con tabs apps/servers/services/dbs/projects/deployments/team
- rest/routes/user.go: registra todas las rutas /app/coolify/*
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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>
- Cross-compila usite-agent para linux/amd64, linux/arm64, linux/arm
Binarios en agent/dist/ (CGO_ENABLED=0, stripped ~6MB c/u)
- GET /agent/download/:filename sirve el binario correcto
con Content-Disposition attachment y validación anti path-traversal
- install.sh ya apunta a /agent/download/usite-agent-linux-ARCH
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Backend:
- Servidor model: AgentToken, AgentLastSeen, MetricasJson nuevos campos
- AgentHeartbeat: endpoint público POST /agent/heartbeat (auth por token)
- GenerateAgentToken: endpoint protegido POST /app/servidor/:id/agent-token
- Ruta pública /agent/install.sh sirve el script de instalación
Agente Go (agent/):
- agent/main.go: binario independiente con gopsutil
- Recolecta RAM, CPU, Disco, Uptime, OS, Load average
- Lee agent.yml o flags --api-url / --token
- Envía POST a /agent/heartbeat cada N segundos
- Instala como servicio systemd via install.sh
- agent/go.mod: módulo independiente (usite-agent)
- agent/agent.yml.sample: configuración de ejemplo
- agent/install.sh: instalador en 1 curl para Linux (systemd)
Frontend servidor_dashboard.html:
- Cards: badge ● En línea / ● Fuera / ○ Sin agente
- Barras de progreso live: RAM%, CPU%, Disco%
- Valores: GB usado/total, núcleos, uptime, OS real
- Tiempo desde último reporte
- Botón 'Agente' en cada card → modal de configuración
- Modal agente: estado, token con copy, comando curl 1 línea,
instalación manual/avanzada con collapse, métricas actuales
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>