53 lines
2.9 KiB
Markdown
53 lines
2.9 KiB
Markdown
# 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 0–100 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`.
|