- game system selector: standalone, existing system (MTG/Pokemon/Lorcana/ SWU/FaB/One Piece/Sorcery/Grand Archive — codes match catalog imports), or a user's custom game - custom_games table + CRUD API (private per user, unique names) - /games hub with create form; /games/[id] space with rename, delete, card gallery, and ?game= deep-link into the designer - catalog twin resolves game: system code, custom game name, or 'Custom' - my-designs shows each design's game association - migration 1787693311000
45 lines
1.4 KiB
JavaScript
45 lines
1.4 KiB
JavaScript
/**
|
|
* 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`);
|
|
};
|