Системный и бизнес-анализ Моделирование процессов: BPMN, нотации, типичные ошибки в схемах
0%

Моделирование процессов: BPMN, нотации, типичные ошибки в схемах

Моделирование процессов: BPMN, нотации, типичные ошибки в схемах

Схема процесса — самый недооценённый инструмент аналитика. Её рисуют «для документа», согласуют за пятнадцать минут на созвоне и кладут в Confluence, где она умирает. Между тем хорошая схема делает вещь, которую не делает ни один другой артефакт: она превращает расхождение в головах людей в видимое противоречие на бумаге. Пока процесс живёт в устных описаниях, каждый участник уверен, что все понимают его одинаково. Как только вы нарисовали стрелку от «склад принял товар» к «бухгалтерия вернула деньги», кто-нибудь обязательно скажет: «Погодите, а кто проверяет, что товар не вскрыт?» — и это будет первое найденное неявное требование за неделю.

Эта статья — про то, как рисовать схемы, которые работают. Не про палитру инструмента и не про полный стандарт OMG на 500 страниц, а про то, какая семантика стоит за элементами, какие ошибки делают схему бесполезной или прямо вредной, и как отличить ситуацию «нужен формальный BPMN с версионированием» от ситуации «хватит пяти прямоугольников на доске и разговора».

Предыдущие статьи трека дали материал: выявление требований приносит сырые факты о процессе, виды требований объясняют, куда эти факты раскладывать, UML даёт язык для описания системы. BPMN здесь — язык для описания работы людей и систем во времени.


1. Зачем моделировать процесс: три причины и одна ловушка

1.1. Схема как разделяемая память

Процесс в организации почти никогда не существует целиком ни в чьей голове. Оператор поддержки знает свои пять шагов, кладовщик — свои три, бухгалтер — свой еженедельный реестр. Никто не видит всю цепочку. Схема — это единственное место, где цепочка собирается целиком, и именно поэтому она находит разрывы: шаги, которые никто не делает («мы думали, это делает склад»), шаги, которые делаются дважды, и переходы, где заявка ждёт три дня, потому что кто-то забирает её раз в неделю.

1.2. Схема как детектор противоречий

Естественный язык прекрасно скрывает конфликты. Фраза «после проверки товара запускаем возврат денег» кажется всем понятной. Когда вы рисуете её, приходится ответить на неудобные вопросы: проверка — это одно действие или два (визуальный осмотр на складе и сверка с фотографиями клиента)? «Запускаем возврат» — синхронно или в ночном батче? Что происходит, если проверка не прошла? Схема заставляет сделать выбор явным, а любой явный выбор мгновенно находит несогласного. Это не баг, это главная функция.

1.3. Схема как основа для декомпозиции

Из процессной модели напрямую вырастают требования: каждая задача на схеме — кандидат в user story или use case, каждый шлюз — бизнес-правило, каждый поток сообщений между пулами — интеграция с контрактом, каждый таймер — нефункциональное требование к срокам. Про то, как это оформляется, — документирование; про интеграции — анализ API.

1.4. Ловушка: модель ≠ реальность

Любая схема — упрощение с целью. «Все модели неверны, некоторые полезны» (Джордж Бокс) — не кокетство, а рабочее правило. Полезность определяется вопросом, на который модель отвечает. Если вопрос звучит «где мы теряем два дня», модель должна показывать ожидания и передачи между ролями, но может не показывать поля форм. Если вопрос «что автоматизировать в первую очередь» — нужны частоты и трудозатраты. Схема без вопроса — это рисунок. Прежде чем открыть модельер, запишите одним предложением, какое решение вы собираетесь принять по этой схеме.


2. Ландшафт нотаций: чем и что описывать

Нотация Что описывает Когда брать Чего не умеет
BPMN 2.0 последовательность работ во времени, участники, события, исключения сквозные процессы с несколькими ролями и системами, автоматизация плохо описывает неструктурированную работу «по ситуации»
UML Activity поток управления и данных внутри системы алгоритм внутри одного сервиса, логика метода слабые средства для межорганизационного взаимодействия
EPC (событийные цепочки) чередование «событие → функция → событие» наследие SAP/ARIS, если так принято в компании многословна, нет строгой семантики исключений
DFD (потоки данных) что откуда куда течёт, без времени обзор системного ландшафта, интеграционная карта не показывает порядок и условия
Value Stream Map время обработки vs время ожидания поиск потерь, Lean-инициативы не описывает логику ветвлений
CJM переживания и каналы клиента продуктовые улучшения, UX не описывает внутреннюю механику
CMMN работа кейсами, где порядок определяет человек расследования, медицина, юридические дела избыточен для линейных процессов
DMN таблицы решений сложные бизнес-правила не описывает поток

