КарьераКарьера
КонтактыКонтакты

Все

23 июля 2026

4 продукта на NestJS: где стек сработал, а где мы ушли на Go

18 ролей, около 460 кандидатов, фоновые очереди и видеосвязь до 100 человек - на примерах из портфолио Qtim.

В портфолио Qtim есть онлайн-школа с 18 ролями, платформа аттестации с видеофиксацией экзамена, Стадикэтс с домашними заданиями и пробниками и ВКС для уроков до 100 участников. В каждом проекте стек упирался в конкретные вещи: права доступа, статусы, очереди задач, файлы, отчеты и поведение системы в пик.

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

NestJS чаще подходит для бизнес-логики с кабинетами, админками, ролями, документами и интеграциями. Go взяли точечно в ВКС: там нагрузка уходит в медиаконтур WebRTC и SFU, где важны обработка потоков, стабильная задержка и контроль соединений.

18 ролей, которые нельзя свести к одному "администратору"

01-3.jpg


В Онлайн-школе №1 команда Qtim подключилась после неудачного опыта клиента с предыдущими подрядчиками. Нужно было привести проект в рабочее состояние, запустить первый релиз за 3 месяца и сохранить пространство для дальнейших изменений.

Для ученика это уроки, домашние задания, материалы, чат с дежурными учителями, календарь и успеваемость. Для команды проекта - больше 10 подпроектов и доступы, которые нельзя собрать в одну роль администратора.

Права держатся на guards и policy-модуле: guard проверяет доступ на входе в сценарий, policy описывает действие над конкретным объектом. Для сложных правил такую схему удобно расширять через CASL - например, когда куратор видит одну группу учеников, координатор управляет расписанием, а администратор меняет настройки проекта.

Модульная структура NestJS помогла развивать обучение, проверки, календарь и права отдельно. Новый блок не приходилось протаскивать через все ядро: у него появлялись свой модуль, сервисы и правила доступа.

В системе 18 типов пользователей: учителя, кураторы, координаторы, администраторы и другие специалисты. Новый доступ настраивается за 15-20 минут, поэтому команда может добавлять роли по мере роста продукта.

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

460 экзаменов под видеозапись: одна ошибка в статусе рушит всю цепочку

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

Регламент разложили на NestJS-модули и сервисы: заявка проходит запись, проверку документов, сдачу, оценку, протоколы, ведомости, PDF-ответы и выгрузки для федерального реестра. Ошибка в переходе статуса здесь сразу ломает цепочку.

Сотрудники в админке создают сессии, назначают специалистов, сверяют документы и результаты. Кандидат в отдельном приложении тестирует камеру и микрофон, включает запись видео, звука и экрана, сдает письменную или устную часть.

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

Доступ к медиафайлам ограничили по ролям. Супер-администратор может открыть видео, администратор работает с документами и результатами, медиа ему недоступны. Через платформу прошли около 460 кандидатов; главная ценность здесь в том, что статус, документ, запись экзамена и право доступа живут в одном проверяемом процессе.

Все сдают ДЗ в ночь перед дедлайном - почему кабинет не ложится

02-4.jpg

Стадикэтс нужен был полноценный контур подготовки к ЕГЭ и ОГЭ: витрина курсов, расписание, домашние задания, пробники, карточки для повторения, статистика и геймификация. Проект сделали на NestJS и Nuxt.js за 5 месяцев.

В EdTech пики часто приходят перед дедлайном. Ученики массово загружают решения, и проверка файлов может занять ресурсы именно тогда, когда кабинет нужен активнее всего.
Тяжелые действия вынесли в фон через BullMQ и очереди на Redis. Ученик сдает задание и возвращается к урокам; отдельный воркер разбирает файлы, запускает проверку и обновляет статус результата.

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

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

Видеосвязь на 100 человек: где NestJS перестал тянуть и мы взяли Go

С ВКС Онлайн-школы №1 задача была другой: собственная видеосвязь внутри образовательной платформы, где расписание, роли, авторизация, записи занятий, массовые уроки и инструменты учителей работают без внешней ссылки.

Здесь стек смешанный: видеоконтур собрали на WebRTC и Go, а API и админку оставили на NestJS. Кабинет ученика и управление уроком живут по одним правилам, ВКС-сессия - по другим.

Node отлично держит тысячи одновременных I/O-операций, но у видеосвязи другой профиль нагрузки. Это CPU-bound участок: WebRTC, SFU, маршрутизация медиапотоков, обработка пакетов, fan-out на десятки участников и контроль задержки. В такой зоне event loop Node может стать горлышком, поэтому медиаконтур вынесли на Go.

NestJS остался там, где он сильнее: роли, авторизация, расписание, записи занятий, админка и связи с основным продуктом. Для пользователя это один интерфейс, а внутри - два разных профиля нагрузки.

Обратная сторона: где стек стоил дороже, чем казалось

Если статья про уроки, честно назвать и те, что дались через боль. Модульность NestJS окупается на больших продуктах, но на маленьком сервисе тот же каркас - лишняя церемония: иногда одного хендлера хватило бы, а мы заводили модуль, провайдер и правила доступа.

Вынос логики в микросервисы, как в Онлайн-школе, дает независимость, но добавляет распределенную отладку и согласованность, которую держишь руками. Это решение под нагрузку, а не по умолчанию.

Go в ВКС тоже не бесплатная кнопка ускорения: появляется отдельный рантайм, сборка, деплой, мониторинг и граница ответственности между продуктовой логикой и медиаконтуром. Все три - осознанные размены, и мы идем на них, когда выгода понятна заранее.

Когда берём NestJS, а когда нет

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

NestJS берем для сервисов, где много бизнес-правил: кабинеты, админки, документы, платежи, отчеты, клиентские приложения. Его удобно использовать там, где важны модули, guards, providers, очереди и понятные границы сценариев.

Go, WebRTC или другой отдельный инструмент используем там, где профиль нагрузки отличается от основной логики: медиапотоки, CPU-bound обработка, отдельный рантайм или жесткие требования к задержке. Для каждого такого решения заранее определяем участок работы.

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

Проект с личными кабинетами, ролями, документами, мобильным контуром или нагрузочными участками можно обсудить с нашей командой в направлении разработки SaaS-сервисов и PaaS-платформ. Больше кейсов с похожими архитектурными задачами смотрите в портфолио: EdTech, ВКС и внутренние продукты.

Подпишись — самые свежие новости сначала в соцсетях