Repositório possuí projeto desenvolvido no período que estive na Trybe, abordando os conceitos de API Rest com CRUD completo e seus endpoints.
- Entender o funcionamento da camada de Model;
- Delegar responsabilidades específicas para essa camada;
- Conectar sua aplicação com diferentes bancos de dados;
- Estruturar uma aplicação em camadas;
- Delegar responsabilidades específicas para cada parte do seu app;
- Melhorar manutenibilidade e reusabilidade do seu código;
- Entender e aplicar os padrões REST;
- Escrever assinaturas para APIs intuitivas e facilmente entendíveis.
Uma API Rest trata-se de um sistema de gerenciamento de vendas, onde será possível criar, visualizar, deletar e atualizar produtos e vendas.
# Clone o repositório
git clone git@github.com:pedrohassen/store-manager.git
# Entre na pasta do repositório que você acabou de clonar:
cd store_manager
# Instale as dependências e inicialize o projeto
npm install
# Entre no Vs Code para verificar os arquivos usando o atalho no terminal:
code .
#Para iniciar o projeto, execute o comando:
npm start
# A pasta tests contém os testes que verifica se os comandos estão atendendo o que foi pedido
# Leia os Requisitos do Projeto logo abaixo explicando o que cada requisito propõem
# Para rodar os tests use o atalho no terminal:
npm run test
-
O endpoint deve ser acessível através do caminho (
/products
); -
Os produtos enviados devem ser salvos na tabela
products
do Banco de Dados; -
O endpoint deve receber a seguinte estrutura:
{
"name": "product_name",
"quantity": "product_quantity"
}
O que será validado
👉 Para o endpoint
POST /products
, o camponame
deve ser uma string com 5 ou mais caracteres e deve ser único.
- Quando a requisição é feita sem o atributo
name
:{ "quantity": 100 }
- sua API deve responder com status http
400
e o seguintebody
:
{ "message": "\"name\" is required" }
- sua API deve responder com status http
- Quando a requisição é feita e contém o seguinte
body
:{ "name": "pro", "quantity": 100 }
- sua API deve responder com status http
422
e o seguintebody
:
{ "message": "\"name\" length must be at least 5 characters long" }
- sua API deve responder com status http
- Quando a requisição é feita com o atributo
name
igual um já cadastrado:{ "name": "produto", "quantity": 100 }
- sua API deve responder com status http
409
e o seguintebody
:
{ "message": "Product already exists" }
- sua API deve responder com status http
👉 Para o endpoint
POST /products
, o campoquantity
deve ser um número inteiro maior que 0.
- Quando a requisição é feita sem o atributo
quantity
:{ "name": "produto" }
- sua API deve responder com status http
400
e o seguintebody
:{ "message": "\"quantity\" is required" }
- sua API deve responder com status http
- Quando a requisição é feita e contém os seguintes
body
:{ "name": "produto", "quantity": "string" }
{ "name": "produto", "quantity": -1 }
{ "name": "produto", "quantity": 0 }
- sua API deve responder com status http
422
e o seguintebody
:
{ "message": "\"quantity\" must be a number larger than or equal to 1" }
- sua API deve responder com status http
👉 Para o endpoint
POST /products
, quando a requisição é feita corretamente, o produto deve ser cadastrado.
- Quando a requisição é feita e contém o seguinte
body
:{ "name": "produto", "quantity": 10 }
- sua API deve responder com status http
201
e o seguintebody
:
{ "id": 1, "name": "produto", "quantity": 10 }
- sua API deve responder com status http
-
O endpoint deve ser acessível através do caminho (
/products
) ou (/products/:id
); -
Através do caminho
/products
, todos os produtos devem ser retornados; -
Através do caminho
/products/:id
, apenas o produto com oid
presente na URL deve ser retornado;
O que será validado
👉 Para o endpoint
GET /products
, será validado que todos produtos estão sendo retornados.
- sua API deve responder com status http
200
e o seguintebody
:
[
{
"id": 1,
"name": "produto A",
"quantity": 10
},
{
"id": 2,
"name": "produto B",
"quantity": 20
}
]
👉 Para o endpoint
GET /products/:id
, será validado que é possível listar um determinado produto.
- sua API deve responder com status http
200
e o seguintebody
:{ "id": 1, "name": "produto A", "quantity": 10 }
👉 Para o endpoint
GET /products/:id
, será validado que não é possível listar um produto que não existe.
- sua API deve responder com status http
404
e o seguintebody
:{ "message": "Product not found" }
-
O endpoint deve ser acessível através do caminho (
/products/:id
); -
O corpo da requisição deve seguir a mesma estrutura do método responsável por adicionar um produto;
-
Apenas o produto com o
id
presente na URL deve ser atualizado; -
O corpo da requisição deve receber a seguinte estrutura:
{
"name": "new_product_name",
"quantity": "new_product_quantity"
}
O que será validado
👉 Para o endpoint
PUT /products/:id
, o camponame
deve ser uma string com 5 ou mais caracteres e deve ser único.
- Quando a requisição é feita e contém o seguinte
body
:{ "name": "pro", "quantity": 15 }
- sua API deve responder com status http
422
e o seguintebody
:
{ "message": "\"name\" length must be at least 5 characters long" }
- sua API deve responder com status http
👉 Para o endpoint
PUT /products/:id
, o campoquantity
deve ser um número inteiro maior que 0.
- Quando a requisição é feita e contém os seguintes
body
:{ "name": "produto", "quantity": "string" }
{ "name": "produto", "quantity": -1 }
{ "name": "produto", "quantity": 0 }
- sua API deve responder com status http
422
e o seguintebody
:
{ "message": "\"quantity\" must be a number larger than or equal to 1" }
- sua API deve responder com status http
👉 Para o endpoint
PUT /products/:id
, quando a requisição é feita corretamente, o produto deve ser alterado.
- Quando a requisição é feita e contém o seguinte
body
:{ "name": "produto", "quantity": 15 }
- sua API deve responder com status http
200
e o seguintebody
:
{ "id": 1, "name": "produto", "quantity": 15 }
- sua API deve responder com status http
👉 Para o endpoint
PUT /products/:id
, será validado que não é possível alterar um produto que não existe.
- sua API deve responder com status http
404
e o seguintebody
:{ "message": "Product not found" }
-
O endpoint deve ser acessível através do caminho (
/products/:id
); -
Apenas o produto com o
id
presente na URL deve ser deletado;
O que será validado
👉 Para o endpoint
DELETE /products/:id
, será validado que é possível deletar um produto com sucesso.
- sua API deve responder com status http
200
e o seguintebody
:
{
"id": 1,
"name": "produto A",
"quantity": 10
}
👉 Para o endpoint
DELETE /products/:id
, será validado que não é possível deletar um produto que não existe.
- sua API deve responder com status http
404
e o seguintebody
:{ "message": "Product not found" }
-
O endpoint deve ser acessível através do caminho (
/sales
); -
As vendas enviadas devem ser salvas na tabela
sales
esales_products
do Banco de dados; -
Deve ser possível cadastrar a venda de vários produtos através da uma mesma requisição;
-
O endpoint deve receber a seguinte estrutura:
[
{
"product_id": "product_id",
"quantity": "product_quantity",
}
]
O que será validado
👉 Para o endpoint
POST /sales
, o campoproduct_id
deve ser um id de um produto anteriormente cadastrado.
- Quando a requisição é feita sem o atributo
product_id
:[ { "quantity": 1 } ]
- sua API deve responder com status http
400
e o seguintebody
:
{ "message": "\"product_id\" is required" }
- sua API deve responder com status http
👉 Para o endpoint
POST /sales
, o campoquantity
deve ser um número inteiro maior que 0.
- Quando a requisição é feita sem o atributo
quantity
:[ { "product_id": 1 } ]
- sua API deve responder com status http
400
e o seguintebody
:{ "message": "\"quantity\" is required" }
- sua API deve responder com status http
- Quando a requisição é feita e contém os seguintes
body
:[ { "product_id": 1, "quantity": -1 } ]
[ { "product_id": 1, "quantity": 0 } ]
[ { "product_id": 1, "quantity": "string" } ]
- sua API deve responder com status http
422
e o seguintebody
:
{ "message": "\"quantity\" must be a number larger than or equal to 1" }
- sua API deve responder com status http
👉 Para o endpoint
POST /sales
, quando a requisição é feita corretamente, o produto deve ser cadastrado.
- Quando a requisição é feita e contém o seguinte
body
:[ { "product_id": 1, "quantity": 3 } ]
- sua API deve responder com status http
201
e o seguintebody
:
{ "id": 1, "itemsSold": [ { "product_id": 1, "quantity": 3 } ] }
- sua API deve responder com status http
👉 Para o endpoint
POST /sales
, quando a requisição é feita corretamente, a venda deve ser cadastrada.
- Quando a requisição é feita e contém o seguinte
body
:[ { "product_id": 1, "quantity": 2 }, { "product_id": 2, "quantity": 5 } ]
- sua API deve responder com status http
201
e o seguintebody
:
{ "id": 1, "itemsSold": [ { "product_id": 1, "quantity": 2 }, { "product_id": 2, "quantity": 5 } ] }
- sua API deve responder com status http
-
O endpoint deve ser acessível através do caminho (
/sales
) ou (/sales/:id
); -
Através do caminho
/sales
, todas as vendas devem ser retornadas; -
Através do caminho
/sales/:id
, apenas a venda com oid
presente na URL deve ser retornada;
O que será validado
👉 Para o endpoint
GET /sales
, será validado que todas vendas estão sendo retornados.
- sua API deve responder com status http
200
e o seguintebody
:
[
{
"saleId": 1,
"date": "2021-09-09T04:54:29.000Z",
"product_id": 1,
"quantity": 2
},
{
"saleId": 1,
"date": "2021-09-09T04:54:54.000Z",
"product_id": 2,
"quantity": 2
}
]
👉 Para o endpoint
GET /sales/:id
, será validado que é possível listar uma determinada venda.
- sua API deve responder com status http
200
e o seguintebody
:[ { "date": "2021-09-09T04:54:29.000Z", "product_id": 1, "quantity": 2 }, { "date": "2021-09-09T04:54:54.000Z", "product_id": 2, "quantity": 2 } ]
👉 Para o endpoint
GET /sales/:id
, será validado que não é possível listar uma venda que não existe.
- sua API deve responder com status http
404
e o seguintebody
:{ "message": "Sale not found" }
-
O endpoint deve ser acessível através do caminho (
/sales/:id
); -
quantity
deve ser um número inteiro maior que 0; -
Apenas a venda com o
id
presente na URL deve ser atualizada; -
O corpo da requisição deve receber a seguinte estrutura:
[
{
"product_id": "id_change",
"quantity": "new_quantity"
}
]
O que será validado
👉 Para o endpoint
PUT /sales/:id
, o campoproduct_id
deve ser um id de um produto anteriormente cadastrado.
- Quando a requisição é feita sem o atributo
product_id
:[ { "quantity": 10 } ]
- sua API deve responder com status http
400
e o seguintebody
:
{ "message": "\"product_id\" is required" }
- sua API deve responder com status http
👉 Para o endpoint
PUT /sales/:id
, o campoquantity
deve ser um número inteiro maior que 0.
- Quando a requisição é feita sem o atributo
quantity
:[ { "product_id": 1 } ]
- sua API deve responder com status http
400
e o seguintebody
:
{ "message": "\"quantity\" is required" }
- sua API deve responder com status http
- Quando a requisição é feita e contém os seguintes
body
:[ { "product_id": 1, "quantity": -1 } ]
[ { "product_id": 1, "quantity": 0 } ]
[ { "product_id": 1, "quantity": "string" } ]
- sua API deve responder com status http
422
e o seguintebody
:
{ "message": "\"quantity\" must be a number larger than or equal to 1" }
- sua API deve responder com status http
👉 Para o endpoint
PUT /sales/:id
, quando a requisição é feita corretamente, a venda deve ser alterada.
- Quando a requisição é feita e contém o seguinte
body
:[ { "product_id": 1, "quantity": 6 } ]
- sua API deve responder com status http
200
e o seguintebody
:
{ "saleId": 1, "itemUpdated": [ { "product_id": 1, "quantity": 6 } ] }
- sua API deve responder com status http
-
Seus arquivos de teste devem ficar no diretório
test/unit
, como citado aqui; -
Seus testes da
model
devem fazer mock do banco de dados obrigatóriamente; -
Opcionalmente você pode parar o serviço do
MYSQL
em sua máquina. Para rodar seus teste utilizenpm run test:mocha
;
O que será validado
👉 Será validado que a cobertura total das linhas dos arquivos nas pastas
models
,services
econtrollers
é maior ou igual a 35%. :point_right: Será validado que ao menos 24 linhas são cobertas pelos testes.
-
Seus arquivos de teste devem ficar no diretório
test/unit
, como citado aqui -
Seus testes da
model
devem fazer mock do banco de dados obrigatóriamente; -
Opcionalmente você pode parar o serviço do
MYSQL
em sua máquina. Para rodar seus teste utilizenpm run test:mocha
;
O que será validado
👉 Será validado que a cobertura total das linhas dos arquivos nas pastas
models
,services
econtrollers
é maior ou igual a 40%. :point_right: Será validado que ao menos 24 linhas são cobertas pelos testes.
-
O endpoint deve ser acessível através do caminho (
/sales/:id
); -
Apenas a venda com o
id
presente na URL deve ser deletado;
O que será validado
👉 Para o endpoint
DELETE /sales/:id
, será validado que é possível deletar uma venda com sucesso.
- sua API deve responder com status http
200
e o seguintebody
:
[
{
"date": "2021-09-09T04:54:29.000Z",
"product_id": 1,
"quantity": 2
},
{
"date": "2021-09-09T04:54:54.000Z",
"product_id": 2,
"quantity": 2
}
]
👉 Para o endpoint
DELETE /sales/:id
, será validado que não é possível deletar uma venda que não existe.
- sua API deve responder com status http
404
e o seguintebody
:
{ "message": "Sale not found" }
-
Ao realizar uma venda, atualizá-la ou deletá-la, você deve também atualizar a quantidade do produto em questão presente na tabela responsável pelos produtos;
- Exemplo 1: suponha que haja um produto chamado Bola de Futebol e a sua propriedade
quantity
tenha o valor 10. Caso seja feita uma venda com 8 unidades desse produto, a quantidade do produto deve ser atualizada para 2 , pois 10 - 8 = 2; - Exemplo 2: Suponha que esta venda tenha sido deletada, logo estas 8 unidades devem voltar ao
quantity
e seu valor voltará a 10, pois 2 + 8 = 10;
- Exemplo 1: suponha que haja um produto chamado Bola de Futebol e a sua propriedade
O que será validado
👉 Será validado que ao fazer uma determinada venda, a quantidade do produto deverá ser atualizada também na tabela responsável pelos produtos. :point_right: Será validado que ao deletar uma determinada venda, a quantidade do produto deverá ser atualizada também na tabela responsável pelos produtos;.
-
Um produto nunca deve ter a quantidade em estoque menor que 0;
-
Quando uma venda for realizada, garanta que a quantidade sendo vendida está disponível no estoque
O que será validado
👉 Para o endpoint
POST /sales
, será validado que a quantidade de produtos em estoque nunca seja menor que 0 (zero).
- Quando a requisição é feita com uma quantidade superior a quantidade em estoque:
[ { "product_id": 1, "quantity": 100 } ]
- sua API deve responder com status http
422
e o seguintebody
:
{ "message": "Such amount is not permitted to sell" }
- sua API deve responder com status http
-
Seus arquivos de teste devem ficar no diretório
test/unit
, como citado aqui; -
Seus testes da
model
devem fazer mock do banco de dados obrigatóriamente; -
Opcionalmente você pode parar o serviço do
MYSQL
em sua máquina. Para rodar seus teste utilizenpm run test:mocha
;
O que será validado
👉 Será validado que a cobertura total das linhas dos arquivos nas pastas
models
,services
econtrollers
é maior ou igual a 50%. :point_right: Será validado que ao menos 24 linhas são cobertas pelos testes.
-
Seus arquivos de teste devem ficar no diretório
test/unit
, como citado aqui; -
Seus testes da
model
devem fazer mock do banco de dados obrigatóriamente; -
Opcionalmente você pode parar o serviço do
MYSQL
em sua máquina. Para rodar seus teste utilizenpm run test:mocha
;
O que será validado
👉 Será validado que a cobertura total das linhas dos arquivos nas pastas
models
,services
econtrollers
é maior ou igual a 60%. :point_right: Será validado que ao menos 24 linhas são cobertas pelos testes.