BR 6.1 → Admin Franchise
Репозиторий: erp-admin (содержит bff/ и web/)
Спеки:
Admin BFF (bff/)
Прокси-эндпоинты
Все 5 эндпоинтов CRUD маркетинговых слайдов проксируются 1-к-1 в Store Service:
-
GET /admin/api/v1/stores/:storeId/marketing-slides→GET /api/v1/admin/stores/:storeId/marketing-slides -
POST /admin/api/v1/stores/:storeId/marketing-slides→POST /api/v1/admin/stores/:storeId/marketing-slides(multipart pass-through) -
PUT /admin/api/v1/stores/:storeId/marketing-slides/:slideId→PUT /api/v1/admin/stores/:storeId/marketing-slides/:slideId -
PATCH /admin/api/v1/stores/:storeId/marketing-slides/reorder→ 1-к-1 -
DELETE /admin/api/v1/stores/:storeId/marketing-slides/:slideId→ 1-к-1 - При прокси multipart — использовать
multipart/form-datapass-through (не парсить → не пересобирать; стримить body) - Forward JWT кассира из
Authorizationheader
Расширить PATCH /admin/api/v1/stores/:id
- Поля
standby_idle_minutes/standby_transition_secondsтеперь принимаются и прокси-пасуются в Store Service
Admin Web (web/)
Sidebar
- В
components/layout/Layout.tsxдобавить новый TOP_ITEM:{ label: 'Маркетинг', path: '/marketing', icon: <PostersIcon />, permission: 'marketing.read' } - Permission-guard через существующий
usePermissionhook - Иконка — постер / picture (lucide-react или существующий пакет)
Pages
-
pages/marketing/StoreListPage.tsx— список ТТ с числом активных слайдов- Route
/marketing - Использует существующий API
GET /api/v1/stores - Для счётчика активных — N параллельных запросов
?active=true(или агрегат, если решим расширить Store API) - Если scope = 1 ТТ → авто-redirect на
/marketing/stores/{id}
- Route
-
pages/marketing/SlideListPage.tsx— список слайдов выбранной ТТ- Route
/marketing/stores/:storeId - Таблица (см. спеку): drag-handle / превью / title / source / active toggle / actions
- Drag-and-drop по образцу
TablesSection.tsx(ручной handler) - Кнопки: «Превью карусели», «Загрузить слайд», «Сгенерировать через AI» (заглушка)
- Empty state, лимит активных
- Route
-
components/marketing/UploadSlideModal.tsx— форма загрузки- File picker + drag-and-drop zone (по образцу PhotoStudioModal.tsx упрощённо)
- Валидация на лету: MIME, size, dimensions (через
new Image()+URL.createObjectURL) - POST multipart
-
components/marketing/EditSlideModal.tsx— редактирование- Pre-fill из props, PUT (json или multipart если меняется картинка)
- Кнопка «Удалить» с confirm
-
components/marketing/CarouselPreviewModal.tsx— preview карусели- Полноэкранная модалка с
<img>slideshow - Использует
standby_transition_secondsиз ответа API
- Полноэкранная модалка с
Stores
-
web/src/stores/marketingStore.ts(Zustand или существующий паттерн):slides: MarketingSlide[]actions:loadByStore,create,update,reorder,delete- Использует
marketingApi(см. ниже)
API client
-
web/src/api/marketing.ts:listSlides(storeId, activeFilter?)createSlide(storeId, file, title, active)— FormDataupdateSlide(storeId, slideId, payload)reorderSlides(storeId, orderArray)deleteSlide(storeId, slideId)
Карточка ТТ — поля standby
- В существующей странице
pages/stores/EditPage.tsxдобавить блок «Standby-режим» с двумя полями:standby_idle_minutes(input number, 1..60)standby_transition_seconds(input number, 3..60)- Disabled если нет
stores.editpermission
- PATCH использует существующий endpoint stores, прокси проброс работает через расширение admin-bff
AI-кнопка (заглушка для BR 6.2)
- Кнопка «✨ Сгенерировать через AI» —
disabled,title="Будет в BR 6.2 — AI-постер из Photo Studio" - При наведении — tooltip (можно через title или существующий tooltip-компонент)
Стили (Alfa Restyle)
- Применить токены из
lib/tokens.ts(см. скилл alfa-restyle) — после реализации функционала - Активный пункт сайдбара «Маркетинг» — красная линия слева (
colors.red) - Toggle-switch активности слайда — красный (
colors.red) - Chip «AI Photo Studio» —
colors.redSoftфон +colors.redтекст
Тесты
- Smoke-тесты Jest/Vitest для marketingStore
- Manual e2e на test VPS
Зависимости
- Store Service — деплой ДО админки
- User Service permissions — для
usePermissionгейтинга
Готово когда
- В сайдбаре виден пункт «Маркетинг» для пользователей с
marketing.read - Можно загрузить слайд через форму, увидеть его в списке
- Drag-and-drop работает — порядок сохраняется на бэке
- Кнопка «Превью карусели» открывает рабочий preview
- В карточке ТТ можно менять
standby_*поля - При деактивации слайда переходит вниз/исчезает из preview-карусели