gbmake-payload/scripts/fix-migrations.ts

212 lines
12 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Fix script: Re-insert historical migration records and apply new migration
* using a direct pg connection (no Payload init to avoid dev-mode push loops).
*
* Run with: pnpm tsx --env-file=.env scripts/fix-migrations.ts
*/
import { createRequire } from 'module'
const require = createRequire(import.meta.url)
const { Pool } = require(
'd:/Project/gbmake/gb-payload/node_modules/.pnpm/pg@8.16.3/node_modules/pg'
)
const pool = new Pool({
connectionString: process.env.DATABASE_URL ?? 'postgres://gb-payload:123123@localhost/gb-payload',
})
async function run(sql: string, params: any[] = []) {
const result = await pool.query(sql, params)
return result.rows
}
// ── Check current migration state ────────────────────────────────────────────
console.log('📋 Checking payload_migrations table...')
const existing = await run(`SELECT name FROM payload_migrations ORDER BY id`)
const existingNames = new Set(existing.map((r: any) => r.name))
console.log('Currently recorded:', existingNames.size > 0 ? [...existingNames] : '(none)')
// ── Mark all historical migrations as done ────────────────────────────────────
const historyMigrations = [
'20260208_171142',
'20260212_193303',
'20260212_202303',
'20260222_170233',
'hero_slider_simplify',
'product_recommendations_simplify',
]
for (const name of historyMigrations) {
if (!existingNames.has(name)) {
await run(
`INSERT INTO payload_migrations (name, batch, updated_at, created_at) VALUES ($1, 1, now(), now())`,
[name]
)
console.log(`✅ Marked done: ${name}`)
} else {
console.log(`⏭️ Already recorded: ${name}`)
}
}
// ── Skip if new migration already applied ─────────────────────────────────────
if (existingNames.has('20260223_disassembly_refactor')) {
console.log('\n⏭ Migration 20260223_disassembly_refactor already applied.')
await pool.end()
process.exit(0)
}
// ── Show what disassembly tables exist ───────────────────────────────────────
const disasmTables = await run(
`SELECT tablename FROM pg_tables WHERE schemaname='public' AND tablename LIKE 'disassembly%' ORDER BY tablename`
)
console.log('\nCurrent disassembly tables:', disasmTables.map((r: any) => r.tablename))
console.log('\n🔧 Applying: 20260223_disassembly_refactor ...')
try {
// 1. disassembly_components
await run(`CREATE TABLE IF NOT EXISTS disassembly_components (
id serial PRIMARY KEY NOT NULL,
label varchar NOT NULL,
start_coordinate_x numeric DEFAULT 0 NOT NULL,
start_coordinate_y numeric DEFAULT 0 NOT NULL,
start_radius numeric DEFAULT 20 NOT NULL,
updated_at timestamp(3) with time zone DEFAULT now() NOT NULL,
created_at timestamp(3) with time zone DEFAULT now() NOT NULL
)`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_components_updated_at_idx ON disassembly_components USING btree (updated_at)`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_components_created_at_idx ON disassembly_components USING btree (created_at)`)
console.log(' ✅ disassembly_components')
// 2. disassembly_linked_products
await run(`CREATE TABLE IF NOT EXISTS disassembly_linked_products (
id serial PRIMARY KEY NOT NULL,
coordinate_x numeric DEFAULT 0 NOT NULL,
coordinate_y numeric DEFAULT 0 NOT NULL,
product_name varchar,
updated_at timestamp(3) with time zone DEFAULT now() NOT NULL,
created_at timestamp(3) with time zone DEFAULT now() NOT NULL
)`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_linked_products_updated_at_idx ON disassembly_linked_products USING btree (updated_at)`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_linked_products_created_at_idx ON disassembly_linked_products USING btree (created_at)`)
console.log(' ✅ disassembly_linked_products')
// 3. disassembly_components_rels
await run(`CREATE TABLE IF NOT EXISTS disassembly_components_rels (
id serial PRIMARY KEY NOT NULL,
"order" integer,
parent_id integer NOT NULL,
path varchar NOT NULL,
disassembly_linked_products_id integer
)`)
await run(`DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'disassembly_components_rels_parent_fk') THEN
ALTER TABLE disassembly_components_rels ADD CONSTRAINT disassembly_components_rels_parent_fk
FOREIGN KEY (parent_id) REFERENCES disassembly_components(id) ON DELETE cascade;
END IF;
END $$`)
await run(`DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'disassembly_components_rels_disassembly_linked_products_fk') THEN
ALTER TABLE disassembly_components_rels ADD CONSTRAINT disassembly_components_rels_disassembly_linked_products_fk
FOREIGN KEY (disassembly_linked_products_id) REFERENCES disassembly_linked_products(id) ON DELETE cascade;
END IF;
END $$`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_components_rels_order_idx ON disassembly_components_rels USING btree ("order")`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_components_rels_parent_idx ON disassembly_components_rels USING btree (parent_id)`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_components_rels_path_idx ON disassembly_components_rels USING btree (path)`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_components_rels_disassembly_linked_products_id_idx ON disassembly_components_rels USING btree (disassembly_linked_products_id)`)
console.log(' ✅ disassembly_components_rels')
// 4. disassembly_linked_products_rels
await run(`CREATE TABLE IF NOT EXISTS disassembly_linked_products_rels (
id serial PRIMARY KEY NOT NULL,
"order" integer,
parent_id integer NOT NULL,
path varchar NOT NULL,
products_id integer,
preorder_products_id integer
)`)
await run(`DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'disassembly_linked_products_rels_parent_fk') THEN
ALTER TABLE disassembly_linked_products_rels ADD CONSTRAINT disassembly_linked_products_rels_parent_fk
FOREIGN KEY (parent_id) REFERENCES disassembly_linked_products(id) ON DELETE cascade;
END IF;
END $$`)
await run(`DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'disassembly_linked_products_rels_products_fk') THEN
ALTER TABLE disassembly_linked_products_rels ADD CONSTRAINT disassembly_linked_products_rels_products_fk
FOREIGN KEY (products_id) REFERENCES products(id) ON DELETE cascade;
END IF;
END $$`)
await run(`DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'disassembly_linked_products_rels_preorder_products_fk') THEN
ALTER TABLE disassembly_linked_products_rels ADD CONSTRAINT disassembly_linked_products_rels_preorder_products_fk
FOREIGN KEY (preorder_products_id) REFERENCES preorder_products(id) ON DELETE cascade;
END IF;
END $$`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_linked_products_rels_order_idx ON disassembly_linked_products_rels USING btree ("order")`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_linked_products_rels_parent_idx ON disassembly_linked_products_rels USING btree (parent_id)`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_linked_products_rels_path_idx ON disassembly_linked_products_rels USING btree (path)`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_linked_products_rels_products_id_idx ON disassembly_linked_products_rels USING btree (products_id)`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_linked_products_rels_preorder_products_id_idx ON disassembly_linked_products_rels USING btree (preorder_products_id)`)
console.log(' ✅ disassembly_linked_products_rels')
// 5. Update disassembly_pages_rels
await run(`ALTER TABLE disassembly_pages_rels DROP CONSTRAINT IF EXISTS disassembly_pages_rels_products_fk`)
await run(`ALTER TABLE disassembly_pages_rels DROP CONSTRAINT IF EXISTS disassembly_pages_rels_preorder_products_fk`)
await run(`DROP INDEX IF EXISTS disassembly_pages_rels_products_id_idx`)
await run(`DROP INDEX IF EXISTS disassembly_pages_rels_preorder_products_id_idx`)
const pc = await run(`SELECT 1 FROM information_schema.columns WHERE table_name='disassembly_pages_rels' AND column_name='products_id'`)
if (pc.length > 0) await run(`ALTER TABLE disassembly_pages_rels DROP COLUMN products_id`)
const prc = await run(`SELECT 1 FROM information_schema.columns WHERE table_name='disassembly_pages_rels' AND column_name='preorder_products_id'`)
if (prc.length > 0) await run(`ALTER TABLE disassembly_pages_rels DROP COLUMN preorder_products_id`)
await run(`ALTER TABLE disassembly_pages_rels ADD COLUMN IF NOT EXISTS disassembly_components_id integer`)
await run(`DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'disassembly_pages_rels_disassembly_components_fk') THEN
ALTER TABLE disassembly_pages_rels ADD CONSTRAINT disassembly_pages_rels_disassembly_components_fk
FOREIGN KEY (disassembly_components_id) REFERENCES disassembly_components(id) ON DELETE cascade;
END IF;
END $$`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_pages_rels_disassembly_components_id_idx ON disassembly_pages_rels USING btree (disassembly_components_id)`)
console.log(' ✅ disassembly_pages_rels updated')
// 6. Update payload_locked_documents_rels
await run(`ALTER TABLE payload_locked_documents_rels ADD COLUMN IF NOT EXISTS disassembly_components_id integer`)
await run(`ALTER TABLE payload_locked_documents_rels ADD COLUMN IF NOT EXISTS disassembly_linked_products_id integer`)
await run(`DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'payload_locked_documents_rels_disassembly_components_fk') THEN
ALTER TABLE payload_locked_documents_rels ADD CONSTRAINT payload_locked_documents_rels_disassembly_components_fk
FOREIGN KEY (disassembly_components_id) REFERENCES disassembly_components(id) ON DELETE cascade;
END IF;
END $$`)
await run(`DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'payload_locked_documents_rels_disassembly_linked_products_fk') THEN
ALTER TABLE payload_locked_documents_rels ADD CONSTRAINT payload_locked_documents_rels_disassembly_linked_products_fk
FOREIGN KEY (disassembly_linked_products_id) REFERENCES disassembly_linked_products(id) ON DELETE cascade;
END IF;
END $$`)
await run(`CREATE INDEX IF NOT EXISTS payload_locked_documents_rels_disassembly_components_id_idx ON payload_locked_documents_rels USING btree (disassembly_components_id)`)
await run(`CREATE INDEX IF NOT EXISTS payload_locked_documents_rels_disassembly_linked_products_id_idx ON payload_locked_documents_rels USING btree (disassembly_linked_products_id)`)
console.log(' ✅ payload_locked_documents_rels updated')
// 7. Drop old array tables
await run(`DROP TABLE IF EXISTS disassembly_pages_components_linked_products CASCADE`)
await run(`DROP TABLE IF EXISTS disassembly_pages_components CASCADE`)
console.log(' ✅ Old array tables dropped')
// 8. Record migration
await run(
`INSERT INTO payload_migrations (name, batch, updated_at, created_at) VALUES ($1, 2, now(), now())`,
['20260223_disassembly_refactor']
)
console.log('\n🎉 Migration 20260223_disassembly_refactor applied successfully!')
} catch (err: any) {
console.error('\n❌ Error:', err?.message ?? err)
await pool.end()
process.exit(1)
}
await pool.end()
process.exit(0)