import { MigrationInterface, QueryRunner } from 'typeorm'; import { CONTRACT_TEMPLATE_DEFAULTS } from '../seed/data/contract-template-defaults'; /** * Creates freight.contract_templates — the six editable contract document * templates (direction × freight type) whose dynamic articles drive the * generated contract PDF — and seeds them from the EDR reference contract * documents. Seeding is idempotent (ON CONFLICT (code) DO NOTHING) so admin * edits are never overwritten by redeploys. */ export class CreateContractTemplates2090000000000 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { await queryRunner.query(` CREATE TABLE IF NOT EXISTS freight.contract_templates ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), code VARCHAR(40) NOT NULL, name VARCHAR(200) NOT NULL, description TEXT, document_title VARCHAR(300) NOT NULL, whereas_clauses JSONB NOT NULL DEFAULT '[]', articles JSONB NOT NULL DEFAULT '[]', is_active BOOLEAN NOT NULL DEFAULT TRUE, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), deleted_at TIMESTAMPTZ, CONSTRAINT uq_contract_templates_code UNIQUE (code) ); `); for (const seed of CONTRACT_TEMPLATE_DEFAULTS) { const articles = seed.articles.map((article, index) => ({ ...article, order: index + 1, })); await queryRunner.query( ` INSERT INTO freight.contract_templates (code, name, description, document_title, whereas_clauses, articles) VALUES ($1, $2, $3, $4, $5::jsonb, $6::jsonb) ON CONFLICT (code) DO NOTHING; `, [ seed.code, seed.name, seed.description, seed.documentTitle, JSON.stringify(seed.whereasClauses), JSON.stringify(articles), ], ); } } public async down(queryRunner: QueryRunner): Promise { await queryRunner.query(`DROP TABLE IF EXISTS freight.contract_templates;`); } }