bowler-chart/db/index.js

63 lines
2.1 KiB
JavaScript

'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;