Commit Graph
14 Commits
Author SHA1 Message Date
Lizandro GuarnizoandClaude Sonnet 5 023a8af494 feat(cobro): suma el consumo de uMind al ciclo de cobro existente
El cobro recurrente (link de pago, webhook con firma, renovación
automática de vencimiento) ya funcionaba de punta a punta; lo único que
le faltaba para cobrar por uso era monto variable.

- MontoACobrar = PrecioAcordado + consumo pendiente del cliente. Si el
  cliente no usa uMind el consumo es 0 y el monto queda idéntico al de
  antes, así que los contratos existentes no cambian.
- El consumo se agrega por Cliente, no por tenant: un contrato es de un
  cliente y un cliente puede tener varios tenants.
- El desglose (cuántos tokens, imágenes y transcripciones, y a cuánto)
  va como líneas de servicio, así las plantillas de correo existentes lo
  muestran sin tocarlas. Cobrar un monto variable sin decir de dónde sale
  es pedir una disputa.
- Al confirmarse el pago se cierra el consumo (facturado_at). Solo si el
  UPDATE del contrato afectó filas: si el webhook llega dos veces, la
  segunda no vuelve a cerrar nada.
- Test de que el detalle del correo suma exactamente lo que se cobra.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-13 11:53:40 -05: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 Guarnizo 9bcddcf1ea up 2026-05-13 22:05:20 -05:00
Lizandro Guarnizo 381425b7e6 ip 2026-05-12 22:34:10 -05:00
Lizandro Guarnizo fd8b5d68fa up 2026-05-12 21:41:26 -05:00
Lizandro Guarnizo 25e3cd6254 up 2026-05-12 19:41:17 -05:00
Lizandro Guarnizo 387485e65b up 2026-05-12 18:34:20 -05:00
Lizandro Guarnizo 3f6eb7dddc p 2026-05-01 13:44:37 -05:00
Lizandro Guarnizo 7f2db7b919 Update renovacion_service.go 2026-05-01 12:54:20 -05:00
Lizandro Guarnizo 0da9331a5e feat: selector de pasarela (Bold/dLocal/ninguna) en regla + muestra {{.EnlacePago}} en editor de plantillas 2026-05-01 12:47:13 -05:00
Lizandro Guarnizo 5e0b6ae2f0 up 2026-05-01 12:02:21 -05:00
Lizandro Guarnizo ee1391db81 fix: usar text/template en renovacion_service para parsear plantillas de correo 2026-04-30 23:15:14 -05:00
Lizandro Guarnizo e751a9f894 feat: contrato soporta múltiples servicios (many2many) con precio sugerido 2026-04-30 22:15:31 -05:00
Lizandro Guarnizo f787821444 up 2026-04-29 23:36:30 -05:00