feat(data): add Waiting task status and CreatedBy column

- New TaskStatus.Waiting for sequential subtask chains.
- New TaskEntity.CreatedBy column with migration AddTaskCreatedBy.
- TaskRepository.GetByCreatorAsync for filtering by creator.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
mika kuns
2026-04-25 09:35:15 +02:00
parent 2ad6f20258
commit 288d2ece8b
5 changed files with 49 additions and 1 deletions

View File

@@ -17,6 +17,7 @@ public class TaskEntityConfiguration : IEntityTypeConfiguration<TaskEntity>
: v == TaskStatus.Planning ? "planning"
: v == TaskStatus.Planned ? "planned"
: v == TaskStatus.Draft ? "draft"
: v == TaskStatus.Waiting ? "waiting"
: throw new ArgumentOutOfRangeException(nameof(v));
private static TaskStatus StatusFromString(string v)
@@ -28,6 +29,7 @@ public class TaskEntityConfiguration : IEntityTypeConfiguration<TaskEntity>
: v == "planning" ? TaskStatus.Planning
: v == "planned" ? TaskStatus.Planned
: v == "draft" ? TaskStatus.Draft
: v == "waiting" ? TaskStatus.Waiting
: throw new ArgumentOutOfRangeException(nameof(v));
private static readonly ValueConverter<TaskStatus, string> StatusConverter =
@@ -64,6 +66,8 @@ public class TaskEntityConfiguration : IEntityTypeConfiguration<TaskEntity>
builder.Property(t => t.PlanningSessionToken).HasColumnName("planning_session_token");
builder.Property(t => t.PlanningFinalizedAt).HasColumnName("planning_finalized_at");
builder.Property(t => t.CreatedBy).HasColumnName("created_by");
builder.HasOne(t => t.Parent)
.WithMany(t => t.Children)
.HasForeignKey(t => t.ParentTaskId)

View File

@@ -0,0 +1,28 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ClaudeDo.Data.Migrations
{
/// <inheritdoc />
public partial class AddTaskCreatedBy : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "created_by",
table: "tasks",
type: "TEXT",
nullable: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "created_by",
table: "tasks");
}
}
}

View File

@@ -82,7 +82,7 @@ namespace ClaudeDo.Data.Migrations
{
Id = 1,
DefaultClaudeInstructions = "",
DefaultMaxTurns = 30,
DefaultMaxTurns = 100,
DefaultModel = "sonnet",
DefaultPermissionMode = "bypassPermissions",
WorktreeAutoCleanupDays = 7,
@@ -236,6 +236,10 @@ namespace ClaudeDo.Data.Migrations
.HasColumnType("TEXT")
.HasColumnName("created_at");
b.Property<string>("CreatedBy")
.HasColumnType("TEXT")
.HasColumnName("created_by");
b.Property<string>("Description")
.HasColumnType("TEXT")
.HasColumnName("description");

View File

@@ -10,6 +10,7 @@ public enum TaskStatus
Planning,
Planned,
Draft,
Waiting,
}
public sealed class TaskEntity
@@ -39,6 +40,8 @@ public sealed class TaskEntity
public string? PlanningSessionToken { get; set; }
public DateTime? PlanningFinalizedAt { get; set; }
public string? CreatedBy { get; set; }
// Navigation properties
public ListEntity List { get; set; } = null!;
public WorktreeEntity? Worktree { get; set; }

View File

@@ -75,6 +75,15 @@ public sealed class TaskRepository
public Task<List<TaskEntity>> GetByListAsync(string listId, CancellationToken ct = default)
=> GetByListIdAsync(listId, ct);
public async Task<List<TaskEntity>> GetByCreatorAsync(string createdBy, CancellationToken ct = default)
{
return await _context.Tasks
.AsNoTracking()
.Where(t => t.CreatedBy == createdBy)
.OrderByDescending(t => t.CreatedAt)
.ToListAsync(ct);
}
#endregion
#region Status transitions