94 lines
4.6 KiB
JavaScript
94 lines
4.6 KiB
JavaScript
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, PUBLIC_PROJECT_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();
|
|
// عین pkg/billboard — هر وضعیتِ واقعی/متعهدشده و غیرِ رد/لغوشده رو میپذیریم، نه فقط
|
|
// done/accepted؛ وگرنه تقریباً هیچ پروژهی واقعیای (که بیشترِ عمرش pending/ongoing/
|
|
// temp_accept هست، نه دقیقاً done/accepted) قابللینکشدن نبود
|
|
if (
|
|
project &&
|
|
String(project.creator_id) === String(userId) &&
|
|
PUBLIC_PROJECT_STATUSES.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();
|
|
// draft/rejected هنوز واقعاً وجود عمومی ندارن، ولی pending_review (ثبتشده، منتظرِ
|
|
// تایید) هم مثل بقیهی موارد بالا باید قابللینک باشه — فقط active بیشازحد سختگیرانه بود
|
|
if (
|
|
shop &&
|
|
String(shop.owner) === String(userId) &&
|
|
['active', 'pending_review'].includes(shop.status)
|
|
) {
|
|
return String(shop._id);
|
|
}
|
|
return null;
|
|
}
|
|
case 'shopproduct': {
|
|
const listing = await ShopProductListingModel.findById(id).select('_id shop status').lean();
|
|
if (!listing || !['active', 'pending_shop_approval'].includes(listing.status)) 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 };
|