Files
EventHubSpec/EventHubFrontAdminSpec.md
T

21 KiB

EventHub Admin UI — Техническое задание (актуальная версия)

1. Роли и права доступа

Роль Идентификатор Права
Суперадмин superadmin Полный доступ ко всем модулям, включая изменение ролей других админов, просмотр аудита, системные настройки, управление администраторами.
Администратор admin Управление пользователями, событиями, жалобами, отзывами, бан-словами, тикетами, подписками. Нет доступа к аудиту и управлению администраторами.
Модератор moderator Работа с жалобами и отзывами. Остальные разделы недоступны.
Поддержка support Работа с тикетами (баг-трекер). Остальные разделы недоступны.

Права проверяются на уровне фронтенда: пункты меню и маршруты (RoleGuard в App.tsx, конфиг src/config/adminAccess.ts) ограничены по роли из GET /v1/admin/me; при прямом URL без прав — страница 403.

2. Аутентификация и авторизация

Эндпоинты:

  • POST /v1/admin/login — вход (email, пароль). Возвращает { token, refresh_token, user }.
  • POST /v1/refresh — обновление access-токена по refresh-токену.
  • GET /v1/admin/me — данные текущего администратора, включая роль.

Реализация:

  • JWT-токены сохраняются в localStorage.
  • Axios-интерсептор добавляет Authorization: Bearer <token> ко всем запросам.
  • При получении 401 автоматически пытается обновить токен через /v1/refresh. Если обновление не удалось — редирект на страницу входа.
  • При перезагрузке страницы токен проверяется через GET /v1/admin/me. Если токен валиден, сессия восстанавливается без повторного входа.

3. Технологический стек

  • Язык: TypeScript
  • Сборщик: Vite
  • UI-фреймворк: React 18 + Ant Design 5
  • Управление состоянием: Zustand (аутентификация), TanStack React Query v5 (серверное состояние)
  • HTTP-клиент: Axios с интерсепторами
  • Формы и валидация: React Hook Form + Zod
  • Графики: Recharts
  • Дата и время: dayjs с русской локалью
  • Интернационализация: react-i18next (русский, английский)
  • Роутинг: React Router v6
  • WebSocket: нативное WebSocket API с автоматическим переподключением
  • Контейнеризация: Docker, Nginx, Traefik

4. Модули панели

4.1. Дашборд (Dashboard)

Эндпоинт: GET /v1/admin/stats

Виджеты:

  • Карточки с метриками: пользователи, события, отзывы, календари, жалобы, тикеты (всего и открытых), среднее время решения.
  • Мини-графики (спарклайны) в карточках «Пользователи» и «События» — динамика по дням с плавной заливкой.
  • Графики «События по дням» и «Регистрации по дням» на основе данных events_by_day и registrations_by_day.
  • Таблица «Активность администраторов» с сортировкой по убыванию числа действий, раскрашенными ролями, форматированной датой последнего входа, заменой пустых значений на прочерк.

4.2. Управление пользователями

Эндпоинты: GET /v1/admin/users, GET /v1/admin/users/:id, PUT /v1/admin/users/:id, DELETE /v1/admin/users/:id

Функциональность:

  • Список с серверной пагинацией и сортировкой по всем столбцам.
  • Первая колонка — иконка для перехода на детальную страницу.
  • Роли и статусы раскрашены (user — синий, bot — фиолетовый; active — зелёный, frozen — оранжевый, deleted — красный).
  • Модальное окно редактирования: email, ник, роль, статус, причина. Обязательные поля подсвечиваются, кнопка «Сохранить» неактивна при пустых обязательных полях. Пустые строки не отправляются на сервер.
  • Кнопка «Заморозить/Разморозить» открывает модальное окно с обязательной причиной при заморозке. Подгружается текущая причина, если она была.
  • Кнопка «Удалить» открывает диалог подтверждения.
  • Для удалённых пользователей (status=deleted) кнопки «Заморозить/Разморозить» и «Удалить» неактивны, кнопка «Редактировать» активна.
  • Детальная страница пользователя: все поля из API, включая телефон, язык, часовой пояс, аватар URL, соцсети, настройки, даты создания/обновления. Пустые значения заменены на прочерк. Даты отформатированы.

4.3. Управление событиями

Эндпоинты: GET /v1/admin/events, GET /v1/admin/events/:id, PUT /v1/admin/events/:id, DELETE /v1/admin/events/:id

Функциональность:

  • Список с серверной пагинацией и сортировкой.
  • Первая колонка — иконка для перехода на детальную страницу.
  • Типы событий раскрашены (single — синий, recurring — фиолетовый).
  • Статусы раскрашены (active — зелёный, cancelled — красный, completed — серый).
  • Модальное окно редактирования: название, описание, тип, статус, дата и время начала (DatePicker), продолжительность, вместимость, специалист ID, календарь ID, ссылка онлайн, теги. Валидация обязательных полей.
  • Кнопки «Редактировать» и «Удалить» с иконками.
  • Детальная страница события: все поля из API (название, описание, тип, статус, причина, дата начала, продолжительность, вместимость, специалист, календарь, мастер-событие, онлайн-ссылка, теги, рейтинг, вложения, история изменений, повторение, локация, является экземпляром, даты создания/обновления). ID-поля (специалист → пользователь, мастер → событие) оформлены как кликабельные ссылки. Статус и тип раскрашены.

