---
# System prepended metadata

title: Desafio M5 - Projeto de aplica

---

*Desafio M5 - Projeto de aplicativo de cobranças*

**O que o usuário pode fazer ?**

- Cadastrar-se
- Logar-se
- Recuperar senha
- Ver cobranças pagas (Dados estáticos)
- Ver cobranças vencidas (Dados estáticos)
- Ver cobranças previstas (Dados estáticos)
- Ver clientes inadimplentes (Dados estáticos)
- Ver clientes em dia (Dados estáticos)
- Editar cadastro
- Listar clientes
- Adicionar clientes
- Adicionar cobranças para os clientes

**O que o usuário não pode fazer ? (Nessa sprint)**

- Cadastrar cobrança
- Editar cobrança
- Ver todas as cobranças
- Ver todos clientes em dia
- Ver todos clientes inadimplentes

<h1>Sprint 1</h1>

***Endpoints***

**Cadastro - POST**

***URL:*** /cadastro
***Método:*** POST

***Dados de entrada***
```
{"name":"Jose Silva",
"email":"josesilva@email.com"
"password":"hashSenha"}
```

***Dados de saída***
*Sucesso*
```
{"Usuário cadastrado com sucesso"}
```
*Falha*
```
{"message":"email já cadastrado"}
```

*Validações / Regras de negócio*
- Verficar se existe algum campo não informado
- Verificar se o email informado não é igual ao de outro cliente.
- Verificar se as senhas coincidem
- Usar criptografia para envio da senha(hash)


**Login - POST**

***URL:*** /login
***Método:*** POST

*Dados de entrada*
```
{
  "email": "josesilva@email.com",
  "password": "hashSenha"
}

```

*Dados de saída*
*Sucesso*
```
{
  "user_id": "1",
  "name":"Jose Silva",
  "email":"josesilva@email.com",
  "token":"c0ce7f40-e12b-393e-bb7c-5ad1fc3c9841"
}
```
*Falha*
```
{"message":"Usuário não existe"}

```
```
{"message":"Senha incorreta"}

```

*Validações / Regras de negócio*
- Verficar se existe algum campo não informado
- Usar criptografia para envio da senha(hash)


**Usuário - GET**

***Necessário autenticação***
***Token no header da requisição***

***URL:*** /usuario
***Método:*** GET

*Dados de entrada*
```json
{"token":"c0ce7f40-e12b-393e-bb7c-5ad1fc3c9841",
"user_id":"1"}
```


*Dados de saída*
*Sucesso*
```json
{"name":"Jose Silva",
"email":"josesilva@email.com"}
```

*Falha*
{"mensagem":"O usuário informado não existe"}

*Validações / Regras de negócio*
- Verificar se o usuário informado existe no banco de dados
- O token tem que ser passado no front no headers athorization

**Usuário - PUT**

***Necessário autenticação***
***Token no header da requisição***

***URL:*** /usuario
***Método:*** PUT

*Dados de entrada*
```json
{
  "name": "Jose Silva Lima",
  "email": "josesl@email.com",
  "password": "hashSenha"
}
```


*Falha*
```json
{"message":"email já cadastrado"}
```

*Validações / Regras de negócio*
-Verificar se o email informado não é igual ao de outro usuario.

**Cadastro cliente - POST**

***Necessário autenticação***
***Token no header da requisição***

***URL:*** /clients
***Método:*** POST

*Dados de entrada*
```json
{
    "name": "Bruna",
    "email": "bruna.silahty@hotmail.com",
    "cpf": "1234567890",
    "phone_client": "7184958568",
    "cep": "52041550",
    "address": "Rua sem nome",
    "complement": "Apatarmento do lado esquerdo",
    "neighborhood": "Fim",
    "city": "Marte",
    "state": "sr"
}

```

*Dados de saída*
*Sucesso*
```json
{"mensagem": "Usuário cadastrado com sucesso"}
```
*Falha*
```json
{"message":"email já cadastrado"}
```
```json
{"message":"Telefone cadastrado por outro cliente"}
```

*Validações / Regras de negócio*
-Verificar se o email informado não é igual ao de outro cliente.
-Verificar se o telefone informado não é igual ao de outro cliente

<h1>Sprint 2</h1>


<h2>Listagem de clientes - GET</h2>

Na posição de usuário do sistema, desejo visualizar uma listagem com todos os clientes cadastrados.

**Obs:** O dados status tem que ser criado a parti da pesquisa do BD de charges e se houver alguma cobrança vencida (com status pendente e com data de vencimento anterior a data atual), deverá exibir true, caso contrário, deverá exibir false.

***Necessaário autenticação***
***Token no header da requisição***

***URL:*** /listclients
***Método:*** GET


