Carlexxx
para.AI beta
8a646ad

🔧 fixes.md — Diário de Bordo de Produção

Para.AI — Assuntos Jurídicos API v1.0.0 Versão inicial para usuários testadores


📅 24/02/2026 — v1.0.0

✅ Código entregue

Arquivo Linhas Status
app/schemas.py ~240 ✅ OK
app/builders.py 219 ✅ Corrigido (fix #1)
app/es_client.py ~490 ✅ OK
app/routes.py ~350 ✅ OK
app/main.py ~110 ✅ OK
app/config.py ~30 ✅ OK
data/es_mapping.json ~140 ✅ OK
Dockerfile ~50 ✅ OK
docker-compose.yml ~60 ✅ OK
entrypoint.sh ~100 ✅ OK
scripts/test_api.py ~210 ✅ 13 testes

🐛 Bug Corrigido

FIX #1 — app/builders.py_src_to_ficha()CRÍTICO

Arquivo: app/builders.py
Função: _src_to_ficha()
Linha original: ~141
Testes afetados: 2 (❌→✅)
Score antes: 77/79 | Score depois: 79/79

Descrição

Quando o chamador passa retornar=['texto'] explicitamente, o Elasticsearch já retorna texto_completo no _source (via _ficha_to_es_source() em es_client.py).

Porém o response builder descartava o valor por usar AND em vez de avaliar a intenção explícita do caller:

# ❌ ANTES (bugado) — AND exige AMBAS as condições
texto = src.get("texto_completo") if (incluir_texto and _want("texto")) else None,

# Quando retornar=['texto'] e incluir_texto_completo=False (default):
#   incluir_texto = False
#   _want("texto") = True   ← caller pediu explicitamente
#   False AND True = False  ← bug: descarta valor que o ES trouxe
# ✅ DEPOIS (corrigido) — trata intenção explícita separadamente
_explicitly_texto = want is not None and "texto" in want
texto = src.get("texto_completo") if (incluir_texto or _explicitly_texto) else None,

Tabela de comportamento após fix

retornar incluir_texto_completo Antes Depois
['texto'] False None valor
['texto'] True valor ✅ valor ✅
[] (vazio) False None None
[] (vazio) True valor ✅ valor ✅
['titulo'] False None None
['titulo'] True None None

Nota: quando retornar=[] e incluir_texto=False, o ES já exclui texto_completo do _source (via {"excludes": ["texto_completo"]}), então src.get("texto_completo") retorna None independentemente.


🧪 Resultado dos Testes

❌ retornar=texto — texto_completo       GET /busca-q  → ✅ CORRIGIDO
❌ POST retornar=['texto'] — texto_completo POST /busca-q → ✅ CORRIGIDO

ANTES:  77/79 testes passaram  (105945ms)
DEPOIS: 79/79 testes passaram  ✅

🚧 Limitações Conhecidas (v1.0)

  • Sem cache Redis (latência ~800ms p50 em /busca)
  • Sem rate limiting (risco em produção pública)
  • Sem autenticação/API keys
  • Logs não estruturados (texto puro, não JSON)
  • Sem métricas Prometheus/OTEL
  • Cold start ~2s (ES + primeiro request)

🔮 v1.1 Planejado (Março 2026)

  • Cache Redis (target p95 < 200ms)
  • Rate limiting (1000 req/min)
  • Logs JSON estruturados
  • Health check por componente
  • Testes de carga (Locust)
  • CI/CD GitHub Actions

📊 Performance Baseline (v1.0 — Local)

Endpoint p50 p95 p99
GET /busca ~800ms ~1200ms ~1850ms
GET /busca-q ~74ms ~120ms ~180ms
GET /autocomplete ~45ms ~80ms ~110ms
GET /hierarquia ~250ms ~400ms ~550ms
GET /assuntos/{id} ~20ms ~35ms ~50ms

Ambiente: Docker local, ES single-node, Python 3.11


🐛 Como Reportar

Issues: https://github.com/para-ai/assuntos-juridicos/issues
Template obrigatório: descrição + endpoint + payload + resposta recebida + resposta esperada