Ключевое различие, которое обычно упускают: BPMN описывает процесс, DMN — решение, CMMN — кейс. Если ваш процесс превращается в кашу из двадцати шлюзов подряд, скорее всего, вы моделируете решение потоком. Вынесите правила в таблицу DMN — схема ужмётся до трёх блоков.

BPMN стал де-факто стандартом по одной прагматичной причине: у него есть исполнимая семантика (спецификация OMG BPMN 2.0). Одна и та же диаграмма читается человеком и запускается движком. Ни одна другая процессная нотация этого не даёт.

2.1. Насколько формально рисовать

Правило простое: формальность модели должна быть пропорциональна цене ошибки, умноженной на время жизни модели. Схема, нарисованная на груминге и выброшенная через час, не нуждается ни в правильных типах шлюзов, ни в пулах — она нужна, чтобы пять человек одинаково поняли следующий шаг. Схема процесса выдачи кредита, на которую смотрит регулятор, обязана быть безупречной по семантике, версионированной и согласованной.


3. Словарь BPMN, которого хватает на 95% схем

Стандарт содержит около сотни элементов. В реальных схемах используется полтора десятка. Вот они.

Основные элементы BPMN: события, задачи, шлюзы, потоки и контейнеры

3.1. События — то, что случается

Событие рисуется кругом и обозначает факт, а не работу. Три позиции:

  • Стартовое (тонкий контур) — с чего начинается экземпляр процесса. У стартового события есть тип: сообщение (пришёл запрос), таймер (первое число месяца), сигнал, условие.
  • Промежуточное (двойной контур) — процесс либо ждёт («ждём подтверждения от банка»), либо бросает («публикуем событие для других систем»).
  • Конечное (жирный контур) — токен уничтожается. Конечных событий может и должно быть несколько: «возврат оформлен», «возврат отклонён», «клиент передумал» — это разные исходы, и их надо различать, потому что по ним считают метрики.

Отдельно — граничные события, приклеенные к задаче. Это самый недоиспользуемый и самый полезный элемент BPMN: таймер на границе означает «если задача не закончилась за N, идём по другой ветке», ошибка на границе — «если упало, вот компенсация». Именно граничные события превращают happy-path-схему в схему, описывающую реальность.

3.2. Задачи — работа

Прямоугольник со скруглением. Правило именования жёсткое: глагол + объект, «Проверить комплектность возврата», а не «Проверка» и не «Комплектность». Тип задачи (маркер в углу) говорит, кто исполнитель:

  • User task — человек в интерфейсе; отсюда растут экраны и права доступа;
  • Service task — вызов системы; отсюда растёт контракт API;
  • Send / Receive — обмен сообщениями с внешним участником;
  • Script / Business rule — вычисление или таблица решений;
  • Call activity — вызов другого процесса как подпроцесса (переиспользование).

Различение user/service — не украшение: оно моментально делит объём работ на «нужен UI» и «нужна интеграция», а это две разные оценки и две разные команды.

3.3. Шлюзы — только маршрутизация

Ромб. Внутри шлюза не происходит работы. Он не «проверяет заказ» — проверяет задача, а шлюз только разводит токены по результату проверки.

  • XOR (крестик) — ровно одна ветка. Условия на исходящих потоках обязаны быть подписаны и покрывать все случаи; одна ветка помечается как default.
  • AND (плюс) — все ветки параллельно; на слиянии ждём все.
  • OR (кружок) — одна или несколько; на слиянии ждём те, которые были активированы. Мощно, но именно OR-join чаще всего ломает движки и головы. Избегайте, пока без него правда никак.
  • Событийный шлюз — ждём, что произойдёт первым: ответ банка или таймаут. Заменяет уродливую конструкцию «параллельно ждём и отменяем».

3.4. Пулы, дорожки, потоки

  • Пул — самостоятельный участник со своим процессом (ваша компания, банк, клиент).
  • Дорожка — роль внутри вашего пула (поддержка, склад, бухгалтерия).
  • Поток управления (сплошная стрелка) — только внутри одного пула.
  • Поток сообщений (пунктир) — только между пулами.

Это не эстетика, а семантика: сплошная стрелка, пересекающая границу пула, — синтаксическая ошибка, потому что вы не управляете чужим процессом, вы можете только послать сообщение и ждать ответа. Ошибка встречается в каждой второй схеме и всегда означает непроговорённое допущение «они точно сделают то, что нам нужно, и вовремя».

