feat: implement admin dashboard with site settings, user management, and activity monitoring

This commit is contained in:
LaurensBartelds committed 2026-04-22 23:28:40 +02:00
1 parent c4c1e1a45a
commit 53abe32795
12 files changed
+1226 -18

No files matched your search

+37
View File
@@ -7,6 +7,7 @@ export function runMigrations(db: Database.Database): void {
email TEXT UNIQUE NOT NULL,
password_hash TEXT NOT NULL,
display_name TEXT NOT NULL,
role TEXT NOT NULL DEFAULT 'user',
email_verified INTEGER DEFAULT 0,
verify_token TEXT,
verify_expires INTEGER,
@@ -42,7 +43,43 @@ export function runMigrations(db: Database.Database): void {
completed_at INTEGER DEFAULT (unixepoch())
);
CREATE TABLE IF NOT EXISTS site_settings (
key TEXT PRIMARY KEY,
value TEXT NOT NULL,
updated_at INTEGER DEFAULT (unixepoch())
);
CREATE INDEX IF NOT EXISTS idx_saved_exams_user ON saved_exams(user_id);
CREATE INDEX IF NOT EXISTS idx_exam_results_user ON exam_results(user_id);
`)
// ── Add role column if missing (existing databases) ──
const cols = db.prepare(`PRAGMA table_info(users)`).all() as { name: string }[]
if (!cols.some(c => c.name === 'role')) {
db.exec(`ALTER TABLE users ADD COLUMN role TEXT NOT NULL DEFAULT 'user'`)
}
// ── Promote first user to admin if no admins exist ──
const adminCount = db.prepare(`SELECT COUNT(*) AS cnt FROM users WHERE role = 'admin'`).get() as { cnt: number }
if (adminCount.cnt === 0) {
db.prepare(`UPDATE users SET role = 'admin' WHERE id = (SELECT MIN(id) FROM users)`).run()
}
// ── Seed default settings ──
const defaults: Record<string, string> = {
site_name: 'BrainWave',
max_upload_mb: '5',
allow_guest_mode: 'true',
registration_enabled: 'true',
default_theme: 'light',
maintenance_mode: 'false',
maintenance_message: 'We are currently performing maintenance. Please check back soon.',
}
const upsert = db.prepare(`
INSERT INTO site_settings (key, value) VALUES (?, ?)
ON CONFLICT(key) DO NOTHING
`)
for (const [key, value] of Object.entries(defaults)) {
upsert.run(key, value)
}
}