Build MVP with Pi installer and atomic updates
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import { mkdirSync } from "node:fs";
|
||||
import { dirname } from "node:path";
|
||||
import Database from "better-sqlite3";
|
||||
|
||||
export type CompanionDatabase = Database.Database;
|
||||
|
||||
export function openDatabase(path: string): CompanionDatabase {
|
||||
if (path !== ":memory:") mkdirSync(dirname(path), { recursive: true, mode: 0o750 });
|
||||
|
||||
const database = new Database(path);
|
||||
database.pragma("journal_mode = WAL");
|
||||
database.pragma("foreign_keys = ON");
|
||||
database.pragma("busy_timeout = 5000");
|
||||
migrate(database);
|
||||
return database;
|
||||
}
|
||||
|
||||
function migrate(database: CompanionDatabase): void {
|
||||
database.exec(`
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
username TEXT NOT NULL UNIQUE COLLATE NOCASE,
|
||||
password_hash TEXT NOT NULL,
|
||||
role TEXT NOT NULL CHECK (role = 'admin'),
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sessions (
|
||||
id_hash TEXT PRIMARY KEY,
|
||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
expires_at TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS sessions_expiry_idx ON sessions(expires_at);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS audit_events (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
actor_user_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
||||
action TEXT NOT NULL,
|
||||
result TEXT NOT NULL CHECK (result IN ('success', 'failure')),
|
||||
ip_address TEXT,
|
||||
details_json TEXT NOT NULL DEFAULT '{}',
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
`);
|
||||
}
|
||||
Reference in New Issue
Block a user