3.5. Три уровня моделирования

Брюс Сильвер в BPMN Method and Style предложил деление, которым удобно пользоваться в переговорах о том, «насколько подробно рисуем»:

Уровень Элементы Аудитория Пример применения
Descriptive задачи, XOR/AND, старт/конец, дорожки бизнес «как устроен возврат» на одной странице
Analytical + граничные события, сообщения, подпроцессы, исключения аналитики, архитекторы приложение к спецификации, основа декомпозиции
Executable + технические атрибуты, переменные, обработчики движок BPMS процесс, который реально исполняется в Camunda

Договоритесь об уровне до начала работы. Половина споров «схема слишком сложная / слишком поверхностная» — это спор о невысказанном уровне.


4. Семантика токена — единственное правило, которое надо выучить

BPMN формально определён через перемещение токенов (наследие сетей Петри). Экземпляр процесса рождается вместе с токеном на стартовом событии; токен движется по стрелкам; AND-развилка размножает токены, AND-слияние ждёт их все; XOR-развилка направляет единственный токен в одну ветку, XOR-слияние пропускает любой пришедший токен немедленно; экземпляр завершён, когда токенов не осталось.

Из этого правила выводятся два самых дорогих дефекта в схемах — и оба регулярно доезжают до прода.

Две классические ловушки шлюзов: XOR-развилка с AND-слиянием даёт deadlock, AND-развилка с XOR-слиянием — двойное завершение

Проверяйте баланс шлюзов. Простое, почти механическое правило: чем открыли — тем и закрывайте. Разошлись по AND — сойдитесь по AND. Разошлись по XOR — сойдитесь по XOR. Смешивать можно, но только осознанно, и в этом случае у вас должен быть ответ на вопрос «сколько токенов дойдёт до конца». Если ответа нет, схема сломана независимо от того, насколько она красива.

Кстати, второй случай — AND-развилка с XOR-слиянием — почти всегда попадает в прод не через BPMN-движок, а через код: две асинхронные ветки, обе дёргают один и тот же обработчик «завершить заявку», и он не идемпотентен. Отсюда прямая дорожка к идемпотентности и семантике доставки.


5. Разбор живого процесса: возврат товара

Абстракции заканчиваются, начинается практика. Дальше — сквозной пример, на котором видно всё: и как схема вскрывает противоречия, и как из неё растут требования.

5.1. Что рассказали стейкхолдеры

Три интервью, три версии одного процесса:

  • Руководитель поддержки: «Клиент пишет в чат, мы заводим заявку, склад принимает товар, бухгалтерия возвращает деньги. Возврат — три дня.»
  • Кладовщик: «Ко мне приходят коробки. Если товар вскрыт, я звоню в поддержку и они решают. Иногда коробка приходит раньше, чем заявка, тогда она лежит в углу.»
  • Бухгалтер: «Я раз в неделю выгружаю реестр из CRM и делаю платёжки. Если заявка попала в выгрузку после четверга, деньги уйдут через неделю.»

Здесь уже три противоречия, и ни одно из них не всплыло бы в тексте требований: обещанные «три дня» не бьются с недельным батчем; товар без заявки — неописанное состояние; «они решают» — шаг без владельца и без правила.

5.2. As-is: как есть на самом деле

Дорожки в mermaid условны — это subgraph, а не настоящие пулы BPMN. Для черновика и для статьи такой схемы достаточно; для документа, который пойдёт на согласование, рисуйте в BPMN-модельере (bpmn.io, Camunda Modeler) и прикладывайте картинку плюс исходный .bpmn.

5.3. Что схема показала за пять минут

  • Неявное требование. Между «клиент отправил посылку» и «склад принял» нет ни таймера, ни статуса. Если посылка не дошла, процесс висит вечно — экземпляров с зависшим состоянием в CRM оказалось 217 штук за год.
  • Противоречие стейкхолдеров. SLA «три дня» физически недостижим при недельном батче. Кто-то должен уступить: либо меняем расписание выплат, либо перестаём обещать три дня. Это управленческое решение, но вытащил его аналитик схемой, а не спором.
  • Шаг без владельца. «Решить, что делать со вскрытым товаром» — не роль, а привычка: решает тот, кому дозвонились. Отсюда разные решения на одинаковых кейсах и жалобы.
  • Обратная петля-крючок. W4 --> S5 --> S4 возвращает процесс в уже пройденную точку. Такие петли — почти всегда признак того, что шаг выполняется в неправильном порядке или что не хватает проверки раньше по потоку.
  • «Хотелка» без задачи. Отдельно в бэклоге лежала просьба «сделать красивый статус-трекер для клиента». На схеме видно: клиент ждёт в единственной точке C9, и ждёт он неделю не из-за отсутствия трекера, а из-за батча. Трекер сделает ожидание прозрачным, но не коротким. Схема не отменяет хотелку, но привязывает её к реальному месту боли — и меняет приоритет.

