// Скрипт для mongosh для исправления незасчитанных рефералов // Использование: // mongosh "mongodb://your-connection-string/nakama" fixReferrals.mongosh.js // или // mongosh nakama --file fixReferrals.mongosh.js // Функция для получения начала дня по московскому времени (UTC+3) function getMoscowStartOfDay(date) { if (!date) { date = new Date(); } // Создаем копию даты const moscowDate = new Date(date); // Получаем UTC время const utcTime = moscowDate.getTime() + (moscowDate.getTimezoneOffset() * 60 * 1000); // Добавляем 3 часа для московского времени const moscowOffset = 3 * 60 * 60 * 1000; const moscowTime = new Date(utcTime + moscowOffset); // Устанавливаем время на 00:00:00 moscowTime.setHours(0, 0, 0, 0); return moscowTime; } // Функция для получения уникальных дат из массива loginDates function getUniqueDates(loginDates) { const uniqueDates = new Set(); if (!loginDates || !Array.isArray(loginDates)) { return uniqueDates; } loginDates.forEach(date => { if (!date) return; const dateObj = getMoscowStartOfDay(new Date(date)); // Используем timestamp начала дня для сравнения uniqueDates.add(dateObj.getTime()); }); return uniqueDates; } print("🔍 Поиск пользователей с незасчитанными рефералами...\n"); // Найти всех пользователей с referredBy, но не засчитанных const usersWithReferrals = db.users.find({ referredBy: { $exists: true, $ne: null }, referralCounted: { $ne: true } }).toArray(); print(`📊 Найдено ${usersWithReferrals.length} пользователей с незасчитанными рефералами\n`); let fixed = 0; let needMoreDays = 0; let errors = 0; let skipped = 0; usersWithReferrals.forEach(user => { try { // Получить реферера const referrer = db.users.findOne({ _id: user.referredBy }); if (!referrer) { print(`⚠️ Пользователь ${user.username || user._id} имеет referredBy, но реферер не найден\n`); skipped++; return; } // Инициализировать loginDates если его нет if (!user.loginDates || user.loginDates.length === 0) { print(`📅 ${user.username || user._id}: нет дат входа. Пропускаем.\n`); needMoreDays++; return; } // Получить уникальные даты const uniqueDates = getUniqueDates(user.loginDates); const uniqueDatesCount = uniqueDates.size; print(`👤 ${user.username || user._id}`); print(` Реферер: ${referrer.username || referrer._id}`); print(` Уникальных дат входа: ${uniqueDatesCount}`); // Показать даты const datesArray = Array.from(uniqueDates).map(t => { const d = new Date(t); return d.toLocaleDateString('ru-RU'); }); if (datesArray.length > 0) { print(` Даты: ${datesArray.join(', ')}`); } // Если есть 2 или более уникальные даты, засчитать реферала if (uniqueDatesCount >= 2) { // Увеличить счетчик рефералов у реферера const currentCount = referrer.referralsCount || 0; const newCount = currentCount + 1; const updateResult = db.users.updateOne( { _id: referrer._id }, { $set: { referralsCount: newCount } } ); if (updateResult.modifiedCount > 0) { print(` ✅ РЕФЕРАЛ ЗАСЧИТАН! Новый счетчик: ${newCount}`); } else { print(` ⚠️ Не удалось обновить счетчик рефералов`); } // Пометить пользователя как засчитанного и очистить loginDates const userUpdateResult = db.users.updateOne( { _id: user._id }, { $set: { referralCounted: true, loginDates: [] } } ); if (userUpdateResult.modifiedCount > 0) { print(` ✅ Пользователь помечен как засчитанный\n`); fixed++; } else { print(` ⚠️ Не удалось пометить пользователя как засчитанного\n`); } } else { print(` ⏳ Нужно еще ${2 - uniqueDatesCount} уникальных дат входа\n`); needMoreDays++; } } catch (error) { print(` ❌ Ошибка при обработке пользователя ${user._id}: ${error.message}\n`); errors++; } }); print(`\n📊 Итого:`); print(` ✅ Засчитано рефералов: ${fixed}`); print(` ⏳ Требуется больше дней: ${needMoreDays}`); print(` ⚠️ Пропущено (нет реферера): ${skipped}`); print(` ❌ Ошибок: ${errors}`); print(`\n✅ Готово!`);