Commit Graph
420 Commits
Author SHA1 Message Date
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 GDandClaude Sonnet 5 1127d944c7 fix: loguear errores de AutoMigrate en el arranque normal
AutoMigrate se detiene en el primer modelo que falla y no continúa con el
resto de la lista. Como esta llamada no revisaba el error, cualquier fallo
silencioso dejaba sin crear todas las tablas listadas después (incluidas
plantillas_documento, tarifas, documentos_generados, arquitecturas).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 01:06:46 +00:00
Lizandro GDandClaude Sonnet 5 c6227150a3 fix: evitar spinner de carga infinito si falla la API en plantillas/tarifas
loadData() no tenía try/catch: si la petición fallaba (deploy sin el código
nuevo, tabla inexistente, etc.) el estado "loading" nunca volvía a false y la
pantalla quedaba trabada en el overlay de carga sin ningún mensaje de error.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 01:00:56 +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 GD 772a4a5656 fix: editar instancia Coolify trae URL fresca del server y valida base_url no vacio 2026-07-22 13:27:02 +00:00
Lizandro GD a1d4c9da23 style: mejorar UI de tarjetas de instancias con iconos y jerarquia visual 2026-07-22 13:02:20 +00:00
Lizandro GD ed19eb3fd6 feat: soporte multi-instancia Coolify en panel web 2026-07-22 02:07:25 +00:00
Lizandro GDandClaude Opus 4.6 d9933a754b feat(agent): comandos /reset /limpiar /start borran historial desde Telegram
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-13 19:46:18 +00: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 GD a8786e2aca fix: exponer es_agente_bot y telegram_config_id en respuesta de AI Config 2026-07-13 19:20:50 +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 4.6 50812749ea fix: corregir argumentos faltantes en fmt.Sprintf y usar net.JoinHostPort
- generateModelFileContent: faltaban 4 args (item Update, Delete comment/func/model)
- generateControllerFileContent: faltaban 2 args (Delete func y mensaje)
- generateRouteFileContent: faltaba 1 arg (comentario Delete)
- servidor_controller: usar net.JoinHostPort para compatibilidad con IPv6

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-13 18:19:19 +00:00
Lizandro GDandClaude Opus 4.6 9fd0772e91 refactor: rename Hermes API to Admin API v2 under /api/v2
Integrates the external API into the existing /api group as v2 with
API key auth (ADMIN_API_KEY), replacing the separate /hermes namespace.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-13 12:17:08 +00:00
Lizandro GDandClaude Sonnet 5 f8d44f3c21 docs: instrucciones completas de Hermes API para consumo externo
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-13 03:05:49 +00:00
Lizandro GDandClaude Sonnet 5 13c3b4c16c feat: endpoint /hermes/spec con documentación completa de la API
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-13 03:01:15 +00:00
Lizandro GDandClaude Sonnet 5 6ccdbd93c8 feat: API Hermes con acceso total para consumo externo (API Key auth)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-13 02:50:31 +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 2ee5e2ea83 fix: sesión sin vencimiento práctico (90 años JWT + cookie persistente)
- JWT exp: 1 año → 90 años
- Cookie Verify-Rest-Token: sin MaxAge (session cookie) → MaxAge 90 años
- Session store: 1 año → 90 años

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-09 20:20:33 -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 0218b93bb4 feat: marcar pago manual en contratos con enlace Bold pendiente
Agrega endpoint POST /api/contratos/:id/marcar-pagado y botón (✓)
en la tabla de contratos para confirmar el pago sin depender del
webhook de Bold. Llama a MarcarContratoPagado (pago_confirmado=true,
limpia enlace, renueva fecha vencimiento) y envía correo de confirmación.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-09 20:11:50 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 9305cd6eb2 fix: drag-and-drop en tablero de tareas (SortableJS + Alpine x-for)
SortableJS mueve el nodo DOM físicamente antes de que Alpine re-renderice,
causando conflicto: la tarjeta desaparecía o volvía a su columna original.
Se revierte el movimiento DOM de SortableJS en onEnd y se deja que Alpine
re-renderice solo al actualizar t.estado; luego se re-inicia Sortable.
Se agrega cursor grab/grabbing como indicador visual de arrastre.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-09 20:04:48 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 65c988dc70 fix: agente ignora discos squashfs y mountpoints /snap/
Los paquetes snap son loop devices de solo lectura que siempre
reportan 100% de uso. Se excluye el fstype squashfs del monitoreo
de disco y adicionalmente se saltan mountpoints que empiecen con /snap/.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-09 19:29:53 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 e4bb986c6c fix: servir carpeta uploads/ como ruta estática
Los archivos adjuntos de tareas se guardaban en uploads/tareas/{id}/
pero Fiber solo servía la carpeta public/. Se agrega ruta estática
/uploads → ./uploads para que los archivos sean accesibles vía HTTP.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-09 19:17:16 -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 6a3793a63b feat: soporte Google Gemini en IA controller + UI 2026-07-07 00:22:58 -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 c6c2f890f6 fix: Renovaciones y PartnerRecursos solo asignados a Administrador 2026-07-06 23:44:48 -05:00
Lizandro Guarnizo b6522fa850 fix: ia streaming usa json.Decoder en vez de Scanner + loggeo + manejo error interno Ollama 2026-07-06 23:40:56 -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 Guarnizo 7d27240f27 fix: contabilidad y websms solo asignados al rol Administrador, no a todos los roles 2026-07-06 22:39:19 -05:00
Lizandro Guarnizo 18c30e928e fix: crear usuario desde admin ahora setea email_verified=true y estado=true para permitir login 2026-07-06 22:29:05 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 e937676160 fix(auth): flujo de recuperación de contraseña usa email en vez de usuario
- login.html: corregir link roto /password/reset → /request-password-reset
- request-password-reset.html: reescribir — pide email, AJAX, diseño de la app
- RequestPasswordResetPost: buscar por email (GetUserByEmail), no revela si
  el correo existe o no (misma respuesta siempre — seguridad)
- password-reset.html: reescribir — eliminar campo nombre_usuario redundante,
  validación de contraseñas en cliente, diseño consistente con el resto del app
- PasswordResetPost: usar c.Locals("email") del token (ya validado por
  middleware) en vez de nombre_usuario del form
- password_reset.go middleware: ampliar expiración de token de 5 min a 1 hora

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-06 22:17:38 -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