5.4. To-be: во что превращается процесс

Изменилось четыре вещи, и каждая — это требование, которое можно проверить:

  1. Правила возврата вынесены из голов в таблицу решений (см. ниже) — исчезает «решает тот, кому дозвонились».
  2. У ожидания товара появился таймер на 14 дней — исчезают вечно висящие заявки.
  3. Возврат платежа стал синхронной сервисной задачей вместо недельного батча — SLA становится достижимым.
  4. Появились явные негативные исходы: отказ, аннулирование, спор. По ним теперь можно считать конверсию и находить проблемы.

5.5. Бизнес-правила: таблица вместо шлюзов

Ветвление G1 выглядит как один шлюз, но за ним стоит правило. Если попытаться нарисовать его шлюзами, получится десяток ромбов. Правильное место для правила — таблица решений (нотация DMN, политика hit policy — «первое совпадение»):

# Категория Сумма, RUB Дней с покупки Признак фрода → Решение
1 любая любая > 14 любой отказ по правилам
2 любая любая ≤ 14 да нужна проверка
3 бельё, косметика любая ≤ 14 нет нужна проверка
4 любая > 30 000 ≤ 14 нет нужна проверка
5 любая ≤ 30 000 ≤ 14 нет автоодобрение

Таблица проверяема: её можно построчно прогнать тестами, показать юристу, поменять без правки схемы. Пятнадцать ромбов — нет. Это и есть ответ на вопрос «где формальный документ, а где схема»: поток — схемой, правила — таблицей, детали полей — текстом.

5.6. Взаимодействие систем: sequenceDiagram

Схема процесса говорит «инициировать возврат платежа». Разработчику этого мало: ему нужно знать, кто кого вызывает, что происходит при таймауте и кто хранит идемпотентность. Это другой вопрос — и другой тип диаграммы.

Обратите внимание, чего здесь нет: ролей, дорожек и бизнес-смысла. И чего нет на процессной схеме: заголовков, кодов ответа, ретраев. Это разные вопросы, и попытка ответить на оба одной диаграммой даёт нечитаемую кашу. Подробнее про контракты — в анализе интеграций.

5.7. Процесс против жизненного цикла объекта

Самая частая путаница в головах начинающих аналитиков: процесс и состояние — не одно и то же. Процесс отвечает на вопрос «что происходит по порядку». Жизненный цикл отвечает на вопрос «в каком состоянии сейчас находится заявка и куда из него можно попасть». Второй нужен разработчику для проектирования модели данных и API, а тестировщику — для построения тест-кейсов на недопустимые переходы.

Из этой диаграммы напрямую вытекают проверяемые требования: список допустимых статусов (значения enum в API), матрица разрешённых переходов, права ролей на переходы и — важно — запрет на всё остальное. Формулировка «из статуса Done нельзя вернуться ни в какой другой» проверяется автотестом, а «система должна корректно обрабатывать статусы» — нет.

5.8. Данные, которые рождает процесс

Каждая задача что-то читает и пишет. Быстрый набросок ERD прямо на этапе процессного моделирования ловит недостающие сущности до того, как разработчик начнёт придумывать их сам.

Заметьте STATUS_CHANGE: этой сущности не было ни в одном интервью. Она появилась из вопроса «а как мы потом узнаем, сколько заявка провисела в ручной проверке?» — то есть из требования к измеримости процесса. Подробный разбор моделирования данных — в следующей статье трека.


6. Каталог ошибок: тринадцать способов сделать схему бесполезной

Это самая полезная часть статьи. Ошибки отсортированы по частоте, с которой я встречаю их в реальных документах.

6.1. Шлюз, который работает

Симптом: ромб с надписью «Проверить документы» или «Согласование». Почему плохо: проверка — это работа, у неё есть исполнитель, длительность и стоимость. Спрятав её в шлюз, вы теряете шаг в оценке трудозатрат и в SLA. Как надо: задача «Проверить документы» → шлюз «Документы корректны?» с ветками «да»/«нет».

6.2. Неподписанные ветки XOR

