English עברית Українська Polski Русский

ERP-система расписания для образовательного центра

Product & Systems Architect — Alex Shevchuk
Суть кейса: замена легаси на базе Excel современным веб-приложением.
Начало разработки: февраль 2026.
Прод: с 1 сентября 2026.
Статус: прод стабилен, работает без сбоев, продолжается разработка нового функционала и дополнительных модулей.

Контекст и проблема

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

Масштаб операционной нагрузки:
26 школ-партнёров до 50 уроков в день 105 учебных групп специализированные лаборатории частые замены преподавателей, отмены и переносы уроков заказы оборудования

Именно поэтому я решил создать систему, которая позволила бы сделать управление расписанием и ресурсами более надёжным и предсказуемым. В свободное от основной работы время я разработал собственную Scheduling System, а в середине августа, перед началом нового учебного года, бесплатно развернул и настроил отдельную копию системы для учебного центра, чтобы упростить ежедневную работу коллег.

Опыт работы с реляционными базами данных сформировал основной архитектурный принцип проекта: изменения расписания и ресурсов должны обрабатываться как транзакции, а не как простое редактирование таблиц.

Контроль целостности был вынесен на уровень СУБД, история изменений сделана неизменяемой через Audit Log, а архитектура позволяет безопасно восстановить состояние расписания на конкретный день.

Моя роль

Обзор системы

4
DB-схемы (campus / laboratory / notifications / settings)
31
таблиц в схеме БД
43
функций PL/pgSQL — бизнес-логика в БД
655
коммитов за 9 месяцев разработки
391
регрессионных проверок перед каждым деплоем
24/7
доступность production-системы

ERP-система управления расписанием и операционной деятельностью:

Технологический стек:

PostgreSQL 16 PL/pgSQL Node.js + Express Vue 3 + PrimeVue (RTL) Docker · AWS · Cloudflare Tunnel

Структура проекта:

Структура проекта
Структура репозитория — система изначально спроектирована с чётким разделением приложения, логики БД и инфраструктуры.

Система в реальной жизни:

Коридорное табло в учительской в здании центра
Коридорное табло в учительской — вживую на стене учебного центра.
Коридорное табло для учеников
Коридорное табло для учеников — вживую на стене учебного центра.
Production monitoring
Production monitoring — система находится под постоянным внешним мониторингом доступности. 100% uptime за последние 30 дней; 99.995% с 1 сентября 2026 — единственный инцидент длительностью 5 минут был плановой остановкой во время деплоя новой версии (миграция БД и перезапуск контейнеров backend/frontend). С тех пор — без сбоев.
Email delivery infrastructure
Инфраструктура отправки писем — уведомления отправляются через верифицированный домен с помощью транзакционного почтового сервиса (Resend), что обеспечивает надёжную доставку и корректную аутентификацию (SPF/DKIM).

Интерфейс системы

Нажмите на любой скриншот, чтобы открыть его в полном размере.

Дневной Гантт
Дневной Гантт — актуальное расписание дня по кабинетам. Цветовая кодировка предметов, подсветка замен, индикатор текущего времени.
Базовый шаблон
Годовой шаблон (Basic Schedule) — источник правды. Изменения из него безопасно распространяются на сгенерированное годовое расписание с помощью двухфазного алгоритма.
Дашборд учителя
Дашборд учителя — личный кабинет: ближайшие уроки, заявки на оборудование, история замен и рабочий график.
Админ-дашборд
Админ-дашборд — центральное «одно окно». Учителя только создают заявки, администраторы рассматривают, корректируют и применяют изменения.
Дашборд лаборантов
Дашборд лаборантов — операционная витрина: заказы оборудования и заметки на выбранный день.
Audit Log
Audit Log — полностью неизменяемая история всех значимых действий. Даже суперадмин не может изменить или удалить записи.
Правила рассылки писем
Правила рассылки писем — кому о чём сообщать. Каждый тип события (новая заявка, одобрение, заказ оборудования, замена, обслуживание сервера...) можно направить отдельно выбранным ролям и участникам события (автор заявки, учитель урока, замещающий, фактический учитель) — настраивается на экране «Control Panel», с общим выключателем для мгновенной остановки всей рассылки.
Реальный почтовый ящик системы
Реальный почтовый ящик системы — входящие уведомления сами сортируются по типу события (заказ оборудования, отмена урока, смена кабинета, замена учителя...) по отдельным папкам, каждая со своим адресом отправителя.
Письмо о подтверждении заказа оборудования
Подтверждение заказа оборудования — с кодами позиций и прямыми ссылками на библиотеку материалов Hemda.
Табло для учеников
Табло для учеников — публичный экран с текущим расписанием.

Инженерная культура — код и документация

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

1. Чёткое разделение структуры и бизнес-логики

Комментарии в schema.sql
schema.sql — явное правило: здесь только структура. Бизнес-логика живёт в модульных файлах.

2. Подбор кабинетов с явными бизнес-правилами

Функция _find_room
campus._find_room() — правила приоритета кабинетов для физики и химии задокументированы и закодированы прямо в запросе.
Заголовок year_schedule.sql
year_schedule.sql — в шапке файла объясняется назначение каждой ключевой функции и поток freeze / unfreeze дня.

3. Контроль качества и проверка инвариантов

391 автоматизированная регрессионная проверка (уровни API и БД) перед каждым деплоем — покрывает цепочки согласования заявок, замены учителей, заморозку/откат дня, предотвращение конфликтов расписания (EXCLUDE USING GIST), заказы оборудования и матрицу правил рассылки.

4. Эксплуатационная дисциплина релизов

Каждый из ~20 релизов на прод за 9 месяцев проходит по одному и тому же протоколу: репетиция миграции на свежей копии прод-базы, Docker-образы с тегом :rollback перед пересборкой, бэкап непосредственно перед накатом и письменный журнал деплоя на сервере. Реальное окно переключения контейнеров — от 13 до 55 секунд.

План восстановления после полного отказа проверен не на бумаге: полный цикл (снос volume → чистая инициализация с нуля → восстановление реального prod-дампа во временную базу) прогнан целиком, а ключевые таблицы (сотрудники, уроки, заявки, права) сверены с живой БД построчно.

5. Внедрение и управление изменениями

Чтобы переход с устаревшего Excel прошёл гладко, я выстроил постепенную стратегию внедрения:

Результаты