96 lines
3.9 KiB
JavaScript
96 lines
3.9 KiB
JavaScript
const mongoose = require('mongoose');
|
|
const CourseModel = require('../models/CourseModel');
|
|
const AcademyModel = require('../models/AcademyModel');
|
|
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');
|
|
|
|
function sameId(a, b) {
|
|
if (a == null || b == null) return false;
|
|
const sa = typeof a === 'object' && a._id != null ? String(a._id) : String(a);
|
|
const sb = typeof b === 'object' && b._id != null ? String(b._id) : String(b);
|
|
return sa === sb;
|
|
}
|
|
|
|
// اعتبارسنجی مشترک «آیتم قابللینکشدن»
|
|
// options.requirePublic (پیشفرض true): برای لینک داخل پست/استوری وضعیت عمومی لازم است.
|
|
// برای صفحه «اشتراکگذاری لینک» فقط مالکیت کافی است (requirePublic: false).
|
|
async function resolveLinkedEntity(kind, id, userId, options = {}) {
|
|
const requirePublic = options.requirePublic !== false;
|
|
if (!id || !mongoose.Types.ObjectId.isValid(id)) return null;
|
|
|
|
switch (kind) {
|
|
case 'pkg': {
|
|
const course = await CourseModel.findById(id)
|
|
.select('_id user_id academyId status')
|
|
.lean();
|
|
if (!course) return null;
|
|
if (requirePublic && !PUBLIC_COURSE_STATUSES.includes(course.status)) return null;
|
|
|
|
// مالکیت: user_id مستقیم روی دوره، یا مالک آکادمیِ دوره
|
|
if (sameId(course.user_id, userId)) return String(course._id);
|
|
if (course.academyId) {
|
|
const academy = await AcademyModel.findById(course.academyId).select('userId').lean();
|
|
if (academy && sameId(academy.userId, userId)) return String(course._id);
|
|
}
|
|
return null;
|
|
}
|
|
case 'project': {
|
|
const project = await ProjectModel.findById(id)
|
|
.select('_id creator_id status')
|
|
.lean();
|
|
if (!project) return null;
|
|
if (requirePublic && !PUBLIC_PROJECT_STATUSES.includes(project.status)) return null;
|
|
if (sameId(project.creator_id, userId)) return String(project._id);
|
|
return null;
|
|
}
|
|
case 'billboard': {
|
|
const ad = await AdvertisingModel.findById(id)
|
|
.select('_id creator_id status')
|
|
.lean();
|
|
if (!ad) return null;
|
|
if (requirePublic && !PUBLIC_BILLBOARD_STATUSES.includes(ad.status)) return null;
|
|
if (sameId(ad.creator_id, userId)) return String(ad._id);
|
|
return null;
|
|
}
|
|
case 'shop': {
|
|
const shop = await ShopModel.findById(id).select('_id owner status').lean();
|
|
if (!shop) return null;
|
|
if (requirePublic && !['active', 'pending_review'].includes(shop.status)) return null;
|
|
if (sameId(shop.owner, userId)) return String(shop._id);
|
|
return null;
|
|
}
|
|
case 'shopproduct': {
|
|
const listing = await ShopProductListingModel.findById(id)
|
|
.select('_id shop status')
|
|
.lean();
|
|
if (!listing) return null;
|
|
if (requirePublic && !['active', 'pending_shop_approval'].includes(listing.status)) {
|
|
return null;
|
|
}
|
|
const shop = await ShopModel.findById(listing.shop).select('_id owner').lean();
|
|
if (shop && sameId(shop.owner, userId)) return String(listing._id);
|
|
return null;
|
|
}
|
|
case 'booking': {
|
|
// ref_id برای رزرو = userId مالک کانفیگ (نه _id خودِ BookingConfig)
|
|
if (!sameId(id, userId)) return null;
|
|
const query = requirePublic
|
|
? { owner: userId, status: 'active' }
|
|
: { owner: userId };
|
|
const config = await BookingConfigModel.findOne(query).select('_id').lean();
|
|
return config ? String(userId) : null;
|
|
}
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
module.exports = { resolveLinkedEntity }; |