Симптом: от ромба идут две стрелки без меток. Почему плохо: схема нечитаема без автора; при передаче разработчику условие додумывается. Как надо: каждая исходящая ветка подписана условием; одна помечена как «во всех остальных случаях». Проверка на полноту: условия покрывают всё пространство значений и не пересекаются.

6.3. Несбалансированные шлюзы

Разобрано в разделе 4: XOR-развилка + AND-слияние = deadlock; AND-развилка + XOR-слияние = двойное выполнение хвоста процесса. Проверяется механически, ломает прод регулярно.

6.4. Только happy path

Симптом: прямая линия из семи задач без единой альтернативы. Почему плохо: 80% усилий разработки и 100% инцидентов приходятся на отклонения. Схема без исключений — это оценка, заниженная втрое. Как надо: пройдитесь по каждой задаче с тремя вопросами: «что, если исполнитель не сделает?», «что, если сделает неправильно?», «что, если внешняя система не ответит?». Ответы — это граничные таймеры, ошибки и альтернативные ветки. Если ответ «такого не бывает» — запишите допущение явно, это тоже артефакт.

6.5. Сплошная стрелка через границу пула

Симптом: поток управления из вашего пула прямо в задачу пула банка. Почему плохо: вы не управляете чужим процессом. Скрывается допущение о синхронности и надёжности внешней стороны. Как надо: поток сообщений (пунктир) + событие получения ответа + таймер на ожидание.

6.6. Ожидание без таймера

Симптом: задача «Ждём ответ от контрагента» без границы. Почему плохо: в реальности процессы зависают, и никто не знает, сколько их сейчас висит. Как надо: граничный таймер + явная ветка эскалации. Побочный эффект: вы обязаны спросить у бизнеса «сколько ждём?» — а это ещё одно нефункциональное требование, вытащенное на свет (см. нефункциональные требования).

6.7. Смешение уровней абстракции

Симптом: рядом стоят задачи «Провести кампанию по возврату клиентов» и «Нажать кнопку «Сохранить»». Почему плохо: невозможно оценить, невозможно читать, невозможно согласовать. Как надо: один уровень на диаграмму. Крупный шаг — свернуть в подпроцесс и раскрыть отдельной схемой. Практический ориентир: 7±2 задачи на одном уровне, максимум 15.

6.8. Моделирование интерфейса вместо процесса

Симптом: «Открыть форму», «Заполнить поле «Причина»», «Нажать «Отправить»». Почему плохо: схема ломается при первом же редизайне, хотя бизнес-процесс не изменился. Как надо: «Оформить заявку на возврат» — одна задача. Как выглядит форма — задача прототипирования и макетов.

6.9. Шаг без владельца

Симптом: задача не лежит ни в одной дорожке или лежит в дорожке «Система/Все». Почему плохо: работа, за которую никто не отвечает, не выполняется или выполняется по-разному. Как надо: каждая задача — в дорожке конкретной роли. Если роль назвать не удаётся, вы нашли организационную дыру; это находка, а не мелочь. Про то, как её закрывать, — работа со стейкхолдерами.

6.10. As-is, который на самом деле to-be

Симптом: нарисованный «как есть» процесс подозрительно аккуратен и всем нравится. Почему плохо: вы описали, как должно быть по регламенту, а оптимизировать будете фантазию. Реальный процесс всегда содержит обходные пути, Excel-файлы и «звоню Марине». Как надо: проверяйте as-is фактами: логи систем, выгрузки, наблюдение за работой (см. раздел 8). Вопрос-детектор: «А когда так не получается — что вы делаете?»

6.11. Петли без условия выхода

Симптом: стрелка «на доработку» уходит назад, и из цикла нет выхода, кроме успеха. Почему плохо: бесконечная переписка «доработайте — не так — доработайте». Нет ни счётчика итераций, ни эскалации. Как надо: ограничьте цикл: «не более двух возвратов на доработку, далее — эскалация руководителю». Это правило, которое можно проверить, и метрика, которую можно считать.

6.12. Одно конечное событие «Конец»

Симптом: все ветки сходятся в единственный кружок. Почему плохо: теряются исходы. «Возврат оформлен» и «Клиент ушёл недовольным» — экономически противоположные события, и они обязаны различаться в аналитике. Как надо: отдельное конечное событие на каждый значимый исход, имя — существительным в совершённом виде: «Деньги возвращены», «Возврат отклонён», «Заявка аннулирована».

6.13. Схема, которую невозможно проверить

