Essa é uma implementação de uma API RESTful, com uso de Node.js, Express.js do banco de dados MySQL. É um sistema de gerenciamento de uma loja, que possibilita o usuário a criar, visualizar, deletar e atualizar produtos e vendas. A aplicação foi construída com a arquitetura MSC (model-service-controller) e foi Dockerizada. Tudo isso com validações e testes pensados para os casos de uso da aplicação, garantindo a qualidade e integridade do código.
O foco dessa projeto foi praticar a construção de um sistema CRUD completo, assim como explorar a arquitetura MSC para construção de uma API robusta, escalável e de fácil manutenção.
Para rodar esta aplicação é necessário ter o Docker e o Docker Compose (v1.29 ou superior) instalados em sua máquina.
- Clone o repositório e entre no diretório
git clone git@github.com:lzaghi/crud-basics.git
cd crud-basics- Instale as dependências
npm install- Suba os containeres do Node e do MySQL
docker-compose up -d --build- Rode o comando para abrir o terminal do container Node
docker exec -it store_manager bash- Rode o comandos para criar e popular as tabelas
npm run migration
npm run seedEssa etapa também pode ser feita diretamente a partir de um cliente MySQL de sua preferência, como o MySQL Workbench.
Conecte-se na porta 3006 com as credenciais de user root e senha password, e execute os scripts que estão nos arquivos migration.sql e seed.sql.
- Inicie a aplicação
npm startA aplicação estará rodando em http://localhost:3000
Para rodar os testes
npm run test:mochaA documentação completa da API pode ser consultada na rota http://localhost:3000/swagger, após a aplicação estar rodando.

Segue um resumo do que é documentado na rota citada acima:
Especificações das requisições
Cadastrar produto
POST /productsExemplo de Entrada:
{
"name": "ProdutoX"
}Exemplo de retorno:
Em caso de sucesso - status 201:
{
"id": "4",
"name": "ProdutoX"
}Em caso de erro - status 400:
{
"message": "'name' is required"
}Ou status 422:
{
"message": "'name' length must be at least 5 characters long"
}Consultar produtos
GET /productsExemplo de retorno:
Status 200:
[
{
"id": 1,
"name": "Martelo de Thor"
},
{
"id": 2,
"name": "Traje de encolhimento"
},
{
"id": 3,
"name": "Escudo do Capitão América"
}
]Consultar produto por nome
GET /products/searchExemplo de Pesquisa:
URL http://localhost:3000/products/search?q=marteloExemplo de retorno:
Sucesso - status 200:
[
{
"id": 1,
"name": "Martelo de Thor"
}
]Consultar produto por id
GET /products/{id}Exemplo de Pesquisa:
URL http://localhost:3000/products/3Exemplo de retorno:
Em caso de sucesso - status 200:
{
"id": 3,
"name": "Escudo do Capitão América"
}Em caso de erro - status 404:
{
"message": "Product not found"
}Atualizar produto
PUT /products/{id}Exemplo de Entrada:
URL http://localhost:3000/products/3{
"name": "ProdutoX"
}Exemplo de retorno:
Em caso de sucesso - status 200:
{
"id": 3,
"name": "ProdutoX"
}Em caso de erro - status 400:
{
"message": "'name' is required"
}Ou status 404:
{
"message": "Product not found"
}Ou status 422:
{
"message": "'name' length must be at least 5 characters long"
}Deletar produto
DELETE /products/{id}Exemplo de retorno:
Em caso de sucesso - status 204:
no contentEm caso de erro - status 404:
{
"message": "Product not found"
}Cadastrar venda
POST /salesExemplo de Entrada:
[
{
"productId": 2,
"quantity": 5
}
]Exemplo de retorno:
Em caso de sucesso - status 201:
{
"id": 3,
"itemsSold": [
{
"productId": 2,
"quantity": 5
}
]
}Em caso de erro - status 400:
{
"message": "'productId'/'quantity' are required"
}Ou status 404:
{
"message": "Product not found"
}Ou status 422:
{
"message": "'quantity' must be greater than or equal to 1"
}Consultar vendas
GET /salesExemplo de retorno:
Status 200:
[
{
"saleId": 1,
"date": "2023-08-15T20:30:31.000Z",
"productId": 1,
"quantity": 5
},
{
"saleId": 1,
"date": "2023-08-15T20:30:31.000Z",
"productId": 2,
"quantity": 10
},
{
"saleId": 2,
"date": "2023-08-15T20:30:31.000Z",
"productId": 3,
"quantity": 15
}
]Consultar venda por id
GET /sales/{id}Exemplo de Pesquisa:
URL http://localhost:3000/sales/2Exemplo de retorno:
Em caso de sucesso - status 200:
[
{
"date": "2023-08-15T20:30:31.000Z",
"productId": 3,
"quantity": 15
}
]Em caso de erro - status 404:
{
"message": "Sale not found"
}Atualizar venda
PUT /sales/{id}Exemplo de Entrada:
URL http://localhost:3000/sales/2[
{
"productId": 2,
"quantity": 50
}
]Exemplo de retorno:
Em caso de sucesso - status 200:
{
"saleId": 2,
"itemsUpdated": [
{
"productId": 2,
"quantity": 50
}
]
}Em caso de erro - status 400:
{
"message": "'productId'/'quantity' are required"
}Ou status 404:
{
"message": "Product not found"
}Ou status 422:
{
"message": "'quantity' must be greater than or equal to 1"
}Deletar venda
DELETE /sales/{id}Exemplo de retorno:
Em caso de sucesso - status 204:
no contentEm caso de erro - status 404:
{
"message": "Sale not found"
}Node.js, Express.js, MySQL, Docker, Joi, Mocha, Chai, Sinon, Arquitetura MSC, API RESTful
Análise SonarCloud
