Commit Graph
23 Commits
Author SHA1 Message Date
Lizandro GuarnizoandClaude Sonnet 4.6 454ee297e2 feat: log every incoming webhook request before validation
Saves a raw entry to webhook_logs immediately on any POST to the webhook,
before HMAC check or JSON parsing. Shows HMAC status (ok/invalida/sin-firma).
Live feed now shows all traffic including rejected and malformed payloads.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 11:39:23 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 483cc4797e fix: replace SSE with polling in live feed to stop blocking FPM workers
SSE kept a PHP-FPM worker open for 28s per connection, blocking the whole
server with only 20 workers shared across all vhosts. Polling with
setInterval(3000) releases the worker on each request immediately.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 11:37:21 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 c702dbadc1 fix: save gemini keys in settings + add AI connection test
- Add gemini_api_key and gemini_model to allowed keys in settings save handler
- Add POST /admin/settings/test-ai endpoint for testing Gemini/OpenAI connection
- Add "Probar conexion IA" card in settings page with live feedback

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 11:34:25 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 5277d47c14 feat: soporte Google Gemini como proveedor de IA
- Settings: agrega Gemini al selector de proveedor, campos gemini_api_key y gemini_model
- Modelos: gemini-2.0-flash, gemini-1.5-flash, gemini-1.5-pro
- AiBot::callGemini(): llama generateContent API con system_instruction y historial
- migrate.php: seed defaults gemini_api_key y gemini_model

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 22:55:13 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 ef799a4a0a feat: botón Sincronizar desde ERP en pestaña Números WhatsApp
- Consume el endpoint numeros_dn configurado para la empresa
- Acepta JSON con array raíz o {numeros:[...]}
- Mapea campos wa_number/numero/phone, nombre/name/label, permiso/permission_type/tipo
- Upsert en company_phones: nuevos se insertan, existentes se actualizan
- Reporta conteo de nuevos / actualizados / omitidos

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 22:45:21 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 b84dd01c40 fix: separa cosecha/sanidad/polinización en 3 endpoints independientes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 22:27:58 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 ea7560f9bf refactor: elimina phone_number_id y display_phone del formulario de empresa
- El número WA Business es global (configuración general), no por empresa
- OutboundWorker usa fallback a WHATSAPP_DEFAULT_PHONE_NUMBER_ID si la empresa no tiene
- CompanyRepository::save() ya no requiere phone_number_id
- phone_number_id permite DEFAULT '' en schema

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 22:19:05 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 2632eff3fb fix: elimina UNIQUE de phone_number_id — varias empresas comparten el mismo número WA
El routing ahora es por número remitente (company_phones), no por phone_number_id.
phone_number_id solo se usa para enviar mensajes salientes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 22:14:57 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 14db6fe27f fix: PHP heredoc interpretaba template literals JS como constantes PHP
- Convierte backtick template literals con \${it.id} a concatenación de strings
- Fix query de chatConversations: GROUP BY solo por phone_number, evita duplicados

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 22:10:38 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 7657e0f55c fix: CompanyRepository::all() → findAll()
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 22:04:00 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 860e93a20b feat: módulo de empresa con números WhatsApp y endpoints API por empresa
- DB: company_phones (3 tipos de permiso, límites por usuarios ERP)
- DB: company_endpoints (11 endpoints upload/download configurables)
- DB: erp_active_users en companies (base para calcular límites)
- Company edit: 3 pestañas — General / Números WhatsApp / Endpoints API
- Límites: tipo 1 = usuarios_erp×10, tipo 2+3 = usuarios_erp
- Endpoints: URL configurable + botón Probar + preview de respuesta JSON
- Layout::close() agregado

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 21:57:31 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 b083d49769 feat: página de mensaje de prueba para simular webhook entrante
- GET /admin/test-message: formulario con empresa, número, nombre y texto
- POST /admin/test-message/send: construye payload WhatsApp, firma HMAC y
  hace POST al webhook propio — pipeline completo sin tocar Meta

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 21:50:25 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 7b8a4c2056 fix: SSE libera worker en 28s y detecta desconexión cada 200ms
- TTL de 28s por conexión; EventSource reconecta automáticamente (retry:3000)
- Reemplaza sleep(2) por loop usleep(200ms) para detectar pagehide rápido
- PHP-FPM workers aumentados de 5 → 20 (directo en servidor)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 21:47:24 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 333317e268 feat: UI minimalista — una sola barra de navegación, drawer móvil, fix SSE
- Layout: fusiona topbar + nav en una sola barra de 56px (elimina doble menú)
- Desktop: brand izquierda, topnav centrado con underline activo, usuario derecha
- Móvil: hamburger animado (3 líneas → X), drawer lateral con overlay
- app.css: reescritura completa sin gradientes ni sombras pesadas
- DashboardController: corrige heights 104px→56px (chat, bot-config tabs)
- Live Feed: cierra EventSource en pagehide para evitar bloqueo al navegar

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 21:41:37 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 ef6e9c1f70 feat: UI/UX overhaul — shared layout, SSE live feed, responsive nav, approval drawer
- admin/Layout.php: nueva clase compartida con topbar, nav agrupado y hamburger móvil
- assets/app.css: CSS centralizado (~130 líneas), elimina ~2000 líneas duplicadas
- DashboardController: 11 vistas refactorizadas con Layout; tarjetas de stats clicables;
  drawer de aprobación rápida desde el dashboard; Live Feed reemplaza polling 3s por SSE;
  bot-config con preview WhatsApp en tiempo real; chat con back-button móvil y textarea auto-resize
- public/index.php: rutas SSE (/admin/webhook/stream/sse) y pending-list (/admin/pending-list)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 21:21:32 -05:00
Lizandro Guarnizo daf1947f13 cambios importantes 2026-06-13 12:03:30 -05:00
Lizandro Guarnizo dd57cba0e2 feat: bot config visual editor, chat admin, debug logging, HMAC toggle 2026-06-13 11:24:32 -05:00
Lizandro Guarnizo a6595862ec cambios importantes 2026-06-12 22:17:05 -05:00
Lizandro Guarnizo 4bd353c128 cambios importantes 2026-06-12 22:02:03 -05:00
Lizandro Guarnizo bc422e0a1c cambios importantes 2026-06-12 12:18:21 -05:00
Lizandro Guarnizo 196855b32d fix: quitar tipo mixed y ENT_SUBSTITUTE para PHP 7.4 2026-06-04 20:09:21 -05:00
Lizandro Guarnizo 43f337ee34 fix: compatibilidad PHP 7.4 — str_starts_with, str_contains, match, never, mixed 2026-06-04 20:04:37 -05:00
Lizandro Guarnizo 202a263e25 feat: bot WhatsApp Business API — Palmas360 inicial 2026-06-04 13:35:23 -05:00