Clear role-scoped sessions

This commit is contained in:
ejclaw
2026-05-17 01:57:37 +09:00
parent a942973bb2
commit 1b0360c8c0
4 changed files with 78 additions and 3 deletions

28
src/db-sessions.test.ts Normal file
View File

@@ -0,0 +1,28 @@
import { beforeEach, describe, expect, it } from 'vitest';
import {
_initTestDatabase,
deleteAllSessionsForGroup,
getSession,
setSession,
} from './db.js';
describe('session accessors', () => {
beforeEach(() => {
_initTestDatabase();
});
it('deletes owner, reviewer, and arbiter role-scoped sessions for a group', () => {
setSession('group-a', 'owner-session');
setSession('group-a:reviewer', 'reviewer-session');
setSession('group-a:arbiter', 'arbiter-session');
setSession('group-b', 'other-session');
deleteAllSessionsForGroup('group-a');
expect(getSession('group-a')).toBeUndefined();
expect(getSession('group-a:reviewer')).toBeUndefined();
expect(getSession('group-a:arbiter')).toBeUndefined();
expect(getSession('group-b')).toBe('other-session');
});
});

View File

@@ -141,8 +141,11 @@ export function deleteAllSessionsForGroupFromDatabase(
groupFolder: string,
): void {
database
.prepare('DELETE FROM sessions WHERE group_folder = ?')
.run(groupFolder);
.prepare(
`DELETE FROM sessions
WHERE group_folder IN (?, ?, ?)`,
)
.run(groupFolder, `${groupFolder}:reviewer`, `${groupFolder}:arbiter`);
}
export function getAllSessionsForAgentTypeFromDatabase(

37
src/runtime-state.test.ts Normal file
View File

@@ -0,0 +1,37 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';
const db = vi.hoisted(() => ({
assignRoom: vi.fn(),
deleteAllSessionsForGroup: vi.fn(),
deleteSession: vi.fn(),
getAllRoomBindings: vi.fn(() => ({})),
getAllSessions: vi.fn(() => ({})),
getRouterState: vi.fn(() => ''),
setRouterState: vi.fn(),
setSession: vi.fn(),
}));
vi.mock('./db.js', () => db);
import { createRuntimeState } from './runtime-state.js';
describe('createRuntimeState', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('clears role-scoped sessions from memory when allRoles is requested', () => {
const state = createRuntimeState();
state.persistSession('group-a', 'owner-session');
state.persistSession('group-a:reviewer', 'reviewer-session');
state.persistSession('group-a:arbiter', 'arbiter-session');
state.persistSession('group-b', 'other-session');
state.clearSession('group-a', { allRoles: true });
expect(state.getSessions()).toEqual({ 'group-b': 'other-session' });
expect(db.deleteAllSessionsForGroup).toHaveBeenCalledWith('group-a');
expect(db.deleteSession).not.toHaveBeenCalled();
});
});

View File

@@ -48,10 +48,17 @@ export function createRuntimeState(): RuntimeState {
groupFolder: string,
opts?: { allRoles?: boolean },
): void => {
delete sessions[groupFolder];
if (opts?.allRoles) {
for (const key of [
groupFolder,
`${groupFolder}:reviewer`,
`${groupFolder}:arbiter`,
]) {
delete sessions[key];
}
deleteAllSessionsForGroup(groupFolder);
} else {
delete sessions[groupFolder];
deleteSession(groupFolder);
}
};