const UserModel = require('../models/UserModel') const SPARSE_UNIQUE_FIELDS = ['mobile', 'email', 'google_id'] /** * ایندکس unique غیر-sparse روی mobile باعث می‌شود فقط یک کاربر بدون موبایل * در دیتابیس مجاز باشد (dup key: { mobile: null }). * این تابع nullها را unset می‌کند و ایندکس‌ها را sparse می‌سازد. */ async function ensureUserSparseUniqueIndexes () { const collection = UserModel.collection for (const field of SPARSE_UNIQUE_FIELDS) { try { const unsetResult = await collection.updateMany( { [field]: null }, { $unset: { [field]: '' } } ) if (unsetResult.modifiedCount > 0) { console.log( `[ensureUserIndexes] unset null ${field}: ${unsetResult.modifiedCount}` ) } } catch (err) { console.error(`[ensureUserIndexes] unset ${field} failed:`, err.message) } } try { const indexes = await collection.indexes() for (const field of SPARSE_UNIQUE_FIELDS) { const existing = indexes.filter( (idx) => idx.key && Object.keys(idx.key).length === 1 && idx.key[field] === 1 && idx.unique ) for (const idx of existing) { const isSparse = Boolean(idx.sparse) if (!isSparse) { try { await collection.dropIndex(idx.name) console.log(`[ensureUserIndexes] dropped non-sparse index ${idx.name}`) } catch (err) { console.error( `[ensureUserIndexes] drop ${idx.name} failed:`, err.message ) } } } } for (const field of SPARSE_UNIQUE_FIELDS) { const name = `${field}_1` try { await collection.createIndex( { [field]: 1 }, { unique: true, sparse: true, name, background: true } ) console.log(`[ensureUserIndexes] ensured sparse unique index ${name}`) } catch (err) { // already exists with same options if (err?.code !== 85 && err?.code !== 86) { console.error( `[ensureUserIndexes] create ${name} failed:`, err.message ) } } } } catch (err) { console.error('[ensureUserIndexes] index sync failed:', err.message) } // کاربران pending بدون کارت ملی نباید تیک خاکستری داشته باشند try { const cleaned = await collection.updateMany( { is_verified: 'pending', $or: [ { national_card_image: null }, { national_card_image: { $exists: false } }, { national_card_image: '' }, ], }, { $set: { is_verified: 'none' } } ) if (cleaned.modifiedCount > 0) { console.log( `[ensureUserIndexes] cleared pending without card: ${cleaned.modifiedCount}` ) } } catch (err) { console.error('[ensureUserIndexes] pending cleanup failed:', err.message) } } module.exports = { ensureUserSparseUniqueIndexes, }