Public Access
feat: implement admin dashboard with site settings, user management, and activity monitoring
This commit is contained in:
1 parent
c4c1e1a45a
commit
53abe32795
12 files changed
+1226
-18
No files matched your search
@@ -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)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user