Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/bastosmatheus/api-control-stock

Esse projeto consiste em uma api para uma aplicação que tem como foco registrar as entradas e saídas de produtos e efetuar o controle de estoque.
https://github.com/bastosmatheus/api-control-stock

express nodejs prisma vitest

Last synced: 11 days ago
JSON representation

Esse projeto consiste em uma api para uma aplicação que tem como foco registrar as entradas e saídas de produtos e efetuar o controle de estoque.

Awesome Lists containing this project

README

        

# Api para controle de estoque/entrada e saída de produtos

Uma api que tem como objetivo automatizar uma tarefa super repetitiva, a saída e entrada dos produtos de uma loja. Além disso, fornece também o recurso de controle de estoque, que é calculado a partir do momento que uma entrada é registrada para tal produto.

A criação da API é feita com o Express, utilizando o ORM Prisma para efetuar as queries no PostgreSQL.

Todos os dados são validados com a biblioteca Zod, as senhas registradas são criptografadas com bcrypt, e além disso, o token JWT é utilizado para autenticação.

Nesse projeto foi implementado o padrão Either (estrutura de dados que representa dois tipos diferentes, Success e Failure), facilitando a manipulação e tratativa dos erros da aplicação.

Para finalizar, são feito alguns testes unitários com o Vitest.

Tópicos 📍

- Ajustes e melhorias
- Tecnologias utilizadas
- Como rodar esse projeto?
- Principais endpoints da API

Melhorias feitas 🧰

- Criação de lojas no sistema
- Autenticação com JWT
- Linkagem dos produtos com uma única loja

Tecnologias Utilizadas 🖥️

