feat(01-02): design initial database schema migration
- 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>
This commit is contained in:
parent
aa07c0270d
commit
17dbfc6dc0
1 changed files with 439 additions and 0 deletions
439
internal/store/migrations/001_initial_schema.sql
Normal file
439
internal/store/migrations/001_initial_schema.sql
Normal file
|
|
@ -0,0 +1,439 @@
|
|||
-- 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);
|
||||
Loading…
Add table
Reference in a new issue