No cooperativismo, cada associado possui um voto e as decisões são tomadas em assembleias, por votação. Imagine que você deve criar uma solução backend para gerenciar essas sessões de votação.
Essa solução deve ser executada na nuvem e promover as seguintes funcionalidades através de uma API REST:
- Cadastrar uma nova pauta
- Abrir uma sessão de votação em uma pauta (a sessão de votação deve ficar aberta por um tempo determinado na chamada de abertura ou 1 minuto por default)
- Receber votos dos associados em pautas (os votos são apenas 'Sim'/'Não'. Cada associado é identificado por um id único e pode votar apenas uma vez por pauta)
- Contabilizar os votos e dar o resultado da votação na pauta
Para fins de exercício, a segurança das interfaces pode ser abstraída e qualquer chamada para as interfaces pode ser considerada como autorizada. A escolha da linguagem, frameworks e bibliotecas é livre (desde que não infrinja direitos de uso).
É importante que as pautas e os votos sejam persistidos e que não sejam perdidos com o restart da aplicação.
- Tarefa Bônus 1 - Integração com sistemas externos
- Integrar com um sistema que verifique, a partir do CPF do associado, se ele pode
votar
- GET https://run.mocky.io/v3/57f23672-c15f-48f8-90d3-d84ce00250b8/users/
- Caso o CPF seja inválido, a API retornará o HTTP Status 404 (Not found)
- Você pode usar geradores de CPF para gerar CPFs válidos
- Caso o CPF seja válido, a API retornará se o usuário pode (ABLE_TO_VOTE) ou não pode (UNABLE_TO_VOTE) executar a operação
- Exemplo de retorno do serviço:
// GET /users/19839091069 // 200 OK { "status": "ABLE_TO_VOTE" } // GET /users/62289608068 // 200 OK { "status": "UNABLE_TO_VOTE" }
- Integrar com um sistema que verifique, a partir do CPF do associado, se ele pode
votar
- Tarefa Bônus 2 - Mensageria e filas
- O resultado da votação precisa ser informado para o restante da plataforma, isso deve ser feito preferencialmente através de mensageria. Quando a sessão de votação fechar, poste uma mensagem com o resultado da votação
- Tarefa Bônus 3 - Performance
- Imagine que sua aplicação possa ser usada em cenários que existam centenas de milhares de votos. Ela deve se comportar de maneira performática nesses cenários
- Testes de performance são uma boa maneira de garantir e observar como sua aplicação se comporta
- Tarefa Bônus 4 - Versionamento da API
- Como você versionaria a API da sua aplicação? Que estratégia usar?
Servidor: https://sessoes-votacao-api.onrender.com
- Java
- SpringBoot
- PostgresSql
- Swagger
- JUnit
- Java JDK 17
- Maven
- Docker
- PostgreSql
A aplicação utiliza o PostgreSQL como banco de dados.
Configure as propriedades no arquivo application.yml
para apontar para o seu banco de dados local.
# Configurações BD local
spring.datasource.url=jdbc:postgresql://localhost:5432/desafiosicredi
spring.datasource.username=postgres
spring.datasource.password=1234
# Configurações BD nuvem
#spring.datasource.url=${DATABASE_URL}
#spring.datasource.username=${DATABASE_USERNAME}
#spring.datasource.password=${DATABASE_PASSWORD}
- Certifique-se de ter o JDK 17 e o Maven instalados.
- Execute o seguinte comando na raiz do projeto:
mvn spring-boot:run
- Acesse a aplicação em http://localhost:8080
- Construa a imagem Docker:
docker build -t backend-api:latest .
- Execute o contêiner Docker:
docker run -p 8080:8080 backend-api
- Acesse a aplicação em http://localhost:8080
Primeiramente gostaria de agradecer a incrivel oportunidade!
No início tive uma pequena dificuldade para imaginar a implementação, logo busquei a caneta e o papel e comecei a fazer um rascunho de como deveria ser implementando. Durante a implementação fiz diversas mudanças e fui documentando melhorias e correções no próprio github.
Optei pelo PostgreSQL devido à minha familiaridade com a plataforma e à facilidade de integração com projetos Spring.
Concluí com sucesso a implementação da validação de CPF utilizando a API externa: https://api-validador-cpf.vercel.app/validarcpf/.
Embora a implementação da mensageria e filas não tenha sido possível devido à limitação de tempo, a base do projeto pode ser encontrada em feature/mensageria.
Infelizmente, devido a restrições de prazo, não foi possível abordar testes de performance neste momento.
Para versionamento da API, adotei a prática de incluir a versão no header de cada controller: @GetMapping(headers = "Api-Version=1").
Optei pela plataforma Render devido à sua gratuidade e facilidade de integração. A API pode ser acessada em: Link da API.