67 lines
4.3 KiB
JavaScript
67 lines
4.3 KiB
JavaScript
// Convert videos.id and slides.id (plus every FK that references them) from
|
|
// serial integers to UUID (gen_random_uuid).
|
|
//
|
|
// Safe for dev: truncates all video data first. Re-run the push script after
|
|
// migrating to re-ingest videos. shared_assets (asset library) is unchanged.
|
|
//
|
|
// This is a one-way migration. There is no meaningful down path.
|
|
|
|
const CHILD_TABLES = [
|
|
// table FK constraint name UNIQUE constraint name UNIQUE expression
|
|
['narration_segments', 'narration_segments_project_id_fkey', 'narration_segments_project_key_unique', '(project_id, segment_key)'],
|
|
['cutouts', 'cutouts_project_id_fkey', 'cutouts_project_name_unique', '(project_id, name)'],
|
|
['filter_chains', 'filter_chains_project_id_fkey', null, null],
|
|
['video_assets', 'video_assets_project_id_fkey', 'video_assets_project_key_unique', '(project_id, asset_key)'],
|
|
['audio_tracks', 'audio_tracks_project_id_fkey', 'audio_tracks_project_key_unique', '(project_id, track_key)'],
|
|
['citations', 'citations_project_id_fkey', null, null],
|
|
['project_sync', 'project_sync_project_id_fkey', 'project_sync_project_id_key', '(project_id)'],
|
|
['transcripts', 'transcripts_project_id_fkey', 'transcripts_project_source_unique', '(project_id, source_name)'],
|
|
];
|
|
|
|
exports.up = (pgm) => {
|
|
// ── Clear all video data ─────────────────────────────────────────────────
|
|
pgm.sql('TRUNCATE videos CASCADE');
|
|
|
|
// ── 1. Drop all FKs pointing at videos.id BEFORE touching the PK ────────
|
|
// slides
|
|
pgm.sql('ALTER TABLE slides DROP CONSTRAINT IF EXISTS slides_video_id_fkey');
|
|
pgm.sql('ALTER TABLE slides DROP CONSTRAINT IF EXISTS slides_video_id_gnommo_slide_id_unique');
|
|
// all other child tables
|
|
for (const [table, fkName, uniqueName] of CHILD_TABLES) {
|
|
pgm.sql(`ALTER TABLE ${table} DROP CONSTRAINT IF EXISTS ${fkName}`);
|
|
if (uniqueName) pgm.sql(`ALTER TABLE ${table} DROP CONSTRAINT IF EXISTS ${uniqueName}`);
|
|
}
|
|
|
|
// ── 2. videos.id: serial → uuid ─────────────────────────────────────────
|
|
pgm.sql('ALTER TABLE videos ALTER COLUMN id DROP DEFAULT');
|
|
pgm.sql('ALTER TABLE videos DROP CONSTRAINT videos_pkey');
|
|
pgm.sql('ALTER TABLE videos ALTER COLUMN id TYPE uuid USING gen_random_uuid()');
|
|
pgm.sql('ALTER TABLE videos ALTER COLUMN id SET DEFAULT gen_random_uuid()');
|
|
pgm.sql('ALTER TABLE videos ADD PRIMARY KEY (id)');
|
|
|
|
// ── 3. slides: video_id FK column, then id PK ───────────────────────────
|
|
pgm.sql('ALTER TABLE slides ALTER COLUMN video_id TYPE uuid USING gen_random_uuid()');
|
|
pgm.sql('ALTER TABLE slides ADD CONSTRAINT slides_video_id_gnommo_slide_id_unique UNIQUE (video_id, gnommo_slide_id)');
|
|
pgm.sql('ALTER TABLE slides ADD CONSTRAINT slides_video_id_fkey FOREIGN KEY (video_id) REFERENCES videos(id) ON DELETE CASCADE');
|
|
|
|
pgm.sql('ALTER TABLE slides ALTER COLUMN id DROP DEFAULT');
|
|
pgm.sql('ALTER TABLE slides DROP CONSTRAINT slides_pkey');
|
|
pgm.sql('ALTER TABLE slides ALTER COLUMN id TYPE uuid USING gen_random_uuid()');
|
|
pgm.sql('ALTER TABLE slides ALTER COLUMN id SET DEFAULT gen_random_uuid()');
|
|
pgm.sql('ALTER TABLE slides ADD PRIMARY KEY (id)');
|
|
|
|
// ── 4. All other child tables: project_id integer → uuid ────────────────
|
|
for (const [table, fkName, uniqueName, uniqueExpr] of CHILD_TABLES) {
|
|
pgm.sql(`ALTER TABLE ${table} ALTER COLUMN project_id TYPE uuid USING gen_random_uuid()`);
|
|
if (uniqueName && uniqueExpr) {
|
|
pgm.sql(`ALTER TABLE ${table} ADD CONSTRAINT ${uniqueName} UNIQUE ${uniqueExpr}`);
|
|
}
|
|
pgm.sql(`ALTER TABLE ${table} ADD CONSTRAINT ${fkName} FOREIGN KEY (project_id) REFERENCES videos(id) ON DELETE CASCADE`);
|
|
}
|
|
};
|
|
|
|
exports.down = () => {
|
|
// Intentionally empty — reversing uuid → serial would require re-sequencing
|
|
// all IDs and is not worth implementing for a dev-only migration.
|
|
};
|