Appearance
@fc/prev-api
API REST de cálculos previdenciários do RGPS: tempo de contribuição, análise de benefícios e atrasados. Expõe Swagger em /_swagger e OpenAPI em /_openapi.json.
Todas as respostas JSON dos endpoints sob /rgps/api/v1/* seguem o envelope PDPJ-Br:
json
{
"status": "ok",
"code": "200",
"messages": [],
"result": { /* ... */ }
}Contrato OpenAPI
O contrato público canônico é /_openapi.json; principal.json é a fonte gerada no build. Ao servir o documento, o runtime acrescenta a origem atual, a proteção por API key e os schemas do envelope de erro, exclui rotas internas e impede cache compartilhado com Cache-Control: no-store. O antigo public/openapi-spec.json não é consumido pela aplicação e está excluído do contexto Docker.
Endpoints
Os endpoints canônicos vivem sob o módulo rgps (Regime Geral de Previdência Social) e compartilham o namespace /rgps/api/v1/* com a rmi-api. Os endpoints /api/v1/* legados foram removidos após o sunset de 2026-05-31 (RFC 8594) e hoje respondem 404.
Cálculos canônicos (JSON)
| Método | Caminho | Descrição |
|---|---|---|
POST | /rgps/api/v1/calculos-tempo | Calcula tempo de contribuição e analisa elegibilidade a benefícios |
POST | /rgps/api/v1/calculos-tempo/por-grupos | Calcula o tempo para todos os grupos de benefícios |
POST | /rgps/api/v1/calculos-atrasados | Calcula atrasados previdenciários |
Nos resultados, cada benefício analisado traz fundamento (a citação legal legível, EC 103, art. 20) e chaveFundamento (a chave estável, EC_103_ART_20, a mesma usada pela API de RMI no cálculo por fundamento).
Fontes externas: documentos e arquivo .calc
| Método | Caminho | Descrição |
|---|---|---|
POST | /rgps/api/v1/calculos-tempo/cnis/ler | Extrai dados de CNIS (PDF ou texto) no formato do cálculo |
POST | /rgps/api/v1/calculos-tempo/rdctc/ler | Extrai dados de RDCTC (PDF ou texto) no formato do cálculo |
POST | /rgps/api/v1/calculos-tempo/carta/ler | Extrai dados de Carta de Concessão no formato do cálculo |
POST | /rgps/api/v1/calculos-tempo/pap/ler | Segmenta um PAP (PDF) e extrai os documentos identificados |
POST | /rgps/api/v1/calculos-tempo/prevjud/ler | Extrai dados do JSON PrevJud no formato do cálculo de tempo |
POST | /rgps/api/v1/calculos-tempo/prevjud/calcular | Leitura + cálculo de tempo a partir do JSON PrevJud |
POST | /rgps/api/v1/calculos-tempo/prevjud/calcular-por-grupos | Leitura + cálculo de tempo por grupos a partir do JSON PrevJud |
POST | /rgps/api/v1/calculos-tempo/arquivo-calc/ler | Lê arquivo .calc de tempo e devolve o JSON pronto |
POST | /rgps/api/v1/calculos-tempo/arquivo-calc/calcular | Leitura + cálculo em uma única chamada |
POST | /rgps/api/v1/calculos-tempo/arquivo-calc/calcular-por-grupos | Leitura + cálculo por grupos em uma única chamada |
POST | /rgps/api/v1/calculos-atrasados/arquivo-calc/ler | Lê arquivo .calc de atrasados e devolve o JSON pronto |
POST | /rgps/api/v1/calculos-atrasados/arquivo-calc/calcular | Leitura + cálculo de atrasados em uma única chamada |
Os endpoints com fonte externa (CNIS, RDCTC, Carta de Concessão, PAP, PrevJud, .calc) aceitam multipart/form-data com o arquivo no campo file. Os demais aceitam application/json. CNIS, RDCTC e Carta de Concessão aceitam application/pdf ou text/plain; quando o PDF contém mais de um documento completo do tipo, vale o ÚLTIMO identificado (separação multi-documento só em PDF). O pap/ler aceita apenas PDF e devolve os CNIS, RDCTC e Cartas de Concessão identificados com certeza, por tipo e na ordem de aparição, com faixa de páginas.
As rotas que efetivamente calculam aceitam a query opcional permalink=true (ou 1). Quando solicitada, a API persiste um snapshot imutável e reabrível na calculadora correspondente e acrescenta permalink — uma URL pública completa — no topo do envelope, sem alterar result. Omitir a query, ou usar false/0, preserva integralmente o contrato anterior. Rotas que apenas leem ou extraem documentos não criam permalink. O snapshot segue a retenção longa da plataforma, atualmente dez anos; o opt-in não amplia os limites de entrada de 10 MiB para JSON e 5 MiB para .calc. Valor diferente dos quatro aceitos responde 400, indisponibilidade da capacidade responde 503 e uma resposta interna sem URL válida responde 502.
As oito rotas que efetivamente calculam (tempo e atrasados) aceitam também a query opcional demonstrativo=true (ou 1): o envelope ganha demonstrativoPdf — o demonstrativo do cálculo em PDF, na identidade visual da calculadora, com conteúdo em base64, nome de arquivo sugerido, quantidade de páginas e tamanho em bytes (schema DemonstrativoPdfApi no OpenAPI). O PDF sempre embute um permalink do cálculo no card de reprodução — por isso a geração do demonstrativo cria um snapshot como o do permalink=true, e as duas queries podem ser combinadas sem criação duplicada; a query permalink decide apenas se a URL também sai como campo separado. Os mesmos códigos valem para a capacidade de permalink (503/502), e falha na geração do PDF responde 500. No corpo JSON canônico, o campo opcional processo (nomeCalculo, numero, autor) preenche o bloco de identificação do PDF sem afetar o cálculo. Nas rotas de atrasados, quando o cálculo apura alçada, o envelope traz também demonstrativoAlcadaPdf, o demonstrativo de alçada, no mesmo schema.
API key estrutural
A proteção por x-api-key é declarativa por path, sem anotação nos handlers, e fica ligada por padrão. O nuxt.config.ts fixa os globs /rgps/api/v1/calculos-tempo/** e /rgps/api/v1/calculos-atrasados/**; assim, as rotas-base e todas as suas subrotas exigem a chave sem depender de variáveis de ambiente de deploy.
A chave é validada pela plataforma contra o cadastro central, com cache curto. Em desenvolvimento local, o assistente pode desligar essa proteção para facilitar testes; fora de dev e test, esse override interrompe o boot e os caminhos protegidos continuam fazendo parte da configuração estrutural da app.
Fail-fast no boot: se algum glob não casar com nenhuma rota registrada, a subida da app falha com mensagem clara.
Ver @fc/base-api/README.md para a mecânica completa.
Telemetria de uso
A prev-api registra telemetria best effort no fim da resposta HTTP, sem bloquear o cálculo nem alterar erros. Quando a rota estiver protegida por API key, o evento reaproveita event.context.apiKeyValidada e preserva o idTokenApiKey sem chamar o validador novamente.
Eventos emitidos:
| Ação | Endpoints |
|---|---|
rgps.beneficios.api | cálculo de tempo canônico e PrevJud |
rgps.beneficios.api.grupos | cálculo de tempo por grupos canônico e PrevJud |
rgps.beneficios.api.arquivo-calc | cálculo de tempo a partir de .calc |
rgps.beneficios.api.arquivo-calc.grupos | cálculo de tempo por grupos a partir de .calc |
rgps.atrasados.api | cálculo de atrasados |
rgps.atrasados.api.arquivo-calc | cálculo de atrasados a partir de .calc |
rgps.documentos.api.carta-concessao | leitura de Carta de Concessão |
rgps.documentos.api.cnis | leitura de CNIS |
rgps.documentos.api.rdctc | leitura de RDCTC |
rgps.documentos.api.prevjud | leitura de JSON PrevJud |
rgps.documentos.api.pap | segmentação e leitura de PAP |
Leitura isolada de .calc não emite evento próprio por enquanto; a taxonomia distingue o uso quando o arquivo é efetivamente calculado.
Os cálculos e as leituras intensivas de documentos são executados fora do fluxo HTTP principal, mantendo o health check responsivo durante operações longas. Se a capacidade temporária estiver ocupada, a API responde 429 Too Many Requests com Retry-After; repetir depois desse intervalo é seguro.
Convenções
Princípio central: um endpoint = um contrato (input único, output único).
- Recurso (plural hifenizado):
calculos-tempo,calculos-atrasados. - Variantes de cálculo (sub-path):
calculos-tempo/por-grupos. - Fonte externa (sub-recurso aninhado):
calculos-tempo/cnis/ler,calculos-tempo/arquivo-calc/calcular.
Sem Content-Type negotiation. As queries permalink e demonstrativo só acrescentam campos opcionais ao envelope; não alteram o schema de result. Cada endpoint tem um único requestBody.content tipado.
Tratamento de erros
Espécie do benefício. opcoesContagem.especie é obrigatória nas entradas JSON e na leitura de arquivo .calc (parametrosGerais.especie): sem ela a resposta é 400 com a mensagem que diz onde informá-la e os códigos aceitos — a API não presume espécie alguma. Aceita todas as espécies do dicionário do INSS.
Toda rota canônica (/rgps/api/v1/**) responde com o envelope PDPJ inclusive em falha — nunca com erro cru do framework. A normalização é feita por tratarErroRota(event, erro) de @base-api/server/utils/erros:
| Origem do erro | HTTP | status |
|---|---|---|
JSON malformado no corpo (SyntaxError de JSON.parse) | 400 | error |
Falha de schema Zod (ZodError) | 400 | error |
ErroDominio lançado pelo handler (validação semântica, upload, etc.) | 400 | error |
Exceção conhecida do core @fc/calculos-previdenciarios | 400 | error |
| Upload acima do limite da classe ou do teto de páginas do endpoint | 413 | error |
ErroConteudoNaoProcessavel (arquivo sem documento reconhecível) | 422 | error |
| Qualquer outra exceção | 500 | error |
Em 400, messages lista os detalhes (caminho.do.campo: mensagem para falhas Zod). Em 500, a mensagem é genérica e o erro é registrado via logOperacional.error — sem vazar stack trace.
Validação de entrada: payloads JSON e uploads multipart/form-data passam por schemas Zod defensivos de superfície (apps/prev-api/server/utils/esquemas.ts). A regra de negócio completa segue dentro do core (DadosCalculo.deApiTempo, desserializarAtrasados, etc.); o Zod existe para transformar entradas catastroficamente inválidas em 400 determinístico, não para duplicar a regra. Corpos JSON são limitados a 10 MiB pela contagem dos bytes recebidos e não dependem de content-length.
Uploads: o multipart deve conter exatamente um arquivo no campo obrigatório file; campo ausente, nome diferente, segundo arquivo ou tipo inválido → 400 com mensagem descritiva. Os uploads multipart aceitam tanto content-length quanto transfer-encoding: chunked; os limites de tamanho continuam valendo e o excesso responde 413. Nas leituras de PDF, o limite varia por classe de consumidor da chave de API (resolverTamanhoMaxPdfPorClasse de @base-api): 20 MB por padrão e 150 MB para a classe judiciario. O endpoint de CNIS também recusa com 413 PDFs acima de 5.000 páginas, antes de extrair o conteúdo de cada página.
Endpoints legados (removidos)
Os caminhos /api/v1/* foram desativados após o sunset de 2026-05-31, anunciado desde a criação do namespace canônico via headers RFC 8594 (Deprecation, Sunset, Link: rel="successor-version"). Hoje respondem 404. Consumidores remanescentes devem migrar para o sucessor:
| Legado | Sucessor |
|---|---|
POST /api/v1/tempo/calcular | POST /rgps/api/v1/calculos-tempo |
POST /api/v1/tempo/calcular-grupos | POST /rgps/api/v1/calculos-tempo/por-grupos |
POST /api/v1/atrasados/calcular | POST /rgps/api/v1/calculos-atrasados |
POST /api/v1/cnis/ler | POST /rgps/api/v1/calculos-tempo/cnis/ler |
POST /api/v1/rdctc/ler | POST /rgps/api/v1/calculos-tempo/rdctc/ler |
POST /api/v1/prevjud/ler | POST /rgps/api/v1/calculos-tempo/prevjud/ler |
POST /api/v1/prevjud/tempo/calcular | POST /rgps/api/v1/calculos-tempo/prevjud/calcular |
POST /api/v1/prevjud/tempo/calcular-grupos | POST /rgps/api/v1/calculos-tempo/prevjud/calcular-por-grupos |
POST /api/v1/arquivo-calc/tempo/ler | POST /rgps/api/v1/calculos-tempo/arquivo-calc/ler |
POST /api/v1/arquivo-calc/tempo/calcular | POST /rgps/api/v1/calculos-tempo/arquivo-calc/calcular |
POST /api/v1/arquivo-calc/tempo/calcular-grupos | POST /rgps/api/v1/calculos-tempo/arquivo-calc/calcular-por-grupos |
POST /api/v1/arquivo-calc/atrasados/ler | POST /rgps/api/v1/calculos-atrasados/arquivo-calc/ler |
POST /api/v1/arquivo-calc/atrasados/calcular | POST /rgps/api/v1/calculos-atrasados/arquivo-calc/calcular |
Os fluxos compostos de PrevJud (leitura + cálculo em uma única chamada) estão disponíveis via prevjud/calcular e prevjud/calcular-por-grupos. Clientes que preferirem inspecionar/editar o JSON lido antes de calcular podem usar o fluxo em duas chamadas: prevjud/ler → calculos-tempo.
Implementação interna
Os endpoints de tempo usam a superfície central do core para unificar o comportamento entre web e API:
- entradas JSON de tempo:
DadosCalculo.deApiTempo(...) - entradas JSON de tempo com PrevJud:
DadosCalculo.deApiTempoPrevjud(...) - entradas
.calc:DadosCalculo.deArquivoTc(...) - saídas serializadas:
AnaliseBeneficios.paraApiResultado(...)eAnaliseBeneficios.paraApiGrupos(...)
Os wrappers legados de @fc/calculos-previdenciarios/utilidades-apis/* continuam existindo por compatibilidade transitória; novas integrações internas devem preferir a superfície centralizada.
Logs
A aplicação emite logs estruturados em JSON via a classe Logger de @fc/utils. Todos os logs são escritos em stdout, prontos para ingestão por qualquer coletor (Loki, Elasticsearch, etc.).
Tipos de log
| Tag | Descrição |
|---|---|
prev-api | Log operacional — registra toda requisição recebida |
prev-api, auditoria | Log de auditoria — registra cada operação de cálculo/leitura concluída |
Os loggers vêm de @base/server/utils/loggers e usam como primeira tag o valor de nomeApp declarado em app/app.config.ts (aqui: prev-api):
logOperacional— usado pelo middleware de log da layer@fc/base-apipara registrar todas as requisições com a URL acessada.logAuditoria— usado em cada endpoint para registrar a operação realizada e o IP de origem.
Filtragem
Para isolar logs de auditoria em um coletor centralizado, filtre pela presença da tag auditoria:
json
{ "tags": ["prev-api", "auditoria"], ... }Eventos de auditoria
Cada endpoint emite um evento:
calculos-tempo→tempo.calculadocalculos-tempo/por-grupos→tempo.grupos.calculadocalculos-atrasados→atrasados.calculadocalculos-tempo/cnis/ler→cnis.lidocalculos-tempo/rdctc/ler→rdctc.lidocalculos-tempo/carta/ler→carta.lidacalculos-tempo/prevjud/ler→prevjud.lidocalculos-tempo/pap/ler→pap.lidocalculos-tempo/prevjud/calcular→tempo.prevjud.calculadocalculos-tempo/prevjud/calcular-por-grupos→tempo.prevjud.grupos.calculadocalculos-tempo/arquivo-calc/ler→arquivo-tc.lidocalculos-tempo/arquivo-calc/calcular→arquivo-tc.calculadocalculos-tempo/arquivo-calc/calcular-por-grupos→arquivo-tc.grupos.calculadocalculos-atrasados/arquivo-calc/ler→arquivo-atrasados.lidocalculos-atrasados/arquivo-calc/calcular→arquivo-atrasados.calculado
Cada evento inclui o campo ip com o endereço de origem confirmado pela borda confiável.