const mongoose = require('mongoose'); const CourseModel = require('../models/CourseModel'); const ProjectModel = require('../models/ProjectModel'); const AdvertisingModel = require('../models/AdvertisingModel'); const ShopModel = require('../models/ShopModel'); const ShopProductListingModel = require('../models/ShopProductListingModel'); const BookingConfigModel = require('../models/BookingConfigModel'); const { PUBLIC_COURSE_STATUSES, PUBLIC_BILLBOARD_STATUSES } = require('./moderationStatus'); // اعتبارسنجی مشترک «آیتم قابل‌لینک‌شدن» — هم پست (linked_*_id) هم استوری (لینک‌اورلی) از // همین یه تابع استفاده می‌کنن تا شرط مالکیت+وضعیت هرکدوم دوبار نوشته نشه. خروجی: شناسه‌ی // معتبری که باید ذخیره بشه، یا null اگه کاربر مالک نیست/وضعیتش پذیرفته‌شده نیست. async function resolveLinkedEntity(kind, id, userId) { if (!id || !mongoose.Types.ObjectId.isValid(id)) return null; switch (kind) { case 'pkg': { const course = await CourseModel.findById(id).select('_id user_id status').lean(); // با همون آستانه‌ی «عمومی قابل‌نمایش» که همه‌جای اپ برای پکیج آموزشی استفاده می‌شه // (temp_accept هم شامل می‌شه) — نه فقط accept نهایی؛ وگرنه هر پکیجی که کاربر تازه // ثبت کرده (وضعیت پیش‌فرضش temp_accept) توی پیکر قابل‌انتخاب بود ولی همیشه رد می‌شد if ( course && String(course.user_id) === String(userId) && PUBLIC_COURSE_STATUSES.includes(course.status) ) { return String(course._id); } return null; } case 'project': { const project = await ProjectModel.findById(id).select('_id creator_id status').lean(); if ( project && String(project.creator_id) === String(userId) && ['done', 'accepted'].includes(project.status) ) { return String(project._id); } return null; } case 'billboard': { const ad = await AdvertisingModel.findById(id).select('_id creator_id status').lean(); // عین pkg — همون آستانه‌ی «عمومی قابل‌نمایش» بیلبورد (شامل temp_accept/paid هم می‌شه) if ( ad && String(ad.creator_id) === String(userId) && PUBLIC_BILLBOARD_STATUSES.includes(ad.status) ) { return String(ad._id); } return null; } case 'shop': { const shop = await ShopModel.findById(id).select('_id owner status').lean(); if (shop && String(shop.owner) === String(userId) && shop.status === 'active') { return String(shop._id); } return null; } case 'shopproduct': { const listing = await ShopProductListingModel.findById(id).select('_id shop status').lean(); if (!listing || listing.status !== 'active') return null; const shop = await ShopModel.findById(listing.shop).select('_id owner').lean(); if (shop && String(shop.owner) === String(userId)) { return String(listing._id); } return null; } case 'booking': { // برای رزرو، id همون userId مالک کانفیگه (نه _id خودِ BookingConfig) — چون صفحه‌ی // عمومی رزرو (/booking/[userId]) با شناسه‌ی کاربر مسیردهی می‌شه، نه شناسه‌ی کانفیگ if (String(id) !== String(userId)) return null; const config = await BookingConfigModel.findOne({ owner: userId, status: 'active' }) .select('_id') .lean(); return config ? String(userId) : null; } default: return null; } } module.exports = { resolveLinkedEntity };