Índice remissivo
O índice alfabético remissivo (Vade Mecum) liga cada assunto ao dispositivo exato, para apps de consulta.
O índice alfabético remissivo é a lista de assuntos que um leitor procuraria para achar um
dispositivo — o índice de um Vade Mecum. Cada entrada liga um termo (o assunto) a um ref_key:
o dispositivo mais específico que trata daquele assunto. O app agrupa pelo termo, ordena
alfabeticamente e, ao toque, abre a lei no ref_key (por exemplo, GET /v1/dispositivos/{ref_key}).
O índice cobre o corpus inteiro (os diplomas de Diplomas no corpus) e é gerado
offline por bun run indice:gerar, que grava em indice_artigos/indice_entradas. A API apenas
lê — nada do índice depende de requisição de cliente.
As rotas são públicas (mesmo limite por IP das demais leituras do corpus). Base:
https://api.leivigente.com.br.
Rotas
| Rota | Devolve |
|---|---|
GET /v1/indice/export | O índice inteiro numa resposta (termos + entradas), com ETag: If-None-Match igual devolve 304 |
GET /v1/indice/termos | Termos do índice paginados, com a contagem de entradas; q filtra por trecho |
GET /v1/indice/termos/{chave} | Entradas de um termo: subtermo + ref_key + sigla/artigo |
A lista completa dos termos, para navegar no site, está em Termos do índice (A–Z,
gerada do banco com bun run indice:exportar).
GET /v1/indice/termos
Lista os termos, ordenados alfabeticamente pela chave (o termo sem acento e em minúsculas), com
quantas entradas cada um agrupa. q filtra por trecho; page/page_size paginam (padrão 1/50).
curl "$VIGENTE_URL/v1/indice/termos?q=prescri"{
"page": 1,
"page_size": 50,
"total": 2,
"items": [
{ "termo": "Prescrição", "chave": "prescricao", "entradas": 183 },
{ "termo": "Prescrição intercorrente", "chave": "prescricao intercorrente", "entradas": 9 }
]
}| Campo | Descrição |
|---|---|
termo | Grafia exata do assunto, estável entre lotes: é por ela que o app agrupa. |
chave | termo sem acento e minúsculo: chave de agrupamento e ordenação. |
entradas | Quantas entradas (subtermos/refs) o termo tem. |
Para montar o A–Z inteiro, pagine com page_size=200 (máximo) ou cacheie a lista.
GET /v1/indice/termos/{chave}
As entradas de um termo, pela chave devolvida acima. A entrada principal (o caput que define o
assunto) vem primeiro, com subtermo: null; depois vêm os recortes, em ordem alfabética.
curl "$VIGENTE_URL/v1/indice/termos/homicidio"{
"termo": "Homicídio",
"chave": "homicidio",
"entradas": [
{ "subtermo": "simples", "ref_key": "CP.121", "sigla": "CP", "artigo": "121" },
{ "subtermo": "qualificado", "ref_key": "CP.121.2", "sigla": "CP", "artigo": "121" },
{ "subtermo": "culposo", "ref_key": "CP.121.3", "sigla": "CP", "artigo": "121" },
{ "subtermo": "simples", "ref_key": "CPM.205", "sigla": "CPM", "artigo": "205" },
{ "subtermo": null, "ref_key": "CTB.302", "sigla": "CTB", "artigo": "302" }
]
}| Campo | Descrição |
|---|---|
subtermo | O recorte dentro do termo (ex.: qualificado, cabimento); null na entrada principal. |
ref_key | O dispositivo mais específico do assunto; o app abre a lei aqui. |
sigla | Sigla do diploma (para exibição). |
artigo | Número do artigo do ref_key (para exibição). |
Chave inexistente devolve 404 com {"error":{"code":"not_found","message":"…"}}.
Como o app usa
- Offline (o app Vade Mecum): baixe
GET /v1/indice/exportuma vez, guarde junto com oETage, a cada sincronização, mandeIf-None-Match;304quer dizer que nada mudou. - Online: liste
GET /v1/indice/termos(paginado,qfiltra) e, ao tocar num termo, chameGET /v1/indice/termos/{chave}. - Para abrir a lei, use o
ref_keyda entrada emGET /v1/dispositivos/{ref_key}— ou o artigo inteiro emGET /v1/diplomas/{sigla}/artigos/{artigo}.
O mesmo índice pode ser consumido por agentes via MCP.
Como é gerado
A geração roda fora da API, na máquina de quem publica, e não usa requisições de clientes: só o texto público das leis sai daqui.
bun run indice:gerar --dry-run --siglas CC,CPC # conta lotes, estima custo, mostra 1 prompt
bun run indice:gerar --siglas CC,CPC # piloto
bun run indice:gerar # corpus inteiro- O script monta um
<artigo>por artigo em vigor (caput + parágrafos, incisos, alíneas e itens), com a rubrica e a seção, e agrupa os artigos em lotes por diploma e seção. - Envia cada lote ao modelo (DeepSeek,
deepseek-chat, JSON) e valida a resposta: termos proibidos,refdentro do artigo, limite de 60 caracteres, deduplicação. - Grava em
indice_artigos(com o hash do que o modelo leu) eindice_entradas.
É incremental: uma nova execução só manda artigos novos ou cuja redação mudou, e poda do índice os que saíram do corpus. Como o resultado é gravado a cada lote, uma interrupção não perde o que já foi feito.
Na última execução (corpus inteiro): 20.480 artigos indexados, 33.571 entradas em 9.463 termos, ~US$ 5,00 em tokens. Os artigos que só têm cláusula de vigência, revogação ou remissão ficam com zero entradas — de propósito.