import { MigrationInterface, QueryRunner } from "typeorm"; /** * Editable customer-facing copy for the portal's public pages (/help, /faq, * /terms, /privacy) plus the shared support-contact block, with an append-only * version log behind it. * * `payload` is opaque jsonb: the five documents have genuinely different shapes * and the help page's blocks change with the copy, so typed columns would mean * a migration per wording tweak. The shape is enforced by per-slug DTOs on * write instead. * * No rows are inserted here — `SupportContentSeeder` fills the table on first * boot and skips whenever it is non-empty, so a redeploy never overwrites * admin edits the way a migration-embedded INSERT eventually would. */ export class SupportContent3350000000000 implements MigrationInterface { name = "SupportContent3350000000000"; public async up(queryRunner: QueryRunner): Promise { await queryRunner.query(` CREATE TABLE IF NOT EXISTS freight.support_documents ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), slug varchar(32) NOT NULL, payload jsonb NOT NULL DEFAULT '{}'::jsonb, version integer NOT NULL DEFAULT 1, updated_by_id uuid, created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now(), deleted_at timestamptz ); `); await queryRunner.query(` CREATE UNIQUE INDEX IF NOT EXISTS uq_support_documents_slug ON freight.support_documents (slug); `); await queryRunner.query(` CREATE TABLE IF NOT EXISTS freight.support_document_versions ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), document_id uuid NOT NULL REFERENCES freight.support_documents(id) ON DELETE CASCADE, version integer NOT NULL, payload jsonb NOT NULL, actor_id uuid, note varchar(255), created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now(), deleted_at timestamptz ); `); // Closes the concurrent-save race: two editors saving at once cannot both // claim the same version number. await queryRunner.query(` CREATE UNIQUE INDEX IF NOT EXISTS uq_support_doc_version ON freight.support_document_versions (document_id, version); `); await queryRunner.query(` CREATE INDEX IF NOT EXISTS idx_support_doc_versions_document ON freight.support_document_versions (document_id); `); } public async down(queryRunner: QueryRunner): Promise { await queryRunner.query( `DROP TABLE IF EXISTS freight.support_document_versions;`, ); await queryRunner.query(`DROP TABLE IF EXISTS freight.support_documents;`); } }