Files
GTI_GERENCIADOR_FISCAL/README.md
T
Gustavo 8d83122e98 feat: login individual por funcionario (cadastro, senha com hash, ativar/desativar)
- Tabela FUNCIONARIO_PAINEL (nova, ja criada no banco de dev) +
  app/db/funcionarios.py: nome/login/senha (hash scrypt, stdlib, sem
  dependencia nova) por funcionario, nunca excluido de verdade (so
  ativo/inativo).
- app/senha.py: gerar_hash/verificar_senha com hashlib.scrypt + salt
  aleatorio por senha.
- app/auth.py: login passa a checar duas fontes, nessa ordem -
  ADMIN_USER/ADMIN_PASSWORD (bootstrap, continua exigindo as duas
  preenchidas) e depois FUNCIONARIO_PAINEL (so contas ATIVO=1). O
  nome retornado (usado no log) passa a ser o nome de verdade do
  funcionario, nao mais sempre 'admin'.
- Tela /funcionarios: listar, criar (com confirmacao de senha e
  checagem de login duplicado), editar nome/login, redefinir senha
  (form separado) e ativar/desativar. Tudo logado em LOG_PAINEL.
- Testado ponta a ponta contra o app real: funcionario criado via
  tela consegue logar de verdade, e a acao aparece no /log com o
  nome de quem fez.

93/93 testes passando (23 novos).
2026-08-13 14:19:58 -03:00

50 lines
3.6 KiB
Markdown

# painel-clientes-web
Painel administrativo (FastAPI + Jinja2) para gestão de `CLIENTE`, `CLIENTE_CONTATO` e geração manual de chave de licenciamento no MySQL do sistema legado.
Proteções: login HTTP Basic em toda rota, CSRF via cookie de duplo envio (`app/csrf.py` — todo formulário que muda estado embute o mesmo token do cookie `csrf_token`, definido pelo middleware em `app/main.py`) e a lista de clientes é paginada (100 por página), com busca e ordenação por código/razão/fantasia/CNPJ.
`CODIGO` de cliente não aceita duplicado (bloqueio duro, sem bypass) e o formulário de novo cliente já sugere o próximo código sequencial (editável). Só `CODIGO`, `CNPJ`, `RAZAO` e `FANTASIA` são obrigatórios — os campos de contrato (implantação, mensalidade, juros, datas) podem ficar em branco e recebem default (0,00 / data de hoje).
A rota `/log` mostra o histórico de ações do painel (tabela `LOG_PAINEL`, criada no banco de dev — **precisa ser criada manualmente em produção também**, DDL no início de `app/db/log.py`) e, se `N8N_API_URL`/`N8N_API_KEY` estiverem configuradas (`.env.example`), os últimos envios automáticos de chave via WhatsApp (lidos da Data Table `pagamentos_processados` do n8n, somente leitura).
## Login por funcionário
Cada funcionário pode ter seu próprio usuário/senha (tabela `FUNCIONARIO_PAINEL`, criada no banco de dev — **precisa ser criada manualmente em produção também**, DDL no início de `app/db/funcionarios.py`; senha em hash `scrypt`, nunca texto puro). Gerencie em **Funcionários** no menu.
`ADMIN_USER`/`ADMIN_PASSWORD` (`.env.example`) continuam funcionando como conta de bootstrap — é com ela que você entra a primeira vez para cadastrar o primeiro funcionário, e serve de plano B se a tabela ficar vazia. Login checa primeiro o admin do `.env`, depois `FUNCIONARIO_PAINEL` (só contas com `ATIVO=1`). O log de ações mostra o nome de quem fez cada coisa.
## Rodando localmente (sem Docker)
1. Instale as dependências de desenvolvimento:
```
pip install -r requirements-dev.txt
```
2. Defina as variáveis de ambiente necessárias (`ADMIN_USER`, `ADMIN_PASSWORD`, `DB_HOST`, `DB_PORT`, `DB_NAME`, `DB_USER`, `DB_PASSWORD` — veja `.env.example`) diretamente no shell antes de subir a aplicação. **Importante:** apesar de `python-dotenv` estar nas dependências, nada no código chama `load_dotenv()` hoje — um arquivo `.env` sozinho NÃO é lido automaticamente fora do Docker. Exporte as variáveis manualmente (ex.: `set -a; source .env; set +a` no bash, ou `$env:...` no PowerShell) ou defina-as por outro meio.
3. Rode a aplicação:
```
uvicorn app.main:app --reload
```
4. Rodando direto na máquina (fora de container), use `DB_HOST=127.0.0.1` (porta `3307`, a mesma do container de dev `licenciamento-mysql-dev`).
## Rodando os testes
```
pytest -v
```
Os testes usam defaults definidos em `tests/conftest.py` (equivalentes ao `.env.example`) e incluem testes de integração que precisam do container MySQL de dev (`licenciamento-mysql-dev`, `127.0.0.1:3307`) rodando.
## Rodando via Docker
1. Copie o arquivo de exemplo de variáveis de ambiente e edite `ADMIN_PASSWORD` (e demais valores, se necessário):
```
cp .env.example .env
```
2. Suba o container:
```
docker compose up -d --build
```
O `docker-compose.yml` já usa `env_file: .env` e mapeia `host.docker.internal` para o host (via `extra_hosts`), então o valor padrão `DB_HOST=host.docker.internal` do `.env.example` funciona também em hosts Docker Linux, não só no Docker Desktop (Windows/Mac).
3. A aplicação fica disponível em `http://localhost:8010`.