Как подружить Яндекс Трекер, Power BI и дата-каталог с помощью одной облачной функции

Легкой рукой мы создали отдельную очередь для ревью корпоративных отчетов (которых на проде существует около 1 тыс.) и внедрили процесс генерации задач на ревью (несколько десятков в месяц). Но мы быстро убедились, что это только половина пути. Мало просто создавать заявки — необходимо настроить процесс так, чтобы он был бесшовным и интуитивно понятным для людей, жестким с точки зрения контроля и гибким в логике переходов по статусам. Кроме того, предстояло автоматизировать всю рутину, для которой не требуется человеческая сознательность.

Меня зовут Лариса Фернандес, я старший разработчик аналитических систем в Лемана Тех. Мы развиваем технологическую платформу Лемана ПРО. Над ней работает команда более чем из 50 BI-разработчиков: они создают и поддерживают отчеты, которыми пользуется свыше 20 тыс. пользователей.
Ранее мы детально рассказывали, для чего внедряли ревью отчетов, какие требования к дашбордам формулировали и как организовали ревью. Сегодня опишем более подробно, как мы настраивали и автоматизировали этот процесс в Яндекс Трекере. Этот материал будет полезен как тем, кто хочет создать подобный процесс ревью отчетов, так и тем, кто настраивает Яндекс Трекер для любых сложных бизнес-процессов со множеством статусов, ветвлений и проверок.
Стандартные опции Яндекс Трекера
Для ревью отчетов мы создали отдельную очередь REPORTS. Это позволило нам изолировать процесс, настроить уникальный жизненный цикл задачи, добавить локальные поля и гибко управлять правами доступа на каждом этапе.

Права доступа: кесарю — кесарево
Штатные сотрудники компании по умолчанию имеют доступ на просмотр задач очереди. Это поддерживает прозрачность процессов.
Исполнитель задачи автоматически получает права на ее редактирование, исполнители меняются на разных этапах.
Технические учетные записи (роботы) наделены максимальными правами, включая изменение настроек очереди. Это необходимо для работы скриптов, которые могут принудительно менять статусы, обновлять системные поля и обходить ограничения UI для обычных пользователей.
Рабочие процессы (воркфлоу) и условия переходов
Стандартные механизмы воркфлоу в Яндекс Трекере закрыли три блока задач.
Автоматизация: очистка, заполнение или копирование полей, отправка уведомлений. При смене статусов триггеры автоматически очищают, заполняют или копируют метаданные. Чаще всего это касается поля «Исполнитель». На разных этапах им может быть автор отчета, дата-стюард, DPO (Data Protection Officer) или назначенный ревьюер. Далее конкретный исполнитель получаетуве домления о дедлайне (в LOOP) и призывается в комментариях.
Задание условий перехода: только пользователи группы ревьюеров могут перевести задачу в статус «В работе» (проведение ревью), только DPO (Data Protection Officer) может вернуть задачу из статуса «Заблокировано» (где происходит проверка корректного отображения персональных данных и доступа к сенситивным данным).
Заполнение полей пользователем на экранах перехода: мы используем всплывающие экраны (вкладка «Экран перехода» в настройках воркфлоу), чтобы обязать (или побудить —зависит от обязательности поля) пользователя заполнить нужные поля в момент смены статуса — например, указать причину возврата на доработку.

