documents/README.md
Breno Pires 50a2d0b628 feat(analyze): extracao por LLM com confianca por campo e dupla passada em datas
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 02:41:39 -03:00

53 lines
2.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# documents
Serviço de documentos e licenças dos postos: catálogo legal (parametrizável por UF), documentos
com trilha de versões, resumo de conformidade, análise de upload e régua de alertas de vencimento.
É o backend do menu **Documentos** do painel (`clubpetro-frontend`, `REACT_APP_DOCUMENTS_API=true`).
Espelho do serviço [`routines`](../routines) — NestJS 10 + Fastify + TypeORM/PostgreSQL, exceções
mapeadas com prefixo `DOC`, upload em bucket GCS privado com URL assinada.
## Endpoints
| Método | Rota | O que faz |
|---|---|---|
| GET | `/catalog?uf=SP` | Catálogo legal com variação estadual aplicada |
| GET | `/documents?programId&storeId` | Documentos da loja (status derivado na leitura) |
| POST | `/documents` (multipart) | Cria obrigação ou registra renovação (versão nova, trilha preservada) |
| POST | `/documents/analyze` (multipart) | Sugere tipo/datas do arquivo (v1: keywords; v1.1: OCR/LLM) |
| POST | `/documents/:id/protocol` | Registra o protocolo de renovação no órgão (status → em renovação) |
| PATCH | `/documents/:id/details` | Responsável e observações |
| GET | `/compliance/summary?programId&storeId` | Score 0100 ponderado por criticidade + totais |
| GET | `/compliance/upcoming?days=90` | Vencimentos na janela, ordenados |
| GET | `/alerts/preview` | O que a régua (lead/30/15/7/1/vencido) enviaria hoje |
| GET | `/health` | Probe do Kubernetes |
Regras de negócio centrais em `src/modules/common/utils/status.util.ts` (status) e
`src/modules/compliance/compliance.service.ts` (score) — as mesmas do painel, agora com o backend
como fonte da verdade. O detalhe jurídico que o modelo carrega: **renovação protocolada no prazo
mantém o documento operante** (na LO da CETESB, protocolo ≥120 dias antes prorroga a validade).
## Análise por LLM
Com `ANTHROPIC_API_KEY` no ambiente, o `POST /documents/analyze` extrai os campos do PDF/imagem
com um modelo multimodal (`DOCUMENTS_LLM_MODEL`, default Haiku): confiança por campo
(`fieldConfidences`), citação do trecho de origem (`evidence`) e **dupla passada em datas**
divergência entre as duas leituras zera o campo e devolve o warning `dateMismatch`, porque data
errada é pior que campo vazio. Qualquer falha do LLM (API fora, arquivo >10MB, mime estranho) cai
na heurística por nome de arquivo com o warning `llmUnavailable` — a análise nunca quebra o upload.
Sem a chave, o serviço se comporta como o v1 (heurística pura).
## Rodar local
```bash
cp .env.example .env # preencher SECRET_TOKEN
yarn && yarn start:dev # migrations rodam no boot (TYPEORM_MIGRATIONS_RUN=true)
yarn test # 38 testes, cobertura mínima 65/73/73/73
```
## Deploy (lab)
`k8s/hml/` uma vez à mão; depois `branch → PR → merge → cd.yml` (Cloud Build). Pré-requisitos
novos no ambiente: database `documents` na instância `clubpetro-homologation` e bucket privado
`corepetro_store_documents`.