feat: planning sessions foundation (Plan A) #4
@@ -267,6 +267,21 @@ public sealed class TaskRepository
|
|||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<TaskEntity?> 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
|
#endregion
|
||||||
|
|
||||||
#region Queue selection
|
#region Queue selection
|
||||||
|
|||||||
@@ -119,4 +119,37 @@ public sealed class TaskRepositoryPlanningTests : IDisposable
|
|||||||
await Assert.ThrowsAsync<InvalidOperationException>(() =>
|
await Assert.ThrowsAsync<InvalidOperationException>(() =>
|
||||||
_tasks.CreateChildAsync("nonexistent-parent-id", "t", null, null, null));
|
_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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user