Клиент обратился с задачей развития существующей образовательной платформы kuzovkin.info. Проект состоял из нескольких связанных сервисов: основного сайта и личного кабинета на Python/Flask, интерактивной онлайн-доски на Node.js и Fabric.js, сервиса видеоконференций на React/WebRTC, PostgreSQL, Redis, PeerJS, Socket.IO, Nginx и Docker Compose.
Работа не ограничивалась одним багом. Требовалось последовательно развивать и стабилизировать продукт без переписывания всей системы с нуля и без потери уже работающих функций.
Основные цели проекта:
объединить функциональную backend-ветку с новой версткой и актуальной веткой разработки;
связать доски с уроками, преподавателями и учениками;
реализовать гостевой демо-доступ с ограничением по времени;
встроить видеосвязь непосредственно в интерфейс онлайн-доски;
исправить ошибки групповых звонков, камеры, микрофона и входа по прямой ссылке;
оптимизировать работу доски с тысячами и десятками тысяч объектов;
уменьшить избыточную нагрузку на PostgreSQL;
исправить realtime-синхронизацию сложных объектов;
внедрить новый интерфейс и подготовить постепенный переход со старого монолитного frontend.js на React и TypeScript;
сохранить совместимость с существующим production-кодом и текущими пользовательскими сценариями.
Отдельной сложностью была архитектура проекта: canvas, интерфейс, Socket.IO-события, сохранение, уроки, задачи и meeting исторически были тесно связаны. Поэтому любые изменения требовали предварительного анализа и точечного внедрения с обязательной проверкой на нескольких пользователях.
Работу я разбил на отдельные этапы и сначала подробно изучил архитектуру всех сервисов, Docker-инфраструктуру, связи между backend, board, meeting и lesson, структуру базы данных и существующие сценарии пользователей.
В Python/Flask backend я работал с объединением нескольких веток, сохраняя функциональность личного кабинета, досок, уроков и авторизации. Исправлял интеграционные маршруты, передачу контекста пользователя и урока в board, JSON/CSRF-сценарии и проблемы, из-за которых отдельные авторизованные пользователи ошибочно попадали в гостевой режим.
Для онлайн-доски были реализованы и доработаны:
гостевой demo-режим с TTL 15 минут;
привязка доски к конкретному уроку;
выбор активного урока преподавателем;
автоматический переход ученика в комнату активного урока без перезагрузки;
переход камеры доски к курсору выбранного участника;
корректное перемещение canvas без случайного захвата объектов;
исправление подписей и имен возле пользовательских курсоров;
восстановление сериализации текста, стилей и сложных Fabric-групп;
синхронизация rich-task, изображений и групповых объектов между клиентами;
рабочий сценарий формирования и копирования ссылки на доску.
Отдельно был проведён аудит производительности тяжёлых досок. Были исследованы сцены с тысячами и десятками тысяч Fabric-объектов, hit-testing, render loop, batch loading, LOD, spatial index, линейные поиски и групповые операции. На основе анализа была начата поэтапная миграция к React/TypeScript-архитектуре с отдельными слоями ObjectStore, Canvas Adapter, Realtime Adapter, Persistence Queue, Render Scheduler, Meeting Bridge и UI shell. Старый интерфейс при этом оставался рабочим fallback-вариантом.
Для PostgreSQL была локализована избыточная write-нагрузка на таблицу boards_items. Анализировались повторные upsert/update, групповые сохранения, modify-события и image-сценарии. Оптимизация выполнялась от приложения к базе: сначала уменьшение лишних сохранений, затем повторные замеры и подготовка настроек PostgreSQL.
Видеосвязь была глубоко интегрирована в доску. Я переработал вход в звонок, precall-проверку устройств, передачу room/user, управление overlay, сворачивание и закрытие. В самом meeting были исправлены duplicate calls, incoming/outgoing race condition, ghost users, cleanup комнат, повторный вход, camera/microphone toggle, screen share, replaceTrack, зависшие видеокадры, пропадание аудио и нестабильный вход по прямой ссылке.
Все изменения собирались и разворачивались через Docker Compose и Nginx на тестовом сервере с резервными копиями, проверкой логов, WebSocket/PeerJS-соединений и регрессионным тестированием.
В результате разрозненные части образовательной платформы были связаны в единый пользовательский сценарий.
Преподаватель может создать доску, привязать ее к уроку, выбрать активное занятие, пригласить учеников и управлять участниками. Ученик автоматически получает нужный контекст урока и подключается к соответствующей доске и комнате видеосвязи.
Гостевые пользователи могут познакомиться с доской в ограниченном demo-режиме, при этом авторизованные пользователи не попадают в него ошибочно.
Видеоконференция работает как часть интерфейса доски: доступны камера, микрофон, чат, демонстрация экрана, сворачивание панели и вход по прямой ссылке. Исправлены нестабильные сценарии, при которых участники не видели друг друга, пропадал звук, зависал последний кадр или создавались конкурирующие WebRTC-соединения.
Повышена стабильность realtime-доски: сложные Fabric-объекты, текст, стили, группы и задания корректнее передаются между пользователями и восстанавливаются после перезагрузки. Исправлены ошибки навигации по холсту, курсоров участников и шаринга доски.
Для тяжёлых досок проведена не только точечная оптимизация, но и подготовлена основа новой архитектуры. Интерфейс, данные объектов, canvas, realtime, сохранение и meeting постепенно разделяются на самостоятельные модули. Это снижает риск дальнейших доработок и позволяет развивать новый дизайн без полного одномоментного переписывания проекта.
Также была локализована нагрузка на PostgreSQL и сокращены лишние сценарии сохранения объектов. Проект продолжает работать в существующей Docker-инфраструктуре и может внедряться поэтапно без остановки текущего продукта.