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>
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* 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]);
|
||||
};
|
||||
Reference in New Issue
Block a user