full
This commit is contained in:
103
utils/ensureUserIndexes.js
Normal file
103
utils/ensureUserIndexes.js
Normal file
@@ -0,0 +1,103 @@
|
||||
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,
|
||||
}
|
||||
Reference in New Issue
Block a user