Neste projeto, foi desenvolvido uma API para um sistema de delivery de comida. O sistema possui um banco de dados com informações de produtos e usuários, e permite que usuários façam pedidos de produtos cadastrados no banco de dados.
A API permite obter produtos disponíveis para compra e manipular a sacola do usuário, incluindo a inserção, escolha de quantidades e remoção de itens. Para a Fase 1, onde o EnaFood possuía cerca de 100 usuários, cada um fazendo em média 5 pedidos por mês, a API foi desenvolvida com a capacidade de gerenciar pedidos com 1 a 5 produtos.
Na Fase 2, que contava com cerca de 10.000 usuários e uma média de 10 pedidos por mês, a API foi atualizada para lidar com pedidos que continham de 1 a 15 produtos. Na Fase 3, que contava com cerca de 1.000.000 de usuários e uma média de 25 pedidos por mês, a API foi novamente atualizada para lidar com pedidos que continham de 1 a 20 produtos.
Por fim, na Fase 4, onde o EnaFood havia se tornado a principal rede de delivery do Brasil, com cerca de 50.000.000 de usuários, a API passou por uma última atualização para lidar com pedidos que também eram feitos por empresas, com um grande volume de produtos e preços mais em conta.
Como executar o projeto
-
Clone o repositório
git clone git@github.com:JackS1o/Delivery-Challenge.git -
Na raíz do projeto, execute o comando
docker-compose up -dpara subir o container da aplicação e do banco de dados. O servidor estará disponível na porta3001. -
Na raíz do projeto, execute o comando
npm run products:importpara popular o banco de dados com os produtos.
Rotas desenvolvidas
POST /register- Cria um novo usuário. O corpo da requisição deve conter oemailepassworddesejados. Exemplo de corpo de requisição:
{
"email": "jack@gmail.com",
"password": "123456",
}a resposta será um objeto com o um token de autenticação no seguinte formato:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImphQGdtYWlsLmNvbSIsImlhdCI6MTY3ODY2NTU3NiwiZXhwIjoxNjc4NjY5MTc2fQ.svDiQTwItv4FG9_0OZNrxmKWb0EWRPsk8LFbYAtUIAc"
}POST /login- Realiza o login de um usuário. O corpo da requisição deve conter oemailepasswordque existam no banco de dados. O retorno dessa requisição tabém gera umtoken. Exemplo de corpo de requisição:
{
"email": "jack@gmail.com",
"password": "123456",
}GET /products- Retorna todos os produtos cadastrados no banco de dados. Exemplo de resposta:
[
{
"_id": "640ebdb605aaccc707ab1507",
"name": "Coca-Cola",
"price": 5,
"description": "Coca-Cola is a carbonated soft drink manufactured by The Coca-Cola Company."
},
{
"_id": "640ebdb605aaccc707ab1508",
"name": "Pepsi",
"price": 5,
"description": "Pepsi is a carbonated soft drink manufactured by PepsiCo."
}
]GET /orders- Retorna todas as ordens de compra cadastradas no banco de dados. Exemplo de resposta:
[
{
"_id": "640ebdb605aaccc707ab1507",
"user": "jack@gmail.com",
"paymentMethod": "cartão",
"address": "Rua São Miguel",
"order": [
{
"_id": "640ebdb605aaccc707ab1507",
"name": "Coca-Cola",
"price": 5,
"description": "Coca-Cola is a carbonated soft drink manufactured by The Coca-Cola Company.",
"quantity": 2
},
{
"_id": "640ebdb605aaccc707ab1508",
"name": "Pepsi",
"price": 5,
"description": "Pepsi is a carbonated soft drink manufactured by PepsiCo.",
"quantity": 2
}
]
}
]GET /user/orders- Retorna todas as ordens de compra de um usuário específico. Exemplo de resposta:
{
"_id": "640ebdb605aaccc707ab1507",
"user": "jack@gmail.com",
"paymentMethod": "cartão",
"address": "Rua São Miguel",
"order": [
{
"_id": "640ebdb605aaccc707ab1507",
"name": "Coca-Cola",
"price": 5,
"description": "Coca-Cola is a carbonated soft drink manufactured by The Coca-Cola Company.",
"quantity": 2
}
]
}GET /order/:id- Retorna uma ordem de compra específica. Exemplo de resposta:
{
"_id": "640ebdb605aaccc707ab1507",
"user": "jack@gmail.com",
"paymentMethod": "cartão",
"address": "Rua São Miguel",
"order": [
{
"_id": "640ebdb605aaccc707ab1507",
"name": "Coca-Cola",
"price": 5,
"description": "Coca-Cola is a carbonated soft drink manufactured by The Coca-Cola Company.",
"quantity": 2
}
]
}DELETE /order/:id- Deleta uma ordem de compra específica. Exemplo de resposta:
{
"message": "Sale deleted successfully!",
"order": {
"_id": "640e204bff9bfc2adbe8933f",
"user": "jack@gmail.com",
"paymentMethod": "cartão",
"address": "Rua São Miguel",
"order": [
{
"_id": "640ebdb605aaccc707ab1507",
"name": "Coca-Cola",
"price": 5,
"description": "Coca-Cola is a carbonated soft drink manufactured by The Coca-Cola Company.",
"quantity": 2
}
]
}
}POST /mvp/order- é possível criar uma nova ordem de compra, porém, nessa rota, o usuário consegue criar uma ordem com nomáximo 5 produtos.POST /earlyadopters/order- é possível criar uma nova ordem de compra, porém, nessa rota, o usuário consegue criar uma ordem com nomáximo 15 produtos.POST /earlymajority/order- é possível criar uma nova ordem de compra, porém, nessa rota, o usuário consegue criar uma ordem com nomáximo 20 produtos.POST /latemajority/order- é possível criar uma nova ordem de compra sem limite de produtos.- Todas as rotas de criação de ordem de compra recebem o seguinte corpo de requisição:
{
"paymentMethod": "cartão",
"address": "Rua São Miguel",
"order": [
{
"_id": "640ebdb605aaccc707ab1507",
"name": "Coca-Cola",
"price": 5,
"description": "Coca-Cola is a carbonated soft drink manufactured by The Coca-Cola Company.",
"quantity": 2
}
]
}- As rotas
PATCH /mvp/order/:id,PATCH /earlyadopters/order/:id,PATCH /earlymajority/order/:idePATCH /latemajority/order/:idsão responsáveis por atualizar uma ordem de compra específica. Todas as rotas recebem o seguinte corpo de requisição:
{
"paymentMethod": "cartão",
"address": "Rua São Miguel",
"order": [
{
"_id": "640ebdb605aaccc707ab1507",
"name": "Coca-Cola",
"price": 5,
"description": "Coca-Cola is a carbonated soft drink manufactured by The Coca-Cola Company.",
"quantity": 2
}
]
}Testes
- Para executar os testes, execute o comando
npm testna raíz do projeto. - Os testes foram desenvolvidos utilizando
Mocha,Jest,ChaieSinon. - Os testes foram desenvolvidos para as camadas de
Controllerdo projeto.
Desenvolvimento
-
O projeto foi desenvolvido utilizando arquitetura MSC (Model, Service e Controller) para uma melhor organização do código e também
middlewarespara verificar se os dados enviados pelo usuário estão corretos, se o usuário está autenticado, se o produto enviado pelo usuário existe, se a quantidade de produtos enviados pelo usuário é válida, entre outros. -
errorHandler- Middleware que captura os erros e retorna uma mensagem de erro. -
authToken- Middleware que verifica se o usuário está autenticado. Caso não esteja, retorna um erro. -
validateLogin- Middleware que verifica se os dados enviados pelo usuário ao realizar o login ou se registrar estão corretos. Caso não estejam, retorna um erro. -
validateOrderFields- Middleware que verifica se os dados enviados pelo usuário ao realizar uma nova ordem de compra estão corretos. Caso não estejam, retorna um erro. -
productExists- Middleware que verifica se o produto enviado pelo usuário ao realizar uma nova ordem de compra existe. Caso não exista, retorna um erro. -
invalidQuantityMVP- Middleware que verifica se a quantidade de produtos enviados pelo usuário ao realizar uma nova ordem de compra na rota/mvp/orderé válida. Caso não seja, retorna um erro. -
invalidQuantityEarlyAdop- Middleware que verifica se a quantidade de produtos enviados pelo usuário ao realizar uma nova ordem de compra na rota/earlyadopters/orderé válida. Caso não seja, retorna um erro. -
invalidQuantityEarlyMajor- Middleware que verifica se a quantidade de produtos enviados pelo usuário ao realizar uma nova ordem de compra na rota/earlymajority/orderé válida. Caso não seja, retorna um erro. -
invalidUpdatedQuantityMVP- Middleware que verifica se a quantidade de produtos enviados pelo usuário ao atualizar uma ordem de compra na rota/mvp/order/:idé válida. Caso não seja, retorna um erro. -
invalidUpdatedQuantityEarlyAdop- Middleware que verifica se a quantidade de produtos enviados pelo usuário ao atualizar uma ordem de compra na rota/earlyadopters/order/:idé válida. Caso não seja, retorna um erro. -
invalidUpdatedQuantityEarlyMajor- Middleware que verifica se a quantidade de produtos enviados pelo usuário ao atualizar uma ordem de compra na rota/earlymajority/order/:idé válida. Caso não seja, retorna um erro. -
invalidUpdatedFields- Middleware que verifica se os dados enviados pelo usuário ao atualizar uma ordem de compra estão corretos. Caso não estejam, retorna um erro.
Tecnologias utilizadas
- O projeto foi desenvolvido utilizando o
Dockerpara a criação de containers. - Linguagem
Node.jse banco de dadosMongoDB. Expresspara a criação das rotas.Mongoosepara a conexão com o banco de dados.JWTpara a autenticação de usuários.Mocha,Jest,ChaieSinonpara a realização dos testes.Joipara a validação de dados.Express Async Errorspara a tratativa de erros.Dotenvpara a utilização de variáveis de ambiente.