Реферальная система: БД, API, UI

**База данных:**
- Создана таблица referrals в MariaDB (193.168.175.128)
- Поля: username, referrer_username, referral_count, bonus_days_earned
- Foreign keys к users таблице с CASCADE/SET NULL

**API Endpoints:**
- POST /api/referral/track - отслеживание новых рефералов
  - Автоматический расчёт бонусов: +7 дней за каждого
  - Milestone bonus: +30 дней за каждые 5 рефералов
  - Обновление expire даты реферера в users таблице

- GET /api/referral/stats?username=xxx - статистика
  - Возвращает количество рефералов, бонусные дни
  - Список приглашённых пользователей со статусами

**Интеграция:**
- POST /api/create-user принимает referrerId параметр
- Автоматический вызов /api/referral/track после создания юзера
- Параметр ref из URL при активации trial

**UI:**
- /app/referral/page.tsx - страница статистики
  - 3 KPI карточки: рефералов, бонусных дней, milestone
  - Реферальная ссылка с кнопкой копирования
  - Список приглашённых юзеров с иконками статуса
  - Инфоблок о механике начисления бонусов

**ReferralModal обновлён:**
- Добавлена кнопка «Моя статистика» → /referral
- Перенос Share/Copy кнопок на второй/третий план

**Зависимости:**
- mysql2@3.16.3 - для подключения к MariaDB

**Логика бонусов:**
- +7 дней за каждого успешного реферала
- +30 дней бонус за каждые 5 рефералов (milestone)
- Автоматическое обновление expire поля в users таблице
- Сохранение всех бонусов в bonus_days_earned
This commit is contained in:
Umbrix Dev
2026-02-06 20:51:40 +03:00
parent 00bfda8748
commit b43eb3c724
8 changed files with 684 additions and 5 deletions

View File

@@ -19,9 +19,9 @@ if (!ADMIN_USERNAME || !ADMIN_PASSWORD) {
export async function POST(request: NextRequest) {
try {
const { planType, telegramId, telegramUsername, firstName, lastName } = await request.json();
const { planType, telegramId, telegramUsername, firstName, lastName, referrerId } = await request.json();
logger.debug('📥 Received data:', { planType, telegramId, telegramUsername, firstName, lastName });
logger.debug('📥 Received data:', { planType, telegramId, telegramUsername, firstName, lastName, referrerId });
// 1. Получаем токен админа
const tokenResponse = await fetch(`${MARZBAN_API}/api/admin/token`, {
@@ -101,6 +101,24 @@ export async function POST(request: NextRequest) {
// 5. Получаем subscription token
const subscriptionToken = userData.subscription_url?.split('/sub/')[1]?.replace(/\/$/, '') || username;
// 6. Track referral if referrerId provided
if (referrerId) {
try {
await fetch(`${request.nextUrl.origin}/api/referral/track`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
username: username,
referrer_username: referrerId,
}),
});
logger.debug('✅ Referral tracked:', { username, referrer: referrerId });
} catch (refError) {
logger.error('❌ Referral tracking failed:', refError);
// Don't fail user creation if referral tracking fails
}
}
return NextResponse.json({
success: true,
token: subscriptionToken,