Маршрутизация — диагностический чеклист¶
Чеклист для диагностики проблем с переходами по маршруту. Каждый пункт: симптом, проверка, решение.
Чеклист «Почему переход не сработал»¶
1. Обязательные ДП на переходе не заполнены¶
Симптом. Пользователь нажимает кнопку перехода, ДП подсвечиваются красным, переход не выполняется. Либо автопереход (при завершении подзадач, по смарту) молча не срабатывает.
Проверка.
Администратор: открыть настройки перехода, вкладка «Доп. параметры» --- там список ДП, обязательных для данного перехода.
SQL --- найти обязательные ДП на переходе:
SELECT
sepr.StepID,
sris.StepDescr AS TransitionName,
sepr.ExtParamID,
ep.ExtParamName
FROM StepExtParamRestrictions sepr
JOIN StatesRoutesInSubcat sris ON sris.StepID = sepr.StepID
JOIN ExtParams ep ON ep.ExtParamID = sepr.ExtParamID
WHERE sris.SubcatID = @SubcatID
ORDER BY sris.StepID;
SQL --- проверить, заполнены ли обязательные ДП у конкретной задачи:
SELECT
sepr.ExtParamID,
ep.ExtParamName,
epv.ExtParamValue
FROM StepExtParamRestrictions sepr
JOIN ExtParams ep ON ep.ExtParamID = sepr.ExtParamID
LEFT JOIN ExtParamValues epv ON epv.ExtParamID = sepr.ExtParamID AND epv.TaskID = @TaskID
WHERE sepr.StepID = @StepID;
API --- при попытке перехода API возвращает data.ok = false и массив requiredExtParams с ID незаполненных ДП:
{
"data": {
"ok": false,
"requiredExtParams": [1234, 5678]
}
}
Решение.
- Заполнить обязательные ДП до перехода.
- Если переход автоматический (смарт, автопереход при завершении подзадач) --- убедиться, что смарт-действие «Перед переходом» заполняет эти ДП, либо убрать обязательность с перехода.
- Частая ошибка: включили
AutoPerformStepOnSubtasksClose, но на целевом переходе есть обязательные ДП --- автопереход не сработает, потому что некому их заполнить.
2. Нет прав на переход¶
Симптом. Кнопка перехода не отображается вообще, или пользователь видит кнопку, но при нажатии получает ошибку.
Проверка.
Три уровня ограничения доступа к переходу (все в настройках перехода):
| Настройка | Поле БД | Поведение |
|---|---|---|
| Ограничить доступ (по умолчанию) | --- | Кнопка только для пользователей с правом «Исполнять» |
| Ограничить доступ (выбрана настройка) | --- | Кнопка скрыта согласно выбранному ограничению |
| Смарт-фильтр видимости | VisibilitySmartFilterID |
Кнопка видна/скрыта по результату смарт-выражения |
| Для заказчика | OwnerOnly |
Переход только для заказчика |
| Для пользователя (исполнителя) | UserOnly |
Переход только для исполнителя |
| Для администратора | ForAdmin |
Переход только для администратора категории |
| Для права исполнять | ForPerfRight |
Переход только для имеющих право «Исполнять» |
| Для права создавать | ForAddRight |
Переход только для имеющих право «Создавать» |
| Для ответственного исполнителя | ForResponsiblePerformer |
Переход только для ответственного |
SQL --- проверить ограничения конкретного перехода:
SELECT
StepID, StepDescr, OwnerOnly, UserOnly,
ForAdmin, ForPerfRight, ForAddRight,
ForResponsiblePerformer, ForViewver,
HiddenStep, VisibilitySmartFilterID
FROM StatesRoutesInSubcat
WHERE SubcatID = @SubcatID AND StepID = @StepID;
Решение.
- Убедиться, что у пользователя есть право «Исполнять» в категории (или соответствующее другое право).
- Проверить смарт-фильтр видимости --- может скрывать кнопку по условию.
- Исключение: Робот1Ф (системный пользователь) может выполнять любые переходы, независимо от настроек видимости.
3. Подписи не завершены¶
Симптом. Задача «зависла» в статусе «На подписи --- {Статус}». Переход не происходит, хотя пользователь нажал кнопку.
Проверка.
Нажатие кнопки перехода не переводит задачу сразу --- сначала запрашиваются подписи. Задача переходит в промежуточный статус «На подписи». Переход завершится только после обработки всех обязательных подписей на всех этапах маршрута согласования.
Что проверять:
- Открыть карточку задачи --- блок подписей. Есть ли необработанные подписи?
- Акцептант не видит подпись? Проверить --- он может быть определён через роль, смарт-выражение или ДП. Если список пуст, подпись не запросится.
- Подпись отклонена? При отклонении задача возвращается в статус, указанный в настройках подписи. Если статус не указан --- остаётся в исходном.
Ловушка: если используется отдельный статус «Согласование» (рекомендуемый паттерн), а при отклонении подписи задача остаётся в нём (настройка по умолчанию) --- задача «застрянет». Нужно указать статус возврата при отклонении (например, «Подготовка»).
Решение.
- Подпись «висит» --- акцептант должен обработать (акцептовать/отклонить/удалить).
- Настроить сроки обработки подписей --- при просрочке возможна эскалация.
- При настройке перехода с подписями --- обязательно указать статус при отклонении, чтобы задача не застревала.
4. Автопереход при завершении подзадач --- нюансы¶
Симптом. Галочка AutoPerformStepOnSubtasksClose включена на переходе, все подзадачи завершены, но переход не произошёл.
Проверка.
SQL --- проверить, что галочка включена:
SELECT StepID, StepDescr, AutoPerformStepOnSubtasksClose,
StateID AS FromStateID, StateNextID AS ToStateID
FROM StatesRoutesInSubcat
WHERE SubcatID = @SubcatID AND AutoPerformStepOnSubtasksClose = 1;
Условия срабатывания автоперехода:
| Условие | Комментарий |
|---|---|
| Все подзадачи (дочерние) в завершающем статусе | Проверяются только прямые дочерние задачи |
| Задача находится в статусе «Из статуса» перехода | Если задача уже не в этом статусе --- переход не сработает |
| Нет обязательных ДП на переходе (или они заполнены) | Главная причина несрабатывания. Автопереход выполняется системой, заполнить ДП некому |
| Нет обязательных подписей на переходе (или они настроены на автоакцепт) | Подписи блокируют автопереход |
Нет SmartFilter BeforeTaskStep, отменяющего переход |
Смарт «Перед переходом» может вернуть отмену |
Частые причины несрабатывания:
- Обязательные ДП на переходе --- самый частый случай. Снять обязательность или заполнить ДП до закрытия последней подзадачи.
- Связанные задачи, а не подзадачи. В настройках «Подзадачи на переходе» если у задачи стоит галочка «Связанная задача», она не считается дочерней. Автопереход
AutoPerformStepOnSubtasksCloseигнорирует связанные задачи --- реагирует только на дочерние. - Есть незакрытая подзадача из другой категории --- проверить все дочерние, не только из текущей.
- Несколько переходов с
AutoPerformStepOnSubtasksCloseиз одного статуса --- неопределённое поведение. Должен быть ровно один такой переход из данного статуса.
SQL --- проверить, все ли подзадачи закрыты:
SELECT TaskID, Description, IsClosed, StateID
FROM Tasks
WHERE ParentTaskID = @ParentTaskID AND IsClosed = 0;
Решение.
- Убрать обязательные ДП с перехода, на котором стоит автопереход при завершении подзадач.
- Либо заполнять ДП заранее (смарт-действие при создании задачи, значение по умолчанию).
- Убедиться, что дочерние задачи --- именно подзадачи, а не связанные задачи.
5. Смарт-действие в пакете конфликтует с переходом¶
Симптом. Смарт-действия выполняются (видно в логе автоматизации), но переход не происходит. Или происходит переход, но данные не те, что ожидались.
Проверка.
Последовательность выполнения при переходе:
- Смарт-пакеты «Перед переходом» (
BeforeTaskStep) - Проверка обязательных ДП, подписей, прав
- Выполнение перехода (смена статуса)
- Процедура при переходе (SQL)
- Постановка подзадач на переходе
- Смарт-пакеты «После перехода» (
AfterTaskStep,AfterTaskStateChange)
Если смарт «Перед переходом» бросает исключение или явно отменяет переход --- переход не произойдёт.
Если на переходе есть подписи, порядок другой:
- Запрос подписей
- Смарт-действия «После подписания статической подписи»
- Переход по маршруту
- Смарт-действия «После перехода»
Журнал автоматизации:
SELECT TOP 20
Id, Type, ObjectName, TaskId, Duration, Date,
CAST(AdditionalInfo AS NVARCHAR(500)) AS Info
FROM AutomationScriptsLog
WHERE TaskId = @TaskID
ORDER BY Id DESC;
Где Type = 2 --- смарт-действие, Type = 4 --- смарт-пакет.
Решение.
- Проверить в журнале автоматизации, выполнился ли пакет и с каким результатом.
- Если смарт «Перед переходом» меняет ДП, от которых зависит условие этого же перехода --- может возникнуть конфликт.
- Смарт-действие
SetState(смена статуса) в пакете «Перед переходом» --- опасная конструкция: задача может перейти в другой статус до основного перехода.
6. Связанные задачи (не подзадачи) --- автопереход не работает¶
Симптом. Настроены «Подзадачи на переходе» с галочкой «Связанная задача». Ожидается, что автопереход AutoPerformStepOnSubtasksClose сработает при их завершении --- но он не срабатывает.
Проверка.
В настройках подзадач на переходе есть поле «Связанная задача»:
«Задача будет создана не как дочерняя, а как связанная. При включении в родительской задаче не работает опция "Автоматически делать переход при завершении всех подзадач" на соответствующих переходах.»
Это by design. Автопереход при завершении подзадач отслеживает только дочерние задачи (Tasks.ParentTaskID = @TaskID), а не связанные (TaskLinks).
Решение.
- Если нужен автопереход --- создавать именно подзадачи, а не связанные задачи.
- Для связанных задач использовать смарт-автоматизацию на событии «После изменения статуса» в категории связанной задачи, которая проверяет статус родительской и выполняет переход.
7. Переход скрыт (кнопка скрыта)¶
Симптом. Переход существует в маршруте, но пользователь не видит кнопку. При этом в ленте основного маршрута кнопка может быть доступна.
Проверка.
SQL --- проверить флаг скрытости:
SELECT StepID, StepDescr, HiddenStep, VisibilitySmartFilterID
FROM StatesRoutesInSubcat
WHERE SubcatID = @SubcatID;
Два механизма скрытия:
| Механизм | Поле | Поведение |
|---|---|---|
HiddenStep = 1 |
Кнопка скрыта | Кнопка отсутствует на карточке. Переход доступен только программно (смарт, API) или через ленту основного маршрута |
| Смарт-фильтр видимости | VisibilitySmartFilterID |
Кнопка показывается/скрывается по условию. Сам переход доступен через API |
Скрытый переход (HiddenStep = 1) остаётся доступен:
- Через ленту основного маршрута (если переход помечен как IsMainRouteStep = 1)
- Через API (POST /api/tasks/{taskId}/change-step с указанием StepId)
- Через смарт-действие SetState
Решение.
- Если кнопка должна быть видна --- снять
HiddenStep. - Если кнопка скрыта смарт-фильтром --- проверить условие выражения в администрировании.
8. Параллельные ветки маршрута¶
Симптом. Из одного статуса есть несколько переходов. Пользователь нажал «не ту» кнопку. Или система выполнила не тот автопереход.
Проверка.
SQL --- все переходы из данного статуса:
SELECT
StepID, StepDescr, StateID, StateNextID,
AutoPerformStepOnSubtasksClose,
OnOverduePerformStepID,
HiddenStep, OwnerOnly, UserOnly, OrderId
FROM StatesRoutesInSubcat
WHERE SubcatID = @SubcatID AND StateID = @CurrentStateID
ORDER BY OrderId;
Проблемные ситуации:
- Несколько
AutoPerformStepOnSubtasksClose = 1из одного статуса --- неопределённый результат. Нужен ровно один. - Альтернативный переход при просрочке (
OnOverduePerformStepID) --- jobOverdueStepActionJob(каждые 4 мин) проверяет просроченные шаги и выполняет альтернативный переход. Может конкурировать с ручным переходом. - Шаг при постановке --- автопереход сразу после создания задачи. Если у пользователя нет прав на этот переход, задача останется в начальном статусе без уведомления.
Решение.
- Для автоматических переходов --- использовать скрытые кнопки (
HiddenStep = 1), чтобы пользователь не нажал вручную. AutoPerformStepOnSubtasksClose--- максимум один переход из каждого статуса.- Для альтернативного перехода при просрочке --- проверить значение
TermMinutesиOnOverduePerformStepID.
Диагностика¶
Где смотреть¶
| Журнал | Таблица | Что покажет |
|---|---|---|
| Ошибки | ExceptionsLog |
Технические ошибки при переходе (SourceID = 5 --- бизнес-логика, 12 --- API) |
| Ошибки бизнес-логики | ExceptionsLog (SourceID = 5) |
Ошибки смартов, валидации, бизнес-правил при переходе |
| Выполнения автоматизации | AutomationScriptsLog |
Выполнение смарт-пакетов на переходе (Type = 2 действие, 4 пакет) |
| Общий (Системный) | ActionLog |
Изменения настроек категории, статусов, переходов (административные действия) |
| История переходов (API) | POST /api/tasks/{taskId}/stephistory |
Последовательность переходов задачи, кто и когда |
SQL-запросы для диагностики¶
Ошибки при переходе конкретной задачи (за последние 7 дней):
SELECT TOP 20 ID, Date, SourceID,
CAST(Exception AS NVARCHAR(500)) AS ExceptionShort
FROM ExceptionsLog
WHERE Exception LIKE '%TaskID=' + CAST(@TaskID AS VARCHAR) + '%'
AND Date > DATEADD(DAY, -7, GETDATE())
ORDER BY ID DESC;
Смарт-автоматизации по задаче:
SELECT TOP 20
Id, Type, ObjectName, TaskId, UserID,
Duration, Date,
CAST(AdditionalInfo AS NVARCHAR(500)) AS Info
FROM AutomationScriptsLog
WHERE TaskId = @TaskID
ORDER BY Id DESC;
Полная конфигурация переходов категории:
SELECT
sris.StepID,
sris.StepDescr AS ButtonName,
s1.Description AS FromState,
s2.Description AS ToState,
sris.HiddenStep,
sris.AutoPerformStepOnSubtasksClose,
sris.OnOverduePerformStepID,
sris.TermMinutes,
sris.OwnerOnly,
sris.UserOnly,
sris.ForAdmin,
sris.ForPerfRight,
sris.VisibilitySmartFilterID,
sris.ForceComment,
sris.OrderId
FROM StatesRoutesInSubcat sris
JOIN States s1 ON s1.StateID = sris.StateID
JOIN States s2 ON s2.StateID = sris.StateNextID
WHERE sris.SubcatID = @SubcatID
ORDER BY sris.StateID, sris.OrderId;
Обязательные ДП по всем переходам категории:
SELECT
sris.StepID,
sris.StepDescr AS ButtonName,
ep.ExtParamID,
ep.ExtParamName,
epv.ExtParamValue AS CurrentValue
FROM StepExtParamRestrictions sepr
JOIN StatesRoutesInSubcat sris ON sris.StepID = sepr.StepID
JOIN ExtParams ep ON ep.ExtParamID = sepr.ExtParamID
LEFT JOIN ExtParamValues epv ON epv.ExtParamID = sepr.ExtParamID AND epv.TaskID = @TaskID
WHERE sris.SubcatID = @SubcatID
ORDER BY sris.StepID, ep.ExtParamName;
Типичные сценарии из практики¶
Сценарий 1: «Автопереход при завершении подзадач не работает»¶
Запрос. Включена галочка «Автоматически делать переход при завершении всех подзадач». Все подзадачи закрыты, но родительская задача не двигается.
Диагностика.
- Проверить обязательные ДП на переходе (пункт 1).
- Проверить, что дочерние --- именно подзадачи, а не связанные (пункт 6).
- Проверить, что нет незакрытых подзадач из других категорий.
- Проверить, нет ли подписей на переходе (пункт 3).
- Посмотреть
ExceptionsLog--- возможна ошибка при попытке автоперехода.
Типичное решение. Убрать обязательные ДП с перехода. Если ДП нужны --- заполнить их до закрытия последней подзадачи (смарт-действие на родительской задаче или ручное заполнение).
Сценарий 2: «Смарт-действия выполняются, но переход нет»¶
Запрос. На переходе настроен смарт-пакет. Пакет отработал (видно в логе), но задача осталась в прежнем статусе.
Диагностика.
- Посмотреть
AutomationScriptsLog--- завершился ли пакет без ошибок. - Проверить, не отменил ли смарт «Перед переходом» сам переход (Action = Cancel).
- Проверить порядок: смарт «Перед переходом» выполняется до проверки обязательных ДП. Если смарт заполняет ДП, а ДП обязательны --- проверить, успевает ли значение записаться.
- Посмотреть
ExceptionsLog--- исключение в смарте блокирует переход.
Сценарий 3: «Даты вехи самопроизвольно смещаются»¶
Запрос. В проектной задаче даты вех меняются без видимых действий пользователя.
Диагностика.
Побочный эффект автоматических переходов:
- Настройка перехода «Действие с датой начала работы» (
TaskStartTimeAction) --- может очищать или заполнять текущим временем. - Настройка «Сбросить срок» (
ResetDueTime) --- очищает поле «Срок» при переходе. - Смарт-действия «После перехода» --- могут менять даты через
ChangeExtParamValue. - Job
OverdueStepActionJob--- при просрочке шага может выполнить альтернативный переход с побочными эффектами.
SQL --- проверить настройки действий с датами на переходах:
SELECT StepID, StepDescr, ResetDueTime, TaskStartTimeAction,
AskPermissionToPerformTSTAction
FROM StatesRoutesInSubcat
WHERE SubcatID = @SubcatID
AND (ResetDueTime = 1 OR TaskStartTimeAction > 0);
Связанные документы¶
| Документ | Путь |
|---|---|
| Бизнес-логика категорий (маршруты, статусы) | docs/domains/categories/business.md |
| Настройки перехода | ../tasks/admin.md |
| Обязательные ДП на переходе | ../tasks/admin.md |
| Подзадачи на переходе | ../tasks/admin.md |
| Подписи на переходе | ../signatures/admin.md |
| Смарты на переходе | ../smart-actions/admin.md |
| API переходов (контракт) | BrunoCoverage/modules/route-transitions/README.md |
| Журналы системы | docs/platform/database/journals.md |
| Подписи: бизнес-логика | docs/domains/signatures/business.md |