Deploy inicial: API FastAPI + infra Podman/Caddy + docs

- App FastAPI (main.py, app/): rotas /health e /dados_retorno, middleware anti-scanner, logging configurado
- Config via configs.json (Pydantic); segredos fora do codigo e do git (.gitignore)
- Dockerfile (oracledb thin, HEALTHCHECK) + requirements.txt + .dockerignore
- Deploy Podman/Quadlet + Caddy em deploy/
- Docs: CLAUDE.md + docs/ (arquitetura, deploy, known-issues)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Ricardo Leite 2026-07-28 16:37:13 -03:00
commit 15c89c9038
22 changed files with 1397 additions and 0 deletions

17
docs/known-issues.md Normal file
View file

@ -0,0 +1,17 @@
# Problemas conhecidos / TODO — API-Scardua
## Segurança
- ✅ **Senha do Holmes movida pro config** (2026-07-23): agora é `settings.holmes.usuario` / `settings.holmes.senha`, lidos do `configs.json` (gitignored). Saiu do código. **Recomendado ainda trocar a senha**, já que ficou em texto claro antes.
- `/dados_retorno` está **público e sem autenticação** — qualquer um pode postar (enche o log). OK pra teste; proteger com token na API real.
- `/docs`, `/redoc`, `/openapi.json` ficam expostos quando `ambiente != prod` (atrás de basic auth). Fechar de vez com `ambiente = prod` no config, se não precisar deles.
- Log mostra o IP do **Caddy** (10.89.0.x), não o real. Pra ver o IP de origem: rodar o uvicorn com `--proxy-headers --forwarded-allow-ips=*` (seguro aqui, porque a porta 8000 não é publicada no host).
## Código incompleto
- **`app/infra/database.py` não existe** — `app/security.py` importa `db_instance` dele e quebraria. Não há camada de conexão Oracle funcional ainda (nada chama `create_pool` no caminho que roda).
- `app/security.py` usa `settings.api.jwt_secret`, que **não existe** em `app/config.py` (`ApiConfig` só tem `port`/`ambiente`/`workers`).
- `PyJWT` é importado em `security.py` mas **não está** nas dependências.
- `app/v1/holmes/holmes.py``obter_dados_compras` é um **stub** (`pass`), sem tipo no parâmetro.
- `pyproject.toml` aponta `readme = "README.md"`, mas o arquivo não existe (quebra `pip install .`; por isso o Docker usa `requirements.txt`).
## Middleware
- `block_scanners` é **denylist + heurística**, não allowlist estrita: qualquer path fora da blocklist, com User-Agent normal, **passa** e vira 404 na app (ex.: `/robots.txt`). Não vaza nada, mas é mais permissivo do que parece. Dá pra inverter pra allowlist estrita (403 em tudo fora da lista permitida) — lembrar de incluir `/docs`,`/redoc`,`/openapi.json` na lista.