167 lines
5.2 KiB
Markdown
167 lines
5.2 KiB
Markdown
# Processes
|
|
|
|
BPMN workflows powered by Activiti. Each process lives in its own subdirectory.
|
|
|
|
```
|
|
processes/
|
|
<process-key>/
|
|
<process-key>.bpmn
|
|
<process-key>-desktop.xml
|
|
<process-key>-mobile.xml # optional when process involves mobile tasks.
|
|
<process-key>-mobile-alt.xml # optional when the client uses two versions of the mobile with different APIs. User should point the need for that one out.
|
|
```
|
|
|
|
The XML form rules, components, engine API, and JS constraints are the same as panels — see `panels/CLAUDE.md`. This file covers only the differences.
|
|
|
|
---
|
|
|
|
## vitruvio.json registration
|
|
|
|
```json
|
|
"processes": [
|
|
{
|
|
"key": "my-process",
|
|
"name": "My Process",
|
|
"bpmn": "processes/my-process/my-process.bpmn",
|
|
"forms": {
|
|
"desktop": "processes/my-process/my-process-desktop.xml",
|
|
"mobile": null,
|
|
"mobileAlternative": null
|
|
},
|
|
"schedules": [
|
|
{
|
|
"name": "Daily trigger",
|
|
"trigger": { "type": "cron", "expression": "0 0 0 * * ?" }
|
|
}
|
|
]
|
|
}
|
|
]
|
|
```
|
|
|
|
`schedules` is optional. Trigger types: `"cron"` (Quartz expression) or `"simple"` (`intervalMs` + `repeatCount: -1` for indefinite).
|
|
|
|
---
|
|
|
|
## Form XML — key differences from panels
|
|
|
|
The root element is `<forms>` (not `<form>`), with a `processKey` attribute matching the BPMN process id:
|
|
|
|
```xml
|
|
<forms xmlns="http://www.davinti.com.br/vitruvio/form"
|
|
xmlns:xsi="..."
|
|
xsi:schemaLocation="..."
|
|
processKey="my-process">
|
|
|
|
<library>
|
|
<!-- reusable complex-component definitions -->
|
|
</library>
|
|
|
|
<form formKey="formAbertura" width="100%">
|
|
<!-- components for the start event / opening task -->
|
|
</form>
|
|
|
|
<form formKey="formAprovacao" width="100%">
|
|
<!-- components for approval task -->
|
|
</form>
|
|
|
|
</forms>
|
|
```
|
|
|
|
### `<library>`
|
|
|
|
Define reusable `<complex-component>` blocks here and reference them by id in task forms. Avoids repeating the same layout across multiple task forms.
|
|
|
|
### `<form formKey="...">`
|
|
|
|
Each `<form>` corresponds to one BPMN user task (via `activiti:formKey`). The keys must match exactly. One process can have many task forms in the same XML file.
|
|
|
|
---
|
|
|
|
## BPMN — key attributes
|
|
|
|
### User tasks
|
|
```xml
|
|
<bpmn2:userTask id="Task_Approve" name="Approve"
|
|
activiti:formKey="formAprovacao"
|
|
activiti:candidateGroups="group-key"
|
|
activiti:assignee="${someVar}">
|
|
```
|
|
|
|
- `activiti:formKey` — must match a `<form formKey="...">` in the desktop/mobile XML.
|
|
- `activiti:candidateGroups` — group key(s) that can claim this task.
|
|
- `activiti:assignee` — specific user expression (optional, overrides candidate groups).
|
|
|
|
### Start event
|
|
```xml
|
|
<bpmn2:startEvent id="start" activiti:formKey="formAbertura" activiti:initiator="owner">
|
|
```
|
|
|
|
`activiti:initiator="owner"` stores the login of whoever opened the process into the `owner` process variable.
|
|
|
|
### Sequence flow conditions
|
|
Conditions reference process variables using JUEL syntax:
|
|
```xml
|
|
<bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">
|
|
#{formAbertura_aprovado=='1'}
|
|
</bpmn2:conditionExpression>
|
|
```
|
|
|
|
Process variables are set by the form engine automatically following the convention `{formKey}_{fieldId}` when a task is completed. They can also be set explicitly in script tasks via the `execution` object.
|
|
|
|
### Script tasks
|
|
```xml
|
|
<bpmn2:scriptTask id="myScript" name="Do something" scriptFormat="javascript">
|
|
<bpmn2:script>
|
|
var lib = vScriptService.loadScript('my-lib', 'javascript');
|
|
var obj = new lib.MyClass();
|
|
obj.doWork(execution);
|
|
</bpmn2:script>
|
|
</bpmn2:scriptTask>
|
|
```
|
|
|
|
- Use `vScriptService.loadScript(key, 'javascript')` — **not** `libService.loadScript()`.
|
|
- `execution` is the Activiti execution context. Use it to read/write process variables:
|
|
```javascript
|
|
execution.getVariable('myVar');
|
|
execution.setVariable('myVar', value);
|
|
```
|
|
|
|
### Task listeners
|
|
Listeners run on task lifecycle events (`create`, `complete`, `assignment`):
|
|
```xml
|
|
<activiti:taskListener class="org.activiti.engine.impl.bpmn.listener.ScriptTaskListener" event="create">
|
|
<activiti:field name="language"><activiti:string>javascript</activiti:string></activiti:field>
|
|
<activiti:field name="script">
|
|
<activiti:string>
|
|
var lib = vScriptService.loadScript('my-lib', 'javascript');
|
|
lib.onTaskCreate(task);
|
|
</activiti:string>
|
|
</activiti:field>
|
|
</activiti:taskListener>
|
|
```
|
|
|
|
`task` is available in listeners (not `execution`). Use `task.getExecution()` if you need the execution context.
|
|
|
|
---
|
|
|
|
## Engine extras in process forms
|
|
|
|
These are available in addition to the standard panel engine API:
|
|
|
|
| Method | Description |
|
|
| ------------------------- | ---------------------------------------------------------------------- |
|
|
| `engine.formKey()` | Returns the `formKey` of the currently active task form |
|
|
| `engine.isTaskComplete()` | Returns `true` if the task has already been completed (read-only view) |
|
|
|
|
Use `engine.formKey()` to share `initScript` logic across multiple task forms with different initialization paths:
|
|
|
|
```javascript
|
|
function run() {
|
|
if (engine.formKey() == 'formAbertura') {
|
|
// init for opening form
|
|
} else if (engine.formKey() == 'formAprovacao') {
|
|
// init for approval form
|
|
}
|
|
}
|
|
```
|