Carlexxx
para.AI beta
8a646ad
# 👨‍💻 DEV.md — Guia para Desenvolvedores
**Para.AI Assuntos Jurídicos API**
---
## Stack
| Camada | Tech | Versão |
|--------|------|--------|
| API | FastAPI | 0.115.12 |
| Search | Elasticsearch | 8.12.0 |
| Validação | Pydantic | 2.x |
| Cliente ES | elasticsearch-py | 8.17.0 |
| Serialização | orjson | 3.10.14 |
| Retry | tenacity | 9.x |
| Logging | rich | 13.x |
| Deploy | Docker Compose | 2.20+ |
| Python | CPython | 3.11+ |
---
## Estrutura do Código
```
app/
__init__.py # importa router
main.py # FastAPI app + lifespan (setup_es no startup)
config.py # Settings via pydantic-settings (ES_HOST, ES_INDEX, …)
schemas.py # Todos os modelos Pydantic (Assunto, FichaAssunto,
# BuscaQRequest, FICHA_CAMPOS_RETORNO, …)
es_client.py # Singleton ES + query builders + buscar/autocomplete/…
builders.py # Response builders: raw ES → Pydantic
routes.py # APIRouter com todos os endpoints
data/
es_mapping.json # Mapping ES com analyzer juridico_pt + edge n-gram
scripts/
test_api.py # Suite de testes HTTP (13 testes contra API live)
split_merge_bulk.py # utilitário para split/merge do bulk NDJSON
purge_and_push.sh # limpa e re-push dos dados no GitHub
Dockerfile # python:3.11-slim + uvicorn
docker-compose.yml # elasticsearch:8.12.0 + app
entrypoint.sh # aguarda ES → download bulk_assuntos.ndjson → uvicorn
```
---
## Setup Rápido
```bash
git clone https://github.com/para-ai/assuntos-juridicos.git
cd assuntos-juridicos
# Sobe ES + API (primeira vez baixa ~18MB de dados)
docker-compose up -d
# Acompanha indexação inicial (~30s)
docker-compose logs -f app
# Testa
curl "http://localhost:8000/health"
curl "http://localhost:8000/busca?q=aposentadoria&size=3"
# Docs interativas
open http://localhost:8000/docs
```
---
## Fluxo de Dados Resumido
```
Request GET /busca?q=aposentadoria
→ routes.busca_get()
→ es_client.buscar() # executa build_busca_query() + ES search
→ builders.build_busca_response() # raw ES → BuscaResponse Pydantic
→ ORJSONResponse # serialização rápida
```
```
Request POST /busca-q {q, campos, retornar, topk}
→ routes.busca_q_post()
→ es_client.busca_q() # build_busca_q_query() + ES search
→ builders.build_busca_q_response()
→ _src_to_ficha() # ← FIX #1 aplicado aqui
→ BuscaQResponse
```
---
## Campos — Mapa Semântico ES ↔ Ficha
| Nome na Ficha (`retornar=`) | Campo ES | Boost |
|-----------------------------|----------|-------|
| `titulo` | `nome_assunto` | 4.0 |
| `titulo_curto` | `titulo_curto` | 3.0 |
| `caminho` | `classes_path` | 2.5 |
| `introducao` | `breve_sintese` | 2.0 |
| `normas` | `dispositivos_legais` | 1.5 |
| `artigos` | `artigos` | 1.5 |
| `definicao` | `glossario` | 1.2 |
| `ramo` | `ramo` | — |
| `nivel1/2/3` | `classes_nivel1/2/3` | — |
| `texto` | `texto_completo` | 1.0 |
| `cod_assunto` | `cod_assunto` | — |
---
## Testes
```bash
# Testes HTTP contra API em execução (13 testes)
python scripts/test_api.py http://localhost:8000
# Resultado esperado após FIX #1:
# 13/13 passou 🎉
```
---
## Variáveis de Ambiente
| Variável | Default | Descrição |
|----------|---------|-----------|
| `ES_HOST` | `http://elasticsearch:9200` | URL do ES |
| `ES_INDEX` | `assuntos_juridicos` | Nome do índice |
| `ES_TIMEOUT` | `30` | Timeout (segundos) |
| `ES_MAX_RETRIES` | `3` | Retries automáticos |
| `APP_PORT` | `8000` | Porta da API |
| `APP_VERSION` | `1.0.0` | Versão da API |
---
## Contribuindo
1. `git checkout -b fix/meu-fix`
2. Implemente + adicione teste em `scripts/test_api.py`
3. `python scripts/test_api.py` → 100% passando
4. Pull Request com descrição do fix
Convenções: PEP8, type hints, docstrings Google, Conventional Commits.