Привет, Хабр! В предыдущей статье мы рассказали об используемых подходах и технологиях в разработке внутри Учи.ру.  На основе этих проверенных решений за уходящий учебный год мы разработали новые вспомогательные инструменты, продукты и сервисы. Сегодня расскажем, как создавались некоторые из них.  Контент Учи.ру был завязан на продуктовых сценариях, что лишало нас гибкости в его повторном использовании. Так мы пришли к выводу, что нужно абстрагировать бизнес-логику от контента. Мы сделали систему единой точки выдачи контента (систему-шлюз) и разработали в дополнение к нему протокол подключения. Этот шлюз можно интегрировать с любой продуктовой системой, такими как МЭШ или личный кабинет. Так появился сервис «Гамбит», который позволяет абстрагировать бизнес-логику от продуктовой системы, куда встраивается контент. Единую систему для всего контента мы начали использовать в качестве вспомогательного сервиса для каталогов учебных материалов, предоставляемых нашим партнерам. Также мы сделали и задокументировали протокол подключения к шлюзу для вновь создаваемых курсов, игровых проектов и методических материалов. Мы попытались из гетерогенной системы контента прийти к гомогенной (прозрачной) по стандартному программному интерфейсу и подключению к продуктам Учи.ру, где требуется выдача конкретного задания в разных сценариях. Получили запрос от бизнеса на доработку карточных заданий, где надо было изменить структуру подачи контента. Мы приступили к разработке  универсального механизма — шлюза домашних (или заданных, как мы их называем) заданий. Что пришлось обдумать: Структура должна подходить всем текущим сервисам и потенциально закрыть будущие потребности. Для этого требуется введение абстрактных сущностей и отказ от понятия «задание», так как выдаваться могут и проверочная, и контрольная и многое другое. То есть в структуре должно учитываться только «кому» и «что» выдали. Остальное — необязательная метаинформация. На первом шаге необходимо реализовать двунаправленную синхронизацию, чтобы данные из нового сервиса-шлюза попадали в старые задания (и наоборот) для тех, кто туда еще заходит. Это было важно, так как первым мы переносили самый крупный сервис, выдающий карточные задания и связанный с другими частями системы. Отделение карточных заданий от монолита и разработка единого gateway помогли увеличить скорость будущих доработок за счет гибкой структуры и GraphQL — участие бэка теперь минимальное. Плюс у нас теперь реализовано понятное управление каналами выдачи: никаких прямых вызовов insert из кода, написанных без нашего участия. У нас есть отдельная структура контента, который можно менять, не затрагивая другие части системы. Для каждого сервиса выдачи заданий ученику больше не нужен отдельный бэк — хватит фронта и захода в единый gateway. Но над этим механизмом мы еще будем работать. Теперь важно перенести остальные сервисы выдачи заданий и те, которые как-то соприкасаются с ними, на gateway.  В этом году мы частично интегрировались с экосистемой mos.ru: теперь пользователям МЭШ в личном кабинете в разделе «Портфолио» стала доступна информация о результатах олимпиад на Учи.ру. На основе протокола OAuth2, OpenID Connect мы сперва получили идентификаторы пользователей в партнерских системах, а затем реализовали экспортер наград за олимпиадные активности в личные кабинеты пользователей МЭШ экосистемы mos.ru.  Сейчас в этой модели мы выступаем в роли клиента, но если внесем доработки и развернем в обратную сторону, сможем стать полноценным провайдером (или поставщиком), реализовав передачу ресурса как во внутренние, так и внешние системы. У системы есть потенциал для масштабирования, и его можно использовать в бесшовной авторизации в экосистеме Учи.ру на разных доменах: Учи.Дома, ЯКласс, Учи.Ответы и так далее. Когда мы увидели, что уведомления мобильного приложения хорошо влияют на удержание пользователей, решили с их помощью побороться за внимание аудитории в веб-версии. Но уже через полноценный Центр уведомлений (ЦУ) — Babbler. Это наше собственное решение, сделанное поверх Kafka. Такой инструмент давно напрашивался, потому что каждая команда для доставки определенных уведомлений городила свои грядки в личном кабинете пользователей. Мы решили вынести Babbler в отдельный инструмент, чтобы поддержать дальнейшее расширение и масштабирование на другие возможные продукты компании.  В Babbler внедрена валидация схем базовых типов уведомлений, на которых основана вся система. Условно в ЦУ есть свой тип сообщений notifications и при отправке от инициатора клиент пытается проверить сообщение по схеме данных, если она представлена для данного типа. Это все можно расширять под разные типы. Типы также помогают разграничивать потребление сообщений конечным клиентом. Например, ЦУ потребляет только сообщения с уже упомянутым типом notifications, а все другие в его выборку не попадают. Также API поддерживает множественную фильтрацию по типам, что можно будет обыграть на мобильных приложениях.  Кроме этого мы сделали гибкий бэк, поэтому ЦУ учителя — это лишь один из возможных вариантов использования протокола сохранения и передачи уведомления. Его можно использовать и в приложениях учителя, родителя. Можно провести интеграцию с другими сервисами — использовать Babbler как единый канал коммуникации с пользователями. Это дешевле, поскольку мы придумали алгоритм сжатия сообщений, который уменьшает объем требуемой памяти и увеличивает объем дискового пространства. Миграция в связи с переводом детей в другой класс — ежегодный процесс, который сопровождается большими издержками и повышенной ответственностью. Несколько человек запускают десятки окон, в которых для разных групп пользователей запускается один и тот же сценарий перевода пользователей. При этом Учи.ру постоянно развивается, поэтому каждый год мы вынуждены не только корректировать существующий код, отвечающий за перевод, но и дорабатывать смежные алгоритмы. Хотя процесс концептуально не меняется. В этом году мы решили основательно подойти к миграции и выделить действующие стороны процесса — инициатора изменений и системы. Они по команде инициатора должны адаптироваться к изменению номера класса и учебной программы ученика. Достаточно правильно выделить нужных акторов и оптимизировать их, после чего можно немного расширить поведение. А свободное время мы уделим мониторингу и контролю, что сделает миграцию более наглядной и управляемой. В результате это решение можно будет использовать в следующем году и дальше. Мы очень кратко прошлись по основным изменениям, которые произошли в разработке крупнейшей образовательной онлайн-платформе для школьников. Практически про каждое можно рассказать намного больше и мы готовы это сделать по вашим запросам. Напишите в комментариях, какой из этих блоков вы бы хотели увидеть с подробным разбором в нашем блоге. Хотите развивать EdTech вместе с нами? Присоединяйтесь к команде Учи.ру — переходите на сайт и выбирайте открытые вакансии!