Симптом: «Система должна оперативно уведомлять ответственного», «Процесс должен быть удобным». Почему плохо: нечего тестировать, не о чем спорить на приёмке, приёмка превращается в вкусовщину. Как надо: каждое утверждение на схеме и рядом с ней должно иметь наблюдаемое следствие. «Оперативно» → «не позднее 15 минут с момента поступления, p95». Тест на проверяемость: можете ли вы придумать эксперимент, который однозначно покажет «выполнено / не выполнено»? Если нет — это не требование, а пожелание, и его надо либо уточнить, либо честно записать в раздел «намерения». Тема разворачивается в статье про приёмку.


7. Как проверить схему: формальные критерии и чек-лист

7.1. Soundness — три условия корректности

Вил ван дер Аалст формализовал корректность процессных моделей через понятие soundness для workflow-сетей. Модель корректна, если выполняются три условия:

  1. Option to complete — из любого достижимого состояния можно дойти до завершения. Нарушение = deadlock (наша панель A).
  2. Proper completion — в момент завершения в процессе не остаётся «блуждающих» токенов. Нарушение = двойное выполнение хвоста (панель B) или подвисшая параллельная ветка.
  3. No dead transitions — для каждой задачи существует сценарий, в котором она выполняется. Нарушение = мёртвый код на схеме, обычно остаток от прошлой версии процесса.

Хорошая новость: движки и модельеры это проверяют автоматически. Плохая: только для формально корректных моделей, а в Miro никто ничего не проверит. Поэтому — ручной чек-лист.

7.2. Чек-лист перед показом схемы

Синтаксис

  • Ровно одно стартовое событие на каждый способ инициации, и оно типизировано.
  • Каждая ветка заканчивается конечным событием; висящих стрелок нет.
  • Шлюзы сбалансированы; для смешанных есть внятный ответ «сколько токенов дойдёт до конца».
  • Все исходящие потоки XOR/OR подписаны, есть default.
  • Между пулами — только потоки сообщений.
  • Задачи названы «глагол + объект», события — «существительное + совершённое действие».

Семантика

  • У каждой задачи есть дорожка (владелец) и понятен тип исполнителя (человек/система).
  • На каждом ожидании внешнего ответа есть таймер и ветка эскалации.
  • Циклы ограничены счётчиком или условием выхода.
  • Значимые исходы разделены; по каждому понятно, какую метрику он даёт.
  • Уровень абстракции единый; крупные шаги свёрнуты в подпроцессы.

Связь с реальностью

  • As-is подтверждён данными или наблюдением, а не только словами руководителя.
  • Для каждого шага известны частота и трудоёмкость хотя бы порядком.
  • Известно, где процесс расходится с регламентом, и это записано.
  • Каждое требование, выведенное из схемы, проверяемо экспериментом.

8. Проверка модели фактами: process mining на минималках

Схема, нарисованная со слов, — гипотеза. Проверить её можно данными: почти любая система оставляет журнал событий, а из журнала строится реальный граф переходов. Формат события минимален (стандарт XES): идентификатор экземпляра, название активности, момент времени.

Псевдокод построения графа непосредственного следования (DFG):

для каждого события: сгруппировать по case_id
для каждой группы: отсортировать по времени
для каждой пары соседних событий (a, b): dfg[(a, b)] += 1

Реализация:

from collections import Counter, defaultdict
from datetime import datetime

# Одна запись лога = один факт: в экземпляре case_id произошла активность в момент ts
Event = tuple[str, str, datetime]


def directly_follows(log: list[Event]) -> Counter:
    """Граф непосредственного следования: сколько раз b шло сразу после a."""
    by_case: dict[str, list[tuple[datetime, str]]] = defaultdict(list)
    for case_id, activity, ts in log:
        by_case[case_id].append((ts, activity))

    dfg: Counter = Counter()
    for events in by_case.values():
        events.sort()  # события внутри экземпляра — по времени
        for (_, a), (_, b) in zip(events, events[1:]):
            dfg[(a, b)] += 1
    return dfg


def conformance(dfg: Counter, model_edges: set[tuple[str, str]]) -> dict:
    """Сравнение реальности с нарисованной схемой."""
    observed = set(dfg)
    return {
        # переходы, которые есть в жизни, но которых нет на схеме
        "undocumented": {e: dfg[e] for e in observed - model_edges},
        # переходы со схемы, которые не встретились ни разу
        "never_happened": model_edges - observed,
        # доля событий, укладывающихся в модель
        "fitness": sum(dfg[e] for e in observed & model_edges) / max(sum(dfg.values()), 1),
    }

Сложность: directly_follows — O(n log n) по времени (сортировка внутри экземпляров; при предварительно упорядоченном логе — O(n)) и O(n) по памяти. conformance — O(|E|) по числу различных переходов, что на порядки меньше n.

