Implementação da user story de Solicitação de Acesso para o teste técnico Java Pleno da Supera. O projeto expõe uma API REST protegida por JWT, aplica todas as regras de negócio descritas no enunciado e entrega infraestrutura dockerizada com balanceamento via Nginx e três instâncias da aplicação.
Ambiente em produção
- Arquitetura da Solução
- Tecnologias e Versões
- Pré-requisitos
- Configuração de Ambiente
- Execução com Docker Compose
- Execução Local
- Testes, Cobertura e Relatório JaCoCo
- Credenciais de Teste
- Exemplos de Requisições
- Regras de Negócio Implementadas
- Nginx distribui requisições HTTP entre três instâncias idênticas (
app1,app2,app3). - PostgreSQL 17 recebe as migrações Flyway (estrutura + seeds de usuários e módulos).
- Spring Boot 3.5 provê autenticação JWT, validações e exposição da API REST.
- Swagger acessível via
http://localhost/swagger-ui.htmlatravés do proxy Nginx.
Visão macro do sistema e seus atores externos.
Detalha a infraestrutura Docker, balanceamento de carga e comunicação entre containers conforme compose.yaml e nginx.conf.
Detalha a estrutura interna da API Spring Boot, mapeando Controllers, Services, Repositories, Validações e Camada de Segurança implementados.
- Nível 1 (Contexto): Mostra o sistema e seus atores externos (usuários, sistemas externos).
- Nível 2 (Container): Detalha a infraestrutura Docker, containers e comunicação entre serviços.
- Nível 3 (Componentes): Expõe a arquitetura interna da aplicação Spring Boot, camadas de segurança, serviços, repositórios e validações.
| Tecnologia | Versão |
|---|---|
| Java | 21 |
| Spring Boot | 3.5.7 |
| Spring Data JPA / Validation / Security | 3.5.x |
| PostgreSQL | 17 |
| Flyway | 10.x |
| Docker / Docker Compose | 26+ / 2.22+ |
| Nginx | 1.27 (alpine) |
| JWT (auth0 java-jwt) | 4.4.0 |
| Instancio | 3.7.1 |
| H2 (somente testes) | 2.2.224 |
| JUnit 5 / Mockito | 5.x / 5.x |
| JaCoCo | 0.8.12 |
- Docker e Docker Compose instalados.
- Java 21 + Maven 3.9 (caso opte por execução local).
- Arquivo
.envna raiz contendo:POSTGRES_DATABASE=accesscontrol POSTGRES_USER=postgres POSTGRES_PASSWORD=postgres JWT_SECRET=sua_chave_super_secreta
-
Linux / Ubuntu
openssl rand -base64 64 | tr -d '\n'; echo
Copie o valor exibido acima para a variável
JWT_SECRET. -
Windows (PowerShell)
[Convert]::ToBase64String((New-Object System.Security.Cryptography.HMACSHA256).Key)
O valor retornado pode ser reutilizado no
.envou em um secret do ambiente.
- Clone o repositório.
- Crie o
.envconforme acima. - (Opcional) Ajuste portas no
compose.yaml.
docker compose up --buildServiços expostos:
- Nginx (proxy + Swagger):
http://localhost - Aplicações (acesso direto):
http://localhost:8080(caso queira bypass do proxy) - PostgreSQL:
localhost:5432
Health checks:
http://localhost/actuator/health(via proxy)
Para encerrar e limpar:
docker compose down -v- Suba o PostgreSQL localmente (docker ou instalador).
- Exporte as mesmas variáveis do
.envou configure noapplication.yml. - Execute:
./mvnw spring-boot:run
- Acesse
http://localhost:8080/swagger-ui.html.
Executar toda a suíte com H2 in-memory:
./mvnw clean test- Cobertura mínima configurada: 90% (plugin JaCoCo falha o build abaixo disso).
- Relatórios:
- HTML:
target/site/jacoco/index.html - PDF:
docs/jacoco-report.pdf(gerado automaticamente após os testes)
- HTML:
O relatório PDF é gerado automaticamente após executar os testes via Maven (mvn verify ou mvn test seguido de mvn jacoco:report).
Para gerar manualmente:
Windows (PowerShell):
.\generate-pdf-report.ps1Linux/Mac ou Windows (Maven):
./mvnw jacoco:report
./mvnw exec:java -Dexec.mainClass=com.cordeirops.accesscontrol.util.HtmlToPdfConverterO PDF será gerado/atualizado em docs/jacoco-report.pdf com a cobertura atualizada.
| Departamento | Senha | |
|---|---|---|
| TI | admin.ti@company.com.br |
123456 |
| Financeiro | ana.fin@company.com.br |
123456 |
| RH | carlos.rh@company.com.br |
123456 |
| Operações | joao.ops@company.com.br |
123456 |
Todos os usuários são criados via migrações Flyway (
V2__insert_inital_data.sql).
curl -X POST http://localhost/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"admin.ti@company.com.br","password":"123456"}'curl -X POST http://localhost/auth/refresh \
-H "Content-Type: application/json" \
-d '{"refreshToken":"<token obtido no login>"}'curl -X POST http://localhost/access-requests \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"moduleIds":[3,4],
"justification":"Necessito dos módulos para análises financeiras semanais detalhadas.",
"urgent":false
}'curl -X POST http://localhost/access-requests/1/cancel \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"reason":"Atividade encerrada"}'Todas as rotas estão documentadas em /swagger-ui.html.
- Autenticação: JWT com expiração de 15 minutos, passwords com BCrypt e
SecurityFiltergarantindo autorização em todos os endpoints. Refresh tokens persistidos (72h) são emitidos no login e rotacionados via/auth/refresh. - Solicitação:
- 1–3 módulos, justificativa 20–500 caracteres, sem textos genéricos (validador customizado).
- Verificação automática de solicitações pendentes e acessos ativos (renovação respeita exceções).
- Protocolo único
SOL-YYYYMMDD-NNNN. - Histórico de alterações persistido (
AccessRequestHistory) e vínculo de renovações viaparentRequest. - Módulos incompatíveis checados tanto entre os solicitados quanto contra os já ativos do usuário.
- Limite de módulos ativos (5 ou 10 para TI) contabilizando apenas novos módulos.
- Consulta e Detalhes:
- Filtros por texto, status, período, urgência e paginação (10 itens).
- Resposta inclui módulos, status, datas, motivo de negação, expiração e histórico completo.
- Renovação:
- Apenas para solicitações ativas com <30 dias para expirar, criando novo protocolo vinculado.
- Cancelamento:
- Somente solicitações ativas, exige motivo (10–200 caracteres), revoga acesso e registra histórico.
- Listagem de Módulos:
- Retorna nome, descrição, departamentos permitidos, flag ativo e lista de incompatibilidades.
O código-fonte do frontend React utilizado neste projeto está disponível em https://github.com/cordeirops/accesscontrol-frontend (veja o README.md do repositório para instruções específicas).