*Dados de saída*
```jsonl
{
  "clientsWithStatus": [
    {
      "id": 1,
      "name_client": "Bruna carla",
      "email_client": "bruna.silahty@hotmail.com",
      "cpf_client": "1234567890 ",
      "phone_client": "7184958568",
      "status": true
    },
    {
      "id": 2,
      "name_client": "tayanna kelly",
      "email_client": "amorim.tayanna@gmail.com",
      "cpf_client": "10278487345",
      "phone_client": "546373838",
      "status": false
    },
    {
      "id": 3,
      "name_client": "Thaysa Ketlen",
      "email_client": "thaysa.ketlen@hotmail.com",
      "cpf_client": "10290999   ",
      "phone_client": "85678900",
      "status": false
    }
  ],
  "totalPages": 1
}

```


<h2>Detalhamento do Cliente- GET</h2>

Na posição de usuário do sistema, desejo visualizar todos os detalhes de um cliente cadastrado, a fim de consultar seus dados e suas respectivas cobranças.

***Necessaário autenticação***
***Token no header da requisição***

***URL:*** /detailclient/:id
***Método:*** GET

*Dados de saída*

```json
{
  "name_client": "Jose Silva",
  "cpf_client": "88051533461",
  "email_client": "josesilva@email.com",
  "phone_client": "1234567890",
  "address_complete": {
    "address": "rua sem nome",
    "cep": "52041550",
    "complement": "Grand Line",
    "neighborhood": "Barra de Jangada",
    "city": "São Paulo",
    "state": "São Paulo"
  },
  "charges": [
    {
      "id_charges": "1",
      "description ": "lorem ipsum, lorem ipsum, lorem ipsum, lorem ipsum",
      "due_date": "12/05/23",
      "amount": "5000",
      "status": true
    },
    {
      "id_charges": "2",
      "description ": "lorem ipsum, lorem ipsum, lorem ipsum, lorem ipsum",
      "due_date": "12/05/23",
      "amount": "3000",
      "status": false
    }
  ]
}

```

<h2>Atualização do cliente - PUT</h2>

Na posição de usuário do sistema, desejo atualizar os dados de um cliente cadastrado.

***Necessaário autenticação***
***Token no header da requisição***

***URL:***/clients/:identification
***Método:*** PUT

- Campos Obrigatórios
    - nome
    - email
    - cpf
    - phone 
    
*Dados de entrada*

```json
{
  "name_client": "Bruna carla",
  "email_client": "bruna.silahty@hotmail.com",
  "cpf_client": "1234567890",
  "phone_client": "7184958568",
  "cep": "52041550",
  "address": "Rua sem nome",
  "complement": "Apatarmento do lado esquerdo",
  "neighborhood": "Fim",
  "city": "Marte",
  "state": "sr"
}

```
*Dados de saída*

*Sucesso*
```json
{
	"id": 22,
	"id_user": 34,
	"name_client": "Wuso Pedro",
	"email_client": "jose.silahty@hotmail.com",
	"cpf_client": "01790525093",
	"phone_client": "81983498923",
	"cep": "65095205",
	"address": "Rua Doze",
	"complement": "Apatarmento do lado esquerdo",
	"neighborhood": "Tibiri",
	"city": "São Luís",
	"state": "PE"
}

```

*Falha*
```json
{"message":"Campos obrigatórios passados em branco"}
```
```json
{"message":"email já existe"}
```

*Mensagem de Erro em caso de:*
- Campos obrigatórios passados em branco
- E-mail informado for diferente do cliente em questão e já existir cadastrado para outro cliente.
- CPF informado for diferente do cliente em questão e já existir cadastrado para outro cliente
- Após realizado a atualização com sucesso o usuário deverá receber uma mensagem de confirmação


<h2>Cadastro de cobranças - POST</h2>

Na posição de usuário do sistema, desejo cadastrar cobranças para um cliente, afim de acessar suas informações no futuro.

***Necessário autenticação***
***Token no header da requisição***

***URL:*** /charges
***Método:*** POST

- Todos os campos são obrigatórios
- O id_customer é o do cliente em questão e não do usuário logado

*Dados de entrada*

```json
{
  "id_customer": "2",
  "name_client": "Heberty",
  "description": "Calça Jeans",
  "status": true,
  "amount": 26000,
  "due_date": "2023-10-01"
}

```

*Dados de saída*

```json
{
	"id_charges": 5,
	"id_customer": 2,
	"name_client": "Heberty",
	"amount": 26000,
	"due_date": "2023-10-01T03:00:00.000Z",
	"registration_date": "2023-09-23T03:00:00.000Z",
	"description": "Calça Jeans",
	"status": true
}

```

*Observações:*

- A validação para saber se está vencida pode ser feita no front
- O valor da cobrança também deve ser persistida no banco como centavos

*Mensagem de Erro em caso de:*
- Campos obrigatórios em branco


