# UserTask State

The "UserTask State" in the Serverless Workflow specification is designed to integrate human tasks, drawing inspiration from the BPMN2 User Task concept. This state facilitates human interactions such as approvals, reviews, and other decision-making processes within workflows.

### **Overview**

| Parameter                                               | Description                                                                                               | Type                  | Required |
| ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | --------------------- | -------- |
| name                                                    | Unique State name                                                                                         | string                | yes      |
| type                                                    | State type                                                                                                | string                | yes      |
| taskKey                                                 | A unique identifier for the task.                                                                         | string                | yes      |
| formKey                                                 | Identifier for the form associated with the task.                                                         | string                | no       |
| [assignee](#task-assignment)                            | Designates a specific user to perform the task.                                                           | string                | no       |
| [candidateUsers](#task-assignment)                      | Lists eligible individual users who can claim the task.                                                   | string                | no       |
| [candidateGroups](#task-assignment)                     | Defines groups whose members can claim the task.                                                          | string                | no       |
| dueDate                                                 | Deadline for the task completion, specified in [ISO 8601 ](https://en.wikipedia.org/wiki/ISO_8601)format. | string                | no       |
| dataFilter                                              | Transforms the task's input data.                                                                         | string                | no       |
| [taskOutcomes](#task-outcomes)                          | Determines potential outcomes based on task completion.                                                   | array of TaskOutcome  | no       |
| [taskListeners](#task-listener-and-event-lifecycle)     | Monitors and acts on various task-related events.                                                         | array of TaskListener | no       |
| [deletedTransition](#task-listener-and-event-lifecycle) | Specifies the workflow path if the task is deleted.                                                       | Transition            | no       |
| [timeoutTransition](#task-listener-and-event-lifecycle) | Specifies the workflow path if the task times out.                                                        | Transition            | no       |
| [timers](#task-timers)                                  | Define timers for the task                                                                                | array of TaskTimer    | no       |
| transition                                              | Next transition of the workflow after all the actions have been performed                                 | string or object      | no       |
| compensatedBy                                           | Unique name of a workflow state which is responsible for compensation of this state                       | string                | no       |
| usedForCompensation                                     | If `true`, this state is used to compensate another state. Default is `false`                             | boolean               | no       |
| metadata                                                | Metadata information                                                                                      | object                | no       |
| end                                                     | Is this state an end state                                                                                | boolean or object     | no       |

**Example:**

<table><thead><tr><th>JSON</th><th>YAML</th></tr></thead><tbody><tr><td><pre class="language-json" data-line-numbers><code class="lang-json">{
  "name": "Submit Form",
  "taskKey": "taskCungCapHoSoVaDeNghiVayVon",
  "type": "usertask",
  "formKey": "LCD#661f784162f95774145bdf9f",
  "assignee": "user01@a4b.vn",
  "taskOutcomes": [
    {
      "code": "Complete",
      "name": "Gửi đề xuất",
      "outcomeDecision": "COMPLETED",
      "transition": "Kiểm soát đề xuất cấp 1 (KSRM1)"
    }
  ],
  "taskListeners": [
    {
      "taskEvent": "completed",
      "actionMode": "sequential",
      "actions": [
        {
          "functionRef": {
            "refName": "notifyCompletion",
            "arguments": {
              "taskId": "${ .taskKey }",
              "outcome": "${ .outcome }"
            }
          },
          "functionRef": {
            "refName": "logActivity",
            "arguments": {
              "message": "Task completed successfully",
              "taskId": "${ .taskKey }"
            }
          }
        }
      ],
      "eventDataFilter": {
        "data": "${ .outputs }",
        "toStateData": "$.taskOutput"
      }
    }
  ]
}
</code></pre></td><td><pre class="language-yaml" data-line-numbers><code class="lang-yaml">name: "Submit Form"
taskKey: "taskCungCapHoSoVaDeNghiVayVon"
type: "usertask"
formKey: "LCD#661f784162f95774145bdf9f"
assignee: "user01@a4b.vn"
taskOutcomes:
  - code: "Complete"
    name: "Gửi đề xuất"
    outcomeDecision: "COMPLETED"
    transition: "Kiểm soát đề xuất cấp 1 (KSRM1)"
taskListeners:
  - taskEvent: "completed"
    actionMode: "sequential"
    actions:
      - functionRef:
          refName: "notifyCompletion"
          arguments:
            taskId: "${ .taskKey }"
            outcome: "${ .outcome }"
        functionRef:
          refName: "logActivity"
          arguments:
            message: "Task completed successfully"
            taskId: "${ .taskKey }"
    eventDataFilter:
      data: "${ .outputs }"
      toStateData: "$.taskOutput"

</code></pre></td></tr></tbody></table>

### **Task Assignment**

Task assignment in the "UserTask State" is vital for designating responsibility for the task's completion. It is directly influenced by the properties `assignee`, `candidateUsers`, and `candidateGroups`.

* **Assignee:** A specific user designated to perform and complete the task. The task is directly assigned to this user, making them primarily responsible for its execution.
* **Candidate Users:** A list of users who are eligible to claim the task. This allows for a flexible assignment where any of the listed users can take responsibility for the task.
* **Candidate Groups:** Specifies one or more groups whose members are eligible to claim the task. This is particularly useful in scenarios where tasks are suitable for any member of a department or team.

This model allows for tasks to be assigned either directly to a specific individual or to a pool of eligible candidates

**Example of Task Assignment:**

```json
{
  "assignee": "user123",
  "candidateUsers": "user124, user125",
  "candidateGroups": "group1"
}
```

### **Task Listener and Event Lifecycle**

Task listeners are configured to respond to task lifecycle events, facilitating automated reactions at various stages of a task's lifecycle, including creation, assignment, update, completion, deletion, and timeouts.

**Properties of Task Listener:**

| Parameter                                                                                                            | Description                                                            | Type            | Required |
| -------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | --------------- | -------- |
| [taskEvent](#events)                                                                                                 | Specifies the [lifecycle event](#events) to monitor.                   | string          | yes      |
| actionMode                                                                                                           | Dictates whether actions are executed `sequentially` or in `parallel`. | string          | no       |
| [actions](https://github.com/serverlessworkflow/specification/blob/main/specification.md#Action-Definition)          | Actions initiated when the event occurs.                               | array of Action | yes      |
| [eventDataFilter](https://github.com/serverlessworkflow/specification/blob/main/specification.md#Event-data-filters) | Filters and maps event data to the actions.                            | EventDataFilter | no       |

#### **Events:**

* **created**: Triggered when a new task instance is created.
* **assigned**: Occurs when a task is assigned to a user.
* **updated**: Fired when any update to the task occurs.
* **completed**: Triggered when the task is completed by the assignee.
* **deleted**: Occurs when the task is deleted.
* **timeout**: Triggered when the task reaches its due date without completion.

**Event Chaining:**&#x20;

The execution of Task Listeners is dependent on the order of firing of the following task-related events:&#x20;

* The **create event** fires when the task has been created as a transient object with all task properties. No other task-related event will be fired before the create event. The event allows us to inspect all properties of the task when we receive it in the create listener.&#x20;
* The **update event** occurs when a task property (e.g., assignee, owner, priority, etc.) on an already created task is changed. Note that the initialization of a task does not fire an update event (the task is being created). This also means that the update event will always occur after a create event has already occurred.
* The **assignment event** specifically tracks the changes of the Task's assignee property. The event may be fired on two occasions: When a task with an explicitly defined assignee is created, the assignment event will be fired after the create event. When an already created task is assigned, i.e., the Task's assignee property is changed, the assignment event will follow the update event since changing the assignee property results in an updated task.
* The **complete event** occurs when the task is successfully completed, resulting in the end of the task event lifecycle.
* The **delete event** occurs just before the task is deleted. No other event is fired after the delete event since it results in the end of the task event lifecycle. This means that the delete event is mutually exclusive with the complete event.

Once the completed event is received, the UserTask state completes its execution and transitions to the next defined workflow state or completes workflow execution in case it is an end state.

The **completed event** payload is merged with the UserTask state data and can be filtered via the "eventDataFilter" definition.

**Example of a Task Listener Configuration:**

```json
{
  "taskListeners": [
    {
      "taskEvent": "completed",
      "actionMode": "sequential",
      "actions": [
        {
          "functionRef": {
            "refName": "notifyCompletion",
            "arguments": {
              "taskId": "${ .taskKey }",
              "outcome": "${ .outcome }"
            }
          },
          "functionRef": {
            "refName": "logActivity",
            "arguments": {
              "message": "Task completed successfully",
              "taskId": "${ .taskKey }"
            }
          }
        }
      ],
      "eventDataFilter": {
        "data": "${ .outputs }",
        "toStateData": "$.taskOutput"
      }
    }
  ]
}
```

### **Task Outcomes**

Task outcomes define the decision paths available upon task completion, linking user decisions to specific workflow transitions.

**Properties of Task Outcome:**

| Parameter       | Description                                           | Type       | Required |
| --------------- | ----------------------------------------------------- | ---------- | -------- |
| code            | Unique identifier for the outcome.                    | string     | yes      |
| name            | Descriptive name of the outcome.                      | string     | yes      |
| outcomeDecision | Decision resulting from this outcome.                 | string     | yes      |
| formKey         | Specifies the form used for data collection.          | string     | no       |
| transition      | Directs the next workflow state based on the outcome. | Transition | no       |

This comprehensive specification and detailed description of the "UserTask State" ensure that workflows can effectively integrate human-centered tasks, with mechanisms for automated event responses and dynamic decision paths, enhancing both flexibility and control in process management.

### **Task Timers**

TBU

**Properties of Task Timer:**

| Parameter  | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Type              | Required                                          |
| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | ------------------------------------------------- |
| date       | <p>A specific point in time defined as ISO 8601 combined date and time representation. Either a <code>date</code> or a <code>duration</code> or a <code>cycle</code> must be specified; if neither is provided, the default setting is '<code>duration</code>'. </p><p>Example: <code>2025-01-01T12:00:00Z</code> or <code>2025-01-01T12:00:00+07:00</code></p>                                                                                                                                 | string            | yes (if either `duration` or `cycle` not defined) |
| duration   | <p>A duration is defined in the ISO 8601 durations format, specifying the intervening time within a time interval. Either a <code>date</code> or a <code>duration</code> or a <code>cycle</code> must be specified; if neither is provided, the default setting is '<code>duration</code>'. </p><p>Example: <code>P1D</code> or <code>PT1H30M</code></p>                                                                                                                                        | string            | yes (if either `date` or `cycle` not defined)     |
| cycle      | <p>A cycle is defined according to the ISO 8601 format for repeating intervals, which includes both the duration and the number of repetitions. If the number of repetitions is not specified, the cycle will repeat indefinitely until it is canceled. Either a <code>date</code> or a <code>duration</code> or a <code>cycle</code> must be specified; if neither is provided, the default setting is '<code>duration</code>'. </p><p>Example: <code>R2/PT1D</code> or <code>R/P1D</code></p> | string            | yes (if either `duration` or `date` not defined)  |
| actionMode | Dictates whether actions are executed `sequentially` or in `parallel`.                                                                                                                                                                                                                                                                                                                                                                                                                          | string            | no                                                |
| actions    | Actions initiated when the timer fires.                                                                                                                                                                                                                                                                                                                                                                                                                                                         | array of `Action` | yes                                               |

TBU

**Example of a Task Timer:**

{% code lineNumbers="true" %}

```json
{
    "timers": [
        {
            "duration": "PT1M",
            "actionMode": "sequential",
            "actions": [
                {
                    "functionRef": {
                        "refName": "NotifyWhenUserTaskCreated",
                        "arguments": {
                            "taskName": "${ $state.name }",
                            "requestCode": "${ .request.code }",
                            "custName": "${ .request.inputhoten }"
                        }
                    },
                    "actionDataFilter": {
                        "useResults": false
                    }
                }
            ]
        },
        {
            "cycle": "R3/PT2M",
            "actionMode": "sequential",
            "actions": [
                {
                    "functionRef": {
                        "refName": "NotifyWhenUserTaskCreated",
                        "arguments": {
                            "taskName": "${ $state.name }",
                            "requestCode": "${ .request.code }",
                            "custName": "${ .request.inputhoten }"
                        }
                    },
                    "actionDataFilter": {
                        "useResults": false
                    }
                }
            ]
        },
        {
            "cycle": "R3/PT5M/PT1M",
            "actionMode": "sequential",
            "actions": [
                {
                    "functionRef": {
                        "refName": "NotifyWhenUserTaskCreated",
                        "arguments": {
                            "taskName": "${ $state.name }",
                            "requestCode": "${ .request.code }",
                            "custName": "${ .request.inputhoten }"
                        }
                    },
                    "actionDataFilter": {
                        "useResults": false
                    }
                }
            ]
        }
    ]
}
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.a4b.vn/xflow/developer-guide/workflow-states-reference/usertask-state.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
