Skip to content

0pedrohalmeida0/Fin_Control

Repository files navigation

FinControl

Aplicativo de controle de orçamento pessoal com rendas, despesas mensais, despesas futuras, rendas futuras e investimentos. Inclui gráficos, indicadores de saúde financeira, projeção de despesas futuras e histórico mensal.

Desenvolvido por Pedro Henrique de Almeida.

🌐 Em produção

A aplicação está rodando em:

https://fincontrol.pythonanywhere.com

Stack: Python 3.11 + Flask + SQLite, deploy em PythonAnywhere. Back e front servidos pelo mesmo processo (mesma origem, sem CORS aberto).

✨ Funcionalidades

  • Autenticação: cadastro e login com usuário/e-mail e senha (hash PBKDF2 + JWT).
  • Rendas ativas e passivas com categoria (Salário, Freelance, Aluguel…).
  • Rendas futuras (13º, PLR, restituição de IR…) com prazo em meses.
  • Despesas mensais com dia de vencimento e categoria.
  • Despesas futuras com prazo em meses (ex.: IPTU daqui a 6 meses).
  • Investimentos com rendimento anual (% a.a.) e cálculo de rendimento mensal.
  • Histórico mensal: salve um snapshot dos totais a cada mês e acompanhe a evolução da renda, despesas e saldo em um gráfico de linha.
  • Gráficos: pizza de distribuição de despesas + barra renda × despesas + linha de evolução temporal.
  • Saúde financeira: taxa de poupança, reserva de emergência (em meses), comprometimento da renda e classificação geral (Excelente → Crítico).
  • Projeção de despesas futuras com sugestão de reserva mensal.
  • Dados isolados por usuário — ninguém vê os dados de outra pessoa.
  • UI responsiva com Tailwind via CDN (sem build step).

🧱 Stack

Camada Tecnologia
Front-end HTML + CSS + JS (vanilla, Tailwind/Chart.js CDN)
Back-end Python 3.9+ / Flask 3 + flask-cors
Banco SQLite (arquivo local)
Auth JWT (PyJWT) + PBKDF2-SHA256 para hash de senha

Nenhuma etapa de build. pip install + python app.py e está rodando.


📂 Estrutura

Fin_Control/
├── index.html             # App principal (protegido)
├── login.html             # Tela de login
├── register.html          # Tela de cadastro
├── style.css              # Estilos (inclui tema das telas de auth)
├── script.js              # Lógica do app (consome a API)
├── api.js                 # Cliente HTTP + storage do token JWT
├── auth.js                # Comportamento das telas de login/registro
├── render.yaml            # Deploy 1-clique no Render.com
├── security_audit.py      # Auditoria automatizada (roda contra a URL em produção)
├── backend/
│   ├── app.py             # Entry point Flask + hardening (CORS, headers)
│   ├── rate_limit.py      # Flask-Limiter compartilhado
│   ├── database.py        # Schema SQLite + helpers de query
│   ├── auth.py            # Hash PBKDF2 + JWT + decorator @auth_required
│   ├── auth_routes.py     # /api/auth/register, /login, /me, /logout
│   ├── data_routes.py     # /api/data + CRUD por recurso + /api/history
│   ├── test_api.py        # Smoke test do backend
│   ├── test_e2e.py        # Fluxo end-to-end
│   ├── test_new_features.py  # future_incomes + monthly_history
│   ├── requirements.txt
│   ├── Dockerfile         # Imagem de produção (gunicorn)
│   ├── Procfile           # Heroku-style start command
│   ├── runtime.txt        # Versão do Python
│   └── .gitignore
└── README.md

🚀 Como rodar

1. Instalar dependências do back-end

cd backend
python3 -m venv .venv
source .venv/bin/activate       # Windows: .venv\Scripts\activate
pip install -r requirements.txt

2. Subir o servidor

python app.py

O servidor escuta em http://127.0.0.1:5000 por padrão. Para mudar: PORT=8080 python app.py. Para expor o backend em outra origem e permitir o front em outro host, defina window.API_BASE antes de api.js (ou ajuste BASE em api.js).

3. Abrir o front-end

4. (Opcional) Configurações de ambiente

Variável Padrão Descrição
PORT 5000 Porta HTTP
FLASK_DEBUG 0 1 para modo debug do Flask
JWT_SECRET dev-secret-change-me-in-production Chave HMAC dos tokens (troque em prod!)
FINCONTROL_DB backend/fincontrol.db Caminho do arquivo SQLite

🔐 API

Todas as rotas de dados exigem o header Authorization: Bearer <token>. Respostas em JSON. Erros vêm como {"error": "mensagem"}.

