# 👨‍💻 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.