Моделирование процессов: 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% схем
Стандарт содержит около сотни элементов. В реальных схемах используется полтора десятка. Вот они.
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-слияние пропускает любой пришедший токен немедленно; экземпляр завершён, когда токенов не осталось.
Из этого правила выводятся два самых дорогих дефекта в схемах — и оба регулярно доезжают до прода.
Проверяйте баланс шлюзов. Простое, почти механическое правило: чем открыли — тем и закрывайте. Разошлись по 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: во что превращается процесс
Изменилось четыре вещи, и каждая — это требование, которое можно проверить:
- Правила возврата вынесены из голов в таблицу решений (см. ниже) — исчезает «решает тот, кому дозвонились».
- У ожидания товара появился таймер на 14 дней — исчезают вечно висящие заявки.
- Возврат платежа стал синхронной сервисной задачей вместо недельного батча — SLA становится достижимым.
- Появились явные негативные исходы: отказ, аннулирование, спор. По ним теперь можно считать конверсию и находить проблемы.
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-сетей. Модель корректна, если выполняются три условия:
- Option to complete — из любого достижимого состояния можно дойти до завершения. Нарушение = deadlock (наша панель A).
- Proper completion — в момент завершения в процессе не остаётся «блуждающих» токенов. Нарушение = двойное выполнение хвоста (панель B) или подвисшая параллельная ветка.
- 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 инструмент, а не признак незрелости.
Источники
- OMG BPMN 2.0.2 Specification — первоисточник, полезен как справочник по семантике, не как учебник.
- Bruce Silver, BPMN Method and Style — практическое руководство по уровням моделирования и стилю схем.
- Dumas, La Rosa, Mendling, Reijers, Fundamentals of Business Process Management — академический, но читаемый учебник по BPM целиком.
- van der Aalst, Process Mining: Data Science in Action и статья Soundness of workflow nets.
- Camunda BPMN Reference — быстрый справочник элементов с примерами исполнения.
- DMN Specification — нотация таблиц решений.
- PM4Py и стандарт XES — инструменты и формат журналов событий.
- BABOK v3, IIBA — раздел про моделирование процессов в общей системе техник анализа.
Что дальше
Схема процесса показала, какие данные рождаются на каждом шаге и каких сущностей не хватает. Следующий шаг — превратить эти наброски в аккуратную модель данных: сущности, связи, мощности, ключи и словарь, по которому все участники называют вещи одинаково.