Plataforma de Operações para Agência
Uma plataforma de gestão que substitui um conjunto disperso de ferramentas SaaS e um sistema legado: vendas de três plataformas de checkout, espelho do CRM, WhatsApp, RH e uma base única de clientes — com agentes de IA que trabalham sobre os mesmos dados e permissões.
- Cliente
- Agência de marketing digital e educação (nome omitido)
- Papel
- Arquitetura, backend (Java/Spring), frontend (Angular), CI/CD e deploy
- Ano
- 2026
- Status
- Em produção desde outubro de 2026
20
módulos Spring Modulith, com fronteiras verificadas por testes
≈420
queries e mutations GraphQL
1,330+
testes de backend com PostgreSQL e Redis reais
45 s → 18 ms
consulta de dashboard após análise
Contexto
A agência operava sobre várias plataformas SaaS — checkouts, um CRM, WhatsApp, funis de quiz — além de um sistema interno de primeira geração cujo banco chegou a 20 GB, quase tudo JSON bruto. Os dados eram duplicados, as permissões eram grosseiras e os relatórios eram montados à mão.
O problema
Construir do zero um sistema de segunda geração que receba tudo com confiabilidade, unifique os dados em uma única base de clientes, dê a cada equipe exatamente o acesso de que precisa e torne a IA útil sobre dados reais sem abrir brechas de segurança.
O que eu fiz
- 01
Projetei a arquitetura: um monólito modular com Spring Modulith (20 módulos), camadas no estilo DDD e um caso de uso por ação.
- 02
Construí a API GraphQL, as integrações e a camada de IA em Java 25 e Spring Boot 4.1.
- 03
Construí o frontend em Angular 21 (zoneless, signals) com cliente GraphQL tipado e atualizações em tempo real via Server-Sent Events.
- 04
Montei o CI/CD e a produção: Docker, Caddy e GitHub Actions, com deploy verificado por health check e rollback automático.
O que faz
- Espelho de três plataformas de checkout — vendas, assinaturas, carrinhos abandonados — com cargas históricas retomáveis e respeitando limites de requisição
- Espelho do CRM e arquivo de conversas do WhatsApp
- Base única de clientes com resolução de identidade e mesclas auditadas e reversíveis
- Ciclos de vendas com metas, atribuição por vendedor, dashboards ao vivo e fechamento de período
- Cadastro de RH com histórico de cargos e remuneração
- Motor de fluxos interno para relatórios agendados por e-mail e WhatsApp
- Assistente de IA e agentes de atendimento com IA no WhatsApp
- Servidor MCP para clientes de IA externos consultarem o sistema via OAuth 2.1
Destaques de engenharia
- 01
Fronteiras garantidas pelo build
Os módulos só conversam por interfaces nomeadas e eventos. Um teste de modularidade quebra o build em qualquer violação, e um teste de padrões lê cada arquivo Java com a API de árvore do javac para garantir as regras de arquitetura.
- 02
Autorização como dado
Um interceptador próprio, @AccessRoute, cobre 649 rotas com escopos todos/equipe/próprio, e os perfis são modelos vivos editados na interface. Sessões no Redis com MFA por e-mail e login Google; campos sensíveis com AES-256-GCM e índice cego.
- 03
Webhooks que nunca se perdem
Uma caixa de entrada só confirma após um commit em grupo. Workers pegam lotes com FOR UPDATE SKIP LOCKED, mantêm a ordem por chave, refazem com backoff e verificam assinaturas HMAC — alguns provedores nunca reenviam um webhook que falhou.
- 04
IA que respeita permissões
Agentes com Spring AI usam 122 ferramentas que rodam com as permissões do próprio dono da conversa, e gravações exigem confirmação explícita. RAG com pgvector (HNSW), memória de chat no Redis, saída estruturada validada e custo de cada chamada conciliado com o faturamento da nuvem.
- 05
GraphQL em escala
≈200 queries e ≈220 mutations sobre 183 entidades JPA, com DataLoader em lote, paginação por cursor, limites de profundidade e complexidade e rate limit por conta no Redis.
- 06
Deploys que não perdem trabalho
O Caddy refaz requisições durante reinícios, o desligamento gracioso termina respostas de IA em andamento e as respostas ficam salvas no PostgreSQL para sobreviver a um deploy.
Partes difíceis
- 01
Concorrência na ingestão
Advisory locks do PostgreSQL, novas tentativas com lock otimista e a regra de nenhuma chamada externa dentro de transações impedem que webhooks paralelos corrompam a base de clientes.
- 02
Resolução de identidade
Mesclar clientes por e-mail, telefone e CPF/CNPJ pode encadear falsos positivos enormes. Regras de força de chave e um limite de chave compartilhada evitam mesclas descontroladas, e qualquer mescla pode ser desfeita.
- 03
Limites de APIs de terceiros
Cargas históricas são divididas em unidades diárias reservadas com SKIP LOCKED, limitadas por minuto e retomáveis após um 429 ou uma pausa manual.
Resultados
- Em produção desde outubro de 2026, substituindo o sistema de primeira geração.
- Consulta “hoje” do dashboard: 45 s → 18 ms. Página inicial da equipe: 37,6 s → 47 ms.
- Exportação de 31 dias de mensagens (1,1 mi de mensagens, numa base de teste de 8 mi) em 32–64 s de tempo de banco.
- ≈1.330 testes de backend com Testcontainers e ≈790 testes de frontend; CI com deploy verificado por health check e rollback automático.
Os números vêm do repositório: testes, medições e relatórios documentados.
Stack
- Java 25
- Spring Boot 4.1
- Spring Modulith
- Spring Security 7
- Spring AI 2.0
- GraphQL
- PostgreSQL · pgvector
- Redis
- Flyway
- Testcontainers
- Docker
- Caddy
- GitHub Actions
- Angular 21
- TypeScript
- Tailwind CSS 4
ProcessoConstruído com um fluxo assistido por IA dirigido por mim: defini a arquitetura e os contratos, escrevi e aprovei o plano de cada etapa e revisei cada mudança antes do merge — cerca de 1.800 commits no backend e 590 no frontend.
Código e cliente são privados. Os detalhes são compartilhados até onde o trabalho permite.