Skip to content

DEVSuperior : Java Spring Professional - Java Spring Professional - Desafio 05

Notifications You must be signed in to change notification settings

marcosfshirafuchi/DEVSUPERIOR-DSCommerce-Versao-Completa

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

image-2024-07-01-T11-45-10-371-Z Java Spring Professional - Desafio 05

Desenvolvido na linguagem Java por:

Formação Desenvolvedor Moderno Módulo: Back end

Capítulo: Login e controle de acesso

DESAFIO: Projeto Spring Boot estruturado

Você deverá entregar o projeto DSCommerce estruturado e com todas funcionalidades implementadas conforme as aulas.
O projeto deve ser implementado com Java e Spring Boot, usando banco de dados H2, conforme aulas.
Para atestar que você implementou gradualmente o projeto, será exigido que seu projeto no Github tenha pelo menos 12 commits no seu usuário do Github.

Critérios de correção

  1. Mínimo 12 commits no projeto no usuário do aluno (eliminatório)
  2. Endpoints públicos GET /produts e GET /products/{id} funcionam sem necessidade de login (eliminatório)
  3. Endpoint de login funcionando e retornando o token de acesso (eliminatório)
  4. Endpoints privados de produto (POST/PUT/DELETE) funcionam somente para usuário ADMIN (eliminatório)
  5. Endpoint GET /users/me retorna usuário logado (eliminatório)
  6. Endpoints GET /orders/{id} e POST /orders funcionando (eliminatório)
  7. Usuário que não é ADMIN não consegue acessar pedido que não é dele em GET /orders/{id} (eliminatório)
  8. Endpoint GET /categories retorna todas categorias


Lembre-se: a collection do Postman e o projeto pronto para referência estão disponíveis no material de apoio do capítulo.

PROJETO: Sistema DSCommerce

Sua solução deverá seguir as seguintes especificações:
Um pedido deve ser representado por um objeto conforme projeto abaixo:

image-2024-07-07-T19-33-34-381-Z

O projeto foi desenvolvido na aula do curso Java Spring Professional - Capítulo: "API REST, camadas, CRUD, exceções, validações" da plataforma DEVSuperior do professor Nélio Alves.

Principais Tecnologias

  • Java 21 : Utilizaremos a versão LTS mais recente do Java para tirar vantagem das últimas inovações que essa linguagem robusta e amplamente utilizada oferece;
  • Spring Boot 3 : Trabalharemos com a mais nova versão do Spring Boot, que maximiza a produtividade do desenvolvedor por meio de sua poderosa premissa de autoconfiguração;
  • Spring Data JPA: Exploraremos como essa ferramenta pode simplificar nossa camada de acesso aos dados, facilitando a integração com bancos de dados SQL;
  • H2 Database: Banco de dados SQL em memória.
  • Postman: Para testar os métodos http do controller.

1. Premissas

Deseja-se fazer um sistema para ser utilizado em cursos da Devsuperior no processo de aprendizado dos alunos. Para isto, a concepção do sistema partiu das seguintes premissas:

  • Deve ser um sistema que possua um modelo de domínio relativamente simples, porém abrangente, ou seja, que explore vários tipos de relacionamentos entre as entidades de negócio (muitos-para-um, muitos-para-muitos, etc.).
  • O sistema deve possibilitar a aplicação de vários conhecimentos importantes das disciplinas de fundamentos.
  • O sistema deve conter as principais funcionalidades que se espera de um profissional iniciante deve saber construir, tais como telas de cadastro e fluxos de caso de uso.

2. Visão geral do sistema

O sistema deve manter um cadastro de usuário, produtos e suas categorias. Cada usuário possui nome, email, telefone, data de nascimento e uma senha de acesso. Os dados dos produtos são: nome, descrição, preço e imagem. O sistema deve apresentar um catálogo de produtos, os quais podem ser filtrados pelo nome do produto. A partir desse catálogo, o usuário pode selecionar um produto para ver seus detalhes e para decidir se o adiciona a um carrinho de compras. O usuário pode incluir e remover itens do carrinho de compra, bem como alterar as quantidades de cada item. Uma vez que o usuário decida encerrar o pedido, o pedido deve então ser salvo no sistema com o status de "aguardando pagamento". Os dados de um pedido são: instante em que ele foi salvo, status, e uma lista de itens, onde cada item se refere a um produto e sua quantidade no pedido. O status de um pedido pode ser: aguardando pagamento, pago, enviado, entregue e cancelado. Quando o usuário paga por um pedido, o instante do pagamento deve ser registrado. Os usuários do sistema podem ser clientes ou administradores, sendo que todo usuário cadastrado por padrão é cliente. Usuários não identificados podem se cadastrar no sistema, navegar no catálogo de produtos e no carrinho de compras. Clientes podem atualizar seu cadastro no sistema, registrar pedidos e visualizar seus próprios pedidos. Usuários administradores tem acesso à área administrativa onde pode acessar os cadastros de usuários, produtos e categorias.

