- 23 tables covering venue settings, chip sets, blind structures, payout structures, buy-in configs, tournament templates, tournaments, players, tables, seating, transactions, bubble prizes, audit trail, and operators - All financial columns use INTEGER (int64 cents, never REAL/FLOAT) - Audit trail append-only enforced by SQLite triggers (reject UPDATE except undone_by, reject DELETE) - All tournament-specific tables reference tournament_id for multi-tournament support - Comprehensive indexes on foreign keys and common query patterns - Players table with UUID PK for cross-venue portability Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
439 lines
18 KiB
SQL
439 lines
18 KiB
SQL
-- 001_initial_schema.sql
|
|
-- Phase 1: Complete tournament engine schema
|
|
-- All financial columns use INTEGER (int64 cents, never REAL/FLOAT)
|
|
-- All timestamps use INTEGER (Unix epoch seconds)
|
|
-- All UUIDs stored as TEXT
|
|
|
|
-- =============================================================================
|
|
-- Venue & Settings
|
|
-- =============================================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS venue_settings (
|
|
id INTEGER PRIMARY KEY CHECK (id = 1), -- singleton row
|
|
venue_name TEXT NOT NULL DEFAULT '',
|
|
currency_code TEXT NOT NULL DEFAULT 'DKK',
|
|
currency_symbol TEXT NOT NULL DEFAULT 'kr',
|
|
rounding_denomination INTEGER NOT NULL DEFAULT 5000, -- 50.00 kr in cents
|
|
receipt_mode TEXT NOT NULL DEFAULT 'digital' CHECK (receipt_mode IN ('off', 'digital', 'print', 'both')),
|
|
timezone TEXT NOT NULL DEFAULT 'Europe/Copenhagen',
|
|
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
updated_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
);
|
|
|
|
-- =============================================================================
|
|
-- Building Blocks (venue-level reusable)
|
|
-- =============================================================================
|
|
|
|
-- Chip Sets
|
|
CREATE TABLE IF NOT EXISTS chip_sets (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL,
|
|
is_builtin INTEGER NOT NULL DEFAULT 0,
|
|
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
updated_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS chip_denominations (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
chip_set_id INTEGER NOT NULL REFERENCES chip_sets(id) ON DELETE CASCADE,
|
|
value INTEGER NOT NULL, -- cents
|
|
color_hex TEXT NOT NULL DEFAULT '#FFFFFF',
|
|
label TEXT NOT NULL DEFAULT '',
|
|
sort_order INTEGER NOT NULL DEFAULT 0,
|
|
UNIQUE(chip_set_id, value)
|
|
);
|
|
|
|
-- Blind Structures
|
|
CREATE TABLE IF NOT EXISTS blind_structures (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL,
|
|
is_builtin INTEGER NOT NULL DEFAULT 0,
|
|
game_type_default TEXT NOT NULL DEFAULT 'nlhe',
|
|
notes TEXT NOT NULL DEFAULT '',
|
|
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
updated_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS blind_levels (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
structure_id INTEGER NOT NULL REFERENCES blind_structures(id) ON DELETE CASCADE,
|
|
position INTEGER NOT NULL, -- sort order
|
|
level_type TEXT NOT NULL DEFAULT 'round' CHECK (level_type IN ('round', 'break')),
|
|
game_type TEXT NOT NULL DEFAULT 'nlhe',
|
|
small_blind INTEGER NOT NULL DEFAULT 0,
|
|
big_blind INTEGER NOT NULL DEFAULT 0,
|
|
ante INTEGER NOT NULL DEFAULT 0,
|
|
bb_ante INTEGER NOT NULL DEFAULT 0,
|
|
duration_seconds INTEGER NOT NULL DEFAULT 900, -- 15 min default
|
|
chip_up_denomination_value INTEGER, -- nullable, cents
|
|
notes TEXT NOT NULL DEFAULT '',
|
|
UNIQUE(structure_id, position)
|
|
);
|
|
|
|
-- Payout Structures
|
|
CREATE TABLE IF NOT EXISTS payout_structures (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL,
|
|
is_builtin INTEGER NOT NULL DEFAULT 0,
|
|
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
updated_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS payout_brackets (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
structure_id INTEGER NOT NULL REFERENCES payout_structures(id) ON DELETE CASCADE,
|
|
min_entries INTEGER NOT NULL,
|
|
max_entries INTEGER NOT NULL,
|
|
CHECK (min_entries <= max_entries)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS payout_tiers (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
bracket_id INTEGER NOT NULL REFERENCES payout_brackets(id) ON DELETE CASCADE,
|
|
position INTEGER NOT NULL,
|
|
percentage_basis_points INTEGER NOT NULL, -- e.g. 5000 = 50.00%
|
|
UNIQUE(bracket_id, position)
|
|
);
|
|
|
|
-- Buy-in Configs
|
|
CREATE TABLE IF NOT EXISTS buyin_configs (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL,
|
|
buyin_amount INTEGER NOT NULL DEFAULT 0, -- cents
|
|
starting_chips INTEGER NOT NULL DEFAULT 0,
|
|
rake_total INTEGER NOT NULL DEFAULT 0, -- cents
|
|
bounty_amount INTEGER NOT NULL DEFAULT 0, -- cents
|
|
bounty_chip INTEGER NOT NULL DEFAULT 0,
|
|
rebuy_allowed INTEGER NOT NULL DEFAULT 0,
|
|
rebuy_cost INTEGER NOT NULL DEFAULT 0, -- cents
|
|
rebuy_chips INTEGER NOT NULL DEFAULT 0,
|
|
rebuy_rake INTEGER NOT NULL DEFAULT 0, -- cents
|
|
rebuy_limit INTEGER NOT NULL DEFAULT 0, -- 0 = unlimited
|
|
rebuy_level_cutoff INTEGER, -- nullable
|
|
rebuy_time_cutoff_seconds INTEGER, -- nullable
|
|
rebuy_chip_threshold INTEGER, -- nullable
|
|
addon_allowed INTEGER NOT NULL DEFAULT 0,
|
|
addon_cost INTEGER NOT NULL DEFAULT 0, -- cents
|
|
addon_chips INTEGER NOT NULL DEFAULT 0,
|
|
addon_rake INTEGER NOT NULL DEFAULT 0, -- cents
|
|
addon_level_start INTEGER, -- nullable
|
|
addon_level_end INTEGER, -- nullable
|
|
reentry_allowed INTEGER NOT NULL DEFAULT 0,
|
|
reentry_limit INTEGER NOT NULL DEFAULT 0,
|
|
late_reg_level_cutoff INTEGER, -- nullable
|
|
late_reg_time_cutoff_seconds INTEGER, -- nullable
|
|
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
updated_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS rake_splits (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
buyin_config_id INTEGER NOT NULL REFERENCES buyin_configs(id) ON DELETE CASCADE,
|
|
category TEXT NOT NULL CHECK (category IN ('house', 'staff', 'league', 'season_reserve')),
|
|
amount INTEGER NOT NULL DEFAULT 0, -- cents
|
|
UNIQUE(buyin_config_id, category)
|
|
);
|
|
|
|
-- Points Formulas
|
|
CREATE TABLE IF NOT EXISTS points_formulas (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL,
|
|
expression TEXT NOT NULL DEFAULT '',
|
|
variables TEXT NOT NULL DEFAULT '{}', -- JSON
|
|
is_builtin INTEGER NOT NULL DEFAULT 0,
|
|
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
updated_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
);
|
|
|
|
-- =============================================================================
|
|
-- Tournament Templates
|
|
-- =============================================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS tournament_templates (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL,
|
|
description TEXT NOT NULL DEFAULT '',
|
|
chip_set_id INTEGER NOT NULL REFERENCES chip_sets(id),
|
|
blind_structure_id INTEGER NOT NULL REFERENCES blind_structures(id),
|
|
payout_structure_id INTEGER NOT NULL REFERENCES payout_structures(id),
|
|
buyin_config_id INTEGER NOT NULL REFERENCES buyin_configs(id),
|
|
points_formula_id INTEGER REFERENCES points_formulas(id), -- nullable
|
|
min_players INTEGER NOT NULL DEFAULT 2,
|
|
max_players INTEGER, -- nullable
|
|
early_signup_bonus_chips INTEGER NOT NULL DEFAULT 0,
|
|
early_signup_cutoff TEXT, -- nullable, datetime or player count
|
|
punctuality_bonus_chips INTEGER NOT NULL DEFAULT 0,
|
|
is_pko INTEGER NOT NULL DEFAULT 0,
|
|
is_builtin INTEGER NOT NULL DEFAULT 0,
|
|
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
updated_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
);
|
|
|
|
-- =============================================================================
|
|
-- Tournaments (runtime instances)
|
|
-- =============================================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS tournaments (
|
|
id TEXT PRIMARY KEY, -- UUID
|
|
name TEXT NOT NULL,
|
|
template_id INTEGER REFERENCES tournament_templates(id), -- nullable, reference only
|
|
|
|
-- Copied config (local changes don't affect template)
|
|
chip_set_id INTEGER NOT NULL REFERENCES chip_sets(id),
|
|
blind_structure_id INTEGER NOT NULL REFERENCES blind_structures(id),
|
|
payout_structure_id INTEGER NOT NULL REFERENCES payout_structures(id),
|
|
buyin_config_id INTEGER NOT NULL REFERENCES buyin_configs(id),
|
|
points_formula_id INTEGER REFERENCES points_formulas(id), -- nullable
|
|
|
|
status TEXT NOT NULL DEFAULT 'created' CHECK (status IN (
|
|
'created', 'registering', 'running', 'paused',
|
|
'final_table', 'completed', 'cancelled'
|
|
)),
|
|
|
|
min_players INTEGER NOT NULL DEFAULT 2,
|
|
max_players INTEGER, -- nullable
|
|
early_signup_bonus_chips INTEGER NOT NULL DEFAULT 0,
|
|
early_signup_cutoff TEXT, -- nullable
|
|
punctuality_bonus_chips INTEGER NOT NULL DEFAULT 0,
|
|
is_pko INTEGER NOT NULL DEFAULT 0,
|
|
|
|
-- Runtime state
|
|
current_level INTEGER NOT NULL DEFAULT 0,
|
|
clock_state TEXT NOT NULL DEFAULT 'stopped' CHECK (clock_state IN ('stopped', 'running', 'paused')),
|
|
clock_remaining_ns INTEGER NOT NULL DEFAULT 0,
|
|
total_elapsed_ns INTEGER NOT NULL DEFAULT 0,
|
|
hand_for_hand INTEGER NOT NULL DEFAULT 0,
|
|
|
|
started_at INTEGER, -- nullable
|
|
ended_at INTEGER, -- nullable
|
|
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
updated_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
);
|
|
|
|
-- =============================================================================
|
|
-- Players
|
|
-- =============================================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS players (
|
|
id TEXT PRIMARY KEY, -- UUID
|
|
name TEXT NOT NULL,
|
|
nickname TEXT,
|
|
email TEXT,
|
|
phone TEXT,
|
|
photo_url TEXT,
|
|
notes TEXT,
|
|
custom_fields TEXT, -- JSON
|
|
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
updated_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS tournament_players (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
tournament_id TEXT NOT NULL REFERENCES tournaments(id) ON DELETE CASCADE,
|
|
player_id TEXT NOT NULL REFERENCES players(id),
|
|
status TEXT NOT NULL DEFAULT 'registered' CHECK (status IN (
|
|
'registered', 'active', 'busted', 'deal'
|
|
)),
|
|
|
|
seat_table_id INTEGER REFERENCES tables(id), -- nullable
|
|
seat_position INTEGER, -- nullable
|
|
|
|
buy_in_at INTEGER, -- nullable
|
|
bust_out_at INTEGER, -- nullable
|
|
bust_out_order INTEGER, -- nullable, position when busted
|
|
finishing_position INTEGER, -- nullable, final position
|
|
|
|
current_chips INTEGER NOT NULL DEFAULT 0,
|
|
rebuys INTEGER NOT NULL DEFAULT 0,
|
|
addons INTEGER NOT NULL DEFAULT 0,
|
|
reentries INTEGER NOT NULL DEFAULT 0,
|
|
bounty_value INTEGER NOT NULL DEFAULT 0, -- cents, for PKO
|
|
bounties_collected INTEGER NOT NULL DEFAULT 0,
|
|
prize_amount INTEGER NOT NULL DEFAULT 0, -- cents
|
|
points_awarded INTEGER NOT NULL DEFAULT 0,
|
|
|
|
early_signup_bonus_applied INTEGER NOT NULL DEFAULT 0,
|
|
punctuality_bonus_applied INTEGER NOT NULL DEFAULT 0,
|
|
hitman_player_id TEXT REFERENCES players(id), -- nullable, who busted them
|
|
|
|
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
updated_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
|
|
UNIQUE(tournament_id, player_id)
|
|
);
|
|
|
|
-- =============================================================================
|
|
-- Tables & Seating
|
|
-- =============================================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS tables (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
tournament_id TEXT NOT NULL REFERENCES tournaments(id) ON DELETE CASCADE,
|
|
name TEXT NOT NULL,
|
|
seat_count INTEGER NOT NULL DEFAULT 9 CHECK (seat_count >= 6 AND seat_count <= 10),
|
|
dealer_button_position INTEGER, -- nullable
|
|
is_active INTEGER NOT NULL DEFAULT 1,
|
|
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
updated_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS table_blueprints (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL,
|
|
table_configs TEXT NOT NULL DEFAULT '[]', -- JSON array of {name, seat_count}
|
|
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
updated_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS balance_suggestions (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
tournament_id TEXT NOT NULL REFERENCES tournaments(id) ON DELETE CASCADE,
|
|
status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN (
|
|
'pending', 'accepted', 'cancelled', 'expired'
|
|
)),
|
|
from_table_id INTEGER NOT NULL REFERENCES tables(id),
|
|
to_table_id INTEGER NOT NULL REFERENCES tables(id),
|
|
player_id TEXT REFERENCES players(id), -- nullable
|
|
from_seat INTEGER, -- nullable
|
|
to_seat INTEGER, -- nullable
|
|
reason TEXT NOT NULL DEFAULT '',
|
|
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
resolved_at INTEGER -- nullable
|
|
);
|
|
|
|
-- =============================================================================
|
|
-- Financial Transactions
|
|
-- =============================================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS transactions (
|
|
id TEXT PRIMARY KEY, -- UUID
|
|
tournament_id TEXT NOT NULL REFERENCES tournaments(id) ON DELETE CASCADE,
|
|
player_id TEXT NOT NULL REFERENCES players(id),
|
|
type TEXT NOT NULL CHECK (type IN (
|
|
'buyin', 'rebuy', 'addon', 'reentry',
|
|
'bounty_collected', 'bounty_paid',
|
|
'payout', 'rake', 'chop', 'bubble_prize'
|
|
)),
|
|
amount INTEGER NOT NULL DEFAULT 0, -- cents
|
|
chips INTEGER NOT NULL DEFAULT 0, -- chips given/removed
|
|
operator_id TEXT NOT NULL, -- who performed the action
|
|
receipt_data TEXT, -- nullable, JSON
|
|
undone INTEGER NOT NULL DEFAULT 0,
|
|
undone_by TEXT, -- nullable, FK audit_entries.id
|
|
metadata TEXT, -- nullable, JSON (bounty chain, chop details, etc)
|
|
created_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS bubble_prizes (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
tournament_id TEXT NOT NULL REFERENCES tournaments(id) ON DELETE CASCADE,
|
|
amount INTEGER NOT NULL DEFAULT 0, -- cents
|
|
funded_from TEXT NOT NULL DEFAULT '[]', -- JSON array of {position, reduction_amount}
|
|
status TEXT NOT NULL DEFAULT 'proposed' CHECK (status IN (
|
|
'proposed', 'confirmed', 'cancelled'
|
|
)),
|
|
created_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
);
|
|
|
|
-- =============================================================================
|
|
-- Audit Trail (append-only)
|
|
-- =============================================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS audit_entries (
|
|
id TEXT PRIMARY KEY, -- UUID
|
|
tournament_id TEXT, -- nullable, some are venue-level
|
|
timestamp INTEGER NOT NULL DEFAULT (unixepoch()), -- UnixNano in Go, epoch seconds in SQL default
|
|
operator_id TEXT NOT NULL,
|
|
action TEXT NOT NULL, -- e.g. 'player.bust', 'financial.buyin', 'clock.pause', 'seat.move'
|
|
target_type TEXT NOT NULL DEFAULT '',
|
|
target_id TEXT NOT NULL DEFAULT '',
|
|
previous_state TEXT, -- JSON
|
|
new_state TEXT, -- JSON
|
|
metadata TEXT, -- nullable, JSON
|
|
undone_by TEXT -- nullable, references audit_entries.id
|
|
-- NO UPDATE OR DELETE -- enforced by triggers below
|
|
);
|
|
|
|
-- Tamper protection: REJECT any UPDATE except setting undone_by on a row where undone_by is currently NULL
|
|
CREATE TRIGGER IF NOT EXISTS audit_entries_no_update
|
|
BEFORE UPDATE ON audit_entries
|
|
WHEN OLD.undone_by IS NOT NULL OR NEW.undone_by IS NULL
|
|
OR OLD.id != NEW.id OR OLD.timestamp != NEW.timestamp
|
|
OR OLD.operator_id != NEW.operator_id OR OLD.action != NEW.action
|
|
BEGIN
|
|
SELECT RAISE(ABORT, 'audit_entries is append-only: only undone_by may be set once');
|
|
END;
|
|
|
|
-- Tamper protection: REJECT any DELETE on audit_entries entirely
|
|
CREATE TRIGGER IF NOT EXISTS audit_entries_no_delete
|
|
BEFORE DELETE ON audit_entries
|
|
BEGIN
|
|
SELECT RAISE(ABORT, 'audit_entries is append-only: deletion is prohibited');
|
|
END;
|
|
|
|
-- =============================================================================
|
|
-- Operators
|
|
-- =============================================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS operators (
|
|
id TEXT PRIMARY KEY, -- UUID
|
|
name TEXT NOT NULL,
|
|
pin_hash TEXT NOT NULL, -- bcrypt
|
|
role TEXT NOT NULL DEFAULT 'floor' CHECK (role IN ('admin', 'floor', 'viewer')),
|
|
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
updated_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
);
|
|
|
|
-- =============================================================================
|
|
-- Indexes
|
|
-- =============================================================================
|
|
|
|
-- Tournament players: active player lookups and rankings
|
|
CREATE INDEX IF NOT EXISTS idx_tournament_players_tournament_status
|
|
ON tournament_players(tournament_id, status);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_tournament_players_tournament_bust_order
|
|
ON tournament_players(tournament_id, bust_out_order);
|
|
|
|
-- Transactions: financial summaries and player history
|
|
CREATE INDEX IF NOT EXISTS idx_transactions_tournament_type
|
|
ON transactions(tournament_id, type);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_transactions_tournament_player
|
|
ON transactions(tournament_id, player_id);
|
|
|
|
-- Audit entries: log browsing and action filtering
|
|
CREATE INDEX IF NOT EXISTS idx_audit_entries_tournament_timestamp
|
|
ON audit_entries(tournament_id, timestamp);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_audit_entries_action
|
|
ON audit_entries(action);
|
|
|
|
-- Tables: active table lookups per tournament
|
|
CREATE INDEX IF NOT EXISTS idx_tables_tournament_active
|
|
ON tables(tournament_id, is_active);
|
|
|
|
-- Foreign key indexes on child tables
|
|
CREATE INDEX IF NOT EXISTS idx_chip_denominations_chip_set
|
|
ON chip_denominations(chip_set_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_blind_levels_structure
|
|
ON blind_levels(structure_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_payout_brackets_structure
|
|
ON payout_brackets(structure_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_payout_tiers_bracket
|
|
ON payout_tiers(bracket_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_rake_splits_buyin_config
|
|
ON rake_splits(buyin_config_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_balance_suggestions_tournament
|
|
ON balance_suggestions(tournament_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_bubble_prizes_tournament
|
|
ON bubble_prizes(tournament_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_tournament_players_player
|
|
ON tournament_players(player_id);
|