API Controle de Estoque

API para controle de estoque de um restaurante delivery.

📜 Sumário

  1. Detalhes do projeto
  2. Tecnologias usadas
  3. Para rodar o projeto
  4. Documentação
  5. Autor

1. 🔍 Detalhes do projeto

A API Controle de Estoque tem como objetivo persistir dados para gerenciamento do estoque de um restaurante. Foi realizado profissionalmente e transcrito neste repositório apenas como demonstração para fins acadêmicos. A troca de dados é realizada em formato JSON e utiliza-se o MySQL como banco de dados.

Cenário:

  • Sistema permite o carregamento de um arquivo .csv para fazer um primeiro cadastro de produtos em massa;
  • Sistema valida as informações e retorna se há algo errado com os registros. O front-end apenas permite a persistência dos dados se todas as validações tiverem sucesso;
  • Com o banco de dados preenchido, o front-end não permite mais o carregamento de aquivo .csv e a atualização, criação e deleção é feita de forma unitária;
  • Sistema não permite cadastro quantidade negativa ou em valor superior ao estoque máximo;
  • Sistema lista quais produtos se encontram em criticidade (inferior a 15% do estoque máximo);

2. 💻 Tecnologias usadas

Languages, Frameworks & Librarys:
JavaScript TypeScript Node Express JSON JWT

Tests:
Insomnia Jest

Database:
MySQL

IDE:
VSCode

3. 🔌 Para rodar o projeto

  1. Instale as dependências necessárias para rodar a API (relacionadas no package.json):

    npm install
    
  2. A API utiliza o MySQL como banco de dados, então se faz necessário que você tenha-o instalado em sua máquina.

  3. Com ele instalado, crie um database e preencha o arquivo ".env.example" com o host, user_db, password_db e database_name. Em seguida, retire o ".example", deixando apenas ".env" como nome do arquivo.

  4. Também é necessário preencher a porta a ser utilizada e o secret da criptografia da senha dos usuários no arquivo ".env".

  5. Rode a aplicação em ambiente de desenvolvimento:

    npm run dev
    
  6. O comando já irá rodar as migrations e criar as tabelas, deixando-as prontas para uso.

  7. Você precisará de uma ferramenta de teste de requisições como o Insomnia, devendo seguir as orientações da documentação abaixo para utilizar a API.

  8. Para rodar os testes automatizados já criados:

    npm run test
    

4. 🔌 Documentação

Endpoints

Sessions
POST /sessions/ - Autenticação de usuário (login)

Users
POST /users/ - Criação de um novo usuário

File
GET /file/ - Armazenamento de arquivo ".csv" na pasta do projeto e valida os registros encontrados POST /file/ - Persiste os registros no banco de dados

Products
POST /products/ Persiste um produto no banco de dados
GET /products/ Busca de todos produtos
GET /products/:id Busca de produto específico
PUT /products/:id Atualização de dados de um produto
PATCH /products/:id/acrescentar Acréscimo da quantidade do produto no estoque
PATCH /products/:id/decrementar Diminuição da quantidade do produto no estoque
DELETE /products/:id - Deleção de um produto

POST sessions

Request

Nome Obrigatório Tipo Descrição
email sim string E-mail do usuário
password sim string Senha do usuário

NOTA: Não é necessário enviar Token JWT via Authorization Header.


Response

Sucesso

{
  "user": [
    {
      "user_id": 1, //número incremental
      "name": "Testador",
      "email": "teste@email.com",
      "password": "senha", //criptografada
      "created_at": "xxxx-xx-xxTyy:yy:yy" //data e hora criados automaticamente
    }
  ],
  "token": "abcdefghijklmnopqrstuvwxyz"
}

status: 200

Erro comum

{
    "mensagem": "E-mail e/ou senha incorreta.",
}

status: 401

POST users

Request

Nome Obrigatório Tipo Descrição
name sim string Nome para perfil
email sim string E-mail do usuário ou admin
password sim string Senha do usuário ou admin

