- Mueve la ruta /storage/{path} fuera del middleware de auth para que
sea pública; necesario para que los servidores de WhatsApp y el navegador
puedan cargar imágenes de promociones sin autenticación
- Dockerfile: agrega 'rm -rf public/storage' antes de storage:link para
evitar que COPY copie la junction de Windows y deje el symlink roto en el contenedor
- Crea .dockerignore: excluye public/storage, .git, .env y artefactos de
build del contexto de Docker para builds más limpios y seguros
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Actualiza graph.facebook.com de v19.0 a v25.0
- Cambia parámetros posicionales a nombrados (parameter_name) en enviarTemplate para compatibilidad con plantillas avanzadas
- enviarPromocion ahora pasa nombre fallback 'estudiante' y claves explícitas
- imagenUrl() soporta imágenes con URL absoluta (http/https) además de rutas relativas de storage
- Agrega Log::info del payload completo antes del envío para facilitar debugging
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Simplifica WhatsAppWebhookController: messages crea WhatsappLog con tipo
'recibido', statuses actualiza el log existente por whatsapp_mensaje_id,
opt-out detecta solo STOP/cancelar con regex. Agrega rutas GET/POST
/webhook/whatsapp fuera del grupo auth en web.php (POST sin CSRF).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Corrige formato de fechas a español con Carbon isoFormat('D [de] MMMM')
- Webhook procesa statuses de Meta (delivered/read/failed) y actualiza pivot alumno_promocion
- Analytics: nuevas métricas de entregados/leídos, embudo de entrega, filtro por tipo
- Inspector de payload raw por log con modal y botón copiar
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove broken transformRequest that crashed with Axios 1.x (headers.post undefined)
- Guard window.Echo.socketId() to avoid TypeError before socket connects
- Wrap broadcast() in try/catch so Reverb downtime does not cause 500 errors
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>