Autenticação

Método Rota Body Resposta
POST /api/auth/register {username, email, password} 201 {token, user}
POST /api/auth/login {username, password} ou {email, password} 200 {token, user}
GET /api/auth/me 200 {user}
POST /api/auth/logout 200 {ok: true}

Dados do usuário

Método Rota Descrição
GET /api/data Snapshot completo
GET /api/<resource> Lista itens
POST /api/<resource> Cria item
PUT /api/<resource>/<id> Atualiza item
DELETE /api/<resource>/<id> Remove item

Recursos: incomes, passive_incomes, monthly_expenses, future_expenses, future_incomes, investments.

Histórico mensal

Método Rota Descrição
GET /api/history Lista snapshots salvos (mais recente primeiro)
POST /api/history/snapshot Salva/atualiza um snapshot (recalcula totais se omitidos)
PUT /api/history/<id> Atualiza apenas as notas de um snapshot
DELETE /api/history/<id> Remove um snapshot

Exemplos:

// POST /api/monthly_expenses
{
  "name": "Aluguel",
  "value": 2200,
  "category": "Moradia",
  "due_day": 5
}

// POST /api/history/snapshot
{
  "month_year": "2026-07",        // opcional: padrão = mês atual
  "notes": "Mês de férias",        // opcional
  "totals": {                      // opcional: se omitido, o servidor recalcula
    "income": 8000,
    "passive": 500,
    "expenses": 2000,
    "investments": 10000
  }
}

🔐 Variáveis de ambiente importantes

Variável Obrigatória? Descrição
PORT automática A plataforma define. Default 5000.
JWT_SECRET sim Chave HMAC dos tokens. Gere um valor forte!
FINCONTROL_DB opcional Caminho do SQLite. Default: backend/fincontrol.db.
FLASK_DEBUG opcional 0 em produção.

🧪 Testes

Dois scripts prontos, ambos usam apenas a stdlib (urllib):

cd backend
python3 test_api.py            # ~20 cenários: auth, validações, isolamento
python3 test_e2e.py            # fluxo UI-equivalente completo
python3 test_new_features.py   # future_incomes + monthly_history

🔒 Segurança

O app foi endurecido para uso público. Medidas implementadas:

Criptografia e autenticação

  • Senhas com PBKDF2-HMAC-SHA256, 200.000 iterações, salt aleatório de 16 bytes.
  • JWT com HS256 e expiração de 7 dias.
  • Senha: 6–128 caracteres; usuário: 3-32 chars (a-z A-Z 0-9 _ . -).

Hardening HTTP (em toda resposta)

  • X-Content-Type-Options: nosniff
  • X-Frame-Options: DENY (anti-clickjacking)
  • Strict-Transport-Security: max-age=31536000; includeSubDomains (HSTS)
  • Content-Security-Policy (CSP) restritivo, liberando só os CDNs usados pelo front
  • Referrer-Policy: strict-origin-when-cross-origin
  • Permissions-Policy desabilitando geolocation, câmera, microfone, etc.
  • Server header reescrito para FinControl (esconde stack)

CORS

  • Origens explícitas e restritas (configurável via ALLOWED_ORIGINS).
  • Default: https://fincontrol.pythonanywhere.com.
  • Em dev, defina ALLOWED_ORIGINS=http://localhost:5000,http://127.0.0.1:5000.

Rate limiting

  • /api/auth/login e /api/auth/register: 10 req/min e 30 req/hora por IP via Flask-Limiter.
  • Resposta 429 Too Many Requests quando excede.

Isolamento de dados

  • Cada query SQL filtra por user_id do JWT — um usuário nunca vê dados de outro.
  • Todos os endpoints de dados exigem Authorization: Bearer <token>; sem ele → 401.

Validação de entrada

  • Username regex, email regex, senha com limites.
  • Payloads grandes / strings longas são rejeitados com 400.
  • Queries 100% parametrizadas (sem concatenação) — imune a SQL Injection clássico.
  • Tokens alg=none e inválidos são rejeitados com 401.

Auditoria

  • security_audit.py (na raiz do repo) faz 80+ verificações automatizadas contra uma URL alvo.

Configuração obrigatória em produção

  • JWT_SECRET: gere um valor forte com python -c "import secrets; print(secrets.token_hex(32))". O default dev-secret-change-me-in-production é apenas para dev local.
  • ALLOWED_ORIGINS: defina o(s) domínio(s) do app, separados por vírgula.

About

Aplicação Web com armazenamento em local storage para controle de finanças pessoais.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors