Mapa Geral do CRM ZPRO
Sistema em camadas
[Browser]
↓ HTTPS (nginx)
[Next.js Frontend :4444]
↓ API calls (axios) ↓ Socket.IO (WebSocket)
[Node.js Backend :3000] ←→ [Redis pub/sub]
↓ ↓
[PostgreSQL :5432] [6 Workers cluster]
↓
[Baileys → WhatsApp Web API]
[Meta Cloud API → WABA]
Módulos principais
Atendimento (core)
- Janela de conversa: chat-header + message-bubble
- Lista de tickets: painel esquerdo com filtros avançados
- Detalhes do contato: ticket-detail
- Realtime: ticket-store + socket
Canais (Sessões)
- Baileys (QR code) —
type: "baileys" - WABA (Meta Cloud API) —
type: "waba" - Gupshup —
type: "gupshup" - Dialog360 —
type: "dialog360" - Instagram, Messenger, Telegram, etc.
CRM / Funil
- Pipeline → Stages → Opportunities
- Kanban por etapa (funil/kanban)
- Kanban por etiqueta (kanban/tags)
- Kanban Novo — criado por nos, superset do vendor
Envio em Massa
- API Oficial (WABA template) —
/massa/template - API com Nome (WABA variavel) —
/massa/template-variavel - Nao Oficial QR (texto) —
/massa/texto - Nao Oficial com Nome (texto variavel) —
/massa/textovariavel - WaVoIP, SMS, RCS
Configuracoes
- Sessoes/Canais —
/sessoes - Meta/WABA —
/configuracoes/meta - Filas —
/filas - Chatbot/FlowBuilder —
/chat-flow - SMS, RCS —
/configuracoes/sms,/configuracoes/rcs
Fluxo de uma mensagem recebida (Baileys)
WhatsApp → Baileys lib
↓ messages.upsert event
Backend worker (Signal decrypt)
↓ se PreKeyError → "failed to decrypt"
↓ se ok
Salva no PostgreSQL (Messages table)
↓
Socket.IO emit → Frontend
↓ use-socket-tickets.ts
Zustand ticket-store update
↓
React re-render → mensagem aparece
Problema de sincronismo Baileys
Quando aparece mas nao chega no CRM:
- O WebSocket esta ok (mostra CONNECTED)
- O Signal Protocol esta corrompido (PreKeyError)
- Fix: menu … → Ressincronizar (fix decrypt) — ver baileys-sync
Cluster e sessoes
6 workers compartilham via Redis pub/sub. CADA worker mantem suas proprias conexoes Baileys.
Se dois workers tentam autenticar o mesmo numero → conflict: replaced → loop.
Por isso: resetBaileysConnection deve ser chamado em UM worker, UM canal por vez.