Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
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.
- Host: GitHub
- URL: https://github.com/bastosmatheus/api-control-stock
- Owner: bastosmatheus
- Created: 2024-03-11T23:23:02.000Z (10 months ago)
- Default Branch: main
- Last Pushed: 2024-09-03T21:05:36.000Z (4 months ago)
- Last Synced: 2024-11-09T00:55:17.910Z (2 months ago)
- Topics: express, nodejs, prisma, vitest
- Language: TypeScript
- Homepage:
- Size: 266 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
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 APIMelhorias feitas 🧰
- Criação de lojas no sistema
- Autenticação com JWT
- Linkagem dos produtos com uma única lojaTecnologias 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
}
```