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 пройшов гладко, я вибудував поступову стратегію впровадження:

Результати