'use strict'; const path = require('path'); const fs = require('fs'); const Database = require('better-sqlite3'); const bcrypt = require('bcryptjs'); const DB_PATH = process.env.DB_PATH || path.join(__dirname, 'bowler.db'); const SCHEMA_PATH = path.join(__dirname, 'schema.sql'); const db = new Database(DB_PATH); db.pragma('journal_mode = WAL'); db.pragma('foreign_keys = ON'); // Apply schema (idempotent — all statements use IF NOT EXISTS). db.exec(fs.readFileSync(SCHEMA_PATH, 'utf8')); /** * First-run seed: if there are no users yet, create the admin from env vars * and a sensible default color scheme. */ function seed() { const userCount = db.prepare('SELECT COUNT(*) AS n FROM users').get().n; if (userCount > 0) return; const schemeCount = db.prepare('SELECT COUNT(*) AS n FROM color_schemes').get().n; let defaultSchemeId; if (schemeCount === 0) { const info = db .prepare( `INSERT INTO color_schemes (name, seed_color, mode, is_default) VALUES (@name, @seed_color, @mode, 1)` ) .run({ name: 'Default', seed_color: '#1565c0', mode: 'light' }); defaultSchemeId = info.lastInsertRowid; // A second scheme so the picker has something to toggle out of the box. db.prepare( `INSERT INTO color_schemes (name, seed_color, mode, is_default) VALUES (@name, @seed_color, @mode, 0)` ).run({ name: 'Midnight', seed_color: '#7e57c2', mode: 'dark' }); } else { defaultSchemeId = db .prepare('SELECT id FROM color_schemes ORDER BY is_default DESC, id ASC LIMIT 1') .get().id; } const username = process.env.ADMIN_USERNAME || 'admin'; const password = process.env.ADMIN_PASSWORD || 'change-me'; const email = process.env.ADMIN_EMAIL || null; const hash = bcrypt.hashSync(password, 10); db.prepare( `INSERT INTO users (username, email, password_hash, role, preferred_scheme_id, active) VALUES (@username, @email, @hash, 'admin', @scheme, 1)` ).run({ username, email, hash, scheme: defaultSchemeId }); console.log(`[seed] Created admin user "${username}" and default color schemes.`); } seed(); module.exports = db;