-- name: AddTaskDependency :exec INSERT INTO task_dependencies (task_id, blocks_task_id) VALUES ($1, $2) ON CONFLICT (task_id, blocks_task_id) DO NOTHING; -- name: RemoveTaskDependency :exec DELETE FROM task_dependencies WHERE task_id = $1 AND blocks_task_id = $2; -- name: ListTaskBlockers :many SELECT t.* FROM tasks t JOIN task_dependencies td ON td.blocks_task_id = t.id WHERE td.task_id = $1 AND t.deleted_at IS NULL; -- name: ListTasksBlockedBy :many SELECT t.* FROM tasks t JOIN task_dependencies td ON td.task_id = t.id WHERE td.blocks_task_id = $1 AND t.deleted_at IS NULL; -- name: CheckDirectCircularDependency :one -- Direct cycle: blocks_task_id is blocked by task_id (would create A->B and B->A) SELECT EXISTS( SELECT 1 FROM task_dependencies WHERE task_id = $2 AND blocks_task_id = $1 ) AS has_circle;