Capture team chat and expose moderation match archives

This commit is contained in:
2026-10-17 20:11:49 -04:00
parent b678de2f6f
commit 870f13b150
28 changed files with 943 additions and 81 deletions
+28 -2
View File
@@ -50,7 +50,7 @@ async function create(overrides: Record<string, unknown> = {}) {
});
}
async function archive(messages: Array<{ guid?: string; message: string }>) {
async function archive(messages: Array<{ guid?: string; message: string; channel?: 'team' }>) {
const { saveTelemetry } = await import('../../src/lib/server/fleet/telemetry.js');
const { matchChatTimeline } = await import('../../src/lib/server/fleet/chat.js');
saveTelemetry({
@@ -77,7 +77,8 @@ async function archive(messages: Array<{ guid?: string; message: string }>) {
guid: message.guid ?? '123',
slot: message.guid ? 2 : 1,
player: message.guid ? 'Witness' : 'Subject',
message: message.message
message: message.message,
...(message.channel ? { channel: message.channel } : {})
}
})
);
@@ -155,6 +156,31 @@ it('allows a new witness reply alongside an attached subject and deduplicates la
expect(await detail(id)).toEqual(attached);
});
it('preserves team chat separately when matching evidence saved before message identifiers', async () => {
const { matchId, entries } = await archive([
{ message: 'Same words', channel: 'team' },
{ message: 'Same words' }
]);
const { id } = await create({
evidence: { matchId, messageIds: [entries[1].messageId] }
});
// A legacy public-chat snapshot has no selected IDs or channel field.
handle
.prepare('UPDATE moderation_evidence SET snapshot=? WHERE case_id=?')
.run(JSON.stringify({ matchId, entry: entries[1] }), id);
await mutate({
op: 'attach-evidence',
id,
revision: 1,
evidence: { matchId, messageIds: [entries[0].messageId] }
});
const attached = await detail(id);
expect(attached.case.evidence).toHaveLength(2);
const snapshot = JSON.parse(attached.case.evidence[1].snapshot!);
expect(snapshot.entry.message.channel).toBe('team');
expect(snapshot.selectedMessageIds).toEqual([entries[0].messageId]);
});
it('validates selection and context bounds and rolls back opening a case with invalid evidence', async () => {
const { matchId, entries } = await archive([{ message: 'Subject statement' }]);
const messageId = entries[0].messageId!;