Представьте, что вы наняли гениального сварщика. Он отлично варит металл. Но когда он открывает рабочую программу, чтобы отметить деталь как готовую, система вываливает на него меню из 40 пунктов: «Отчеты по маржинальности», «Налоговые декларации», «Справочник контрагентов». Он пугается, закрывает ноутбук и идет курить.
Это болезнь старых систем. Они пытаются быть универсальными для всех сразу. В ModernERP Pro мы приняли жесткое архитектурное решение: мы разнесли логику и интерфейсы разных должностей по отдельным контроллерам пространства `LK` (Личный Кабинет).
Анатомия ролевого фокуса
Каждый Личный Кабинет спроектирован так, чтобы отвечать на главный вопрос конкретной должности. Взгляните на дашборды (Dashboard), зашитые в код наших контроллеров:
1. Кабинет Закупщика (BuyerController)
Его фокус — Критический дефицит. Ему плевать, сколько компания заработала. Он должен знать, из-за какого отсутствующего болта сейчас встанет конвейер.
- KPI на экране: Активные закупки в пути, Опоздавшие поставщики, Дефицит материалов.
2. Кабинет Менеджера по продажам (SalesManagerController)
Его фокус — Деньги и горящие сроки. Он не видит остатки сырья, он видит свои сделки.
- KPI на экране: Объем продаж за месяц, Ожидаемые оплаты, Просроченные отгрузки клиентам.
3. Кабинет Мастера цеха (MasterController)
Его фокус — Задачи (Production Tasks) и Брак. Ему не нужны деньги. Ему нужен план на смену.
- KPI на экране: Детали в очереди, Детали в работе.
- Главная кнопка: «Зафиксировать брак» (с автоматической эскалацией проблемы и остановкой заказа).
Жесткая изоляция (Hard Security)
Эти кабинеты не просто визуально скрыты друг от друга CSS-стилями. Они защищены на уровне ядра (Symfony Security). Если Кладовщик (`ROLE_STOREKEEPER`) попытается вручную вбить в адресную строку URL кабинета Закупщика (`/admin/buyer`), бэкенд мгновенно выдаст ошибку 403 Access Denied. За это отвечает атрибут #[IsGranted('ROLE_...')] над каждым классом.
🛠 B2B Портал: Кабинет Клиента
Самая высокая степень изоляции — это ClientController. Мы пускаем ваших внешних заказчиков внутрь вашей ERP, чтобы они сами видели статус производства своих заказов. Но здесь нужна параноидальная безопасность. Клиент не должен увидеть чужой заказ.
public function show(SaleOrder $order): Response
{
// Если ID клиента в заказе не совпадает с ID авторизованного пользователя...
if ($order->getClient() !== $this->getUser()->getClient()) {
throw $this->createAccessDeniedException('Это не ваш заказ.');
}
return $this->render('lk/client/order_show.html.twig', [...]);
}
Даже если клиент попытается угадать ID чужого заказа в URL, контроллер выбросит его с ошибкой. Данные герметичны.
Бизнес-результат
Разделение на изолированные кабинеты кардинально снижает порог входа в систему. Время обучения нового сотрудника сокращается с недель до часов. Человек открывает планшет, видит три кнопки, относящиеся только к его работе, и сразу начинает приносить пользу компании.
Симулятор Личного Кабинета
Выберите роль сотрудника, чтобы увидеть, как изменится интерфейс и фокус системы.