<h2>Listagem de cobranças - GET</h2>

Na posição de usuário do sistema, desejo visualizar uma listagem com todos as cobranças cadastradas.

***Necessário autenticação***
***Token no header da requisição***

***URL:*** /cobranca
***Método:*** GET


*Dados de saída*

```json
{
  "id": "4234234",
  "id_customer": "id que vem do req.user",
  "name_client": "Juliana Paiva",
  "description": "lorem ipsum",
  "cpf_client": "1234567890",
  "due_date": "1695168000",
  "amount": "20000",
  "status_charge": true || false
}

```
- A cobrança recebe Vencido (Caso o status seja pendente e a data de vencimento for anterior a data atual)


<h1>Sprint 3</h1>


<h2>Edição de Cobrança - PUT</h2>

### `Na posição de usuário do sistema, desejo atualizar os dados de uma cobrança cadastrada.`

***Necessário autenticação***
***Token no header da requisição***

***URL:*** /updatecharge
***Método:*** PUT

- Campos Obrigatórios
    - Descrição (<b>\*</b>)
    - Status (<b>\*</b>)
    - Valor (<b>\*</b>)
    - Vencimento (<b>\*</b>)

*Dados de entrada*

```json
{
  "id_charges": 2,
  "name_client": "Heberty",
  "description": "Calça Jeans",
  "status": true,
  "amount": 26000,
  "due_date": "2023-10-01"
}

```

*Dados de saída*

```json
{
  "id_charges": 2,
  "name_client": "Heberty",
  "description": "Calça Jeans",
  "status": true,
  "amount": 26000,
  "due_date": "2023-10-01",
  "registration_date": "2023-09-27"
}

```

*Mensagem de Erro em caso de:*
 - Campos obrigatórios passados em branco

 - Após realizado a atualização com sucesso o usuário deverá receber uma mensagem de confirmação (FRONT-END)


<h2>Exclusão de cobranças - DELETE</h2>

#### `Na posição de usuário do sistema, desejo excluir uma cobrança cadastrada.`

***Necessário autenticação***
***Token no header da requisição***

***URL:*** /deletecharge:idChages
***Método:*** DELETE

- Só poderá excluir a cobrança, se: 
    - A cobrança estiver com status <b>pendente</b>
    - A data de vencimento for <b>igual</b> ou <b>posterior a data atual</b>
  - Cobranças com status <b>"pagas"</b>, não poderão ser apagadas
  - OBS: Essa validações podem ser feitas no front e o back só receberia o id da cobrança que seria excluída.

*Dados de saída*

```json
{
  mensage: "Cobrança deletada com sucesso"
}

```

<h2>[Cobranças/Clientes] Busca e ordenação</h2>

#### `Na posição de usuário do sistema, desejo buscar cobranças e clientes a partir de suas respectivas listagens.`

<h4>
    Listagem Cobrança:
</h4>

- Na listagem de cobranças deverá possibilitar a <b>ordenação dos registros</b> pelo <b>nome do cliente</b> ou <b>ID da Cobrança</b> (front-end)
- Campo de busca que permitirá buscar cobranças pelos seguintes campos:
    - Nome do cliente
    - Id da cobrança
- OBS: esse filtro pode ser adicionado como uma verificação na rota já criada de listagem de cobranças
- Ex: Por exemplo, se na requisição existir um parâmetro de query que seja diferente de undefined para campos como id_charges ou name_client, a API realizará uma pesquisa correspondente com base no parâmetro fornecido.

***Lembre-se de que a pesquisa será sensível a maiúsculas e minúsculas, caso não seja definido nenhum critério de busca.***

```javascript
const {  id_charges, name_client, page } = req.query;

 if (nome !== undefined) {
    try {
      const chargesList = // aqui você pode pegar o mesmo objeto de pequisa para o Bd para listar todas as cobranças, mas tirando a paginação

      const chargeFilter = chargesList.filter(
        (charge) => charge.name_client === nome
      );

      return res.json(chargeFilter);
    } catch (error) {
      res.status(500).json({
        mensagem: "Erro interno do servidor",
        detalhes: error.message,
      });
    }
  }

```

<h4>
    Listagem Clientes:
</h4>

- Nas <b>listagens de clientes</b> deverá possibilitar a <b>ordenação</b> dos registros pelo <b>nome</b> (FRONT-END)
- Campo de busca que permitirá bucasr Clientes pelos seguintes campos:
    - Nome do cliente
    - CPF do cliente
    - E-mail do cliente

```javascript
const { name, email, cpf, page } = req.query; 

 if (name !== undefined) {
    try {
      const clientsList = // aqui você pode pegar o mesmo objeto de pequisa para o Bd para listar todas as cobranças, mas tirando a paginação

      const clientsFilter = clientsFilter.filter(
        (client) => client.name_client === name
      );

      return res.json(chargeFilter);
    } catch (error) {
      res.status(500).json({
        mensagem: "Erro interno do servidor",
        detalhes: error.message,
      });
    }
  }

```

