Внутренняя система управления, которую разработчики делают для отдела продаж, склада или поддержки, живёт по другим правилам, чем клиентский сайт. Здесь никто не будет разбираться с багами через тикет в поддержку - сотрудник просто перестанет открывать таблицу и вернётся в Excel или в переписку с бухгалтером на бумажке. За несколько лет на фрилансе я собрал больше десятка панелей на React - от CRM для логистической компании до дашборда для колл-центра, - и в каждой на старте всплывали одни и те же провалы. Собрал чек-лист того, что закладываю в такую систему с первого спринта, а не докручиваю после жалоб пользователей.
Зачем внутренней системе управления архитектура, а не набор компонентов
На клиентском сайте достаточно красивой формы и рабочей кнопки. Во внутренней панели через полгода появляется шесть модулей - склад, заказы, сотрудники, отчёты, финансы, - и если не выделить общий слой форм и таблиц с самого начала, в каждом модуле заводится свой чекбокс с чуть-чуть другим поведением. Я видел проект, где у трёх разных разработчиков получилось три реализации одной и той же модалки подтверждения удаления - с разной логикой закрытия по Escape.
Перед первым коммитом фиксирую три вещи: монорепозиторий с общим UI-китом (обычно беру за основу shadcn/ui или Ant Design и допиливаю под задачу), feature-based структуру папок вместо разделения на pages/components, и TypeScript в строгом режиме с общими типами между фронтом и бэком через Zod-схемы. Это экономит примерно неделю разработки на каждый следующий модуль - вторая CRM-таблица собирается за два дня, а не за пять, потому что фильтры, пагинация и экспорт уже вынесены в переиспользуемые хуки.
Роли, права доступа и аутентификация в корпоративной системе управления
Внутреннюю систему нельзя показывать заказчику без нормальной модели доступа - и дело не в чек-листе безопасности, а в том, что рано или поздно менеджер с правами кладовщика удалит заказ на 300 000 ₽, потому что кнопка была видна и активна. Роли “админ/менеджер/наблюдатель” - это только начало, реальная система требует прав на уровне действий: can_edit_price, can_delete_order, can_export_clients.
Пример проверки прав на клиенте выглядит так:
function useCan(action) {
const { permissions } = useAuth();
return permissions.includes(action);
}
function OrderRow({ order }) {
const canDelete = useCan('order.delete');
return (
<tr>
<td>{order.number}</td>
{canDelete && <button onClick={() => deleteOrder(order.id)}>Удалить</button>}
</tr>
);
}
Важный момент: проверка на клиенте - это только про удобство интерфейса, реальная защита всегда дублируется на бэкенде, иначе права обходятся через DevTools за минуту. Для аутентификации использую JWT с коротким access-токеном (10-15 минут) и refresh-токеном в httpOnly cookie, а для компаний с 20+ сотрудниками - SSO через корпоративную почту или Keycloak, чтобы не заводить пароли вручную в самой панели.
Таблица прав по ролям, которую я обычно защищаю с заказчиком на старте проекта:
| Действие | Админ | Менеджер | Наблюдатель |
|---|---|---|---|
| Просмотр заказов | да | да | да |
| Редактирование цены | да | да | нет |
| Удаление записей | да | нет | нет |
| Экспорт базы клиентов | да | по согласованию | нет |
Таблицы, фильтры и экспорт данных без тормозов на реальных объёмах
Любая внутренняя система рано или поздно упирается в таблицу на 10-50 тысяч строк. Если рендерить их все в DOM через обычный map, браузер начинает подтормаживать уже на 3-5 тысячах записей - особенно на слабых офисных ноутбуках, где реально работают сотрудники, а не тестовый MacBook разработчика. Беру TanStack Table для логики колонок и сортировки плюс серверную пагинацию - запрос отдаёт по 50-100 строк за раз, а не всю таблицу целиком.
Что закладываю обязательно:
- серверную фильтрацию и пагинацию, а не клиентскую - иначе первый запрос грузит мегабайты JSON
- дебаунс на поиск (300-400 мс), чтобы не долбить бэкенд на каждую букву
- сохранённые фильтры (saved views) на пользователя - менеджер по продажам и логист смотрят на одну таблицу заказов совершенно по-разному
- экспорт в XLSX, который генерируется на бэкенде через exceljs или openpyxl, а не в браузере - клиентская генерация файла на 50 тысяч строк вешает вкладку на 20-30 секунд
- виртуализацию списков через react-window там, где серверная пагинация неудобна (например, дерево категорий склада)
Для кэширования запросов использую TanStack Query - он же решает задачу оптимистичных обновлений: пользователь меняет статус заказа, интерфейс реагирует мгновенно, а откат происходит только если запрос реально упал. На дашбордах с несколькими одновременными пользователями (склад, где статус меняется в реальном времени у пяти сотрудников сразу) добавляю WebSocket-канал поверх обычного REST - без него люди работают с устаревшими данными и путают заказы.
Бесплатный материал
🎁 Полезный скрипт в подарок
Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.
Без спама. Отписка в 1 клик.
Интеграции с СДЭК, эквайрингом и мессенджерами
Внутренняя панель почти никогда не живёт одна - она тянет заказы из 1С, оплаты через эквайринг T‑Bank, статусы доставки через API СДЭК, уведомления в Telegram через aiogram-бота. Для логистической компании делал панель, которая по вебхуку от СДЭК обновляла статус посылки в базе и сразу слала сообщение в рабочий Telegram-чат через aiogram - отдел продаж видел движение груза, не заходя в личный кабинет перевозчика по десять раз в день.
Для рутинных цепочек, которые меняются раз в квартал (выгрузка отчётов, синхронизация статусов между CRM и складом, простые уведомления по расписанию), беру n8n вместо отдельного сервиса на Python - дешевле по времени разработки и проще передать логику нетехническому сотруднику для мелких правок. У меня в библиотеке есть готовые скрипты интеграции с СДЭК и эквайрингом, которые ускоряют такие задачи - не приходится писать обвязку с нуля под каждый проект.
Отдельно про персональные данные: если панель хранит телефоны и контакты клиентов, база и бэкенд должны стоять на серверах в РФ - по 152-ФЗ хранить такие данные в Google Sheets, Airtable или Notion нельзя, это прямое нарушение требований локализации. Для внутренних CRM всегда развожу это на старте с заказчиком, чтобы не переделывать хранилище через полгода после проверки.
Логирование и аудит действий сотрудников
Без журнала действий рано или поздно возникает спор: кто поменял цену в заказе, кто удалил клиента из базы, почему статус отгрузки откатился назад. Отдельная таблица audit_log с полями user_id, action, entity, old_value, new_value, created_at решает это за один вечер разработки и экономит часы разбирательств потом.
Что должно логироваться минимум:
- изменение цены, статуса заказа, суммы скидки
- удаление любых записей - с возможностью восстановления в течение 30 дней
- вход и выход пользователей, попытки доступа без прав
- изменение прав доступа других пользователей - это чаще всего забывают, а именно тут прячутся злоупотребления
Отдельный экран “История изменений” по каждой карточке заказа или клиента - то, что заказчики обычно просят добавить уже после первого спорного случая, хотя закладывается это за пару часов на этапе проектирования базы.
Сроки и стоимость разработки внутренней системы управления
Цена зависит не от количества экранов, а от глубины интеграций и объёма данных. Простая MVP-панель с одной таблицей заказов и базовыми ролями собирается за 3-4 недели, система с полноценной матрицей прав, интеграциями и аудитом - за 2-3 месяца.
| Формат системы | Что входит | Сроки |
|---|---|---|
| MVP-панель | 1-2 таблицы, роли админ/менеджер, без интеграций | 3-4 недели |
| Стандартная CRM/админка на React | несколько модулей, права по действиям, экспорт, аудит | 1,5-2 месяца |
| Система с интеграциями | СДЭК, эквайринг, Telegram-уведомления, n8n-цепочки | 2-3 месяца |
Я веду разработку CRM и админ-панелей на React от 100 000 ₽ - итоговая сумма зависит от количества модулей и интеграций, но не ниже этой планки даже для урезанного MVP. На рынке фриланса и в небольших студиях за похожую панель просят от 60 000 до 200 000 ₽ в зависимости от опыта команды - это ориентир по рынку, не моя цена, и такой разброс обычно означает разную глубину проработки прав доступа и аудита, о которых писал выше. Отдельные доработки вроде добавления нового модуля или интеграции с n8n обычно укладываются в рамки автоматизации от 25 000 ₽, а разовая консультация по архитектуре перед стартом - от 3 000 ₽.
Кастомный CRM/админ-интерфейс
Админка / CRM
от 100 000 ₽
Подробнее →Частые вопросы
Сколько стоит разработка внутренней системы управления на React?
Базовая CRM или админ-панель на React у меня стоит от 100 000 ₽ - сумма растёт вместе с количеством модулей, интеграций и глубиной проработки ролей. MVP с одной таблицей и простыми правами укладывается в нижнюю границу, система с СДЭК, эквайрингом и аудитом действий - заметно дороже базовой цены.
Можно ли встроить панель в существующую CRM или 1С?
Да, это стандартная задача - обычно через REST API или прямое подключение к базе 1С по OData. Я закладываю такие интеграции на этапе проектирования, а не пытаюсь пристроить их после сдачи проекта, потому что от формата обмена данными зависит структура таблиц в самой панели.
Нужен ли отдельный бэкенд или хватит n8n без кода?
Для простых цепочек - выгрузка отчётов, уведомления, синхронизация статусов раз в день - n8n закрывает задачу без отдельного сервиса и обходится дешевле. Для полноценной панели с ролями, аудитом и большими объёмами данных нужен собственный бэкенд: n8n не заменяет базу с индексами и транзакционную логику списания остатков на складе.
Как быстро можно сдать MVP внутренней системы управления?
При чётком техзадании и без блокирующих интеграций первую рабочую версию с базовыми ролями и одной-двумя таблицами сдаю за 3-4 недели. Сроки растягиваются, если заказчик на этапе разработки решает подключить СДЭК или эквайринг - такие интеграции стоит планировать сразу, а не добавлять в последний момент.