4.4. Жалобы (Reports)

Эндпоинты: GET /v1/admin/reports, GET /v1/admin/reports/:id, PUT /v1/admin/reports/:id

Функциональность:

  • Список с серверной пагинацией и сортировкой.
  • Первая колонка — иконка для перехода на детальную страницу.
  • Резолвинг отправителя: если нет ника — показывается email (ссылка на профиль пользователя).
  • Колонка «Тип» раскрашена (event — синий, calendar — зелёный, review — фиолетовый).
  • Колонка «Цель» — кликабельная ссылка с названием (для событий) или ID.
  • Быстрый просмотр в модальном окне: ID, отправитель (ссылка с ником/email), тип цели, цель (ссылка с названием для событий), причина, статус, дата создания, дата решения, кем решено (ссылка на админа с ником/email). В модалке кнопки «Рассмотрено» и «Отклонено» для жалоб в статусе pending.
  • Детальная страница жалобы: все поля с возможностью принять решение (кнопки «Рассмотрено» и «Отклонено»).

4.5. Отзывы (Reviews)

Эндпоинты: GET /v1/admin/reviews, GET /v1/admin/reviews/:id, PUT /v1/admin/reviews/:id, PATCH /v1/admin/reviews

Функциональность:

  • Список с серверной пагинацией и сортировкой.
  • Возможность выбора нескольких отзывов для массового изменения статуса (скрыть, показать, удалить) с обязательной причиной при скрытии/удалении.
  • Первая колонка — иконка для перехода на детальную страницу.
  • Резолвинг пользователя (никнейм → email → ID) и цели (название события).
  • Оценка отображается звёздами.
  • Статусы раскрашены (visible — зелёный, hidden — оранжевый, deleted — красный).
  • Тип цели раскрашен (event — синий, calendar — зелёный).
  • Модальное окно редактирования: оценка, комментарий, статус, причина (обязательна при скрытии/удалении).
  • Детальная страница отзыва: все поля, кнопки изменения статуса с причиной.

4.6. Бан-слова (Banned Words)

Эндпоинты: GET /v1/admin/banned-words, POST /v1/admin/banned-words, DELETE /v1/admin/banned-words/:word

Функциональность:

  • Список с серверной пагинацией, сортировкой и поиском.
  • Резолвинг поля «Кем добавлено» (ссылка на администратора с ником/email).
  • Дата добавления отформатирована.
  • Форма добавления нового слова и кнопка удаления с подтверждением.

4.7. Тикеты (баг-трекер)

Эндпоинты: GET /v1/admin/tickets, GET /v1/admin/tickets/stats, GET /v1/admin/tickets/:id, PUT /v1/admin/tickets/:id, DELETE /v1/admin/tickets/:id

Функциональность:

  • Статистика вверху: открыто, в работе, решено, закрыто.
  • Список с серверной пагинацией и сортировкой.
  • Первая колонка — иконка для перехода на детальную страницу.
  • Резолвинг назначенного администратора (ссылка с ником/email).
  • Статусы раскрашены (open — красный, in_progress — синий, resolved — зелёный, closed — серый).
  • Детальная страница: все поля тикета, отправитель как ссылка на пользователя, назначенный администратор как ссылка, форма изменения статуса с выбором администратора из списка (email — ник).
  • Кнопка удаления с подтверждением.

4.8. Подписки (Subscriptions)

Эндпоинты: GET /v1/admin/subscriptions, GET /v1/admin/subscriptions/:id, PUT /v1/admin/subscriptions/:id, DELETE /v1/admin/subscriptions/:id

Функциональность:

  • Список с серверной пагинацией и сортировкой.
  • Резолвинг пользователя (никнейм → email → ID) со ссылкой.
  • Планы раскрашены (trial — голубой, monthly — синий, quarterly — зелёный, biannual — фиолетовый, annual — оранжевый).
  • Статусы раскрашены (active — зелёный, expired — оранжевый, cancelled — красный).
  • Даты отформатированы.
  • Модальное окно редактирования: план, статус, пробный период, дата окончания (DatePicker). Данные подгружаются с сервера.

4.9. Управление администраторами

Эндпоинты: GET /v1/admin/admins, GET /v1/admin/admins/:id, POST /v1/admin/admins, PUT /v1/admin/admins/:id, DELETE /v1/admin/admins/:id

