Avaliar as habilidades de desenvolvimento do candidato na construção de um sistema simples de gerenciamento de usuários CRUD utilizando .NET Core para a API e Angular para a aplicação cliente web.
-
Backend API em .NET Core:
-
Autenticação e Autorização:
-
Endpoints:
- POST /api/auth/login Autenticação de usuário.
- GET /api/users Listar todos os usuários (protegido por autenticação).
- POST /api/users Adicionar um novo usuário (protegido por autenticação).
- PUT /api/users/{id} Atualizar um usuário existente (protegido por autenticação).
- GET /api/users/{id} Obter detalhes de um usuário específico (protegido por autenticação).
- DELETE /api/users/{id} Deletar um usuário (opcional e protegido por autenticação).
-
Banco de Dados:
- Usar Entity Framework Core para interação com o banco de dados.
- Criar uma tabela de usuários com colunas para ID, Nome, Email, Senha (hash).
-
-
Frontend (Aplicação Cliente) em Angular:
- Tela de Login:
- Formulário com campos para email e senha.
- Validação de formulário.
- Chamada ao endpoint de login da API.
- Redirecionamento para a tela de gerenciamento de usuários em caso de sucesso.
- Tela de Gerenciamento de Usuários:
- Grid de listagem de usuários com colunas para Nome e Email.
- Botão "Adicionar Usuário" para abrir um formulário de criação de usuário.
- Opção para editar um usuário existente (ao clicar em uma linha do grid ou um botão de editar).
- Validação de formulário ao adicionar ou editar usuários.
- Chamada aos endpoints apropriados da API para listar, adicionar e editar usuários.
- Proteção de rota para garantir que apenas usuários autenticados possam acessar.
- Tela de Login:
- Autenticação:
- Usuários devem poder se autenticar usando email e senha.
- Após o login bem-sucedido, um token JWT deve ser armazenado no cliente e usado para autenticação em chamadas subsequentes.
- Gerenciamento de Usuários:
- Listar todos os usuários em um grid na tela de gerenciamento.
- Permitir adição de novos usuários através de um formulário.
- Permitir edição de usuários existentes através de um formulário.
- O sistema deve validar que emails são únicos e senhas são suficientemente seguras.
- Qualidade de Código:
- Seguir boas práticas de codificação, incluindo a utilização de princípios SOLID e padrões de design apropriados.
- Escrever código limpo e comentado.
- Performance e Segurança:
- Garantir que a aplicação seja responsiva e tenha um bom desempenho.
- Implementar práticas de segurança para proteger contra ataques comuns (e.g., SQL Injection, XSS).
- Testes:
- Escrever testes unitários para componentes críticos do frontend e backend.
- Testar a aplicação manualmente para garantir que todas as funcionalidades estão operando corretamente.
- Compromisso:
- Independente de ter terminado ou não, entregue.
- Funcionalidade:
- O sistema atende a todos os requisitos funcionais especificados?
- A autenticação e autorização estão implementadas corretamente?
- Qualidade do Código:
- O código segue boas práticas de desenvolvimento?
- Está bem organizado e fácil de entender?
- Interface de Usuário:
- A UI é intuitiva e fácil de usar?
- As telas são responsivas e visualmente agradáveis?
- Performance e Segurança:
- A aplicação tem um bom desempenho?
- Foram implementadas medidas de segurança adequadas?
- Testes (Bônus):
- Existem testes unitários e eles cobrem as partes críticas do código?
Utilizei o padrão MVC para criação da API visto que incluiremos também um módulo de View mais na frente com o Angular. Além da estrutura padrão do MVC criei as pastas Services, que irão armazenar nossos serviços/métodos de acesso e a pasta Helpers para armazenar utilitários (No inicio da aplicação só consigo lembrar da classe de configuração do JWT, mas geralmente, aparecem mais no decorrer do desenvolvimento).
Apesar de o banco de dados padrão da avaliadora ser SQL Server, pela simplicidade e similidaridade optei pelo SQLite. Como ORM, seguiremos como pede o teste utilizando o Entity Framework.
Comentários que se iniciem com * tratam-se de comentários para serem feitos na entrevista de apresentação do projeto e não de comentários técnicos, ou seja, comentários que visam lembrar o que pensei enquanto desenvolvia. Dessa forma, peço que na avaliação sejam ignorados os comentários que se iniciarem com *.
-
Banco de Dados e EF
O Banco de dados será o SQLite, manipulado pelo EntityFramework.
Instalação:
dotnet add package Microsoft.EntityFrameworkCore.Sqlite dotnet add package Microsoft.EntityFrameworkCore.Design -
JWT
Para autenticação e autorização de usuários
Instalação:
dotnet add package System.IdentityModel.Tokens.Jwt dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer --version 8.0.10
-
BCrypt
O BCrypt será utilizado na criação e tradução de Hash visando manter o tráfego de dados sensíveis seguro.
Instalação:
dotnet add package BCrypt.Net-Next --version 4.0.3
Criei um pequeno módulo com uma aplicação simples de console que retorna alguns tipos de chave. A criação foi baseada na necessidade de criação de guid e hash fixos para as migrations além de ser utilizada também para criar uma chave segura para o JWT. Esse módulo pode ser acessado Clicando Aqui.
-
Método:
POST -
Rota:
/api/customers/register -
Autenticação: Não requer autenticação.
-
Corpo da Requisição:
{ "name": "João Silva", "email": "joao.silva@example.com", "password": "senhaSegura123" } -
Resposta de Sucesso:
Copy { "message": "Customer registered successfully!" }
-
Resposta de Erro:
Copy { "error": "Email already registered." }
Retorna uma lista de todos os clientes registrados.
-
Método:
GET -
Rota:
/api/customers -
Autenticação: Requer autenticação.
-
Resposta de Sucesso:
[ { "id": "d3b4f5e6-7a8b-4c9d-8e1f-2a3b4c5d6e7f", "name": "Admin", "email": "admin@teste.com.br", "role": "Admin" }, { "id": "80752c0c-4672-492d-b4c6-db5db5dc4366", "name": "Denisson Silva", "email": "denisson@teste.com.br", "role": "Admin" } ]
Retorna os detalhes de um cliente específico com base no ID.
-
Método:
GET -
Rota:
/api/customers/{id} -
Autenticação: Requer autenticação.
-
Parâmetros de URL:
id: ID do cliente.
-
Resposta de Sucesso:
[ { "id": "80752c0c-4672-492d-b4c6-db5db5dc4366", "name": "Denisson Silva", "email": "denisson@teste.com.br", "role": "Admin" } ] -
Resposta de Erro:
[ { "error": "Customer not found." } ]
Atualiza as informações de um cliente existente.
-
Método:
PUT -
Rota:
/api/customers/{id} -
Autenticação: Requer autenticação e permissão de administrador.
-
Parâmetros de URL:
id: ID do cliente.
-
Corpo da requisição (é possível passar somente a propriedade a ser alterada):
{ "password": "novaSenhaSegura123", "role": "Default" } -
Resposta de Sucesso:
{ "message": "Customer updated successfully!" } -
Resposta de Erro:
{ "error": "Customer not found." }
Exclui um cliente do sistema.
-
Método:
DELETE -
Rota:
/api/customers/{id} -
Autenticação: Requer autenticação e permissão de administrador..
-
Parâmetros de URL:
id: ID do cliente.
-
Resposta de Sucesso:
{ "message": "Customer deleted successfully!" } -
Resposta de Erro:
{ "error": "Customer not found." }
-
Proteção contra XSS: Todas as entradas de dados são sanitizadas para prevenir ataques de Cross-Site Scripting (XSS).
-
Hash de Senhas: As senhas dos clientes são armazenadas utilizando o algoritmo de hash BCrypt.
-
Controle de Acesso: Apenas administradores podem excluir e atualizar clientes.