feat(gateway): add sender presence tracking

This commit is contained in:
William Valentin
2026-02-15 19:28:16 -08:00
parent 421942f66d
commit c6e3d09ecc
11 changed files with 358 additions and 8 deletions
+51
View File
@@ -64,6 +64,57 @@ describe('system handlers', () => {
{ name: 'cron', type: 'automation', status: 'configured', description: 'Cron scheduler', itemCount: 2 },
]);
});
it('system.presence returns empty result when getPresence is not provided', async () => {
const req: GatewayRequest = { id: 4, method: 'system.presence' };
const result = await handlers['system.presence'](req) as GatewayResponse;
expect(result.id).toBe(4);
expect((result.result as any).presence).toEqual([]);
expect((result.result as any).summary).toEqual({ total: 0, online: 0, offline: 0 });
});
it('system.presence returns filtered presence entries', async () => {
const handlers = createSystemHandlers({
...deps,
getPresence: ({ channel, status, limit } = {}) => {
const all = [
{
channel: 'telegram',
senderId: '1',
senderName: 'alice',
firstSeenAt: 1000,
lastSeenAt: 2000,
messageCount: 3,
status: 'online' as const,
},
{
channel: 'discord',
senderId: '2',
senderName: 'bob',
firstSeenAt: 1000,
lastSeenAt: 1500,
messageCount: 1,
status: 'offline' as const,
},
];
return all
.filter((entry) => !channel || entry.channel === channel)
.filter((entry) => !status || entry.status === status)
.slice(0, limit ?? 100);
},
});
const req: GatewayRequest = {
id: 5,
method: 'system.presence',
params: { channel: 'telegram', status: 'online', limit: 10 },
};
const result = await handlers['system.presence'](req) as GatewayResponse;
expect((result.result as any).presence).toHaveLength(1);
expect((result.result as any).presence[0].channel).toBe('telegram');
expect((result.result as any).summary).toEqual({ total: 1, online: 1, offline: 0 });
});
});
describe('system.tokenUsage handler', () => {