initial
This commit is contained in:
@@ -0,0 +1,216 @@
|
||||
# Create Vitruvio Process BPMN
|
||||
|
||||
> All messages shown to the user must be written in Portuguese.
|
||||
|
||||
You are creating the **BPMN workflow file** of a Vitruvio process. This skill is focused
|
||||
on the `.bpmn` file only — the desktop form is handled by **vitruvio-criar-form-desktop**
|
||||
(process variant) and the mobile form by **vitruvio-criar-form-mobile** (process variant).
|
||||
|
||||
## Step 1 — Confirm you are inside a Vitruvio repo
|
||||
|
||||
```bash
|
||||
ls vitruvio.json 2>/dev/null && echo "OK" || echo "NOT_A_VITRUVIO_REPO"
|
||||
```
|
||||
|
||||
If `NOT_A_VITRUVIO_REPO`, stop and tell the user to `cd` into the correct repo.
|
||||
|
||||
## Step 2 — Collect flow details
|
||||
|
||||
Ask the user (in a single message, only ask what is missing):
|
||||
|
||||
- **Key** — snake_case or camelCase unique identifier. Becomes the BPMN process ID and the
|
||||
folder name. Must match the `key` used for the process in `vitruvio.json`.
|
||||
- **Name** — human-readable label.
|
||||
- **Who can start it?** — group key(s) allowed to open the process (e.g. `gestao`,
|
||||
`admin`). Used in `activiti:candidateStarterGroups`.
|
||||
- **Steps** — the human tasks (user tasks), and which group handles each. A simple linear
|
||||
flow is enough to start.
|
||||
- **Decisions / branches?** — any exclusive gateways with conditions.
|
||||
- **Automatic steps?** — any script tasks running between user tasks.
|
||||
|
||||
## Step 3 — Write the BPMN file: `processes/<key>/<key>.bpmn`
|
||||
|
||||
### Critical rules
|
||||
|
||||
- The `<bpmn2:process id="...">` value is the canonical process identity. The importer
|
||||
reads it from the BPMN, not from vitruvio.json. **It must match the `key`.**
|
||||
- Every node must appear in a `<bpmn2:laneSet>` / `<bpmn2:lane>` **and** in the
|
||||
`<bpmndi:BPMNDi>` section — Vitruvio renders the diagram.
|
||||
- Each `activiti:formKey` on the start event and user tasks must match a
|
||||
`<form formKey="...">` in the desktop form XML (and mobile form, if present).
|
||||
- Process variables from submitted forms are auto-named `{formKey}_{fieldId}`
|
||||
(e.g. `formAbertura_status`). Gateway conditions reference them.
|
||||
- Gateway conditions use `#{variable == 'value'}` (JUEL expression language).
|
||||
- Script tasks call `vScriptService.loadScript('scriptKey', 'javascript')`, **not**
|
||||
`libService`.
|
||||
|
||||
### Minimal skeleton (start → user task → end, single lane)
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bpmn2:definitions
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL"
|
||||
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
|
||||
xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
|
||||
xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
|
||||
xmlns:activiti="http://activiti.org/bpmn"
|
||||
id="sample-diagram"
|
||||
targetNamespace="http://bpmn.io/schema/bpmn"
|
||||
exporter="bpmn-js (https://demo.bpmn.io)"
|
||||
exporterVersion="8.2.0"
|
||||
xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
|
||||
|
||||
<bpmn2:collaboration id="Collaboration_<key>">
|
||||
<bpmn2:participant id="processo_<key>" name="<Name>" processRef="<key>" />
|
||||
</bpmn2:collaboration>
|
||||
|
||||
<bpmn2:process id="<key>" name="<Name>" isExecutable="true"
|
||||
activiti:candidateStarterGroups="<starterGroup>">
|
||||
<bpmn2:laneSet>
|
||||
<bpmn2:lane id="lane_execucao" name="Execução">
|
||||
<bpmn2:flowNodeRef>inicio</bpmn2:flowNodeRef>
|
||||
<bpmn2:flowNodeRef>task_executar</bpmn2:flowNodeRef>
|
||||
<bpmn2:flowNodeRef>fim</bpmn2:flowNodeRef>
|
||||
</bpmn2:lane>
|
||||
</bpmn2:laneSet>
|
||||
|
||||
<!-- Start event: activiti:initiator stores the login of who opened the process -->
|
||||
<bpmn2:startEvent id="inicio" name="Início"
|
||||
activiti:formKey="formAbertura"
|
||||
activiti:initiator="iniciador">
|
||||
<bpmn2:outgoing>flow_inicio_task</bpmn2:outgoing>
|
||||
</bpmn2:startEvent>
|
||||
|
||||
<!-- User task: candidateGroups controls who sees it in their inbox -->
|
||||
<bpmn2:userTask id="task_executar" name="Executar"
|
||||
activiti:formKey="formExecutar"
|
||||
activiti:candidateGroups="${vStringUtils.validateRoles(gr_executores)}">
|
||||
<bpmn2:incoming>flow_inicio_task</bpmn2:incoming>
|
||||
<bpmn2:outgoing>flow_task_fim</bpmn2:outgoing>
|
||||
</bpmn2:userTask>
|
||||
|
||||
<!-- Script task example (omit if not needed):
|
||||
<bpmn2:scriptTask id="script_processar" name="Processar" scriptFormat="javascript">
|
||||
<bpmn2:incoming>flow_task_script</bpmn2:incoming>
|
||||
<bpmn2:outgoing>flow_script_fim</bpmn2:outgoing>
|
||||
<bpmn2:script>var f = vScriptService.loadScript('meu_script', 'javascript');
|
||||
f(execution);</bpmn2:script>
|
||||
</bpmn2:scriptTask>
|
||||
-->
|
||||
|
||||
<!-- Exclusive gateway example (omit if not needed):
|
||||
<bpmn2:exclusiveGateway id="gw_decisao" name="Aprovado?">
|
||||
<bpmn2:incoming>flow_task_gw</bpmn2:incoming>
|
||||
<bpmn2:outgoing>flow_sim</bpmn2:outgoing>
|
||||
<bpmn2:outgoing>flow_nao</bpmn2:outgoing>
|
||||
</bpmn2:exclusiveGateway>
|
||||
<bpmn2:sequenceFlow id="flow_sim" name="Sim" sourceRef="gw_decisao" targetRef="fim">
|
||||
<bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">#{formExecutar_aprovado == '1'}</bpmn2:conditionExpression>
|
||||
</bpmn2:sequenceFlow>
|
||||
<bpmn2:sequenceFlow id="flow_nao" name="Não" sourceRef="gw_decisao" targetRef="task_executar">
|
||||
<bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">#{formExecutar_aprovado == '0'}</bpmn2:conditionExpression>
|
||||
</bpmn2:sequenceFlow>
|
||||
-->
|
||||
|
||||
<bpmn2:endEvent id="fim" name="Fim">
|
||||
<bpmn2:incoming>flow_task_fim</bpmn2:incoming>
|
||||
</bpmn2:endEvent>
|
||||
|
||||
<bpmn2:sequenceFlow id="flow_inicio_task" sourceRef="inicio" targetRef="task_executar" />
|
||||
<bpmn2:sequenceFlow id="flow_task_fim" sourceRef="task_executar" targetRef="fim" />
|
||||
</bpmn2:process>
|
||||
|
||||
<!-- BPMNDi: visual layout — required for the diagram to render -->
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_<key>">
|
||||
|
||||
<bpmndi:BPMNShape id="Participant_di" bpmnElement="processo_<key>" isHorizontal="true">
|
||||
<dc:Bounds x="100" y="80" width="750" height="180" />
|
||||
</bpmndi:BPMNShape>
|
||||
|
||||
<bpmndi:BPMNShape id="lane_execucao_di" bpmnElement="lane_execucao" isHorizontal="true">
|
||||
<dc:Bounds x="130" y="80" width="720" height="180" />
|
||||
</bpmndi:BPMNShape>
|
||||
|
||||
<bpmndi:BPMNShape id="inicio_di" bpmnElement="inicio">
|
||||
<dc:Bounds x="192" y="152" width="36" height="36" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="195" y="195" width="30" height="14" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
|
||||
<bpmndi:BPMNShape id="task_executar_di" bpmnElement="task_executar">
|
||||
<dc:Bounds x="310" y="130" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
|
||||
<bpmndi:BPMNShape id="fim_di" bpmnElement="fim">
|
||||
<dc:Bounds x="492" y="152" width="36" height="36" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="497" y="195" width="19" height="14" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
|
||||
<bpmndi:BPMNEdge id="flow_inicio_task_di" bpmnElement="flow_inicio_task">
|
||||
<di:waypoint x="228" y="170" />
|
||||
<di:waypoint x="310" y="170" />
|
||||
</bpmndi:BPMNEdge>
|
||||
|
||||
<bpmndi:BPMNEdge id="flow_task_fim_di" bpmnElement="flow_task_fim">
|
||||
<di:waypoint x="410" y="170" />
|
||||
<di:waypoint x="492" y="170" />
|
||||
</bpmndi:BPMNEdge>
|
||||
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn2:definitions>
|
||||
```
|
||||
|
||||
### Multi-lane pattern (when tasks belong to different roles)
|
||||
|
||||
Add each lane inside `<bpmn2:laneSet>`, list the node IDs inside each lane, and adjust
|
||||
the BPMNDi bounds:
|
||||
|
||||
```xml
|
||||
<bpmn2:laneSet>
|
||||
<bpmn2:lane id="lane_gestao" name="Gestão">
|
||||
<bpmn2:flowNodeRef>inicio</bpmn2:flowNodeRef>
|
||||
<bpmn2:flowNodeRef>fim</bpmn2:flowNodeRef>
|
||||
</bpmn2:lane>
|
||||
<bpmn2:lane id="lane_execucao" name="Execução">
|
||||
<bpmn2:flowNodeRef>task_executar</bpmn2:flowNodeRef>
|
||||
</bpmn2:lane>
|
||||
</bpmn2:laneSet>
|
||||
```
|
||||
|
||||
### Script task — script side
|
||||
|
||||
```javascript
|
||||
// In <bpmn2:script> inside a scriptTask:
|
||||
var f = vScriptService.loadScript('meu_script', 'javascript');
|
||||
f(execution);
|
||||
|
||||
// In the script file itself (pattern: process/task script — see vitruvio-criar-script):
|
||||
(function(execution) {
|
||||
var db = libService.loadScript('db');
|
||||
var banco = new db(db.VITRUVIO_DATASOURCE);
|
||||
var status = execution.getVariable('formAbertura_status');
|
||||
// ...
|
||||
})(execution)
|
||||
```
|
||||
|
||||
## Step 4 — Manifest
|
||||
|
||||
If this skill is run **standalone** (the process already exists in `vitruvio.json`),
|
||||
ensure its entry has `"bpmn": "processes/<key>/<key>.bpmn"`. Do not create or modify
|
||||
the rest of the entry here — full registration is handled by **vitruvio-criar-processo**.
|
||||
|
||||
## Step 5 — Report
|
||||
|
||||
Tell the user:
|
||||
- File created/updated: `processes/<key>/<key>.bpmn`
|
||||
- The process identity is the `<bpmn2:process id>` — it must match the key.
|
||||
- Each `activiti:formKey` must have a matching `<form formKey="...">` in the form XML
|
||||
(create/update it with **vitruvio-criar-form-desktop** / **vitruvio-criar-form-mobile**).
|
||||
- Submitted field `id="X"` in `formKey="formAbertura"` becomes variable `formAbertura_X`.
|
||||
- For complex flows, recommend editing the BPMN in bpmn.io or Camunda Modeler before deploying.
|
||||
Reference in New Issue
Block a user