'use strict'; // Supports the new advertisement creation wizard: // - content_mode: "image" (image only) vs "content" (badge/headline/ // description/CTAs alongside the image) — an explicit admin choice, // decoupled from placement/format. Added as STRING + an explicit CHECK // constraint (addColumn can't create a native enum type on this // CockroachDB instance, unlike createTable) — matching the pattern used // in 20260710000001-add-status-to-courses.js. The Sequelize model still // declares it as DataTypes.ENUM for app-level validation; the column // itself is a plain string. // - redirect_link: where the ad as a whole links to when clicked with no // CTA of its own (banners/full-image ads have no CTA row). // - landing_page: when no redirect_link is given, an internally-authored // landing page (title/description/body/links) the ad's own click-through // resolves to instead (see GET /api/client/advertisements/uuid/:uuid and // the /ads/:uuid client route). module.exports = { async up(queryInterface, Sequelize) { await queryInterface.addColumn('advertisements', 'content_mode', { type: Sequelize.STRING, allowNull: false, defaultValue: 'image', }); await queryInterface.sequelize.query(` ALTER TABLE advertisements ADD CONSTRAINT check_content_mode CHECK (content_mode IN ('image', 'content')) `); await queryInterface.addColumn('advertisements', 'redirect_link', { type: Sequelize.STRING(512), allowNull: true, }); await queryInterface.addColumn('advertisements', 'landing_page', { type: Sequelize.JSONB, allowNull: true, }); // Existing rows already have real content (headline/description/ctas) — // treat them as "content" mode rather than defaulting to "image". await queryInterface.sequelize.query(` UPDATE advertisements SET content_mode = 'content' WHERE headline IS NOT NULL AND headline <> '' `); }, async down(queryInterface) { await queryInterface.removeColumn('advertisements', 'landing_page'); await queryInterface.removeColumn('advertisements', 'redirect_link'); await queryInterface.sequelize.query(`ALTER TABLE advertisements DROP CONSTRAINT IF EXISTS check_content_mode`); await queryInterface.removeColumn('advertisements', 'content_mode'); }, };