Commit Graph
198 Commits
Author SHA1 Message Date
Lizandro GD 40dfaf5773 Agrega API Keys scoped (token + IP obligatoria + alcance) para /api/v2
Alternativa al ADMIN_API_KEY único de entorno, que sigue funcionando
como llave maestra para no romper integraciones existentes.

- Modelo ApiKey: token hasheado, IP/CIDR obligatoria (fail-closed sin
  IP), scopes habilitados, último uso (fecha + IP).
- AdminApiAuth() acepta ahora tanto la llave maestra como una ApiKey;
  nuevo middleware RequireScope(scope) para gatear grupos de rutas.
- Fase 1: scopes aplicados a lo más sensible — oss (archivos),
  query_runner (SQL arbitrario), usuarios (usuarios/roles/módulos),
  pasarelas (credenciales de pago). El resto de /api/v2 sigue con
  la llave maestra hasta una fase 2.
- Panel /app/api-keys: crear/editar/revocar, token visible solo al
  crear, scopes por checkbox, IP obligatoria.
2026-08-10 16:33:57 +00:00
Lizandro GD 21d8cd5260 Agrega diagrama de relaciones (FK) al Query Runner
- GetSchemaRelations: trae todas las llaves foráneas de la base con
  consulta específica por motor (Postgres/MySQL/MSSQL/SQLite). No
  aplica a Redis/Mongo (schemaless).
- Endpoint GET /query-runner/relations, con el mismo chequeo de
  autorización por conexión que ya usa RunQuery — de paso se lo
  agrego también a GetDatabases/GetTables, que no lo tenían.
- UI: botón "Ver relaciones" (diagrama completo) y un ícono por tabla
  en el árbol lateral (relaciones solo de esa tabla), renderizado con
  Mermaid.js servido localmente (public/js/mermaid.min.js, sin CDN).
2026-08-08 23:11:48 +00:00
Lizandro GD 4b9d4a9a5b Agrega detalle_tarea al agente de Telegram y doc comercial de uMind
- El bot solo tenía listar_tareas (resumen: título/estado/prioridad),
  sin forma de pedir la descripción completa ni el historial de
  comentarios de una tarea puntual. Nuevo tool detalle_tarea trae la
  tarea completa + comentarios (autor, contenido, adjuntos, fecha).
- UMIND_CASOS_DE_USO.html: documento comercial con casos de uso por
  tipo de negocio, argumentos de venta y límites actuales del
  producto, para ofrecer uMind a clientes.
2026-08-07 16:24:43 +00:00
Lizandro GD 5ee5880dc2 Agrega uMind: chat con IA embebible por tenant (F1 — widget web + RAG)
Multi-tenant dentro de soft_usite, reutilizando la infraestructura ya
existente (AiConfig, motor de function-calling del agente de Telegram)
en vez de un servicio nuevo aparte:

- UmindTenant: sitio/cliente con dominios permitidos, config de IA para
  el chat y personalidad/tono.
- Ingesta: crawler simple (mismo dominio, N páginas) + chunking +
  embeddings (config global con módulo "umind_embeddings", pensada
  para OpenAI ya que Claude no ofrece embeddings) guardados como JSON,
  con búsqueda por similitud coseno en memoria (sin pgvector todavía).
- Agente acotado: única herramienta buscar_conocimiento, sin acceso a
  nada interno — si no encuentra la respuesta, lo dice en vez de
  inventar.
