/** * Phase 2 — game targeting + custom game spaces. * * custom_games: private, per-user named game systems. Cards, frames, and * (later) symbols can belong to one. * * custom_cards.game_target: 'custom' (default, standalone designs) or the * code of an existing system ('MTG', 'Pokemon', 'Lorcana', ...). * custom_cards.custom_game_id: set when the design belongs to a user's * custom game. */ export const up = (pgm) => { pgm.sql(` CREATE TABLE IF NOT EXISTS custom_games ( id SERIAL PRIMARY KEY, user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, name VARCHAR(100) NOT NULL, description TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, CONSTRAINT uq_custom_games_user_name UNIQUE (user_id, name) ) `); pgm.sql(` ALTER TABLE custom_cards ADD COLUMN IF NOT EXISTS game_target VARCHAR(50) NOT NULL DEFAULT 'custom', ADD COLUMN IF NOT EXISTS custom_game_id INTEGER REFERENCES custom_games(id) ON DELETE SET NULL `); pgm.sql(` CREATE INDEX IF NOT EXISTS idx_custom_cards_custom_game_id ON custom_cards(custom_game_id) `); }; export const down = (pgm) => { pgm.sql(` ALTER TABLE custom_cards DROP COLUMN IF EXISTS custom_game_id, DROP COLUMN IF EXISTS game_target `); pgm.sql(`DROP TABLE IF EXISTS custom_games CASCADE`); };