Commit Graph
149 Commits
Author SHA1 Message Date
Lizandro Guarnizo c05a2a8137 up 2026-06-03 21:32:50 -05:00
Lizandro Guarnizo f087fd46f1 up 2026-06-03 20:10:22 -05:00
Lizandro Guarnizo 1e1ba682b0 up 2026-06-02 15:41:20 -05:00
Lizandro Guarnizo c5603c51f8 up 2026-06-02 13:27:45 -05:00
Lizandro Guarnizo 28d0eae715 up 2026-06-02 13:13:29 -05:00
Lizandro Guarnizo ba76754331 up 2026-06-02 10:35:37 -05:00
Lizandro Guarnizo 06d85dc0bf up 2026-05-27 10:16:28 -05:00
Lizandro Guarnizo 36c9e0a6d5 up 2026-05-26 21:55:48 -05:00
Lizandro Guarnizo d8f38a6669 up 2026-05-26 21:28:35 -05:00
Lizandro Guarnizo 7a374340c1 up 2026-05-26 20:54:10 -05:00
Lizandro GuarnizoandCopilot 39f4641540 fix: agrega coma faltante en método openAppDeployments del componente Alpine
El objeto Alpine.js tenía un } sin coma al final de openAppDeployments,
causando un error de sintaxis JS que impedía la inicialización del componente
y hacía que la página /app/coolify apareciera completamente en blanco.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-26 14:20:55 -05:00
Lizandro Guarnizo 553252508f up 2026-05-26 14:06:38 -05:00
Lizandro Guarnizo e9548e13ae up 2026-05-26 11:42:41 -05:00
Lizandro Guarnizo d1a668e229 Update coolify.html 2026-05-26 11:36:38 -05:00
Lizandro Guarnizo 304aa33a99 Update coolify.html 2026-05-26 10:12:07 -05:00
Lizandro Guarnizo a489844c73 up 2026-05-26 10:05:01 -05:00
Lizandro Guarnizo 6bcbe58a9a Merge branch 'copilot/vcard-api-integraciones-anlisis' 2026-05-25 22:04:25 -05:00
Lizandro GuarnizoandCopilot 0f386ad456 fix: botones start/stop/restart usan POST; agrega webhook Coolify
- 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>
2026-05-25 22:04:25 -05:00
Lizandro GuarnizoandCopilot ce2ffff3e8 feat: add missing Coolify controller, view and routes
- 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>
2026-05-25 21:01:58 -05:00
Lizandro Guarnizo 467c3f5e3a Merge branch 'copilot/vcard-api-integraciones-anlisis' 2026-05-25 20:21:19 -05:00
Lizandro GuarnizoandCopilot 5373cebf9c fix: coolify_configs table missing + miniwebs real status
- Add coolify_config.go model (missing from worktree branch)
- Add CoolifyConfig to normal-startup AutoMigrate → creates table on next start
- Fix miniwebs tab: m.activo is not in API response; fallback to
  vcard.estado (true/false) to show real status instead of always Inactiva
- Improve miniwebs row: show url, user name, vcard status badge

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-25 20:20:50 -05:00
Lizandro Guarnizo c30abb58a6 Update vcard_api.html 2026-05-25 15:47:18 -05:00
Lizandro Guarnizo c82831702e up 2026-05-25 15:14:04 -05:00
Lizandro Guarnizo c46b1317af Update vcard_api.html 2026-05-25 14:58:45 -05:00
Lizandro Guarnizo 497cda97d5 Update vcard_api.html 2026-05-25 14:49:24 -05:00
Lizandro Guarnizo 03c6e74bd6 up 2026-05-25 14:37:59 -05:00
Lizandro Guarnizo 471b2f50c6 up 2026-05-25 14:27:27 -05:00
Lizandro Guarnizo 58d98f23aa Revert "telegram"
This reverts commit 46daf3d4aa.
2026-05-25 12:50:53 -05:00
Lizandro Guarnizo 46daf3d4aa telegram 2026-05-25 10:08:40 -05:00
Lizandro Guarnizo b714fa71ac Merge branch 'copilot/vcard-api-integraciones-anlisis' 2026-05-23 08:59:17 -05:00
Lizandro GuarnizoandCopilot 661e02ef9c feat: desactivar usuario + VCards desde tab usuarios
- Botón '🚫 + VCards' abre modal de confirmación
- Modal carga y lista las VCards activas del usuario
- Al confirmar: inactiva cada VCard (PUT estado:false) y desactiva el usuario
- Muestra resumen del resultado antes de cerrar
- Botón 'Ordenar por vencimiento' con colores en filas (rojo/amarillo/verde)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-23 08:57:18 -05:00
Lizandro Guarnizo fb67a308dc Update telegram.html 2026-05-22 00:17:00 -05:00
Lizandro Guarnizo c21fab079d Update telegram.html 2026-05-22 00:03:06 -05:00
Lizandro Guarnizo 1a96caeb83 ip 2026-05-21 23:49:37 -05:00
Lizandro Guarnizo d121f399ed up 2026-05-21 22:52:24 -05:00
Lizandro Guarnizo 0cf7c6d279 up 2026-05-21 22:37:31 -05:00
Lizandro GuarnizoandCopilot 4fec04e5fe fix: inicializar users/roles en Alpine y null-safety en loadRegister
- Declara users:[] y roles:[] en el estado inicial de Alpine para que
  x-for funcione reactivamente desde el primer render
