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
14 lines
565 B
C#
14 lines
565 B
C#
namespace ClaudeDo.Data.Models;
|
|
|
|
/// <summary>
|
|
/// One declared "task must run after task" edge. A task can carry n of them; the queue picker
|
|
/// claims it only once every predecessor reached <see cref="TaskStatus.Done"/>.
|
|
/// Deliberately separate from <see cref="TaskEntity.BlockedByTaskId"/>, the planning chain's own
|
|
/// internal single link — see ClaudeDo.Worker/CLAUDE.md → Status Model.
|
|
/// </summary>
|
|
public sealed class TaskDependencyEntity
|
|
{
|
|
public required string TaskId { get; init; }
|
|
public required string DependsOnTaskId { get; init; }
|
|
}
|