Files
jogos_matheus/.claude/skills/vitruvio-criar-processo-bpmn/SKILL.md
T
2026-09-23 12:29:08 -03:00

228 lines
9.4 KiB
Markdown

---
name: vitruvio-criar-processo-bpmn
description: >
Use when the user wants to create or edit only the BPMN workflow file of a Vitruvio
process (the Activiti flow: lanes, tasks, gateways, sequence flows), without touching
the forms. Triggers: "create bpmn", "criar bpmn", "novo bpmn", "fluxo do processo",
"workflow do processo", "só o bpmn", "process flow", "edit the bpmn".
For the full process (BPMN + forms + manifest) use vitruvio-criar-processo, which calls
this skill for the BPMN part.
---
# 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.