{"id":15101378,"url":"https://github.com/didifive/desafio-api-java","last_synced_at":"2026-02-22T23:04:56.585Z","repository":{"id":153798440,"uuid":"557627902","full_name":"didifive/desafio-api-java","owner":"didifive","description":"Desafio API (semana 18/07 ~ 29/07/2022) - Programa GFT Start","archived":false,"fork":false,"pushed_at":"2024-02-03T21:05:13.000Z","size":1107,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-01T20:45:13.414Z","etag":null,"topics":["api-rest","eclipse-ide","environment-variables","gson","h2-database","jacoco-plugin","java","junit5","jwt","lombok","maven","mysql","open-api","postman-collection","spring-boot","spring-data-jpa","spring-security","spring-web","swagger3"],"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/didifive.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}},"created_at":"2022-10-26T02:22:14.000Z","updated_at":"2023-12-21T12:16:08.000Z","dependencies_parsed_at":"2024-02-03T22:30:41.435Z","dependency_job_id":null,"html_url":"https://github.com/didifive/desafio-api-java","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/didifive%2Fdesafio-api-java","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/didifive%2Fdesafio-api-java/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/didifive%2Fdesafio-api-java/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/didifive%2Fdesafio-api-java/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/didifive","download_url":"https://codeload.github.com/didifive/desafio-api-java/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245892100,"owners_count":20689447,"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","eclipse-ide","environment-variables","gson","h2-database","jacoco-plugin","java","junit5","jwt","lombok","maven","mysql","open-api","postman-collection","spring-boot","spring-data-jpa","spring-security","spring-web","swagger3"],"created_at":"2024-09-25T18:21:26.840Z","updated_at":"2025-10-28T22:03:19.206Z","avatar_url":"https://github.com/didifive.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DESAFIO API - Programa Start\n\n## Description\n\nRepositório para entrega do Desafio API (semana 18/07 ~ 29/07/2022) - Programa GFT Start  \nObjetivo: Aplicar os conceitos de API aprendidos nas semanas de estudo, juntamente com a pesquisa de novos recursos;  \nEscopo: Neste desafio você deverá desenvolver diversos End Points para um sistema de atendimento veterinário, nesse sistema, deverá considerar somente o atendimento de cachorros.\nEntrega Básica:\nO sistema deverá obrigatoriamente fornecer End Points para:\n\n- CRUD completo para clientes (armazenar somente dados básicos)\n- CRUD completo para médicos veterinários (armazenar somente dados básicos)\n- CRUD completo para o cachorro (cada animal deverá estar associado a um tutor/cliente | dados básicos do animal)\n- Registrar dados do atendimento: veterinário que está atendendo, tutor, animal em atendimento, data, hora, dados do animal no dia, diagnóstico,\ncomentários.\n- Autenticação do usuário (Basic Authentication – user:password) para acessar os End Points.\n- Não deixe de popular o banco\n\nDesafios bônus (Exceeds):\n\n- No cadastro do animal, recuperar dados da raça buscando na API fornecida pelo link no final da descrição da atividade.\n- Fornecer ao menos 3 serviços da API descrita no final da atividade para o cliente ( o cliente não pode acessar a API diretamente, deve acessar seu End Point, e seu End Poit deverá acessar a API e passar os dados para o cliente)\n- Manter histórico dos atendimentos e permitir que tanto o cliente quanto veterinário possam acessar esses dados.\n    OBS: Nesse caso, o cliente poderá acessar somente dados das consultas de seus animais. Os veterinários por sua vez, podem ver histórico de qualquer consulta.\n- Swagger ou projeto no postman\n- TDD\n\nO link da API que deverá ser utilizada é apresentado a seguir:\n\u003chttps://thedogapi.com/\u003e\n\n### Meu AmigAU! - Versão 1.0.0\n\n#### Clínica Veterinária Especializada\n\nPara o desafio foi criado **Meu AmigAU! - Clínica Veterinária Especializada**.\nNeste projeto foi aplicado:\n\n- Os arquivos fontes dos diagramas EER e UML que aparecem como imagem neste documento estão disponíveis na pasta `docs/diagrams`. O diagrama EER foi feito utilizando o MySQL Workbench Model e o UML foi feito utilizando o site [Draw.io];\n- Abstração criando `Person` para as classes `Client` e `Vet`. Assim é possível que uma pessoa seja cadastrada como cliente e veterinário sem necessitar colocar dados cadastrais pessoais, como o CPF/CNPJ, data de nascimento ou o endereço novamente, e pode ser aproveitada evoluções do projeto, como cadastro de funcionários;\n- Criado a entidade `Address` para que a entidade `Person` possa ter mais de um endereço cadastrado;\n- Criado o enumerador `AddressType` para diferenciar os tipos de endereços que são vinculados à pessoa;\n- Criado o enumerador `PersonType` para que tenha a possibilidade de informar pessoa física ou jurídica. Este enumerador também auxilia na validação de CPF ou CNPJ na mesma variável, usando como apoio as interfaces `CpfGroup` e `CnpjGroup` e a classe `PersonGroupSequenceProvider`, conforme orientações da página [Validando CPF/CNPJ na mesma variável];\n- O usuário, entidade `User`, pode possuir mais de um perfil de acesso;\n- Criada a classe `Breed` para guardar dados da raça com campos baseados na página [TheDogAPI Postman Docs];\n- Utilizado o Swagger v3 (OpenApi) e na segurança foi usado o bean `SecurityFilterChain` para não utilizar o `WebSecurityConfigurerAdapter` que foi depreciado nas versões recentes do spring;\n- Foram criadas classes com constants (`public static final`), pacote `enums.constants`, para guardar textos usados para mapeamentos de rotas, para documentação no swagger e em mensagens do sistema, assim é possível reaproveitá-las nas classes do sistema e testes, além de organizar os textos para facilitar revisão ou mesmo tradução;\n- Para evitar expor senhas ou chaves em repositório remoto, foram utilizadas variáveis de ambiente (_environment variables_) configuradas na IDE Ecplise, mais detalhes estarão na seção _Installation_;\n- Criado o arquivo `application-test.properties` para que nos testes carregue o banco de dados H2, desativado o flyway e outros detalhes para evitar problemas com testes, dados da aplicação e problema com variáveis de ambientes em testes;\n- Criado a classe `DateTimeConverter` no pacote `com.gft.meuamigau.utils` para fazer a conversão de datas para string e vice-versa e ser utilizada em método estáticos (`static`), ele utiliza `DateTimeFormatter` e `LocalDate`, pois o `SimpleDateFormatter`, que faria uma conversão mais direta de `Date` para `String`, e vice-versa, não é _thread-safe_ e, portanto, utilizá-lo em métodos estáticos pode acarretar em problemas, [ver mais sobre](https://stackoverflow.com/questions/6137548/can-we-declare-simpledateformat-objects-as-static-objects);\n- Para nomes de variáveis diferentes entre objeto e JSON, foi utilizado as intruções em [Serialize POJO to JSON with different names using GSON];\n- Para os testes, foi criado o método estático público `assertThrowsExceptionWithCorrectMessage` na classe `Assertions`, pacote `com.gft.meuamigau.utils`, para abstrair a conferência do lançamento de excessão com mensagem correta;\n- Criado a classe `EntityDtoBox`, pacote `utils`, para poder fazer um mesmo método poder retornar entidade ou DTO. Esta classe foi utilizada em métodos create e findById dos services;\n- Os endpoints do grupo \"Raças de Cachorros\" fazem busca na API externa [TheDogAPI]. Apenas o endpoint \u003chttp://localhost:8080/api/v1/breeds/{id\u003e} que realiza primeiramente uma consulta na base de dados local e quando não localiza a raça cadastrada, ele procura na base externa e salva os dados;\n- Todo cadastro de cachorro que inclui um id de raça que ainda não existe na base de dados local, já aproveita o método de busca no endpoint \u003chttp://localhost:8080/api/v1/breeds/{id\u003e}, e salva as informações da raça localmente;\n- No atendimento existe o atributo de cliente explícito, pois caso ocorrer a mudança de cliente no cachorro o atendimento ainda terá vinculo com o cadastro de cliente que era o responsável pelo cachorro no momento do atendimento.\n\n## Configuration\n\nO projeto foi feito utilizando:\n\n- [IDE Eclipse] versão 2022-06 (4.24.0).\n- Iniciado com Spring Starter Project, com as configurações e dependências:\n  - Project: [Maven] Project\n  - Language: Java\n  - [Spring Boot] 2.7.1\n  - Packaging: Jar\n  - [Java 17]\n  - Dependencies:\n    - Spring Boot DevTools\n    - Spring Web\n    - Spring Data JPA\n    - Spring Security\n    - Validation\n    - MySQL Driver\n    - Flyway\n    - Lombok\n    - H2 Database\n- Dependências adicionadas manualmente ao `pom.xml`:\n  - `springdoc-openapi-ui` e `springdoc-openapi-security` para Swagger v3 (OpenApi);\n  - `java-jwt` para trabalhar com token JWT;\n  - `gson` para [Converter JSON para Objeto com GSON];\n  - `jacoco-maven-plugin` para gerar relatório de coverage quando o teste é executado diretamente pelo terminal. _É necessário também inserir plugin específico, verifique o `pom.xml` para checar o plugin `jacoco-maven-plugin` adicionado_\n\n## Visuals\n\nLogotipo feito utilizando o site [Canva]:  \n![Meu AmigAU! Logo](docs/images/meu_amigau_-_logo.png?raw=true \"Meu AmigAU! Logo\")  \nSpring Banner personalizado com utilização de conversão de imagem para ascii pelo site [ASCII-Art]:  \n![Spring Banner Personalizado](docs/images/spring_banner.png?raw=true \"Spring Banner Personalizado\")  \nDiagrama EER com MySQL Workbench Model:  \n![Diagrama EER MySQL Workbench Model](docs/images/diagrams/meu_amigau_eer_diagram.png?raw=true \"Diagrama EER MySQL Workbench Model\")  \nDiagrama de classes UML feito utilizando o site [Draw.io]:  \n![Diagrama UML - Entities](docs/images/diagrams/meu_amigau_uml-Entities.drawio.png?raw=true \"Diagrama UML - Entities\")  \n![Diagrama UML - DTOs](docs/images/diagrams/meu_amigau_uml-DTOs.drawio.png?raw=true \"Diagrama UML - DTOs\")  \nVariáveis de ambiente usadas no `application.properties`:  \n![application.properties](docs/images/application.properties_environment_variables_useds.PNG?raw=true \"application.properties\")  \nSwagger v3 - OpenApi:  \n![Swagger](docs/images/swagger/meu_amigau_-_swagger.png?raw=true \"Swagger\")  \nSwagger Schemas - Cadastro de Pessoas - No Schema do RecordPersonDTO é mostrado os campos para requisição, cada um sua descrição e marcado com * se é requerido, no caso de uso de enumerador, é mostrada as opções disponíveis para o campo\n![Requisição de Cadastro de Pessoa](docs/images/cadastro-pessoa/cadastro_pessoa_requisicao_personType_enum.PNG?raw=true \"Requisição de Cadastro de Pessoa\")  \nResposta de cadastro de pessoa no Swagger, é mostrado também os outros tipos de respostas que também podem ocorrer, como o 409 que indica violação de integridade em algum campo  \n![Resposta de Cadastro de Pessoa](docs/images/cadastro-pessoa/cadastro_pessoa_respostas.PNG?raw=true \"Resposta de Cadastro de Pessoa\")  \nResposta de cadastro de pessoa com violação de integridade ao tentar cadastrar nova pessoa com Email já existente:  \n![Violação de Integridade - E-mail deve ser único](docs/images/cadastro-pessoa/cadastro_pessoa_validacao_unico_email.PNG?raw=true \"Violação de Integridade - E-mail deve ser único\")  \nClassificação de Endpoints no Swagger - Tags por assunto:  \n![Swagger Tags 01](docs/images/swagger/meu_amigau_-_swagger_-_endpoints-tag01.png?raw=true \"Swagger Tags 01\")  \nClassificação de Endpoints no Swagger - Tags por autorização de acesso:  \n![Swagger Tags 02](docs/images/swagger/meu_amigau_-_swagger_-_endpoints-tag02.png?raw=true \"Swagger Tags 02\")  \nClassificação de Endpoints no Swagger - Tags por método HTTP:  \n![Swagger Tags 03](docs/images/swagger/meu_amigau_-_swagger_-_endpoints-tag03.png?raw=true \"Swagger Tags 03\")  \nResultado dos testes na IDE Eclipse:  \n![Resultado de testes pelo terminal](docs/images/eclipse_tests.PNG?raw=true \"Resultado de testes pelo terminal\")  \nResultado dos testes pelo terminal:  \n![Resultado de testes pelo terminal](docs/images/terminal_tests.PNG?raw=true \"Resultado de testes pelo terminal\")  \nRelatório de coverage gerado pelo jacoco plugin:  \n![Relatório coverage jacoco plugin](docs/images/jacoco_coverage_report.PNG?raw=true \"Relatório coverage jacoco plugin\")  \n\n## Installation\n\nPara abrir o projeto basta clonar o repositório ou realizar o download e após:\n\n- Importar o projeto, preferencialmente na IDE Eclipse;\n- Fazer atualizações das dependências do Maven (Alt+F5 no Eclipse);\n- Possuir no mínimo JDK 17 LTS instalado, sugestão de JDK: [OpenJDK Zulu];\n- Possuir acesso à internet para atualização de dependências e acesso à API de terceiros;\n- Para projeto carregar corretamente na IDE pode ser necessário [Instalar Lombok];\n- Necessário possuir o banco de dados MySQL Server, caso não possua, pode visitar [MySQL Community Download] para download e instalação;\n- No arquivo src/main/resources/application.properties verificar e se necessário alterar os parâmentros conforme segue:\n  - URL de conexão com o banco: `spring.datasource.url=jdbc:mysql://localhost:3306/meu-amigau?createDatabaseIfNotExist=True`\n  - Usuário root do banco: `spring.datasource.username=root` - O usuário root padrão com permissão ao MySQL Server local, alterar somente caso seja esteja desativado ou seja diferente;\n  - Usuário root do banco: `spring.datasource.password=${DATABASE_ROOT_PASSWORD}` - Senha do banco de dados, alterar para a senha do root utilizado localmente ou setar valor na variável de ambiente `DATABASE_ROOT_PASSWORD`;\n  - Chave secreta para o JWT gerar e validar tokens: `meu-amigau-api.jwt.secret=${TOKEN_API_SECRET}` - Alterar para chave secreta de sua preferencia ou setar valor na variável de ambiente `TOKEN_API_SECRET`.\n  - Chave The Dog Api: `meu-amigau-api.the-dog-api.x-api-key=${THE_DOG_API_X_API_KEY}` - Alterar para chave gerada no site [TheDogAPI] ou setar o valor da chave na variável de ambiente `THE_DOG_API_X_API_KEY`.\n- Variáveis de ambientes que devem ser setadas no sistema ou na IDE para funcionamento adequado da aplicação:\n  - DATABASE_ROOT_PASSWORD\n  - TOKEN_API_SECRET\n  - THE_DOG_API_X_API_KEY\n- Setar valor de variável de ambiente na [IDE Eclipse]:\n  - Menu Run -\u003e Run Configurations..., selecionar o app desejado, no caso `meu-amigau-api`, e procurar a aba `Environment`  \n    ![Environment Configuration Eclipse 1](docs/images/environment-configuration/environment_configuration_eclipse_01.PNG?raw=true \"Environment Configuration Eclipse 1\")  \n  - Após, basta ir no botão `Add...` para adicionar a variável e valor, exemplo:\n    ![Environment Configuration Eclipse 2](docs/images/environment-configuration/environment_configuration_eclipse_02.PNG?raw=true \"Environment Configuration Eclipse 2\")  \n  - Adicionalmente, pode colocar a execução da aplicação no favoritos da IDE, basta ir na aba `Common`  \n    ![Environment Configuration Eclipse 3](docs/images/environment-configuration/environment_configuration_eclipse_03.PNG?raw=true \"Environment Configuration Eclipse 3\")  \n\n## Tests\n\nOs testes foram feitos utilizando o [JUnit 5], Mockito e MockMVC.  \n\n- Utilizando a [IDE Eclipse], basta executar (Run As) a pasta de teste ou escolher o arquivo.\n- Utilizando o terminal (PowerShell ou similiar), basta executar na pasta do projeto o comando abaixo:\n\n    ```shell\n    ./mvnw clean test\n    ```\n\n    _Após o teste finalizado com sucesso, é possível verificar relatório de coverage em: target/site/jacoco/index.html_  \n\n_Observação: Até a versão 1.0.0 existe teste na classe `BreedServiceTest`, pacote `services`, que faz conexão ao [TheDogAPI], portanto para o teste executar é necessário estar online._\n\n## Usage\n\nAntes de iniciar o projeto, configurar as variáveis de ambiente `DATABASE_ROOT_PASSWORD`, `TOKEN_API_SECRET` e `THE_DOG_API_X_API_KEY` no sistema ou IDE, ou então editar o arquivo `application.properties` nas condfigurações `spring.datasource.password`, `meu-amigau-api.jwt.secret` e `meu-amigau-api.the-dog-api.x-api-key` com suas informações.\nPara iniciar o projeto, basta utilizar uma das opções abaixo:\n\n- Utilizando a [IDE Eclipse], basta executar (Run) a classe `MeuAmigauApiApplication` no pacote `com.gft.meuamigau`.\n- Utilizando o terminal (PowerShell ou similiar), basta executar na pasta do projeto o comando abaixo:\n\n    ```shell\n    ./mvnw clean package spring-boot:run\n    ```\n\nAo executar a aplicação será criado o esquema do banco de dados através do flyway e o banco será automaticamente populado através da classe `PopulateDB`, pacote `config.populate`, com:\n\n- 5 perfis conforme disponíveis pela classe `RoleName.class` do pacote `enums`:\n  - ROLE_ADMIN\n  - ROLE_USER\n  - ROLE_PERSON\n  - ROLE_VET\n  - ROLE_CLIENT\n- 2 usuários:\n  - username: admin@email.com\n    - senha: pass@1234\n    - perfil(s): ROLE_USUARIO, ROLE_ADMIN\n  - username: usuario@email.com\n    - senha: pass@1234\n    - perfil(s): ROLE_USUARIO\n- 4 pessoas\n- 3 clientes\n- 2 veterinários\n- 1 raça de cachorro (_Undefined Race_)\n- 4 cachorros\n- 5 atendimentos\n\n## Endpoints\n\n- Autenticação:\n    | Método | URL                               | Perfil(s) Autorizado(s) |\n    | ------ | ---                               | ----------------------- |\n    | GET    | \u003chttp://localhost:8080/api/v1/auth\u003e | Público                 |\n\n- Usuários:\n    | Método | URL                                                | Perfil(s) Autorizado(s)                   |\n    | ------ | ---                                                | -----------------------                   |\n    | POST   | \u003chttp://localhost:8080/api/v1/users\u003e                 | ROLE_ADMIN                                |\n    | GET    | \u003chttp://localhost:8080/api/v1/users\u003e                 | ROLE_ADMIN                                |\n    | GET    | \u003chttp://localhost:8080/api/v1/users/{id\u003e}            | _ONLY OWN USER_, ROLE_ADMIN               |\n    | PUT    | \u003chttp://localhost:8080/api/v1/users/{id\u003e}            | ROLE_ADMIN                                |\n    | PATCH  | \u003chttp://localhost:8080/api/v1/users/pass/{username\u003e} | _ONLY OWN USER_                           |\n    | DELETE | \u003chttp://localhost:8080/api/v1/users/{id\u003e}            | ROLE_ADMIN {NOT OWN USER}**_              |\n\n- Pessoas:\n    | Método | URL                                                                      | Perfil(s) Autorizad(s)                                |\n    | ------ | ---                                                                      | -----------------------                               |\n    | POST   | \u003chttp://localhost:8080/api/v1/people\u003e                                      | ROLE_USER, ROLE_ADMIN                                 |\n    | GET    | \u003chttp://localhost:8080/api/v1/people\u003e                                      | ROLE_USER, ROLE_ADMIN                                 |\n    | GET    | \u003chttp://localhost:8080/api/v1/people/{id\u003e}                                 | _ROLE_PERSON {ONLY OWN USER}*_, ROLE_USER, ROLE_ADMIN |\n    | PUT    | \u003chttp://localhost:8080/api/v1/people/{id\u003e}                                 | ROLE_ADMIN                                            |\n    | PATCH  | \u003chttp://localhost:8080/api/v1/people/{id}/handle-user/id/{newUserId\u003e}      | ROLE_ADMIN                                            |\n    | PATCH  | \u003chttp://localhost:8080/api/v1/people/{id}/handle-user/username/{username\u003e} | ROLE_ADMIN                                            |\n    | DELETE | \u003chttp://localhost:8080/api/v1/people/{id\u003e}                                 | ROLE_ADMIN                                            |\n\n- Clientes:\n    | Método | URL                                       | Perfil(s) Autorizado(s)                               |\n    | ------ | ---                                       | -----------------------                               |\n    | POST   | \u003chttp://localhost:8080/api/v1/clients\u003e      | ROLE_USER, ROLE_ADMIN                                 |\n    | GET    | \u003chttp://localhost:8080/api/v1/clients\u003e      | ROLE_USER, ROLE_ADMIN                                 |\n    | GET    | \u003chttp://localhost:8080/api/v1/clients/{id}\u003e | _ROLE_CLIENT {ONLY OWN USER}*_, ROLE_USER, ROLE_ADMIN |\n    | PUT    | \u003chttp://localhost:8080/api/v1/clients/{id}\u003e | ROLE_USER, ROLE_ADMIN                                 |\n    | DELETE | \u003chttp://localhost:8080/api/v1/clients/{id}\u003e | ROLE_ADMIN                                            |\n\n- Veterinários:\n    | Método | URL                                    | Perfil(s) Autorizado(s)                            |\n    | ------ | ---                                    | -----------------------                            |\n    | POST   | \u003chttp://localhost:8080/api/v1/vets\u003e      | ROLE_USER, ROLE_ADMIN                              |\n    | GET    | \u003chttp://localhost:8080/api/v1/vets\u003e      | ROLE_USER, ROLE_ADMIN                              |\n    | GET    | \u003chttp://localhost:8080/api/v1/vets/{id}\u003e | _ROLE_VET {ONLY OWN USER}*_, ROLE_USER, ROLE_ADMIN |\n    | PUT    | \u003chttp://localhost:8080/api/v1/vets/{id}\u003e | ROLE_USER, ROLE_ADMIN                              |\n    | DELETE | \u003chttp://localhost:8080/api/v1/vets/{id}\u003e | ROLE_ADMIN                                         |\n\n- Raças de Cachorros:\n    | Método | URL                                             | Perfil(s) Autorizado(s)         |\n    | ------ | ---                                             | -----------------------         |\n    | GET    | \u003chttp://localhost:8080/api/v1/breeds\u003e             | ROLE_VET, ROLE_USER, ROLE_ADMIN |\n    | GET    | \u003chttp://localhost:8080/api/v1/breeds/name/{name}\u003e | ROLE_VET, ROLE_USER, ROLE_ADMIN |\n    | GET    | \u003chttp://localhost:8080/api/v1/breeds/{id}\u003e        | ROLE_VET, ROLE_USER, ROLE_ADMIN |\n    | GET    | \u003chttp://localhost:8080/api/v1/breeds/images/{id}\u003e | ROLE_VET, ROLE_USER, ROLE_ADMIN |\n\n- Cachorros:\n    | Método | URL                                            | Perfil(s) Autorizado(s)                                         |\n    | ------ | ---                                            | -----------------------                                         |\n    | POST   | \u003chttp://localhost:8080/api/v1/dogs\u003e              | ROLE_VET, ROLE_USER, ROLE_ADMIN                                 |\n    | GET    | \u003chttp://localhost:8080/api/v1/dogs\u003e              | ROLE_VET, ROLE_USER, ROLE_ADMIN                                 |\n    | GET    | \u003chttp://localhost:8080/api/v1/dogs/clients/{id}\u003e | _ROLE_CLIENT {ONLY OWN USER}*_, ROLE_VET, ROLE_USER, ROLE_ADMIN |\n    | GET    | \u003chttp://localhost:8080/api/v1/dogs/{id}\u003e         | ROLE_VET, ROLE_USER, ROLE_ADMIN                                 |\n    | PUT    | \u003chttp://localhost:8080/api/v1/dogs/{id}\u003e         | ROLE_VET, ROLE_USER, ROLE_ADMIN                                 |\n    | DELETE | \u003chttp://localhost:8080/api/v1/dogs/{id}\u003e         | ROLE_ADMIN                                                      |\n\n- Atendimentos:\n    | Método | URL                                                   | Perfil(s) Autorizado(s)                                         |\n    | ------ | ---                                                   | -----------------------                                         |\n    | POST   | \u003chttp://localhost:8080/api/v1/attendances\u003e              | ROLE_VET, ROLE_USER, ROLE_ADMIN                                 |\n    | GET    | \u003chttp://localhost:8080/api/v1/attendances\u003e              | ROLE_VET, ROLE_USER, ROLE_ADMIN                                 |\n    | GET    | \u003chttp://localhost:8080/api/v1/attendances/clients/{id}\u003e | _ROLE_CLIENT {ONLY OWN USER}*_, ROLE_VET, ROLE_USER, ROLE_ADMIN |\n    | GET    | \u003chttp://localhost:8080/api/v1/attendances/dogs/{id}\u003e    | ROLE_VET, ROLE_USER, ROLE_ADMIN                                 |\n    | GET    | \u003chttp://localhost:8080/api/v1/attendances/vets/{id}\u003e    | ROLE_VET, ROLE_USER, ROLE_ADMIN                                 |\n    | GET    | \u003chttp://localhost:8080/api/v1/attendances/{id}\u003e         | ROLE_VET, ROLE_USER, ROLE_ADMIN                                 |\n    | PUT    | \u003chttp://localhost:8080/api/v1/attendances/{id}\u003e         | ROLE_VET, ROLE_USER, ROLE_ADMIN                                 |\n    | DELETE | \u003chttp://localhost:8080/api/v1/attendances/{id}\u003e         | ROLE_ADMIN                                                      |\n\n**IMPORTANTE:** Como é uma aplicação que possui checagem de permissão de acesso, é necessário que se utilize token para as requisições através do Endpoint, o(s) perfil(s) de acesso(s) estão relacionados nas tabelas acima.  \n_OBSERVAÇÃO:_ Os perfis marcados com _{ONLY OWN USER}*_, indica que a permissão é atribuída somente para que o usuário do perfil possa acessar apenas o recurso que tenha relação direta para si.  \n_OBSERVAÇÃO 2:_ No endpoint de delete o ROLE_ADMIN está marcado com _{NOT OWN USER}**_, indicando que não é possível executar o processo sendo o próprio usuário do recurso, no caso, um usuário mesmo sendo administrador, não pode se deletar.\n_OBSERVAÇÃO 3:_ No endpoint que permite ao próprio usuário trocar a senha a permissão está marcada com: _ONLY OWN USER_\n\nA documentação completa dos Endpoints estará disponível através do Swagger que estará acessível pelo link quando o projeto iniciar: \u003chttp://localhost:8080/swagger-ui.html\u003e\n\nTambém existe arquivo de Coleção do Postman, basta importar o arquivo `MeuAmigAU-API.postman_collection.json` que está na pasta docs.\n\n### Autenticando e utilizando o token no Swagger\n\nPara fazer a autenticação e utilizar o token no Swagger siga os passos:  \n1- Na página do Swagger (\u003chttp://localhost:8080/swagger-ui.html\u003e) procure por \"1. Autenticação\", depois o endpoint POST em \"/api/v1/auth Generate Token\" e clique em \"Try it out\"  \n![Swagger Authentication Step 01](docs/images/swagger/swagger_auth01.png?raw=true \"Swagger Authentication Step 01\")  \n2- Irá ter um campo de texto (textarea) com um JSON de modelo, altere o email e password para email e senha de usuário já cadastrado (exemplo: admin@email.com), depois é só clicar em \"Execute\"  \n![Swagger Authentication Step 02](docs/images/swagger/swagger_auth02.png?raw=true \"Swagger Authentication Step 02\")  \n3- Após a execução irá aparecer a resposta abaixo na seção \"Server response\", o token estará no \"Response body\", copiar somente o token sem as aspas. _Se retornar erro 401, o usuário ou senha estão inválidos._  \n![Swagger Authentication Step 03](docs/images/swagger/swagger_auth03.png?raw=true \"Swagger Authentication Step 03\")  \n4- Para realizar a autorização de acesso aos endpoist basta clicar no botão \"Authorize\" ou no ícone de cadeado que aparece em frente aos endpoints que exigem autorização\n![Swagger Authentication Step 04](docs/images/swagger/swagger_auth04.png?raw=true \"Swagger Authentication Step 04\")  \n5- Na janela que abrir, informar o token gerado e copiado no passo 3 e clique em \"Authorize\". _A autorização disponível já está configurada para aceitar Bearer token, portanto é só colar o token sem acrescentar nada_  \n![Swagger Authentication Step 05](docs/images/swagger/swagger_auth05.png?raw=true \"Swagger Authentication Step 05\")  \n6- Após informar o token, a janela irá mudar com a mensagem de \"Authorized\" e os ícones de cadeados que aparecem no botão \"Authorize\" e nos endpoints que exigem autorização irão aparecer como cadeado fechado  \n![Swagger Authentication Step 06](docs/images/swagger/swagger_auth06.png?raw=true \"Swagger Authentication Step 06\")\n![Swagger Authentication Step 06](docs/images/swagger/swagger_auth07.png?raw=true \"Swagger Authentication Step 06\")  \n\n### Autenticando e utilizando o token no Postman\n\nPara fazer a autenticação e utilizar o token no Postman siga os passos:  \n1- No aplicativo Postman é necessário fazer a requisição com método POST na URL \u003chttp://localhost:8080/api/v1/auth\u003e com o nome de usuário e senha no body da requisição. A configuração da requisição está na Coleção \"MeuAmigAU! API / Autenticação / Gerar Token de Acesso\"  \n![Postman Authentication Step 01](docs/images/postman/postman_auth01.png?raw=true \"Postman Authentication Step 01\")  \n2- A requisição bem sucedida irá retornar resposta 200 OK e o token, copie o token  \n![Postman Authentication Step 02](docs/images/postman/postman_auth02.png?raw=true \"Postman Authentication Step 02\")  \n3- Após o token gerado e copiado, é só ir em qualquer requisição, ir na aba Authorization, escolher a opção \"Bearer Token\" e colar o token.  \n![Postman Authentication Step 03](docs/images/postman/postman_auth03.png?raw=true \"Postman Authentication Step 03\")  \n\n## Roadmap\n\nAqui estão listadas sugestões para futuras atualizações:\n\n- Criar campos para guardar _timestamps_ de criação e atualização com o usuário que realizou a operação;\n- CRUD para raças de cachorros (Breeds);\n- Transformar o delete definitivo em um delete lógico, quando a informação continua presente nos dados, mas fica \"inativa\" no sistema;\n- Para o processo acima funcionar corretamente, deve-se considerar como serão tratados novos cadastros que por ventura violem a restrição de ser único para a entidade/tabela, como email ou documento;\n- Criar endpoint no cachorro para poder permitir a troca de cliente;\n- Criar endpoint para permitir pesquisar atendimentos por data e hora;\n- Para o caso de permitir troca de cliente, criar DTO para atualização de atendimento deixando o campo de cliente disponível para preenchimento, atualmente o cliente é preenchido automaticamente pelo sistema;\n- Criar testes unitários com contexto de segurança para testar a acessibilidade dos perfils, assim pode cobrir 100% o `AttendanceService`;\n- Criar testes que cubram 100% o `BreedService` em relação à conexão da API externa e sem a necessidade da resposta real. Verificar a implementação de Mock Server para não necessitar de conectar ao recurso real.\n\n## Support and Contributing\n\nDúvidas, problemas ou sugestões: abrir Issue ou Merge Request.\n\n## Authors and acknowledgment\n\nDesafio proposto por Michel, Ubiratran, Clécio e equipe do Programa Start da GFT.  \nFeito por [Luis Carlos Zancanela]  \n\n\u003e O código deve ser elegante para agradar a quem olhar.  \n\n\u003e ###### _ZANCANELA L. C., 2022. Desafio API (semana 18/07 ~ 29/07/2022) - Programa GFT Start._  \n\n## Project status\n\n_Done in 29/07/2022_  \n\n[Java 17]: https://docs.oracle.com/en/java/javase/17/docs/api/index.html\n[JUnit 5]: https://junit.org/junit5/docs/current/user-guide/index.html\n[IDE Eclipse]: https://www.eclipse.org/ide/\n[Spring Boot]: https://spring.io/projects/spring-boot\n[Maven]: https://maven.apache.org/\n[MySQL Community Download]: https://dev.mysql.com/downloads/\n[OpenJDK Zulu]: https://www.azul.com/downloads/\n[Draw.io]: https://app.diagrams.net/\n[Canva]: https://www.canva.com/pt_br/\n[ASCII-Art]: https://ascii-art.botecodigital.dev.br/\n\n[Luis Carlos Zancanela]: https://github.com/didifive\n\n[Instalar Lombok]: https://dev.to/gilton/instalando-o-lombok-no-eclipse-3c59#:~:text=%20Para%20instalar%20o%20Lombok%20no%20Eclipse%20e,clique%20duas%20vezes%20no%20%27lombok.jar%27%20%28double-click%29%3B%20More%20\n\n[Validando CPF/CNPJ na mesma variável]: https://medium.com/blog-gilson-silva-ti/validando-cpf-cnpj-na-mesma-vari%C3%A1vel-com-bean-validation-4429a49e9bb5\n\n[TheDogAPI]: https://thedogapi.com/\n[TheDogAPI Postman Docs]: https://documenter.getpostman.com/view/4016432/the-dog-api/RW81vZ4Z#26bd3f92-dd58-4569-bc13-22fa76396fe8\n\n[Converter JSON para Objeto com GSON]: https://stackoverflow.com/questions/1688099/converting-json-data-to-java-object\n[Serialize POJO to JSON with different names using GSON]: https://stackoverflow.com/questions/32547662/serialize-pojo-to-json-with-different-names-using-gson\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdidifive%2Fdesafio-api-java","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdidifive%2Fdesafio-api-java","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdidifive%2Fdesafio-api-java/lists"}