3. Protótipos de tela:

https://www.figma.com/file/ZrGNVNG0kZL6txDv4G8P6s/DSCommerce

4. Modelo conceitual

Este é o modelo conceitual do sistema DSCommerce. Considerações:

  • Cada item de pedido (OrderItem) corresponde a um produto no pedido, com uma quantidade. Sendo que o preço também é armazenado no item de pedido por questões de histórico (se o preço do produto mudar no futuro, o preço do item de pedido continua registrado com o preço real que foi vendido na época).
  • Um usuário pode ter um ou mais "roles", que são os perfis de acesso deste usuário no sistema (client, admin).

image-2024-07-07-T19-33-34-381-Z

5. Casos de uso (visão geral)

O escopo funcional do sistema consiste nos seguintes casos de uso:

Caso de uso Visão geral Acesso
Manter produtos CRUD de produtos, podendo filtrar itens pelo nome Somente Admin
Manter categorias CRUD de categorias, podendo filtrar itens pelo nome Somente Admin
Manter usuários CRUD de usuários, podendo filtrar itens pelo nome Somente Admin
Gerenciar carrinho Incluir e remover itens do carrinho de compras, bem como alterar as quantidades do produto em cada itemPúblico
Consultar catálogo Listar produtos disponíveis, podendo filtrar produtos pelo nomePúblico
Sign up Cadastrar-se no sistema Público
Login Efetuar login no sistema Público
Registrar pedido Salvar no sistema um pedido a partir dos dados do carrinho de compras informadoUsuário logado
Atualizar perfil Atualizar o próprio cadastro Usuário logado
Visualizar pedidos Visualizar os pedidos que o próprio usuário já fez Usuário logado
Registrar pagamento Salvar no sistema os dados do pagamento de um pedido Somente Admin
Reportar pedidos Relatório de pedidos, podendo ser filtrados por data Somente Admin


image-2024-07-11-T15-54-21-032-Z

Atores

Ator Responsabilidade
Usuário anônimo Pode realizar casos de uso das áreas públicas do sistema, como catálogo, carrinho de compras, login e sign up.
Cliente Responsável por manter seu próprios dados pessoais no sistema, e pode visualizar histórico dos seus pedidos. Todo usuário cadastrado por padrão é um Cliente.
Admin Responsável por acessar a área administrativa do sistema com cadastros e relatórios. Admin também pode fazer tudo que Cliente faz.

6. Casos de uso (detalhamento)

Consultar catálogo

Atores Usuário anônimo, Cliente, Admin
Precondições -
Pós-condições -
Visão geral Listar produtos disponíveis, podendo filtrar produtos pelo nome


Cenário principal de sucesso
1. [OUT] O sistema informa uma listagem paginada de nome, imagem e preço dos produtos, ordenada por nome.
2. [IN] O usuário informa, opcionalmente, parte do nome de um produto
3. [OUT] O sistema informa a listagem atualizada



Informações complementares
O número padrão de registros por página deve ser 12. Como a listagem é paginada, o usuário pode navegar nas próximas páginas.


Manter produtos
Atores Admin
Precondições Usuário logado
Pós-condições -
Visão geral CRUD de produtos, podendo filtrar itens pelo nome


Cenário principal de sucesso
1. Executar caso de uso: Consultar catálogo.
2. O admin seleciona uma das opções
- 2.1. Variante Inserir
- 2.2. Variante Atualizar
- 2.3. Variante Deletar

Cenário alternativos: variantes
2.1. Variante Inserir
2.1.1. [IN] O admin informa nome, preço, descrição e URL da imagem e categorias do produto.

2.2. Variante Atualizar
2.2.1. [IN] O admin seleciona um produto para editar.
2.2.2. [OUT] O sistema informa nome, preço, descrição, URL da imagem e categorias do produto selecionado.
2.2.3. [IN] O admin informa novos valores para nome, preço, descrição, URL da imagem e categorias do produto selecionado.

2.3. Variante Deletar
2.3.1. [IN] O admin seleciona um produto para deletar.

Cenário alternativos: exceções
2.1.1a. Dados inválidos
2.1.1a.1. [OUT] O sistema informa os erros nos campos inválidos [1].
2.1.1a.2. Vai para passo 2.1.1.

2.2.3a. Dados inválidos
2.2.3a.1. [OUT] O sistema informa os erros nos campos inválidos [1].
2.2.3a.2. Vai para passo 2.2.1.

2.2.3b. Id não encontrado
2.2.3b.1. [OUT] O sistema informa que o id não existe.
2.2.3b.2. Vai para passo 2.2.1.

