A history is identified by a unique key, made up of up to five labels (labels a-e). By convention labela is the name of a workflow process (for histories created by the workflow engine) or the name of a form (for histories created using the history event form action). Labelb is a unique ID. This is either the workflow instance business key, or an ID generated by the history event form action.
The use of these two labels is enough to identify a service, then uniquely log and retrieve a history record from that service.
Creating Related Histories - Label C
Using an additional label, labelc, we have developed a set of conventions for creating subsets of history records, related to the main labela/labelb record. These brand new histories share the labela and labelb values of the main record, but are used to store information for summaries, reporting, auditing or additional notes. By carefully considering the data that gets saved in these sub-histories, it's possible to create records that contain no identifiable user information.
The labelc values we're currently using are:
labelc | Purpose |
---|---|
blank | A standard history created and written to by forms and workflow process instances. These histories will likely contain user data in their events and summaries. They will be subject to your data retention policies and may have to be deleted on request. These histories appear in the Self Service and User Requests templates |
notes | These histories are updated alongside the standard history. Their events are used to store notes relevant to the service, added either by the agent handling the service request or the user. These histories should normally be deleted with the main history |
attachments | As explained in Handling File Uploads, a history event can hold file references that identify files uploaded to the API Server's filestore. By recording references in an "attachments history" these file references can be shared between processes. There's an example of this in the Case Management solution. These histories should be deleted with the main history |
Holds sent email records, including the body and email address These histories should be deleted with the main history | |
reporting | When designing your service there will be aspects of it that you want to report on. We store this information in a "reporting history". No personal identifiable information should be saved in these histories, meaning that they needn't be deleted with the main history |
reporting_modifier | A modifier or subset of the reporting data (see below). You might use these histories to log daily or weekly summary data. As long as these summaries don't contain any identifiable information, they needn't be deleted |
audit | Audit can be used to record the fact that other histories have been deleted. They shouldn't contain any personal data and should not be deleted |
Reporting
The reports we generate for the services we design are generally displayed using our Performance Dashboards. The dashboards will, in a future version, look for and report on histories with a labelc of "reporting" (the current version 1.4 only reports on histories with a blank labelc). The information you save to these histories shouldn't contain any user data. They might record:
- Dates
- A count of requests opened
- A count of requests closed
- Request durations
- A location (for example where graffiti or fly-tipping occurred)
When you have a large number of history records it's often useful to create summary data records to speed up processing and retrieval. The conventions we use for these histories are:
- labela: The process/form name (as normal). This is kept the same to link this history to its parent
- labelb: The date (in ISO8601 format). Even though stored as a string, the ISO8601 format allows us to do basic querying
- labelc: reporting_modifier (where modifier is typically daily/weekly etc). The modifier is needed to prevent these histories being included in the data reported on standard dashboards
Example
This process creates and maintains three histories.
Main History
The main history has standard labela and labelb values, generated when the process starts. This history records the initial form submission, the user task form submission, and workflow summary events. This is the history that will be seen in the Self Service and User Requests articles used by the agent and user who submitted the form that started the process.
Here's a simplified version (so it fits on the page). It includes all of the usual form data and user IDs generated by a service.
{
"jsonrpc": "2.0",
"id": 1374,
"result": {
"result": {
"result": {
"labela": "example history",
"labelb": "8348-2799-2852-1446",
"labelc": null,
"labeld": null,
"labele": null,
"subject": {...},
"events": [{
"pos": [1, 6],
"event": {
"private": false,
"description": "Process Started",
"formData": {
"data": {
"TEXT1": "value for text1"
}
},
"event": "STARTWORKFLOW",
"userRole": "user",
"userId": "ANONYMOUS"
}
}, {
"pos": [2, 6],
"event": {
"taskDefinitionKey": "ReviewTask",
"private": true,
"description": "Task 117801 claimed for user \"timg\"",
"event": "CLAIMTASK",
"userRole": "workflowengine",
"userId": "TIMG",
"taskId": "117801"
}
}, {
"pos": [3, 6],
"event": {
"taskDefinitionKey": "ReviewTask",
"private": false,
"description": "ReviewTask",
"formData": {
"data": {
"NOTES": "Some notes",
"TEXT2": "value for text2",
"RADIOGROUP": "Yes"
}
},
"event": "COMPLETETASK",
"userRole": "user",
"userId": "TIMG",
"taskId": "117801"
}
}, {
"pos": [4, 6],
"event": {
"taskDefinitionKey": "ReviewTask",
"private": true,
"description": "Task 117819 claimed for user \"timg\"",
"event": "CLAIMTASK",
"userRole": "workflowengine",
"userId": "TIMG",
"taskId": "117819"
}
}, {
"pos": [5, 6],
"event": {
"taskDefinitionKey": "ReviewTask",
"private": false,
"description": "ReviewTask",
"formData": {
"data": {
"NOTES": "Some more notes",
"TEXT2": "Another value for text2",
"RADIOGROUP": "No"
}
},
"event": "COMPLETETASK",
"userRole": "user",
"userId": "TIMG",
"taskId": "117819"
}
}, {
"pos": [6, 6],
"event": {
"private": false,
"description": "Process Ended",
"event": "PROCESSENDED",
"userRole": "workflowengine",
"userId": null
}
}]
}
},
"id": "_42",
"jsonrpc": "2.0"
}
}
Reporting History
The reporting history is updated by three tasks. They have the following labels. Labela and labelb match the main history:
- labela:
myExampleProcess - labelb:
${businessKey} - labelc:
reporting
Task one records the process start time, task two adds an event with a timestamp each time a note is added, and task three logs an event with the end time. This means we can generate reports that count the number of requests in a given time period, report on the length of time between a request being raised and closed, and calculate response times and frequency between notes.
Nothing written to the reporting history includes any personal information or anything that could identify the user or agent.
This is the reporting history that relates to the history above. Again some standard properties have been removed (time stamps and filter positions) to make it easier to read. It contains no data from the forms themselves - all of the event data is set in the workflow history activities.
{
"jsonrpc": "2.0",
"id": 1375,
"result": {
"result": {
"result": {
"labela": "example history",
"labelb": "8348-2799-2852-1446",
"labelc": "reporting",
"labeld": null,
"labele": null,
"created": 1549900107397,
"sealed": false,
"subject": {
"description": "Reporting History"
},
"events": [{
"pos": [1, 3],
"event": {
"taskname": "Reporting History 1",
"started": "2019-02-11T15:48:27Z",
"event": "The process started"
}
}, {
"pos": [2, 3],
"event": {
"private": false,
"taskname": "Reporting History 2",
"time": "2019-02-11T15:48:55Z",
"event": "Notes have been added"
}
}, {
"pos": [3, 3],
"event": {
"private": false,
"taskname": "Reporting History 3",
"endTime": "2019-02-11T15:49:27.769Z",
"event": "Complete"
}
}]
}
},
"id": "_47",
"jsonrpc": "2.0"
}
}
Notes
The "Add Notes" history tasks save a value from the review task form in a history event. Labela and labelb are the same as the main history, labelc is
{
"jsonrpc": "2.0",
"id": 1376,
"result": {
"result": {
"result": {
"labela": "example history",
"labelb": "8348-2799-2852-1446",
"labelc": "notes",
"labeld": null,
"labele": null,
"created": 1549900150947,
"sealed": false,
"subject": null,
"lastupdated": 1549900167757,
"id": "286d4ed1-a50e-4859-9b88-ae4ec12f3273",
"events": [{
"pos": [1, 2],
"event": {
"taskname": "Notes",
"Notes": "Some notes"
},
"fpos": [1, 2],
"timestamp": 1549900150947
}, {
"pos": [2, 2],
"event": {
"taskname": "Notes",
"Notes": "Some more notes"
},
"fpos": [2, 2],
"timestamp": 1549900167757
}]
}
},
"id": "_52",
"jsonrpc": "2.0"
}
}