- Agrega totalPages:0 al estado inicial
- Añade comprobación response.ok antes de parsear JSON
- Usa || [] y || 0 para evitar TypeError si el backend retorna error
- Reemplaza data.Users.length con this.users.length (siempre array)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 12:30:08 -05:00
Lizandro GuarnizoandCopilot 6cca8e6fcd fix: reactividad Alpine ping — estado en cx directamente
Alpine v3 NO puede rastrear accesos dinámicos pingCargando[cx.ID]
dentro de x-for porque no sabe qué key observar por item.

Solución: estado de ping embebido en cada objeto cx:
- abrirModal inyecta _pingCargando:false y _pingResultado:null en cada cx
- hacerPing muta cx._pingCargando / cx._pingResultado directamente
- template usa cx._pingCargando y cx._pingResultado (proxy reactivo del x-for)

Esto garantiza que el spinner, el botón deshabilitado y el resultado
del ping se actualicen correctamente para cada card.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 12:06:00 -05:00
Lizandro GuarnizoandCopilot 2779c0a15d 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>
2026-05-21 11:56:12 -05:00
Lizandro GuarnizoandCopilot d9d3f8a5eb feat: sistema de agente ligero para monitoreo de servidores
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>
2026-05-21 11:29:24 -05:00
Lizandro GuarnizoandCopilot f52e266527 fix: corregir ping - mutación directa y manejo de cx.ID || cx.id
- Cambia spread+reassign por mutación directa (this.pingCargando[id] = true)
  para garantizar reactividad correcta en Alpine.js 3.x
- Usa (cx.ID || cx.id) en toda la plantilla para compatibilidad con
  ambos formatos de serialización JSON de GORM
- Agrega type="button" y @click.stop en el botón de verificar
- Maneja respuestas HTTP no-OK con mensaje de error explícito
- Muestra mensaje de error real del catch en la UI

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 11:07:39 -05:00
Lizandro GuarnizoandCopilot 194db3e9ed fix: mejorar UX del ping en servidor_dashboard
- Mueve el resultado del ping directamente bajo los datos de la BD
- Muestra mensaje de error cuando falla la conexión (usa campo error del backend)
- Spinner y texto 'Probando...' durante la espera
- Resultado verde/rojo inline con ✓/✗ y tiempo/mensaje de error
- Etiqueta del botón cambia a 'Verificar' (más descriptivo que 'Ping')

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 10:48:40 -05:00
Lizandro GuarnizoandCopilot b4b60810a1 feat(prov_servidor): add many2many integrations linking
- ProvServidor model: add Integraciones []Submodules (many2many:prov_servidor_submodules)
- GetAllProvServidor: preload Integraciones
- SetProvServidorIntegraciones: new model func to replace associations
- New endpoint PUT /app/provservidor/:id/integraciones
- GetSubmodules: support ?limit= query param
- prov_servidor.html: show integrations as badges in table, view modal,
  and edit modal with checkboxes to select one or more existing submodules

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 10:34:01 -05:00
Lizandro GuarnizoandCopilot c834e40e83 fix(servidor-dashboard): show DB connection count on server cards
- GetServidor: query conx_count per server with GROUP BY and attach to response
- servidor_dashboard.html: use conx_count from API (fallback to _conexiones.length)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 10:25:18 -05:00
Lizandro GuarnizoandCopilot 4cb564890d feat(conx_db): complete edit/add modals with nombre, estado, version fields
- Edit modal: added Nombre, Versión, Estado (select) fields
- Add modal: added Nombre, Versión, Estado (select) fields
- loadData() JS mapping: includes nombre, estado, version
- updateItem() payload: sends nombre, estado, version to backend

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 10:14:40 -05:00
Lizandro GuarnizoandCopilot 03ccc75337 Fix servidor dashboard: correct all field names to match models
All fields were using wrong names (Go struct names instead of JSON tags):
- servidor.Nombre → servidor.nombre
- servidor.IP → servidor.ip_servidor
- servidor.TipoServidor → servidor.tipo_servidor
- servidor.ProvServidor → servidor.prov_servidor
- servidor.Ram → servidor.ram
- servidor.CPU → servidor.nucleos (correct field)
- servidor.Almacenamiento → servidor.disco
- servidor.SO → servidor.so
- servidor.FechaExpiracion → servidor.vencimiento
- servidor.Activo → removed (field does not exist)
- servidor.Descripcion → removed (field does not exist)