Локальные поля: переменные, флаги, контекст
Для управления логикой в очереди REPORTS мы активно используем локальные поля. Они выполняют роль переменных, флагов автоматизации и контекстных подсказок для пользователей. Их можно разделить на три основные группы.
Ролевые поля (Тип: «Пользователь»)
Мы завели отдельные поля под каждую роль в процессе: технический владелец отчета, ревьюер, дата-стюард.
Зачем это нужно: на них завязана вся динамическая смена исполнителей и ограничение прав. Например, технический владелец является исполнителем только в статусах «Новый» и «Доработка». На этих этапах он работает над задачей, для него приближается дедлайн, но в остальных статусах его права ограничиваются — так, он не может сам закрыть задачу и указать статус ревью.
Логические переключатели (флаги ветвления)
Ответы на вопросы вроде «Требуется полное ревью?» или «Требуется согласование DPO?» записываются в логические поля и определяют дальнейший трек задачи или выбор автоматизации.
Если отчету не нужно полное ревью (актуально для мини-, архивных, постраничных отчетов), триггер автоматически исключает из чек-листа ревьюера пункт о детальной проверке модели данных. Флаг согласования DPO переводит задачу по альтернативной ветке воркфлоу, добавляя системные комментарии о проверке персональных данных.
Технические переменные для API
Ряд полей используется как переменные для обмена данными между трекером и внешними системами. Например, это поле asset_id отчета.
Как работает автоматизация: по asset_id мы проверяем полноту описания отчета в дата-каталоге и заполняем поле «Отчет описан в дата-каталоге: да/нет». Далее при переходе «Валидировать отчет в дата-каталоге» происходит проверка значения в этом поле, определяющая дальнейшие действия триггера. Если значение = «нет», стандартный триггер трекера откатывает задачу в предыдущий статус и просит автора сначала заполнить описание в каталоге, что ранее дата-стюарды делали вручную.
Кроме того, значения в полях позволяют исполнителям видеть текущий контекст проверок и причины ограничений. Правда, работа с локальными вспомогательными полями не всегда получается простой, но об этих ограничениях мы поговорим чуть ниже.
Инструменты автоматизации: триггеры, автодействия и отказ от макросов
Основную работу по автоматизации очереди REPORTS выполняют триггеры и автодействия. А вот стандартным макросам в нашем процессе места не нашлось: на наш взгляд, они рассчитаны на слишком простые, полуручные операции, которые не менее эффективно закрываются воркфлоу или триггерными сценариями.
Но начнем с автодействий. Если триггеры реагируют на конкретные события «здесь и сейчас», то автодействия работают по расписанию. Для них не нужно подбирать события, которые их запустят. Они стартуют с заданной периодичностью и сканируют очередь по фильтрам.
В нашем процессе автодействия закрывают три регулярные задачи.
Контроль дедлайнов

Напоминание в LOOP Система регулярно проверяет, сколько дней осталось от срока, выделенного на конкретный этап (на большинстве этапов это 15 дней), и время от времени отправляет исполнителю ненавязчивые напоминания о приближении или, что хуже, пересечении «мертвой черты».
Ежедневные дайджесты
Каждое утро автодействие собирает список задач в статусе «Готово к ревью» и отправляет список в корпоративный Loop-канал ревьюеров, которые разбирают их как горячие пирожки.
Пакетная инициализация и миграция данных
Это незаменимый инструмент для разовых инфраструктурных задач. Например, когда мы внедряем новое локальное поле, триггеры начинают заполнять его только в новых карточках задач. Чтобы массово прописать дефолтные значения или привязать родительские задачи во всем историческом массиве, мы разово запускаем целевое автодействие.
Триггеры как ядро автоматизации и архитектура «одной функции»
Если встроенные воркфлоу задают базовые пути процесса, то триггеры — это главный инструмент для реализации нашей кастомной бизнес-логики. Мы используем их для всех проверок и интеграций, которые невозможно настроить через стандартный интерфейс.
Все наши триггерные сценарии можно разделить на четыре ключевые задачи.
Обогащение данных из дата-каталога
При создании задачи триггер инициирует проверку карточки отчета в дата-каталоге и заполняет локальные поля «Отчет описан в дата-каталоге» и «Статус валидации отчета в дата-каталоге».
Валидация на переходах
Мы блокируем движение задачи, если не выполнены условия предыдущих этапов. Например, без отметки об описании отчета задача не уйдет на валидацию к дата-стюарду. А пока дата-стюард не валидирует описание, задача не может перейти в статус «Готово к ревью».
Автоматическое закрытие (защита от «мусорных» задач)
Если отчет был удален из BI-системы, проводить ревью бессмысленно. В этом случае функция, запускаемая по триггеру, проверяет, что отчет действительно удален, и закрывает задачу с соответствующей резолюцией.
Синхронизация метаданных (обратная связь)
После некоторых действий в трекере триггеры отправляют данные обратно в дата-каталог, фиксируя там номер задачи, имя ревьюера, финальный статус и дату прохождения ревью.
Реализовать такую логику стандартными средствами трекера невозможно: встроенные HTTP-запросы (вебхуки) умеют отправлять данные наружу, но не умеют принимать ответ от внешней системы, обрабатывать его и на его основе менять поля задачи. Для этого необходим полноценный бэкенд.
Поэтому мы обратились к облачным функциям. Точнее — к одной. По причинам, которые находятся за пределами сферы влияния автора статьи, для автоматизации очереди REPORTS мы получили в распоряжение ровно одну облачную функцию.
Чтобы уместить в нее множество совершенно разных проверок и не запутаться, мы настроили ее как единое окно для всех запросов.
На стороне Яндекс Трекера мы создали несколько независимых триггеров под каждую задачу, но все они отправляют POST-запросы на один и тот же URL нашей единственной функции.
На стороне функции в теле каждого JSON-запроса мы передаем специальный параметр — название конкретного действия, которое нужно выполнить (например, проверить описание или закрыть задачу), а также метаданные (ID отчета, автора и другие). Код внутри облачной функции считывает этот параметр и понимает, какой именно блок скрипта нужно запустить в данный момент.

