feat(documents): suporte a linha condicional (conditional) + catálogo completo

Necessário pra importar os 7 templates reais do legado (fornecidos pelo
usuário via export do OrçaFácil): o Termo de Contratação STFC usa o nó
`conditional` (envelope em volta de uma tableRow, franquia de minutos/0800)
— sem suporte, tanto o backend quanto o editor Tiptap rejeitavam/renderizavam
em branco esse documento específico, mesmo bug já documentado no export do
legado. A condição em si nunca é avaliada nesta leva (fora de escopo) — a
linha sempre passa adiante, comportamento explícito e documentado.

Também adiciona ao variable-catalog.ts as ~25 variáveis que faltavam
(tarifação STFC por banda, 0800, portabilidade, prazo de instalação),
descobertas comparando contra as chaves reais usadas nos 7 templates
importados.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-19 20:26:18 -03:00
parent 1545666f17
commit 3785b32c5f
6 changed files with 215 additions and 6 deletions

View File

@@ -913,3 +913,61 @@ Publicado o rascunho e confirmado que a versão publicada aparece corretamente n
"Razão Social"/"CNPJ/CPF" renderizado com o estilo `.merge-field-chip` aplicado). Template de teste
(`qa_test_editor_*`) desativado ao final via `UPDATE document_templates SET active=false` (sem endpoint de
exclusão, mesmo padrão de higiene de dados de teste já seguido nesta sessão).
---
## Importação dos 7 templates reais do legado + suporte a `conditional`
Data: 2026-09-19. Usuário forneceu `/home/handix/document_templates_export.zip` — export real dos 7
templates de documento do OrçaFácil legado (Contrato de Software, Termo de Cessão, Termo de Portabilidade,
Termo de Contratação STFC, Contrato Canal Finder, Contrato Canal Recorrente, Termo de Adesão), cada um com
seu `editor_content` (árvore Tiptap real, não simplificada) e as 4 extensões Tiptap customizadas do
próprio editor legado (`mergeField`, `pageBreak`, `conditional`, `tableRow.repeat`). Pediu pra trazer esses
templates pro EDEN "pra ver como ficou" — validação de ponta a ponta do editor rico construído na leva
anterior contra conteúdo de produção real, não sintético.
**Achado real**: dos 7 templates, 6 usam só o que já era suportado (paragraph/table/mergeField/bold/
textAlign/colspan); o Termo de Contratação STFC usa também o nó `conditional` (envelope em volta de uma
`tableRow`, usado nas linhas de franquia de minutos/0800) — não suportado na leva anterior. Sem essa
extensão, o **editor renderizava em branco** pra esse documento específico — exatamente o mesmo bug já
documentado (e corrigido) no próprio export do legado (`ConditionalRow.jsx`, comentário no README do zip).
Nenhum dos 7 usa `tableRow.attrs.repeat` — não precisou ser implementado.
### Backend
`editor-content-renderer.ts`: novo `case "conditional"` em `renderBlock` — sempre renderiza a linha
(avaliação real da condição contra contexto cru é trabalho futuro, fora de escopo, igual já documentado
pro nó em si). `collectMergeFieldKeys` já enxergava por dentro de qualquer node type genericamente, não
precisou mudar. `variable-catalog.ts`: adicionadas as ~25 entradas que faltavam (tabela de tarifação STFC
por banda/normal-reduzida, 0800, `comercializacao_inicio/fim`, `contrato.prazo_instalacao`,
`portabilidade.titular_cpf_cnpj_doadora`) — descobertas comparando as chaves realmente usadas nos 7
templates contra o catálogo já portado, todas historicamente do `variableRegistry.js` original.
### Frontend
Novo `conditionalRowExtension.ts` (porta de `ConditionalRow.jsx` do export) + `Table.extend({ content:
"(tableRow|conditional)+" })` em `DocumentEditor.tsx` — sem essa extensão de schema o Tiptap rejeita
qualquer documento com `conditional` como filho direto de `table`, mesmo bug do parágrafo acima.
### Importação
Script único (`scratchpad`, não versionado — é carga de dados, não feature) reaproveitando os endpoints já
existentes (create template → create draft → update draft com o `editor_content` real → publish) pra cada
um dos 7 JSONs, exatamente como um humano faria pela UI — nenhum endpoint de "importar" novo foi criado.
### Verificação
`pnpm turbo run typecheck build` 28/28. Suíte 125/125 (123→125: 2 novos casos de `conditional`). Os 7
templates reais importados e publicados com sucesso contra o ambiente docker local. Testado ao vivo: tela
de overview do Termo de Contratação STFC renderiza o contrato completo (3 páginas) com a tabela de
tarifação (LC/LDN/VC1/VC2/VC3/LDI × Normal/Reduzido) e as linhas condicionais de franquia/0800 no lugar
certo; o editor rico abre o MESMO documento sem tela em branco, com as 53 variáveis usadas listadas
corretamente no painel lateral (com badges "obrigatório"). Contrato de Software (o maior, 162KB de JSON)
também verificado: abre no editor sem erro de console/página, gera pré-visualização em PDF real sem erro.
PDF do STFC gerado via curl direto (Chromium real) e conferido via `pdftotext`: 3 páginas, texto
`[oferta.franquia_minutos]`/`[oferta.inclui_0800]`/`[oferta.numero_0800]`/tarifas em `[chave]` no lugar
certo do documento — confirma que o `conditional` nunca é removido, só passa adiante sem avaliação real
(comportamento documentado, não um bug).
### Achado colateral, não corrigido (fora de escopo)
A tela de listagem de templates estava com ~145 registros `qa_test_*` acumulados de suítes de teste
anteriores desta sessão — desativados via `UPDATE document_templates SET active=false` (mesmo padrão já
usado antes). Restaram ~9 templates de teste manual mais antigos (`client_test_contract`, `live_test_*`,
`smoke_*`, `teste_web_final` etc.) que não seguem o prefixo `qa_test_` automatizado — não mexidos, por
poderem ser exploração manual do próprio usuário.