NOTA: Não é necessário enviar Token JWT via Authorization Header.


Response

Sucesso

{
	"user_id": 1,
  "name": "Testador",
  "email": "teste@email.com",
  "password": "senha", //criptografada
  "created_at": "xxxx-xx-xxTyy:yy:yy" //data e hora criados automaticamente
}

status: 201

Erro comum

{
    "mensagem": "Este email já está em uso.",
}

status: 400

GET file

Request

Arquivo .csv com quatro atributos. Exemplo:

sku nome estoque_max quantidade
SKU0001 Queijo Prato Kg 30 5
SKU0002 Tomate Kg 20 10
SKU0003 Coca-cola Lata Un 200 50

Response

Sucesso e registros válidos

[
  {
		"sku": "SKU0001",
		"nome": "Queijo Prato Kg",
		"validacao": "ok"
	},
	{
		"sku": "SKU0002",
		"name": "Tomate Kg",
		"validacao": "ok"
	},
	{
		"sku": "SKU0003",
		"name": "Coca-cola Lata Un",
		"validacao": "ok"
	}
]

status: 200

Sucesso e registros inválidos

[
  {
		"sku": "SKU0001",
		"nome": "Queijo Prato Kg",
		"validacao": "ok"
	},
	{
		"sku": "SKU0002",
		"name": "Tomate Kg",
		"validacao": "Quantidade (inserida ou total) não pode ser negativa"
	},
	{
		"sku": "SKU0003",
		"name": "Coca-cola Lata Un",
		"validacao": "Quantidade supera o estoque máximo"
	}
]

status: 200

Erros comuns

{
    "mensagem": "Falha ao receber o arquivo. Verifique se o arquivo é um .csv",
}

status: 400

{
    "mensagem": "Arquivo .csv não possui nenhum registro.",
}

status: 400

POST file

Request

Arquivo .csv já está armazenado na pasta do projeto em razão da requisição anterior e a requisição apenas é disparada pelo front-end caso todas as validações retornem "ok".

Não é necessário enviar informações na requisição


Response

Sucesso

[
  {
		"id": 1,
		"sku": "SKU0001",
		"name": "Queijo Prato Kg",
		"quantidade": 30,
		"estoque_max": 5
	},
	{
		"id": 2,
		"sku": "SKU0002",
		"name": "Tomate Kg",
		"quantidade": 20,
		"estoque_max": 10
	},
	{
		"id": 3,
		"sku": "SKU0003",
		"name": "Coca-cola Lata Un",
		"quantidade": 200,
		"estoque_max": 50
	}
]

status: 201


GET products

Request

Buscar todos produtos

Nome Obrigatório Tipo Descrição
- - - Não é necessário enviar nenhum parâmetro

NOTA: É necessário enviar Token JWT via Authorization Header.


Response

Sucesso

{
    "listaProdutos": [
      {
        "id": 1,
        "sku": "SKU0001",
        "name": "Queijo Prato Kg",
        "quantidade": 30,
        "estoque_max": 5
      },
      {
        "id": 2,
        "sku": "SKU0002",
        "name": "Tomate Kg",
        "quantidade": 20,
        "estoque_max": 10
      },
      {
        "id": 3,
        "sku": "SKU0003",
        "name": "Coca-cola Lata Un",
        "quantidade": 200,
        "estoque_max": 50
      }
    ],
    "listaEstoqueCritico": [
      "SKU0001"
    ]
}

status: 200



Sucesso sem retorno de dados

{
  :[]
}

status: 200

GET products/:id

Request

Buscar produto específico

Nome Obrigatório Tipo Descrição
id sim number Enviar via parâmetro de rota

NOTA: É necessário enviar Token JWT via Authorization Header.


Response

Sucesso

{
  "id": 2,
  "sku": "SKU0002",
  "name": "Tomate Kg",
  "quantidade": 20,
  "estoque_max": 10
}

