// سقفِ کلیِ (نه روزانه/ماهانه) بیلبورد رایگان — طبق خواسته‌ی صریحِ کاربر: ۲۰۰ تا // در کلِ عمرِ حساب، مستقل از سهمیه‌ی مشترکِ daily_free_request (که بین پروژه/بیلبورد/ // درخواست تقسیم می‌شه) و مستقل از سقفِ عمومیِ FREE_LIFETIME_CREATION_LIMIT // (utils/freeCreationLimit.js) const BILLBOARD_FREE_LIMIT = 200 function canUseFreeBillboard (user) { const used = user?.free_billboard_count || 0 return used < BILLBOARD_FREE_LIMIT } /** * نسخه‌ی atomic — چک (free_billboard_count < سقف) و افزایش توی یه عملیاتِ واحدِ * MongoDB (findOneAndUpdate با شرط توی query) انجام می‌شه، نه در دو مرحله‌ی جدا * (قبلاً canUseFreeBillboard روی یه user از قبل fetch‌شده چک می‌شد و بعد جداگانه * $inc می‌خورد) — وگرنه دو درخواستِ هم‌زمان (دابل‌کلیکِ «تلاشِ دوباره» روی صفحه‌ی * پرداختِ ناموفق، که تا امروز گاردِ submitting هم نداشت) هر دو می‌تونستن همون * user رو با free_billboard_count زیرِ سقف بخونن و هر دو از سقف رد بشن */ async function tryConsumeFreeBillboard (UserModel, userId) { const updated = await UserModel.findOneAndUpdate( { _id: userId, free_billboard_count: { $lt: BILLBOARD_FREE_LIMIT } }, { $inc: { free_billboard_count: 1 } }, { new: true } ) if (!updated) { return { ok: false, message: `سقف ${BILLBOARD_FREE_LIMIT} بیلبورد رایگان به پایان رسیده است.` } } return { ok: true, user: updated } } module.exports = { BILLBOARD_FREE_LIMIT, canUseFreeBillboard, tryConsumeFreeBillboard }