soporteSendMail leía la configuración SMTP sin verificar que hubiera base. Con
la conexión en nil eso es un desreferenciado de puntero, y como el envío corre
en su propia goroutine no hay recover que lo contenga: se lleva puesto el
proceso.
En producción no se veía porque siempre hay base. Lo que sí bloqueaba era la
suite de pkg/services, que no se podía correr entera desde hacía tiempo —
cualquier test que tocara el auto-respuesta de soporte hacía explotar toda la
corrida y tapaba el resultado del resto.
Ahora devuelve un error en vez de reventar, y los 7 paquetes con tests del
proyecto pasan en verde.
(utils/xopen tiene 2 tests que fallan: es una dependencia de terceros incluida
en el repo desde el commit inicial y no la toca nada de esto.)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Telegram: los avisos se mandaban a todas las configuraciones activas sin mirar
a dónde apuntan. Con el mismo chat cargado en dos filas, cada aviso llegaba dos
veces. Ahora se manda una vez por destino (bot + chat); los chats distintos
siguen recibiendo todos.
Correo al remitente: el camino STARTTLS abría una conexión, hacía StartTLS,
autenticaba… y la descartaba para llamar a smtp.SendMail, que abre otra. La
primera quedaba colgada y el envío real salía por una conexión distinta, que
podía no estar autenticada. Reescrito: una sola conexión, asegurada según la
configuración, y cierre con QUIT.
Y como el acuse se manda en segundo plano, su error moría en el log. Ahora hay
un botón "Enviar correo de prueba" que usa exactamente el mismo camino y
devuelve el error del servidor en pantalla, y el último fallo del acuse real
aparece en el resultado de "Revisar buzón ahora".
Co-Authored-By: Claude Opus 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>