# Processes BPMN workflows powered by Activiti. Each process lives in its own subdirectory. ``` processes/ / .bpmn -desktop.xml -mobile.xml # optional when process involves mobile tasks. -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 `` (not `
`), with a `processKey` attribute matching the BPMN process id: ```xml
``` ### `` Define reusable `` blocks here and reference them by id in task forms. Avoids repeating the same layout across multiple task forms. ### `
` Each `` 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 ``` - `activiti:formKey` — must match a `` 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 ``` `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 #{formAbertura_aprovado=='1'} ``` 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 var lib = vScriptService.loadScript('my-lib', 'javascript'); var obj = new lib.MyClass(); obj.doWork(execution); ``` - 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 javascript var lib = vScriptService.loadScript('my-lib', 'javascript'); lib.onTaskCreate(task); ``` `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 } } ```