Arquitetura de Serviços e Refatoração WhatsApp · SQLite · Socket.io · TypeScript
A arquitetura foi desenhada para separar responsabilidades em camadas independentes. Cada arquivo tem uma única razão para existir, aplicando conceitos de Clean Code para facilitar a manutenção, testes e evolução.
| Camada | Responsabilidade |
|---|---|
src/types/index.ts |
Contratos TypeScript compartilhados (interfaces, types). |
src/utils/logger.ts |
Logger de domínio — logs coloridos padronizados. |
src/services/whatsapp.service.ts |
Client WPP, listeners, envio e reset de sessão. |
src/services/chat.service.ts |
Normalização, persistência SQLite e consultas otimizadas. |
src/controllers/chat.controller.ts |
Eventos Socket.io de chat (rooms, histórico, envio). |
src/controllers/disparo.controller.ts |
Rota REST POST /disparo-massa (isolada). |
src/controllers/metrics.controller.ts |
Rota REST GET /metrics (isolada). |
src/server.ts |
Ponto de entrada — orquestração pura, zero lógica de negócio. |
A separação de pastas respeita o princípio de responsabilidade única (SRP):
src/
├── types/
│ └── index.ts # Interfaces e types (IMensagem, IContato)
├── utils/
│ └── logger.ts # Logger colorido com escape ANSI
├── services/
│ ├── whatsapp.service.ts # Client WPP, inicialização, reset
│ ├── chat.service.ts # Banco, normalização, consultas SQLite
│ ├── worker.ts # Fila de disparo em massa
│ ├── sanitizer.ts # Tratamento de dados
│ └── spintax.ts # Variação de textos (Anti-ban)
├── controllers/
│ ├── chat.controller.ts # Eventos Socket.io de chat
│ ├── disparo.controller.ts # POST /disparo-massa
│ └── metrics.controller.ts # GET /metrics
├── database/
│ └── connection.ts # Conexão centralizada com o banco
└── server.ts # Inicialização da aplicação
🖨️ 3. Logger de Domínio (utils/logger.ts)Sem dependências externas — construído com escape ANSI puro. Cada categoria de log tem cor e ícone fixos para rastreamento rápido e visual no terminal.MétodoUsoVisual no Terminallogger.inbound(num, txt)Mensagem recebida do cliente📥 [INBOUND ] em verdelogger.outbound(dest, txt)Mensagem enviada pelo bot📤 [OUTBOUND] em cianologger.fallback(orig, cor)Tentativa com 9º dígito🔁 [FALLBACK] em amarelologger.erro(ctx, detalhe)Qualquer erro de envio/banco❌ [ERRO ] em vermelhologger.socket(event, id)Conexão / desconexão WS🟢 [SOCKET ] em verdelogger.worker(msg)Eventos do worker de fila⚡ [WORKER ] em amarelologger.sistema(msg)Inicialização, migrações⚙️ [SISTEMA ] em azul📄 4. Contratos TypeScript (types/index.ts)Todas as interfaces vivem em um único lugar, garantindo que o Frontend (Flutter) e o Backend (Node.js) falem a mesma língua, evitando surpresas de payload.IMensagem — Payload de ChatTypeScriptinterface IMensagem {
numero: string;
texto: string;
isFromMe: boolean; // true = enviada por nós (balão azul/direita)
direcao: "in" | "out"; // Explícito para o renderizador do Flutter
timestamp: string;
status?: string;
}
IContato — Item do Inbox (Painel Esquerdo)TypeScriptinterface IContato {
numero: string;
ultimaMensagem: string;
ultimaInteracao: string;
naoLidas: number; // Contador de mensagens não lidas (zera ao abrir)
}