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)и APIMAJOR.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/ws→http://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; учёткиSMOKE_ADMIN_*/ADMIN_SUPER_*изEventHubDevOps/ift/.env; workflowe2e-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.