- Widget público (/widget/umind.js + /widget/:site_key/*), autenticado
  por site_key + validación de dominio (Origin/Referer), no por
  secreto, ya que la key viaja en el HTML público del sitio instalado.
- Panel /app/umind: tenants, estado de ingesta, historial de
  conversaciones por sesión.
2026-08-07 16:18:16 +00:00
Lizandro GD 0eef3f80a3 Corrige tablas faltantes en producción y bug de listado en Entidades
- AutoMigrate migraba ~50 modelos en un solo llamado que se detiene en
  el primer error, dejando todo lo posterior (plantillas_documento,
  tarifas, documentos_generados, arquitecturas, telegram_staff_tokens)
  sin tabla, en silencio. Ahora se migra modelo por modelo: uno roto
  ya no bloquea al resto.
- /app/contabilidad/entidades pedía datos a la misma URL de la página
  (devuelve HTML) en vez de /list (JSON) — el listado nunca traía nada.
- Mensaje de bienvenida del asistente: estaba generado por la IA cada
  vez con calidad variable; ahora es determinístico para /ayuda y
  /start, con redacción revisada, y el system prompt pide el mismo
  formato cuando el usuario solo saluda.
2026-08-07 03:00:02 +00:00
Lizandro GD 25cde836f1 Corrige adjuntos no-imagen (docx, xlsx, etc.) en Telegram con Claude
Un archivo adjunto que no fuera PDF o imagen se mandaba igual como
bloque "image" a la API de Claude, que la rechaza (400) y tumbaba toda
la respuesta del agente. Ahora solo se intenta previsualizar tipos que
Claude soporta (PDF/jpeg/png/webp/gif); cualquier otro formato se
guarda igual con adjuntar_documento_tarea/proyecto/factura, solo que
la IA no puede leer su contenido, únicamente el nombre.
2026-08-04 22:57:58 +00:00
Lizandro GD e5849549a0 Agrega API de pagos externos: tokens por servicio, atados a pasarela e IP
Permite emitir credenciales (token hasheado + IP/CIDR opcional) desde
/app/pagos-externos para que aplicaciones de terceros pidan cobros a
través de Bold/dLocal/PayPal sin acceso a nada más del sistema:

- POST /api/v1/pagos-externos/solicitar genera el link de cobro real
  usando solo las pasarelas habilitadas para ese servicio.
- Los webhooks existentes de Bold/dLocal/PayPal (firma obligatoria,
  idempotentes) ahora también resuelven referencias "extpay-…" sin
  tocar el flujo de contratos ("contrato-{id}").
- Al confirmarse el pago se notifica por webhook firmado (HMAC) y/o
  Telegram, configurable por servicio.
- CRUD de servicios protegido con SoloAdmin; token y callback_secret
  solo se muestran una vez, en DB se guardan hasheados.
2026-08-04 14:16:13 +00:00
Lizandro GD 3e2e4b63e9 Permite adjuntar archivos a tareas desde Telegram
Antes solo facturas y documentos de proyecto consumían el adjunto
pendiente de Telegram; crear_tarea/asignar_tarea lo ignoraban. Agrega
adjuntar_documento_tarea: si el usuario manda un archivo junto con una
instrucción de tarea ("asigna esto a Natalia"), el agente crea/resuelve
la tarea y guarda el archivo como comentario adjunto, visible igual que
un adjunto subido desde /app/tareas.
2026-08-03 20:12:24 +00:00
Lizandro GD 999c5fcf08 Agrega transcripción de audio (Whisper) en Telegram y corrige adjuntos en tareas
- Nueva config "whisper" reutilizando /app/ai-config (credenciales/endpoint
  validables) y servicio de transcripción compatible con OpenAI/Groq.
- El webhook de Telegram ahora detecta notas de voz/audio, las transcribe
  y procesa el texto resultante como si el usuario lo hubiera escrito.
- Fix: subir un archivo adjunto en un comentario de tarea sin escribir
  texto era rechazado por el backend ("contenido requerido") aunque el
  frontend sí lo permitía.
2026-08-03 20:09:43 +00:00
Lizandro GDandClaude Opus 5 5ac70a4d6e fix: tareas del agente invisibles en el Kanban + facturas de compra por Telegram
- El agente creaba tareas con estado='pendiente' (default), pero el tablero
  Kanban del dashboard solo reconoce por_hacer/en_progreso/revision/hecho. La
  tarea se guardaba bien (por eso llegaba el correo de notificación) pero no
  aparecía en ninguna columna. Se corrigen los enums y el default de las tools
  crear_tarea/actualizar_estado_tarea, y se agrega una reparación única al
  arranque que corrige las tareas ya creadas con el estado inválido.

- adjuntar_factura siempre asumía factura de VENTA (ligada a un cliente). Se
  agrega adjuntar_factura_compra: cuando un proveedor le factura a U-SITE (no
  al revés), busca/crea la Entidad proveedor y registra una cuenta por pagar
  con el documento adjunto (se agregan campos archivo/original_name/tipo_mime
  a CuentaPagar, que no los tenía). El prompt del sistema instruye a Claude a
  decidir la dirección leyendo quién emite y quién recibe el documento.
  De paso: endpoint de descarga del soporte de la factura de compra, expuesto
  también en el dashboard (/app/contabilidad/cuentas-pagar).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 14:53:47 +00:00
Lizandro GDandClaude Opus 5 c8e5afceb2 fix: seguridad de pagos y accesos, integración PayPal y Coolify ampliado
Seguridad (crítico):
- Los webhooks de Bold y dLocal solo validaban la firma si el atacante la
  enviaba: sin cabecera se aceptaba cualquier payload. Ahora es obligatoria.
- GET /pago-exitoso marcaba contratos como pagados leyendo un query param del
  navegador. Ahora solo muestra estado; la confirmación la hace la verificación
  contra la API de la pasarela o el webhook firmado.
- /uploads se servía como estático público: se descargaban RUTs, facturas y
  entregables sabiendo la ruta. Ahora exige sesión.
- Los secretos JWT no se podían sobreescribir por entorno (faltaba el tag env:)
  y su valor estaba en el repo, permitiendo firmarse una sesión de admin. Ahora
  son configurables y el arranque se detiene si siguen con el valor publicado.
- .env y session.db salen del control de versiones.
- Query Runner, gestión de usuarios/roles/módulos y seeds quedan restringidos a
  administradores; antes bastaba con tener sesión.

Pasarelas de pago:
- dLocal generaba enlaces que nunca se reconciliaban: mandaba el ID numérico en
  vez de "contrato-N", la URL de retorno apuntaba a la API de dLocal y nunca se
  enviaba notification_url, así que su webhook jamás se disparaba.
- PayPal solo tenía pantalla de configuración. Se implementa el servicio
  completo (OAuth, orden, captura, verificación de webhook) y queda
  seleccionable como pasarela.
- La moneda estaba fija en COP: un contrato en USD generaba un cobro por esa
  cifra en pesos.

Contratos:
- pago_confirmado nunca volvía a false, así que el segundo ciclo de renovación
  no se cobraba aunque el cliente pagara. Se reinicia al generar enlace nuevo.
- Los contratos vencidos nunca cambiaban de estado y recibían correo a diario
  de forma indefinida; ahora se cierran tras 30 días de gracia.

Otros:
- Coolify: coolifyCall ignoraba el status HTTP y reportaba errores como éxito.
  El agente pasa de 10 a cobertura completa (servicios, bases de datos,
  variables de entorno, proyectos, equipos y recursos de servidor).
- SeedBalanceData ya no corre en cada arranque (recreaba transacciones
  borradas); ahora se invoca con SEED_BALANCE=1.
- Los seeds dejan de devolver permisos revocados en cada despliegue.
- Timeouts en las llamadas HTTP a Telegram y dLocal que podían colgarse.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 03:20:00 +00:00
Lizandro GDandClaude Sonnet 5 5607836261 feat: pantalla para administrar chats autorizados del agente de Telegram
Antes la whitelist de telegram_agent_auth solo se podía tocar con curl/Postman
contra /api/v2/agent/auth. Se agrega /app/agente/chats-autorizados con un
CRUD simple, más un botón "buscar mensajes recientes" (UpdatesRecientesDelBot,
vía getUpdates) para descubrir el chat_id de alguien que le acaba de escribir
al bot sin tener que pedírselo por otro medio. Entrada nueva en el menú lateral
del módulo Automatización IA.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 02:37:40 +00:00
Lizandro GDandClaude Sonnet 5 7b0e4b9b5c fix: convertir Markdown a HTML de Telegram antes de enviar mensajes del agente
El bot manda mensajes con parse_mode=HTML, pero la IA responde en Markdown
(##, **negrita**, listas con "-", separadores ---), que Telegram no
interpreta — salía todo literal con los símbolos. Ahora FormatearParaTelegram
convierte el Markdown a las etiquetas que Telegram sí soporta (b, code, pre,
a) justo antes de enviar, escapando cualquier < > & literal para que
sendMessage tampoco falle por HTML inválido. Se ajustó el único lugar que ya
armaba HTML a mano (/instancias) para que use el mismo formato Markdown y
pase por el mismo conversor. Incluye tests con el caso real reportado.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 02:26:42 +00:00
Lizandro GDandClaude Sonnet 5 a0b2e9ae0a feat: registrar proyectos con fases, adjuntar documentos y asignar tareas por Telegram
- crear_fase_proyecto: agrega fases/etapas a un proyecto (se puede llamar
  varias veces seguidas para cargar todas las fases de un proyecto nuevo).
- adjuntar_documento_proyecto: guarda el archivo que el usuario acaba de
  enviar por Telegram como documento del proyecto (mismo mecanismo de
  adjuntos ya usado para facturas — se generalizó TelegramAttachment para
  servir a ambos casos).
- listar_usuarios + asignado_id en crear_tarea + asignar_tarea: permite
  asignar tareas a alguien del equipo por Telegram, disparando la misma
  notificación (Telegram/email/sistema) que ya dispara el dashboard.
- El prompt del sistema ahora indica cómo decidir entre adjuntar_factura y
  adjuntar_documento_proyecto según el contexto del archivo recibido.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 02:11:02 +00:00
Lizandro GDandClaude Sonnet 5 cd0ca6d232 feat: leer el contenido real del documento adjunto con Claude
Antes solo se avisaba en texto "llegó un documento" — la IA nunca veía el
archivo, por eso siempre tenía que preguntar cliente y monto. Ahora, cuando
el proveedor activo es Anthropic, se le adjunta la imagen/PDF real (base64)
al mensaje para que Claude lo lea directamente y extraiga cliente, monto y
número de factura, llamando a adjuntar_factura sin pedir confirmación salvo
que de verdad no pueda determinar cliente o monto.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 02:01:12 +00:00
Lizandro GDandClaude Sonnet 5 b292d98cf6 feat: enviar factura por Telegram como documento adjunto
El bot solo procesaba mensajes de texto: un documento o foto enviado al chat
se ignoraba por completo (Telegram lo manda en message.document/photo con
caption, no en el campo text). Ahora el webhook detecta el adjunto, lo
descarga desde la API de Telegram y lo deja pendiente para el chat; el agente
usa la nueva tool adjuntar_factura para asociarlo a un cliente (preguntando
cliente/monto si el caption no los trae) y crear la Factura con el archivo ya
vinculado, igual que si se subiera desde el dashboard.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 01:37:13 +00:00
Lizandro GDandClaude Sonnet 5 8fce587304 fix: recalcular consolidado mensual automáticamente al crear/editar/borrar transacciones
CalcularYGuardarConsolidado solo se ejecutaba al visitar /contabilidad/consolidado,
así que un consolidado ya guardado quedaba desincronizado en cuanto alguien
editaba o borraba una transacción de ese mes. Ahora CreateTransaccion,
UpdateTransaccion y DeleteTransaccion recalculan el consolidado del mes
afectado (y del mes anterior si una edición cambia la fecha de mes). También
aplica a los pagos de cuentas por cobrar/pagar, que ahora crean su
transacción a través de CreateTransaccion en vez de un Create directo.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 01:29:16 +00:00
Lizandro GDandClaude Sonnet 5 d2bf699b60 fix: seguridad del webhook de soporte, pagos en contabilidad y Telegram para tareas
- soporte: el webhook de correo entrante era público sin ninguna validación;
  ahora exige una API key (query ?key= o header) comparada en tiempo constante.
  Además evita tickets duplicados por reintentos del proveedor (dedup por
  Message-Id) y enhebra respuestas del mismo remitente en vez de abrir un
  ticket nuevo por cada correo.
- contabilidad: marcar una cuenta por cobrar/pagar como pagada ahora crea y
  vincula la Transaccion correspondiente (antes el dashboard de ingresos/
  egresos nunca reflejaba esos pagos). Se corrige además que actualizar una
  cuenta por cobrar borraba su transaccion_id en cada PUT.
- tareas: se activa por defecto el canal Telegram para tarea_asignada (estaba
  apagado desde el seed original) y se agrega un flujo real de vinculación de
  Telegram para el staff interno (código temporal + verificación), igual al
  que ya existía para los usuarios del portal — sin esto el chat_id de cada
  usuario había que pegarlo a mano y la notificación nunca llegaba.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 01:25:17 +00:00
Lizandro GD a36e2e1048 Merge remote-tracking branch 'origin/main'
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

# Conflicts:
#	main.go
2026-08-03 00:47:00 +00:00
Lizandro GDandClaude Sonnet 5 516220a8a1 feat: automatización de cotizaciones, contratos, actas y cuentas de cobro con IA
Implementa las 4 fases de la especificación de automatización: módulo de
plantillas/tarifas editable por el equipo, generación de PDF (HTML+JS vía
Chrome headless) para cotizaciones/contratos/arquitecturas/cuentas de cobro,
chat propio en el dashboard reutilizando el mismo motor y tools del bot de
Telegram, y nuevas tools del agente para crear estos documentos end-to-end.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 00:45:58 +00:00
Lizandro Guarnizo 03b18418eb feat: SMTP salida propio en webhook de soporte 2026-07-30 12:19:56 -05:00
Lizandro Guarnizo 333fe03de0 fix: historial por usuario (user_id en query_history) 2026-07-30 11:02:19 -05:00
Lizandro Guarnizo 1d7bfd3596 feat: multi-query/upload .sql en query runner + selector BD por rol 2026-07-30 09:19:24 -05:00
Lizandro Guarnizo 28affb5a55 feat: área de soporte con webhook de correo y asignación de tickets 2026-07-28 23:39:03 -05:00
Lizandro GDandClaude Opus 4.6 c7b71d914f perf(agent): reducir tokens ~75% guardando solo user+assistant en historial
Los tool_calls y tool_results intermedios (JSON crudo de listas) se
mantenían en BD y se reenviaban a la IA en cada turno, consumiendo
la mayoría de tokens sin aportar contexto nuevo.

Ahora solo se persisten mensajes user y la respuesta final assistant.
Los datos de herramientas viven únicamente en memoria durante el round
actual. También se reduce el límite de historial de 20 a 10 mensajes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-13 19:45:34 +00:00
Lizandro GDandClaude Opus 4.6 622a89e966 fix: restaurar tool_calls en historial al cargar conversación del agente
Cuando el agente hacía múltiples rondas de herramientas, los mensajes
del asistente con tool_calls se guardaban como JSON en Content. Al
recargar el historial, ToolCalls quedaba nil y Anthropic recibía
tool_result sin el tool_use correspondiente → error 400.

Ahora se detecta si Content es un array JSON y se deserializa de vuelta
a []agentToolCall antes de enviarlo a la API.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-13 19:36:48 +00:00
Lizandro GDandClaude Sonnet 4.6 ee9a2f09d6 feat: notificaciones Telegram en webhook de Coolify
- CoolifyWebhook parsea el payload y envía mensaje formateado a Telegram
- Detecta estado ( success /  fail / 🚀 deploying / ⏹ stop / 🔄 restart)
- Ruta /webhooks/coolify/:config_id identifica de qué instancia viene
- Notifica a todos los chats autorizados del agente bot
- GetAgentTelegramConfig() en models para obtener el bot activo

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-13 19:28:59 +00:00
Lizandro GDandClaude Sonnet 4.6 4f309ad9d5 feat: soporte nativo Anthropic en el agente (tool use format)
Agrega callAnthropicAI() que convierte mensajes y herramientas al formato
nativo de Anthropic Messages API (tool_use / tool_result), con conversión
de vuelta al formato interno OpenAI para mantener el historial unificado.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-13 19:16:11 +00:00
Lizandro GDandClaude Sonnet 4.6 5c81939bbf feat: agente - agregar listar_facturas + campos agente en AI Config create/update
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-13 18:31:15 +00:00
Lizandro GDandClaude Sonnet 4.6 33cfe4fdb0 feat: agente Telegram con IA + Coolify multi-instancia
- Coolify: soporte multi-instancia (CRUD de configs, ?config_id= en todos
  los endpoints, endpoints expandidos para services/databases/teams/envs)
- AiConfig: campos es_agente_bot + telegram_config_id para marcar qué
  config de IA actúa como cerebro del bot administrador
- TelegramAgentHistory + TelegramAgentAuth: historial de conversación por
  chat_id y whitelist de chats autorizados
- Agent Engine: function calling OpenAI-compatible con 25+ herramientas
  (clientes, contratos, contabilidad, proyectos, tickets, tareas,
  Coolify multi-instancia, servidores, monitores URL)
- Webhook POST /webhooks/telegram-agent/:bot_token (público, sin sesión)
- API /api/v2/agent/auth y /api/v2/agent/history para administrar el agente
- AutoMigrate: AiConfig, TelegramAgentHistory, TelegramAgentAuth

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-13 18:29:06 +00:00
Lizandro GDandClaude Sonnet 5 6e281dfbda feat: cuentas por cobrar usa listado de clientes en vez de entidades contables
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-13 02:44:19 +00:00
Lizandro GuarnizoandClaude Sonnet 4.6 daf0b2c2a1 fix: marcar pagada en cuentas por pagar sobreescribía datos con ceros
UpdateCuentaPagar actualizaba TODAS las columnas incluyendo entidad_id=0,
valor=0, descripcion='' cuando solo se enviaba estado+fecha_pago.
Se agrega MarcarCuentaPagarPagada que solo toca estado y fecha_pago,
con su endpoint POST /cuentas-pagar/:id/pagar.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-09 20:25:39 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 b3b6f6705d fix: marcar pago manual no toca estado ni fecha_vencimiento
MarcarContratoPagado siempre sobreescribía estado='activo' y renovaba
fecha_vencimiento, lo que causaba doble renovación si el admin ya había
ajustado el contrato manualmente. ConfirmarPagoManual solo limpia
pago_confirmado, fecha_pago y el enlace Bold, sin tocar nada más.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-09 20:13:40 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 dfe8d9e4a9 fix: columna FK incorrecta en contrato_servidores y filtrado de BDs en modal
- syncContratoJoin derivaba "contrato_servidore_id" en vez de "servidor_id"
  al recortar el último carácter del nombre de tabla; ahora usa TrimPrefix+TrimSuffix
  para derivar correctamente servidor_id, conx_db_id, ai_config_id
- Modal contratos: filteredConxDbList filtra BDs por servidor(es) seleccionado(s)
  en vez de mostrar todas las BDs sin contexto

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-09 11:58:01 -05:00
Lizandro Guarnizo 62397f2f8c feat: telegram chat ID en usuarios (UI + notificacion al asignado) 2026-07-07 00:26:31 -05:00
Lizandro Guarnizo 38ff9270ab fix: ia controller soporta OpenAI-compatible + native Ollama; TelegramChatID en Users 2026-07-06 23:54:21 -05:00
Lizandro Guarnizo 9dfa3afab0 fix: ia controller usa endpoint default si no hay config en BD + valida status HTTP de Ollama 2026-07-06 23:37:26 -05:00
Lizandro Guarnizo 9a3a5d4b25 feat: pagina principal configurable por rol (HomeUrl) 2026-07-06 23:05:02 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 37648724f8 feat(notif): integrar notificaciones de tareas con NotifEventoConfig
- SeedNotifDefaults: poblar 10 eventos por defecto (tickets, servidores, tareas)
- notif_dispatch: NotificarTareaAsignada/Estado/Comentario ahora respetan
  canal_email, canal_telegram y canal_sistema de la config de notificaciones
- mail_service: añadir SendTareaAsignadaEmail y SendTareaNotifAdmin
- notif_config.html: agregar eventos tarea_asignada, tarea_estado, tarea_comentario
  al panel de configuración para que el admin pueda activar/desactivar canales

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-06 22:06:40 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 107178aa97 feat(users): reemplazar confirmación por envío de credenciales con link de reset
- Eliminar envío automático de confirmación al crear usuario
- Nuevo botón en cada fila: enviar credenciales (usuario + link establecer contraseña)
- POST /app/users/:id/credenciales → SendUserCredencialesEmail
- Email incluye username, link al login y link para establecer contraseña

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-06 21:57:36 -05:00
Lizandro Guarnizo bf3cbd3606 fix: CUENTAS DE COBRO van como CuentasPagar (son las que te pasan a ti), FAC POR PAGAR unificado, entidades reclasificadas 2026-07-06 21:46:34 -05:00
Lizandro Guarnizo 1ffc695154 fix(mail): fallback HTML cuando PrepareHtml falla, mejor logging, simplificar goroutine 2026-07-06 21:44:18 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 bc79553b7e feat(tareas): módulo de tablero kanban con drag & drop, comentarios y Telegram
- Modelos Tarea y TareaComentario con GORM, migración automática
- Estados: por_hacer → en_progreso → revisión → hecho; prioridades: baja/media/alta/urgente
- Drag & drop entre columnas via SortableJS (PUT /tarea/:id/estado)
- CRUD completo: crear, editar, eliminar; asignación a usuario + fecha límite
- Panel lateral de detalle: historial de comentarios, adjuntar archivos (uploads/tareas/:id)
- Telegram: notifica asignación, cambio de estado y comentarios nuevos via sendTelegramAdmin
- Seed automático bajo módulo "Administración", solo rol Administrador

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-06 20:18:26 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 5f92934fba feat(url-monitor): agregar monitoreo de disponibilidad de URLs desde servidor
- Modelos UrlMonitor y UrlMonitorLog con purga automática a 7 días
- Cron cada minuto ejecuta chequeos HEAD→GET con fallback, alerta Telegram en cambio de estado
- CRUD completo + chequeo manual + historial de logs
- Migración automática de tablas

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-06 09:33:48 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 569d8b0f28 feat(ai-config): agregar botón Probar para verificar conectividad del provider
- Endpoint GET /ai-config/:id/test que llama /api/tags (Ollama) o /v1/models (OpenAI-compat/Anthropic)
- Botón "Probar" en cada fila de la tabla con modal de resultado JSON

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-06 09:33:29 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 66088ce691 feat(agent): auto-renice top CPU process after 2 consecutive high-CPU reports
- Agent tracks consecutive reports above cpu_threshold (default 90%)
- After renice_consecutive reports (default 2 = 60s sustained), runs
  renice -n 19 on the top CPU process
- Reports the action back in the heartbeat payload
- Backend sends Telegram alert when renice is applied
- All params configurable in agent.yml and install.sh flags

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 11:17:07 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 ae74d0ef90 feat(agent): persist 7-day metrics history per server heartbeat
- New table servidor_metricas_history (cpu%, ram%, swap%, disco%, tcp, load1)
- Each heartbeat inserts a compact row (~60 bytes)
- GET /app/servidor/:id/metricas-history?horas=24 returns the data
- Daily cron at 3AM purges rows older than 7 days
- ~1.2 MB per server per 7 days at 30s interval

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 11:03:16 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 4b98161070 feat(cron): include top 3 processes in CPU/RAM alert Telegram messages
When CPU or RAM exceeds the threshold, the alert now lists the top 3
processes sorted by the relevant metric (CPU% or RAM MB).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 10:53:43 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 73fe73b04f fix(cron): parse discos array correctly for disk alert threshold checks
The metrics JSON uses 'discos' (array) not 'disco' (single object),
so disk alerts were never firing. Also reports per-mountpoint label.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 10:47:04 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 cb9d984ee8 fix: capturar subid de LabsMobile como MsgID en logs de SMS
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 18:36:14 -05:00