- 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>
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>
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>
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>
- 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>
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>
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>
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>
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>
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>
- 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>
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>
- 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>
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>
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>
- 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>
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>
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>
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>
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>
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>
- 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>
- 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>
- 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>
- 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>