Sistema completo de gerenciamento financeiro com controle de transações, contas, categorias e usuários.
- Descrição
- Arquitetura
- Tecnologias
- Estrutura do Projeto
- Instalação
- Configuração
- Rotas da API
- Testes
- Docker
- Contato
A API Finanças é uma aplicação RESTful robusta desenvolvida para gerenciamento completo de finanças pessoais. O sistema oferece funcionalidades de controle de transações financeiras, gestão de contas bancárias, categorização de gastos, autenticação de usuários e geração de relatórios analíticos.
- ✅ Autenticação JWT com bcrypt
- ✅ CRUD completo de Usuários
- ✅ Gestão de Contas Bancárias
- ✅ Controle de Transações (Depósitos e Retiradas)
- ✅ Categorização de Gastos
- ✅ Atualização automática de saldo
- ✅ Relatórios por categoria, período e tipo
- ✅ Ranking de gastos por categoria
- ✅ Documentação Swagger
- ✅ Testes unitários completos (56 testes)
O projeto segue o padrão MVC (Model-View-Controller) com separação clara de responsabilidades:
┌─────────────┐
│ Cliente │
└──────┬──────┘
│
▼
┌─────────────────────────────────────┐
│ Camada de Rotas │
│ (Express Router + Middleware Auth) │
└──────────┬──────────────────────────┘
│
▼
┌──────────────────────────────────────┐
│ Camada de Controllers │
│ (Lógica de Negócio e Validação) │
└──────────┬───────────────────────────┘
│
▼
┌──────────────────────────────────────┐
│ Camada de Models │
│ (Sequelize ORM + MySQL) │
└──────────┬───────────────────────────┘
│
▼
┌──────────────────────────────────────┐
│ Banco de Dados MySQL │
└──────────────────────────────────────┘
1. Cliente envia credenciais → POST /login
2. Controller valida usuário e senha (bcrypt)
3. Gera token JWT com expiração
4. Cliente recebe token
5. Cliente envia token no header: Authorization: Bearer {token}
6. Middleware valida token antes de acessar rotas protegidas
| Tecnologia | Versão | Descrição |
|---|---|---|
| Node.js | 18.x | Ambiente de execução JavaScript |
| Express.js | 4.22.1 | Framework web minimalista |
| Sequelize | 6.37.7 | ORM para MySQL |
| MySQL2 | 3.12.0 | Driver MySQL para Node.js |
| JWT | 9.0.3 | Autenticação baseada em tokens |
| Bcrypt | 6.0.0 | Hash de senhas |
| Cors | 2.8.5 | Controle de acesso entre origens |
| Dotenv | 16.4.7 | Gerenciamento de variáveis de ambiente |
| Tecnologia | Versão | Descrição |
|---|---|---|
| Jest | 29.7.0 | Framework de testes |
| Supertest | 7.1.4 | Testes de integração HTTP |
| @jest/globals | 29.7.0 | Utilitários globais do Jest |
| Tecnologia | Descrição |
|---|---|
| Docker | Containerização da aplicação |
| Docker Compose | Orquestração de containers |
| Nodemon | Auto-reload em desenvolvimento |
ApiFInancas/
├── __tests__/ # Testes unitários
│ ├── middlewares/
│ │ └── authMiddleware.test.js # Testes do middleware
│ ├── routes/
│ │ ├── auth.test.js # Testes de autenticação
│ │ ├── user.test.js # Testes de usuários
│ │ ├── account.test.js # Testes de contas
│ │ ├── category.test.js # Testes de categorias
│ │ └── transaction.test.js # Testes de transações
│ └── README.md # Documentação dos testes
│
├── src/
│ ├── config/
│ │ └── sequelize.js # Configuração do Sequelize
│ │
│ ├── controllers/
│ │ ├── accountController.js # Lógica de contas
│ │ ├── authController.js # Lógica de autenticação
│ │ ├── categoryController.js # Lógica de categorias
│ │ ├── transactionController.js # Lógica de transações
│ │ └── userController.js # Lógica de usuários
│ │
│ ├── middlewares/
│ │ └── authMiddleware.js # Middleware de autenticação JWT
│ │
│ ├── models/
│ │ ├── Account.js # Model de conta
│ │ ├── Category.js # Model de categoria
│ │ ├── Transaction.js # Model de transação
│ │ ├── User.js # Model de usuário
│ │ └── index.js # Exportação dos models
│ │
│ └── routes/
│ └── routes.js # Definição de todas as rotas
│
├── .env # Variáveis de ambiente (não versionado)
├── .gitignore # Arquivos ignorados pelo Git
├── app.js # Configuração do Express
├── docker-compose.yml # Configuração Docker Compose
├── Dockerfile # Imagem Docker da aplicação
├── init.sql # Script de inicialização do banco
├── jest.setup.js # Configuração do Jest
├── package.json # Dependências do projeto
├── README.md # Este arquivo
└── server.js # Ponto de entrada da aplicação
- Node.js 18.x ou superior
- MySQL 8.0 ou superior
- npm ou yarn
- Docker e Docker Compose (opcional)
Esta opção requer que você tenha o Node.js e MySQL instalados em sua máquina.
git clone https://github.com/EuAndersonDev/ApiFInancas.git
cd ApiFInancasnpm installCertifique-se de que o MySQL está rodando em sua máquina e crie o banco de dados:
CREATE DATABASE financas_db;Crie um arquivo .env na raiz do projeto com as seguintes configurações:
# Servidor
PORT=3000
NODE_ENV=development
# Banco de Dados
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=sua_senha
DB_NAME=financas_db
DB_PORT=3306
# JWT
JWT_SECRET=sua_chave_secreta_forte_aqui
TOKEN_EXPIRY=1h
⚠️ Importante:
- Substitua
sua_senhapela senha do seu MySQL- Gere uma chave secreta forte para o
JWT_SECRET
O Sequelize criará as tabelas automaticamente na primeira execução.
# Modo desenvolvimento (com auto-reload usando Nodemon)
npm run dev
# Modo produção
npm start✅ Pronto! O servidor estará disponível em http://localhost:3000
Esta é a forma mais rápida e fácil de rodar o projeto! O Docker irá configurar automaticamente a aplicação e o banco de dados MySQL.
- Docker
- Docker Compose
git clone https://github.com/EuAndersonDev/ApiFInancas.git
cd ApiFInancasdocker-compose up --buildNota: Na primeira execução, o Docker irá:
- Baixar as imagens necessárias (Node.js e MySQL)
- Instalar todas as dependências
- Criar o banco de dados
- Executar o script de inicialização (
init.sql)- Iniciar a aplicação
# Iniciar em modo background (detached)
docker-compose up -d --build
# Ver logs em tempo real
docker-compose logs -f
# Ver logs apenas da aplicação
docker-compose logs -f app
# Parar os containers
docker-compose down
# Parar e remover volumes (limpa o banco de dados)
docker-compose down -v
# Reiniciar apenas a aplicação
docker-compose restart app
# Acessar o terminal do container
docker-compose exec app sh| Serviço | Porta Host | Porta Container |
|---|---|---|
| API | 3000 | 3000 |
| MySQL | 3307 | 3306 |
✅ Pronto! A aplicação estará disponível em http://localhost:3000
💡 Dica: Com Docker você não precisa configurar variáveis de ambiente manualmente, tudo já está configurado no
docker-compose.yml!
Se precisar conectar ao MySQL via cliente externo (MySQL Workbench, DBeaver, etc.):
Host: localhost
Port: 3307
User: root
Password: root
Database: financas_db
| Variável | Descrição | Padrão |
|---|---|---|
PORT |
Porta do servidor | 3000 |
NODE_ENV |
Ambiente de execução | development |
DB_HOST |
Host do MySQL | localhost |
DB_USER |
Usuário do MySQL | root |
DB_PASSWORD |
Senha do MySQL | - |
DB_NAME |
Nome do banco | financas_db |
DB_PORT |
Porta do MySQL | 3306 |
JWT_SECRET |
Chave secreta JWT | - |
TOKEN_EXPIRY |
Tempo de expiração do token | 1h |
POST /register
Cria um novo usuário e uma conta automaticamente.
Body:
{
"name": "João Silva",
"email": "joao@example.com",
"password": "senha123",
"initialBalance": 1000.00
}Resposta (201):
{
"user": {
"id": "uuid-gerado",
"name": "João Silva",
"email": "joao@example.com"
},
"account": {
"id": "uuid-gerado",
"balance": 1000.00,
"user_id": "uuid-do-usuario"
}
}POST /login
Autentica um usuário e retorna um token JWT.
Body:
{
"email": "joao@example.com",
"password": "senha123"
}Resposta (200):
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}Importante: Todas as rotas abaixo requerem o header:
Authorization: Bearer {seu-token-jwt}
GET /getAllUsers
Resposta (200):
[
{
"id": "uuid",
"name": "João Silva",
"email": "joao@example.com",
"createdAt": "2025-12-16T10:00:00.000Z",
"updatedAt": "2025-12-16T10:00:00.000Z"
}
]POST /addAccount
Body:
{
"balance": 5000.00,
"user_id": "uuid-do-usuario"
}Resposta (201):
{
"id": "uuid-gerado",
"balance": 5000.00,
"user_id": "uuid-do-usuario",
"createdAt": "2025-12-16T10:00:00.000Z"
}GET /getAccountById/:id
Resposta (200):
{
"id": "uuid-da-conta",
"balance": 5000.00,
"user_id": "uuid-do-usuario",
"User": {
"id": "uuid",
"name": "João Silva",
"email": "joao@example.com"
}
}GET /balance/:id
Resposta (200):
{
"balance": 5000.00
}POST /addCategory
Body:
{
"name": "Alimentação"
}Resposta (201):
{
"id": "uuid-gerado",
"name": "Alimentação",
"createdAt": "2025-12-16T10:00:00.000Z"
}GET /getAllCategories
Resposta (200):
[
{
"id": "uuid",
"name": "Alimentação"
},
{
"id": "uuid",
"name": "Transporte"
}
]GET /getCategoryByName
Body:
{
"name": "Alimentação"
}Resposta (200):
{
"id": "uuid",
"name": "Alimentação"
}GET /categorySpendingRanking
Body (opcional):
{
"user_id": "uuid-do-usuario",
"startDate": "2025-01-01",
"endDate": "2025-12-31",
"type": "withdrawal"
}Resposta (200):
{
"filters": {
"type": "withdrawal",
"user_id": "uuid-do-usuario",
"period": {
"startDate": "2025-01-01",
"endDate": "2025-12-31"
}
},
"totalCategories": 3,
"ranking": [
{
"category_id": "uuid",
"category_name": "Alimentação",
"totalSpent": 1500.00,
"transactionCount": 25
},
{
"category_id": "uuid",
"category_name": "Transporte",
"totalSpent": 800.00,
"transactionCount": 15
}
]
}POST /addTransaction
Body (Depósito):
{
"description": "Salário",
"amount": 5000.00,
"date": "2025-12-16",
"type": "deposit",
"user_id": "uuid-do-usuario",
"account_id": "uuid-da-conta",
"category_id": "uuid-da-categoria"
}Body (Retirada):
{
"description": "Compra no supermercado",
"amount": 250.50,
"date": "2025-12-16",
"type": "withdrawal",
"user_id": "uuid-do-usuario",
"account_id": "uuid-da-conta",
"category_id": "uuid-da-categoria"
}Resposta (201):
{
"id": "uuid-gerado",
"description": "Salário",
"amount": 5000.00,
"date": "2025-12-16T00:00:00.000Z",
"type": "deposit",
"user_id": "uuid",
"account_id": "uuid",
"category_id": "uuid",
"createdAt": "2025-12-16T10:00:00.000Z"
}Nota: O saldo da conta é atualizado automaticamente.
GET /getAllTransactions
Resposta (200):
[
{
"id": "uuid",
"description": "Salário",
"amount": 5000.00,
"date": "2025-12-16T00:00:00.000Z",
"type": "deposit",
"User": {
"id": "uuid",
"name": "João Silva",
"email": "joao@example.com"
},
"Account": {
"id": "uuid",
"balance": 5000.00
},
"Category": {
"id": "uuid",
"name": "Salário"
}
}
]GET /getTransactionById/:id
Resposta (200):
{
"id": "uuid",
"description": "Compra no supermercado",
"amount": 250.50,
"date": "2025-12-16T00:00:00.000Z",
"type": "withdrawal",
"User": { ... },
"Account": { ... },
"Category": { ... }
}PUT /updateTransaction/:id
Body:
{
"description": "Compra no mercado - atualizado",
"amount": 300.00,
"date": "2025-12-16",
"type": "withdrawal",
"user_id": "uuid",
"account_id": "uuid",
"category_id": "uuid"
}Resposta (200):
{
"id": "uuid",
"description": "Compra no mercado - atualizado",
"amount": 300.00,
...
}Nota: O saldo da conta é recalculado automaticamente.
DELETE /deleteTransaction/:id
Resposta (200):
{
"message": "Transaction deleted successfully"
}Nota: O saldo da conta é revertido automaticamente.
GET /transactionsByCategory/:category_id
Resposta (200):
[
{
"id": "uuid",
"description": "Almoço",
"amount": 45.00,
"type": "withdrawal",
"date": "2025-12-16T00:00:00.000Z"
}
]GET /transactionsByPeriod
Query Params:
startDate: Data inicial (YYYY-MM-DD)endDate: Data final (YYYY-MM-DD)user_id: ID do usuário (opcional)
Exemplo:
GET /transactionsByPeriod?startDate=2025-01-01&endDate=2025-12-31&user_id=uuid
Resposta (200):
{
"period": {
"startDate": "2025-01-01",
"endDate": "2025-12-31"
},
"totalTransactions": 50,
"transactions": [ ... ]
}GET /transactionsByType
Query Params:
type: "deposit" ou "withdrawal"user_id: ID do usuário (opcional)
Exemplo:
GET /transactionsByType?type=deposit&user_id=uuid
Resposta (200):
{
"type": "deposit",
"totalTransactions": 12,
"totalAmount": 15000.00,
"transactions": [ ... ]
}| Código | Descrição |
|---|---|
| 200 | Sucesso |
| 201 | Criado com sucesso |
| 400 | Requisição inválida |
| 401 | Não autorizado (token inválido ou ausente) |
| 404 | Recurso não encontrado |
| 500 | Erro interno do servidor |
O projeto possui uma suíte completa de testes unitários com 81.33% de cobertura.
# Executar todos os testes com cobertura
npm test
# Modo watch (desenvolvimento)
npm run test:watch- ✅ 56 testes passando
- ✅ 6 suítes de teste
- ✅ Testes de autenticação
- ✅ Testes de todas as rotas
- ✅ Testes de middleware
- ✅ Testes de validação
Para mais detalhes, consulte o README dos testes.
# Iniciar containers
docker-compose up -d
# Ver logs
docker-compose logs -f
# Parar containers
docker-compose down
# Parar e remover volumes
docker-compose down -vA aplicação estará disponível em http://localhost:3000
O MySQL estará disponível na porta 3307
Acesse a documentação interativa em:
http://localhost:3000/api-docs
- Fork o projeto
- Crie uma branch para sua feature (
git checkout -b feature/AmazingFeature) - Commit suas mudanças (
git commit -m 'Add some AmazingFeature') - Push para a branch (
git push origin feature/AmazingFeature) - Abra um Pull Request
Este projeto está sob a licença ISC.
Anderson Reis
Desenvolvido com ❤️ por Anderson Reis