Files
eden/packages/database/migrations/1789862600000_seed-document-templates.cjs
Matheus (Handix) 398579fa82 feat(database): migration de seed com os 7 templates reais de documento
Traz pro código os 7 templates importados na leva anterior (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) —
uma VM nova já nasce com eles publicados assim que roda `pnpm db:migrate`,
sem precisar reimportar manualmente. Segue o mesmo padrão de seed já usado
neste repo pra dado de catálogo (INSERT ... ON CONFLICT DO NOTHING dentro
da própria migration), idempotente por key.

Corrige de passagem um html_content vazio em 4 dos 7 JSONs originais
(não afeta geração/editor, só o card de preview) — recalculado com o
próprio renderToHtml antes de virar seed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-19 21:09:28 -03:00

90 lines
3.9 KiB
JavaScript

/**
* Semeia os 7 templates reais de documento herdados 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) — eden.md §1.1: "Registros existentes hoje (query real ao
* banco): 7 templates". A migration `1788468521075_documents.cjs` que criou
* o schema deixou essas 7 linhas explicitamente de fora ("Handix production
* data to be migrada later, not schema") — esta migration é esse "depois":
* assim toda máquina nova (`pnpm db:migrate` / `docker compose ... exec
* eden-api pnpm --filter @eden/database exec node-pg-migrate up`, ver
* docs/runbooks/setup-vm-pre-producao.md) já nasce com os 7 templates
* publicados, sem precisar reimportar manualmente.
*
* `editor_content`/`html_content` de cada um vêm de
* `document-template-seeds/<key>.json` ao lado deste arquivo — cópia
* exata da versão PUBLICADA fornecida pelo usuário (export do sistema
* legado, `/home/handix/document_templates_export.zip`), o mesmo conteúdo
* já testado ao vivo nesta sessão (renderiza no editor Tiptap, gera PDF via
* Chromium, inclusive o nó `conditional` do Termo de Contratação STFC).
* `html_content` já vem pré-renderizado (não precisa rodar
* `renderEditorContentToHtml` aqui — este pacote não pode depender do
* código do apps/api).
*
* Idempotente via `ON CONFLICT (key) DO NOTHING` (mesmo padrão de
* `fiscal_operation_nature`/`applications`/`roles` — ver
* 1788457368744_fiscal.cjs e 1788430575858_baseline-schema.cjs): se o
* template já existe (por exemplo, alguém já editou manualmente uma versão
* mais nova), esta migration NUNCA sobrescreve — só cria o que falta.
*
* Único par de `up`/`down` assíncrono desta pasta (as outras migrations
* usam `pgm.sql` síncrono) — precisa do `id` gerado pelo INSERT do
* template antes de inserir a versão (e o `id` da versão antes de apontar
* `current_version_id` de volta), então usa `pgm.db.query` (parametrizado,
* `$1`/`$2`/...) em vez de `pgm.sql` (que só monta SQL, não devolve linhas
* pro código da migration decidir o próximo passo).
*/
const fs = require("fs");
const path = require("path");
const SEED_DIR = path.join(__dirname, "document-template-seeds");
const SEED_FILES = [
"client_software_contract.json",
"client_cession_term.json",
"client_portability_term.json",
"client_stfc_term.json",
"reseller_contract_finder.json",
"reseller_contract_recorrente.json",
"reseller_adhesion_term.json",
];
function loadSeeds() {
return SEED_FILES.map((file) => JSON.parse(fs.readFileSync(path.join(SEED_DIR, file), "utf8")));
}
exports.shorthands = undefined;
exports.up = async (pgm) => {
for (const seed of loadSeeds()) {
const { rows: templateRows } = await pgm.db.query(
`INSERT INTO document_templates (key, name, doc_group)
VALUES ($1, $2, $3)
ON CONFLICT (key) DO NOTHING
RETURNING id`,
[seed.key, seed.name, seed.doc_group],
);
const template = templateRows[0];
if (!template) continue; // já existe — nunca sobrescreve.
const { rows: versionRows } = await pgm.db.query(
`INSERT INTO document_template_versions
(template_id, version, status, editor_content, html_content, css_content, page_config, published_at)
VALUES ($1, 1, 'published', $2::jsonb, $3, $4, '{}'::jsonb, now())
RETURNING id`,
[template.id, JSON.stringify(seed.editor_content), seed.html_content ?? "", seed.css_content ?? null],
);
const version = versionRows[0];
await pgm.db.query(`UPDATE document_templates SET current_version_id = $1 WHERE id = $2`, [
version.id,
template.id,
]);
}
};
exports.down = async (pgm) => {
const keys = loadSeeds().map((seed) => seed.key);
// ON DELETE CASCADE em document_template_versions.template_id cuida da versão junto.
await pgm.db.query(`DELETE FROM document_templates WHERE key = ANY($1::text[])`, [keys]);
};