| # 🔧 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: |
|
|
| ```python |
| # ❌ 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 |
| ``` |
|
|
| ```python |
| # ✅ 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 |
| |