CRM-платформа с low-code/no-code-настройкой: пользователь сам собирает объектную модель раздела, настраивает бизнес-процессы и маршруты согласования под свой бизнес. Дизайнер раздела — инструмент, через который заводится любая бизнес-сущность в системе.

TL;DR

Маршрутов в продукте не существовало — модуль проектировался с нуля. Над ним я работал в роли продакт-менеджера и продуктового дизайнера, с end-to-end ответственностью от пользовательских историй до релиза. Команда — семь человек: я, ещё один продуктовый дизайнер, которого я менторил по ходу проекта, два фронтенд-разработчика, два бэкенд-разработчика и тестировщик.

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

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

Ниже несколько кейсов из этого проекта.

Участник маршрута
Шаг маршрута
Группа маршрута

Модель маршрута

Базовая структура одного маршрута: уровни, на которые он раскладывается, и логика их выполнения.

Ситуация

Один из первых вопросов на старте — как устроить структуру одного маршрута. Самый простой вариант — плоская иерархия: шаг → исполнитель. Этого достаточно для линейных согласований, но конструкция оказалась тесной.

Цель

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

Действия

Начал с двухуровневой модели: шаг и участники внутри шага. На уровне шага — режим выполнения (последовательно или параллельно) и условие завершения (ждать всех или одного). Для линейных согласований этого было достаточно, и в таком виде решение пошло на согласование.

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

Пара настроек «режим выполнения» и «условие завершения» осталась одинаковой на уровне шага и на уровне группы — внутри группы нужны те же режимы, что и на уровне шага. Настройки спрятал в правую панель по устоявшемуся в продукте паттерну, под каждой — поясняющая строка о том, что произойдёт в итоге.

Результат

Модель легла в основу всех остальных сценариев модуля и без изменений выдержала весь скоуп первой версии — свой маршрут, редактирование на ходу, создание активностей собирались поверх неё.

Предусловия запуска маршрута

Управление тем, когда на карточке записи появляется кнопка «Отправить по маршруту».

Ситуация

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

Задача

Дать владельцу процесса инструмент, чтобы исключить операционные ошибки. Без участия разработки, на уровне настроек шаблона.

Действия

Начал с одного уровня — условие доступности самой кнопки «Отправить по маршруту». Пока запись не удовлетворяет условию, кнопка на карточке не появляется.

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

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

Результат

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

Маршрут под конкретную запись

Сборка или правка маршрута прямо со страницы записи, когда подходящего шаблона нет или он требует корректировки.

Ситуация

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

Задача

Закрыть оба случая на странице записи, не отправляя пользователя в дизайнер раздела ради разовой задачи.

Действия

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

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

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

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

Результат

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

Правка маршрута

Правка запущенного маршрута

Возможность вносить изменения в маршрут, который уже запущен на записи, без отмены и перезапуска.

Ситуация

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

Задача

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

Действия

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

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

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

Результат

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

Итог

Продукт не вышел в коммерческую эксплуатацию, поэтому количественной картины по маршрутам у меня нет. Если бы у модуля появились реальные пользователи, я бы стартово смотрел на несколько вещей.

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

Через какое-то время после запуска посмотрел бы обращения в поддержку по модулю — разложил бы их по категориям, поискал корреляции с остальными метриками. Если корреляции находятся — формулировал бы гипотезы и согласовывал решения уже на их основании.

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

Маршруты — модуль, который я собирал end-to-end, заходя в предметную область с нуля.