ERP-система расписания для образовательного центра
Product & Systems Architect — Alex Shevchuk
Суть кейса: замена легаси на базе Excel современным веб-приложением. Начало разработки: февраль 2026. Прод: с 1 сентября 2026. Статус: прод стабилен, работает без сбоев, продолжается разработка нового
функционала и дополнительных модулей.
Контекст и проблема
После начала работы в научно-образовательном центре физики и химии я обнаружил,
что организация работает на тяжёлой системе, построенной на базе Excel.
Она постоянно падала, зависала под нагрузкой и делала ежедневные операционные изменения
крайне болезненными и подверженными ошибкам.
Масштаб операционной нагрузки:
26 школ-партнёровдо 50 уроков в день105 учебных группспециализированные лабораториичастые замены преподавателей, отмены и переносы уроковзаказы оборудования
Именно поэтому я решил создать систему, которая позволила бы сделать управление
расписанием и ресурсами более надёжным и предсказуемым. В свободное от основной работы
время я разработал собственную Scheduling System, а в середине августа,
перед началом нового учебного года, бесплатно развернул и настроил отдельную копию системы
для учебного центра, чтобы упростить ежедневную работу коллег.
Опыт работы с реляционными базами данных сформировал основной архитектурный принцип
проекта: изменения расписания и ресурсов должны обрабатываться как транзакции, а не как
простое редактирование таблиц.
Контроль целостности был вынесен на уровень СУБД, история изменений сделана неизменяемой
через Audit Log, а архитектура позволяет безопасно восстановить состояние
расписания на конкретный день.
Моя роль
Архитектура системы и базы данных — разработал мультисхемную архитектуру БД, ролевую модель доступа, гибкую логику разрешения конфликтов (замена учителя, перенос урока в другой кабинет), развёртывание годового расписания из недельного шаблона с автоматическим подбором кабинетов по заданным правилам, вынес все ключевые бизнес-инварианты на уровень БД (интервалы GiST, предотвращающие двойное бронирование), транзакционные снапшоты сессий редактирования и очереди событий.
Интеграция каталога оборудования — интегрировал интерактивный каталог оборудования, благодаря чему заказ учителя прослеживается через всю систему на каждом этапе обработки (dashboard учителя, dashboard лаборанта, на панели администратора и в письмах-уведомлениях).
Табло в реальном времени — спроектировал табло для учеников и для учителей (табло учителей показывает дополнительную служебную информацию).
DevOps и инфраструктура — контейнеризация в Docker, Nginx, деплой AWS EC2 + Cloudflare Tunnel, автоматические бэкапы в S3, транзакционный pipeline отправки писем через Resend (с возможностью динамического изменения бизнес-правил через админ-панель).
Disaster Recovery — разработал и протестировал схему восстановления после полного краха системы (крах был смоделирован по следующей схеме: полностью снёс инстанс, создал новый (обновил систему, установил необходимые компоненты), деплой новой копии из GitHub + накатывание последнего backup базы). По результатам была написана пошаговая инструкция восстановления системы.
ERP-система управления расписанием и операционной деятельностью:
Годовой шаблон + генерируемое годовое расписание
Редактирование расписания на уровне дня с freeze / unfreeze / rollback
Замены учителей
Отмены и переносы уроков
Создание новых уроков и дополнительных занятий
Процесс заказа лабораторного оборудования
Очередь заявок (принцип «одного окна»)
Email-уведомления по всем ключевым событиям — изменения расписания, смена кабинета, назначение замены учителя, отмена урока, заказы оборудования, одобрение заявок, а также служебные уведомления для админов
PostgreSQL — выбран ради нативной поддержки EXCLUDE USING GIST. Это
позволяет на уровне движка СУБД обеспечить отсутствие пересечений временных интервалов
и автоматически исключать race conditions при параллельных запросах.
Логика в БД — перенос инвариантов в СУБД обеспечил единый источник правды
и целостность данных независимо от точки подключения (API, фоновые скрипты или прямые админ-сессии).
Node.js + Express — тонкий stateless-шлюз (Thin API Gateway),
ограниченный задачами авторизации и транзита запросов без дублирования бизнес-логики.
Vue 3 + PrimeVue — сократил time-to-market за счёт готовой экосистемы
сложных UI-компонентов для административных экранов.
Cloudflare Tunnel — изолировал инфраструктуру по принципу Zero Trust,
полностью исключив необходимость публикации публичного IP и открытия входящих портов.
Структура проекта:
Структура репозитория — система изначально спроектирована с чётким разделением
приложения, логики БД и инфраструктуры.
Система в реальной жизни:
Коридорное табло в учительской — вживую на стене учебного центра.
Коридорное табло для учеников — вживую на стене учебного центра.
Production monitoring — система находится под постоянным внешним
мониторингом доступности. 100% uptime за последние 30 дней; 99.995% с 1 сентября 2026 —
единственный инцидент длительностью 5 минут был плановой остановкой во время деплоя новой
версии (миграция БД и перезапуск контейнеров backend/frontend). С тех пор — без сбоев.
Инфраструктура отправки писем — уведомления отправляются через
верифицированный домен с помощью транзакционного почтового сервиса (Resend), что
обеспечивает надёжную доставку и корректную аутентификацию (SPF/DKIM).
Интерфейс системы
Нажмите на любой скриншот, чтобы открыть его в полном размере.
Дневной Гантт — актуальное расписание дня по кабинетам.
Цветовая кодировка предметов, подсветка замен, индикатор текущего времени.
Годовой шаблон (Basic Schedule) — источник правды.
Изменения из него безопасно распространяются на сгенерированное годовое расписание
с помощью двухфазного алгоритма.
Дашборд учителя — личный кабинет: ближайшие уроки, заявки на оборудование,
история замен и рабочий график.
Админ-дашборд — центральное «одно окно». Учителя только создают заявки,
администраторы рассматривают, корректируют и применяют изменения.
Дашборд лаборантов — операционная витрина: заказы оборудования
и заметки на выбранный день.
Audit Log — полностью неизменяемая история всех значимых действий.
Даже суперадмин не может изменить или удалить записи.
Правила рассылки писем — кому о чём сообщать. Каждый тип события (новая
заявка, одобрение, заказ оборудования, замена, обслуживание сервера...) можно направить
отдельно выбранным ролям и участникам события (автор заявки, учитель урока, замещающий,
фактический учитель) — настраивается на экране «Control Panel», с общим выключателем для
мгновенной остановки всей рассылки.
Реальный почтовый ящик системы — входящие уведомления сами сортируются по
типу события (заказ оборудования, отмена урока, смена кабинета, замена учителя...) по
отдельным папкам, каждая со своим адресом отправителя.
Подтверждение заказа оборудования — с кодами позиций и прямыми ссылками на
библиотеку материалов Hemda.
Табло для учеников — публичный экран с текущим расписанием.
Инженерная культура — код и документация
Один из ключевых принципов проекта: логика и решения объясняются прямо в коде —
не только что делает функция, но и зачем она нужна и что сломается,
если нарушить инвариант.
1. Чёткое разделение структуры и бизнес-логики
schema.sql — явное правило: здесь только структура.
Бизнес-логика живёт в модульных файлах.
2. Подбор кабинетов с явными бизнес-правилами
campus._find_room() — правила приоритета кабинетов для физики и химии
задокументированы и закодированы прямо в запросе.
year_schedule.sql — в шапке файла объясняется назначение каждой
ключевой функции и поток freeze / unfreeze дня.
3. Контроль качества и проверка инвариантов
391 автоматизированная регрессионная проверка (уровни API и БД) перед каждым деплоем —
покрывает цепочки согласования заявок, замены учителей, заморозку/откат дня, предотвращение
конфликтов расписания (EXCLUDE USING GIST), заказы оборудования и матрицу правил рассылки.
4. Эксплуатационная дисциплина релизов
Каждый из ~20 релизов на прод за 9 месяцев проходит по одному и тому же протоколу: репетиция
миграции на свежей копии прод-базы, Docker-образы с тегом :rollback перед
пересборкой, бэкап непосредственно перед накатом и письменный журнал деплоя на сервере.
Реальное окно переключения контейнеров — от 13 до 55 секунд.
План восстановления после полного отказа проверен не на бумаге: полный цикл (снос volume →
чистая инициализация с нуля → восстановление реального prod-дампа во временную базу) прогнан
целиком, а ключевые таблицы (сотрудники, уроки, заявки, права) сверены с живой БД построчно.
5. Внедрение и управление изменениями
Чтобы переход с устаревшего Excel прошёл гладко, я выстроил постепенную
стратегию внедрения:
Раннее вовлечение и демонстрации. На этапе разработки я регулярно показывал
коллегам работающие прототипы, объясняя на конкретных примерах, как система избавит их от
ежедневной рутины и путаницы. Начальное безразличие быстро сменилось искренним ожиданием
релиза.
Плавная адаптация за 2 недели до старта. Я внимательно наблюдал за реакцией
сотрудников и оценивал их открытость к изменениям. Когда я увидел, что большинство настроено
позитивно, я пришёл к директору с предложением: не усложнять переход лишней параллельной
работой в двух системах, так как двойной ввод только нервировал бы коллектив. Система
объективно получилась намного проще и удобнее прежней, поэтому я предложил начинать учебный
год сразу на ней, и директор согласился. Чтобы команда успела освоиться, в середине августа
всем сотрудникам был открыт доступ в «песочницу», где каждый мог спокойно покликать интерфейс
и изучить свои кабинеты. Одновременно новая сетка расписания была выведена на все коридорные
экраны центра — за две недели до 1 сентября, чтобы коллектив визуально свыкся с новым форматом.
Практическое обучение. Было проведено несколько раундов практического
обучения для преподавателей и лаборантов: как устроен личный кабинет, как в пару кликов
заказать оборудование в лабораторию, запросить перенос урока и отслеживать статус своей заявки
в реальном времени.
Уважение к привычкам и бумажным заметкам. Я учёл, что части лаборантов и
преподавателей привычнее работать с листом в руках — отмечать карандашом подготовленные опыты,
делать пометки на полях. Этот функционал (отметка готовности оборудования, комментарии к
уроку) заложен и в самой системе — кто-то вносит это прямо в интерфейс, а кто-то сначала на
бумаге, а потом переносит в систему. Поэтому я предусмотрел возможность выгрузки в Excel для
последующей печати отображаемой на экране информации.
Результат. Благодаря интуитивному интерфейсу даже самая консервативная часть
коллектива освоила систему практически без вопросов. Уже к концу сентября (первый месяц
учебного года) система полностью и бесшовно влилась во все ежедневные рабочие процессы
научного центра.
Результаты
Система успешно работает в продакшене с сентября 2026
Выдерживает реальную ежедневную операционную нагрузку центра
Критические инварианты (конфликты расписания, права доступа, аудит) обеспечиваются на уровне базы данных
Полная неизменяемая история всех значимых действий