For ConxDb:
- conexion.Nombre → removed (field does not exist)
- conexion.Host → conexion.servidor.ip_servidor (from preloaded relation)
- conexion.Puerto → conexion.puerto
- conexion.Usuario → conexion.usuario
- conexion.TipoDb → conexion.tipo_db
- conexion.Estado → removed (field does not exist)
- conexion.Version → removed (field does not exist)

Also improved UI: loading skeleton, better card layout, ping badges inline.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 10:07:06 -05:00
Lizandro GuarnizoandCopilot 7d02add55e Fix dashboard URLs: remove /api prefix from fetch calls
Routes are registered under /app (web group), not /api/app.
The requests were hitting the JWT-protected API group causing 'Invalid Attempt' error.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 09:58:21 -05:00
Lizandro GuarnizoandCopilot d1e56c8bd8 Add debug logging to servidor list
- Added console.log statements to track data loading
- Better error messages with emojis and details
- Shows count of servidores, proveedores, tipos loaded
- Helps diagnose if data is not loading

This will help identify if:
- API endpoint is working
- Data is being returned
- Frontend is processing it correctly

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 09:22:03 -05:00
Lizandro GuarnizoandCopilot 29820c8706 Add Servidor Dashboard with connection monitoring
- Created servidor_dashboard.html with beautiful visual dashboard
- Shows all servers in grid cards with basic info
- Click button opens detailed modal with:
  - Server full information (IP, CPU, RAM, Storage, OS, Expiration)
  - All connected databases in a clean diagram layout
  - Database connection status (active/inactive)
  - Connection details (Host, Port, User, Type)
  - Ping button to test connection with response time
  - View Connection button to open query-runner
- Backend updates:
  - Added ServidorDashboard() controller to render the dashboard view
  - Added GetServidorDashboard() API endpoint to fetch server + connections
  - Added PingConexion() endpoint to test database connections (TCP + DB test)
  - Color-coded status badges and database type indicators
  - Responsive design for mobile and desktop
- Routes:
  - GET /app/servidor-dashboard (render view)
  - GET /api/app/servidor-dashboard/:id (get server details API)
  - GET /api/app/conx-ping/:id (ping connection endpoint)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 08:49:18 -05:00
Lizandro GuarnizoandCopilot 63d124215b feat(query-runner): soporte completo Redis
Backend:
- Agrega github.com/redis/go-redis/v9 como dependencia
- isRedisDriver() detecta 'redis' y 'valkey' en nombre del tipo de BD
- redisConnect(): abre cliente Redis con auth, host, port, db index
- redisTestConnection(): PING para probar conexión
- redisListDatabases(): lee CONFIG GET databases → devuelve db0..dbN
- redisListKeys(): SCAN iterativo, hasta 200 keys del db seleccionado
- redisExecuteCommand(): parsea comandos línea a línea, multi-comando
  devuelve tabla command/result/error; comando único devuelve QueryResult
  tipado (string, int64, []any para KEYS/SMEMBERS/LRANGE, HGETALL como
  field/value table)
- redisParseArgs(): tokenizador respetando comillas simples y dobles
- Todos los comandos se guardan en query_history

Frontend:
- isRedis: false estado y reset en onConxChange()
- Detecta redis/valkey en tipo_db.nombre
- Editor cambia label 'Redis CLI', placeholder con ejemplos Redis
- Sidebar: 'Keys' en lugar de 'Tablas' para Redis
- insertTable(): TYPE + TTL + GET para inspeccionar una key de Redis
- Panel de chips rojos: KEYS *, DBSIZE, INFO, CONFIG GET, CLIENT LIST, SLOWLOG
- Generador Redis: select de 24 comandos + formulario contextual
  (key, value, ttl, field según el comando elegido)
- generateRedisCmd(): genera el comando en el editor
- Badge MySQL no aparece cuando es Redis

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-20 21:07:33 -05:00