User Management
1. Summary
Goal: Полноценная админ-панель для управления пользователями goLoot — поиск, просмотр, модерация, управление балансами.
User Value: Администратор получает полный контроль над пользователями: от просмотра детальной статистики до управления банами и валютами.
2. Business Logic
Capabilities
- Search & Browse
- User Details
- Actions
- Game Stats
Таблица пользователей:
- Пагинация: 10/25/50/100 записей
- Поиск: по имени, username, Telegram ID
- Сортировка: дата регистрации, уровень, scrap, xp
- Фильтры: level (min/max), premium, banned, active, lastActivityDays
StatCards метрики:
- Всего пользователей
- Доступны для рассылки
- Premium пользователи
- Активные за 7 дней
- Новые за 24ч
- Забаненные
Детальная карточка (6 секций):
| Секция | Данные |
|---|---|
| Основное | ID, Telegram данные, статус регистрации, дата создания |
| Балансы | Scrap, XP, Level, Streak Points, breakdown по источникам |
| Статистика | Квесты, достижения, стрики, активность |
| Рефералы | Кто пригласил, кого пригласил, реферальный доход |
| Инвентарь | Предметы с изображениями, фильтр по tier |
| Выводы | История выводов скинов |
Модерация:
- Бан — с обязательной причиной (max 500 символов)
- Разбан — снятие бана
- Удаление — soft delete (
deletedAt+isActive = false), скрывает из списка админки
Управление валютами:
- Scrap — добавить/убрать (1..1,000,000)
- XP — добавить/убрать
- Streak Points — добавить/убрать
- Каждая операция требует причину (опционально)
История с пагинацией:
- История открытия кейсов
- История спинов рулетки
- Активные и завершённые квесты
- Полученные достижения
- История выводов
Services
| Сервис | Методы | Описание |
|---|---|---|
| UserCRUDService | getAllUsers, getUserDetailed, getUserStats, deleteUser | Основной CRUD + статистика для StatCards |
| UserActionsService | banUser, unbanUser, addScrap, removeScrap, addXP, removeXP, addStreakPoints, removeStreakPoints | Административные действия |
| UserInventoryStatsService | getUserInventory, getWithdrawals | Инвентарь и выводы |
| UserActivityStatsService | getCasesList, getSpinsList, getCaseHistory, getSpinHistory, getAllQuests, getAllAchievements | Справочники и история активности |
| UserCraftStatsService | getCraftHistory, getSalvageHistory | История крафта и salvage |
| UserRewardsStatsService | getPromoCodeRedemptions, getRaffleHistory, getSeasonRewards, getAdminGrants, getBuffHistory | Награды и баффы |
| UserSearchService | delegates to UserCRUDService | Обратная совместимость |
Constants
Backend константы
// backend/src/common/constants/admin-users.constants.ts
ADMIN_USERS_CONSTANTS = {
pagination: {
defaultLimit: 10,
maxLimit: 100
},
filters: {
levelMin: 1,
levelMax: 100,
lastActivityDays: [1, 7, 30, 90]
}
}
CURRENCY_LIMITS = {
min: 1,
max: 1_000_000
}
Protection
| Действие | Rate Limit | Auth | Validation |
|---|---|---|---|
| list users | adminApiLimiter (50/min) | admin | AdminUsersListQueryValidation |
| get stats | adminApiLimiter | admin | — |
| get details | adminApiLimiter | admin | UserIdParamValidation |
| ban user | adminApiLimiter | admin | BanUserBodyValidation |
| unban user | adminApiLimiter | admin | UserIdParamValidation |
| delete user | adminApiLimiter | admin | DeleteUserBodyValidation |
| manage currency | adminApiLimiter | admin | UpdateCurrencyBodyValidation |
| get inventory | adminApiLimiter | admin | UserInventoryQueryValidation |
| get histories | adminApiLimiter | admin | *HistoryQueryValidation |
Edge Cases
| Ситуация | Поведение |
|---|---|
| Пользователь не найден | HTTP 404, Prisma error handling |
| Невалидный amount | HTTP 400, валидация 1..1,000,000 |
| Убавление > баланса | Проверка текущего баланса перед операцией |
| Бан уже забаненного | Обновляется причина и дата |
| Удаление (soft delete) | deletedAt + isActive = false. Скрывается из списка админки, но продолжает иметь доступ к TMA (auth middleware не проверяет deletedAt) |
3. ADR (Architectural Decisions)
Почему UserSearchService делегирует к UserCRUDService?
Проблема: Дублирование логики поиска в двух сервисах.
Решение: UserSearchService стал wrapper, делегирующий все вызовы к UserCRUDService.
Последствия:
- DRY — единая точка логики
- Обратная совместимость — старые импорты продолжают работать
- Проще тестирование
Почему adminId = username?
Проблема: Нужно логировать кто выполнил действие, но JWT payload содержит username, не id.
Решение: Использовать request.user.username как adminId в логах.
Последствия:
bannedByхранит username админа- При переименовании админа — старые логи не обновятся
Три уровня управления доступом
| Уровень | Поля | Блокирует доступ к TMA? | Удаляет данные? |
|---|---|---|---|
| Бан | isBanned = true | Да — auth middleware проверяет | Нет |
| Soft Delete | deletedAt, isActive = false | Нет — auth middleware не проверяет deletedAt | Нет |
Full Reset (/stop) | Удаление связанных записей | Нет (аккаунт остаётся) | Да (инвентарь, квесты, история) |
Soft delete через админку не блокирует доступ пользователя к TMA. Auth middleware (telegram-auth.middleware.ts) проверяет только isBanned, но не deletedAt. Soft-deleted пользователь продолжает пользоваться приложением как обычно.
Если нужно заблокировать доступ — используй Бан, а не удаление.
Почему soft delete?
Проблема: Полное удаление пользователя потеряет данные для аналитики.
Решение: Soft delete через deletedAt + isActive = false.
Что делает:
- Устанавливает
deletedAt = now()иisActive = false - Скрывает пользователя из списка в админке
- Данные сохраняются для аналитики
- Можно восстановить при необходимости
Чего НЕ делает:
- Не блокирует доступ к TMA (auth middleware не проверяет
deletedAt) - Не удаляет данные пользователя
- Не отвязывает Steam аккаунт
Почему UserGameStatsService разделён на 4 сервиса?
Проблема: UserGameStatsService вырос до 1,408 строк и 19 методов — God Object антипаттерн.
Решение: Разделение по доменам:
UserInventoryStatsService— инвентарь, выводыUserActivityStatsService— кейсы, спины, квесты, достиженияUserCraftStatsService— крафт, salvageUserRewardsStatsService— промокоды, розыгрыши, награды, баффы
Последствия:
- Каждый сервис ≤500 строк
- Чёткая ответственность по домену
- Проще тестировать (19 unit-тестов для критичных методов)
- API остаётся неизменным — рефакторинг прозрачен для фронтенда
4. Architecture
Services Overview
Key Components
| Компонент | Путь | Описание |
|---|---|---|
| UserCRUDService | backend/src/domains/admin/services/user-crud.service.ts | CRUD операции + статистика |
| UserActionsService | backend/src/domains/admin/services/user-actions.service.ts | Бан, валюты |
| UserInventoryStatsService | backend/src/domains/admin/services/user-stats/user-inventory-stats.service.ts | Инвентарь, выводы |
| UserActivityStatsService | backend/src/domains/admin/services/user-stats/user-activity-stats.service.ts | Кейсы, спины, квесты, достижения |
| UserCraftStatsService | backend/src/domains/admin/services/user-stats/user-craft-stats.service.ts | Крафт, salvage |
| UserRewardsStatsService | backend/src/domains/admin/services/user-stats/user-rewards-stats.service.ts | Промокоды, розыгрыши, награды, баффы |
| UserSearchService | backend/src/domains/admin/services/user-search.service.ts | Wrapper для совместимости |
| Routes | backend/src/domains/admin/routes/admin-users.routes.ts | 15+ API endpoints |
| Validation Schemas | backend/src/common/schemas/admin-users-validation.schemas.ts | JSON Schema валидация |
| Types | backend/src/common/types/admin-users.types.ts | TypeScript типы |
| Constants | backend/src/common/constants/admin-users.constants.ts | Лимиты, фильтры |
| Ban Middleware | backend/src/common/middleware/ban-check.middleware.ts | Проверка бана |
Frontend Components
| Компонент | Путь | Описание |
|---|---|---|
| Users.tsx | admin/src/pages/Users.tsx | Главная страница |
| UsersTable | admin/src/components/users/UsersTable.tsx | Таблица с пагинацией |
| UserDetailsModal | admin/src/components/users/UserDetailsModal.tsx | Детальная карточка |
| BanUserModal | admin/src/components/users/modals/BanUserModal.tsx | Модалка бана |
| UnbanConfirmModal | admin/src/components/users/modals/UnbanConfirmModal.tsx | Подтверждение разбана |
| DeleteUserModal | admin/src/components/users/modals/DeleteUserModal.tsx | Удаление с подтверждением |
| ManageCurrencyModal | admin/src/components/users/modals/ManageCurrencyModal.tsx | Управление валютами |
5. Database Schema
Ban & Delete Fields on User
| Поле | Тип | Описание |
|---|---|---|
isBanned | Boolean | Флаг бана (default: false). Проверяется auth middleware |
bannedAt | DateTime? | Когда забанен |
banReason | String? | Причина бана (max 500 chars) |
bannedBy | String? | Username админа |
deletedAt | DateTime? | Когда удалён (soft delete). Не проверяется auth middleware |
isActive | Boolean | Флаг активности (default: true). Устанавливается в false при soft delete |
Indexes
@@index([isBanned])
@@index([bannedAt])
Related Models
| Модель | Использование |
|---|---|
| User | Основные данные + ban fields |
| UserInventory | Инвентарь пользователя |
| CaseOpening | История кейсов |
| SpinResult | История спинов |
| UserQuest | Квесты |
| UserAchievement | Достижения |
| Withdrawal | История выводов |
| Referral | Реферальные связи |
6. API Endpoints
Admin API (15 endpoints)
- Basic
- Actions
- Currency
- Game Stats
| Метод | Эндпоинт | Описание |
|---|---|---|
| GET | /admin/users | Список с фильтрами и пагинацией |
| GET | /admin/users/stats | Статистика для StatCards |
| GET | /admin/users/:userId | Детальная информация |
| GET | /admin/users/search | Поиск (legacy) |
| Метод | Эндпоинт | Описание |
|---|---|---|
| POST | /admin/users/:userId/ban | Забанить пользователя |
| DELETE | /admin/users/:userId/ban | Разбанить пользователя |
| DELETE | /admin/users/:userId | Удалить (soft delete) |
| Метод | Эндпоинт | Описание |
|---|---|---|
| POST | /admin/users/:userId/scrap | Добавить/убрать Scrap |
| POST | /admin/users/:userId/xp | Добавить/убрать XP |
| POST | /admin/users/:userId/streak-points | Добавить/убрать SP |
| Метод | Эндпоинт | Описание |
|---|---|---|
| GET | /admin/users/:userId/inventory | Инвентарь с фильтром по tier |
| GET | /admin/users/:userId/case-history | История открытия кейсов |
| GET | /admin/users/:userId/spin-history | История спинов |
| GET | /admin/users/:userId/quests | Квесты (фильтр по status) |
| GET | /admin/users/:userId/achievements | Достижения (фильтр по status) |
| GET | /admin/users/:userId/withdrawals | История выводов |
Request/Response Examples
GET /admin/users
Query params:
- page: number (default 1)
- limit: number (default 10, max 100)
- sortBy: 'createdAt' | 'level' | 'scrap' | 'xp'
- sortOrder: 'asc' | 'desc'
- search: string (name, username, telegramId)
- levelMin, levelMax: number
- isPremium, isBanned, isActive: boolean
- lastActivityDays: number
POST /admin/users/:userId/ban
{
"reason": "Нарушение правил платформы"
}
POST /admin/users/:userId/scrap
{
"amount": 1000,
"reason": "Компенсация за баг"
}
// amount > 0 = добавить
// amount < 0 = убрать
7. Admin Guide
Доступ к панели пользователей
- Войти в Admin Panel
- Выбрать в меню раздел "Пользователи"
Просмотр списка
- Статистика отображается в StatCards над таблицей
- Поиск по имени, нику или Telegram ID
- Сортировка по колонкам таблицы
- Пагинация внизу таблицы
Детальная информация
- Нажать на строку пользователя
- Откроется модальное окно с секциями
Управление валютами
- Открыть детали пользователя
- Нажать кнопку "Scrap" / "XP" / "SP"
- Выбрать операцию: добавить или убрать
- Указать сумму (1 - 1,000,000) и причину
- Подтвердить
Бан пользователя
- Открыть детали пользователя
- Нажать "Забанить"
- Указать причину (обязательно, max 500 символов)
- Подтвердить
Забаненный пользователь не сможет войти в TMA и получать уведомления от бота.
Разбан
- Открыть детали забаненного пользователя
- Нажать "Разбанить"
- Подтвердить
Удаление пользователя
- Открыть детали пользователя
- Нажать "Удалить"
- Поставить галочку подтверждения
- Подтвердить
Удаление устанавливает deletedAt и isActive = false. Пользователь скрывается из списка админки, данные сохраняются для аналитики.
Важно: Пользователь продолжит иметь доступ к TMA после soft delete. Для блокировки доступа используй Бан.
8. Dashboard & Analytics
Админ-панель включает дашборд с ключевыми метриками платформы.
Dashboard Stats
| Метрика | Описание | Сервис |
|---|---|---|
| Sent Withdrawals | Выводы, ожидающие принятия (статус SENT) | DashboardStatsService |
| Active Season Users | Пользователи с активностью в текущем сезоне | DashboardStatsService |
| Total Withdrawn (RUB) | Сумма всех выведенных скинов | DashboardStatsService |
| Scrap in Circulation | Общий баланс Scrap у всех пользователей | DashboardStatsService |
Charts & Analytics
| Компонент | Описание | Сервис |
|---|---|---|
| User Analytics | DAU, MAU, retention, когорты | UserAnalyticsService |
| UTM Analytics | Конверсии по источникам трафика | UniversalChartService |
| Revenue Charts | Графики экономики | UnifiedChartEngineService |
Key Components
| Компонент | Путь | Описание |
|---|---|---|
| DashboardStatsService | backend/src/domains/admin/services/dashboard-stats.service.ts | Ключевые метрики |
| UserAnalyticsService | backend/src/domains/admin/services/user-analytics.service.ts | Аналитика пользователей |
| UnifiedChartEngineService | backend/src/domains/admin/services/unified-chart-engine.service.ts | Универсальный движок графиков |
| Admin Analytics Routes | backend/src/domains/admin/routes/admin-analytics.routes.ts | API эндпоинты |
| Admin Charts Routes | backend/src/domains/admin/routes/admin-charts.routes.ts | API графиков |
API Endpoints
| Метод | Эндпоинт | Описание |
|---|---|---|
| GET | /admin/analytics/dashboard | Метрики дашборда |
| GET | /admin/analytics/banners | Аналитика баннеров |
| GET | /admin/analytics/banners/metrics | Метрики баннеров |
| GET | /admin/analytics/push | Аналитика push-уведомлений |
| GET | /admin/analytics/referrals | Статистика рефералов |
| GET | /admin/analytics/referrals/admin | Детальная статистика рефералов |
| GET | /admin/analytics/export/referrals | Экспорт рефералов |
| GET | /admin/analytics/users/registration | Статистика регистраций |
| GET | /admin/analytics/bot-blocks | Блокировки бота |
| GET | /admin/charts/* | Универсальные графики (UTM, revenue, etc.) |
9. Related
- Profile — профиль пользователя (User API)
- Settings — настройки пользователя
- Feedback — тикеты пользователей
- UTM Tracking — источники трафика
- Security Matrix — обзор защит