- [Node.js](https://nodejs.org/en)
- [Typescript](https://www.typescriptlang.org/)
- [PostgreSQL](https://www.postgresql.org/)
- [Express](https://www.expressjs.com/pt-br/)
- [Prisma](https://www.prisma.io/)
- [Zod](https://zod.dev/)
- [JWT](https://jwt.io/)
- [BCrypt](https://github.com/kelektiv/node.bcrypt.js#readme)
- [Vitest](https://vitest.dev/)

Como rodar esse projeto? 💿

Pre-requisitos

- [Node.js](https://nodejs.org/en)
- [PostgreSQL](https://www.postgresql.org/)
- [Git](https://git-scm.com/)
- [Github](https://github.com/)

Clonagem

```bash
# clone o repositório
$ git clone https://github.com/bastosmatheus/api-control-stock
```

Configuração do arquivo .env

```bash
# arquivo .env
DATABASE_URL="postgresql://username:password@localhost:5432/yourdatabase?schema=public"
```

Projeto

```bash
# depois de clonado, procure a pasta do projeto
$ cd api-control-stock

# instale todas as dependências
$ npm install

# execute o projeto
$ npm run start
```

Principais endpoints da API 🗺️

| ROUTE | DESCRIPTION |
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| RESPOSTAS DE SUCESSO | |
| POST /products | cria um produto, veja mais na [resposta da requisição](#post-products) |
| POST /entrances | cria uma entrada para determinado produto, veja [detalhes da requisição](#post-entrances) |
| POST /exits | informa uma saída de um produto, veja mais na [resposta da requisição](#post-exits) |
| POST /devolutions | registra detalhes da devolução de um produto, veja [detalhes da requisição](#post-devolutions) |
| POST /defectiveproducts | registra detalhes de um produto defeituoso, veja mais na [resposta da requisição](#post-defectiveproducts) |
| POST /stores | cria uma loja, veja [detalhes da requisição](#post-stores) |
| GET /products/:id | retorna todos os produtos registrado na API, veja [resposta da requisição](#get-products) |
| RESPOSTAS COM ERROS |
| GET /products/:idInexistente | erro ao passar um id inexistente para o get, veja mais na [resposta da requisição](#get-products-error) |
| POST /products | falha ao tentar registrar um produto que já existe no banco de dados, veja mais na [resposta da requisição](#post-products-error) |
| PUT /entrances/:id | erro ao passar um id de produto errado, veja mais na [resposta da requisição](#put-entrances-error) |
| PUT /exits/:id | falha ao passar um tipo errado da descrição, veja mais na [resposta da requisição](#put-exits-error-req) |
| POST /defectiveproducts | erro ao tentar registrar um produto defeituoso sem um campo obrigatório, veja mais na [resposta da requisição](#post-defectiveproducts-error-req) |

Respostas de sucesso

POST /products

Ao criar uma loja (store), o usuário recebe um token de autenticação JWT, que é necessário para fazer as requisições de criação, atualização e deleção de produtos (products).

**REQUISIÇÃO**

```json
{
"name_product": "Barra de cereal",
"price_product": 2.4,
"id_store": 1
}
```

**RESPOSTA**

```json
{
"message": "Produto criado com sucesso",
"type": "OK",
"statusCode": 200,
"productCreated": {
"id": 3,
"name_product": "Barra de cereal",
"price_product": 2.4,
"quantity_product_stock": 0,
"id_store": 1
}
}
```

POST /entrances

**REQUISIÇÃO**

```json
{
"supplier": "maTheus fornecedor",
"quantity_products": 200,
"price_total": 480,
"id_product": 3
}
```

**RESPOSTA**

```json
{
"message": "Entrada criada com sucesso",
"type": "OK",
"statusCode": 200,
"entranceCreated": {
"id": 17,
"supplier": "maTheus fornecedor",
"quantity_products": 200,
"price_total": 480,
"entrance_date": "2024-03-18T00:00:00.000Z",
"id_product": 3
}
}
```

POST /exits

**REQUISIÇÃO**

```json
{
"description": "Usuário comprou uma barra de cereal",
"quantity_products": 1,
"price_total": 2.4,
"id_product": 3
}
```

**RESPOSTA**

```json
{
"message": "Saída criada com sucesso",
"type": "OK",
"statusCode": 200,
"exitCreated": {
"id": 11,
"description": "Usuário comprou uma barra de cereal",
"quantity_products": 1,
"price_total": 2.4,
"exit_date": "2024-03-18T00:00:00.000Z",
"id_product": 3
}
}
```

POST /devolutions

**REQUISIÇÃO**

```json
{
"description": "Barra de cereal veio quebrada",
"quantity_products": 1,
"id_entrance": 17
}
```

**RESPOSTA**

```json
{
"message": "Devolução criada com sucesso",
"type": "OK",
"statusCode": 200,
"devolutionCreated": {
"id": 3,
"description": "Barra de cereal veio quebrada",
"quantity_products": 1,
"devolution_date": "2024-03-18T00:00:00.000Z",
"id_entrance": 17
}
}
```

POST /defectiveproducts

**REQUISIÇÃO**

```json
{
"description": "Barra de cereal com bixinhos dentro",
"quantity_products": 1,
"id_entrance": 17
}
```

**RESPOSTA**

```json
{
"message": "Produto com defeito criado com sucesso",
"type": "OK",
"statusCode": 200,
"defectiveProductCreated": {
"id": 5,
"description": "Barra de cereal com bixinhos dentro",
"quantity_products": 1,
"id_entrance": 17
}
}
```

POST /stores

**REQUISIÇÃO**

```json
{
"name_store": "mtCompany",
"email": "[email protected]",
"password": "102030"
}
```

**RESPOSTA**

```json
{
"message": "Loja criada com sucesso",
"type": "Created",
"statusCode": 201,
"storeCreated": {
"id": 5,
"name_store": "mtCompany",
"email": "[email protected]",
"password": "$2b$10$l/YKKyezrYU/18RjG7cxlOjl1HWaLH/neDz4.hFmJhQAYEBofcI/2",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lX3N0b3JlIjoibXRDb21wYW55IiwiaWQiOjUsImlhdCI6MTcxMzM5MDkwNCwiZXhwIjoxNzE1OTgyOTA0fQ.1K7qHrdMuJdlZ3xSpYbsN2ub9s-DCZ6wg-hMUVFX8l8"
}
}
```

GET /products/:id

**RESPOSTA**

```json
{
"type": "OK",
"statusCode": 200,
"product": {
"id": 3,
"name_product": "Barra de ceral",
"price_product": 2.4,
"quantity_product_stock": 280,
"id_store": 1,
"entrance": [
{
"id": 17,
"supplier": "maTheus fornecedor",
"quantity_products": 1,
"price_total": 2.4,
"entrance_date": "2024-03-18T00:00:00.000Z",
"id_product": 3,
"defective_product": [
{
"id": 5,
"description": "Barra de cereal com bixinhos dentro",
"quantity_products": 1,
"id_entrance": 17
}
],
"devolution": [
{
"id": 3,
"description": "Barra de cereal veio quebrada",
"quantity_products": 1,
"devolution_date": "2024-03-18T00:00:00.000Z",
"id_entrance": 17
}
]
}
],
"exit": [
{
"id": 11,
"description": "Usuário comprou uma barra de cereal",
"quantity_products": 1,
"price_total": 2.4,
"exit_date": "2024-03-18T00:00:00.000Z",
"id_product": 3
}
]
}
}
```

Respostas com erros

Além dessas respostas de sucesso, a API também conta com algumas respostas informando erros, tanto de requisições, quanto de regras de negócio, veja agora:

GET /products/:idInexistente

**RESPOSTA**

```json
{
"message": "Nenhum produto foi encontrado com o ID: {idInexistente}",
"type": "Not Found",
"statusCode": 404
}
```

POST /products

**REQUISIÇÃO**

```json
{
"name_product": "Barra de cereal",
"price_product": 2.4,
"id_store": 1
}
```

**RESPOSTA**

```json
{
"message": "Já existe um produto com esse nome: Barra de cereal",
"type": "Conflict",
"statusCode": 409
}
```

PUT /entrances/:id

**REQUISIÇÃO**

```json
{
"supplier": "maTheus fornecedor",
"quantity_products": 1,
"price_total": 2.4,
"id_product": {id_productInexistente}
}
```

**RESPOSTA**

```json
{
"message": "Nenhum produto foi encontrado com o ID: {id_productInexistente}",
"type": "Not Found",
"statusCode": 404
}
```

PUT /exits/:id

**REQUISIÇÃO**

```json
{
"description": null,
"quantity_products": 1,
"price_total": 2.4,
"id_product": 3
}
```

**RESPOSTA**

```json
{
"message": "A descrição da saída do(s) produto(s) deve ser uma string",
"type": "Unprocessable Entity",
"statusCode": 422
}
```

POST /defectiveproducts

**REQUISIÇÃO**

```json
{
"quantity_products": 1,
"id_entrance": 17
}
```

**RESPOSTA**

```json
{
"message": "Informe o defeito desse produto",
"type": "Unprocessable Entity",
"statusCode": 422
}
```