Франшизы
Источник требований
BR 1.4.4 §3, §7, §8
Франшиза — tenant системы. Каждая франшиза — это изолированный набор данных (ЮЛ, ТТ, сотрудники, каталог, склад) под единым franchise_id. В одной инсталляции ERP может быть произвольное количество франшиз (multi-tenant).
В MVP UI для CRUD франшиз нет — управление вручную через SQL при bootstrap. Эта спека описывает свойства франшизы как сущности и связанное UI-поведение.
Сущность франшизы
| Поле | Обязательность | Описание |
|---|---|---|
id | Автогенерация | UUID, используется всем остальным как franchise_id |
name | Обязательно | Бренд/название сети |
type | Обязательно | corporate | individual — см. ниже |
created_at | Автогенерация |
Поле type: corporate vs individual
(Введено в BR 1.4.4 §3)
type | Поведение |
|---|---|
corporate | Полноценная франшиза с иерархией: одно главное ЮЛ (type=franchise) + произвольное число ЮЛ партнёров (type=franchisee). В меню видны разделы «Юр. лица», «Партнёры». Можно создавать партнёров через UI |
individual | ИП-режим: одно главное ЮЛ (type=franchise), партнёров нет. Раздел «Юр. лица» скрыт в меню. На дашборде нет виджета ЮЛ. API: попытка создать ЮЛ type=franchisee → 403 FRANCHISE_TYPE_INDIVIDUAL |
Default при создании новой франшизы: corporate. При миграции существующей единственной франшизы: corporate.
Что не меняется между типами
- Раздел «Торговые точки» — есть у обоих (у ИП тоже несколько ТТ на одном ЮЛ)
- Форма создания сотрудника — одинаковая (ЮЛ в ней не упоминается)
- Каталог, Склад, Роли, Сотрудники — без изменений
Переключение типа
(MVP) Только вручную через SQL. Отдельной UI-операции нет.
UPDATE franchises SET type = 'corporate' WHERE id = '...';
При переключении individual → corporate уже существующее главное ЮЛ type=franchise сохраняется; появляется возможность создавать партнёров.
При переключении corporate → individual с уже созданными партнёрами — поведение не определено MVP. Рекомендуется предварительно удалить/архивировать всех партнёров.
Смена типа после старта — вне MVP
UI-переключение типа — отдельная BR в будущем. См. BR 1.4.4 §открытый вопрос 5.
Bootstrap новой франшизы
(Введено в BR 1.4.4 §8)
В MVP автоматической регистрации через UI нет. Когда клиент подписывает договор, администратор системы вручную выполняет шаги (SQL или admin-скрипт).
Шаги bootstrap
- Создать запись в
franchises- Имя
- Тип:
corporateилиindividual(обсуждается с клиентом)
- Создать главное ЮЛ в
legal_entitiestype = 'franchise'is_primary = true- Реквизиты со слов клиента
- Создать системную роль «Администратор» в
rolesдля этой франшизы (полный набор permissions,system=true) - Создать сотрудника-владельца в
employees- Email (указан клиентом)
- Временный пароль (сгенерировать и передать клиенту)
- Связать ЮЛ и сотрудника:
legal_entities.owner_user_id = {id сотрудника} - Назначить сотруднику системную роль в
employee_roles
После bootstrap:
- Владелец входит в админку по email+паролю
- Его scope = вся франшиза (правило
owner_user_idв главном ЮЛ, см. Ролевая модель) - Он меняет временный пароль и начинает работу
Автоматическая регистрация (будущее)
Публичная форма регистрации бренда — отдельная BR.
Скрытие разделов при type=individual
(Введено в BR 1.4.4 §7)
Фронт (Admin Web) получает franchise.type из /auth/me и в PermissionContext. На основе типа:
| Элемент UI | corporate | individual |
|---|---|---|
| Пункт меню «Юр. лица» | Виден | Скрыт |
| Виджет «Юр. лица» на дашборде | Виден | Скрыт |
| Кнопка «Создать партнёра» / «Добавить ЮЛ Франчайзи» | Доступна | Скрыта |
Роуты /admin/legal-entities/* | Доступны | Возвращают 404 или редирект на главную |
На бэке:
POST /legal-entitiesсtype=franchiseeприfranchises.type=individual→403 FRANCHISE_TYPE_INDIVIDUALPOST /legal-entitiesсtype=franchiseпри уже существующем главном ЮЛ →409 PRIMARY_LE_EXISTS(независимо от типа франшизы)
Связи с другими модулями
- Юридические лица — раздел скрыт при
type=individual - Сотрудники — scope сотрудника и правила создания опираются на главное ЮЛ франшизы
- Роли — системная «Администратор» автосоздаётся при bootstrap франшизы
- Ролевая модель — правила scope