Estudo de caso
Quimia — painel administrativo com auditoria e restauração de exclusões
Painel em Spring Boot para gerenciar o Quimia, com login seguro, log de tudo que muda e desfazer exclusões.
Stack
Java 25
Spring Boot 4.1
Spring Security
- Thymeleaf
- Spring Data JPA
PostgreSQL
JUnit 5
GitHub Actions
Contexto
O Quimia ajuda pessoas a evitar misturas perigosas de produtos de limpeza, registrando estoque, usos, misturas e descartes. Empresas parceiras cadastram seus produtos e acompanham o uso. O painel administra usuários, empresas, produtos, prateleiras, históricos e descartes. Projeto em equipe, desenvolvido para a ExpoTech 2026.
Problema
Um painel que apaga e altera dados de verdade precisa ser seguro e reversível. Era preciso saber quem mudou o quê, conseguir desfazer uma exclusão com dependências em cascata e não abrir brechas em login, formulários e upload de fotos.
Decisões
- Auditoria completa. Toda criação, edição e exclusão feita pela interface é registrada com o admin responsável e os dados anteriores. Senhas nunca entram no log.
- Exclusão reversível. Antes de apagar, o conjunto de linhas vai para o log em JSON. Isso permite restaurar com os IDs originais. Exclusão e restauração rodam em uma única transação: se um passo falha (por exemplo, e-mail já em uso), nada muda.
- O banco é a fonte do esquema. Com
ddl-auto=validate, a aplicação só sobe se as entidades batem com o banco real. - CRUD genérico reaproveitado.
CrudService,GenericControllereListControlleratendem as 11 telas; adicionar uma tela nova é preencher um roteiro conhecido (entidade, DTO, mapper, service, controller e template). - Segurança em camadas: senhas com Argon2id; bloqueio de 15 minutos após 5 falhas seguidas de login; só admins com status ATIVO entram; CSRF ligado e logout só por POST; Content Security Policy restrita ao mesmo domínio; cookie de sessão HttpOnly e SameSite=Lax, com expiração de 30 minutos.
- Upload de foto defensivo. O tipo do arquivo é identificado pelos bytes, e não pela extensão; a imagem é recodificada (o que remove metadados e conteúdo escondido); o nome é aleatório; limite de 2 MB e 4096 px por lado.
- Nomes de coluna em ações em massa vêm de uma lista permitida, porque entram em SQL.
- Painel rápido. O dashboard lê uma view materializada em uma consulta só, atualizada a cada 2 horas por um workflow e sob demanda por um botão, e as proteções impedem um segundo clique durante a atualização.
Qualidade
Mais de 160 testes (JUnit 5, @WebMvcTest, @SpringBootTest e Spring Security Test) que rodam sem banco. Há testes que pegam desalinhamento entre telas e repositórios, e um teste opcional que apaga e restaura um registro de cada tipo no banco real, dentro de uma transação sempre revertida.
Processo da equipe
Branches a partir de develop com prefixos (feat/, fix/, refactor/, test/, chore/), Conventional Commits e pull request com revisão. Nada vai direto para a main.
Resultado
Um painel com 11 telas, auditoria de ponta a ponta e exclusões reversíveis, coberto por mais de 160 testes automatizados.
Limitações e próximos passos
O SQL da view materializada não está versionado em nenhum dos repositórios, e o contador de tentativas de login fica em memória. Ambos são melhorias claras.