diff --git a/src/data/database.test.ts b/src/data/database.test.ts index de49541..ad32b43 100644 --- a/src/data/database.test.ts +++ b/src/data/database.test.ts @@ -23,6 +23,23 @@ describe("database", () => { expect(names).toContain("bot_instances"); }); + it("creates users and sessions tables on init", () => { + const tables = botDb.db + .prepare("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name") + .all() as Array<{ name: string }>; + const names = tables.map((t) => t.name); + expect(names).toContain("users"); + expect(names).toContain("sessions"); + + const userCols = botDb.db.prepare("PRAGMA table_info(users)").all() as Array<{ name: string }>; + const userColNames = userCols.map((c) => c.name).sort(); + expect(userColNames).toEqual(["createdAt", "id", "passwordHash", "updatedAt", "username"]); + + const sessionCols = botDb.db.prepare("PRAGMA table_info(sessions)").all() as Array<{ name: string }>; + const sessionColNames = sessionCols.map((c) => c.name).sort(); + expect(sessionColNames).toEqual(["createdAt", "expiresAt", "id", "lastSeenAt", "userId"]); + }); + it("records and retrieves play history", () => { botDb.addPlayHistory({ botId: "bot1", diff --git a/src/data/database.ts b/src/data/database.ts index fdcdb8f..7dd79da 100644 --- a/src/data/database.ts +++ b/src/data/database.ts @@ -127,12 +127,33 @@ function initTables(db: Database.Database): void { serverPassword TEXT NOT NULL DEFAULT '', identity TEXT ); + + CREATE TABLE IF NOT EXISTS users ( + id TEXT PRIMARY KEY, + username TEXT NOT NULL UNIQUE COLLATE NOCASE, + passwordHash TEXT NOT NULL, + createdAt INTEGER NOT NULL, + updatedAt INTEGER NOT NULL + ); + + CREATE TABLE IF NOT EXISTS sessions ( + id TEXT PRIMARY KEY, + userId TEXT NOT NULL, + createdAt INTEGER NOT NULL, + expiresAt INTEGER NOT NULL, + lastSeenAt INTEGER NOT NULL, + FOREIGN KEY (userId) REFERENCES users(id) ON DELETE CASCADE + ); + + CREATE INDEX IF NOT EXISTS idx_sessions_userId ON sessions(userId); + CREATE INDEX IF NOT EXISTS idx_sessions_expiresAt ON sessions(expiresAt); `); } export function createDatabase(dbPath: string): BotDatabase { const db = new Database(dbPath); db.pragma("journal_mode = WAL"); + db.pragma("foreign_keys = ON"); initTables(db); migrateSchema(db);