feat: let the current assignee reassign a pending task

Keep the same task id, move the pending inbox, and record TASK_REASSIGNED without advancing the step.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
0264408
2026-09-16 08:40:25 +08:00
co-authored by Cursor
parent 5795778112
commit 850583f326
15 changed files with 286 additions and 26 deletions
@@ -29,6 +29,7 @@ public interface OrdoEngine {
return reject(taskId, actor, null);
}
ApprovalTask reject(String taskId, String actor, String comment);
ApprovalTask reassign(String taskId, String actor, String newAssignee);
default ProcessInstance withdraw(String instanceId, String actor) {
return withdraw(instanceId, actor, null);
}
@@ -7,6 +7,7 @@ public enum ProcessEventType {
TASK_APPROVED,
TASK_REJECTED,
TASK_SKIPPED,
TASK_REASSIGNED,
INSTANCE_APPROVED,
INSTANCE_REJECTED,
INSTANCE_WITHDRAWN,
@@ -25,12 +25,21 @@ public interface ApprovalTaskRepository {
List<ApprovalTask> findPendingByInstanceId(String instanceId);
/**
* Atomically completes the task only if it is still pending.
* Atomically completes the task only if it is still pending and still assigned to
* {@code completedTask.assignee()}.
*
* @return true if the update was applied, false if the task had already been completed by a concurrent operation
* @return true if the update was applied, false if the task had already been completed or reassigned
*/
boolean completeIfPending(ApprovalTask completedTask);
/**
* Atomically changes the assignee only if the task is still pending and still assigned to
* {@code expectedAssignee}.
*
* @return true if the update was applied
*/
boolean reassignIfPending(String taskId, String expectedAssignee, String newAssignee);
/** Paginated, filterable query; results are ordered newest-first (created_at desc). */
Page<ApprovalTask> query(TaskQuery query, PageRequest pageRequest);
}