History
1. Summary
Goal: Агрегация и отображение истории активности пользователя в TMA.
User Value: Пользователь видит свои последние действия — открытия кейсов, результаты рулеток, выводы скинов, выигрыши в розыгрышах.
2. Business Logic
Source Types
Домен объединяет данные из нескольких источников:
| Type | Описание | Источник данных |
|---|---|---|
DAILY_CASE | Бесплатный ежедневный кейс | case_openings |
PAID_CASE | Платный кейс | case_openings |
SPIN | Рулетка | spin_results |
RAFFLE | Выигрыш в розыгрыше | user_inventory (sourceType=RAFFLE_WIN) |
WITHDRAWAL | Вывод скина | withdrawals |
UI Filters
Дополнительные типы для фильтрации в интерфейсе:
| Filter | Включает |
|---|---|
CASE | DAILY_CASE + PAID_CASE |
ROULETTE | SPIN |
Rules
Read-only домен
История только читается — домен не изменяет данные. Записи создаются в соответствующих доменах (cases, streaks, inventory).
- Записи возвращаются по давности с настраиваемым лимитом (без фильтрации по дате)
- Максимум 500 записей за запрос (default в controller: 100, default в service/repo: 10)
- Сортировка по дате (новые сверху)
3. Architecture
Key Components
| Компонент | Путь | Описание |
|---|---|---|
| Controller | backend/src/domains/history/controllers/user-history.controller.ts | HTTP handlers |
| Service | backend/src/domains/history/services/history.service.ts | Business logic |
| Repository | backend/src/domains/history/repositories/history.repository.ts | Агрегация из 4 таблиц |
| Routes | backend/src/domains/history/routes/user-history.routes.ts | API endpoints |
| Schemas | backend/src/domains/history/schemas/user-history.schemas.ts | Swagger/validation schemas |
| Types | backend/src/domains/history/types/history.types.ts | Domain types (HistoryItem, HistoryFilters, RewardSnapshot) |
Data Flow
4. Database Schema
Source Tables
Домен не имеет собственных таблиц — агрегирует данные из:
| Таблица | Модель | Используемые поля |
|---|---|---|
case_openings | CaseOpening | id, userId, caseId, rewardSnapshot (Json), paidScrap (Int), openedAt + relations: case.name, case.imageUrl, case.caseType.isDailyFree |
spin_results | SpinResult | id, userId, rewardSnapshot (Json), spunAt + relations: spin.name, spin.priceScrap, spin.spinType.name |
user_inventory | UserInventory | id, userId, itemId, sourceType, acquiredAt + relations: item.tier, item.itemType |
withdrawals | Withdrawal | id, userId, itemId, status (enum: PENDING, PROCESSING, SENT, COMPLETED, FAILED, CANCELLED — history endpoint фильтрует до COMPLETED, FAILED, CANCELLED), requestedAt, completedAt + relations: item.name, item.imageUrl, item.tier, item.itemType |
5. API Endpoints
User API
| Метод | Эндпоинт | Описание |
|---|---|---|
| GET | /api/history/recent | Последние события пользователя |
Query Parameters
| Param | Type | Default | Описание |
|---|---|---|---|
type | enum | — | Фильтр по типу: DAILY_CASE, PAID_CASE, SPIN, RAFFLE, WITHDRAWAL, CASE (= DAILY_CASE + PAID_CASE), ROULETTE (= SPIN) |
caseId | string | — | Фильтр по конкретному кейсу |
limit | number | 100 | Лимит записей (1-500) |
Response Example
{
"success": true,
"data": [
{
"id": "clxyz...",
"sourceType": "PAID_CASE",
"sourceName": "Military Box",
"sourceImage": "https://...",
"caseId": "case-uuid",
"reward": {
"type": "ITEM",
"name": "AK-47 | Redline",
"itemId": "item-uuid",
"itemName": "AK-47 | Redline",
"itemImageUrl": "https://...",
"itemTier": "TIER_3",
"itemType": "SKIN"
},
"paidScrap": 150,
"timestamp": "2024-01-15T12:00:00.000Z"
}
]
}
6. Related
- Cases — источник DAILY_CASE, PAID_CASE
- Daily Spins — источник SPIN
- Inventory — источник RAFFLE
- Withdrawals — источник WITHDRAWAL