Task History: Access "completed by user"

Is there any ability in history api to access who completed a task? I don’t see it in any entities, api’s or tables.

This seems to be important information, as I could have task get completed by somebody who is not the assignee, if done from Task List or API.

Example - Identity links only track these three items (which don’t include completedByUser), and seem to be supported in historical values:

public class IdentityLinkType {
    public static final String ASSIGNEE = "assignee";
  public static final String CANDIDATE = "candidate";
  public static final String OWNER = "owner";
}

@Autowired
HistoryService historyService;

public void test(){
    HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery()
            .processInstanceId("processInstanceId")
            .singleResult();
    String assignee = historicTaskInstance.getAssignee();
    System.out.println(assignee);
}

Hope it helps!

Yeah, I can see the assignee, but I want the value when a different user completes the task.

EG: assignee is ‘joe’, but ‘bob’ completes the task on joe’s behalf. I want a “completed by” value (bob), which is common to any audit system, but I don’t see that getting tracked anywhere.

Thanks!

Hi @Scott_Langeberg,

you can find the information in the user operations log: https://docs.camunda.org/manual/7.14/user-guide/process-engine/history/#user-operation-log.

The enterprise edition has a cockpit view to inspect them: https://docs.camunda.org/manual/7.14/webapps/cockpit/auditing/.

Hope this helps, Ingo

2 Likes

I suppose i should have looked up “audit” in the docs :wink:

Initial inspection shows tracking in ACT_HI_OP_LOG table, where operation_type is “Complete” for user_id.

Thank you so much, Ingo!

Scott

and matching code for posterity sake:

  filtered.stream().map(historicActivityInstance -> {
            final var taskId = historicActivityInstance.getTaskId();
            if (nonNull(taskId)) {
                UserOperationLogEntry taskCompletedEntry = historyService.createUserOperationLogQuery()
                    .taskId(taskId)
                    .operationType(UserOperationLogEntry.OPERATION_TYPE_COMPLETE)
                    .singleResult();
                if (nonNull(taskCompletedEntry)) {
                   final String completedBy = taskCompletedEntry.getUserId();
                }