Files
marketplace/отчеты/отчет-реализация.md
delta-lynx-89e8 dbbbbd26f4 Add rental system: listings, bookings, payments, payouts, reviews
Full rental marketplace with 6 categories (apartment, house, car, motorcycle, bicycle, ebike).
Booking workflow: create → confirm → pay → active → complete → payout.
Landlord dashboard, admin moderation, availability calendar, Stripe Connect payouts.
14 QA bugs found and fixed including validator schemas, API response types, HTTP methods.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 15:33:29 -08:00

320 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Отчёт о реализации: Админ-панель, Модерация, Монетизация
**Дата**: 22 февраля 2026
**Проект**: Marketplace
**Статус**: Реализовано, собрано, мигрировано, seed обновлён
---
## Общий объём работ
- **29 новых файлов** создано
- **13 существующих файлов** модифицировано
- **42 файла** затронуто суммарно
- **1 новая зависимость** (`recharts`) установлена
- **1 миграция БД** применена (`admin_moderation_monetization`)
---
## Новые серверные файлы (16)
| # | Файл | Назначение | Статус |
|---|---|---|---|
| 1 | `server/src/middleware/requireRole.ts` | RBAC middleware — `requireModerator`, `requireAdmin`, `requireSuperAdmin` | Готово |
| 2 | `server/src/middleware/checkBanned.ts` | Проверка бана пользователя (403) | Готово |
| 3 | `server/src/utils/moderation.ts` | Кэш PlatformConfig (60с), проверка blockedKeywords | Готово |
| 4 | `server/src/routes/admin/index.ts` | Агрегатор всех админ-роутов с authenticate | Готово |
| 5 | `server/src/routes/admin/stats.ts` | GET /api/admin/stats — дашборд-аналитика | Готово |
| 6 | `server/src/routes/admin/users.ts` | CRUD юзеров, бан/разбан, смена ролей | Готово |
| 7 | `server/src/routes/admin/listings.ts` | Approve/reject листингов, featured, force delete | Готово |
| 8 | `server/src/routes/admin/reports.ts` | Управление жалобами — список, детали, resolve/dismiss | Готово |
| 9 | `server/src/routes/admin/moderation.ts` | Очередь PENDING_REVIEW + лог модерации | Готово |
| 10 | `server/src/routes/admin/payments.ts` | Все платежи + revenue breakdown по типам | Готово |
| 11 | `server/src/routes/admin/settings.ts` | CRUD PlatformConfig с инвалидацией кэша | Готово |
| 12 | `server/src/routes/report.ts` | POST /api/reports — создание жалобы юзером | Готово |
| 13 | `server/src/routes/subscription.ts` | Подписки: current, create, cancel | Готово |
| 14 | `server/src/routes/promotion.ts` | Продвижение листингов: promote, get status | Готово |
| 15 | `server/src/validators/admin.ts` | Zod-схемы: ban, role, reject, resolve, settings | Готово |
| 16 | `server/src/validators/report.ts` | Zod-схема создания жалобы | Готово |
---
## Новые клиентские файлы (13)
| # | Файл | Назначение | Статус |
|---|---|---|---|
| 17 | `client/src/components/layout/RequireRole.tsx` | Route guard по роли пользователя | Готово |
| 18 | `client/src/components/layout/AdminLayout.tsx` | Sidebar-layout админки с навигацией | Готово |
| 19 | `client/src/components/ui/StatCard.tsx` | Карточка метрики (иконка, число, цвет) | Готово |
| 20 | `client/src/components/ui/DataTable.tsx` | Переиспользуемая таблица с поиском и пагинацией | Готово |
| 21 | `client/src/components/ReportModal.tsx` | Модалка жалобы с радиокнопками причин | Готово |
| 22 | `client/src/pages/admin/AdminDashboardPage.tsx` | Дашборд: 5 метрик + Quick Stats + Health | Готово |
| 23 | `client/src/pages/admin/AdminUsersPage.tsx` | Таблица юзеров с поиском и навигацией | Готово |
| 24 | `client/src/pages/admin/AdminUserDetailPage.tsx` | Детали юзера: профиль, статы, бан, роль, история | Готово |
| 25 | `client/src/pages/admin/AdminListingsPage.tsx` | Таблица листингов с табами по статусу | Готово |
| 26 | `client/src/pages/admin/AdminReportsPage.tsx` | Жалобы с табами + модалка resolve/dismiss | Готово |
| 27 | `client/src/pages/admin/AdminModerationPage.tsx` | Очередь модерации — карточки с approve/reject | Готово |
| 28 | `client/src/pages/admin/AdminPaymentsPage.tsx` | 4 StatCard выручки + таблица транзакций | Готово |
| 29 | `client/src/pages/admin/AdminSettingsPage.tsx` | Форма настроек: fees, limits, moderation | Готово |
---
## Модифицированные файлы (13)
| # | Файл | Что изменено | Статус |
|---|---|---|---|
| 30 | `server/prisma/schema.prisma` | 8 новых enum, 6 новых моделей, 3 модели расширены | Готово |
| 31 | `server/prisma/seed.ts` | + PlatformConfig, + роли (alice=SA, bob=A, carol=M), + cleanup новых таблиц | Готово |
| 32 | `server/src/index.ts` | + 4 новых route group: reports, subscriptions, promotions, admin | Готово |
| 33 | `server/src/middleware/auth.ts` | + `userRole?: string` в Request type | Готово |
| 34 | `server/src/routes/auth.ts` | + `role` в select (3 места), + проверка `isBanned` при логине | Готово |
| 35 | `server/src/routes/listing.ts` | + autoApprove check, + blockedKeywords check, + isFeatured в select | Готово |
| 36 | `server/src/routes/payment.ts` | + динамический listingFee из PlatformConfig, + type: LISTING_FEE | Готово |
| 37 | `server/src/routes/offer.ts` | + создание Commission payment при ACCEPTED | Готово |
| 38 | `client/src/types/index.ts` | + role в User, + PENDING_REVIEW, + новые NotificationType, + 5 новых интерфейсов | Готово |
| 39 | `client/src/context/AuthContext.tsx` | + isAdmin, isModerator, isSuperAdmin | Готово |
| 40 | `client/src/router.tsx` | + /admin/* routes (8 маршрутов) | Готово |
| 41 | `client/src/components/layout/Header.tsx` | + ссылка "Admin" с иконкой Shield | Готово |
| 42 | `client/src/pages/ProductDetailPage.tsx` | + ReportModal вместо alert() | Готово |
| + | `client/src/pages/NotificationsPage.tsx` | + иконки и цвета для 6 новых NotificationType | Готово |
---
## Схема БД — новые enum'ы
```
UserRole: USER | MODERATOR | ADMIN | SUPER_ADMIN
ReportReason: SPAM | INAPPROPRIATE | SCAM | COUNTERFEIT | PROHIBITED_ITEM | HARASSMENT | OTHER
ReportStatus: OPEN | REVIEWING | RESOLVED | DISMISSED
ReportTargetType: LISTING | USER
SubscriptionTier: BASIC | PRO | BUSINESS
SubscriptionStatus: ACTIVE | CANCELLED | EXPIRED | PAST_DUE
PaymentType: LISTING_FEE | COMMISSION | PROMOTION | SUBSCRIPTION
ModerationAction: APPROVED | REJECTED | WARNING | BAN | UNBAN | LISTING_DELETED | LISTING_FEATURED
```
---
## Схема БД — новые модели
### Report
```
id, reporterId → User, targetType (LISTING|USER), targetId, reason, description?,
status (OPEN→REVIEWING→RESOLVED|DISMISSED), resolvedBy?, resolution?
```
### PlatformConfig (singleton)
```
listingFee ($5), commissionPercent (5%), autoApprove (true),
maxImagesPerListing (6), maxListingsFreeTier (5),
proPrice ($9.99), businessPrice ($29.99), promotionDayPrice ($2.99),
blockedKeywords []
```
### Subscription
```
userId (unique) → User, tier (BASIC|PRO|BUSINESS), status,
stripeSubscriptionId?, currentPeriodEnd?
```
### PromotedListing
```
listingId (unique) → Listing, userId → User, startDate, endDate,
amountPaid, isActive
```
### ModerationLog
```
moderatorId → User, targetUserId?, targetListingId?,
action (ModerationAction), reason?, details (Json?)
```
---
## API Endpoints — полный список
### Admin Stats
| Method | Path | Доступ |
|---|---|---|
| GET | `/api/admin/stats` | MODERATOR+ |
| GET | `/api/admin/stats/revenue` | ADMIN+ |
| GET | `/api/admin/stats/users` | ADMIN+ |
| GET | `/api/admin/stats/listings` | MODERATOR+ |
### Admin Users
| Method | Path | Доступ |
|---|---|---|
| GET | `/api/admin/users` | MODERATOR+ |
| GET | `/api/admin/users/:id` | MODERATOR+ |
| PATCH | `/api/admin/users/:id/role` | SUPER_ADMIN |
| POST | `/api/admin/users/:id/ban` | ADMIN+ |
| POST | `/api/admin/users/:id/unban` | ADMIN+ |
### Admin Listings
| Method | Path | Доступ |
|---|---|---|
| GET | `/api/admin/listings` | MODERATOR+ |
| POST | `/api/admin/listings/:id/approve` | MODERATOR+ |
| POST | `/api/admin/listings/:id/reject` | MODERATOR+ |
| DELETE | `/api/admin/listings/:id` | ADMIN+ |
| POST | `/api/admin/listings/:id/feature` | ADMIN+ |
### Admin Reports
| Method | Path | Доступ |
|---|---|---|
| GET | `/api/admin/reports` | MODERATOR+ |
| GET | `/api/admin/reports/:id` | MODERATOR+ |
| PATCH | `/api/admin/reports/:id` | MODERATOR+ |
### Admin Moderation
| Method | Path | Доступ |
|---|---|---|
| GET | `/api/admin/moderation/queue` | MODERATOR+ |
| GET | `/api/admin/moderation/logs` | ADMIN+ |
### Admin Payments
| Method | Path | Доступ |
|---|---|---|
| GET | `/api/admin/payments` | ADMIN+ |
| GET | `/api/admin/payments/revenue` | ADMIN+ |
### Admin Settings
| Method | Path | Доступ |
|---|---|---|
| GET | `/api/admin/settings` | ADMIN+ |
| PATCH | `/api/admin/settings` | SUPER_ADMIN |
### User Reports
| Method | Path | Доступ |
|---|---|---|
| POST | `/api/reports` | Авторизованный |
### Subscriptions
| Method | Path | Доступ |
|---|---|---|
| GET | `/api/subscriptions/current` | Авторизованный |
| POST | `/api/subscriptions/create` | Авторизованный |
| POST | `/api/subscriptions/cancel` | Авторизованный |
### Promotions
| Method | Path | Доступ |
|---|---|---|
| POST | `/api/listings/:id/promote` | Авторизованный |
| GET | `/api/listings/:id/promotion` | Авторизованный |
---
## Роли и права
| Действие | USER | MODERATOR | ADMIN | SUPER_ADMIN |
|---|---|---|---|---|
| Просмотр дашборда | - | + | + | + |
| Просмотр юзеров | - | + | + | + |
| Бан/разбан | - | - | + | + |
| Смена роли | - | - | - | + |
| Approve/Reject листинг | - | + | + | + |
| Force delete листинг | - | - | + | + |
| Feature листинг | - | - | + | + |
| Управление жалобами | - | + | + | + |
| Просмотр платежей | - | - | + | + |
| Настройки платформы (чтение) | - | - | + | + |
| Настройки платформы (запись) | - | - | - | + |
| Создание жалобы | + | + | + | + |
| Подписки | + | + | + | + |
| Продвижение | + | + | + | + |
---
## Тестовые данные (seed)
### Пользователи с ролями
| Пользователь | Email | Роль | Пароль |
|---|---|---|---|
| Alice Chen | alice.chen@example.com | SUPER_ADMIN | password123 |
| Bob Martinez | bob.martinez@example.com | ADMIN | password123 |
| Carol Nguyen | carol.nguyen@example.com | MODERATOR | password123 |
| David Kim | david.kim@example.com | USER | password123 |
| Eva Johnson | eva.johnson@example.com | USER | password123 |
### PlatformConfig (дефолты)
- Listing Fee: $5.00
- Commission: 5%
- Auto-Approve: true (включено)
- Max Images: 6
- Free Tier Limit: 5 листингов
- Pro Price: $9.99/мес
- Business Price: $29.99/мес
- Promotion Day Price: $2.99
- Blocked Keywords: `illegal`, `drugs`, `weapons`
---
## Миграция данных — обратная совместимость
| Поле | Default | Влияние на старые данные |
|---|---|---|
| `User.role` | `USER` | Все существующие юзеры → USER |
| `User.isBanned` | `false` | Никто не затронут |
| `ListingStatus.PENDING_REVIEW` | — | Аддитивно, старые данные не ломаются |
| `Payment.type` | `LISTING_FEE` | Корректно для всех существующих платежей |
| `PlatformConfig.autoApprove` | `true` | Текущее поведение не меняется |
---
## Проверка сборки
| Проверка | Результат |
|---|---|
| `npx tsc --noEmit` (server) | Без ошибок |
| `npx tsc --noEmit` (client) | Без ошибок |
| `npm run build --workspace=client` | Успешно (432 KB JS, 47 KB CSS) |
| `npx prisma migrate dev` | Миграция применена |
| `npx tsx prisma/seed.ts` | Seed выполнен |
| Health check `/api/health` | `{"status":"ok"}` |
---
## Инструкции по деплою
```bash
# На сервере 173.212.212.157:
# 1. Обновить код
cd /var/www/marketplace-app && git pull
# 2. Установить зависимости
npm install
# 3. Применить миграцию
cd server && npx prisma db push
# 4. Обновить seed (опционально)
npx tsx prisma/seed.ts
# 5. Собрать клиент
cd .. && npm run build --workspace=client
# 6. Скопировать билд
cp -r client/dist/* /var/www/marketplace/
# 7. Перезапустить сервер
pm2 restart marketplace-api
```
---
## Верификация на проде
1. Логин как `alice.chen@example.com` (SUPER_ADMIN) → в хедере видна ссылка "Admin"
2. `/admin` → дашборд с 5 метриками
3. `/admin/users` → таблица юзеров с ролями и статусами
4. `/admin/users/:id` → детали юзера, бан david → логин как david → 403
5. Разбанить david → логин работает
6. `/admin/settings` → отключить autoApprove
7. Создать листинг → статус PENDING_REVIEW
8. `/admin/moderation` → approve → листинг активен
9. На странице товара → Report → модалка → отправить
10. `/admin/reports` → resolve жалобу
11. `/admin/payments` → транзакции по типам
12. `/admin/settings` → изменить listing fee → проверить