Initial: kyrykbaev_i joins the platform
This commit is contained in:
commit
0d2ab71165
33
.gitignore
vendored
Normal file
33
.gitignore
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
# secrets
|
||||
.env
|
||||
.env.local
|
||||
.jwt-secret
|
||||
credentials*.json
|
||||
secrets.json
|
||||
*.pem
|
||||
*.key
|
||||
id_rsa*
|
||||
id_ed25519*
|
||||
|
||||
# build artifacts
|
||||
node_modules/
|
||||
.venv/
|
||||
venv/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.next/
|
||||
dist/
|
||||
build/
|
||||
out/
|
||||
target/
|
||||
|
||||
# data
|
||||
*.sqlite*
|
||||
*.db
|
||||
*.log
|
||||
|
||||
# OS / IDE
|
||||
.DS_Store
|
||||
.claude/
|
||||
.vscode/
|
||||
.idea/
|
||||
23
PRD.md
Normal file
23
PRD.md
Normal file
@ -0,0 +1,23 @@
|
||||
# Product Requirements Description
|
||||
|
||||
## Что я хочу автоматизировать
|
||||
<!-- Опиши простыми словами, какую боль ты решаешь -->
|
||||
|
||||
|
||||
## Кто будет пользоваться
|
||||
<!-- Финансист? Руководитель? Бухгалтер? -->
|
||||
|
||||
|
||||
## Что должно произойти на выходе
|
||||
<!-- Какой результат ты получишь, и кто его получает? -->
|
||||
|
||||
|
||||
## Шаги взаимодействия
|
||||
<!-- 1. Пользователь делает X
|
||||
2. Система проверяет Y
|
||||
3. Если Z — ... иначе — ... -->
|
||||
|
||||
|
||||
## Что НЕ входит в задачу
|
||||
<!-- Чтобы не разрастаться -->
|
||||
|
||||
26
README.md
Normal file
26
README.md
Normal file
@ -0,0 +1,26 @@
|
||||
# kyrykbaev_i
|
||||
|
||||
Привет, kyrykbaev_i!
|
||||
|
||||
Это твоя личная папка в среде telecom.quest.
|
||||
- VS Code в браузере: https://code.telecom.quest/?folder=/Users/telecom/dev/_hack18may/kyrykbaev_i/
|
||||
- Бэкап на Gitea: https://git.telecom.quest/kt-innovators/kyrykbaev_i
|
||||
|
||||
## Action Plan (как пользоваться)
|
||||
|
||||
В этой папке уже лежат три стартовых файла:
|
||||
- `PRD.md` — здесь ты простыми словами описываешь, что хочешь автоматизировать
|
||||
- `ZORRO.md` — справочник по системе Zorro (для Claude, не для тебя)
|
||||
- `TRD.md` — пустой; Claude заполнит его после того, как ты напишешь PRD
|
||||
|
||||
**Шаг 1.** Открой `PRD.md` и напиши свою идею.
|
||||
**Шаг 2.** Открой Claude (Desktop или web). Дай ему `PRD.md` + `ZORRO.md` и попроси: «Сделай TRD.md на основе PRD и ZORRO».
|
||||
**Шаг 3.** Сохрани результат в `TRD.md`.
|
||||
**Шаг 4.** Запусти Claude Code в этой папке. Скажи: «Реализуй TRD.md». Получишь рабочий MVP.
|
||||
|
||||
## Как сохранять работу
|
||||
|
||||
В VS Code открой панель "Source Control" (слева), напиши краткое описание, нажми галочку → "Commit and Push".
|
||||
Изменения сохранятся в Gitea и будут доступны при следующем входе.
|
||||
|
||||
В этой папке уже инициализирован git и подключен remote `origin` → Gitea.
|
||||
15
TRD.md
Normal file
15
TRD.md
Normal file
@ -0,0 +1,15 @@
|
||||
# Technical Requirements Description
|
||||
|
||||
<!--
|
||||
Этот файл создаст Claude.
|
||||
|
||||
Открой Claude (Desktop или web), приложи:
|
||||
1. этот файл (или скажи "сделай TRD.md")
|
||||
2. PRD.md (твоё описание идеи)
|
||||
3. ZORRO.md (справочник по Zorro)
|
||||
|
||||
Попроси: "Сделай TRD на основе PRD и ZORRO. Опиши какие BPMN-задачи нужны,
|
||||
какие API-эндпоинты Zorro вызывать, какие данные передавать."
|
||||
|
||||
Полученный текст положи сюда (замени этот комментарий).
|
||||
-->
|
||||
598
ZORRO.md
Normal file
598
ZORRO.md
Normal file
@ -0,0 +1,598 @@
|
||||
# ZorroBPM Development Guide
|
||||
|
||||
Единый справочник для разработки процессов на ZorroBPM.
|
||||
|
||||
---
|
||||
|
||||
## Содержание
|
||||
|
||||
- [Архитектура](#архитектура)
|
||||
- [Окружения](#окружения)
|
||||
- [Локальный запуск](#локальный-запуск)
|
||||
- [Docker Compose — полный стек](#docker-compose--полный-стек)
|
||||
- [Docker Compose — только фронт (dev)](#docker-compose--только-фронт-dev)
|
||||
- [Docker Compose — фронт + воркеры](#docker-compose--фронт--воркеры)
|
||||
- [API Reference](#api-reference)
|
||||
- [RabbitMQ и внешние воркеры](#rabbitmq-и-внешние-воркеры)
|
||||
- [Разработка процессов](#разработка-процессов)
|
||||
- [Тестирование](#тестирование)
|
||||
- [Примеры](#примеры)
|
||||
- [Известные ограничения](#известные-ограничения)
|
||||
|
||||
---
|
||||
|
||||
## Архитектура
|
||||
|
||||
```
|
||||
┌──────────┐ ┌──────────────┐ ┌────────────┐
|
||||
│ UI │────▶│ REST API │────▶│ PostgreSQL │
|
||||
│ (nginx) │ │ (Spring Boot)│ │ │
|
||||
└──────────┘ └──────┬───────┘ └────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────┐ ┌────────────────┐
|
||||
│ RabbitMQ │◀───▶│ External │
|
||||
│ │ │ Workers (опц.) │
|
||||
└──────────────┘ └────────────────┘
|
||||
```
|
||||
|
||||
| Компонент | Образ | Описание |
|
||||
|-----------|-------|----------|
|
||||
| **api** | `zorrodev/zorrobpm-rest` | BPM движок. Управляет определениями, инстансами, задачами, инцидентами |
|
||||
| **ui** | `zorrodev/zorrobpm-ui` | Nginx SPA — мониторинг процессов, задач, деплоев |
|
||||
| **db** | `postgres:18` | Хранит определения, инстансы, переменные, инциденты |
|
||||
| **rabbitmq** | `rabbitmq:4.0.7-management` | Очереди для serviceTask и событий жизненного цикла |
|
||||
|
||||
---
|
||||
|
||||
## Окружения
|
||||
|
||||
| Окружение | URL | Примечание |
|
||||
|-----------|-----|------------|
|
||||
| **LOCAL** | http://localhost:9092 | Docker Compose |
|
||||
| **PROD** | https://api.bpms.telecom.kz | Через VPN |
|
||||
| **DEV Studio** | https://studio.zorrobpm.dev | Визуальный редактор |
|
||||
| **DEV Station** | https://station.zorrobpm.dev | Мониторинг |
|
||||
| **DEMO (m11s)** | https://api.m11s.zorrobpm.dev | Микросервисная демо-среда |
|
||||
|
||||
Swagger UI:
|
||||
- Local: http://localhost:9092/swagger-ui/index.html
|
||||
- Demo: https://api.m11s.zorrobpm.dev/swagger-ui/index.html
|
||||
|
||||
Аутентификация: не требуется (dev-окружение).
|
||||
|
||||
---
|
||||
|
||||
## Локальный запуск
|
||||
|
||||
```bash
|
||||
# Запуск полного стека
|
||||
docker compose -f docker-compose.yaml --env-file .env up -d
|
||||
|
||||
# Логи API
|
||||
docker compose logs api -f
|
||||
|
||||
# Остановка
|
||||
docker compose down
|
||||
|
||||
# Остановка + удаление данных
|
||||
docker compose down -v
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Docker Compose — полный стек
|
||||
|
||||
Полный стек для самостоятельного запуска движка. Используй только если нужен свой локальный инстанс BPM.
|
||||
|
||||
```yaml
|
||||
# docker-compose.yaml — полный стек ZorroBPM
|
||||
services:
|
||||
|
||||
api:
|
||||
image: zorrodev/zorrobpm-rest
|
||||
environment:
|
||||
- DB_URL=jdbc:postgresql://db/${DB_NAME}
|
||||
- DB_USERNAME=${DB_USER}
|
||||
- DB_PASSWORD=${DB_PASSWORD}
|
||||
- APP_FILES_DIR=/files
|
||||
- RABBITMQ_HOST=rabbitmq
|
||||
- RABBITMQ_USERNAME=${RABBITMQ_USER}
|
||||
- RABBITMQ_PASSWORD=${RABBITMQ_PASSWORD}
|
||||
- RABBITMQ_PORT=5672
|
||||
volumes:
|
||||
- files:/files
|
||||
ports:
|
||||
- 9092:80
|
||||
|
||||
db:
|
||||
image: postgres:18
|
||||
environment:
|
||||
- POSTGRES_DB=${DB_NAME}
|
||||
- POSTGRES_USER=${DB_USER}
|
||||
- POSTGRES_PASSWORD=${DB_PASSWORD}
|
||||
volumes:
|
||||
- db:/var/lib/postgresql/18/docker
|
||||
ports:
|
||||
- "0.0.0.0:5435:5432"
|
||||
|
||||
ui:
|
||||
image: zorrodev/zorrobpm-ui
|
||||
ports:
|
||||
- 9091:80
|
||||
environment:
|
||||
- ZORROBPM_API_URL=http://zorrobpm.local
|
||||
|
||||
rabbitmq:
|
||||
image: rabbitmq:4.0.7-management
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- RABBITMQ_DEFAULT_USER=${RABBITMQ_USER}
|
||||
- RABBITMQ_DEFAULT_PASS=${RABBITMQ_PASSWORD}
|
||||
volumes:
|
||||
- rabbitmq-data:/var/lib/rabbitmq
|
||||
|
||||
volumes:
|
||||
rabbitmq-data:
|
||||
db:
|
||||
files:
|
||||
```
|
||||
|
||||
`.env`:
|
||||
```env
|
||||
DB_NAME=zorrobpm
|
||||
DB_USER=zorrobpm
|
||||
DB_PASSWORD=zorrobpm
|
||||
RABBITMQ_USER=guest
|
||||
RABBITMQ_PASSWORD=guest
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Docker Compose — только фронт (dev)
|
||||
|
||||
**Для разработки процессов без локального движка.** Подключается к удалённому API (demo, dev или prod). Не нужны PostgreSQL, RabbitMQ, API — только UI.
|
||||
|
||||
```yaml
|
||||
# docker-compose.front.yaml — фронт без движка
|
||||
services:
|
||||
|
||||
ui:
|
||||
image: zorrodev/zorrobpm-ui
|
||||
ports:
|
||||
- 9091:80
|
||||
environment:
|
||||
- ZORROBPM_API_URL=${ZORROBPM_API_URL}
|
||||
```
|
||||
|
||||
`.env.front`:
|
||||
```env
|
||||
# Указать один из:
|
||||
ZORROBPM_API_URL=https://api.m11s.zorrobpm.dev # demo
|
||||
# ZORROBPM_API_URL=https://api.bpms.telecom.kz # prod (VPN)
|
||||
# ZORROBPM_API_URL=http://localhost:9092 # local
|
||||
```
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.front.yaml --env-file .env.front up -d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Docker Compose — фронт + воркеры
|
||||
|
||||
**Когда процесс содержит serviceTask с внешними воркерами.** Фронт для мониторинга + RabbitMQ для получения задач + твой воркер.
|
||||
|
||||
```yaml
|
||||
# docker-compose.workers.yaml — фронт + RabbitMQ воркеры
|
||||
services:
|
||||
|
||||
ui:
|
||||
image: zorrodev/zorrobpm-ui
|
||||
ports:
|
||||
- 9091:80
|
||||
environment:
|
||||
- ZORROBPM_API_URL=${ZORROBPM_API_URL}
|
||||
|
||||
# Пример Java-воркера
|
||||
worker:
|
||||
build: ./worker
|
||||
environment:
|
||||
- ZORROBPM_API_URL=${ZORROBPM_API_URL}
|
||||
- RABBITMQ_HOST=${RABBITMQ_HOST}
|
||||
- RABBITMQ_PORT=${RABBITMQ_PORT:-5672}
|
||||
- RABBITMQ_USERNAME=${RABBITMQ_USER}
|
||||
- RABBITMQ_PASSWORD=${RABBITMQ_PASSWORD}
|
||||
depends_on:
|
||||
- ui
|
||||
```
|
||||
|
||||
`.env.workers`:
|
||||
```env
|
||||
ZORROBPM_API_URL=https://api.m11s.zorrobpm.dev
|
||||
|
||||
# RabbitMQ — указать хост удалённого брокера, если он открыт,
|
||||
# или поднять локально (добавить rabbitmq сервис)
|
||||
RABBITMQ_HOST=rabbitmq.m11s.zorrobpm.dev
|
||||
RABBITMQ_USER=guest
|
||||
RABBITMQ_PASSWORD=guest
|
||||
```
|
||||
|
||||
> **Примечание:** если удалённый RabbitMQ недоступен извне, добавь сервис `rabbitmq` из полного стека и настрой API на использование этого брокера.
|
||||
|
||||
---
|
||||
|
||||
## API Reference
|
||||
|
||||
Base URL: `http://localhost:9092` (local) или `https://api.m11s.zorrobpm.dev` (demo)
|
||||
|
||||
### Process Definitions
|
||||
|
||||
| Метод | Endpoint | Описание |
|
||||
|-------|----------|----------|
|
||||
| `POST` | `/process-definitions` | Деплой BPMN |
|
||||
| `GET` | `/process-definitions` | Список (с пагинацией) |
|
||||
| `GET` | `/process-definitions/{id}` | По ID |
|
||||
| `GET` | `/process-definitions/{id}/xml` | BPMN XML |
|
||||
|
||||
**Деплой:**
|
||||
```http
|
||||
POST /process-definitions
|
||||
Content-Type: application/json
|
||||
|
||||
{ "bpmn": "<bpmn:definitions>...</bpmn:definitions>" }
|
||||
```
|
||||
|
||||
Ответ — `ProcessDefinition`:
|
||||
```json
|
||||
{
|
||||
"id": "uuid",
|
||||
"key": "string",
|
||||
"version": 1,
|
||||
"name": "string",
|
||||
"sha256": "string",
|
||||
"createdAt": "date-time",
|
||||
"startFormKey": "string"
|
||||
}
|
||||
```
|
||||
|
||||
Query params: `pageIndex`, `pageSize`, `processDefinitionKey`, `processDefinitionVersion`, `latestVersionOnly`
|
||||
|
||||
---
|
||||
|
||||
### Process Instances
|
||||
|
||||
| Метод | Endpoint | Описание |
|
||||
|-------|----------|----------|
|
||||
| `POST` | `/process-instances` | Запуск инстанса |
|
||||
| `GET` | `/process-instances` | Список (с пагинацией) |
|
||||
|
||||
**Запуск:**
|
||||
```http
|
||||
POST /process-instances
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"processDefinitionId": "uuid",
|
||||
"processDefinitionKey": "string",
|
||||
"processDefinitionVersion": 1,
|
||||
"variables": [
|
||||
{ "name": "var1", "value": "val1", "type": "STRING" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Можно указать `processDefinitionId` ИЛИ `processDefinitionKey` + `processDefinitionVersion`.
|
||||
|
||||
Ответ: `{ "id": "uuid" }`
|
||||
|
||||
Query params: `id`, `pageIndex`, `pageSize`, `processDefinitionId`, `processDefinitionKey`, `processDefinitionVersion`
|
||||
|
||||
Объект `ProcessInstance`:
|
||||
```json
|
||||
{
|
||||
"id": "uuid",
|
||||
"parentActivityId": "uuid",
|
||||
"processDefinitionId": "uuid",
|
||||
"startedAt": "date-time",
|
||||
"completedAt": "date-time"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Service Tasks
|
||||
|
||||
| Метод | Endpoint | Описание |
|
||||
|-------|----------|----------|
|
||||
| `GET` | `/service-tasks` | Список сервисных задач |
|
||||
| `POST` | `/service-tasks/{id}/complete` | Завершить задачу |
|
||||
|
||||
Query params: `id`, `jobType`, `completed`, `pageIndex`, `pageSize`, `processInstanceId`
|
||||
|
||||
Объект `ServiceTask`:
|
||||
```json
|
||||
{
|
||||
"id": "uuid",
|
||||
"code": "string",
|
||||
"name": "string",
|
||||
"processInstanceId": "uuid",
|
||||
"processDefinitionId": "uuid",
|
||||
"job": "string",
|
||||
"createdAt": "date-time",
|
||||
"completedAt": "date-time"
|
||||
}
|
||||
```
|
||||
|
||||
**Завершение:**
|
||||
```http
|
||||
POST /service-tasks/{id}/complete
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"variables": [
|
||||
{ "name": "result", "value": "done", "type": "STRING" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### User Tasks
|
||||
|
||||
| Метод | Endpoint | Описание |
|
||||
|-------|----------|----------|
|
||||
| `GET` | `/user-tasks` | Список пользовательских задач |
|
||||
| `POST` | `/user-tasks/{id}/complete` | Завершить задачу |
|
||||
|
||||
Query params: `id`, `assignee`, `candidateGroup`, `candidateUser`, `completed`, `assigned`, `pageIndex`, `pageSize`, `processInstanceId`
|
||||
|
||||
Объект `UserTask`:
|
||||
```json
|
||||
{
|
||||
"id": "uuid",
|
||||
"code": "string",
|
||||
"name": "string",
|
||||
"processInstanceId": "uuid",
|
||||
"processDefinitionId": "uuid",
|
||||
"formKey": "string",
|
||||
"createdAt": "date-time",
|
||||
"completedAt": "date-time"
|
||||
}
|
||||
```
|
||||
|
||||
**Завершение:**
|
||||
```http
|
||||
POST /user-tasks/{id}/complete
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"variables": [
|
||||
{ "name": "action", "value": "approve", "type": "STRING" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Incidents
|
||||
|
||||
| Метод | Endpoint | Описание |
|
||||
|-------|----------|----------|
|
||||
| `GET` | `/incidents` | Список инцидентов |
|
||||
| `POST` | `/incidents/{id}/resolve` | Разрешить инцидент |
|
||||
|
||||
Query params: `id`, `processInstanceId`, `processDefinitionId`, `processDefinitionKey`, `processDefinitionVersion`, `bpmnElementId`, `pageIndex`, `pageSize`
|
||||
|
||||
Объект `Incident`:
|
||||
```json
|
||||
{
|
||||
"id": "uuid",
|
||||
"activityId": "uuid",
|
||||
"message": "string",
|
||||
"createdAt": "date-time",
|
||||
"completedAt": "date-time"
|
||||
}
|
||||
```
|
||||
|
||||
**Разрешение:**
|
||||
```http
|
||||
POST /incidents/{id}/resolve
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"id": "uuid",
|
||||
"variables": [
|
||||
{ "name": "fix", "value": "retried", "type": "STRING" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Типы переменных
|
||||
|
||||
`STRING`, `UUID`, `LONG`, `BOOLEAN`
|
||||
|
||||
### Формат пагинации
|
||||
|
||||
Все list-эндпоинты возвращают:
|
||||
```json
|
||||
{
|
||||
"pageIndex": 0,
|
||||
"pageSize": 20,
|
||||
"totalElements": 100,
|
||||
"data": [...]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## RabbitMQ и внешние воркеры
|
||||
|
||||
### Очереди
|
||||
|
||||
| Очередь | Описание |
|
||||
|---------|----------|
|
||||
| `zorrobpm.engine.definition-events` | Жизненный цикл определений (deployed, updated) |
|
||||
| `zorrobpm.engine.runtime-events` | Жизненный цикл инстансов (created, completed) и задач |
|
||||
| `zorrobpm.jobs.<job_type>` | Очередь для каждого типа serviceTask |
|
||||
|
||||
### Как это работает
|
||||
|
||||
Когда BPMN `serviceTask` с атрибутом `job="srv_child_work"` достигается движком:
|
||||
1. Движок публикует сообщение в очередь `zorrobpm.jobs.srv_child_work`
|
||||
2. Внешний воркер читает из этой очереди
|
||||
3. Воркер выполняет работу
|
||||
4. Воркер вызывает `POST /service-tasks/{id}/complete`
|
||||
|
||||
### Пример воркера (Java + Spring AMQP)
|
||||
|
||||
```java
|
||||
@RabbitListener(queues = "zorrobpm.jobs.srv_child_work")
|
||||
public void handleChildWork(ServiceTaskMessage msg) {
|
||||
// выполнить работу...
|
||||
api.completeServiceTask(msg.getTaskId());
|
||||
}
|
||||
```
|
||||
|
||||
### Инспекция очередей
|
||||
|
||||
```bash
|
||||
docker exec zorrobpm-rabbitmq-1 rabbitmqctl list_queues name messages consumers
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Разработка процессов
|
||||
|
||||
### Быстрый старт
|
||||
|
||||
1. **Нарисуй BPMN** — в Studio (https://studio.zorrobpm.dev) или любом BPMN-редакторе
|
||||
2. **Деплой** — `POST /process-definitions` с BPMN XML
|
||||
3. **Запусти** — `POST /process-instances` с ключом или ID определения
|
||||
4. **Обрабатывай задачи**:
|
||||
- `serviceTask` — воркер через RabbitMQ или ручной `POST /service-tasks/{id}/complete`
|
||||
- `userTask` — UI или ручной `POST /user-tasks/{id}/complete`
|
||||
|
||||
### Выбор docker-compose
|
||||
|
||||
```
|
||||
Нужен ли локальный BPM движок?
|
||||
├── Да → docker-compose.yaml (полный стек)
|
||||
└── Нет, использую удалённый API
|
||||
├── Есть serviceTask с воркерами? → docker-compose.workers.yaml
|
||||
└── Только UI/мониторинг? → docker-compose.front.yaml
|
||||
```
|
||||
|
||||
### Структура проекта (рекомендуемая)
|
||||
|
||||
```
|
||||
my-process/
|
||||
├── docker-compose.yaml # выбери нужный вариант
|
||||
├── .env
|
||||
├── bpmn/
|
||||
│ ├── myProcess.bpmn
|
||||
│ └── childProcess.bpmn
|
||||
├── worker/ # если есть serviceTask
|
||||
│ ├── Dockerfile
|
||||
│ └── src/
|
||||
└── tests/
|
||||
└── e2e/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Тестирование
|
||||
|
||||
### Dev-контейнер
|
||||
|
||||
```yaml
|
||||
# docker-compose.dev.yaml
|
||||
services:
|
||||
app:
|
||||
image: maven:3.9-eclipse-temurin-17
|
||||
container_name: examples-dev
|
||||
working_dir: /app
|
||||
volumes:
|
||||
- .:/app
|
||||
- maven-cache:/root/.m2
|
||||
ports:
|
||||
- "8080:8080"
|
||||
- "5005:5005" # remote debug
|
||||
command: sleep infinity
|
||||
|
||||
volumes:
|
||||
maven-cache:
|
||||
```
|
||||
|
||||
### Режимы тестирования
|
||||
|
||||
| Режим | Команда | Зависимости | Описание |
|
||||
|-------|---------|-------------|----------|
|
||||
| **embedded** | `./test.sh` | Только dev контейнер | Unit тесты, встроенный движок + H2 |
|
||||
| **local** | `./test.sh local` | Dev + ZorroBPM docker | E2E против `localhost:9092` |
|
||||
| **remote** | `./test.sh remote` | Dev + интернет | E2E против `api.m11s.zorrobpm.dev` |
|
||||
| **custom** | `./test.sh http://my-server:8080` | Dev + сервер | E2E против произвольного URL |
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.dev.yaml up -d
|
||||
./test.sh # embedded
|
||||
./test.sh local # E2E local
|
||||
./test.sh remote # E2E remote
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Примеры
|
||||
|
||||
### call-activity — вызов дочернего процесса
|
||||
|
||||
**Родительский процесс** (`parentProcess.bpmn`):
|
||||
```
|
||||
[Start] → [CallActivity: childProcess] → [End]
|
||||
```
|
||||
|
||||
**Дочерний процесс** (`childProcess.bpmn`):
|
||||
```
|
||||
[Start] → [ServiceTask: srv_child_work] → [End]
|
||||
```
|
||||
|
||||
**Поток выполнения:**
|
||||
1. Деплой обоих BPMN
|
||||
2. Запуск родительского — он входит в `callActivity`, создаёт дочерний инстанс
|
||||
3. Дочерний работает в **отдельном processInstance**
|
||||
4. Завершение serviceTask в дочернем → callActivity возобновляется → родитель завершается
|
||||
|
||||
**Файлы:**
|
||||
```
|
||||
src/main/resources/examples/call-activity/
|
||||
parentProcess.bpmn
|
||||
childProcess.bpmn
|
||||
|
||||
src/test/java/.../examples/callactivity/
|
||||
CallActivityTest.java # unit (embedded)
|
||||
|
||||
src/test/java/.../e2e/
|
||||
CallActivityE2ETest.java # E2E
|
||||
ZorroWebAPI.java # HTTP клиент
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Известные ограничения
|
||||
|
||||
### Нет parentProcessInstanceId
|
||||
|
||||
API не поддерживает фильтр `parentProcessInstanceId` в `ProcessInstance`. Поле `parentActivityId` — это UUID активити (callActivity элемента), а не ID родительского инстанса.
|
||||
|
||||
**Нельзя напрямую запросить:** "дай все дочерние процессы родителя X".
|
||||
|
||||
**Workaround:** найти последний инстанс с `parentActivityId != null` на последней странице. Работает для последовательных тестов, ненадёжно при параллельных.
|
||||
|
||||
**Желаемое улучшение API:**
|
||||
```
|
||||
GET /process-instances?parentProcessInstanceId={uuid}
|
||||
```
|
||||
|
||||
Плюс добавить поле `parentProcessInstanceId` в объект `ProcessInstance`.
|
||||
Reference in New Issue
Block a user