Здоровье дежурств#
Здоровье дежурств (On-call Health) помогает операторам убедиться, что ротации и команды готовы принимать и обрабатывать алерты до возникновения инцидента.
Индикатор здоровья показывается прямо в таблицах Rotations и Teams. Он даёт быструю сводку в строке таблицы и открывает подробное диагностическое модальное окно при выборе.
Индикаторы здоровья#
Каждая строка отображает один из следующих индикаторов:
- Зелёная галочка — критических или предупреждающих проблем не найдено.
- Жёлтый восклицательный знак — найдено одно или несколько предупреждений, критических проблем нет.
- Красный крест — найдена одна или несколько критических проблем.
- Знак вопроса — сводка здоровья ещё загружается, не удалось её рассчитать или она не была возвращена.
Наведите курсор на индикатор, чтобы увидеть краткую сводку. Выберите индикатор, чтобы открыть полное диагностическое модальное окно.
Информационные заметки не переводят строку из зелёного состояния в жёлтое или красное.
Здоровье ротации#
Здоровье ротации проверяет, может ли ротация выдать пригодное назначение дежурства.
Облегчённая табличная сводка проверяет структурные проблемы, такие как:
- ротация отключена;
- у ротации нет слоёв;
- у ротации нет включённых слоёв;
- у включённого слоя нет участников;
- у ротации нет активных участников;
- доступен только один активный участник;
- неактивные пользователи всё ещё назначены на включённые слои.
Полное диагностическое модальное окно может дополнительно проверять:
- текущее назначение дежурства;
- будущие пробелы в расписании в проверяемом окне;
- неактивных или удалённых ответственных;
- готовность к доставке уведомлений;
- связанные проблемы маршрутизации и назначения.
Табличная сводка намеренно облегчённая. Полные проверки расписания и доставки рассчитываются только при открытии диагностического модального окна.
Здоровье команды#
Здоровье команды проверяет, могут ли алерты, направленные в команду, разрешиться в допустимое назначение и путь доставки.
Проверки могут включать:
- у команды нет включённой ротации;
- у включённого маршрута нет ни ротации, ни политики эскалации;
- у связанной ротации есть критические проблемы или предупреждения;
- у включённых маршрутов нет пригодных каналов уведомлений;
- конфигурация маршрута или эскалации не может разрешить цель назначения.
Маршруту не нужна прямая ротация, если у него есть политика эскалации. Политика может разрешить цель через ротацию или правило пользователя.
Диагностическое модальное окно#
Диагностическое модальное окно показывает:
- фактический статус здоровья;
- количество критических проблем;
- количество предупреждений;
- количество информационных заметок;
- проверяемое временное окно;
- подробные карточки проблем, сгруппированные по серьёзности;
- предлагаемые действия, когда доступна подсказка.
Каждая проблема имеет стабильный машиночитаемый code. Это позволяет API-клиентам и тестам идентифицировать состояние, не завися от отображаемого текста.
Примеры кодов проблем:
rotation_has_no_layers
rotation_has_no_enabled_layers
enabled_layer_has_no_members
rotation_has_no_active_members
rotation_has_single_active_member
layer_has_inactive_members
schedule_gap
route_has_no_assignment_target
Точный набор кодов проблем может расширяться по мере добавления дополнительной диагностики.
Фильтрация и обновление таблиц#
Индикаторы здоровья обновляются после повторной отрисовки таблицы Rotations или Teams.
Это включает:
- фильтрацию ротаций по команде;
- изменение фильтров поиска или статуса;
- перезагрузку таблицы после редактирования;
- переключение между видимыми группами, где это поддерживается.
Ранее загруженные сводки могут повторно использоваться из кэша на стороне браузера. Вновь появившиеся строки запрашиваются из API сводок.
Модель производительности#
Здоровье дежурств использует два уровня диагностики.
Облегчённые сводки#
Эндпоинты сводок используются для табличных индикаторов. Они выполняют структурные проверки и избегают полного сканирования расписания.
GET /api/oncall-health/rotations/summaries
GET /api/oncall-health/teams/summaries
Идентификаторы передаются как повторяющиеся параметры запроса:
/api/oncall-health/rotations/summaries?rotation_id=3&rotation_id=4
/api/oncall-health/teams/summaries?team_id=1&team_id=2
Ответ содержит как упорядоченный список items, так и объект by_id для быстрого поиска:
{
"items": [
{
"rotation_id": 3,
"summary": {
"status": "warning",
"critical": 0,
"warning": 1,
"info": 0,
"total": 1,
"partial": true
}
}
],
"by_id": {
"3": {
"status": "warning",
"critical": 0,
"warning": 1,
"info": 0,
"total": 1,
"partial": true
}
}
}
Отсутствующие или недоступные объекты исключаются из ответа.
Полная диагностика#
Эндпоинты деталей вызываются только когда пользователь открывает модальное окно здоровья:
GET /api/oncall-health/rotations/{rotation_id}
GET /api/oncall-health/teams/{team_id}
Полный ответ включает сводку, проверяемое окно и подробные проблемы:
{
"scope": "rotation",
"rotation_id": 3,
"rotation_name": "Primary on-call",
"team_id": 1,
"window": {
"starts_at": "2026-06-20T00:00:00Z",
"ends_at": "2026-06-27T00:00:00Z"
},
"summary": {
"status": "critical",
"critical": 1,
"warning": 0,
"info": 0,
"total": 1
},
"issues": [
{
"severity": "critical",
"code": "schedule_gap",
"title": "Schedule gap detected",
"message": "No active on-call user can be resolved for part of the checked window.",
"target_type": "rotation",
"target_id": 3,
"starts_at": "2026-06-21T02:00:00Z",
"ends_at": "2026-06-21T08:00:00Z"
}
]
}
Права доступа#
Здоровье дежурств следует тем же правам на чтение, что и связанная ротация или команда.
- Пользователи, которые могут читать ротацию, могут запросить её сводку здоровья и детали.
- Пользователи, которые могут читать команду, могут запросить её сводку здоровья и детали.
- Недоступные объекты исключаются из пакетных ответов со сводками.
- Эндпоинты деталей возвращают ошибку доступа, когда объект существует, но текущий пользователь не может его читать.
Доступ к здоровью не даёт прав на редактирование команд, ротаций, слоёв, маршрутов или политик эскалации.
Устранение неполадок#
Индикатор остаётся знаком вопроса#
Проверьте панель сети браузера на наличие запроса к одному из эндпоинтов сводок.
Если запрос не отправляется:
- Убедитесь, что
oncall_health.jsподключён на странице. - Убедитесь, что функция отрисовки таблицы вызывает загрузчик сводок здоровья после перестроения строк.
- Проверьте консоль браузера на наличие ошибок JavaScript.
Если запрос возвращает 404:
- Убедитесь, что
oncall_health_bpзарегистрирован с префиксом/api/oncall-health. - Убедитесь, что точный маршрут сводок существует в
oncall_health_view.py. - Перезапустите приложение после изменения регистрации blueprint.
Если запрос выполняется успешно, но индикатор остаётся неизменным, убедитесь, что у строки есть ожидаемый атрибут data-rotation-health-id или data-team-health-id.
Здоровье перестаёт обновляться после фильтрации#
Таблица перестраивается при изменении фильтра. Функция отрисовки должна вызывать соответствующий загрузчик после вставки новых строк:
window.loadRotationHealthSummariesForVisibleRows();
или:
window.loadTeamHealthSummariesForVisibleRows();
Кэш сводок на стороне клиента должен хранить полную сводку по ID объекта, а не только набор ранее загруженных ID.
Модальное окно открывается пустым при загрузке страницы#
Общее модальное окно здоровья должно быть изначально скрыто:
<div class="app-modal" id="rotation-health-modal" style="display: none;" aria-hidden="true">
Не вызывайте функцию открытия модального окна во время инициализации страницы. Открывайте его только после того, как пользователь выберет индикатор здоровья.
Запросы сводок работают медленно#
Убедитесь, что сводки строк не вызывают полную диагностику.
Код сводки не должен выполнять:
- сканирование будущего расписания;
- повторные вызовы
get_current_oncall_user(); - проверки доставки уведомлений;
- полное разрешение маршрута или эскалации;
- ленивые запросы к базе данных для каждой строки.
Сводки ротаций должны предварительно загружать слои, участников и пользователей пакетами, где это возможно. Полные проверки относятся только к эндпоинту деталей.
Документация API#
Эндпоинты здоровья дежурств также включены в сгенерированную спецификацию OpenAPI.
Swagger UI:
/docs
OpenAPI JSON:
/api/openapi.json