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 дорабатывается и выводится в продакшн. Оценка уточняется после аудита: расхождение обычно даёт не разработка, а согласования и доступы.
Этапы идут с перекрытием: проектирование начинается до завершения аудита, а тестирование — параллельно с финальной доработкой. Это сокращает общий срок внедрения примерно на треть по сравнению с последовательным запуском. Длительность этапов фиксируем в плане внедрения, чтобы заказчик видел, на каком шаге находится проект и что от него требуется на входе.
Если часть работ уже выполнена или интеграции типовые, сроки сокращаются. Если требуется миграция данных из старой системы или нестандартные сценарии ролей — добавляем запас. Точную оценку даём после аудита: опишите задачу, и мы вернёмся с планом и сроками по каждому этапу.







