MLF-355 Редактор automation — обновлённый UI

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

Ресёрч: визуальный язык редактора

Что изменилось в UI относительно текущего редактора проекта

Базовый редактор (src/components/flow/…) — SendPulse-подобный: у нод цветная шапка-бар по типу, палитра — всегда открытый сайдбар, инспектор на нативных контролах. Обновление — уход от «радуги» к единому cyan-акценту и стилизованным контролам.

Аспект Сейчас в проекте Обновлённый UI
Ноды — видЦветная шапка-бар по типу (Messenger #0EA5E9, Email #3B82F6…), белый текст, 220pxНейтральная карточка: cyan чип-иконка + тёмный заголовок + divider, 240px
Цвет нодСвой цвет у каждого типа — «радуга» на канвасеЕдиный cyan-акцент на всех; тип различается формой иконки
Выделение нодыСинее кольцо ring-blue-500Cyan-обводка + мягкое свечение (glow)
ПалитраВсегда открытый сайдбар 208px: цветные иконки + цветная левая полоса, категории спискомУзкий icon-rail 56px, раскрытие до 190px по hover (десктоп); на мобильном — bottom-sheet по «+»
Инспектор — контролыНативные <select> и radioКастомные Select (дропдаун) и Segmented (пилюли)
Инспектор — ширина320px (w-80)420px
Инспектор — акцентСиний (blue-400/blue-50)Cyan (бренд-accent)
Инспектор — шапкаЦветная левая полоса по типу нодыНейтральная строка + cyan чип-иконка
Не менялось (как в проекте): миникарта, клик по палитре → нода в центре канваса, drag-n-drop, плавный слайд инспектора (translate-x), зум-контролы, удаление ноды (футер + модалка), radial-dot фон, шрифты Golos/Unbounded.

Карточка ноды: было → стало

Главный уход — убрать сплошную цветную шапку-бар и радугу цветов по типам. Шапка становится строкой «чип + заголовок», отделённой тонкой линией; все ноды в едином cyan-акценте, тип различается формой иконки, а не цветом.

Было (текущий редактор проекта)
Messenger

Main1

Цветная плашка на всю ширину, белый текст. Радужный канвас из таких нод = сигнатура SendPulse.

Стало (Mailfit)
Messenger

Main1

Чистая карточка, единый cyan-акцент в чипе. Тёмный читаемый заголовок, тонкий divider. Канвас спокойный, без радуги.

Состояния ноды

Рамкой + маленькой точкой, без заливки всей карточки (в отличие от жёлтой подсветки SendPulse). Для MVP обязательна только «Ошибка».

Палитра на мобильном — «+» → bottom-sheet

На тач-устройствах hover нет, поэтому бокового рельса нет: плавающая кнопка «+» открывает нижний лист со списком нод. Канвас максимально свободен.

Цепочка Опубл.
Start

Триггер: событие

Добавить блок

Нажми «+» в макете телефона — откроется нижний лист.

Раскрытие рельса вешаем на hover — только десктоп; на мобильном триггер — тап по «+», не наведение (иначе на тач не сработает).

Если редактор на мобильном окажется read-only — палитру там можно скрыть совсем.

MLF-286 Нода START — триггеры «событие / сегмент»

Инспектор ноды START выше (тип триггера «Произошло событие») уже показывает новый UI: имя события с автокомплитом, интерактивный фильтр по свойствам и политику повторного входа. Ниже — решение по глубине фильтра, открытые вопросы и пояснения к каждому полю.

Ресёрч: триггеры запуска сценариев

Главное решение · глубина фильтра по свойствам события

Что рендерить в поле «Фильтр» инспектора. Карточка просит переиспользовать предикат-билдер сегментов — ресёрч показал два уровня. В самом инспекторе сейчас используется вариант A.

ВАРИАНТ A · полный

Предикат-билдер сегментов 1:1

И/ИЛИ/НЕ · вложенные группы · богатые операторы. Путь Customer.io.

+ Максимум мощности; один компонент на сегменты и триггеры

− Тяжелее в исполнителе: сложные предикаты по свойствам события

ВАРИАНТ B · урезанный

Плоский фильтр (equals / в списке, только И)

Без групп и ИЛИ. Сложное — в отдельный сегмент. Путь Segment v2.

+ Просто в UI и дёшево в исполнителе

− Мощную логику всё равно надо строить через сегмент

Что нужно решить до реализации

  1. Насколько мощный фильтр по свойствам события давать?
    Простой (только «равно» и «в списке», как вариант B) или полный конструктор с И/ИЛИ и группами (вариант A). Полный мощнее, но дольше делать.
  2. Когда срабатывает «вход в сегмент»?
    Сразу, как только человек попал в сегмент (быстрее для клиента, сложнее технически), или с небольшой задержкой, когда сегменты пересчитываются (проще).
  3. Нужен ли триггер «выход из сегмента» сразу?
    Или добавить его позже, после того как заработает «вход».
  4. Что делать при повторном событии, пока человек ещё в сценарии?
    Хватит ли трёх вариантов (пропустить / в очередь / начать заново), или нужны ещё «войти только один раз навсегда» и «не входить чаще, чем раз в N времени».

Пояснения к полям инспектора — простыми словами

Зачем каждое поле нужно и откуда взялось (по ресёрчу конкурентов).

Тип триггера

Выбираем, от чего запускается сценарий: человек совершил действие (событие) или попал в сегмент / вышел из него. Так устроено у всех крупных платформ — поэтому в списке три новых варианта.

Имя события

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

Фильтр по свойствам

Часто запускать нужно не на любое событие, а с условием — например, «заказ дороже 5000 ₽». Здесь и решаем, насколько мощный конструктор условий дать (два варианта выше).

Если человек уже в сценарии

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

Как считается вход — это про поведение, а не про поле

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

MLF-287 Настройки блоков — Email, Пауза, Условие, Действие

Настройки этих четырёх блоков (в редакторе выше) мы обновили, опираясь на то, как это сделано у похожих сервисов (Customer.io, Braze, Klaviyo, Iterable, HubSpot, ActiveCampaign, n8n). Ниже по каждому блоку — что решили, что ещё предстоит обсудить и что означает каждое поле простыми словами. То, что пока не делаем, помечено серым — и в самих настройках, и здесь.

Ресёрч: инспекторы нод у конкурентов

Email

отправка письма
Что решили
  • Добавили главную настройку — как отправлять письмо: пока готовить черновики (безопасно) или сразу слать людям. По умолчанию — черновики, чтобы не разослать случайно.
  • Тема письма, откуда берётся содержимое (готовый шаблон или свой HTML-код) и данные отправителя — оставили как было.
  • A/B-тест письма (несколько версий на разные части аудитории) пока не делаем, но место под него оставили.
Что ещё обсудить
  • Где настраивать отправителя (от кого письмо, куда отвечать) и как часто вообще можно писать человеку — прямо в этом блоке или в общих настройках рассылки.
  • Нужен ли предпросмотр письма (как оно выглядит: от кого, кому, тема) прямо здесь.

Пауза

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

Условие

развилка «да» / «нет»
Важно — это два разных блока. «Фильтр» отсеивает людей: кто не подходит под условие — дальше не идёт. «Условие» никого не отсеивает, а разводит людей на две дорожки — «да» и «нет» (в других системах это называют If/Else). Здесь речь именно про «Условие».
Что решили
  • Две дорожки — «да» и «нет», обе обязательны. Если условие не заполнено, человек идёт по «нет». Так же сделано у всех похожих сервисов.
  • Условие проверяет либо что за человек (город, теги, сколько потратил), либо что он уже сделал (открыл письмо, кликнул, купил). Конструктор условий тот же, что и для сегментов, — не изобретаем второй.
  • «Открыл ли за пару дней» собираем связкой Пауза → Условие, а не встраиваем ожидание внутрь условия — так понятнее.
  • Развилку сразу на много дорожек пока не делаем, но настройки готовим так, чтобы легко добавить позже.
Что ещё обсудить
  • Насколько сложные условия разрешать: с группами и «и / или» (как сейчас) или совсем простые.
  • Смотреть только на текущее действие человека или на всю его историю (например, покупал ли он вообще когда-нибудь).
  • Нужно ли уметь ветвить по конкретному письму — например, «кликнул именно в этом письме».

Действие

изменить свойство, тег или отправить данные
Что решили
  • Значение можно вписать вручную, взять из профиля человека или из переменной сценария. Так одно действие покрывает и «поставить 5», и «скопировать из другого поля» (идею взяли у Customer.io).
  • Со значением можно не только записать новое, но и добавить, увеличить, уменьшить или очистить — у многих сервисов это отдельные блоки, у нас всё в одном.
  • Одним блоком можно менять сразу несколько свойств.
  • Теги — можно добавить или убрать нужный тег.
  • Отправка данных во внешнюю систему (webhook) есть; ожидание ответа и запись его обратно в профиль — на будущее.
Что ещё обсудить
  • Должен ли сценарий дождаться, пока свойство точно обновится, прежде чем идти дальше — чтобы следующий шаг видел свежие данные (детали с разработчиками).
  • Нужно ли учитывать тип свойства (например, к списку — добавить/убрать, к обычному полю — заменить).
  • Разрешить ли создавать новый тег прямо здесь, не заходя в отдельный раздел.

Что означает каждое новое поле — простыми словами

Коротко: зачем оно нужно и что с ним делать.

Режим отправки (Email)

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

Режим паузы (До момента)

Вместо «подождать 2 дня» можно «дождаться, например, вторника 10 утра по времени получателя». Удобно, чтобы письма приходили в рабочее время, а не ночью.

Условие → да / нет

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

Источник значения (Действие)

Когда меняем свойство человека, значение можно вписать вручную, взять из его профиля или из переменной сценария. Так одно действие покрывает и «поставить 5», и «скопировать из другого поля».

Пока не делаем (в настройках помечено серым): A/B-тест письма, отправку только в рабочее время, развилку сразу на много дорожек, ожидание ответа от внешней системы с записью обратно в профиль. Место под всё это оставляем заранее, чтобы потом добавить без переделок.

MLF-295 Мультиканальные ноды — Telegram и Web Push «первого класса»

Omnichannel — ключевое отличие от обычного email-сервиса: сценарий должен уметь писать людям не только на почту, но и в Telegram и в push-уведомления в браузере. Блоки Telegram и Push (в редакторе выше) мы довели до «первого класса», опираясь на то, как это сделано у похожих сервисов (SendPulse, OneSignal, Braze). Ниже — что решили по каждому блоку, что ещё обсудить и что означает каждое поле простыми словами.

Ресёрч: мультиканальные ноды у конкурентов

Как блок понимает, каким каналом слать

Есть два подхода. Мы уже идём по первому и менять его не нужно — ресёрч это подтвердил.

НАШ ПУТЬ · как у SendPulse

Отдельный блок на каждый канал

В палитре свои блоки — Email, Telegram, Push, SMS, Viber. Выбрал блок — выбрал канал. Понятно с первого взгляда, и так уже собрана палитра.

Другой путь · как у Braze

Один блок «Сообщение» + выбор канала

Один универсальный блок, а канал (почта / push / SMS…) выбирается внутри него шагом. Мощно, но ломало бы уже согласованную палитру, поэтому не берём.

Telegram

сообщение в мессенджер
Что решили
  • Оставили выбор бота — как и раньше. Добавили подпись, что именно бот определяет канал: сообщение уйдёт от его имени. Так же устроено у SendPulse.
  • Оставили два вида контента: написать сообщение или запустить готовую цепочку. Третий вид (одобренный шаблон) для Telegram не нужен.
  • Добавили честное предупреждение: сообщение получат только те, кто уже написал этому боту. Кому нельзя написать первым — ничего не отправится.
Что ещё обсудить
  • Как показать в omnichannel-сценарии, что у workspace несколько ботов, и помочь не перепутать, через какого слать.
  • Как заранее проверять, что у человека вообще есть Telegram-подписка на этого бота, — по аналогии с проверкой подписки на push (детали с разработчиками).

Web Push

уведомление в браузере
Что решили
  • Было только «заголовок / текст / ссылка». Добавили иконку, картинку-баннер, кнопки (до 2), время жизни и приоритет — набор между минимумом SendPulse и богатым OneSignal.
  • Кнопки честно помечены: их показывает только Chrome (до 2), а Firefox и Safari — нет. Это ограничение самих браузеров, не наше.
  • Время жизни — сколько хранить уведомление, пока человек офлайн (по умолчанию 3 дня). Приоритет — показать сразу или тихо.
  • Добавили предупреждение: push уйдёт только подписанным на уведомления. Остальным ничего не отправится — это по правилам согласия.
Что ещё обсудить
  • Показывать ли прямо в блоке счётчик достижимой аудитории — сколько человек реально подписаны и получат push.
  • Нужны ли на старте бейдж (значок на иконке), отдельные иконки под разные браузеры и группировка уведомлений — пока отложили.

Проверка перед публикацией — по каждому каналу

Общий принцип «сломанный сценарий не опубликуется» уже есть (красная точка на блоке + список ошибок). К нему добавили правила под конкретный канал — блок подсвечивается как ошибка сразу, пока не заполнено главное:

Telegram

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

Web Push

Ошибка, если не заполнен заголовок или текст уведомления. Остальные поля (иконка, картинка, кнопки, ссылка) необязательны и публикацию не блокируют.

Что означает каждое новое поле — простыми словами

Коротко: зачем оно нужно и что с ним делать.

Чат-бот (Telegram)

Через какого бота слать. Бот и есть канал — сообщение придёт человеку от его имени, поэтому важно выбрать правильного.

Иконка / Картинка (Push)

Иконка — маленькая картинка рядом с текстом (квадратная, 256×256). Картинка — большой баннер под текстом. Оба необязательны, картинку показывают не все браузеры.

Кнопки (Push)

До двух кнопок с текстом и ссылкой прямо в уведомлении. Их показывает только Chrome — в Firefox и Safari кнопок не будет, это ограничение браузеров.

Время жизни · Приоритет (Push)

Время жизни — сколько хранить уведомление, пока человек офлайн (по умолчанию 3 дня). Приоритет — показать сразу (высокий) или тихо (обычный).

Пока не делаем (место в настройках оставили): бейдж и отдельные иконки под разные браузеры для push, группировку уведомлений (Web Push Topic), счётчик достижимой аудитории в блоке, проверку наличия Telegram-подписки заранее.

MLF-288 Публикация сценария: проверка схемы и счётчики на блоках

Главное правило «сценарий не должен ломаться» переносим на автоворонки: сломанную схему нельзя запустить на реальной базе клиентов. Ниже — как показать ошибки в схеме (прямо на поле, где собирается сценарий), жизненный цикл сценария (черновик → публикация → пауза → архив, где опубликованную версию уже нельзя случайно изменить) и счётчики на блоках (сколько людей прошло через каждый шаг) — с опорой на то, как это сделано у похожих сервисов (SendPulse, Klaviyo, Customer.io, Braze, HubSpot, n8n). В конце — что ещё нужно решить с продуктом до реализации.

Ресёрч: guardrails публикации у конкурентов

Проверка схемы перед публикацией

сломанный сценарий не опубликуется

Два уровня — предупреждение (не мешает опубликовать) и ошибка (не даёт опубликовать, пока не исправишь). Проблема видна сразу в двух местах: на самом блоке (красная точка в углу, уже есть во вкладке «Обновление UI») и в отдельном списке ошибок. Клик по строке в списке → нужный блок подсвечивается и оказывается по центру экрана — этого приёма как раз не хватает n8n.

2 ошибки · 1 предупреждение
Клик по ошибке → переход к блоку
Email

Тема не заполнена

Проблемный блок подсвечен (голубая обводка + красная рамка), и поле сборки сценария сдвигается к нему.

Кнопка недоступна, пока есть хотя бы одна ошибка. Предупреждения публикацию не блокируют.

Проверка идёт сразу во время редактирования (инлайн): блок подсвечивается и попадает в список ошибок, как только поле опустело или отвалилась ветка, — не дожидаясь публикации. Заполнили поле — ошибка тут же пропадает. Так устроено у SendPulse. Клик на «Опубликовать» — это последняя страховка: он блокирует запуск, пока есть хоть одна ошибка, и подводит к первому проблемному блоку.

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

Счётчики на блоках

сколько людей прошло через блок

Показывать цифры прямо на блоке сценария — приём, который используют похожие сервисы (SendPulse, Customer.io, Klaviyo). Берём его по смыслу, но оформляем спокойно в нашем голубом цвете, а не «радугой», как у SendPulse. Цифры показываются поверх схемы (это называют «оверлей») по переключателю «Показать статистику» и не мешают редактировать сценарий.

Блок отправки (Email) со счётчиками
Email

Тема: Ваш заказ оформлен

Вошло1 240
Сейчас38
Прошло1 190
Вышло12

На блоках отправки — вошло / сейчас / прошло / вышло. «Открыть список» — переход к списку конкретных людей (пока не в первой версии).

Блок-развилка (Условие)
Условие

Открыл письмо → да / нет

Вошло1 190
→ да610
→ нет580

На блоках-развилках — свой набор: сколько людей ушло по каждой дорожке.

Развилка · что считаем в MVP

За период (вошло / прошло / вышло, скажем, за месяц) — считается из уже накопленной статистики, это дёшево. Так делают почти все.

«Сейчас в блоке» — цифра в реальном времени (сколько людей прямо сейчас на этом шаге). Считается по-другому и обходится дороже. Из проверенных сервисов есть только у Klaviyo. Вопрос: делаем «сейчас» уже в первой версии или пока только цифры за период?

Жизненный цикл сценария

черновик → публикация → пауза → архив

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

Верхняя панель · полный набор кнопок
Цепочка Опубликована Версия 3 · история версий
черновик — правится свободно · опубликована — эту версию уже нельзя изменить · на паузе — новых людей не берёт, уже идущие доходят до конца · в архиве — только просмотр

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

Люди, уже идущие по сценарию, доиграют по прежней версии. Новую версию увидят только те, кто войдёт после публикации.

Единого решения в отрасли нет — сервисы делятся на два подхода. Опубликованное неизменно, правки — в новую версию (наш путь): так у Braze и HubSpot, старые версии можно только смотреть, но не менять. Правки прямо в работающем сценарии: так у Customer.io. Сравнения двух версий между собой (что именно изменилось) нет ни у кого из проверенных — в первую версию не берём.

Повторный вход в сценарий

кратко — детали в MLF-286
Настраивается для всего сценария сразу (в его старте), а не для отдельного блока — так же, как у Braze, и так же, как задумано у нас. Варианты «войти один раз / каждый раз / не чаще раза в N дней» уже разобраны во вкладке — здесь не дублируем.

Что нужно решить с продуктом до реализации

Ресёрч зафиксировал развилки — сам за продукт не решает. Пять вопросов к согласованию:

  1. Насколько глубоко проверять схему в первой версии.
    Ловить ли уже сейчас тупики (ветки, до которых никто не дойдёт) и зацикливания без паузы — и считать это ошибкой или предупреждением? Или в первой версии ограничиться простыми проверками (поля заполнены, обе дорожки подключены), а разбор структуры — позже?
  2. Показывать ли «сейчас в блоке» уже в первой версии.
    Цифра «сколько людей прямо сейчас на этом шаге» обходится дороже, чем цифры за период (она считается по-другому). Достаточно ли на старте «вошло / прошло / вышло», а «сейчас» — позже?
  3. Где показывать счётчики.
    Прямо на блоках сценария (как у SendPulse, Customer.io, Klaviyo) — или в отдельном отчёте (как у Braze), или и то, и другое?
  4. Как объяснить правило про уже идущих людей.
    Каким текстом показать пользователю, что правки не затронут тех, кто уже идёт по сценарию — учитывая, что в части других сервисов поведение обратное (людей переводят на новую версию)?
  5. Сколько кнопок жизненного цикла нужно в первой версии.
    Нужны ли сразу архив и история версий с просмотром прошлых, или на старте хватит «черновик → публикация → пауза»?

MLF-293 Симуляция пути и live-debugger

Две новые поверхности в редакторе. Симуляция — прогон выбранного контакта по схеме без реальных отправок: видно, куда он пойдёт, и почему свернул в ту ветку. Live-debugger — лента исполнения по реальным контактам с фильтром, чтобы разобрать «почему письмо не ушло». Обе рисуют один слой подсветки — зелёный путь на схеме и бейдж «почему» на развилке. Опора — на то, как это сделано у Braze, HubSpot, Customer.io и n8n.

Ресёрч: симуляция и live-debugger у конкурентов
Попробуйте вживую наверху кнопка режима зависит от статуса сценария

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

② Debug (на опубликованном сценарии): сначала опубликуйте — кликните блок Email, впишите тему (уберётся ошибка) и нажмите «Опубликовать». Статус станет «Опубликована», и кнопка «Симуляция» сменится на «Debug» → нажмите → внизу откроется лента исполнения. Клик по строке подсветит путь этого контакта на схеме и покажет разбор события. Вернуть черновик — «Архивировать», затем «Восстановить».

Режим «Симуляция» — прогон без отправок

отдельный read-only режим на черновике

Отдельный режим (кнопка в тулбаре), в который входишь — как «Test Canvas» у Braze и «Test» у HubSpot. Выбираешь реального контакта из базы (отдельную сущность «тестовый контакт» не вводим — индустрия её не навязывает) и жмёшь «Прогнать». Прогон строго без сайд-эффектов: ни отправок, ни записи событий, ни изменения профиля. Путь контакта зеленеет на схеме, непройденные ветки — приглушаются. Пока идёт прогон, схему не редактируешь (режим read-only).

Лента контролов (появляется под тулбаром)
Симуляция · dry-run Иван Петров · Москва · открыл письмо Прогнать 5 шагов · Email не отправился бы

Название «Симуляция / dry-run» намеренно отличает её от «отправить тестовое письмо» (это отдельная будущая кнопка). Урок Adobe: у них «test mode» реально шлёт сообщения — мы так не делаем.

Подсветка на схеме
Messenger
Пауза

Пройденный шаг — зелёное кольцо + галочка; непройденная ветка — приглушена. Cyan-выделение в режиме прогона уступает зелёному, чтобы цвета не спорили.

Эталон — Braze «Preview User Paths». Выбор профиля → Run без реальных отправок; на развилках показывает met/unmet — «почему пошёл сюда». Берём один-в-один.
Зелёная подсветка — HubSpot. Путь записи подсвечивается зелёным, «No actual actions will be executed». Тот же визуальный язык у нас.
Отстройка от SendPulse. У него симуляции/dry-run нет вообще — только агрегаты постфактум. Предсказание пути «до» и объяснение «почему» — наш дифференциатор.

«Почему пошёл сюда» — объяснение ветвления

first-match · бейдж + разбор

Индустрия объясняет развилку одинаково: контакт идёт по первой ветке, чьё условие выполнил (first-match — так у Braze, HubSpot, Customer.io). На развилке показываем компактный бейдж (какая ветка выбрана и почему), а клик по блоку раскрывает в инспекторе разбор — какие условия выполнены (зелёным), какие нет (серым). Тот же самый разбор работает и в симуляции (прогноз), и в debugger'е (факт) — учить его нужно один раз.

Бейдж на развилке
Условие

Открыл письмо → да / нет

✓ Открыл письмо → да

Сразу видно, по какой дорожке ушёл контакт, без раскрытия деталей.

Разбор шага в инспекторе (read-only)
✓ Пройден в прогоне
Почему выбрана ветка «да»

Ветки проверяются по порядку, контакт идёт по первой, чьё условие выполнил (first-match).

  • Открыл письмо = да
Прогноз по выбранному профилю — dry-run, без реальных отправок и событий.
Где прогон упёрся бы
Email

Тема не заполнена — не отправится

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

Live-debugger — лента исполнения по контактам

нижняя панель · фильтр по контакту

Нижняя панель («консоль») на активном сценарии: лента исполнения из логов (cdp.automation_analytics_events — события шагов; состояние и путь контакта — из AutomationExecutions) — время, контакт, блок, событие, статус; ошибки красным. Есть фильтр по контакту (обязателен) и по статусу (идёт / ожидание / успех / ошибка / пропущен). Клик по строке → подсветка пути этого контакта на схеме (тот же зелёный слой, что и в симуляции) и разбор события справа. Нижний dock, а не правый drawer — правый борт занят инспектором, а ленте нужна ширина; получается естественная пара: путь на схеме ↑, лог снизу ↓.

Live-debugger near-real-time · 30 дней Контакт: Иван Петров ▾ Все Ошибка
ВремяКонтактБлокСобытиеСтатус
11:58:40Иван ПетровEmailОшибка: тема письма не заполненаОшибка
11:58:40Иван ПетровУсловиеВетка «Да» (открыл письмо)Успех
11:58:39Иван ПетровMessengerСообщение отправленоУспех
12:03:12Алексей СмирновПаузаОжидание 2 дняОжидание
Эталон — HubSpot Enrollment history. Поиск записи → полная история шагов с таймстемпами, ошибки красным, подсветка пройденных веток. Прямо ложится на наши AutomationExecutions (состояние по контакту) + cdp.automation_analytics_events (события шагов).
Типы событий — Customer.io Activity Log. Фильтр по типу (доставка / ошибка / пропуск) и окно 30 дней — берём как модель фильтра и ретенции.
Реальность рынка. Живого real-time стрима контактов по нодам почти ни у кого нет. Поэтому «real-time» у нас = near-real-time (обновление раз в 3–5 с), а не WS-стрим.

Один движок подсветки — два входа

прогноз и факт рисуются одинаково
Симуляция — на черновике

Субъект — выбранный профиль, без runtime-данных. Показывает прогноз: куда контакт пойдёт и почему. Проверка сценария до запуска (design-time QA).

Debug — на активном flow

Субъект — реальные контакты из AutomationExecutions, нижний dock. Показывает факт: как контакт прошёл на самом деле. Разбор проблем на живом сценарии (run-time troubleshooting).

Отдельной таблицы логов (AutomationExecutionLogs) у automation нет — и не требуется: состояние и путь берём из AutomationExecutions (path, currentNodeId, status), ленту событий — из cdp.automation_analytics_events. (FlowExecutionLogs — это чат-боты, ADR-000.)

Оба рисуют один и тот же слой «зелёный путь + бейдж почему» — движок строим один раз (как у HubSpot). Разделяем только входы, потому что это разные стадии жизни сценария с разным контекстом тулбара (черновик vs активный).

Что уже зафиксировано с продуктом

Проговорено с М. Терентьевым по итогам ресёрча — это бриф для макета:

  1. Субъект симуляции — любой реальный профиль (поиск/выбор из базы, как HubSpot). Отдельной сущности «тестовый контакт» не вводим.
  2. Строгий no-send. Симуляция — абсолютно без сайд-эффектов (ни отправок, ни событий, ни изменения профиля), в отличие от Adobe test mode. Отправка тестового — отдельная будущая кнопка.
  3. «Real-time» = near-real-time. Лента debugger'а обновляется раз в 3–5 с (poll/refresh), не WS-стрим — совпадает с рынком.
  4. Окно debugger'а — последние 30 дней (как Customer.io), простая пагинация; расширение до 6 мес — потом.
  5. Единый слой объяснения — один визуальный механизм «подсветка пути + почему» на обе фичи.
  6. Глубина «почему» — met/unmet + сработавшая ветка (first-match), уровень Braze. Полный разбор предиката со значениями — не MVP.

Что ещё уточнить с продуктом

Крупные решения уже зафиксированы (выше); осталось несколько развилок реализации:

  1. Где живёт Debug.
    В самом редакторе (нижний dock, как в макете) — или на отдельной странице мониторинга сценария? В макете сделан dock в редакторе: путь на схеме и лог рядом.
  2. Глубина drill-down по событию.
    Сейчас в разборе показываем краткий payload (что записалось / почему пропущен). Нужен ли уже в первой версии полный разбор предиката со значениями атрибутов, или это на потом?
  3. Интервал обновления и пагинация.
    3–5 секунд на обновление ленты — норм? Как листаем окно 30 дней (по страницам / подгрузка вниз)?
  4. За рамками MVP — заложить место.
    Конфиг времени входа (прошлое/будущее, как у Braze), «частичный прогон от ноды» (как у n8n), расширение ретенции до 6 мес (как у HubSpot). Не делаем сейчас, но проектируем так, чтобы добавить без переделок.