- Em caso de não retornar <b>nenhum resultado</b> uma mensagem adequada deverá ser exibida.(FRONT-END)



<h2>
    [Cobranças/Clientes] Botão "ver todos" - Home
</h2>

#### `Na posição de usuário do sistema, desejo visualizar um relatório personalizado de cobranças e clientes.`

***Necessário autenticação***
***Token no header da requisição***

***URL:*** /custom-report
***Método:*** GET

- Nos dados de saída deverá retornar dois objetos, sendo eles


- Objeto que contenha informação sobre todas as ***cobranças*** agrupadas em tres categorias
    - ***paid*** - se a cobrança possuir o ```status = false```
    - ***preview*** - se o ```status = true``` e ```due_date > ``` que a data atual
    - ***Overdue*** - ```status = true``` e ``due_date < ``` que data atual

*xemplo de objeto de Charges*

```json
{

 "paid": [
    { "amount": 6500 },
    { "total": 7 },
    {
      "charges": [
        {
          "id_charges": 1,
          "name_client": "Bruna carla",
          "amount": 2000
        },
        {
          "id_charges": 2,
          "name_client": "tayanna kelly",
          "amount": 4500
        }
      ]
    }
  ],
 "preview": [
    { "amount": 24000 },
    { "total": 8 },
    {
      "charges": [
        {
          "id_charges": 1,
          "name_client": "Bruna carla",
          "amount": 2000
        },
        {
          "id_charges": 2,
          "name_client": "tayanna kelly",
          "amount": 4500
        }
      ]
    }
  ],
 "overdue": [
    { "amount": 24000 },
    { "total": 5 },
    {
      "id_charges": 1,
      "name_client": "Bruna carla",
      "amount": 2000
    },
    {
      "id_charges": 2,
      "name_client": "tayanna kelly",
      "amount": 4500
    }
  ],

}

```

- Objeto que contenha informação sobre todas as ***clientes*** agrupadas pelo seu status

    - ***defaulters*** - se o cliente possuir o ```status = true```
    - - ***compliant*** - se o cliente possuir o ```status = false```

*Exemplo de objeto de Clients*

```json
{

  "defaulters": [
    { "total": 4 },
    {
      "clients": [
        {
          "id": 16,
          "name_client": "Tayanna",
          "cpf_client": "123146456"
        },
        {
          "id": 17,
          "name_client": "Oriana",
          "cpf_client": "123145353"
        }
      ]
    }
  ],
  "compliant": [
    { "total": 6 },
    {
      "clients": [
        {
          "id": 17,
          "name_client": "Oriana",
          "cpf_client": "123145353"
        },
        {
          "id": 17,
          "name_client": "Oriana",
          "cpf_client": "123145353"
        }
      ]
    }
  ]

}
```

*Dados saída*

```json
{
  "paid": [
    { "amount": 6500 },
    { "total": 7 },
    {
      "charges": [
        {
          "id_charges": 1,
          "name_client": "Bruna carla",
          "amount": 2000
        },
        {
          "id_charges": 2,
          "name_client": "tayanna kelly",
          "amount": 4500
        }
      ]
    }
  ],
  "preview": [
    { "amount": 24000 },
    { "total": 8 },
    {
      "charges": [
        {
          "id_charges": 1,
          "name_client": "Bruna carla",
          "amount": 2000
        },
        {
          "id_charges": 2,
          "name_client": "tayanna kelly",
          "amount": 4500
        }
      ]
    }
  ],
  "Overdue": [
    { "amount": 24000 },
    { "total": 5 },
    {
      "id_charges": 1,
      "name_client": "Bruna carla",
      "amount": 2000
    },
    {
      "id_charges": 2,
      "name_client": "tayanna kelly",
      "amount": 4500
    }
  ],
  "defaulters": [
    { "total": 4 },
    {
      "clients": [
        {
          "id": 16,
          "name_client": "Tayanna",
          "cpf_client": "123146456"
        },
        {
          "id": 17,
          "name_client": "Oriana",
          "cpf_client": "123145353"
        }
      ]
    }
  ],
  "compliant": [
    { "total": 6 },
    {
      "clients": [
        {
          "id": 17,
          "name_client": "Oriana",
          "cpf_client": "123145353"
        },
        {
          "id": 17,
          "name_client": "Oriana",
          "cpf_client": "123145353"
        }
      ]
    }
  ]
}
```

***OBS: Adicionar uma ordenação do maior para o menor id, e só precisa retornar para o front os 4 primeiros resultados, tanto do objeto de charge como do de clients***