6.2 KiB
ADDED Requirements
Requirement: openTask node — idempotent Thread/task creation
The openTask node (nodeType: automatedTask, nodeSubType: openTask) SHALL compile into a Flowable ServiceTask referencing OpenTaskDelegate. It SHALL idempotently create a Thread with configurable TaskType and TaskStatus.Open. If an open Thread/task already exists for the entity, it SHALL be a no-op.
Scenario: BPMN structure is compiled correctly
- WHEN a workflow definition contains an
openTasknode with config{ "template": "incident", "taskType": "RequestTestCaseFailureResolution" } - THEN the compiled BPMN model SHALL contain a ServiceTask referencing
OpenTaskDelegate.class.getName() - AND the ServiceTask SHALL have Expression fields for
templateExpr,taskTypeExpr,responsiblesExpr, andinputNamespaceMapExpr
Scenario: Node registered in NodeFactory
- WHEN
NodeFactoryreceives a node definition withnodeSubType: openTask - THEN it SHALL instantiate
OpenTaskand return a valid node
Requirement: OpenTaskDelegate wires Flowable to business logic
The OpenTaskDelegate SHALL implement JavaDelegate, receive configuration via Flowable Expression fields, extract values from the DelegateExecution, instantiate OpenTaskImpl, call it, and set the taskCreated process variable from the result. On business logic failure, it SHALL throw a BpmnError.
Scenario: Delegate passes config to impl and sets process variable
- WHEN
OpenTaskDelegate.execute()is called with aDelegateExecutioncontaining valid expression values - THEN it SHALL instantiate
OpenTaskImplwith resolved config values, call the impl, and setexecution.setVariable("taskCreated", result)
Scenario: Delegate wraps exceptions as BpmnError
- WHEN
OpenTaskImplthrows an exception during execution - THEN
OpenTaskDelegateSHALL catch it and throw aBpmnError
Requirement: OpenTaskImpl creates Thread/task (clean state)
When no open Thread/task exists for the entity, OpenTaskImpl SHALL create a Thread with the configured TaskType and TaskStatus.Open and return taskCreated = true. Auto-assignment is configurable via the optional responsibles config field. When responsibles is not set, the task SHALL be created unassigned (matching current behavior).
Scenario: First failure creates unassigned Thread (default, no responsibles config)
- WHEN no open Thread/task exists for the entity
- AND no
responsiblesconfig is set on the node - THEN
OpenTaskImplSHALL create an unassigned Thread task and returntaskCreated = true
Scenario: First failure auto-assigns to table owner (responsibles configured)
- WHEN no open Thread/task exists for the entity
- AND
responsibles.sourceis"tableOwner" - THEN
OpenTaskImplSHALL create a Thread task assigned to the table entity's owner and returntaskCreated = true
Scenario: First failure auto-assigns to specific user (responsibles configured)
- WHEN no open Thread/task exists for the entity
- AND
responsibles.sourceis"specificUser"withresponsibles.targetset to a user FQN - THEN
OpenTaskImplSHALL create a Thread task assigned to the specified user and returntaskCreated = true
Requirement: OpenTaskImpl skips when Thread/task already exists
When an open Thread/task already exists for the entity, OpenTaskImpl SHALL skip creation and return taskCreated = false.
Scenario: Duplicate event is idempotently skipped
- WHEN an open Thread/task already exists for the entity (e.g., Ack or Assigned event after Thread was created on New)
- THEN
OpenTaskImplSHALL returntaskCreated = false - AND no duplicate Thread SHALL be created
Requirement: OpenTaskImpl runs as governance-bot
All actions performed by OpenTaskImpl (Thread creation, task assignment) SHALL execute under the governance-bot identity.
Scenario: Governance-bot identity prevents event loops
- WHEN
OpenTaskImplcreates a Thread task - THEN the ChangeEvent generated by that creation SHALL have
governance-botas the updatedBy user - AND
WorkflowEventConsumerSHALL skip processing that event
Requirement: closeTask node — Thread/task closure
The closeTask node (nodeType: automatedTask, nodeSubType: closeTask) SHALL compile into a Flowable ServiceTask referencing CloseTaskDelegate. It SHALL close an open Thread/task for the entity. If no open Thread/task exists, it SHALL be a no-op.
Scenario: BPMN structure is compiled correctly
- WHEN a workflow definition contains a
closeTasknode with config{ "template": "incident", "taskType": "RequestTestCaseFailureResolution" } - THEN the compiled BPMN model SHALL contain a ServiceTask referencing
CloseTaskDelegate.class.getName()
Scenario: Node registered in NodeFactory
- WHEN
NodeFactoryreceives a node definition withnodeSubType: closeTask - THEN it SHALL instantiate
CloseTaskand return a valid node
Requirement: CloseTaskDelegate wires Flowable to business logic
The CloseTaskDelegate SHALL implement JavaDelegate, receive configuration via Flowable Expression fields, instantiate CloseTaskImpl, call it, and set the taskClosed process variable.
Scenario: Delegate passes config to impl and sets process variable
- WHEN
CloseTaskDelegate.execute()is called with aDelegateExecution - THEN it SHALL instantiate
CloseTaskImpl, call the impl, and setexecution.setVariable("taskClosed", result)
Requirement: CloseTaskImpl closes Thread/task
When an open Thread/task exists for the entity, CloseTaskImpl SHALL close it and return taskClosed = true. When no open Thread/task exists, it SHALL return taskClosed = false.
Scenario: Open Thread/task is closed
- WHEN an open Thread/task exists for the entity
- THEN
CloseTaskImplSHALL close the Thread task and returntaskClosed = true
Scenario: No-op when no open Thread/task exists
- WHEN no open Thread/task exists for the entity
- THEN
CloseTaskImplSHALL returntaskClosed = falsewithout error
Requirement: CloseTaskImpl runs as governance-bot
All actions performed by CloseTaskImpl SHALL execute under the governance-bot identity.