5432734240
Players can now opt into a Skins side game when creating a BBB round. The side game uses the same skins settings (carryover, net/gross, skin value, double back nine). The scorecard gains a third Skins tab during play and on the summary; the BBB leaderboard continues to rank by BBB points. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
137 lines
5.2 KiB
Python
137 lines
5.2 KiB
Python
import os
|
|
import aiosqlite
|
|
|
|
DATABASE_PATH = os.getenv("DATABASE_PATH", "/data/skinspins.db")
|
|
|
|
|
|
async def get_db():
|
|
async with aiosqlite.connect(DATABASE_PATH) as db:
|
|
db.row_factory = aiosqlite.Row
|
|
yield db
|
|
|
|
|
|
async def init_db():
|
|
async with aiosqlite.connect(DATABASE_PATH) as db:
|
|
await db.executescript("""
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
id TEXT PRIMARY KEY,
|
|
email TEXT UNIQUE NOT NULL,
|
|
name TEXT,
|
|
handicap REAL,
|
|
avatar TEXT,
|
|
is_onboarded INTEGER NOT NULL DEFAULT 0,
|
|
created_at TEXT NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS invitations (
|
|
id TEXT PRIMARY KEY,
|
|
email TEXT UNIQUE NOT NULL,
|
|
invited_by TEXT NOT NULL,
|
|
created_at TEXT NOT NULL,
|
|
FOREIGN KEY (invited_by) REFERENCES users(id)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS magic_link_tokens (
|
|
id TEXT PRIMARY KEY,
|
|
email TEXT NOT NULL,
|
|
token TEXT UNIQUE NOT NULL,
|
|
expires_at TEXT NOT NULL,
|
|
used_at TEXT
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS sessions (
|
|
id TEXT PRIMARY KEY,
|
|
user_id TEXT NOT NULL,
|
|
token TEXT UNIQUE NOT NULL,
|
|
expires_at TEXT NOT NULL,
|
|
created_at TEXT NOT NULL,
|
|
FOREIGN KEY (user_id) REFERENCES users(id)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS courses (
|
|
id TEXT PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
holes INTEGER NOT NULL DEFAULT 18,
|
|
location TEXT,
|
|
created_at TEXT NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS course_holes (
|
|
id TEXT PRIMARY KEY,
|
|
course_id TEXT NOT NULL,
|
|
hole_number INTEGER NOT NULL,
|
|
par INTEGER NOT NULL DEFAULT 4,
|
|
UNIQUE (course_id, hole_number),
|
|
FOREIGN KEY (course_id) REFERENCES courses(id)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS course_tees (
|
|
id TEXT PRIMARY KEY,
|
|
course_id TEXT NOT NULL,
|
|
name TEXT NOT NULL,
|
|
slope INTEGER NOT NULL,
|
|
rating REAL NOT NULL,
|
|
FOREIGN KEY (course_id) REFERENCES courses(id)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS games (
|
|
id TEXT PRIMARY KEY,
|
|
format TEXT NOT NULL DEFAULT 'bingo_bango_bongo',
|
|
holes_count INTEGER NOT NULL,
|
|
status TEXT NOT NULL DEFAULT 'lobby',
|
|
created_by TEXT NOT NULL,
|
|
created_at TEXT NOT NULL,
|
|
course_id TEXT,
|
|
FOREIGN KEY (created_by) REFERENCES users(id),
|
|
FOREIGN KEY (course_id) REFERENCES courses(id)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS game_players (
|
|
id TEXT PRIMARY KEY,
|
|
game_id TEXT NOT NULL,
|
|
user_id TEXT NOT NULL,
|
|
handicap_snapshot REAL,
|
|
joined_at TEXT NOT NULL,
|
|
UNIQUE (game_id, user_id),
|
|
FOREIGN KEY (game_id) REFERENCES games(id),
|
|
FOREIGN KEY (user_id) REFERENCES users(id)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS hole_scores (
|
|
id TEXT PRIMARY KEY,
|
|
game_id TEXT NOT NULL,
|
|
hole_number INTEGER NOT NULL,
|
|
user_id TEXT NOT NULL,
|
|
strokes INTEGER,
|
|
bingo INTEGER NOT NULL DEFAULT 0,
|
|
bango REAL NOT NULL DEFAULT 0.0,
|
|
bongo INTEGER NOT NULL DEFAULT 0,
|
|
updated_by TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
UNIQUE (game_id, hole_number, user_id),
|
|
FOREIGN KEY (game_id) REFERENCES games(id),
|
|
FOREIGN KEY (user_id) REFERENCES users(id),
|
|
FOREIGN KEY (updated_by) REFERENCES users(id)
|
|
);
|
|
""")
|
|
await db.commit()
|
|
# Migrations for columns added after initial release
|
|
for migration in [
|
|
"ALTER TABLE games ADD COLUMN course_id TEXT REFERENCES courses(id)",
|
|
"ALTER TABLE game_players ADD COLUMN tee_id TEXT REFERENCES course_tees(id)",
|
|
"ALTER TABLE course_holes ADD COLUMN stroke_index INTEGER",
|
|
"ALTER TABLE games ADD COLUMN carryover INTEGER NOT NULL DEFAULT 1",
|
|
"ALTER TABLE game_players ADD COLUMN playing_handicap INTEGER",
|
|
"ALTER TABLE game_players ADD COLUMN strokes_allocation TEXT",
|
|
"ALTER TABLE magic_link_tokens ADD COLUMN code TEXT",
|
|
"ALTER TABLE games ADD COLUMN skin_value REAL",
|
|
"ALTER TABLE games ADD COLUMN skin_double_back_nine INTEGER NOT NULL DEFAULT 0",
|
|
"ALTER TABLE games ADD COLUMN skins_net INTEGER NOT NULL DEFAULT 0",
|
|
"ALTER TABLE games ADD COLUMN side_skins_enabled INTEGER NOT NULL DEFAULT 0",
|
|
]:
|
|
try:
|
|
await db.execute(migration)
|
|
await db.commit()
|
|
except Exception:
|
|
pass # column already exists
|