O que foi desenvolvido
-
Uma API RESTful utilizando a arquitetura em camadas;
-
A API é um sistema de gerenciamento de vendas em que será possível criar, visualizar, deletar e atualizar produtos e vendas;
-
API desenvolvida utilizando o banco de dados MySQL para a gestão de dados;
-
Testes unitários para garantir as funcionalidade das implementações.
Habilidades desenvolvidas
- Interação com um banco de dados relacional (MySQL);
- Implementação uma API utilizando arquitetura em camadas (MSC);
- Criação de validações para os dados recebidos pela API;
- Desenvolvimento de testes para APIs, garantindo o funcionamento correto da implementação dos endpoints.
Iniciando a aplicação
# Instale as dependências
npm install
# Inicie os containers do compose `backend` e `db`
# A aplicação estará disponível em `http://localhost:3001` em modo de desenvolvimento
docker-compose up -d
# É possível ver os logs da aplicação com `docker logs -n 10 -f <nome-do-container>`
docker logs -n 10 -f store_manager
Como executar os testes
Resumo dos comandos relacionados aos testes:
npm run test:mocha # roda os testes do mocha
npm run test:coverage # roda os testes e mostra a cobertura geral
npm run test:mutation # roda os testes e mostra a cobertura de mutações
- O endpoint para listar todos os produtos é acessível através do caminho
GET /products
eGET /products/:id
; - Através de
GET /products
, todos os produtos são retornados; - Através de
GET /products/:id
, apenas o produto com oid
presente na URL é retornado; - Foram criados testes que garantem as funcionalidades implementadas.
O que foi desenvolvido:
-
Listagem de todos os produtos
Ao fazer uma requisição para
GET /products
, é retornado o status http200
com o seguinte:[ { "id": 1, "name": "Martelo de Thor" }, { "id": 2, "name": "Traje de encolhimento" } /* ... */ ]
-
Não é possível listar um produto que não existe
Ao fazer uma requisição para
GET /products/:id
com o id de um produto, o resultado retornado é um status http404
com o seguinte corpo:{ "message": "Product not found" }
-
Listagem de um produto específico
Ao fazer uma requisição para
GET /products/:id
, caso exista um produto com oid
, retorna um status http200
e o seguinte corpo:{ "id": 1, "name": "Martelo de Thor" }
- O endpoint para listar vendas é acessível através do caminho
GET /sales
eGET /sales/:id
; - Através do
GET /sales
retorna todas as vendas; - Através do
GET /sales/:id
, retorna a venda com oid
presente na URL;
O que foi desenvolvido:
-
Listagem de todas as vendas
Ao fazer uma requisição para
GET /sales
, retorna o status http200
com o seguinte corpo:[ { "saleId": 1, "date": "2021-09-09T04:54:29.000Z", "productId": 1, "quantity": 2 }, { "saleId": 1, "date": "2021-09-09T04:54:54.000Z", "productId": 2, "quantity": 2 } /* ... */ ]
-
Não é possível listar uma venda que não existe
Ao fazer uma requisição para
GET /sales/:id
com um id inexistente, retorna o status http404
com o seguinte corpo:{ "message": "Sale not found" }
-
Listagem de uma venda específica
Ao fazer uma requisição para
GET /sales/:id
com um id existente, retorna o status http200
com o seguinte corpo:[ { "date": "2021-09-09T04:54:29.000Z", "productId": 1, "quantity": 2 }, { "date": "2021-09-09T04:54:54.000Z", "productId": 2, "quantity": 2 } /* ... */ ]
- O endpoint é acessível através do caminho
POST /products
; - Os produtos enviados são salvos na tabela
products
do banco de dados; - O corpo da requisição segue o formato abaixo:
{
"name": "ProdutoX"
}
O que foi desenvolvido:
-
É possível cadastrar um produto
Ao fazer uma requisição para
POST /products
, o resultado é um status http201
:{ "id": 4, "name": "ProdutoX" }
- O endpoint de cadastro de produtos retorna mensagens de erro para requisições com dados inválidos;
O que foi desenvolvido:
-
Não é possível cadastrar um produto sem o campo
name
Se a requisição para
POST /products
não tiver o camponame
, o resultado retornado é um status http400
:{ "message": "\"name\" is required" }
-
Não é possível cadastrar um produto com o campo
name
menor que 5 caracteresSe a requisição para
POST /products
não tivername
com pelo menos 5 caracteres, o resultado retornado é um status http422
com a seguinte mensagem:{ "message": "\"name\" length must be at least 5 characters long" }
- O endpoint de vendas é acessível através do caminho
POST /sales
; - As vendas enviadas são salvas nas tabelas
sales
esales_products
do banco de dados; - É possível cadastrar a venda de vários produtos através da uma mesma requisição;
- O corpo da requisição segue o seguinte formato:
[
{
"productId": 1,
"quantity": 1
},
{
"productId": 2,
"quantity": 5
}
]
O que foi desenvolvido:
-
É possível cadastrar uma venda
Ao fazer uma requisição válida para
POST /sales
, o resultado é um status http201
com o seguinte corpo:{ "id": 3, "itemsSold": [ { "productId": 1, "quantity": 1 }, { "productId": 2, "quantity": 5 } ] }
- O endpoint de cadastro de vendas retorna mensagens de erro para requisições com dados inválidos;
O que foi desenvolvido:
-
Não é possível cadastrar uma venda sem o campo
productId
Se algum dos itens da requisição para
POST /sales
não tiver o campoproductId
, o resultado retornado é um status http400
com a seguinte mensagem:{ "message": "\"productId\" is required" }
-
Não é possível cadastrar uma venda sem o campo
quantity
Se algum dos itens da requisição para
POST /sales
não tiver o campoquantity
, o resultado retornado é um status http400
com a seguinte mensagem:{ "message": "\"quantity\" is required" }
-
Não é possível cadastrar uma venda com o campo
quantity
menor ou igual a zeroSe a requisição para
POST /sales
tiver algum item em que o campoquantity
seja menor ou igual a zero, o resultado retornado é um status http422
com a seguinte mensagem:{ "message": "\"quantity\" must be greater than or equal to 1" }
-
Não é possível cadastrar uma venda com o campo
productId
inexistente, em uma requisição com um único itemSe o campo
productId
do item da requisição paraPOST /sales
não existir no banco de dados, o resultado retornado é um status http404
com a seguinte mensagem:{ "message": "Product not found" }
-
Não é possível cadastrar uma venda com o campo
productId
inexistente, em uma requisição com vários itemsSe a requisição para
POST /sales
tiver algum item cujo campoproductId
não existe no banco de dados, o resultado retornado é um status http404
com a seguinte mensagem:{ "message": "Product not found" }
- O endpoint é acessível através do caminho
PUT /products/:id
; - Apenas o produto com o
id
presente na URL é atualizado; - O corpo da requisição é validado igual ao cadastro;
- O corpo da requisição segue o seguinte formato:
{
"name": "Martelo do Batman"
}
O que foi desenvolvido:
-
Não é possível alterar um produto sem o campo
name
Se a requisição para
PUT /products/:id
não tiver o camponame
, o resultado retornado é um status http400
com a seguinte mensagem:{ "message": "\"name\" is required" }
-
Não é possível alterar um produto com o campo
name
menor que 5 caracteresSe a requisição para
PUT /products/:id
não tivername
com pelo menos 5 caracteres, o resultado retornado é um status http422
com a seguinte mensagem:{ "message": "\"name\" length must be at least 5 characters long" }
-
Não é possível alterar um produto que não existe
Se a requisição para
PUT /products/:id
informar oid
de um produto inexistente, o resultado retornado é um status http404
com a seguint mensagem:{ "message": "Product not found" }
-
É possível alterar um produto
Ao fazer uma requisição válida para
PUT /products/:id
, o resultado retornado é um status http200
com o seguinte corpo:{ "id": 1, "name": "Martelo do Batman" }
- O endpoint é acessível através do caminho
DELETE /products/:id
; - Apenas o produto com o
id
presente na URL é deletado;
O que foi desenvolvido:
-
Não é possível deletar um produto que não existe
Se a requisição para
DELETE /products/:id
informar oid
de um produto inexistente, o resultado retornado é um status http404
com a seguinte mensagem:{ "message": "Product not found" }
-
É possível deletar um produto com sucesso
Ao fazer uma requisição válida para
DELETE /products/:id
, não é retornada nenhuma resposta, apenas um status http204
;
- O endpoint é acessível através do caminho
DELETE /sales/:id
; - Apenas a venda com o
id
presente na URL é deletada;
O que foi desenvolvido:
-
Não é possível deletar uma venda que não existe
Se a requisição para
DELETE /sales/:id
informar oid
de uma venda inexistente, o resultado retornado é um status http404
com a seguinte mensagem:{ "message": "Sale not found" }
-
É possível deletar uma venda com sucesso
Ao fazer uma requisição válida para
DELETE /sales/:id
, não é retornada nenhuma resposta, apenas um status http204
;
- O endpoint é acessível através do caminho
/sales/:saleId/products/:productId/quantity
; - Apenas a quantidade do produto vendido com o
productId
na URL é atualizada;
{
"quantity": 20
}
O que foi desenvolvido:
-
Não é possível realizar alterações em uma venda sem o campo
quantity
Se a requisição para
PUT /sales/:saleId/products/:productId/quantity
não tiver o campoquantity
, o resultado retornado é um status http400
com a seguinte mensagem:{ "message": "\"quantity\" is required" }
-
Não é possível realizar alterações em uma venda com o campo
quantity
menor ou igual a zeroSe a requisição para
PUT /sales/:saleId/products/:productId/quantity
tiver o campoquantity
menor que zero, o resultado retornado é um status http422
com a seguinte mensagem:{ "message": "\"quantity\" must be greater than or equal to 1" }
-
Não é possível realizar alterações em uma venda com
productId
inexistenteSe a requisição para
PUT /sales/:saleId/products/:productId/quantity
tiver o campoproductId
com um valor não existente no banco, o resultado retornado é um status http404
com a seguinte mensagem:{ "message": "Product not found in sale" }
-
Não é possível alterar uma venda que não existe
Se a requisição para
PUT /sales/:saleId/products/:productId/quantity
informar osaleId
de uma venda inexistente, o resultado retornado é um status http404
com a seguinte mensagem:{ "message": "Sale not found" }
-
É possível alterar a quantidade de um produto de uma venda
Ao fazer uma requisição válida para
PUT /sales/:saleId/products/:productId/quantity
, a requisição retorna um status http200
com o seguinte corpo:{ "date": "2023-05-06T03:14:28.000Z", "productId": 2, "quantity": 20, "saleId": 1 }
- O endpoint é acessível através do URL
GET /products/search
; - O endpoint é capaz de trazer todos os produtos no banco de dados contendo o valor da query
q
emname
, se existirem; - Retorna um array de produtos que contenham em seu nome o termo passado na URL;
- Retorna todos os produtos caso a query
q
esteja vazia; - Retorna um array vazio caso nenhum nome satisfaça a busca;
- A query da requisição segue o seguinte formato:
http://localhost:PORT/products/search?q=Martelo
O que foi desenvolvido:
-
É possível buscar um produto pelo
name
Se a requisição para
GET /products/search
for feita com uma queryq
cujo valor exista no atributoname
de algum produto, o resultado retornado é um status http200
com o seguinte corpo:// GET /products/search?q=Martelo [ { "id": 1, "name": "Martelo de Thor" } ]
-
É possível buscar todos os produtos quando passa a busca vazia
Se a requisição para
GET /products/search
foi feita com uma queryq
vazia, retorna um status http200
e o seguinte corpo:// GET /products/search?q= [ { "id": 1, "name": "Martelo de Thor", }, { "id": 2, "name": "Traje de encolhimento", } /* ... */ ]
-
A busca retorna um array vazio quando não há produtos correspondentes
Se a requisição para
GET /products/search
for feita com uma queryq
cujo valor não exista no atributoname
de nenhum produto, retorna um array vazio, com um status http200
:// GET /products/search?q=ProdutoInexistente []