const jwt = require('jsonwebtoken') const UserModel = require('../models/UserModel') const { getRedisClient } = require('../utils/redisClient') const { markOnline } = require('../utils/presence') // این میدل‌ور روی *هر* درخواستِ احرازهویت‌شده اجرا می‌شه (app.use سراسری) — قبلاً // یعنی هر درخواست یه findById+save کاملِ Mongo می‌زد، حتی برای کاربری که پشتِ‌سرِهم // صدها درخواست در دقیقه می‌فرسته. الان: وضعیتِ «آنلاینِ لحظه‌ای» توی Redis با TTLِ // کوتاه نگه داشته می‌شه (هر درخواست رفرش می‌شه، تقریباً رایگان — utils/presence.js)، // و نوشتنِ last_online توی Mongo (برای «آخرین بازدید» که جاهای دیگه‌ی اپ می‌خونن) // throttle می‌شه به حداکثر یک‌بار در هر ۶۰ ثانیه برای هر کاربر const MONGO_SYNC_TTL_SECONDS = 60 async function syncLastOnlineToMongo (userId) { const user = await UserModel.findById(userId).select('ghost_mode account_status') if (user && !user.ghost_mode && user.account_status !== 'deactivated') { await UserModel.updateOne({ _id: userId }, { last_online: new Date() }) } } module.exports = async (req, res, next) => { if (req.header && req.header('Authorization')) { try { const token = req.header('Authorization').split(' ')[1] const decodedToken = jwt.verify(token, process.env.APP_SECRET) const userId = String(decodedToken.id) const redis = getRedisClient() if (redis) { await markOnline(userId) const acquiredSyncLock = await redis.set( `presence:sync:${userId}`, '1', { NX: true, EX: MONGO_SYNC_TTL_SECONDS } ) if (acquiredSyncLock) { await syncLastOnlineToMongo(userId) } } else { // Redis در دسترس نیست — همون رفتارِ قبلی، مستقیم Mongo (fallback امن، کندتر // ولی درست) تا وقتی Redis دوباره وصل بشه await syncLastOnlineToMongo(userId) } } catch (error) { console.error('Error updating last online time:', error) } } next() }