Bizproc 26.1800.0: ошибка действия обрывает ветку, опции стали feature-флагами
Ломающее обновление
Удалены или изменены публичные API — прикладной код может перестать работать.
В Bizproc 26.1800.0 действие на BaseActivity, вернувшее ошибку, обрывает свою ветку в новом конструкторе, поля «Файл» в хранилищах закрыты для записи, а одиннадцать скрытых опций модуля заменены feature-флагами, и Option::set() их больше не включает. Свои действия, запись файлов в хранилища, скрипты настройки модуля и флаги функций, которые включали опциями, проверьте сразу после обновления. Прошлый разбор модуля — Bizproc 26.1500.0–26.1700.0.
Новое
Запускайте черновик от триггера с тестовыми данными
Bitrix\Bizproc\Public\Service\TestRun\TestRunService запускает сохранённый черновик шаблона, а выходы триггера пользователь вводит руками (prepare(), start(), status(), finish()). Триггер-старт вместо своей логики публикует введённые значения (BaseTrigger::executeWithPayload()), его условие не проверяется, процесс идёт с событием CBPDocumentEventType::Debug. Сервис работает с шаблонами нового конструктора (TYPE = nodes) на документе Workflow, один запуск на пользователя и шаблон, не дольше 24 часов. Права сервис не проверяет. Запускать может тот, кто вправе публиковать шаблон, и проверить это перед вызовом должен ваш код (TemplateAccessService::canPublish()). CBPDocument::startWorkflow() и CBPRuntime::createWorkflow() получили в конце необязательные ?VersionChoice и ?TestRunContext, у CBPActivity появились getTestRunContext() и setTestRunContext().
Проверяйте условие узла на записи своего триггера
Триггер, в том числе из другого модуля, может назвать запись, на которой решается условие его узла до старта и при выполнении, если объявит три публичных метода. Интерфейса нет намеренно: implements дал бы fatal там, где ваш модуль уже обновлён, а bizproc ещё нет, поэтому bizproc ищет методы по именам.
<?php declare(strict_types=1);
use Bitrix\Bizproc\Activity\BaseTrigger;
use Bitrix\Bizproc\Activity\Trigger\TriggerParameters;
// Фрагмент триггера своего модуля: условие узла решается на элементе инфоблока из события
class CBPCatalogItemSoldTrigger extends BaseTrigger
{
// FieldName свойств узла, от которых зависит документ условия
public static function getConditionDocumentSourceFieldNames(): array
{
return ['iblock_id'];
}
public function getConditionDocumentComplexType(): ?array
{
$iblockId = (int)$this->IblockId;
return $iblockId > 0 ? ['iblock', 'CIBlockDocument', 'iblock_' . $iblockId] : null;
}
public function getConditionDocumentId(TriggerParameters $parameters): ?array
{
$elementId = (int)$parameters->get('ELEMENT_ID');
// Все три части — непустые строки, иначе ответ считается пустым
return $elementId > 0 ? ['iblock', 'CIBlockDocument', (string)$elementId] : null;
}
}
Передавайте данные в исходящий вебхук
У блока «Исходящий Вебхук» появилось свойство Payload, JSON-объект скалярных значений с подстановками. В теле он уходит под ключом payload рядом с document_id. Если подстановка дала не скаляр или тело вышло больше 1 МБ, вебхук не отправляется, а в журнал процесса пишется ошибка. Блок без Payload шлёт прежнее тело.
Ограничьте «Сотрудник уволен» подразделениями
Триггер получил свойство DEPARTMENTS, привязку к подразделениям и командам из humanresources. Пустая привязка запускает сценарий на каждое увольнение, как раньше. Если привязка задана, а humanresources на портале нет, запуск отклоняется с кодом REFUSAL_NO_HUMANRESOURCES, но в лог как ошибка не пишется.
Кому теперь доступны хранилища и отладка
Хранилища и представления данных раньше открывались только администратору. Теперь хватит права создавать, редактировать или публиковать шаблоны (TemplateAccessService::canAccessTemplates()). Хранилище представления закрыто тому, кто не может редактировать шаблон-владелец (canEditStorage(), getClosedStorageTypeIds()). При сохранении и превью представление проверяет каждый источник строк, свой провайдер отвечает через SourceAvailabilityCapableProvider::isSourceAvailable().
Сессии отладки видят администратор и те, кто может публиковать шаблон, а трассы они получают только по своей сессии. DebugTrace::getBySessionIdAction() принимает afterId и отдаёт записи после него.
Список запуска проверяет права на шаблон
bizproc.workflow.start.list раньше проверял права только на документ. Теперь каждая пара «шаблон + документ» идёт через canUserOperateDocument(StartWorkflow) с WorkflowTemplateId и группами пользователя. Шаблон без разрешённой пары скрыт, как и пара, на которой проверка бросила исключение. При start_list_order_enabled = Y (по умолчанию N) сверху закреплённые шаблоны, за ними впервые опубликованные за 168 часов, дальше по числу успешных ручных запусков за 30 дней.
Поля и схема в конструкторе
- Поле «Список» в
bizproc.fieldsпри одиночном выборе открывает диалогui.entity-selector, при множественном показывает чипыTagSelector, в обоих есть вкладка выражения. ИзSelectFieldубраныrenderSelectionControl(),getValueState()иisExpressionCarrierValid(). - В поле «Пользователь» кнопка «...» вставляет выражение тегом.
- Свой
SelectionProviderможет реализовать необязательныйopenSelection(), поле обращается к нему черезBaseField::requestSelection(). - Узел «Пул» (
CBPPoolNode) обозначает участника на схеме и скрыт заPoolNodeFlag. - Enum
ActivityPortRoleзадаёт роли портов (positive,negative,loopBody,loopExit,entry), у утверждения, foreach и while они уже стоят. ReadableExpressionResolver::resolve()переводит{=Document:...}в{Имя поля}.
AI-агенты
Свой блок может описать настройки для агента с учётом документа и ограничить их сочетания (IBPActivityAiContextualDescription, IBPActivityAiSettingConstraints), а категорию каждой настройки bizproc определяет сам. Название и описание черновика, заполненные агентом, помечаются как его (AgentOwnedMetadata), а колонка «используют» в гриде агентов учитывает участников проектов из констант шаблона.
Что сломается
Проверьте свои действия на BaseActivity
BaseActivity::execute() с ошибками из checkProperties() или internalExecute() возвращает Cancelled вместо Closed. В новом конструкторе поток идёт по выходному порту только после успеха, и ветка за упавшим действием не выполняется.
В классическом последовательном шаблоне следующий блок запустится, как раньше.
Из коробки на BaseActivity построены createstoragenode, readdatastorageactivity, writedatastorageactivity, deletedatastorageactivity, fixresultactivity, outgoingwebhookactivity и calendargetinform из calendar. В Битрикс24 на нём же построены действия смарт-процессов crm (создание, изменение, удаление элемента и другие), а также действия im, imopenlines, sign, humanresources, biconnector и call. «Чтение данных» больше не считает пустой результат ошибкой и очищает выходные поля. Если ошибка вашего действия не должна останавливать ветку, пишите её в журнал сами:
<?php declare(strict_types=1);
use Bitrix\Bizproc\Activity\BaseActivity;
use Bitrix\Main\ErrorCollection;
use Bitrix\Main\Result;
class CBPPartnerSyncActivity extends BaseActivity
{
protected static function getFileName(): string
{
return __FILE__;
}
protected function internalExecute(): ErrorCollection
{
$result = $this->pushToPartner();
if (!$result->isSuccess()) {
// Сбой выгрузки не повод останавливать ветку: только запись в журнал процесса
$this->logError(implode('; ', $result->getErrorMessages()));
}
// Непустая коллекция теперь означает Cancelled
return new ErrorCollection();
}
private function pushToPartner(): Result
{
return new Result(); // запрос во внешнюю систему
}
}
Включайте функции флагами, а не опциями
Скрытые опции модуля заменены feature-флагами Bitrix\Main\Config\Feature. Флаг хранится в b_feature_flag и по умолчанию выключен. Переноса значений в коде модуля нет, его делает установщик обновления, который на сайте не остаётся. После обновления в b_option у bizproc появляется отметка feature_flags_migration_740096_completed, а bizprocdesigner 26.1200.0 тем же переносом включил свои флаги ровно для опций со значением Y. Опции bizproc, скорее всего, переносятся так же, но если пользовались функциями из таблицы, проверьте их флаги после обновления. Опции модуль больше не читает, и Option::set('bizproc', …, 'Y') в скриптах развёртывания и настройки ничего не включает. Переведите их на Feature::enable().
Опция bizproc |
Флаг Bitrix\Bizproc\Public\Feature\… |
|---|---|
debugger_available |
Debugger\ProcessDebuggerFlag |
dataview_enabled |
DataView\DataViewFlag |
last_values_capture |
Template\LastValuesCaptureFlag |
template_version_history_enabled |
Template\TemplateVersionHistoryFlag |
pilot_publication_available |
Template\PilotPublicationFlag |
node_variable_actions_available |
Node\NodeVariableActionsFlag |
outgoing_webhook_node_available |
Node\OutgoingWebhookNodeFlag |
process_data_enabled |
ProcessData\ProcessDataFlag |
ai_agent_upgrade_enabled |
AiAgent\AgentUpgradeFlag |
bitrix_ai_boss_report_available |
AiAgent\BossReportAgentFlag |
bitrix_ai_project_pulse_available |
AiAgent\ProjectPulseAgentFlag |
Уже включённый флаг Feature::enable() не трогает, так что скрипт можно запускать повторно:
<?php declare(strict_types=1);
use Bitrix\Bizproc\Public\Feature\DataView\DataViewFlag;
use Bitrix\Bizproc\Public\Feature\Debugger\ProcessDebuggerFlag;
use Bitrix\Main\Config\Feature;
use Bitrix\Main\Loader;
Loader::requireModule('bizproc');
// Было: Option::set('bizproc', 'debugger_available', 'Y');
Feature::enable(ProcessDebuggerFlag::class, DataViewFlag::class);
Пока ProcessDebuggerFlag выключен, контроллеры отладки отвечают ACCESS_DENIED.
Уберите файлы из записи в хранилища
- Поле «Файл» больше не создать и не получить сменой типа:
AddStorageFieldCommandHandlerбросаетCreateStorageFieldException,UpdateStorageFieldCommandHandlerбросаетUpdateStorageFieldException, AJAXaddиupdateпринимают толькоFieldService::EDITABLE_TYPES. Команда добавления сбрасывает пришедший id и всегда создаёт новое поле. - Чужой файл в поле не положить. Валидатор репозиториев отклоняет id файла другого модуля, если его нет в сохранённом значении, а контроллер
Controller\Storageпринимает в файловом поле только уже сохранённые id:addItemActionс непустым файловым полем отвечает ошибкойINVALID_PARAM_ARGи элемент не создаёт. - «Запись данных» молча пропускает файловые поля, так что шаблон, писавший туда файл, его больше не запишет.
Так закрыта выдача чужих файлов через грид элементов, который отдаёт файл по id без проверки прав смотрящего.
Проверьте фильтры «Удаления данных»
Если в фильтре «Удаления данных» есть условие, которое движок не может прочитать или перевести в ORM, блок ничего не удаляет. Раньше он удалял по остальным условиям. «Чтение данных» нечитаемые условия отбрасывает и читает по остальным: прочитанное можно проверить потом, удалённое уже нет.
Обновите наследников Storage и SystemProvider
Protected-метод Controller\Storage::checkAdminAccess() удалён, наследник с его вызовом упадёт. Вместо него checkStorageAccess(), checkStorageTypeAccess(int $storageTypeId) и checkStorageTypesAccess(array $storageTypeIds). Из Integration\UI\EntitySelector\SystemProvider убраны protected-константы ENTITY_TYPE_WORKFLOW, ENTITY_TYPE_USER и ENTITY_TYPE_TEMPLATE, список системных значений переехал в Workflow\Template\SystemValueCatalog.
БД
b_bp_workflow_template.FIRST_PUBLISHED_AT(nullable) пишет только bizproc при первой публикации общей версии, значение от вызывающего кода выбрасывается. У старых шаблонов поле пустое. Копия, конвертация, импорт и стандартные шаблоны вызываютCBPWorkflowTemplateLoader::add(..., markFirstPublication: false).b_bp_workflow_start_stat(Internal\Model\StartStat\WorkflowStartStatTable) считает успешные ручные запуски по шаблонам и дням, без тестовых, отладочных и брошенных. АгентStartStatCleanupAgentраз в сутки удаляет записи старшеstart_list_stat_retention_days(35 дней, но не меньше окна популярности), удаление шаблона чистит его статистику.b_bp_debug_session: новый индексIX_BP_DEBUG_SESSION_USER_TEMPLATE_END.
Мелочи и находки
- В годовой итог intranet добавлена метрика
bizproc.started_workflows, число процессов, запущенных сотрудником. Считается при опцииannual_summary_enabled = Y. BaseComplexActivityсчитает отметкой «не заполнено» любое непустое значение, кромеN, а не толькоY.
Устаревшие и удалённые API в этой версии
| Символ | Статус | Чем заменять |
|---|---|---|
Bitrix\Bizproc\Controller\Storage::checkAdminAccess()
|
Удалено |
Bitrix\Bizproc\Controller\Storage::checkStorageAccess()
|