/PDV-Cubos

Primary LanguageJavaScript

API PDV-Cubos

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).

📜 Sumário

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

1. 🔍 Detalhes do projeto

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.

Cenário:

  • 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;

2. ✅ Deploy

A API está rodando no servidor da Cyclic: Link do deploy.

Para utilizá-la, basta seguir a documentação presente neste conteúdo.

3. 🔌 Para rodar o projeto em ambiente de desenvolvimento

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

    npm install
    
  2. 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.

  3. 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.

  4. Rode a aplicação que o sistema já irá criar as tabelas automaticamente no banco de dados, deixando-as prontas para uso.

  5. 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.

  6. Você pode rodar os testes automatizados criados com Jest:

    npm run test
    

4. 📖 Documentação

Endpoints

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
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.

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
email 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
email 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
email 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
email 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

5. 💻 Tecnologias usadas

Languages, Frameworks & Librarys:
JavaScript Node Express JSON JWT NPM ESLint Prettier Nodemon Git

Organization:
Trello GitHub

Tests:
Insomnia Jest

Database:
PostgreSQL

IDE:
VSCode

6. 👨‍💻 Autor

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!