JuscIA · jul a out 2026 · manutenção ativa
JuscIA
Plataforma jurídica SaaS com inteligência artificial, resgatada de dois anos sem versão estável e reconstruída em Google Cloud.
1M+
requisições por semana, de forma estável
< R$ 700
de custo mensal de infraestrutura no GCP
~75%
de redução no custo de infraestrutura
Resumo do que fiz
- Plataforma estabilizada em um mês, depois de dois anos sem versão estável com a equipe anterior.
- Arquitetura reconstruída em Google Cloud: mais de 1 milhão de requisições por semana com infraestrutura abaixo de R$ 700 por mês, cerca de 75% mais barata.
- 24 falhas graves de segurança corrigidas, de brechas de acesso entre escritórios a injeção de SQL.
- Testes de 8 para 63 arquivos, 77 migrações versionadas e processos em produção de 6 para 1.
- Painel de controle de 13 telas construído do zero e 282 endpoints sob um padrão único.
Tecnologias
Req. / semana
1M+
Infra / mês
< R$700
Usuários
2.951
Requisições por semana
produçãoGoogle Cloud · PostgreSQL · CDN · CI/CD
A virada
O que mudou no projeto
A Juscia me chamou depois de dois anos com uma equipe interna que nunca conseguiu estabilizar o produto. Entrei, auditei o que existia, reescrevi a base da aplicação e, em um mês, entreguei o que a equipe anterior dizia não ser possível. É o tipo de trabalho que faço: encontrar falhas, arquitetura ruim e código ruim, e corrigir. Os números abaixo foram apurados no próprio repositório do projeto.
1 mês
Para estabilizar o que 2 anos de equipe anterior não conseguiram.
< 1 semana
Para entregar dois recursos que a equipe anterior dizia serem impossíveis.
< 10%
Era a satisfação dos usuários antes de eu assumir o projeto.
24
Falhas graves de segurança corrigidas, da senha universal a brechas de acesso entre escritórios.
Arquitetura
A infraestrutura antes e depois
Cada linha da coluna da esquerda é o estado que encontrei. À direita, o que ficou no lugar.
Antes
Depois
Problema e solução
Ponto a ponto, o que estava errado e o que fiz
Cada par mostra o problema encontrado e a correção aplicada.
O que encontrei
Tudo numa única VM
API e serviços auxiliares dividiam a mesma máquina virtual, sem separação, sem redundância e sem capacidade de escalar. Qualquer pico de uso ou falha atingia o sistema inteiro de uma vez.
O que fiz
Infraestrutura reconstruída na Google Cloud
Banco, cache e armazenamento passaram a rodar em serviços dedicados, cada um configurado e protegido por conta própria, no lugar de tudo dividindo a mesma máquina.
O que encontrei
Seis processos rodando em paralelo
Além da API, mais cinco serviços auxiliares escritos em Python ficavam no ar o tempo todo, na mesma máquina, cada um com a própria porta e o próprio ciclo de vida pra alguém acompanhar.
O que fiz
Os cinco serviços em Python saíram do ar
Foram substituídos por filas sobre Redis, rodando dentro da própria API. Cinco processos a menos pra manter no ar, monitorar e reiniciar.
O que encontrei
Follow-up e agendamento sumiam em silêncio
O disparo dependia de uma chamada HTTP direta pra esses serviços auxiliares. Se o processo estivesse fora do ar ou reiniciando, a falha era engolida: não havia retentativa, não havia alerta, e o follow-up simplesmente desaparecia sem ninguém ficar sabendo.
O que fiz
Agendamento e follow-up viraram jobs persistentes
Cada tarefa entra numa fila que sobrevive a reinício do servidor, com 3 retentativas automáticas e espera crescente entre elas. Se algo falha, a fila tenta de novo em vez de perder o trabalho.
O que encontrei
Treze falhas de acesso entre escritórios
Um usuário autenticado de um escritório conseguia ler, editar ou apagar dados de outro escritório apenas trocando um identificador numérico na requisição. Eram treze pontos diferentes do sistema, da transferência de conversa aos quadros de kanban.
O que fiz
Treze falhas de acesso fechadas
O escopo do cliente passou a ser aplicado em todas as consultas. Pedir o dado de outro escritório agora devolve 404 em vez de entregar o registro.
O que encontrei
Rotas sem autenticação e uma injeção de SQL
Cinco endpoints respondiam a qualquer um que os chamasse, sem exigir login, um deles devolvendo a lista completa de usuários com e-mail. Uma rota de contagem também tinha uma injeção de SQL, por montar a consulta concatenando texto.
O que fiz
Rotas abertas fechadas e injeção de SQL corrigida
As cinco rotas sem autenticação passaram a exigir login, e a consulta vulnerável foi reescrita com parâmetros.
O que encontrei
Webhooks abertos
Os webhooks aceitavam qualquer chamada, sem validar a origem. Na prática, dava pra forjar um evento de entrada e fazer o sistema reagir a algo que nunca aconteceu.
O que fiz
Webhooks passaram a validar origem
Cada chamada precisa apresentar o token da instância. O que não valida é descartado.
O que encontrei
Credenciais escritas no código
Chaves de serviços externos estavam fixas no código-fonte. Quem tivesse acesso ao repositório, ou ao histórico dele, tinha as credenciais junto.
O que fiz
Credenciais fora do código
Todas as chaves saíram do código-fonte e passaram a vir de variáveis de ambiente.
O que encontrei
CORS liberado e sem cabeçalhos de segurança
A API aceitava requisição de qualquer origem e não enviava nenhum dos cabeçalhos de segurança que o navegador usa pra proteger o usuário.
O que fiz
CORS restrito e cabeçalhos de segurança aplicados
A API passou a aceitar só as origens conhecidas e a enviar os cabeçalhos de segurança que o navegador usa pra proteger o usuário.
O que encontrei
Uma senha universal abria qualquer conta
Existia uma senha única que dava acesso a qualquer conta do sistema, prática que a equipe anterior considerava aceitável.
O que fiz
Senha universal removida
No lugar dela, senha temporária gerada sob demanda no painel de controle: válida por 30 minutos, restrita a uma única conta, revogável a qualquer momento, guardada apenas como hash e exibida uma única vez a quem a gerou. A senha do próprio cliente continua valendo e não muda.
O que encontrei
Token de autenticação no localStorage
O token ficava guardado no armazenamento local do navegador, de onde qualquer script rodando na página consegue lê-lo.
O que fiz
Autenticação reescrita com dois tokens
O token de acesso vive só em memória e dura 15 minutos. A renovação fica num cookie httpOnly, que o JavaScript da página não consegue ler. Nenhum token voltou a ser gravado no navegador.
O que encontrei
Dados pessoais nos rastros de telemetria
Telefone, nome e conteúdo de mensagem do WhatsApp eram gravados nos rastros de monitoramento da aplicação, sem nenhuma anonimização, fora de conformidade com a LGPD.
O que fiz
Dados pessoais fora da telemetria
Telefone, nome e conteúdo de mensagem deixaram de ser gravados nos rastros de monitoramento, em conformidade com a LGPD.
O que encontrei
Banco sincronizado automaticamente em produção
O ORM alterava o esquema do banco sozinho a cada subida, sem migração versionada. O que existia eram dez arquivos SQL soltos, sem controle de ordem e sem histórico confiável do que já tinha sido aplicado.
O que fiz
Banco sob controle de migrações
A sincronização automática de esquema foi desligada em produção. Hoje são 77 migrações versionadas, aplicadas em ordem e com histórico do que já rodou.
O que encontrei
IDs sequenciais e fáceis de adivinhar
As tabelas centrais do banco usavam identificador numérico sequencial, o tipo de chave que facilita adivinhar o próximo registro só somando um ao anterior, exatamente o que abria as falhas de acesso entre escritórios.
O que fiz
Chaves primárias migradas para UUID
As 12 tabelas centrais deixaram de usar inteiro sequencial. Além de facilitar integração, tira do caminho a adivinhação de identificador que abria as falhas de acesso.
O que encontrei
Oito arquivos de teste no projeto inteiro
O back-end inteiro tinha oito arquivos de teste automatizado. Na prática, quase toda mudança dependia de teste manual pra não quebrar alguma coisa.
O que fiz
Suíte de testes de 8 para 63 arquivos
Mais de 770 testes rodando na última execução registrada, cobrindo o caminho crítico do sistema.
O que encontrei
Serviços gigantes, difíceis de manter
Alguns serviços chegavam a mais de 1.800 linhas de código numa função só, o que tornava qualquer mudança arriscada e praticamente impossível de testar em partes.
O que fiz
Serviços gigantes decompostos
Entre eles, um de 1.800 linhas. A quebra foi feita sempre começando pelos testes, pra garantir que o comportamento não mudasse no caminho.
O que encontrei
Consultas N+1 nos relatórios
Relatórios, dashboard e kanban faziam uma consulta ao banco pra cada item da lista, em vez de uma consulta só trazendo tudo de uma vez. Quanto mais dado, mais lenta ficava a tela.
O que fiz
Três consultas em cascata eliminadas
Relatórios, dashboard e kanban faziam uma consulta por item retornado. Viraram uma consulta agregada só.
O que encontrei
Relatório de vendas somava o escritório inteiro
O número de vendas mostrado pra um atendente era, na prática, a soma do escritório inteiro, não o total individual dele.
O que fiz
Erro de escopo em relatório corrigido
Cada atendente estava vendo o total do escritório inteiro no lugar do próprio número.
O que encontrei
Uma falha derrubava o servidor inteiro
Um erro no envio de uma única mensagem não ficava contido: derrubava o processo e, com ele, o sistema todo.
O que fiz
Falha de envio isolada
Um erro ao enviar uma mensagem passou a ficar contido nela mesma, sem derrubar o restante do sistema.
O que encontrei
Deploy manual aos domingos, sem esteira de integração contínua
Publicar uma versão era procedimento manual, só feito na madrugada de domingo pra reduzir o risco de atrapalhar quem estava usando. Não havia verificação automática a cada mudança: as checagens de qualidade existiam apenas num gancho local de commit, que qualquer pessoa podia pular.
O que fiz
Esteira de deploy automatizada
Publicar deixou de ser procedimento manual de madrugada de domingo.
O que encontrei
Interface difícil até pro básico
A interface era pouco funcional a ponto de tarefa simples do dia a dia virar obstáculo.
O que fiz
Front-end migrado para Angular 18
Com design system próprio baseado em tokens: uma fonte única de verdade pra cor, espaçamento e tipografia, no lugar de valor solto espalhado pelas telas.
O que encontrei
Bot e CRM sem funcionar
O bot de atendimento respondia errado quando respondia, e o CRM estava praticamente fora de uso.
O que fiz
Tema claro e escuro completo
A paleta foi gerada a partir da marca da Juscia, com contraste verificado, e o tema acompanha a preferência do sistema operacional.
O que encontrei
Paleta de gráficos ilegível pra quem tem daltonismo
As cores usadas nos gráficos ficavam praticamente indistinguíveis pra quem tem os tipos mais comuns de daltonismo, sem nenhuma validação de contraste entre elas.
O que fiz
Paleta de gráficos validada para daltonismo
As séries continuam distinguíveis nos três tipos de deficiência de visão de cores, verificado por medição de distância de cor, não no olho.
O que encontrei
Cinquenta e seis erros de acessibilidade no front-end
O front-end tinha 56 problemas de acessibilidade identificados, do tipo que dificulta o uso por quem depende de leitor de tela ou navegação por teclado.
O que fiz
Cinquenta e seis erros de acessibilidade corrigidos
E a verificação passou a travar a entrega se algum voltar.
O que encontrei
Dois anos sem uma versão estável
O projeto rodava havia dois anos e nunca tinha chegado a uma versão que a própria equipe considerasse estável em produção.
O que fiz
Carregamento com esqueleto de conteúdo
No lugar de giradores, cada tela mostra um esqueleto com as mesmas medidas do conteúdo real, então a página não pula quando os dados chegam.
O que encontrei
Nenhum painel de controle
A equipe da Juscia não tinha nenhuma tela administrativa. Qualquer ação de gestão precisava ser feita direto no banco de dados.
O que fiz
Painel de controle construído do zero
Treze telas, onde antes não havia nenhuma.
O que encontrei
Satisfação abaixo de 10%
Menos de um em cada dez usuários se dizia satisfeito com a plataforma.
O que fiz
Planos modulares e acompanhamento de processos
Os dois recursos que a equipe anterior dizia serem impossíveis, entregues e funcionais em menos de uma semana.
O que encontrei
Infraestrutura cobrando pelo que ninguém usava
O custo não tinha relação com o tamanho da base de usuários. Havia revisões antigas do serviço esquecidas no ar, sendo cobradas todo mês sem atender ninguém.
O que fiz
Custo de infraestrutura reduzido em cerca de 75%
Revisões ociosas desligadas e recursos redimensionados pro uso real, sem tirar capacidade de quem usa.
O que encontrei
Código sem padrão nenhum entre as partes do sistema
Cada parte do sistema seguia uma convenção diferente de código e de arquitetura, sem nada documentado pra próxima pessoa seguir.
O que fiz
Padronização de código e arquitetura
Um padrão único em todo o back-end, com as decisões de arquitetura registradas e documentação escrita por módulo, pra próxima pessoa não precisar adivinhar o porquê.
Entrega
Os números apurados no repositório
Nenhum número aqui é estimativa: todos saíram do próprio repositório do projeto.
24
Falhas de segurança corrigidas, de brechas de acesso a credenciais expostas.
~75%
De redução no custo mensal de infraestrutura.
282
Endpoints que a API expõe hoje, sob um padrão único.
13
Telas no painel de controle que a Juscia não tinha antes.
Migrações de banco versionadas
arquivos de migração
No lugar da sincronização automática de esquema direto em produção.
Arquivos de teste no back-end
arquivos de teste
Mais de 770 testes rodando na última execução registrada.
Processos rodando em produção
processos
Os cinco serviços auxiliares em Python viraram filas dentro da própria API.
Cobertura de testes
Linhas cobertas
Última medição registrada, partindo de 8 arquivos de teste no projeto inteiro.
Falhas de segurança corrigidas, por tipo
Frentes de trabalho
Tudo que foi feito, por área
A entrega dividida nas frentes que ela realmente teve.
Segurança e acesso
Da senha universal às brechas entre escritórios, o que protegia menos do que devia.
Senha universal removida
Substituída por senha temporária de 30 minutos, gerada sob demanda, restrita a uma conta e revogável.
Senha guardada só como hash
Exibida uma única vez a quem a gerou, nunca guardada em texto puro depois disso.
Treze brechas de acesso fechadas
Escopo do cliente aplicado em todas as consultas, entre escritórios diferentes.
Rotas abertas e injeção de SQL corrigidas
Cinco rotas sem autenticação passaram a exigir login, e a consulta vulnerável foi corrigida.
Tokens fora do navegador
Acesso em memória por 15 minutos, renovação num cookie httpOnly que o JavaScript não lê.
Cabeçalhos de segurança e CORS restrito
A API só aceita as origens conhecidas e envia os cabeçalhos que protegem o usuário.
Dados pessoais fora da telemetria
Telefone, nome e mensagem deixaram de ser gravados nos rastros de monitoramento, em conformidade com a LGPD.
Auditoria e bloqueio de IP
Tela de saúde do sistema, com bloqueio de IP manual ou automático.
Confiabilidade da operação
Onde a operação parava de responder, e como ela passou a se recuperar sozinha.
Cinco serviços em Python saíram do ar
Viraram filas rodando dentro da própria API.
Jobs persistentes
Agendamento, follow-up e resposta sobrevivem a reinício do servidor.
Três retentativas automáticas
Por job, com espera crescente entre uma tentativa e outra.
Falha de envio isolada
Um erro ao enviar uma mensagem não derruba mais o restante do sistema.
Três consultas em cascata eliminadas
Nos relatórios, no dashboard e no kanban.
Erro de escopo em relatório corrigido
Cada atendente via o total do escritório inteiro; agora vê só o próprio número.
Banco e arquitetura
Como os dados e o código passaram a ter controle de versão e um padrão único.
Sincronização automática desligada
O esquema do banco não muda mais sozinho em produção.
77 migrações versionadas
Assumiram o controle do banco, em ordem e com histórico do que já rodou.
Chaves primárias em UUID
Nas 12 tabelas centrais, no lugar do inteiro sequencial fácil de adivinhar.
Serviços gigantes decompostos
A quebra foi feita sempre começando pelos testes.
Tipos em modo estrito
Verificação ligada em todo o projeto, não só em partes novas.
Decisões de arquitetura registradas
Documentação escrita por módulo, pra próxima pessoa não precisar adivinhar o porquê.
Interface e experiência
Do framework à acessibilidade, o que mudou pra quem usa o sistema todo dia.
Front-end migrado para Angular 18
A base do front-end saiu de uma versão antiga direto pro Angular 18.
Design system baseado em tokens
Uma fonte única de verdade pra cor, espaçamento e tipografia.
Tema claro e escuro completo
Segue a preferência do sistema operacional automaticamente.
Paleta gerada a partir da marca
Contraste verificado, não só escolhido no olho.
Paleta de gráficos validada
Pros três tipos mais comuns de daltonismo.
56 erros de acessibilidade corrigidos
A verificação trava a entrega se algum erro voltar.
Esqueleto de conteúdo no carregamento
No lugar de giradores, espelhando o layout real da tela.
Avisos e erros unificados
Numa camada só, no lugar de vários padrões espalhados.
Painel de controle, que não existia
Treze telas que a equipe da Juscia não tinha antes, construídas do zero.
13 telas construídas do zero
Onde antes não havia nenhuma tela administrativa.
Visão geral da operação
Usuários, planos, pacotes e cupons, tudo numa tela só.
Agentes e custos
Custo de IA e custo de consulta processual.
Processos
Lista e o detalhe de cada um.
Auditoria e saúde do sistema
Acompanhamento do estado geral da operação.
IPs bloqueados
Bloqueio manual ou automático, com histórico de tentativas.
Senha temporária pelos gerentes
Emissão e revogação de senha temporária pra qualquer conta, direto do painel.
Confiabilidade
Como a operação passou a se comportar
Resultado
O que a virada entregou na prática
Sistema estável e no ar
Em um mês, depois de dois anos sem conseguir sair do lugar.
Nada mais se perde
Mensagem, follow-up ou agendamento: tudo virou job persistente com retentativa automática.
24 falhas de segurança corrigidas
Entre elas, treze brechas de acesso a dados de outro escritório.
Acesso administrativo sempre temporário
Gerado sob demanda, sem nenhuma senha universal.
Painel de controle com 13 telas
Usado todos os dias pelos gerentes da Juscia.
Banco sob controle de 77 migrações
No lugar da sincronização automática em produção.
Suíte de testes, de 8 para 63 arquivos
Mais de 770 testes rodando na última execução registrada.
Custo de infraestrutura, cerca de 75% menor
Redução no custo mensal de infraestrutura.
Custo de operação reduzido
A uma fração do que a equipe interna anterior consumia.
Recursos antes vistos como inviáveis, no ar
Hoje em produção e usados pelos clientes da Juscia.
Próximo projeto
Toca aê