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

Выберите одного ученика с пропуском и одного с успешным уведомлением того же урока. Сравните enrollment, группу, дату открытия, timezone, настройки уведомлений и журнал delivery. Не отправляйте массовое повторное письмо, пока не исключили дубли для уже получивших пользователей.

Что проверить в первую очередь

Начните с одного воспроизводимого сценария. Зафиксируйте точное время, идентификатор объекта, пользователя или операции, версию приложения и последнее известное рабочее состояние. Не меняйте несколько параметров одновременно: один контролируемый шаг должен подтверждать или исключать одну гипотезу. Перед работой с данными и конфигурацией подготовьте резервную копию и проверенный способ отката.

  • Проверьте статус урока, дату публикации и правила постепенного открытия.
  • Убедитесь, что ученик активен, зачислен в нужный поток и имеет доступ к уроку.
  • Найдите notification event, получателя и статус выбранного канала.
  • Проверьте подтверждение email, push token, отписку и quiet hours.

Почему возникает проблема

Внешний симптом часто появляется дальше по цепочке, чем первичная ошибка. Интерфейс может показывать неверное состояние из-за backend, очереди, кеша, прав доступа, фоновой задачи или внешнего API. Поэтому важно проследить данные от источника до результата и найти первую точку расхождения, а не исправлять только последнее сообщение об ошибке.

  • Урок сохранен как draft либо опубликован только для другой группы.
  • Планировщик рассчитывает дату в timezone сервера вместо ученика.
  • Событие создается до завершения транзакции и worker не видит новый урок.
  • Ученик исключен ошибочным фильтром сегмента или настройкой отписки.
  • Почтовый провайдер принял письмо, но домен, bounce или suppression блокирует доставку.

Пошаговая диагностика

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

  • Проследите lesson ID от публикации до строки notification и provider message ID.
  • Сравните выборку получателей с фактическими enrollment и правами доступа.
  • Проверьте очередь, retry, dead-letter и возраст необработанных заданий.
  • Воспроизведите публикацию тестового урока для разных timezone и каналов.
  • Проверьте ответ email or push provider и причины bounce, invalid token или suppression.

Как разделить событие, аудиторию и доставку

Публикация урока должна порождать устойчивое событие. Отдельный процесс рассчитывает аудиторию по версии правил, а канал доставки хранит собственный статус. Это позволяет повторить только пропущенные сообщения.

  • Событие lesson_published имеет event ID и фактическое время доступности.
  • Recipient snapshot фиксирует, почему ученик включен в аудиторию.
  • Каждая пара event plus user plus channel уникальна.
  • Provider response, retry и окончательная причина недоставки сохраняются отдельно.

Как исправить проблему

Исправление делите на небольшие обратимые изменения. Сначала устраните подтвержденную причину, затем повторите исходный сценарий и проверьте соседние функции. Массовое обновление данных запускайте на ограниченной выборке с отчетом и только после сверки расширяйте на весь объем. Не отключайте авторизацию, проверку сертификатов, валидацию или аудит ради быстрого исчезновения симптома.

  • Исправьте расчет аудитории и timezone на основе даты доступности ученику.
  • Создавайте событие после успешной фиксации урока через transactional outbox.
  • Добавьте уникальность уведомления и выборочный backfill для отсутствующих получателей.
  • Разделите временные ошибки провайдера и постоянные invalid address or token.
  • Показывайте ученику настройки каналов и историю важных уведомлений в кабинете.

Безопасный порядок внедрения

  • Сохраните затрагиваемые данные, конфигурацию и текущие журналы, затем проверьте возможность реального восстановления.
  • Повторите проблему на тестовом объекте без реальных списаний, рассылок и необратимых изменений клиентских данных.
  • Зафиксируйте изменение в системе контроля версий или журнале работ вместе с причиной, ожидаемым эффектом и планом отката.
  • Проведите тест на нормальном сценарии, ошибочном вводе, повторном запросе, параллельной операции и временной недоступности зависимости.
  • После выпуска наблюдайте полный пользовательский путь, логи и метрики, а не только один успешный запрос.

Как проверить результат

Разовый успешный тест недостаточен. Повторите операцию, проверьте крайние значения, одновременные действия и восстановление после перезапуска или временного сбоя. Для важного сценария сохраните автоматический тест либо короткий регрессионный чек-лист. Итог должен подтверждаться не только интерфейсом, но и состоянием базы, очереди, внешнего сервиса и журналом действий.

  • Ученики нужного потока получают одно уведомление в ожидаемое локальное время.
  • Не зачисленный пользователь не получает ссылку на закрытый урок.
  • Повтор worker не создает дубли, а пропущенный получатель догружается.
  • Ошибка email не мешает доступному альтернативному каналу, если он разрешен.

Типичные ошибки при исправлении

  • Рассылать всем пользователям курса без проверки потока и даты доступа.
  • Считать статус accepted у провайдера гарантией попадания письма во входящие.
  • Удалять invalid push token без сохранения причины и пользователя.
  • Повторно отправлять весь список после частичного сбоя.

Как предотвратить повторение

Профилактика строится вокруг явных контрактов, повторяемых релизов и наблюдаемости. Система должна не только работать сейчас, но и позволять быстро увидеть нарушение правила при следующем обновлении, росте нагрузки или сбое внешнего сервиса. Проверки особенно полезно автоматизировать там, где ошибка уже привела к потере времени, данных, денег или заявок.

  • Добавьте контроль опубликованных уроков без созданного события.
  • Сверяйте ожидаемое и фактическое число получателей по потокам.
  • Мониторьте возраст очереди, bounce rate, invalid tokens и suppression.
  • Тестируйте расписание на границе суток и переходах timezone.

Что контролировать после выпуска

  • Количество успешных и ошибочных операций в разрезе версии, канала и типа сценария.
  • Возраст необработанных записей, длину очередей, число повторных попыток и долю окончательных отказов.
  • Расхождение между пользовательским статусом и фактическим состоянием в базе или внешней системе.
  • Появление новых кодов ошибок после релиза и изменение времени выполнения ключевой операции.
  • Сигналы от поддержки и бизнес-метрики, которые могут показать скрытый частичный сбой.

Что подготовить для технического разбора

  • Описание ожидаемого и фактического поведения с точной последовательностью действий.
  • Время проблемы, идентификатор тестового объекта и версии затронутых компонентов.
  • Фрагменты журналов до и после ошибки без секретов и персональных данных.
  • Перечень последних изменений и уже выполненных проверок.
  • Безопасный доступ к тестовой среде либо способ воспроизвести сбой без влияния на клиентов.

Частые вопросы

Почему урок виден, а письмо не пришло?

Доступ к контенту и доставка уведомления — разные процессы. Нужно проверить recipient и provider status, а не только публикацию урока.

Можно ли безопасно повторить рассылку?

Да, если у каждого уведомления есть уникальный ключ event, user и channel. Тогда повтор выбирает только отсутствующие или временно ошибочные записи.

Когда нужна помощь специалиста

Если LMS открывает уроки без уведомлений, я могу проверить события, аудиторию, очередь и доставку, восстановить пропуски без дублей и настроить контроль каналов.