Таким образом, в теле API-запроса из трекера мы передаем контекст задачи. На текущий момент наш JSON-payload включает следующие параметры:
- run_fn — ключевой параметр (название функции), определяющий, какой именно сценарий автоматизации нужно запустить;
- report_id — уникальный идентификатор отчета в дата-каталоге, по которому робот находит нужную карточку;
- report_review_request_id — номер самой задачи на ревью в Яндекс Трекере;
- issue_status, issue_resolution — текущий статус и финальная резолюция задачи;
- reviewer_ldap, owner_ldap — LDAP-логины ревьюера и технического владельца отчета. Они нужны для авторизации, отправки уведомлений и проверки «автор не может быть ревьюером»;
- report_review_request_closed_date — дата закрытия задачи, которая передается в дата-каталог для фиксации времени успешного прохождения проверки.
Даже с облачными функциями не все безоблачно в сервисе Яндекс Трекера
Несмотря на универсальный тандем триггеров и облачных функций, периодически нам не хватает встроенных возможностей самого трекера. В процессе эксплуатации мы столкнулись с четырьмя досадными ограничениями платформы.
Ограничение №1: невозможность запретить очистку локальных полей
В трекере нельзя сделать локальное поле жестко обязательным для заполнения так, чтобы пользователь не мог его просто очистить. В нашем процессе это может приводить к ошибкам.
Рабочая ситуация: задача на ревью автоматически создается на пользователя, который опубликовал или обновил отчет на сервере Power BI. Он назначается «Исполнителем» и «Техническим владельцем» отчета. Однако пользователь по разным причинам может решить отказаться от «чести» готовить отчет к ревью и просто удаляет себя из полей. Итог: задача «висит» без ответственного, уведомления о дедлайнах летят в никуда, ревью отчета не проводится.
Если бы поле было неудаляемым, пользователю пришлось бы указать вместо себя имя нового BI-разработчика, передавая ему ответственность. Сейчас мы видим два пути решения этой проблемы.
1. Подтягивать имя предыдущего владельца через историю изменений задачи.
2. Создать дублирующее скрытое поле «Технический владелец (скрытое)». Оно автоматически копирует значение из основного поля, пока то заполнено. Если пользователь очищает основное поле, триггер берет значение из скрытого и возвращает его на место.
Ограничение №2. Особенности работы со скрытыми полями и асинхронность API
Второй способ приводит к еще одной боли — специфике скрытых полей. Чтобы пользователь не очистил бэкап-поле, мы хотим сделать его скрытым. Но здесь кроется нюанс: трекер не позволяет триггеру прочитать значение из скрытого поля «на лету» — его нужно сначала сделать видимым.
При попытке настроить стандартную цепочку действий в триггере мы натыкаемся на асинхронность API.
Предположим, есть два действия, которые идут последовательно.
1. Сделать поле видимым.
2. Взять его значение и записать в основное поле.
Однако из-за отсутствия встроенных механизмов задержки (таймаутов) в триггерах трекера второй шаг пытается выполниться до того, как завершится первый. Система считывает еще скрытое (а значит, недоступное для чтения) поле и возвращает пустое значение.
Итог: эту последовательность шагов придется переносить в нашу облачную функцию. Обидно, ведь логика состоит из двух банальных обращений к API Яндекса, но из-за архитектурных нюансов платформы реализовать ее простым триггером без написания кода невозможно.
Ограничение №3. Односторонняя работа вебхуков
Главная архитектурная слабость встроенного конструктора триггеров в трекере — работа по классическому принципу одностороннего вебхука. Система умеет отправлять HTTP-запросы во внешние сервисы (поддерживаются даже методы GET и POST), но полностью игнорирует тело ответа.
Вы физически не можете стандартными средствами триггера распарсить JSON, полученный от внешней системы, и разложить его данные по локальным полям задачи. Именно из-за этой особенности, несмотря на всю зрелость и полноту API Яндекс Трекера, для построения сквозной интеграции с дата-каталогом нам приходится задействовать промежуточную облачную функцию. Она выступает полноценным бэкендом: принимает запрос от трекера, опрашивает каталог, забирает нужные данные и сама переписывает поля в задаче через входящий API трекера.
Ограничение №4. Статичные условия переходов в воркфлоу
Последнее важное замечание касается настройки процессов. В условиях перехода между статусами нельзя динамически проверять значения локальных полей для блокировки или разрешения перехода.
Из-за этого ограничения нам пришлось реализовать более громоздкую логику.
1. Пользователь нажимает кнопку перехода в следующий статус.
2. Система пропускает задачу вперед, подтягивает нового исполнителя по логике этапа.
3. В этот момент срабатывает триггер нового статуса, который проверяет содержимое полей (например, заполнено ли описание отчета).
4. Если поле не соответствует ожиданиям, триггер принудительно возвращает задачу в предыдущий статус, меняет исполнителя и оставляет комментарий с требованием завершить свою часть работы.
В этой статье мы подробно разобрали, как с помощью одной облачной функции и кастомных триггеров можно построить гибкий и контролируемый процесс ревью, связав Яндекс Трекер и корпоративный дата-каталог. Действительно, такая связка позволяет реализовывать практически любые сложные сценарии автоматизации. Тем не менее это требует написания и поддержки внешнего кода. Было бы здорово, если бы самые частые и очевидные боли при настройке процессов со временем появились в Яндекс Трекере как коробочные, стандартные инструменты. В частности, хочется увидеть в интерфейсе:
гибкую настройку локальных полей;
валидацию переходов между статусами через проверку значений в любых полях непосредственно в момент перехода;
и — мечтать так мечтать — полноценную обработку ответов от внешних API внутри стандартных вебхуков.
Наш процесс автоматизации ревью отчетов в Лемана Тех остается живым и гибким, подстраиваясь под меняющийся рабочий контекст. Регулярно появляются новые кейсы и рутинные задачи, которые точно стоит переложить с человека на робота. Кроме того, мы постоянно дорабатываем логику взаимодействия систем под меняющиеся нужды бизнеса и методологию Data Governance.
Буду рада обсудить ваши решения аналогичных задач в комментариях. Что удается закрыть стандартными инструментами, а для чего приходится изобретать собственные решения?
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.