From 2278d97b7e6eb20f8274a9dbccf1eb4dbd13396e Mon Sep 17 00:00:00 2001 From: mika kuns Date: Thu, 23 Apr 2026 17:56:19 +0200 Subject: [PATCH] feat(data): TaskRepository.SetPlanningStartedAsync --- .../Repositories/TaskRepository.cs | 15 +++++++++ .../TaskRepositoryPlanningTests.cs | 33 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/src/ClaudeDo.Data/Repositories/TaskRepository.cs b/src/ClaudeDo.Data/Repositories/TaskRepository.cs index 98862b8..96fee59 100644 --- a/src/ClaudeDo.Data/Repositories/TaskRepository.cs +++ b/src/ClaudeDo.Data/Repositories/TaskRepository.cs @@ -267,6 +267,21 @@ public sealed class TaskRepository return child; } + public async Task SetPlanningStartedAsync( + string taskId, + string sessionToken, + CancellationToken ct = default) + { + var affected = await _context.Tasks + .Where(t => t.Id == taskId && t.Status == TaskStatus.Manual) + .ExecuteUpdateAsync(s => s + .SetProperty(t => t.Status, TaskStatus.Planning) + .SetProperty(t => t.PlanningSessionToken, sessionToken), ct); + + if (affected == 0) return null; + return await _context.Tasks.AsNoTracking().FirstOrDefaultAsync(t => t.Id == taskId, ct); + } + #endregion #region Queue selection diff --git a/tests/ClaudeDo.Worker.Tests/Repositories/TaskRepositoryPlanningTests.cs b/tests/ClaudeDo.Worker.Tests/Repositories/TaskRepositoryPlanningTests.cs index 4f29c07..e47b09c 100644 --- a/tests/ClaudeDo.Worker.Tests/Repositories/TaskRepositoryPlanningTests.cs +++ b/tests/ClaudeDo.Worker.Tests/Repositories/TaskRepositoryPlanningTests.cs @@ -119,4 +119,37 @@ public sealed class TaskRepositoryPlanningTests : IDisposable await Assert.ThrowsAsync(() => _tasks.CreateChildAsync("nonexistent-parent-id", "t", null, null, null)); } + + [Fact] + public async Task SetPlanningStartedAsync_ManualTask_TransitionsToPlanning() + { + var listId = await CreateListAsync(); + var task = MakeTask(listId, TaskStatus.Manual); + await _tasks.AddAsync(task); + + var result = await _tasks.SetPlanningStartedAsync(task.Id, "tok-abc"); + + Assert.NotNull(result); + Assert.Equal(TaskStatus.Planning, result!.Status); + Assert.Equal("tok-abc", result.PlanningSessionToken); + + var loaded = await _tasks.GetByIdAsync(task.Id); + Assert.Equal(TaskStatus.Planning, loaded!.Status); + Assert.Equal("tok-abc", loaded.PlanningSessionToken); + } + + [Fact] + public async Task SetPlanningStartedAsync_NonManualTask_ReturnsNull() + { + var listId = await CreateListAsync(); + var task = MakeTask(listId, TaskStatus.Queued); + await _tasks.AddAsync(task); + + var result = await _tasks.SetPlanningStartedAsync(task.Id, "tok-xyz"); + + Assert.Null(result); + var loaded = await _tasks.GetByIdAsync(task.Id); + Assert.Equal(TaskStatus.Queued, loaded!.Status); + Assert.Null(loaded.PlanningSessionToken); + } }