Что вы увидите на настоящих данных, почти гарантированно:

  • Undocumented переходы. «Осмотр → Ручная проверка» встречается 1400 раз, а на схеме такого перехода нет. Значит, кладовщики отправляют заявки назад, и это никем не описано.
  • Never happened. Ветка «спор» на схеме есть, а в логах ноль случаев — либо она мертва, либо процесс идёт мимо системы (в почте), и вы не видите половины работы.
  • Fitness сильно ниже 1. Модель описывает не тот процесс, который выполняется. Не спешите «чинить людей»: чаще чинить надо модель.

Дальше — время. Разница timestamp между соседними событиями даёт распределение времени ожидания на каждом переходе; именно там прячутся дни, которые бизнес считает «тремя днями». Если хотите готовый инструмент, а не свои двадцать строк, — PM4Py (открытая библиотека) или коммерческие Celonis, Apromore. Теоретическая база — Process Mining, van der Aalst.


9. Когда схема становится кодом: исполняемый BPMN

Если процесс исполняется в движке (Camunda, Zeebe, Flowable, Bizagi), схема перестаёт быть документом и становится артефактом сборки. Это меняет требования к аналитику: каждое имя элемента — идентификатор в коде, каждый шлюз — выражение на языке движка, каждая service task — реальная точка интеграции с ретраями и обработкой ошибок.

<bpmn:process id="return_request" name="Возврат товара" isExecutable="true">

  <bpmn:startEvent id="StartReturnCreated" name="Заявка на возврат создана">
    <bpmn:outgoing>flow_to_rules</bpmn:outgoing>
  </bpmn:startEvent>

  <!-- Бизнес-правила вынесены в таблицу решений, а не в цепочку шлюзов -->
  <bpmn:businessRuleTask id="ApplyReturnPolicy" name="Применить правила возврата"
                         camunda:decisionRef="return_policy"
                         camunda:resultVariable="decision">
    <bpmn:incoming>flow_to_rules</bpmn:incoming>
    <bpmn:outgoing>flow_to_gateway</bpmn:outgoing>
  </bpmn:businessRuleTask>

  <bpmn:exclusiveGateway id="DecisionGateway" name="Решение по заявке"
                         default="flow_manual"/>

  <bpmn:sequenceFlow id="flow_auto" sourceRef="DecisionGateway" targetRef="GenerateLabel">
    <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">
      ${decision == 'AUTO_APPROVE'}
    </bpmn:conditionExpression>
  </bpmn:sequenceFlow>

  <bpmn:serviceTask id="InitiateRefund" name="Инициировать возврат платежа"
                    camunda:type="external" camunda:topic="refund-initiate"/>

  <!-- Ожидание товара с жёстким дедлайном: без этого экземпляры живут вечно -->
  <bpmn:intermediateCatchEvent id="AwaitItem" name="Товар поступил на склад">
    <bpmn:messageEventDefinition messageRef="msg_item_received"/>
  </bpmn:intermediateCatchEvent>

  <bpmn:boundaryEvent id="ReturnDeadline" attachedToRef="AwaitItem" cancelActivity="true">
    <bpmn:timerEventDefinition>
      <bpmn:timeDuration>P14D</bpmn:timeDuration>
    </bpmn:timerEventDefinition>
  </bpmn:boundaryEvent>

  <bpmn:endEvent id="EndExpired" name="Заявка аннулирована"/>
</bpmn:process>

Что тут важно для аналитика, даже если XML пишет разработчик:

  • isExecutable="true" означает, что неточность в схеме — это баг в проде, а не опечатка в документе.
  • Идентификаторы стабильны. Переименовали элемент — сломали работающие экземпляры и метрики. Имена элементов становятся частью контракта, как имена полей в API.
  • Каждая внешняя задача нуждается в политике ошибок: сколько ретраев, с какой задержкой, куда падает инцидент. Это ваши нефункциональные требования, и их спросят на этапе разработки, а не постфактум.
  • Компенсации. Если процесс уже вернул деньги, а потом выяснилось, что товар не тот, «откатить» нельзя — нужна компенсирующая операция. Это ровно то, что в архитектуре называется сагой.

Полезные ссылки: референс элементов BPMN от Camunda, бесплатный веб-модельер bpmn.io (тот же движок редактора, что в Camunda Modeler).


10. Когда формальная схема не нужна

Симметричный и не менее важный вопрос. Формальное моделирование стоит времени: рисование, согласование, поддержание в актуальности. Если это время не окупается, вы производите мусор.

