- TypeScript 95.8%
- Python 1.7%
- JavaScript 1%
- HTML 0.6%
- CSS 0.6%
- Outra 0.2%
| Nome de arquivo | Última mensagem de commit | Última data de commit |
|---|---|---|
| .agents/skills/row-level-security | ||
| .claude | ||
| .trae/skills/row-level-security | ||
| .windsurf/skills/row-level-security | ||
| __tests__ | ||
| app | ||
| bin | ||
| components | ||
| docs | ||
| e2e | ||
| hooks | ||
| lib | ||
| plans | ||
| public | ||
| scripts | ||
| stores | ||
| types | ||
| .claudeignore | ||
| .dockerignore | ||
| .gitignore | ||
| .mcp.json | ||
| components.json | ||
| docker-compose.prod.yml | ||
| docker-compose.yml | ||
| Dockerfile | ||
| drizzle.config.ts | ||
| eslint.config.mjs | ||
| instrumentation.ts | ||
| next.config.ts | ||
| package-lock.json | ||
| package.json | ||
| playwright.config.ts | ||
| postcss.config.mjs | ||
| proxy.ts | ||
| README.md | ||
| SECURITY-AUDIT.md | ||
| skills-lock.json | ||
| tsconfig.json | ||
| vitest.config.ts | ||
Blitzap — blitzap-mkt
SaaS multi-tenant de automação de marketing em massa via WhatsApp — campanhas, contatos, templates, billing e observabilidade em tempo real, sobre Next.js 16, PostgreSQL com RLS nativo e filas BullMQ.
Sobre
O Blitzap (blitzap-mkt) é a aplicação principal da plataforma: um SaaS multi-tenant para automação de marketing via WhatsApp. Cada tenant cria campanhas com templates personalizados, importa listas de contatos (CSV/Excel com mapeamento de colunas assistido por IA) e dispara envios em massa com controle fino de velocidade, cotas, horário comercial e rotação de conexões. O envio é executado por um pipeline assíncrono de 15 etapas sobre filas BullMQ, com idempotência, rate limit por tenant (Lua atômico no Redis), back-pressure e DLQ para falhas permanentes.
A plataforma é operada por três painéis com autenticação Clerk e papéis segregados: o Portal do cliente (campanhas, contatos, templates, conexões, relatórios, billing), o painel DEV (infraestrutura: banco, Redis, filas, workers, ferramentas de diagnóstico) e o painel SuperAdmin (gestão comercial: tenants, planos, cobrança, cupons). O monitoramento de campanhas acontece em tempo real via SSE, com ponte Redis Pub/Sub entre workers e o servidor Next.js.
O multi-tenancy é aplicado em duas camadas: filtragem por tenant_id na aplicação e Row-Level Security nativa do PostgreSQL em 22 tabelas, ativada por transação via withTenantContext() (troca para app_role + SET app.tenant_id). Dessa forma, mesmo um WHERE faltoso não vaza dados entre tenants. Campanhas seguem a máquina de estados DRAFT → SCHEDULED → RUNNING → COMPLETED/FAILED/CANCELLED, com RUNNING ↔ PAUSED e auto-pausa por threshold de erros.
Números do projeto
| Métrica | Valor |
|---|---|
| Páginas (App Router) | 112 |
Handlers de API (route.ts) |
327 |
| Tabelas Drizzle | 48 (109 migrations SQL) |
| Tabelas com RLS nativo | 22 |
| Filas BullMQ | 11 (blast-*) |
| Workers dedicados | 9 (+ entrada unificada all-workers) |
| Etapas do pipeline de mensagem | 15 |
| Jobs cron (scheduler) | ~30 |
| Arquivos TS/TSX | ~1.500 |
| Testes | 20 arquivos unitários (Vitest) + 2 specs E2E (Playwright) |
Stack tecnológica
| Camada | Tecnologia | Versão |
|---|---|---|
| Framework | Next.js (App Router, output standalone) | ^16.1.6 |
| UI | React + React DOM | ^19.2.0 |
| Linguagem | TypeScript | ^5.9.0 |
| Banco de dados | PostgreSQL (driver postgres) |
postgres ^3.4.0 |
| ORM | Drizzle ORM + Drizzle Kit | ^0.45.1 / ^0.28.0 |
| Filas / jobs | BullMQ | ^5.67.0 |
| Cache / broker | Redis via ioredis (3 instâncias: sistema, dispatch, notificações) | ioredis ^5.9.0 |
| Autenticação | Clerk (@clerk/nextjs, email/senha + OAuth Google/Facebook) |
^7.0.7 |
| Estilização | Tailwind CSS v4 + shadcn/Radix UI | ^4.0.0 / ^4.0.6 |
| Estado cliente | Zustand | ^4.5.0 |
| Data fetching | TanStack React Query | ^5.90.0 |
| Validação | Zod | ^3.23.0 |
| IA | Google Gemini (@google/generative-ai) |
^0.24.1 |
| Nodemailer + React Email | ^8.0.4 / ^1.0.11 |
|
| Testes unitários | Vitest | ^2.1.0 |
| Testes E2E | Playwright | ^1.58.2 |
| Runtime (Docker) | Node.js 20 (multi-stage node:20-alpine) |
20 |
Arquitetura resumida
Painéis
| Painel | Rota | Acesso | Propósito |
|---|---|---|---|
| Portal | /portal/* |
Clerk (roles admin/operator) |
Campanhas, contatos, templates, conexões, relatórios, billing |
| DEV | /dev/* |
Clerk + role dev |
Banco, Redis, filas, workers, config e ferramentas de diagnóstico |
| SuperAdmin | /superadmin/* |
Clerk + role superadmin |
Tenants, planos, cobrança, cupons, notificações |
Filas e workers (BullMQ)
11 filas especializadas: blast-dispatch (modo controller com micro-batches e back-pressure), blast-send (modo legacy, com sub-filas por velocidade: ultra_fast/fast/standard/cautious/custom), blast-schedule, blast-sync (cron jobs), blast-webhook (ACKs de entrega), blast-dlq, blast-billing, blast-email, blast-notification, blast-bulk-invoice e blast-verify.
9 workers dedicados em lib/queue/workers/ — campaign-controller, dispatch-sender, message-sender, webhook-processor, sync, billing, email, notification e bulk-invoice — que podem rodar juntos em um único processo (npm run workers:all, via all-workers.ts) ou segregados em containers próprios (docker-compose.prod.yml). O módulo affiliate-digest é executado dentro do worker sync.
O scheduler registra ~30 jobs cron: checagem de campanhas agendadas (1 min), health-check de conexões e snapshots Meta (5 min), reconciliação de mensagens travadas (10 min), sync de templates (1 h), reset de cotas diárias, renovações/vencimentos/suspensões de billing, health score de tenants, digests semanais de afiliados e limpezas periódicas.
Pipeline de mensagem (15 etapas)
message-processor.ts, compartilhado entre os modos legacy e controller: cache de estado da campanha → idempotência (Redis NX) → checagem de estado terminal → status da campanha → rate limit por tenant (Lua) → cota mensal → cota diária por conexão → horário comercial (08h–20h BRT) → marca PROCESSING → dispatch no provider → persistência do sucesso → message log → publicação SSE → métricas → checagem de conclusão/limite de erros.
Providers de mensagem
lib/providers/factory.ts — Meta WhatsApp Cloud API, UZApi e Simulator (wamid fake e ACKs automáticos para testes). Credenciais de providers criptografadas em repouso com AES-256-GCM (DB_ENCRYPTION_KEY, sem fallback).
Multi-tenancy com RLS
Isolamento em duas camadas: tenant_id em todas as queries (via withTenantContext(), que abre transação, assume app_role e configura app.tenant_id) e políticas ROW LEVEL SECURITY/FORCE ROW LEVEL SECURITY em 22 tabelas (scripts/sql/0001_enable_rls.sql), verificadas com current_setting('app.tenant_id'). Auto-provisionamento de tenant no primeiro login via bridge Clerk (lib/auth/clerk.ts).
Integrações externas
Meta WhatsApp Cloud API · UZApi · InfinitePay e PixGo (billing multi-gateway via interface PaymentGateway) · Google Gemini (mapeamento de colunas na importação) · CheckNumber.ai (validação de números) · SMTP/React Email (transacional e drip).
Estrutura de diretórios
evolx-whatsapp-marketing/
├── app/ # Next.js App Router (páginas + API)
│ ├── (auth)/ # Login, registro, SSO callback
│ ├── (dashboard)/portal/ # Painel do cliente (~112 páginas no total)
│ ├── (dev)/dev/ # Painel DEV (database, redis, queues, tools)
│ ├── (superadmin)/ # Painel SuperAdmin (tenants, planos, billing)
│ └── api/ # 327 route handlers (campanhas, webhooks, billing…)
├── lib/ # Núcleo de negócio e infraestrutura
│ ├── auth/ # Bridge Clerk → JWTPayload interno + middleware
│ ├── db/ # Drizzle: schema (48 tabelas), 109 migrations, RLS ctx
│ ├── queue/ # BullMQ: filas, producer, scheduler, message-processor
│ ├── providers/ # Factory + providers meta / uazapi / simulator
│ ├── gateways/ # Adapters de pagamento (InfinitePay, PixGo)
│ ├── integrations/ # Clientes externos (Meta, UZApi, Gemini, CheckNumber…)
│ ├── services/ # Camada de serviços de negócio
│ └── validation/ # Schemas Zod
├── components/ # UI (shadcn/Radix) + shells por painel
├── stores/ # Zustand (wizard de campanha, importação, templates)
├── hooks/ # use-sse, use-auth, filtros de relatório
├── types/ # Tipos TypeScript compartilhados
├── __tests__/lib/ # Testes unitários (Vitest)
├── e2e/ # Specs E2E (Playwright)
├── docs/ # Documentação interna (ver seção abaixo)
├── scripts/ # Seeds, SQL de RLS, utilitários
├── bin/start.cjs # Launcher dual-process (Next.js + workers)
├── proxy.ts # Middleware Clerk (isolamento de roles por painel)
├── instrumentation.ts # Boot do scheduler no startup
├── Dockerfile # Multi-stage node:20-alpine
├── docker-compose.yml # Container único (app + workers via bin/start.cjs)
└── docker-compose.prod.yml # Produção com workers segregados (11 serviços)
Como rodar
Pré-requisitos
- Node.js 20+
- PostgreSQL
- Redis (o sistema usa até 3 instâncias — sistema, dispatch e notificações; na ausência das URLs dedicadas, tudo cai no
REDIS_URLprimário) - Conta Clerk (chaves de API)
- Arquivo
.envna raiz com as variáveis listadas abaixo
Desenvolvimento local
npm install # instala dependências (roda postinstall do Next)
npm run db:migrate # aplica as 109 migrations (Drizzle Kit)
npm run db:seed-demo # (opcional) dados de demonstração
npm run dev # apenas o Next.js na porta 3001
npm run dev:all # Next.js + 9 workers via concurrently (recomendado)
A aplicação sobe em http://localhost:3001.
Workers e banco
npm run workers:all # todos os workers em um único processo (all-workers.ts)
npm run dev:worker # worker individual (message-sender), etc.
npm run db:generate # gera nova migration a partir do schema
npm run db:migrate # aplica migrations
npm run db:push # push direto do schema (apenas dev)
npm run db:studio # Drizzle Studio (GUI)
npm run db:seed-pricing # seed de preçário
npm run db:seed-volume # seed de volume (testes de carga)
npm run db:seed-coupons # seed de cupons
Docker
# Container único: Next.js + workers no mesmo processo via bin/start.cjs
docker compose up -d --build # usa docker-compose.yml (porta 3001)
# Produção com workers segregados (11 serviços: app + 9 workers + worker-all)
docker compose -f docker-compose.prod.yml up -d --build
O Dockerfile é multi-stage (node:20-alpine): stages builder, prod-deps, worker e runner. O bin/start.cjs gerencia o ciclo de vida dual-process (servidor Next.js standalone + workers) e propaga sinais de shutdown.
Variáveis de ambiente
Documentação completa em docs/ARCHITECTURE.md (seção 15). Somente os nomes das variáveis principais (valores ficam no .env, fora do controle de versão):
| Grupo | Variáveis |
|---|---|
| Banco | DATABASE_URL |
| Redis | REDIS_URL, REDIS_DISPATCH_URL, REDIS_NOTIFICATION_URL |
| Auth (Clerk) | NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY, CLERK_SECRET_KEY, NEXT_PUBLIC_CLERK_SIGN_IN_URL, NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL |
| Segurança | DB_ENCRYPTION_KEY (AES-256-GCM das credenciais de providers), WEBHOOK_SECRET |
| Meta Cloud API | META_WEBHOOK_VERIFY_TOKEN, META_WEBHOOK_APP_SECRET |
| UZApi | UAZAPI_WEBHOOK_SECRET |
| Billing | INFINITEPAY_API_KEY, INFINITEPAY_WEBHOOK_SECRET, PIXGO_API_KEY, PIXGO_BASE_URL, PIXGO_WEBHOOK_SECRET |
| IA / enrich | GEMINI_API_KEY, CHECKNUMBER_API_KEY |
| Aplicação | NEXT_PUBLIC_APP_URL, PORT, NODE_ENV, USE_CAMPAIGN_CONTROLLER (ativa o modo controller: micro-batches + back-pressure) |
Nunca commite valores dessas variáveis. Tokens de providers são armazenados criptografados no banco, não no env.
Testes
npm test # testes unitários (Vitest, __tests__/lib/)
npm run test:watch # modo watch
npm run test:coverage # relatório de cobertura
npx playwright test # E2E (Playwright, e2e/, baseURL http://localhost:3001)
npm run lint # ESLint (@typescript-eslint)
O projeto conta com 20 arquivos de testes unitários e 2 specs E2E. O auditor externo e as correções aplicadas estão documentados em SECURITY-AUDIT.md e docs/others/AUDIT-FIXES-APPLIED.md (pentest concluído com risco baixo).
Documentação interna
Documentação detalhada no diretório docs/:
| Documento | Conteúdo |
|---|---|
docs/ARCHITECTURE.md |
Arquitetura completa: camadas, filas, pipeline, env vars |
docs/DATABASE.md |
Schema do banco, relações e índices |
docs/QUEUE-SYSTEM.md |
Filas BullMQ, workers e jobs cron |
docs/PROVIDERS.md |
Providers de mensagem (Meta, UZApi, Simulator) |
docs/AUTHENTICATION.md |
Bridge Clerk, roles e middleware |
docs/BILLING-SYSTEM.md e docs/gateways.md |
Billing, InfinitePay/PixGo, multi-gateway |
docs/META-INTEGRATION.md |
Integração Meta WhatsApp Cloud API |
docs/NOTIFICATIONS-SYSTEM.md |
Notificações in-app, e-mail e WhatsApp |
docs/DEPLOYMENT.md |
Infraestrutura e deploy (Docker, topologia) |
docs/DEVELOPER-GUIDE.md |
Guia de desenvolvimento e convenções |
docs/CLAUDE.md |
Diretrizes para agentes de IA (Claude Code) |
SECURITY-AUDIT.md |
Auditoria de segurança (pentest, risco baixo) |
Origem do repositório
Este repositório foi migrado do GitLab para o OmniGit em 22/10/2026:
- Origem:
gitlab.com/evolx.mkt/evolx-whatsapp-marketing - Destino: https://omnigit.dev/BLITZAP/evolx-whatsapp-marketing
O histórico completo de commits foi preservado na migração. O desenvolvimento continua exclusivamente no OmniGit.
© EVOLX / Blitzap. Todos os direitos reservados.