status: 200



Erro comum

{
    "mensagem": "Arquivo .csv não possui nenhum registro.",
}

status: 400


POST products

Request

Nome Obrigatório Tipo Descrição
sku sim string Código de identificação do produto
nome sim string Nome do produto
quantidade sim number Quantidade do produto
estoque_max sim number Estoque máximo para produto

NOTA: É necessário enviar Token JWT de Admin via Authorization Header.


Response

Sucesso

{
	"id": 1,
	"sku": "SKU0001",
	"name": "Queijo Prato Kg",
	"quantidade": 20,
	"estoque_max": 50
}

status: 201

Erros comuns

{
    "mensagem": "SKU já cadastrado.",
}

status: 400

{
    "mensagem": "Quantidade (inserida ou total) não pode ser negativa.",
}

status: 400

{
    "mensagem": "Quantidade supera o estoque máximo.",
}

status: 400

PUT products

Request

SKU não pode ser modificado. Qualquer outra informação pode ser modificada, mas não é obrigatória.

Nome Obrigatório Tipo Descrição
id sim number ID do produto que será atualizado (recebido por parâmetro)
nome não string Nome do produto
quantidade não number Quantidade do produto
estoque_max não number Estoque máximo para produto

NOTA: É necessário enviar Token JWT de Admin via Authorization Header.


Response

Sucesso

{
	"id": 1,
	"sku": "SKU0001",
	"name": "Queijo Prato Kg",
	"quantidade": 30,
	"estoque_max": 50
}

status: 200

Erros comuns

{
    "mensagem": "Produto não existe.",
}

status: 400

{
    "mensagem": "Quantidade (inserida ou total) não pode ser negativa.",
}

status: 400

{
    "mensagem": "Quantidade supera o estoque máximo.",
}

status: 400

PATCH products/:id/acrescentar

Request

Nome Obrigatório Tipo Descrição
id sim number ID do produto que terá a quantidade aumentada (recebido por parâmetro)
quantidade sim number Quantidade a ser acrescentada (não é a nova quantidade e sim o valor a ser somado)

NOTA: É necessário enviar Token JWT de Admin via Authorization Header.


Response

Sucesso

{
	"id": 1,
	"sku": "SKU0001",
	"name": "Queijo Prato Kg",
	"quantidade": 35,
	"estoque_max": 50
}

status: 200

Erros comuns

{
    "mensagem": "Produto não existe.",
}

status: 400

{
    "mensagem": "Quantidade (inserida ou total) não pode ser negativa.",
}

status: 400

{
    "mensagem": "Quantidade supera o estoque máximo.",
}

status: 400

PATCH products/:id/decrementar

Request

Nome Obrigatório Tipo Descrição
id sim number ID do produto que terá a quantidade diminuida (recebido por parâmetro)
quantidade sim number Quantidade a ser reduzida (não é a nova quantidade e sim o valor a ser subtraído)

NOTA: É necessário enviar Token JWT de Admin via Authorization Header.


Response

Sucesso

{
	"id": 1,
	"sku": "SKU0001",
	"name": "Queijo Prato Kg",
	"quantidade": 25,
	"estoque_max": 50
}

status: 200

Erros comuns

{
    "mensagem": "Produto não existe.",
}

status: 400

{
    "mensagem": "Quantidade (inserida ou total) não pode ser negativa.",
}

status: 400

{
    "mensagem": "Quantidade supera o estoque máximo.",
}

status: 400

DELETE products/:id

Request

Nome Obrigatório Tipo Descrição
id sim number ID do produto que será deletado (recebido por parâmetro)

NOTA: É necessário enviar Token JWT de Admin via Authorization Header.


Response

Sucesso
no body returned for response status: 204

Erro comum

{
    "mensagem": "Produto não existe.",
}

status: 400

5. 👨‍💻 Autor

Criado por Daniel Justo

linkedin github

Obrigado pela visita!