import { MigrationInterface, QueryRunner } from "typeorm"; /** * Converts the HELP document from its original fixed-block shape * (`video` / `chat` / `channels` / `topics` / `checklist`) to the free-form * `sections[]` builder, where every block is a heading plus markdown plus * attached media. * * Only rows still in the old shape are touched — detected by the presence of a * `channels` key — so this is a no-op on any environment seeded after the * change, and re-running it does nothing. * * The payload literal is inlined rather than imported from * `SUPPORT_CONTENT_DEFAULTS`: a migration must keep doing the same thing * forever, and that constant will keep moving. * * The rewrite also bumps `version` and writes a matching history row. The live * row's version always having a matching entry in * `support_document_versions` is the invariant the history list and rollback * both depend on, and a silent payload swap would break it. */ const HELP_SECTIONS = [ { id: "help-walkthrough", heading: "Portal walkthrough", body: "A guided tour of the portal — registering your company, raising a booking against a contract, and settling an invoice.", media: [ { id: "help-walkthrough-video", kind: "video", src: "/assets/edr-portal-guide.webm", caption: null, }, ], }, { id: "help-chat", heading: "Chat with our team", body: "Signed-in customers can open a support conversation from the headset button at the bottom right of every portal page. You can send screenshots and documents in the chat, and replies appear there and as a notification.\n\n[Open the portal](/portal)", media: [], }, { id: "help-contact", heading: "Contact us", body: "- **Email** — [{{supportEmail}}](mailto:{{supportEmail}}). Best for document issues and anything needing an attachment.\n- **Phone** — [{{supportPhone}}](tel:{{supportPhoneTel}}). Best for urgent problems with cargo already in transit.\n- **Head office** — {{supportOffice}}. Walk-in support during working hours.\n- **Support hours** — {{supportHours}}. Outside these hours, email us and we reply the next working day.", media: [], }, { id: "help-topics", heading: "Common topics", body: "- **[Account & onboarding](/faq)** — registering your company, uploading your trade licence and TIN, and getting an operational profile approved.\n- **[Contracts](/faq)** — requesting a freight contract, reviewing its terms and signing it with your saved signature and stamp.\n- **[Bookings & tracking](/faq)** — raising a booking against a contract, adding last-mile transport and following the consignment along the corridor.\n- **[Invoices & payments](/faq)** — finding invoices, paying through the bank channels and confirming a payment that has not yet settled.", media: [], }, { id: "help-checklist", heading: "What to include when you contact us", body: "- Your company name and the email you sign in with.\n- The reference of the contract, booking or invoice involved.\n- What you expected to happen and what happened instead.\n- A screenshot of any error message the portal showed.", media: [], }, ]; export class SupportHelpSections3360000000000 implements MigrationInterface { name = "SupportHelpSections3360000000000"; public async up(queryRunner: QueryRunner): Promise { const rows: { id: string; version: number; payload: Record }[] = await queryRunner.query(` SELECT id, version, payload FROM freight.support_documents WHERE slug = 'HELP' AND payload ? 'channels' `); for (const row of rows) { const payload = { title: row.payload.title ?? "Help & Support", subtitle: row.payload.subtitle ?? "Get answers fast — watch the walkthrough, browse the common topics, check the FAQ, or reach our team directly.", sections: HELP_SECTIONS, }; const version = row.version + 1; await queryRunner.query( `UPDATE freight.support_documents SET payload = $1::jsonb, version = $2, updated_at = now() WHERE id = $3`, [JSON.stringify(payload), version, row.id], ); await queryRunner.query( `INSERT INTO freight.support_document_versions (document_id, version, payload, actor_id, note) VALUES ($1, $2, $3::jsonb, NULL, $4)`, [ row.id, version, JSON.stringify(payload), "Converted help page to free-form sections", ], ); } } /** * Not reversible: the old fixed blocks cannot be recovered from markdown * sections an editor may since have rewritten. The version history holds the * pre-conversion payload if it is ever genuinely needed. */ public async down(): Promise { // no-op } }