Функциональность:

  • Список с серверной пагинацией и сортировкой.
  • Первая колонка — иконка для перехода на детальную страницу.
  • Роли раскрашены (superadmin — красный, admin — синий, moderator — фиолетовый, support — голубой).
  • Статусы раскрашены (active — зелёный, blocked — красный).
  • Модальное окно создания: email, пароль, роль.
  • Модальное окно редактирования: ник, email, роль, статус, часовой пояс (выпадающий список), язык (русский/английский), телефон.
  • Кнопки «Редактировать» и «Удалить» с иконками.
  • Детальная страница администратора: все поля с раскрашенными ролью и статусом.

4.10. Аудит (Audit)

Эндпоинт: GET /v1/admin/audit

Функциональность:

  • Список с серверной пагинацией и сортировкой.
  • Резолвинг администратора (ссылка с ником/email).
  • Роль раскрашена.
  • Действие раскрашено (create, update, delete, freeze, unfreeze, block, unblock, hide, unhide, login, logout и др.).
  • Тип сущности раскрашен (user, event, calendar, review, report, ticket, subscription, admin).
  • Наименование сущности: для user — ник/email (ссылка), для event — название (ссылка), для review — ссылка на отзыв, для остальных — ID.
  • Фильтры: администратор (выпадающий список с поиском), действие (выпадающий список уникальных действий), диапазон дат.
  • Дата отформатирована.

4.11. Профиль текущего администратора

Эндпоинты: использует данные из useAuthStore().user, редактирование через PUT /v1/admin/admins/:id

Функциональность:

  • Просмотр всех полей профиля: email, ник, роль, статус, часовой пояс, язык, телефон, аватар URL, настройки (JSON), последний вход.
  • Пустые значения заменены на прочерк, дата отформатирована.
  • Кнопка «Редактировать» доступна только для superadmin. При редактировании можно изменить ник, часовой пояс, язык, телефон, URL аватара, настройки (с валидацией JSON).
  • Доступен всем ролям, страница открывается из виджета профиля в боковом меню.

5. Real-time уведомления (WebSocket)

Эндпоинт: wss://<домен>/admin/ws?token=<jwt>

Функциональность:

  • При входе устанавливается WebSocket-соединение; при logout или смене accessToken сокет явно закрывается, reconnect отменяется, метрики в store сбрасываются.
  • Подписка на каналы reports и tickets.
  • При получении сообщения { type: "report_created" } или { type: "ticket_created" } показывается уведомление со ссылкой на соответствующую страницу.
  • Автоматическое переподключение при разрыве соединения.
  • Защита от дубликатов по timestamp.

6. Интерфейс

  • Боковое меню (сайдбар) с пунктами, доступными в соответствии с ролью.
  • В нижней части сайдбара — виджет профиля текущего администратора с аватаром и именем (ник или email). При клике открывается меню «Мой профиль» и «Выйти». Кнопка сворачивания сайдбара находится в этой же панели.
  • Верхняя панель содержит моки оперативной статистики (онлайн, заказов сегодня, тикетов) — в будущем будут заменены на реальные данные.
  • В меню профиля (аватар в header): «Мой профиль», язык UI, Admin MAJOR.MINOR (sha) и API MAJOR.MINOR (sha) (API — из GET /v1/admin/health), «Выйти».
  • Все даты в интерфейсе русифицированы (dayjs с русской локалью; i18n ru/en).
  • Единая нормализация данных: пустые значения (null, undefined, "undefined", "-") заменяются на прочерк, даты приводятся к читаемому формату. Нормализация применяется централизованно в хуках списков; для форм редактирования используются сырые данные.
  • Все таблицы имеют серверную пагинацию и сортировку через заголовок X-Total-Count.

7. Развёртывание

  • Product version: файл VERSION (MAJOR.MINOR); в CI bake как VITE_APP_*. Образы: sha-<12> + floating :ift / :stage (см. EventHubSpec/WORKFLOW.md §6).
  • Production-сборка: npm run build → папка dist/.
  • Docker-образ на основе Nginx Alpine.
  • Контейнер подключается к сети eventhub_network.
  • Traefik маршрутизирует домен admin-ui.stage.eventhub.local на контейнер.
  • Nginx внутри контейнера раздаёт статику и проксирует API-запросы (/v1/http://eventhub:8445, /admin/wshttp://eventhub:8446), что позволяет избежать проблем с CORS и самоподписанными сертификатами.
  • WebSocket также проксируется через Nginx.
  • Makefile автоматизирует установку, сборку, запуск и очистку проекта.

8. E2E (Playwright)

  • Каркас: playwright.config.ts, каталог e2e/.
  • Контракт селекторов: e2e/TESTIDS.md (data-testid + a11y).
  • Mock-suite (npm run test:e2e): в CI после lint/build; route-моки **/v1/admin/**.
  • IFT smoke (npm run test:e2e:ift): login → shell → logout против IFT; secrets E2E_ADMIN_*; workflow e2e-ift.yml после Deploy IFT.
  • Coverage (mock): auth/roles, shell, inbox reports/tickets, reports/reviews CRUD-пути, explore users/calendars/events/subscriptions, banned-words, admins/audit/monitoring/profile, i18n.