diff --git a/src/main/services/team/TeamTaskReader.ts b/src/main/services/team/TeamTaskReader.ts index 92be5402..fef631a2 100644 --- a/src/main/services/team/TeamTaskReader.ts +++ b/src/main/services/team/TeamTaskReader.ts @@ -600,7 +600,7 @@ export class TeamTaskReader { const tasks = await request; if (TeamTaskReader.allTasksGeneration === generationAtStart) { TeamTaskReader.allTasksCache = { - value: cloneTasks(tasks), + value: tasks, expiresAt: Date.now() + ALL_TASKS_CACHE_TTL_MS, }; } diff --git a/test/main/services/team/TeamTaskReader.test.ts b/test/main/services/team/TeamTaskReader.test.ts index 27ba1e1a..560ba8f2 100644 --- a/test/main/services/team/TeamTaskReader.test.ts +++ b/test/main/services/team/TeamTaskReader.test.ts @@ -92,6 +92,24 @@ describe('TeamTaskReader', () => { expect(readAllTasksUncached).toHaveBeenCalledTimes(2); }); + it('keeps cached getAllTasks data isolated from caller mutations', async () => { + const readAllTasksUncached = vi + .spyOn( + TeamTaskReader.prototype as unknown as { + readAllTasksUncached: () => Promise<(TeamTask & { teamName: string })[]>; + }, + 'readAllTasksUncached' + ) + .mockResolvedValueOnce([makeTask('cached-task')]); + + const reader = new TeamTaskReader(); + const firstRead = await reader.getAllTasks(); + firstRead[0]!.subject = 'mutated caller copy'; + + await expect(reader.getAllTasks()).resolves.toEqual([makeTask('cached-task')]); + expect(readAllTasksUncached).toHaveBeenCalledTimes(1); + }); + it('reuses parsed task files until their file signature changes', async () => { await setupTasksRoot(); await writeTaskFile('atlas-hq', {