API desenvolvida como desafio final do curso de desenvolvimento de software back-end da Cubos Academy. Trata-se de um sistema PDV (Ponto de Venda).
A API PDV_Cubos tem como objetivo controlar as vendas de um comércio fictício. Foi realizado academicamente durante curso de desenvolvimento de software back-end da Cubos Academy.
- O sistema permite o cadastro de usuário, com validação de informações;
- O sistema permite apenas as requisições de cadastro de usuário, login e listagem de categorias sem autenticação por meio de JWT;
- Com o usuário logado, o sistema permite a edição e detalhmento das informações do usuário, criação, edição, detalhamento e listagem de clientes, criação, edição, detalhamento, deleção e listagem de produtos, criação e listagem de pedidos;
- O sistema permite a inclusão de imagens de produtos, que são armazenados em um serviço de armazenamento na nuvem;
- O sistema decrementa automaticamente quantidade de itens no estoque de acordo com o pedido realizado;
- O sistema encaminha e-mail ao cliente em casa de pedido efetuado com sucesso;
A API está rodando no servidor da Cyclic: Link do deploy.
Para utilizá-la, basta seguir a documentação presente neste conteúdo.
-
Instale as dependências necessárias para rodar a API (relacionadas no package.json):
npm install
-
A API utiliza o PostgreSQL como banco de dados rodando em um servidor do ElephantSQL. A API também faz uso de um bucket no BackBlaze para armazenamento de imagens, bem como de um serviço do Brevo para servidor SMTP.
-
Dessa forma, se faz necessário criar os respectivos serviços para API consumir e preencher o arquivo
.env
utilizando o.env.example
de exemplo para os nomes das variáveis de ambiente. -
Rode a aplicação que o sistema já irá criar as tabelas automaticamente no banco de dados, deixando-as prontas para uso.
-
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.
-
Você pode rodar os testes automatizados criados com Jest:
npm run test
Login - Autenticação de usuário
POST login
Logar com um usuário por meio de email
e password
. Retorna um token JWT para ser utilizado nas requisições.
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
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.
Exemplo de requisição:
{
"email": "fulano@email.com",
"senha": "password"
}
Response
Sucesso
{
"type": "Bearer",
"token": "abcdefghijklmno.abcdefghijklmnopqrstuvwxyz.abcdefghijklmnop"
}
status: 200
Erro comum
{
"message": "Invalid email and/or password."
}
status: 401
Usuário - Criação de um novo usuário, edição de um usuário e detalhamento do usuário
POST usuario
Criar um usuário para poder utilizar a API e jogar D&D.
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
nome | sim | string |
Nome do usuário |
sim | string |
Email do usuário | |
senha | sim | string |
Senha do usuário |
NOTA: Não é necessário enviar Token JWT via Authorization Header.
Exemplo de requisição:
{
"nome": "Fulano",
"email": "fulano@email.com",
"senha": "password"
}
Response
Sucesso
{
"id": 1,
"name": "Fulano",
"email": "fulano@email.com"
}
status: 201
Erros comuns
{
"message": "Email already exists."
}
status: 400
{
"message": "The password must at least 6 characters"
}
status: 400
PUT usuario
Editar um usuário. Apenas nome e e-mail podem ser editados (ou apenas um dos dois).
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
nome | sim | string |
Nome do usuário |
sim | string |
Email do usuário | |
senha | sim | string |
Senha do usuário |
NOTA: É necessário enviar Token JWT via Authorization Header.
Exemplo de requisição:
{
"name": "Fulano Editado",
"email": "fulano.editado@email.com",
"password": "password"
}
Response
Sucesso
no body returned for response
status: 204
Erros comuns
{
"message": "Email already in use"
}
status: 400
GET usuario
Detalhar um usuário. O id
é enviado automaticamente com o token.
Request
Não é necessário enviar dados na requisição
NOTA: É necessário enviar Token JWT via Authorization Header.
Response
Sucesso
{
"id": 1,
"name": "Fulano",
"email": "fulano@email.com"
}
status: 200
Erros comuns
{
"message": "User not found."
}
status: 404
Categoria - Listagem de categorias dos produtos
GET categoria
Listar categorias.
Request
Não é necessário enviar dados na requisição
NOTA: Não é necessário enviar Token JWT via Authorization Header.
Response
Sucesso
[
{
"id": 1,
"descricao": "Informática"
},
{
"id": 2,
"descricao": "Celulares"
},
{
"id": 3,
"descricao": "Beleza e Perfumaria"
}
]
status: 200
Sucesso sem retorno
[]
status: 200
Cliente - Criação de um novo cliente, edição de um cliente, listagem de clientes e detalhamento de um cliente
POST cliente
Criar um cliente.
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
nome | sim | string |
Nome do usuário |
sim | string |
Email do usuário | |
cpf | sim | string |
CPF do usuário |
cep | não | string |
CEP do endereço do usuário |
rua | não | string |
Rua do endereço do usuário |
numero | não | string |
Número do endereço do usuário |
bairro | não | string |
Bairro do endereço do usuário |
cidade | não | string |
Cidade do endereço do usuário |
estado | não | string |
Estado do endereço do usuário |
NOTA: É necessário enviar Token JWT via Authorization Header.
Exemplo de requisição:
{
"nome": "Ciclano",
"email": "ciclano@gmail.com",
"cpf": "12345678911",
"cep": "12345678",
"rua": "Rua 1",
"numero": "11-A",
"bairro": "Bairro 1",
"cidade": "Cidade 1",
"estado": "Estado 1"
}
Response
Sucesso
{
"id": 3,
"nome": "Ciclano",
"email": "ciclano@gmail.com",
"cpf": "12345678911",
"cep": "12345678",
"rua": "Rua 1",
"numero": "11-A",
"bairro": "Bairro 1",
"cidade": "Cidade 1",
"estado": "Estado 1"
}
status: 201
Erros comuns
{
"message": "Client already exists."
}
status: 400
GET cliente
Listar clientes.
Request
Não é necessário enviar dados na requisição
NOTA: É necessário enviar Token JWT via Authorization Header.
Response
Sucesso
[
{
"id": 1,
"nome": "Beltrano",
"email": "beltrano@email.com",
"cpf": "12345678910",
"cep": null,
"rua": null,
"numero": null,
"bairro": null,
"cidade": null,
"estado": null
},
{
"id": 2,
"nome": "Ciclano",
"email": "ciclano@gmail.com",
"cpf": "12345678911",
"cep": "12345678",
"rua": "Rua 1",
"numero": "11-A",
"bairro": "Bairro 1",
"cidade": "Cidade 1",
"estado": "Estado 1"
}
]
status: 200
Sucesso sem retorno
[]
status: 200
GET cliente-id
Detalhar um personagem. O id
deve ser enviado na url.
Request
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,
"nome": "Ciclano",
"email": "ciclano@gmail.com",
"cpf": "12345678911",
"cep": "12345678",
"rua": "Rua 1",
"numero": "11-A",
"bairro": "Bairro 1",
"cidade": "Cidade 1",
"estado": "Estado 1"
}
status: 200
Erros comuns
{
"message": "Client not found."
}
status: 404
PUT cliente-id
Alterar os dados do cliente. O id
deve ser enviado na url.
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
id | sim | number |
Enviar via parâmetro de rota |
nome | sim | string |
Nome do usuário |
sim | string |
Email do usuário | |
cpf | sim | string |
CPF do usuário |
cep | não | string |
CEP do endereço do usuário |
rua | não | string |
Rua do endereço do usuário |
numero | não | string |
Número do endereço do usuário |
bairro | não | string |
Bairro do endereço do usuário |
cidade | não | string |
Cidade do endereço do usuário |
estado | não | string |
Estado do endereço do usuário |
NOTA: É necessário enviar Token JWT via Authorization Header.
Exemplo de requisição:
{
"nome": "Ciclano Editado",
"email": "ciclano.editado@gmail.com",
"cpf": "12345678911",
"cep": "12345678",
"rua": "Rua 1",
"numero": "11-A",
"bairro": "Bairro 1",
"cidade": "Cidade 1",
"estado": "Estado 1"
}
Response
Sucesso
no body returned for response
status: 204
Erros comuns
{
"message": "Client not found."
}
status: 404
{
"message": "Email already exists."
}
status: 400
{
"message": "CPF already exists."
}
status: 400
Produto - Criação de um novo produto, edição de um produto, listagem de produtos, deleção de um produto e detalhamento de um produto
POST produto
Criar um produto.
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
descricao | sim | string |
Descrição do produto |
quantidade_estoque | sim | number |
Quantidade de itens no estoque |
valor | sim | number |
Valor do produto (em centavos) |
categoria_id | sim | number |
Id da categoria do produto |
produto_imagem | não | file |
Arquivo de imagem do produto |
NOTA: É necessário enviar Token JWT via Authorization Header.
Response
Sucesso
{
"id": 1,
"descricao": "Teclado",
"quantidade_estoque": 50,
"valor": 10000,
"categoria_id": 1,
"produto_imagem": "url_da_imagem"
}
status: 201
Erros comuns
{
"message": "Category not found."
}
status: 404
{
"message": "Description already exists."
}
status: 400
GET produto
Listar produtos. Pode ser passado um parâmetro query categoria_id
para listar apenas os produtos de uma categoria específica.
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
categoria_id | não | number |
Enviar via parâmetro de query na rota |
NOTA: É necessário enviar Token JWT via Authorization Header.
Exemplo de requisição:
url/produto?categoria_id=1
Response
Sucesso
[
{
"id": 1,
"descricao": "Teclado X",
"quantidade_estoque": 25,
"valor": 10000,
"categoria_id": 1,
"produto_imagem": "url/Teclado_X/teclado_x.png"
},
{
"id": 2,
"descricao": "Teclado Y",
"quantidade_estoque": 48,
"valor": 20000,
"categoria_id": 1,
"produto_imagem": "url/Teclado_Y/teclado_y.png"
}
]
status: 200
Sucesso sem retorno
[]
status: 200
GET produto-id
Detalhar um produto. O id
deve ser enviado na url.
Request
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": 1,
"descricao": "Teclado X",
"quantidade_estoque": 25,
"valor": 10000,
"categoria_id": 1
}
status: 200
Erros comuns
{
"message": "Product not found."
}
status: 404
PUT produto-id
Alterar os dados do produto. O id
deve ser enviado na url.
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
id | sim | number |
Enviar via parâmetro de rota |
descricao | sim | string |
Descrição do produto |
quantidade_estoque | sim | number |
Quantidade de itens no estoque |
valor | sim | number |
Valor do produto (em centavos) |
categoria_id | sim | number |
Id da categoria do produto |
produto_imagem | não | file |
Arquivo de imagem do produto |
NOTA: É necessário enviar Token JWT via Authorization Header.
Response
Sucesso
no body returned for response
status: 204
Erros comuns
{
"message": "Product not found."
}
status: 404
{
"message": "Category not found."
}
status: 404
{
"message": "Description already exists."
}
status: 400
DELETE produto-id
Deletar um produto. O id
deve ser enviado na url.
Request
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
no body returned for response
status: 204
Erros comuns
{
"message": "Product not found."
}
status: 404
{
"message": "This product is linked to an order."
}
status: 400
Pedido - Criação de um novo pedido e listagem de pedidos
POST pedido
Criar um pedido.
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
cliente_id | sim | number |
Id do cliente |
observacao | não | string |
Observação para o pedido |
pedido_produtos | sim | array |
Array com produtos relacionados ao pedido |
produto_id | sim | number |
Id do produto |
quantidade_produto | sim | number |
Quantidade de itens do produto |
NOTA: É necessário enviar Token JWT via Authorization Header.
Exemplo de requisição:
{
"cliente_id": 1,
"observacao": "Em caso de ausência recomendo deixar com algum vizinho",
"pedido_produtos": [
{
"produto_id": 1,
"quantidade_produto": 10
},
{
"produto_id": 2,
"quantidade_produto": 20
}
]
}
Response
Sucesso
{
"pedido": {
"id": 1,
"cliente_id": 1,
"observacao": "Em caso de ausência recomendo deixar com algum vizinho",
"valor_total": 100000
},
"pedido_produtos": [
{
"id": 1,
"pedido_id": 1,
"produto_id": 1,
"quantidade_produto": 10,
"valor_produto": 5000
},
{
"id": 2,
"pedido_id": 1,
"produto_id": 2,
"quantidade_produto": 20,
"valor_produto": 2500
}
]
}
status: 201
Erros comuns
{
"message": "Client not found."
}
status: 404
{
"message": "Product not found."
}
status: 404
{
"message": "Insufficient stock."
}
status: 400
GET pedido
Listar pedidos. Pode ser passado um parâmetro query cliente_id
para listar apenas os pedidos de um cliente específico.
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
cliente_id | não | number |
Enviar via parâmetro de query na rota |
NOTA: É necessário enviar Token JWT via Authorization Header.
Exemplo de requisição:
url/pedido?cliente_id=1
Response
Sucesso
[
{
"pedido": {
"id": 1,
"cliente_id": 1,
"observacao": "Em caso de ausência recomendo deixar com algum vizinho",
"valor_total": 100000
},
"pedido_produtos": [
{
"id": 1,
"pedido_id": 1,
"produto_id": 1,
"quantidade_produto": 10,
"valor_produto": 5000
},
{
"id": 2,
"pedido_id": 1,
"produto_id": 2,
"quantidade_produto": 20,
"valor_produto": 2500
}
]
},
{
"pedido": {
"id": 2,
"cliente_id": 1,
"observacao": "Em caso de ausência recomendo deixar com algum vizinho",
"valor_total": 10000
},
"pedido_produtos": [
{
"id": 3,
"pedido_id": 2,
"produto_id": 1,
"quantidade_produto": 1,
"valor_produto": 5000
},
{
"id": 4,
"pedido_id": 2,
"produto_id": 2,
"quantidade_produto": 2,
"valor_produto": 2500
}
]
}
]
status: 200
Sucesso sem retorno
[]
status: 200
Languages, Frameworks & Librarys:
Criado por Daniel M. Justo, Matheus O. da Silva, Ney H. M. Ribeiro, Raimundo F. da Silva Neto, Ricardo J. S. Barbosa.
Obrigado pela visita!