Compare commits
2 Commits
338677edc1
...
2aeb745d87
| Author | SHA1 | Date | |
|---|---|---|---|
| 2aeb745d87 | |||
| 398579fa82 |
@@ -971,3 +971,40 @@ anteriores desta sessão — desativados via `UPDATE document_templates SET acti
|
|||||||
usado antes). Restaram ~9 templates de teste manual mais antigos (`client_test_contract`, `live_test_*`,
|
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
|
`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.
|
poderem ser exploração manual do próprio usuário.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Os 7 templates viram parte do código (migration de seed)
|
||||||
|
|
||||||
|
Data: 2026-09-19. Usuário pediu pra embutir os 7 templates importados na leva anterior no próprio código,
|
||||||
|
pra que uma máquina nova (VM de pré-produção) já nasça com eles, sem precisar rodar o script de importação
|
||||||
|
manualmente de novo.
|
||||||
|
|
||||||
|
Padrão já usado neste repo pra dado de catálogo/referência é seed **dentro de uma migration** (`INSERT ...
|
||||||
|
ON CONFLICT DO NOTHING`, ver `1788457368744_fiscal.cjs`/`fiscal_operation_nature` e
|
||||||
|
`1788430575858_baseline-schema.cjs`/`applications`/`roles`) — não um serviço à parte. Nova migration
|
||||||
|
`packages/database/migrations/1789862600000_seed-document-templates.cjs` segue o mesmo padrão, com os 7
|
||||||
|
JSONs (key/name/doc_group/editor_content/html_content/css_content) copiados em
|
||||||
|
`document-template-seeds/*.json` ao lado dela. Idempotente por `key`: nunca sobrescreve um template já
|
||||||
|
existente (ex.: se alguém já editou manualmente).
|
||||||
|
|
||||||
|
Único `up`/`down` assíncrono desta pasta de migrations (as outras usam `pgm.sql` síncrono) — precisa do
|
||||||
|
`id` gerado pelo INSERT do template antes de inserir a versão, e do `id` da versão antes de apontar
|
||||||
|
`current_version_id` de volta, então usa `pgm.db.query` parametrizado em vez de `pgm.sql`.
|
||||||
|
|
||||||
|
**Achado real, corrigido no caminho**: o `html_content` do export original vinha **vazio** pra 4 dos 7
|
||||||
|
templates (`client_cession_term`/`client_portability_term`/`client_software_contract`/`client_stfc_term`)
|
||||||
|
— só os 3 `reseller_*` tinham. Não afeta geração real nem o editor (ambos leem `editor_content` direto),
|
||||||
|
só deixaria o card "Preview da versão publicada" vazio pra esses 4 numa instalação nova. Corrigido
|
||||||
|
recalculando o `html_content` desses 4 offline com o próprio `renderToHtml` (o mesmo já testado nesta
|
||||||
|
sessão, via `apps/api/dist/documents/editor-content-renderer.js` compilado) antes de gravar os JSONs de
|
||||||
|
seed — não precisou mudar nada no motor em si.
|
||||||
|
|
||||||
|
### Verificação
|
||||||
|
Testado contra banco **totalmente vazio** (não só o de desenvolvimento, que já tinha os 7 da importação
|
||||||
|
manual anterior): criado `eden_migration_test` no mesmo Postgres, rodado `node-pg-migrate up` do zero
|
||||||
|
(todas as migrations, não só esta) — os 7 templates nasceram publicados, com `editor_content` e
|
||||||
|
`html_content` corretos (conferido via query direta: `jsonb_array_length`/`length(html_content)` > 0 para
|
||||||
|
os 7). Banco de teste apagado depois. `pnpm --filter @eden/database typecheck` e suíte da API
|
||||||
|
125/125 sem regressão. Runbook (`docs/runbooks/setup-vm-pre-producao.md`) atualizado avisando que o passo
|
||||||
|
de migrations já traz os templates.
|
||||||
|
|||||||
@@ -66,6 +66,11 @@ rodar direto de dentro do container — `DATABASE_URL` já está no ambiente del
|
|||||||
docker compose --env-file .env exec eden-api pnpm --filter @eden/database exec node-pg-migrate up
|
docker compose --env-file .env exec eden-api pnpm --filter @eden/database exec node-pg-migrate up
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Isso já cria e publica os 7 templates de documento reais (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) — vêm junto com as migrations (`1789862600000_seed-document-templates.cjs`), não precisa reimportar
|
||||||
|
manualmente numa VM nova.
|
||||||
|
|
||||||
(Ou, se tiver Node 22 + pnpm instalados na própria VM, fora de Docker: `pnpm install && pnpm db:migrate`,
|
(Ou, se tiver Node 22 + pnpm instalados na própria VM, fora de Docker: `pnpm install && pnpm db:migrate`,
|
||||||
com `DATABASE_URL` apontando pra porta mapeada do Postgres no host.)
|
com `DATABASE_URL` apontando pra porta mapeada do Postgres no host.)
|
||||||
|
|
||||||
|
|||||||
@@ -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]);
|
||||||
|
};
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user