Magalu Logo

Desafio Técnico Magalu

Este desafio foi feito usando o framework NestJS e a conexão com o banco de dados foi feita utilizando a ORM TypeORM

Pré requisitos

  • MySQL
  • Docker com Docker-compose
Instalando os pré-requisitos

Este projeto utiliza MySQL como banco de dados. Eu decidi criar o ele usando o Docker para facilitar o desenvolvimento e reprodução e não ter que criar um banco hospedado em algum outro lugar.

Rodando o projeto

Depois que os pré-requisitos estão instalados, você pode usar o comando abaixo para subir ele:

Com docker

$ npm install
$ docker-compose up 

Sem docker

É necessário alterar as variáveis de ambiente listadas abaixo no arquivo .env para coincidir com seu banco de dados:

  • MYSQL_HOST
  • MYSQL_PORT
  • MYSQL_USER
  • MYSQL_PASSWORD

Então você pode executar o projeto com os comandos:

$ npm install 
$ npm run start:dev

Reproduzindo os casos de uso do projeto

Conforme o solicitado no desafio, existem as funcionalidades de autorização e autenticação. Acho interessante notar que se vocês olharem no histórico de commits, vão poder observar que eu tive que fazer uma pequena refatoração para acomodar adequadamente o serviço.

Disclaimer (Todas as rotas estão disponíveis na rota /swagger em seu localhost na porta 3000)

Criando usuário

  1. Crie dois usuários com os dados abaixo
{
    "email": "magalu@gmail.com",
    "password": "magalu1",
    "name": "Magalu Teste 1"
}
  1. Faça o login pela rota /auth/login usando o usuário e senha que foram criados

Adicionando favoritos

  1. Para adicionar um produto à lista de favoritos do usuário, use a rota de favorites, lembrando de adicionar o header Authorization com o valor Bearer :seu_token na requisição. Exemplo: localhost:3000/favorites/af04c0ee-7137-4848-fd33-a2d148412095
  2. Ao fazer um GET do usuário pela rota /customers/:id, você deve receber o usuário com a lista de favoritos. ( Ao fazer o GET em /customers a lista detalhada de favoritos não é exibida. Está explicado nas considerações )

Testes unitários

O desafio não especificava, mas um dos assuntos que conversamos foram testes unitários, então deixei uma pasta com alguns testes para visualizar de exemplo. Para rodar os testes, o comando abaixo deve ser executado

Com Docker

$ docker-compose -f docker-compose.test.yaml up

Sem Docker

$ npm install # esse passo não é necessário se já tiver sido feito ao rodar o projeto
$ npm run test

Cleanup

$ docker-compose down
$ docker-compose -f docker-compose.test.yaml down

Considerações

  1. As variáveis do projeto estão em um arquivo .env preenchido, entretanto o correto, levando em consideração segurança e governança, é este arquivo subir pro repositório apenas com as variáveis não preenchidas. Eu preenchi elas por que quem for avaliar o projeto não deve ter o trabalho de criar todas as variáveis manualmente
  2. Pra melhorar a performance da API, ao buscar o endereço [GET] /customers, eu envio exatamente o que eu gravei na api, visto que eu vou buscar talvez centenas de usuários e faço uma integração com uma api externa, enviar apenas os ids dos produtos favorece a performance. Já ao consultar [GET] /customers/:id eu faço a integração com a api externa e trago todos os produtos. Visto que o usuário, neste cenário, vai ter no máximo 10 a 20 produtos em seus favoritos. Entretanto, com múltiplos usuários acessando a api constantemente, é de se esperar que o volume de requisições exceda o razoável. Eu cheguei a cogitar fazer um cacheamento no redis porém, eu desisti da ideia, visto que é um marketplace, os preços podem flutuar muito e eu não conseguiria, com o setup que eu tenho agora, sincronizar os preços dos produtos constantemente, o que poderia causar um problema maior no final. (posso elaborar melhor se precisar)
  3. Apesar de não ser necessário, eu decidi disponibilizar o client de produtos como uma api à parte enquanto eu testava o projeto no meu mini-frontend. No final, eu decidi deixar ele disponibilizado na documentação pra que vocês pudessem ver o processo que tomei pra desenvolver
  4. A documentação da API foi feita em modelo swagger, dessa maneira é possível avaliar os endpoints com facilidade pelo recrutador. Ele fica disponível em http://localhost:3000/swagger
  5. Levando em consideração que esta api pode ser reutilizada para criar clients pelo swagger-codegen, eu disponibilizei um yaml com as definições no endereço http://localhost:3000/swagger-json
  6. Apesar de não ser necessário, eu fiz um pequeno front-end para testes, por isso habilitei o CORS
  7. Eu habilitei algumas outras funcionalidades de segurança: rate-limiting e helmet são as principais
  8. Eu adicionei um arquivo do travis pra exemplificar como ficam os testes com integração contínua