import Database from "better-sqlite3"; import { drizzle } from "drizzle-orm/better-sqlite3"; import * as schema from "./schema"; import path from "path"; const DB_PATH = path.join(process.cwd(), "data", "bingo.db"); function getDb() { const sqlite = new Database(DB_PATH); sqlite.pragma("journal_mode = WAL"); sqlite.pragma("foreign_keys = ON"); return sqlite; } function initDatabase(sqlite: Database.Database) { sqlite.exec(` CREATE TABLE IF NOT EXISTS users ( id TEXT PRIMARY KEY, nickname TEXT UNIQUE NOT NULL, password_hash TEXT NOT NULL, is_admin INTEGER NOT NULL DEFAULT 0, created_at TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS sessions ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE, expires_at TEXT NOT NULL, created_at TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS campaigns ( id TEXT PRIMARY KEY, name TEXT NOT NULL, grid_size INTEGER NOT NULL DEFAULT 5, status TEXT NOT NULL DEFAULT 'active', created_by TEXT NOT NULL REFERENCES users(id), created_at TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS bingo_items ( id TEXT PRIMARY KEY, campaign_id TEXT NOT NULL REFERENCES campaigns(id) ON DELETE CASCADE, text TEXT NOT NULL, emoji TEXT NOT NULL DEFAULT '💀', sound_category TEXT NOT NULL DEFAULT 'horn', sound_url TEXT, grid_index INTEGER NOT NULL, created_at TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS marks ( id TEXT PRIMARY KEY, campaign_id TEXT NOT NULL REFERENCES campaigns(id) ON DELETE CASCADE, item_id TEXT NOT NULL REFERENCES bingo_items(id) ON DELETE CASCADE, user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE, created_at TEXT NOT NULL ); CREATE UNIQUE INDEX IF NOT EXISTS idx_campaign_item_pos ON bingo_items(campaign_id, grid_index); CREATE UNIQUE INDEX IF NOT EXISTS idx_unique_mark ON marks(campaign_id, item_id); `); try { sqlite.exec("ALTER TABLE bingo_items ADD COLUMN sound_url TEXT"); } catch {} } const sqlite = getDb(); initDatabase(sqlite); export const db = drizzle(sqlite, { schema });