diff --git a/backend/scripts/fixReferrals-commands.txt b/backend/scripts/fixReferrals-commands.txt new file mode 100644 index 0000000..c41e659 --- /dev/null +++ b/backend/scripts/fixReferrals-commands.txt @@ -0,0 +1,201 @@ +// Команды mongosh для исправления незасчитанных рефералов +// Выполняйте по порядку + +// ============================================ +// 1. НАЙТИ ВСЕХ ПОЛЬЗОВАТЕЛЕЙ С REFERREDBY (независимо от referralCounted) +// ============================================ +db.users.find({ + referredBy: { $exists: true, $ne: null } +}).forEach(function(user) { + print("Пользователь: " + (user.username || user._id)); + print(" Реферер ID: " + user.referredBy); + print(" Засчитан: " + (user.referralCounted || false)); + print(" Дат входа: " + (user.loginDates ? user.loginDates.length : 0)); + if (user.loginDates && user.loginDates.length > 0) { + print(" Даты: " + user.loginDates.map(function(d) { return new Date(d).toLocaleDateString('ru-RU'); }).join(', ')); + } + print("---"); +}); + +// ============================================ +// 2. НАЙТИ ВСЕХ С REFERREDBY И НЕ ЗАСЧИТАННЫХ (включая null и false) +// ============================================ +db.users.find({ + referredBy: { $exists: true, $ne: null }, + $or: [ + { referralCounted: { $exists: false } }, + { referralCounted: null }, + { referralCounted: false } + ] +}).forEach(function(user) { + print("Пользователь: " + (user.username || user._id)); + print(" Реферер ID: " + user.referredBy); + print(" Дат входа: " + (user.loginDates ? user.loginDates.length : 0)); + print("---"); +}); + +// ============================================ +// 3. ПРОВЕРИТЬ КОНКРЕТНОГО РЕФЕРЕРА (замените USER_ID) +// ============================================ +// db.users.find({ referredBy: ObjectId("69090d0b52ac792c78253963") }).forEach(function(u) { +// print(u.username + " - засчитан: " + (u.referralCounted || false) + ", дат: " + (u.loginDates ? u.loginDates.length : 0)); +// }); + +// ============================================ +// 4. ПОСЧИТАТЬ СКОЛЬКО ВСЕГО С REFERREDBY +// ============================================ +// db.users.countDocuments({ referredBy: { $exists: true, $ne: null } }) + +// ============================================ +// 5. ПОСЧИТАТЬ СКОЛЬКО НЕ ЗАСЧИТАННЫХ +// ============================================ +// db.users.countDocuments({ +// referredBy: { $exists: true, $ne: null }, +// $or: [ +// { referralCounted: { $exists: false } }, +// { referralCounted: null }, +// { referralCounted: false } +// ] +// }) + +// ============================================ +// 6. ЗАСЧИТАТЬ ВСЕХ РЕФЕРАЛОВ С 2+ УНИКАЛЬНЫМИ ДАТАМИ +// ============================================ +db.users.find({ + referredBy: { $exists: true, $ne: null }, + $or: [ + { referralCounted: { $exists: false } }, + { referralCounted: null }, + { referralCounted: false } + ], + loginDates: { $exists: true, $ne: [] } +}).forEach(function(user) { + // Получить уникальные даты + var uniqueDates = new Set(); + if (user.loginDates && Array.isArray(user.loginDates)) { + user.loginDates.forEach(function(date) { + if (!date) return; + var d = new Date(date); + d.setHours(0, 0, 0, 0); + uniqueDates.add(d.getTime()); + }); + } + + print("Проверка: " + (user.username || user._id) + " - уникальных дат: " + uniqueDates.size); + + // Если есть 2+ уникальные даты, засчитать + if (uniqueDates.size >= 2) { + var referrer = db.users.findOne({ _id: user.referredBy }); + if (referrer) { + // Увеличить счетчик рефералов + var newCount = (referrer.referralsCount || 0) + 1; + db.users.updateOne( + { _id: referrer._id }, + { $set: { referralsCount: newCount } } + ); + + // Пометить как засчитанного + db.users.updateOne( + { _id: user._id }, + { + $set: { + referralCounted: true, + loginDates: [] + } + } + ); + + print("✅ ЗАСЧИТАН: " + (user.username || user._id) + " -> " + (referrer.username || referrer._id) + " (счетчик: " + newCount + ")"); + } + } else if (uniqueDates.size > 0) { + print("⏳ Нужно еще дат: " + (user.username || user._id) + " (сейчас: " + uniqueDates.size + ")"); + } else { + print("📅 Нет дат входа: " + (user.username || user._id)); + } +}); + +// ============================================ +// 7. ПРОВЕРИТЬ РЕЗУЛЬТАТ - СКОЛЬКО РЕФЕРАЛОВ У КОНКРЕТНОГО ПОЛЬЗОВАТЕЛЯ +// ============================================ +// db.users.findOne({ _id: ObjectId("69090d0b52ac792c78253963") }, { username: 1, referralsCount: 1, referralCode: 1 }) + +// ============================================ +// 8. НАЙТИ ВСЕХ РЕФЕРАЛОВ КОНКРЕТНОГО ПОЛЬЗОВАТЕЛЯ +// ============================================ +// db.users.find({ referredBy: ObjectId("69090d0b52ac792c78253963") }, { username: 1, referralCounted: 1, loginDates: 1 }).forEach(function(u) { +// var dates = u.loginDates ? u.loginDates.length : 0; +// print(u.username + " - засчитан: " + (u.referralCounted || false) + ", дат входа: " + dates); +// }); + +// ============================================ +// 9. ЗАСЧИТАТЬ ВСЕХ РЕФЕРАЛОВ КОНКРЕТНОГО ПОЛЬЗОВАТЕЛЯ +// (замените USER_ID на ID пользователя) +// ============================================ +var userId = ObjectId("ЗАМЕНИТЕ_НА_ID_ПОЛЬЗОВАТЕЛЯ"); + +var user = db.users.findOne({ _id: userId }); +if (!user) { + print("❌ Пользователь не найден!"); +} else { + print("👤 Пользователь: " + (user.username || user._id)); + print(" Текущий счетчик: " + (user.referralsCount || 0)); + print("\n🔍 Поиск рефералов...\n"); + + var fixed = 0; + var needMoreDays = 0; + + db.users.find({ referredBy: userId }).forEach(function(ref) { + if (ref.referralCounted === true) { + print("✅ " + (ref.username || ref._id) + " - уже засчитан"); + return; + } + + var uniqueDates = new Set(); + if (ref.loginDates && Array.isArray(ref.loginDates)) { + ref.loginDates.forEach(function(date) { + if (!date) return; + var d = new Date(date); + d.setHours(0, 0, 0, 0); + uniqueDates.add(d.getTime()); + }); + } + + if (uniqueDates.size >= 2) { + var newCount = (user.referralsCount || 0) + 1; + db.users.updateOne({ _id: userId }, { $set: { referralsCount: newCount } }); + db.users.updateOne({ _id: ref._id }, { $set: { referralCounted: true, loginDates: [] } }); + user.referralsCount = newCount; + print("✅ ЗАСЧИТАН: " + (ref.username || ref._id) + " (счетчик: " + newCount + ")"); + fixed++; + } else { + print("⏳ " + (ref.username || ref._id) + " - нужно еще дат (сейчас: " + uniqueDates.size + ")"); + needMoreDays++; + } + }); + + var finalUser = db.users.findOne({ _id: userId }); + print("\n📊 Засчитано новых: " + fixed); + print("📈 Финальный счетчик: " + (finalUser.referralsCount || 0)); +} + +// ============================================ +// 10. НАЙТИ ПОЛЬЗОВАТЕЛЯ ПО USERNAME И ИСПРАВИТЬ ЕГО РЕФЕРАЛОВ +// ============================================ +// var user = db.users.findOne({ username: "USERNAME" }); +// if (user) { +// var userId = user._id; +// // Затем выполните команды из пункта 9, заменив userId +// } + +// ============================================ +// 11. УСТАНОВИТЬ referralCounted: false ДЛЯ ВСЕХ С REFERREDBY (если нужно сбросить) +// ============================================ +// db.users.updateMany( +// { +// referredBy: { $exists: true, $ne: null }, +// referralCounted: { $ne: true } +// }, +// { +// $set: { referralCounted: false } +// } +// ) diff --git a/backend/scripts/fixReferrals-simple.mongosh.js b/backend/scripts/fixReferrals-simple.mongosh.js new file mode 100644 index 0000000..bace4c3 --- /dev/null +++ b/backend/scripts/fixReferrals-simple.mongosh.js @@ -0,0 +1,53 @@ +// Простые команды mongosh для исправления рефералов +// Скопируйте и выполните в mongosh + +// ============================================ +// ОДНА КОМАНДА ДЛЯ ВСЕГО: +// ============================================ + +db.users.find({ + referredBy: { $exists: true, $ne: null }, + referralCounted: { $ne: true }, + loginDates: { $exists: true, $ne: [] } +}).forEach(function(user) { + // Получить уникальные даты + var uniqueDates = new Set(); + if (user.loginDates && Array.isArray(user.loginDates)) { + user.loginDates.forEach(function(date) { + if (!date) return; + var d = new Date(date); + d.setHours(0, 0, 0, 0); + uniqueDates.add(d.getTime()); + }); + } + + // Если есть 2+ уникальные даты, засчитать + if (uniqueDates.size >= 2) { + var referrer = db.users.findOne({ _id: user.referredBy }); + if (referrer) { + // Увеличить счетчик рефералов + var newCount = (referrer.referralsCount || 0) + 1; + db.users.updateOne( + { _id: referrer._id }, + { $set: { referralsCount: newCount } } + ); + + // Пометить как засчитанного + db.users.updateOne( + { _id: user._id }, + { + $set: { + referralCounted: true, + loginDates: [] + } + } + ); + + print("✅ ЗАСЧИТАН: " + (user.username || user._id) + " -> " + (referrer.username || referrer._id) + " (счетчик: " + newCount + ")"); + } + } +}); + +print("\n✅ Готово! Проверьте результат командой:"); +print("db.users.find({ referralsCount: { $gt: 0 } }, { username: 1, referralsCount: 1 })"); + diff --git a/backend/scripts/fixReferrals.js b/backend/scripts/fixReferrals.js index ba47fcd..3fe8236 100644 --- a/backend/scripts/fixReferrals.js +++ b/backend/scripts/fixReferrals.js @@ -2,8 +2,9 @@ const mongoose = require('mongoose'); const dotenv = require('dotenv'); const path = require('path'); -// Загрузить переменные окружения -dotenv.config({ path: path.join(__dirname, '../.env') }); +// Загрузить переменные окружения из корня проекта +// __dirname указывает на backend/scripts, поэтому нужно подняться на 2 уровня вверх +dotenv.config({ path: path.join(__dirname, '../../.env') }); const User = require('../models/User'); const { getMoscowStartOfDay } = require('../utils/moscowTime'); @@ -11,14 +12,19 @@ const { awardReferral } = require('../utils/tickets'); async function fixReferrals() { try { - const mongoUri = process.env.MONGO_URI || 'mongodb://localhost:27017/nakama'; + const mongoUri = process.env.MONGODB_URI || 'mongodb://localhost:27017/nakama'; await mongoose.connect(mongoUri); console.log('✅ Подключено к MongoDB'); // Найти всех пользователей, у которых есть referredBy, но они еще не засчитаны + // Включаем случаи, когда referralCounted отсутствует, null или false const usersWithReferrals = await User.find({ referredBy: { $exists: true, $ne: null }, - referralCounted: { $ne: true } + $or: [ + { referralCounted: { $exists: false } }, + { referralCounted: null }, + { referralCounted: false } + ] }).populate('referredBy', 'username referralCode referralsCount'); console.log(`\n📊 Найдено ${usersWithReferrals.length} пользователей с незасчитанными рефералами\n`); diff --git a/backend/scripts/fixReferrals.mongosh.js b/backend/scripts/fixReferrals.mongosh.js new file mode 100644 index 0000000..50af4ea --- /dev/null +++ b/backend/scripts/fixReferrals.mongosh.js @@ -0,0 +1,140 @@ +// Скрипт для 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✅ Готово!`); diff --git a/backend/scripts/fixUserReferrals.mongosh.js b/backend/scripts/fixUserReferrals.mongosh.js new file mode 100644 index 0000000..c436369 --- /dev/null +++ b/backend/scripts/fixUserReferrals.mongosh.js @@ -0,0 +1,118 @@ +// Команды для исправления рефералов конкретного пользователя +// Замените USER_ID на ID пользователя, у которого должны быть рефералы + +// ============================================ +// 1. НАЙТИ ПОЛЬЗОВАТЕЛЯ ПО USERNAME ИЛИ ID +// ============================================ +// var userId = db.users.findOne({ username: "USERNAME" })._id; +// или +// var userId = ObjectId("USER_ID"); + +// ============================================ +// 2. НАЙТИ ВСЕХ РЕФЕРАЛОВ ЭТОГО ПОЛЬЗОВАТЕЛЯ +// ============================================ +// db.users.find({ referredBy: userId }).forEach(function(ref) { +// print("Реферал: " + (ref.username || ref._id)); +// print(" Засчитан: " + (ref.referralCounted || false)); +// print(" Дат входа: " + (ref.loginDates ? ref.loginDates.length : 0)); +// if (ref.loginDates && ref.loginDates.length > 0) { +// print(" Даты: " + ref.loginDates.map(function(d) { return new Date(d).toLocaleDateString('ru-RU'); }).join(', ')); +// } +// print("---"); +// }); + +// ============================================ +// 3. ЗАСЧИТАТЬ ВСЕХ РЕФЕРАЛОВ КОНКРЕТНОГО ПОЛЬЗОВАТЕЛЯ +// (замените USER_ID на ID пользователя) +// ============================================ +var userId = ObjectId("ЗАМЕНИТЕ_НА_ID_ПОЛЬЗОВАТЕЛЯ"); + +// Найти пользователя +var user = db.users.findOne({ _id: userId }); +if (!user) { + print("❌ Пользователь не найден!"); +} else { + print("👤 Пользователь: " + (user.username || user._id)); + print(" Текущий счетчик рефералов: " + (user.referralsCount || 0)); + print("\n🔍 Поиск рефералов...\n"); + + var fixed = 0; + var needMoreDays = 0; + var alreadyCounted = 0; + + db.users.find({ referredBy: userId }).forEach(function(ref) { + print("Реферал: " + (ref.username || ref._id)); + + // Если уже засчитан, пропускаем + if (ref.referralCounted === true) { + print(" ✅ Уже засчитан"); + alreadyCounted++; + print("---\n"); + return; + } + + // Получить уникальные даты + var uniqueDates = new Set(); + if (ref.loginDates && Array.isArray(ref.loginDates)) { + ref.loginDates.forEach(function(date) { + if (!date) return; + var d = new Date(date); + d.setHours(0, 0, 0, 0); + uniqueDates.add(d.getTime()); + }); + } + + print(" Уникальных дат: " + uniqueDates.size); + if (uniqueDates.size > 0) { + var datesArray = Array.from(uniqueDates).map(function(t) { + return new Date(t).toLocaleDateString('ru-RU'); + }); + print(" Даты: " + datesArray.join(', ')); + } + + // Если есть 2+ уникальные даты, засчитать + if (uniqueDates.size >= 2) { + var newCount = (user.referralsCount || 0) + 1; + + // Увеличить счетчик рефералов + db.users.updateOne( + { _id: userId }, + { $set: { referralsCount: newCount } } + ); + + // Пометить реферала как засчитанного + db.users.updateOne( + { _id: ref._id }, + { + $set: { + referralCounted: true, + loginDates: [] + } + } + ); + + user.referralsCount = newCount; // Обновить локальную переменную + + print(" ✅ ЗАСЧИТАН! Новый счетчик: " + newCount); + fixed++; + } else if (uniqueDates.size > 0) { + print(" ⏳ Нужно еще " + (2 - uniqueDates.size) + " уникальных дат"); + needMoreDays++; + } else { + print(" 📅 Нет дат входа"); + needMoreDays++; + } + + print("---\n"); + }); + + print("\n📊 Итого:"); + print(" ✅ Засчитано новых: " + fixed); + print(" ✅ Уже были засчитаны: " + alreadyCounted); + print(" ⏳ Требуется больше дней: " + needMoreDays); + + // Обновить счетчик пользователя + var finalUser = db.users.findOne({ _id: userId }); + print("\n 📈 Финальный счетчик рефералов: " + (finalUser.referralsCount || 0)); +} + diff --git a/backend/scripts/initTags.js b/backend/scripts/initTags.js index cf77674..1d10c5a 100644 --- a/backend/scripts/initTags.js +++ b/backend/scripts/initTags.js @@ -44,7 +44,7 @@ const INITIAL_TAGS = [ async function initTags() { try { - const mongoUri = process.env.MONGO_URI || 'mongodb://localhost:27017/nakama'; + const mongoUri = process.env.MONGODB_URI || 'mongodb://localhost:27017/nakama'; await mongoose.connect(mongoUri); console.log('✅ Подключено к MongoDB');