consttenants=this.database.prepare("SELECT tenant_id, name, enabled, is_test, created_at, updated_at FROM tenants ORDER BY created_at DESC").all()asTenantRow[];
constaccounts=this.database.prepare("SELECT user_id, tenant_id, username, enabled, created_at FROM users WHERE account_type = 'tenant_user' ORDER BY created_at").all()asTenantAccountRow[];
constuser=this.database.prepare("SELECT user_id FROM users WHERE user_id = ? AND tenant_id = ? AND account_type = 'tenant_user'").get(userId,tenantId);
if(!user)thrownewAuthError("租户账号不存在",404);
this.revokeUserSessions(userId);
}
close():void{this.database.close();}
privatemigrate():void{
this.database.exec(`
CREATE TABLE IF NOT EXISTS tenants (
tenant_id TEXT PRIMARY KEY, name TEXT NOT NULL, enabled INTEGER NOT NULL DEFAULT 1 CHECK(enabled IN (0,1)),
is_test INTEGER NOT NULL DEFAULT 0 CHECK(is_test IN (0,1)), created_at TEXT NOT NULL, updated_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS users (
user_id TEXT PRIMARY KEY, username TEXT NOT NULL UNIQUE COLLATE NOCASE, password_hash TEXT NOT NULL,
account_type TEXT NOT NULL CHECK(account_type IN ('system_admin','tenant_user')), tenant_id TEXT REFERENCES tenants(tenant_id),
enabled INTEGER NOT NULL DEFAULT 1 CHECK(enabled IN (0,1)), created_at TEXT NOT NULL, updated_at TEXT NOT NULL,
CHECK((account_type = 'system_admin' AND tenant_id IS NULL) OR (account_type = 'tenant_user' AND tenant_id IS NOT NULL))
);
CREATE TABLE IF NOT EXISTS sessions (
session_id TEXT PRIMARY KEY, token_hash TEXT NOT NULL UNIQUE, user_id TEXT NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
expires_at TEXT NOT NULL, created_at TEXT NOT NULL, last_seen_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS sessions_user_id_idx ON sessions(user_id);
CREATE INDEX IF NOT EXISTS sessions_expires_at_idx ON sessions(expires_at);
`);
this.database.prepare("DELETE FROM sessions WHERE expires_at <= ?").run(newDate().toISOString());