Medusa JS адмін панель: де ламається управління магазином
Штатна Medusa JS адмін панель закриває базовий сценарій: товари, замовлення, клієнти, склади. Поки каталог — сотня позицій і один регіон, усе працює. Як тільки з'являються кілька складів, десятки тисяч SKU і ролі співробітників, починають проявлятися вузькі місця.
Перше — повільне завантаження списків товарів. Адмінка запитує зв'язки (варіанти, ціни, залишки, колекції) і без явного зазначення полів тягне весь об'єкт цілком.
На 20-30 тисячах позицій сторінка відкривається десятки секунд, фільтри «зависають», а менеджер іде працювати в таблицю. Друге — ручні операції: масова правка цін, прив'язка категорій, перерахунок знижок робляться по одному товару, бо штатних масових дій немає.
Третє і найдорожче — розходження залишків. Замовлення, повернення і списання живуть у різних місцях, синхронізація з 1С або маркетплейсом іде за розкладом, і в моменті адмінка показує не те, що реально на складі. Підсумок — продаж того, чого немає, і ручна звірка.
Четверте — відсутність потрібних віджетів: у відділу є свої метрики (оборотність, частка скасувань, статус поставки), але вбудувати їх у дашборд без правки коду не можна.
Кастомізація адмінки Medusa вирішує це точково: налаштовувані вибірки з пагінацією і фільтрами на стороні сервера, масові операції, віджети під конкретні ролі, єдине джерело правди щодо залишків. Розбираємо, як це закривається.
Що дає доопрацьована адмінка: віджети, ролі, швидкість
Кастомні віджети замість доопрацювання ядра
Штатна панель закриває базові сценарії, але щойно з'являються власні сутності — склад, програма лояльності, погодження — команда починає правити ядро.
Віджети в Medusa 2 підключаються через точки розширення і живуть окремо від основної кодової бази: оновлення платформи не ламає доопрацювання.
На практиці це скорочує обсяг коду, який потрібно переперевіряти при кожному апгрейді, у рази — замість правки десятків файлів залишається один ізольований модуль.
Ролі та права: доступ за операціями, а не «усім усе»
Розмежування доступу будується на ролях із набором дозволів за конкретними діями: менеджер бачить замовлення, але не чіпає ціни та налаштування платежів; контент-редактор працює з картками товарів без доступу до фінансів.
Права перевіряються і в інтерфейсі, і на стороні API — прихована кнопка не замінює серверної перевірки. Це прибирає клас інцидентів, коли співробітник із зайвими правами випадково змінює ціни або видаляє замовлення.
Оптимізація запитів: панель перестає «зависати» на великих каталогах
Основна причина повільної адмінки — списки, які тягнуть пов'язані дані цілком. Ми обмежуємо вибірку полів, додаємо пагінацію та індекси під реальні фільтри, кешуємо довідники.
Список замовлень на десятках тисяч записів відкривається за секунди замість десятків секунд, а фільтри за статусом і датою перестають блокувати інтерфейс.
| Варіант | Коли підходить | Обмеження |
|---|---|---|
| Віджети через точки розширення | Власні сутності та сценарії | Потребують акуратної типізації даних |
| Форк і правка ядра | Разовий нестандартний сценарій | Кожне оновлення — ручне перенесення правок |
| Зовнішня панель поверх API | Свій інтерфейс під вузьку роль | Дублювання логіки та авторизації |
Для контролю продуктивності використовуємо профілювання запитів на реальних обсягах даних — Medusa віддає метрики за кожним зверненням до API, і за ними видно, яка ділянка гальмує.
Як ми впроваджуємо доопрацювання: етапи інженерної роботи
Роботу починаємо з аудиту адмін панелі: дивимося, які сутності та зв'язки вже є в моделі даних, як влаштовані наявні розширення, де розходяться права ролей і реальні обов'язки співробітників.
На виході — карта точок розширення та список сценаріїв, які ламаються зараз або зламаються після доопрацювання. Далі проєктуємо схему інтеграції віджетів: які блоки вбудовуються в картку замовлення, які живуть окремою сторінкою, що тягне дані із зовнішніх систем, а що пише назад.
- Аудит адмін панелі та моделі даних. Фіксуємо поточні сутності, кастомні поля, розширення та розходження між правами ролей і фактичними задачами співробітників.
- Схема інтеграції віджетів. Визначаємо точки вбудовування, джерела даних і спосіб зв'язку із зовнішніми сервісами — через штатні розширення або окремий шар поверх.
- Налаштування ролей доступу. Розмежовуємо права за ролями: хто бачить замовлення цілком, хто лише свою частину, хто керує товарами та цінами. Перевіряємо, що обмеження працюють на рівні запитів, а не лише інтерфейсу.
- Перевірка сценаріїв. Прогоняємо наскрізні шляхи: оформлення замовлення, повернення, зміна статусу, масові операції. Окремо — поведінка при відмовах зовнішніх сервісів і повторних запитах.
- Оптимізація. Прибираємо зайві запити на списках, додаємо індекси під часті фільтри, перевіряємо час відгуку на великих вибірках.
- Деплой. Збираємо конфігурацію оточень, міграції та змінні, піднімаємо на стенді, потім на робочому контурі з можливістю відкату.
- Передача конфігурації. Віддаємо налаштовану адмінку, схему інтеграції, політики доступу та документацію за типовими операціями.
Кожен етап закінчується перевірюваним результатом: карта розширень, схема, матриця прав, звіт за сценаріями, конфігурація оточень. Опишіть задачу — повернемося з оцінкою та планом за вашим контуром.
Чим кастомний віджет відрізняється від правки ядра Medusa?
Кастомний віджет — це окремий модуль, який підключається до medusa js адмін панелі через точку розширення і живе поверх ядра, не змінюючи його файли.
Правка ядра — це коли інженер відкриває вихідні коди @medusajs/admin або серверних пакетів і редагує їх напряму: переписує роут, додає поле в модель, змінює логіку оформлення замовлення. Зовні результат однаковий — нова кнопка в інтерфейсі або нове поле в картці товару. Різниця проявляється не в момент розробки, а в момент першого оновлення.
Архітектура розширень будується на тому, що ядро залишається незмінним артефактом з реєстру пакетів. Віджет реєструється в окремому файлі конфігурації, отримує доступ до потрібних даних через публічні хуки та API і не знає про внутрішній устрій сусідніх модулів.
Коли виходить нова гілка Medusa, ви оновлюєте версію пакета і перезбираєте адмінку — ваш код залишається на місці, бо він ніколи не був вбудований у чужий.
При правці ядра оновлення перетворюється на ручне злиття: потрібно порядково порівняти свої зміни з новою версією, перенести їх заново і перевірити, що нічого не відвалилося.
Чим більше правок накопичилося, тим дорожче кожне оновлення і тим вищий шанс, що команда вирішить «поки не чіпаємо» — і залишиться на застарілій гілці з відомими уразливостями.
Ризики правки ядра накопичуються непомітно. Перша зміна здається нешкідливою, але кожна наступна нашаровується на попередню, і через кілька ітерацій уже ніхто не пам'ятає, навіщо перевизначено конкретний метод.
Тести, написані для стандартної поведінки, починають падати на вашій збірці, а баг-репорти від постачальника неможливо застосувати, бо відтворити проблему на зміненому ядрі не можна.
Віджет такий клас проблем виключає: він ізольований, його можна вимкнути одним рядком у конфігурації, і поведінка системи повернеться до еталонної.
Практичне правило просте: все, що можна зробити через віджет, подію або окремий модуль, робиться так.
Пряма правка ядра виправдана тільки там, де публічної точки розширення справді немає, — і тоді це оформлюється як патч з окремим тестом і позначкою, яку команда зобов'язана переглянути при кожному оновленні. Підтримка оновлень у цьому випадку стає керованим процесом, а не авралом раз на квартал.
Кейс: прискорили адмінку та прибрали ручні операції
Проєкт — маркетплейс на Medusa з каталогом у кілька десятків тисяч товарів і десятком постачальників.
Оператори скаржилися, що список замовлень відкривається по 8-12 секунд, а частина рутинних дій — звірка залишків, проставлення статусів, перевипуск карток після імпорту — робилася руками в таблицях.
Помилки від ручного введення накопичувалися тижнями: розбіжності в залишках, задвоєні позиції, загублені статуси.
Що зробили
Адмінку доопрацювали, а не переписали: додали віджети в картку замовлення і товару, винесли часті дії в кнопки з підтвердженням, а важкі списки перевели на серверну пагінацію і фільтри на стороні API.
Імпорт постачальників став фоновим завданням із журналом — оператор бачить, що пройшло, що впало і чому, замість очікування біля екрана.
Метрики до і після
| Показник | До | Після |
|---|---|---|
| Завантаження списку замовлень | 8-12 с | 1-2 с |
| Частка ручних операцій | ~40% | ~10% |
| Розбіжності в залишках | щотижня | поодинокі випадки |
| Обробка імпорту постачальника | вручну, години | фоном, хвилини |
Ручні операції не зникли повністю — залишилися там, де потрібне рішення людини. Але рутина пішла в автоматику з журналом: якщо щось пішло не так, видно, на якому кроці і з якими даними.
Що це дало
Команда перестала витрачати час на звірку і розбір розбіжностей — вивільнені години пішли на роботу з асортиментом і постачальниками. Клас помилок «людина забула/переплутала» практично зник: там, де раніше правили вручну, тепер спрацьовує перевірка на вході.
Працювали на стеку Medusa — Medusa дає готову адмінку і API, тому доопрацювання лягли поверх без переписування ядра. Якщо у вас схожа ситуація — опишіть задачу, повернемося з оцінкою та планом.
Сумісність, міграція та відкат: що обговорити до старту
Перед стартом важливо зафіксувати, як адмін-панель на Medusa впишеться в поточний контур: де розташована база, як влаштована авторизація, хто і за якими ролями заходить в інтерфейс.
Якщо в проєкті вже є власний шар автентифікації або зовнішній провайдер входу, ми плануємо зв'язку заздалегідь — інакше після деплою виникають конфлікти сесій і дублі облікових записів.
Окремо проговорюємо міграцію даних: переносимо каталог, замовлення та налаштування так, щоб не зупиняти роботу магазину.
Що якщо знадобиться відкат? План відкату готуємо до першої зміни в проді: фіксуємо точку відновлення бази, версіонуємо конфігурацію та тримаємо попередній робочий реліз доступним для повернення.
Якщо після викату щось іде не так, повертаємося на зафіксований стан за хвилини, а не перезбираємо все заново.
Як бути з доступами? Ролі та права розмежовуємо за принципом мінімально необхідного: менеджер бачить замовлення, але не чіпає налаштування, адміністратор керує каталогом, розробник отримує доступ до конфігурації. Усі ключі та облікові дані передаємо через захищений канал, а не в листуванні.
Чи можна мігрувати без зупинки сайту?
Так. Переносимо дані поетапно: спочатку синхронізуємо каталог і налаштування на копію, перевіряємо цілісність зв'язків, потім перемикаємо трафік у коротке вікно. Покупці продовжують оформлювати замовлення, а розбіжності звіряємо за контрольними сумами до фінального перемикання.
Після здачі ви отримуєте на руки повний комплект:
- конфігурацію віджетів і кастомних полів адмін-панелі;
- схему ролей і матрицю прав доступу;
- скрипти міграції даних з описом порядку запуску;
- інструкцію з деплою та налаштування середовищ;
- регламент резервного копіювання та відновлення;
- план відкату з точками повернення;
- документацію щодо підключених інтеграцій і зовнішніх сервісів.
Опишіть вашу поточну інфраструктуру та задачу — повернемося з оцінкою, планом міграції та строками.
Терміни етапів впровадження: від аудиту до передачі
Терміни залежать не від розміру команди, а від стану поточного контуру: чим менше в проєкті ручних операцій і «залипань» між системами, тим коротший кожен етап.
Нижче — орієнтир щодо тривалості для типового проєкту, де адмін-панель Medusa 2 доопрацьовується і виводиться в продакшн. Оцінка уточнюється після аудиту: розбіжність зазвичай дає не розробка, а погодження та доступи.
Етапи йдуть з перекриттям: проєктування починається до завершення аудиту, а тестування — паралельно з фінальним доопрацюванням. Це скорочує загальний термін впровадження приблизно на третину порівняно з послідовним запуском.
Тривалість етапів фіксуємо в плані впровадження, щоб замовник бачив, на якому кроці перебуває проєкт і що від нього потрібно на вході.
Якщо частину робіт уже виконано або інтеграції типові, терміни скорочуються. Якщо потрібна міграція даних зі старої системи або нестандартні сценарії ролей — додаємо запас. Точну оцінку даємо після аудиту: опишіть задачу, і ми повернемося з планом і термінами за кожним етапом.







