-- +goose Up -- Per-game blocks of a disguised-robot opponent. A disguised robot is a shared pool -- account reused across games under different per-game names, so it must never go into -- `blocks` (that would make the same robot look blocked in the blocker's other games under -- other names, leaking that it is a bot, and show its pool name instead of the one seen). -- Each such block is recorded here against the specific game + seat, snapshotting the name -- the player saw, so the blocked list shows it as a distinct personality and the in-game -- card re-marks that one seat. The real robot account is never blocked, so the matchmaker -- leaves robots free. Unblocking deletes the row. SET search_path = backend, pg_catalog; CREATE TABLE robot_blocks ( id uuid PRIMARY KEY, blocker_id uuid NOT NULL REFERENCES accounts (account_id) ON DELETE CASCADE, game_id uuid NOT NULL REFERENCES games (game_id) ON DELETE CASCADE, seat smallint NOT NULL, robot_id uuid NOT NULL REFERENCES accounts (account_id) ON DELETE CASCADE, display_name text NOT NULL, created_at timestamptz NOT NULL DEFAULT now(), UNIQUE (blocker_id, game_id, seat) ); CREATE INDEX robot_blocks_blocker_idx ON robot_blocks (blocker_id); -- +goose Down SET search_path = backend, pg_catalog; DROP TABLE robot_blocks;