User tasks (User Task)
User tasks are units of work that must be performed as part of a business process for a ticket .
Key principles
- User tasks are created by the process engine according to the process model .
- When a task event occurs, the process engine publishes a
TaskDtomessage with task data to Kafka. - Cabinee finds the ticket by
businessKeyand the assignee byassignee. - A new task is bound to the found ticket, assignee, and the ticket’s space .
- An existing task is updated from the latest process-engine event.
The topic must match in producer and consumer configuration:
unibpm.camunda8.user-task-event-topic— event publication inunibpm-camunda8-adapter;camunda-kafka-import.user-task-event-topic— event import inunibpm-app.
Default configuration value: reunico.unibpm.task.events.prod.
Task data
A USER_TASK record describes task state and does not contain the task name, variables, or form reference as they were set at modeling time. unibpm-app restores these itself:
| Field | Source |
|---|---|
name | from the process model by taskDefinitionKey |
formKey | from the process model, attribute zeebe:formDefinition/@formId |
variables | via /v2/user-tasks/{userTaskKey}/variables/search |
Variables are read from secondary storage, so immediately after task creation the response may be empty — data arrives with the next task event. A read failure does not drop the event: the task is created without variables.
On creation the task first appears without an assignee, and only then does the assignment event arrive. Therefore a newly created task may have an empty assignee even if the model specifies one.
Main attributes
| Attribute | Type | Source and purpose |
|---|---|---|
id | String | Task identifier in the process engine |
name | String | Task name |
description | String | Task description |
priority | Integer | Task priority |
processInstanceId | String | Process instance identifier |
taskDefinitionKey | String | User Task key in the BPMN model |
assignee | User | Current assignee |
ticket | Ticket | Parent ticket, found by businessKey |
workflow | Workflow | Task space; copied from ticket.workflow on creation |
dueDate | Instant | Due date from Camunda |
completedTime | Instant | Time the task moved to a terminal state |
variables | Map<String, Object> | Process instance variables |
localVariables | Map<String, Object> | Task local variables |
availability | TaskAvailability | Computed availability for the current user |
dueDate and completedTime in the REST API are ISO 8601, for example 2026-08-25T15:30:00Z. dueDate may be absent (null) if no due date is set in the process engine.
The availability field is not stored in the database and is not sent by the process engine. Cabinee computes it when building the REST response relative to the current user.
Due date and space synchronization rules
dueDateis managed by the process engine. If Camunda changes the due date, the next task event updatesTask.dueDatein Cabinee.workflowis set only when the task is created astask.ticket.workflow.- After creation, the task’s link to the space is not changed by Camunda events or REST operations. At the ORM level, column
workflow_idis not updatable.
This denormalized link lets you filter tasks by space and apply access restrictions without an extra join through the ticket.
TaskDto event contract
A user-task message includes fields such as:
{
"id": "8f45d5c2-...",
"name": "Approve ticket",
"eventName": "create",
"assignee": "user-id",
"businessKey": "bd7f1b04-...",
"processInstanceId": "f5c03be9-...",
"taskDefinitionKey": "Activity_approve",
"dueDate": "2026-08-25T15:30:00Z"
}
workflow is not passed in TaskDto: Cabinee determines it from the parent ticket’s space.
Task statuses
A process-engine event is mapped to a Cabinee status:
| Event | Status |
|---|---|
create | NEW — new task |
assignment | ASSIGNED — assigned |
complete | COMPLETED — completed |
delete | DELETED — deleted |
A user task can have an associated screen form in Camunda Forms format. Screen form templates are stored in space artifacts .
Task availability for the current user
The availability field shows the current user’s role relative to a specific task and helps the client choose the available interaction scenario.
Possible values:
| Value | Conditions |
|---|---|
ASSIGNEE | The task is in status ASSIGNED, and task.assignee matches the current user |
CANDIDATE | The task is in status NEW, there is no assignee, and the current user is listed among candidates directly or belongs to at least one candidate group |
NONE | None of the conditions above apply |
User and group candidates from TaskDto.candidateUsers and TaskDto.candidateGroups are materialized in Cabinee as TaskPermission records. When computing CANDIDATE, both personal records for the current user and records for their groups are considered.
If several conditions apply at once, priority is:
ASSIGNEE > CANDIDATE > NONE
Thus:
- a candidate who claims the task gets
ASSIGNEE; - a candidate after the task is assigned to another user gets
NONE, even if theTaskPermissionrecord still exists; - for tasks in statuses
COMPLETEDandDELETED, a regular user getsNONE.
availabilityis UI context, not a security boundary by itself. Task visibility and permission to perform REST operations are still checked by the server throughPermissionService.
Retrieving and filtering tasks
The task list is returned by GET /api/task. In addition to standard criteria, the following are supported:
workflowId— filter by space identifier;dueDate— range filter by due date;availability— filter by computed availability for the current user.
Examples:
GET /api/task?workflowId.equals=9d3d80a3-5e6d-4ccd-a85f-9d40aaf83b21
GET /api/task?dueDate.greaterThanOrEqual=2026-08-10T00:00:00Z&dueDate.lessThan=2026-09-01T00:00:00Z
GET /api/task?availability.equals=CANDIDATE
GET /api/task?availability.in=ASSIGNEE,CANDIDATE
Filtering by availability is performed in the database before pagination. Therefore page size and totalElements reflect the already filtered set. The value is computed in the context of the current user: for example, availability.equals=NONE returns visible tasks for which the user is neither assignee nor candidate. An administrative role is not encoded in availability and is checked by the client separately.
Criteria can be combined with each other and with pagination parameters. Full operator descriptions are in Filters .
Available task operations
assign— assign the task to a user;claim— assign the task to yourself;unassign— remove the task assignee;complete— complete the task.
When the
completeoperation is performed, a request that completes the task is sent to the process engine.