2.3.1a. Id não encontrado
2.3.1a.1. [OUT] O sistema informa que o id não existe.
2.3.1a.2. Vai para passo 2.3.1.

2.3.1b. Integridade referencial violada
2.3.1b.1. [OUT] O sistema informa que a deleção não pode ser feita porque viola a integridade referencial dos dados.
2.3.1b.2. Vai para passo 2.3.1.

Informações complementares
[1] Validação dos dados:
- Nome: deve ter entre 3 e 80 caracteres
- Preço: deve ser positivo
- Descrição: não pode ter menos que 10 caracteres
- Deve haver pelo menos 1 categoria

Login

Atores Usuário anônimo
Precondições -
Pós-condições Usuário logado
Visão geral Efetuar login no sistema


Cenário principal de sucesso
1. [IN] O usuário anônimo informa suas credenciais (nome e senha).
2. [OUT] O sistema informa um token válido.


Cenário alternativos: exceções
1a. Credenciais inválidas
1a.1. [OUT] O sistema informa que as credenciais são inválidas.
1a.2. Vai para passo 1.

Gerenciar carrinho
Atores Usuário anônimo
Precondições -
Pós-condições -
Visão geral Incluir e remover itens do carrinho de compras, bem como alterar as quantidades do produto em cada item

Cenário principal de sucesso
1. Executar caso de uso: Consultar catálogo.
2. [IN] O Usuário anônimo seleciona um produto.
3. [OUT] O sistema informa nome, preço, descrição, imagem, e nomes das categorias do produto selecionado.
4. [IN] O Usuário anônimo informa que deseja adicionar o produto ao carrinho.
5. [OUT] O sistema informa os dados do carrinho de compras [1].
6. [IN] O Usuário anônimo informa, opcionalmente, que deseja incrementar ou decrementar a quantidade de um item no carrinho de compras.
7. [ OUT] O sistema informa os dados atualizados do carrinho de compras [1].

Informações complementares
[1] Dados do carrinho de compras:
- lista de itens de carrinho
- valor total do carrinho de compras
Dados do item de carrinho:
- id do produto
- nome do produto
- preço do produto
- quantidade
- subtotal

Registrar pedido
Atores Cliente
Precondições - Usuário logado
- Carrinho de compras não vazio
Pós-condições Carrinho de compras vazio
Visão geral Salvar no sistema um pedido a partir dos dados do carrinho de compras informado.

Cenário principal de sucesso
1. [IN] O cliente informa os dados do carrinho de compras [1].
2. [OUT] O sistema informa os dados do carrinho de compras[1] e o id do pedido.

Informações complementares
[1] Dados do carrinho de compras: vide caso de uso Gerenciar carrinho.

Checklist: adicionar segurança ao projeto

Modelo de dados User-Role

user-role

Mapeamento N-N

@ManyToMany
@JoinTable(name = "tb_user_role",
        joinColumns = @JoinColumn(name = "user_id"),
        inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles = new HashSet<>();

Seed

INSERT INTO tb_role (authority) VALUES ('ROLE_OPERATOR');
INSERT INTO tb_role (authority) VALUES ('ROLE_ADMIN');

INSERT INTO tb_user_role (user_id, role_id) VALUES (1, 1);
INSERT INTO tb_user_role (user_id, role_id) VALUES (2, 1);
INSERT INTO tb_user_role (user_id, role_id) VALUES (2, 2);

Dependências

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-security</artifactId>
</dependency>

<dependency>
	<groupId>org.springframework.security</groupId>
	<artifactId>spring-security-test</artifactId>
	<scope>test</scope>
</dependency>

<dependency>
	<groupId>org.springframework.security</groupId>
	<artifactId>spring-security-oauth2-authorization-server</artifactId>
</dependency>

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>

Valores de configuração

security.client-id=${CLIENT_ID:myclientid}
security.client-secret=${CLIENT_SECRET:myclientsecret}

security.jwt.duration=${JWT_DURATION:86400}

cors.origins=${CORS_ORIGINS:http://localhost:3000,http://localhost:5173}

Checklist OAuth2 JWT password grant

  • Implementação customizada do password grant
  • Authorization server
  • Resource server

Fazer o controle de acesso por perfil e rota

Checklist Spring security

  • GrantedAuthority
  • UserDetails
  • UserDetailsService
  • UsernameNotFoundException

Controle de acesso por perfil e rota

@PreAuthorize("hasRole('ROLE_ADMIN')")

@PreAuthorize("hasAnyRole('ROLE_ADMIN', 'ROLE_OPERATOR')")

Salvando um pedido

{
  "items": [
    {
      "productId": 1,
      "quantity": 2
    },
    {
      "productId": 5,
      "quantity": 1
    }
  ]
}