feat(status): add WaitingForChildren task status value

This commit is contained in:
mika kuns
2026-06-04 15:32:11 +02:00
parent 204b089000
commit ee0d1257dd
3 changed files with 103 additions and 4 deletions

View File

@@ -14,8 +14,9 @@ public class TaskEntityConfiguration : IEntityTypeConfiguration<TaskEntity>
TaskStatus.Idle => "idle",
TaskStatus.Queued => "queued",
TaskStatus.Running => "running",
TaskStatus.WaitingForReview => "waiting_for_review",
TaskStatus.Done => "done",
TaskStatus.WaitingForReview => "waiting_for_review",
TaskStatus.WaitingForChildren => "waiting_for_children",
TaskStatus.Done => "done",
TaskStatus.Failed => "failed",
TaskStatus.Cancelled => "cancelled",
_ => throw new ArgumentOutOfRangeException(nameof(v)),
@@ -27,8 +28,9 @@ public class TaskEntityConfiguration : IEntityTypeConfiguration<TaskEntity>
"idle" => TaskStatus.Idle,
"queued" => TaskStatus.Queued,
"running" => TaskStatus.Running,
"waiting_for_review" => TaskStatus.WaitingForReview,
"done" => TaskStatus.Done,
"waiting_for_review" => TaskStatus.WaitingForReview,
"waiting_for_children" => TaskStatus.WaitingForChildren,
"done" => TaskStatus.Done,
"failed" => TaskStatus.Failed,
"cancelled" => TaskStatus.Cancelled,
_ => throw new ArgumentOutOfRangeException(nameof(v)),

View File

@@ -6,6 +6,7 @@ public enum TaskStatus
Queued,
Running,
WaitingForReview,
WaitingForChildren,
Done,
Failed,
Cancelled,

View File

@@ -0,0 +1,96 @@
using ClaudeDo.Data;
using ClaudeDo.Data.Models;
using ClaudeDo.Data.Repositories;
using Microsoft.EntityFrameworkCore;
using TaskStatus = ClaudeDo.Data.Models.TaskStatus;
namespace ClaudeDo.Data.Tests;
public sealed class CreateChildTests : IDisposable
{
private readonly string _dbPath;
private readonly ClaudeDoDbContext _ctx;
public CreateChildTests()
{
_dbPath = Path.Combine(Path.GetTempPath(), $"claudedo_test_{Guid.NewGuid():N}.db");
var options = new DbContextOptionsBuilder<ClaudeDoDbContext>()
.UseSqlite($"Data Source={_dbPath}")
.Options;
_ctx = new ClaudeDoDbContext(options);
_ctx.Database.EnsureCreated();
}
public void Dispose()
{
_ctx.Dispose();
try { File.Delete(_dbPath); } catch { }
try { File.Delete(_dbPath + "-wal"); } catch { }
try { File.Delete(_dbPath + "-shm"); } catch { }
}
private async Task<string> SeedListAsync(string id = "l1")
{
_ctx.Lists.Add(new ListEntity { Id = id, Name = "Test List", CreatedAt = DateTime.UtcNow });
await _ctx.SaveChangesAsync();
return id;
}
// ---- Task 1 ----
[Fact]
public async Task WaitingForChildren_roundtrips_through_value_converter()
{
await SeedListAsync();
var taskId = Guid.NewGuid().ToString();
_ctx.Tasks.Add(new TaskEntity
{
Id = taskId,
ListId = "l1",
Title = "Parent",
Status = TaskStatus.WaitingForChildren,
CreatedAt = DateTime.UtcNow,
});
await _ctx.SaveChangesAsync();
_ctx.ChangeTracker.Clear();
var loaded = await _ctx.Tasks.AsNoTracking().FirstAsync(t => t.Id == taskId);
Assert.Equal(TaskStatus.WaitingForChildren, loaded.Status);
}
// ---- Task 2 ----
[Fact]
public async Task CreateChild_attaches_to_non_planning_parent_and_stamps_createdBy()
{
await SeedListAsync();
var parentId = "p1";
_ctx.Tasks.Add(new TaskEntity
{
Id = parentId,
ListId = "l1",
Title = "Parent",
Status = TaskStatus.Running,
PlanningPhase = PlanningPhase.None,
CreatedAt = DateTime.UtcNow,
});
await _ctx.SaveChangesAsync();
var child = await new TaskRepository(_ctx).CreateChildAsync(
"p1", "Refactor X", "desc", commitType: null, createdBy: "p1");
Assert.Equal("p1", child.ParentTaskId);
Assert.Equal("p1", child.CreatedBy);
Assert.Equal(TaskStatus.Idle, child.Status);
Assert.Equal("l1", child.ListId);
}
[Fact]
public async Task CreateChild_throws_when_parent_missing()
{
await SeedListAsync();
await Assert.ThrowsAsync<InvalidOperationException>(() =>
new TaskRepository(_ctx).CreateChildAsync("nope", "T", null, null, null));
}
}