Достаточно разговора и схемы на доске, когда:

  • участников двое-трое и они сидят рядом;
  • процесс проживёт до следующего эксперимента;
  • цена ошибки — переделать за день;
  • цель — договориться прямо сейчас, а не зафиксировать надолго.

Формат: прямоугольники и стрелки на доске, фото в тикет, три строчки текста «договорились так». Именно так работает аналитик в Agile-команде большую часть времени — см. аналитик в Agile.

Нужен формальный BPMN, когда:

  • участников больше трёх и они в разных подразделениях или компаниях;
  • процесс подпадает под регуляторику или аудит (финансы, медицина, персональные данные);
  • процесс будет автоматизирован в BPMS — схема становится исходным кодом;
  • по процессу считаются деньги или SLA перед клиентом;
  • процесс переживёт нескольких сотрудников (онбординг, передача дел).

Промежуточный вариант, который часто оказывается лучшим: descriptive-BPMN на одну страницу плюс таблица решений плюс список исключений текстом. Читается за две минуты, поддерживается за десять, ловит 80% противоречий.

Отдельно: не рисуйте схему как способ избежать разговора. Схема — повод для разговора и его протокол, а не замена. Диаграмма, разосланная на согласование без встречи, собирает формальные «ок» от людей, которые в неё не вчитались, и создаёт ложное ощущение согласия.


11. От схемы к требованиям: механическое преобразование

Хорошая процессная модель почти автоматически раскладывается в бэклог. Таблица соответствий:

Элемент схемы Что из него следует Куда попадает
User task экран, роль, права, валидации user story + макет
Service task вызов API: метод, контракт, ошибки, ретраи спецификация интеграции
Поток сообщений между пулами внешний контракт и SLA контрагента соглашение об интеграции
XOR-шлюз бизнес-правило таблица решений + тесты на границы
Граничный таймер требование к сроку и поведение при просрочке NFR + сценарий эскалации
Граничная ошибка сценарий отказа и компенсация негативный сценарий приёмки
Конечное событие исход процесса метрика и статус в отчётности
Data object / store сущность и её атрибуты модель данных, словарь данных
Дорожка роль матрица доступа (RACI, права)

Проверка полноты по схеме: для каждой задачи должны существовать ответы на вопросы «кто делает», «из чего», «во что», «сколько по времени», «что если не получилось». Если хоть один ответ отсутствует — у вас не требование, а название работы. Про перевод в user stories и критерии приёмки — документирование; базовые формулировки требований разбираются также в материалах трека архитектуры.

Смежная техника, полезная перед рисованием BPMN, — Event Storming: команда за час выкладывает на стену события домена, а уже потом из них собирается процесс и границы контекстов. Разбор — в статье Event Storming.


12. Мини-итог

  • Схема нужна не для документа, а для того, чтобы сделать неявное явным: недостающие шаги, шаги без владельца, невозможные SLA, отсутствующие исключения.
  • Перед моделированием сформулируйте вопрос, на который схема отвечает, и уровень детализации (descriptive / analytical / executable). Половина конфликтов о схемах — конфликты о невысказанном уровне.
  • Выучите семантику токена. Из неё выводятся два самых дорогих дефекта: deadlock на XOR→AND и двойное выполнение на AND→XOR.
  • Поток — схемой, правила — таблицей решений, детали интерфейса — макетом, взаимодействие систем — sequence-диаграммой, состояния объекта — state-диаграммой. Не пытайтесь ответить на все вопросы одной картинкой.
  • Happy path — это треть работы. Ценность схемы в исключениях, таймерах и негативных исходах.
  • As-is проверяйте фактами: логи, наблюдение, process mining. Схема со слов руководителя — это регламент, а не процесс.
  • Формальность пропорциональна цене ошибки и времени жизни модели. Доска и разговор — legitimate инструмент, а не признак незрелости.

Источники

Что дальше

Схема процесса показала, какие данные рождаются на каждом шаге и каких сущностей не хватает. Следующий шаг — превратить эти наброски в аккуратную модель данных: сущности, связи, мощности, ключи и словарь, по которому все участники называют вещи одинаково.

Моделирование данных: сущности, связи, ERD, словарь данных

Нашли неточность? Выделите фрагмент текста — рядом появится жучок.

Нужен разбор именно вашей ситуации?

Статья описывает общий случай. Если у вас частный — можно разобрать его отдельно, платно. А если не хватает целого материала, предложите тему: её оплачивают вскладчину, и она выходит открытой для всех.

Доска запросов