{"id":19580128,"url":"https://github.com/jmsmarcelo/raffle-api-restful-spring-java","last_synced_at":"2026-05-10T07:33:52.310Z","repository":{"id":250642509,"uuid":"834695366","full_name":"jmsmarcelo/raffle-api-restful-spring-java","owner":"jmsmarcelo","description":"Challenge DIO | API RESTful | Spring Framework | Java","archived":false,"fork":false,"pushed_at":"2024-08-02T22:01:07.000Z","size":255,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-09T05:15:47.156Z","etag":null,"topics":["api-rest","bootcamp","challenge","database","dio","java","jpa","spring-boot"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jmsmarcelo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-28T04:37:23.000Z","updated_at":"2024-08-02T22:01:10.000Z","dependencies_parsed_at":"2024-11-11T07:35:23.710Z","dependency_job_id":null,"html_url":"https://github.com/jmsmarcelo/raffle-api-restful-spring-java","commit_stats":null,"previous_names":["jmsmarcelo/raffle-api-restful-spring-java"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmsmarcelo%2Fraffle-api-restful-spring-java","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmsmarcelo%2Fraffle-api-restful-spring-java/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmsmarcelo%2Fraffle-api-restful-spring-java/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmsmarcelo%2Fraffle-api-restful-spring-java/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jmsmarcelo","download_url":"https://codeload.github.com/jmsmarcelo/raffle-api-restful-spring-java/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240849053,"owners_count":19867617,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-rest","bootcamp","challenge","database","dio","java","jpa","spring-boot"],"created_at":"2024-11-11T07:22:34.190Z","updated_at":"2026-05-10T07:33:52.279Z","avatar_url":"https://github.com/jmsmarcelo.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Raffle API RESTful\n![Status do Projeto](https://img.shields.io/badge/status-concluído-brightgreen)\n\n\u003cimg align=\"right\" width=\"200\" src=\"./dio-desenvolvimento.java.com.ia.png\"\u003e\n\n### Desafio DIO Bootcamp\n\n- **Desafio:** Desenvolver uma API RESTful com Spring Framework e Java\n- **Tema:** A livre escolha\n- **Bootcamp:** [Coding The Future GFT - Desenvolvimento Java com IA](https://www.dio.me/bootcamp/coding-future-gft-desenvolvimento-java-com-ia)\n\n## Tecnologias utilizadas:\n- ![Java 21 LTS](https://img.shields.io/badge/Java-21%20LTS-blue)\n- ![Spring Boot 3.3.2](https://img.shields.io/badge/Spring%20Boot-3.3.2-brightgreen)\n- ![Gradle - Groovy](https://img.shields.io/badge/Gradle-Groovy-brightgreen)\n- ![Spring JPA](https://img.shields.io/badge/Spring%20JPA-%23323330.svg?style=flat\u0026logo=spring)\n- ![H2 Database](https://img.shields.io/badge/H2%20Database-%23007396.svg?style=flat\u0026logo=h2)\n- ![OpenAPI Swagger](https://img.shields.io/badge/OpenAPI-Swagger-brightgreen)\n- ![Spring Security](https://img.shields.io/badge/Spring%20Security-gray.svg?style=flat\u0026logo=spring%20security)\n\n## Detalhes do Projeto:\n    API que armazena rifas, clientes, bilhetes e realiza o sorteio.\n\n- ### Raffle: \n  - **Armazena e obtém os dados da rifa no Banco de Dados**\n  - **ID** *(Gerado automaticamente pelo o banco de dados)*\n  - **Name** *(Nome da Rifa, não é permitido nomes repetidos)*\n  - **Date** *(Data e hora do sorteio)*\n  - **Price** *(Valor da rifa)*\n  - **Status** *(Pendente, Cancelado, Disponível e Realizado)*\n  - **Award** *(Prêmios a ser Ganhado)*\n  - **Tickets** *(Contendo a lista de Bilhetes adqueridos)*\n\n- ### Customer:\n  - Armazena e obtém os dados do cliente no Banco de Dados\n  - **CPF** *(Será a ID no banco de dados, portanto é obrigatório)*\n  - **Name** *(Nome do cliente, é obrigatório)*\n  - **Phone** *(Telefone, é obrigatório)*\n  - **alternativePhone** *(Telefone alternativo, é opcional)*\n  - **Email** *(é Opcional)*\n\n- ### Ticket:\n  - Armazena e obtém os dados do bilhete no Banco de Dados\n  - **ID** *(Gerado automaticamento pelo banco de dados)*\n  - **Raffle** *(Pertencente)*\n  - **Customer** *(Proprietário)*\n  - **Status** *(Participando, Cancelado e Ganhador)*\n\n- ### RaffleDraw:\n  - Realiza o sorteio\n  - Atualiza o Status da Rifa para Realizado\n  - Atualiza o Status do Bilhete para Ganhador\n\n- ### Spring Security:\n  - As senhas dos usuários são criptografadas com **BCrypt** e armazenadas no banco de dados\n  - Adicionei duas hierarquias: **ADMIN** que tem acesso total e o **USER** que somente ver as Rifas.\n  - Permissão de acesso via Token, que é gerado via login\n  - Não adicionei cadastro, terá que ser feito manualmente no banco de dados\n\n## Progresso do Projeto:\n- [x] Implementação do modelo `Customer`\n- [x] Implementação do modelo `Raffle`\n- [x] Implementação do modelo `Ticket`\n- [x] Criação dos endpoints de CRUD para `Customer`\n- [x] Criação dos endpoints de CRUD para `Raffle`\n- [x] Criação dos endpoints de CRUD para `Ticket`\n- [x] Implementação do H2 Database e Console\n- [x] Testes de CRUD para `Raffle`\n- [x] Testes de CRUD para `Customer`\n- [x] Testes de CRUD para `Ticket`\n- [x] Implementação da Documentação Swagger\n- [x] Implementação do controlador `RaffleDraw`\n- [x] Implementação do serviço `RaffleDraw`\n- [x] Configuração da validação de dados\n- [x] Tratamento das excessões\n- [x] Implementação de segurança com autenticação baseada em Token\n- [ ] ~~Adição de testes unitários~~\n- [ ] ~~Configuração do CI/CD~~\n\n## Como usar:\n- **Swagger-UI:**\n  - `http://localhost:8080/swagger-ui.html`\n- **Console do Banco de Dados:**\n  - `http://localhost:8080/h2-console/`\n- **Usuário/Administrador:**\n  - Como o Banco de Dados somente está em memória adicionei a Class `UserForTest` para criar automaticamente um ADMIN (user: `adminTest`, pass: `12345678`) e um USER (user: `userTest`, pass: `12345678`) para testes de hierarquia\n  - \n\n## Diagrama UML:\n```mermaid\nclassDiagram\n    class Customer {\n        - String cpf\n        - String name\n        - String phone\n        - String alternativePhone\n        - String email\n        + getCpf()\n        + setCpf(String cpf)\n        + getName()\n        + setName(String name)\n        + getPhone()\n        + setPhone(String phone)\n        + getAlternativePhone()\n        + setAlternativePhone(String alternativePhone)\n        + getEmail()\n        + setEmail(String email)\n    }\n    class CustomerController {\n        - CustomerService customerService\n        + add(Customer customer)\n        + getAll()\n        + getById(String cpf)\n        + set(Customer customer)\n    }\n    class CustomerRepository {\n        \u003c\u003cinterface\u003e\u003e\n    }\n    class CustomerService {\n        - CustomerRepository customerRepository\n        + create(Customer customer)\n        + findAll()\n        + findById(String cpf)\n        + update(Customer customer)\n    }\n\n    class Raffle {\n        - Long id\n        - String name\n        - Date drawDate\n        - Double price\n        - String award\n        - RaffleStatus status\n        + getId()\n        + setId(Long id)\n        + getName()\n        + setName(String name)\n        + getDrawDate()\n        + setDrawDate(Date drawDate)\n        + getPrice()\n        + setPrice(Double price)\n        + getAward()\n        + setAward(String award)\n        + getStatus()\n        + setStatus(RaffleStatus status)\n        + getTickets()\n        + setTickets(List~Ticket~ tickets)\n    }\n    class RaffleController {\n        - RaffleService raffleService\n        + add(Raffle raffle)\n        + getAll()\n        + getById(Long id)\n        + set(Raffle raffle)\n    }\n    class RaffleRepository {\n        \u003c\u003cinterface\u003e\u003e\n    }\n    class RaffleService {\n        - RaffleRepository raffleRepository\n        + create(Raffle raffle)\n        + findAll()\n        + findById(Long id)\n        + update(Raffle raffle)\n    }\n    class RaffleStatus {\n        \u003c\u003cenumeration\u003e\u003e\n        PENDING\n        CANCELLED\n        UPCOMING\n        COMPLETED\n    }\n\n    class Ticket {\n        - Long id\n        - Raffle raffle\n        - Customer customer\n        - TicketStatus status\n        + getId()\n        + setId(Long id)\n        + getRaffle()\n        + setRaffle(Raffle raffle)\n        + getCustomer()\n        + setCustomer(Customer customer)\n        + getStatus()\n        + setStatus(TicketStatus status)\n    }\n    class TicketController {\n        - TicketService ticketService\n        + create(Ticket ticket)\n        + get(Long id)\n        + getAllByRaffleId(Long id)\n        + getAllByCustomerCPf(String cpf)\n        + getAllByRaffleIdAndCustomerCPf(Long id, String cpf)\n        + set(Ticket ticket)\n    }\n    class TicketRepository {\n        \u003c\u003cinterface\u003e\u003e\n        + List~Ticket~ findAllByRaffleId(Long raffleId)\n        + List~Ticket~ findAllByCustomerCpf(String customerCpf)\n        + List~Ticket~ findAllByRaffleIdAndCustomerCpf(Long raffleId, String customerCpf)\n    }\n    class TicketService {\n        - TicketRepository ticketRepository\n        + create(Ticket ticket)\n        + findById(Long id)\n        + findAllByRaffleId(Long raffleId)\n        + findAllByCustomerCpf(String customerCpf)\n        + findAllByRaffleIdAndCustomerCpf(Long raffleId, String customerCpf)\n        + update(Ticket ticket)\n    }\n    class TicketStatus {\n        \u003c\u003cenumeration\u003e\u003e\n        PARTICIPATING\n        CANCELLED\n        WINNER\n    }\n\n    class RaffleDrawController {\n        - RaffleDrawService raffleDrawService\n        + drawTicket(Raffle raffle)\n    }\n    class RaffleDrawService {\n        - RaffleRepository raffleRepository\n        - TicketRepository ticketRepository\n        + drawTicket(Raffle raffle)\n    }\n    \n    class GlobalExceptionHandler {\n        + handle(Exception e)\n    }\n    class ValidationException {\n        - ExceptionDetails\n        + ValidationException()\n        + getExceptionDetails()\n    }\n    class ExceptionDetails {\n    }\n\n    CustomerController --\u003e CustomerService\n    CustomerService --\u003e CustomerRepository\n    CustomerRepository --\u003e Customer\n    CustomerService --\u003e ValidationException\n\n    RaffleController --\u003e RaffleService\n    RaffleService --\u003e RaffleRepository\n    RaffleRepository --\u003e Raffle\n    Raffle --\u003e \"1\" RaffleStatus\n    RaffleService --\u003e ValidationException\n\n    TicketController --\u003e TicketService\n    TicketService --\u003e TicketRepository\n    TicketRepository --\u003e Ticket\n    Ticket --\u003e \"1\" TicketStatus\n    Ticket \"0..*\" --\u003e \"1\" Raffle\n    Ticket \"0..*\" --\u003e \"1\" Customer\n    TicketService --\u003e ValidationException\n\n    RaffleDrawController --\u003e RaffleDrawService\n    RaffleDrawService --\u003e RaffleRepository\n    RaffleDrawService --\u003e TicketRepository\n    RaffleDrawService --\u003e ValidationException\n    \n    GlobalExceptionHandler --\u003e ValidationException\n    GlobalExceptionHandler --\u003e ExceptionDetails\n    ValidationException --\u003e ExceptionDetails\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjmsmarcelo%2Fraffle-api-restful-spring-java","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjmsmarcelo%2Fraffle-api-restful-spring-java","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjmsmarcelo%2Fraffle-api-restful-spring-java/lists"}