feat(claude-do): depends_on als Menge statt Einzelfeld
Ein Task kann jetzt auf beliebig viele Vorgaenger warten. Die Einzelspalte tasks.depends_on_task_id wird durch die Beziehungstabelle task_dependencies ersetzt (Composite-PK, beide FKs ON DELETE CASCADE -- das reproduziert das alte ON DELETE SET NULL: geloeschter Vorgaenger = Kante weg = Task wieder pickbar). BlockedByTaskId bleibt unberuehrt. - Migration AddTaskDependencies kopiert jede bestehende depends_on_task_id verlustfrei in die Tabelle, bevor die Spalte fallengelassen wird - QueuePicker gatet per doppelt negiertem NOT EXISTS: kein Task mit 0 Kanten wird blockiert, alle Kanten muessen done sein, eine Kante auf einen verschwundenen Task blockiert weiter - SetDependsOnAsync ersetzt die ganze Menge; Zykluspruefung ist jetzt eine BFS ueber den Graphen, faengt also auch A->B->C->A - blockedReason nennt alle offenen Vorgaenger (External/TaskBlocking, von ExternalMcpService und TaskWaitMcpTools gemeinsam genutzt) - add_task/update_task nehmen dependsOnTaskIds; die alte Skalarform bleibt als Ein-Element-Menge inkl. ""-Clear-Sentinel gueltig - UI: Fan-in-Zeile bleibt flach und listet alle Vorgaenger im After-Label, die lineare Kette rendert unveraendert
This commit is contained in:
@@ -475,6 +475,24 @@ namespace ClaudeDo.Data.Migrations
|
||||
b.ToTable("task_attachments", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ClaudeDo.Data.Models.TaskDependencyEntity", b =>
|
||||
{
|
||||
b.Property<string>("TaskId")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("task_id");
|
||||
|
||||
b.Property<string>("DependsOnTaskId")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("depends_on_task_id");
|
||||
|
||||
b.HasKey("TaskId", "DependsOnTaskId");
|
||||
|
||||
b.HasIndex("DependsOnTaskId")
|
||||
.HasDatabaseName("idx_task_dependencies_depends_on");
|
||||
|
||||
b.ToTable("task_dependencies", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ClaudeDo.Data.Models.TaskEntity", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
@@ -504,10 +522,6 @@ namespace ClaudeDo.Data.Migrations
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("created_by");
|
||||
|
||||
b.Property<string>("DependsOnTaskId")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("depends_on_task_id");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("description");
|
||||
@@ -675,9 +689,6 @@ namespace ClaudeDo.Data.Migrations
|
||||
b.HasIndex("BlockedByTaskId")
|
||||
.HasDatabaseName("idx_tasks_blocked_by");
|
||||
|
||||
b.HasIndex("DependsOnTaskId")
|
||||
.HasDatabaseName("idx_tasks_depends_on");
|
||||
|
||||
b.HasIndex("ListId")
|
||||
.HasDatabaseName("idx_tasks_list_id");
|
||||
|
||||
@@ -912,6 +923,21 @@ namespace ClaudeDo.Data.Migrations
|
||||
b.Navigation("Task");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ClaudeDo.Data.Models.TaskDependencyEntity", b =>
|
||||
{
|
||||
b.HasOne("ClaudeDo.Data.Models.TaskEntity", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("DependsOnTaskId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("ClaudeDo.Data.Models.TaskEntity", null)
|
||||
.WithMany("Dependencies")
|
||||
.HasForeignKey("TaskId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ClaudeDo.Data.Models.TaskEntity", b =>
|
||||
{
|
||||
b.HasOne("ClaudeDo.Data.Models.TaskEntity", null)
|
||||
@@ -919,11 +945,6 @@ namespace ClaudeDo.Data.Migrations
|
||||
.HasForeignKey("BlockedByTaskId")
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
b.HasOne("ClaudeDo.Data.Models.TaskEntity", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("DependsOnTaskId")
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
b.HasOne("ClaudeDo.Data.Models.ListEntity", "List")
|
||||
.WithMany("Tasks")
|
||||
.HasForeignKey("ListId")
|
||||
@@ -973,6 +994,8 @@ namespace ClaudeDo.Data.Migrations
|
||||
{
|
||||
b.Navigation("Children");
|
||||
|
||||
b.Navigation("Dependencies");
|
||||
|
||||
b.Navigation("Runs");
|
||||
|
||||
b.Navigation("Subtasks");
|
||||
|
||||
Reference in New Issue
Block a user