check
This commit is contained in:
@@ -1,33 +1,33 @@
|
||||
/* eslint-disable camelcase */
|
||||
const PostModel = require('../../../models/PostModel');
|
||||
const UserModel = require('../../../models/UserModel');
|
||||
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 { CountryModel, ProvinceModel, CityModel } = require('../../../models/StateCity');
|
||||
const { resolveLinkedEntity } = require('../../../utils/resolveLinkedEntity');
|
||||
const { check, validationResult } = require('express-validator');
|
||||
const jwt = require('jsonwebtoken');
|
||||
const path = require('path');
|
||||
const { default: mongoose } = require('mongoose');
|
||||
const { viewerIsBlockedBy } = require('../../../utils/blockVisibility');
|
||||
const { attachSinglePostEngagement } = require('../../../utils/postEngagement');
|
||||
const { isHiddenFromPublic } = require('../../../utils/accountLifecycle');
|
||||
const { viewerCanSeeUserContent } = require('../../../utils/privateProfile');
|
||||
const { isPostPubliclyVisible } = require('../../../utils/postModeration');
|
||||
const { postStatusFilter, PUBLIC_POST_STATUSES, commentStatusFilter } = require('../../../utils/moderationStatus');
|
||||
const { resolvePostModerationStatus } = require('../../../utils/contentModeration');
|
||||
const { savePostWithModerationStatus } = require('../../../utils/postStatusSave');
|
||||
const { createTagNotifications } = require('../../../utils/tagNotification');
|
||||
const { notifyFollowers } = require('../../../utils/notifyFollowers');
|
||||
const PostModel = require('../../../models/PostModel')
|
||||
const UserModel = require('../../../models/UserModel')
|
||||
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 { CountryModel, ProvinceModel, CityModel } = require('../../../models/StateCity')
|
||||
const { resolveLinkedEntity } = require('../../../utils/resolveLinkedEntity')
|
||||
const { check, validationResult } = require('express-validator')
|
||||
const jwt = require('jsonwebtoken')
|
||||
const path = require('path')
|
||||
const { default: mongoose } = require('mongoose')
|
||||
const { viewerIsBlockedBy } = require('../../../utils/blockVisibility')
|
||||
const { attachSinglePostEngagement } = require('../../../utils/postEngagement')
|
||||
const { isHiddenFromPublic } = require('../../../utils/accountLifecycle')
|
||||
const { viewerCanSeeUserContent } = require('../../../utils/privateProfile')
|
||||
const { isPostPubliclyVisible } = require('../../../utils/postModeration')
|
||||
const { postStatusFilter, PUBLIC_POST_STATUSES, commentStatusFilter } = require('../../../utils/moderationStatus')
|
||||
const { resolvePostModerationStatus } = require('../../../utils/contentModeration')
|
||||
const { savePostWithModerationStatus } = require('../../../utils/postStatusSave')
|
||||
const { createTagNotifications } = require('../../../utils/tagNotification')
|
||||
const { notifyFollowers } = require('../../../utils/notifyFollowers')
|
||||
|
||||
let processPostVideoInBackground = async () => {};
|
||||
let processPostVideoInBackground = async () => {}
|
||||
try {
|
||||
({ processPostVideoInBackground } = require('../../../utils/postVideoProcessing'));
|
||||
({ processPostVideoInBackground } = require('../../../utils/postVideoProcessing'))
|
||||
} catch (error) {
|
||||
console.warn('[postController] postVideoProcessing unavailable:', error.message);
|
||||
console.warn('[postController] postVideoProcessing unavailable:', error.message)
|
||||
}
|
||||
|
||||
const createPostValidationRules = () => {
|
||||
@@ -35,81 +35,81 @@ const createPostValidationRules = () => {
|
||||
check('caption')
|
||||
.optional({ nullable: true })
|
||||
.isLength({ max: 2000 })
|
||||
.withMessage('کپشن حداکثر ۲۰۰۰ کاراکتر'),
|
||||
];
|
||||
};
|
||||
.withMessage('کپشن حداکثر ۲۰۰۰ کاراکتر')
|
||||
]
|
||||
}
|
||||
|
||||
const createPost = async (req, res) => {
|
||||
try {
|
||||
console.log('DEBUG: createPost called', {
|
||||
filesCount: Array.isArray(req.files) ? req.files.length : 0,
|
||||
hasCaption: Boolean(req.body?.caption),
|
||||
userId: String(req.user?._id || req.user?.id || ''),
|
||||
});
|
||||
userId: String(req.user?._id || req.user?.id || '')
|
||||
})
|
||||
|
||||
const { caption } = req.body;
|
||||
const files = req.files || [];
|
||||
const userId = req.user?._id || req.user?.id;
|
||||
const { caption } = req.body
|
||||
const files = req.files || []
|
||||
const userId = req.user?._id || req.user?.id
|
||||
if (!userId) {
|
||||
return res.status(401).json({ error: true, message: 'توکن ارائه نشده است' });
|
||||
return res.status(401).json({ error: true, message: 'توکن ارائه نشده است' })
|
||||
}
|
||||
|
||||
let taggedUserIds = [];
|
||||
let taggedUserIds = []
|
||||
if (req.body.tagged_user_ids) {
|
||||
const raw = req.body.tagged_user_ids;
|
||||
let parsed = [];
|
||||
const raw = req.body.tagged_user_ids
|
||||
let parsed = []
|
||||
try {
|
||||
parsed = Array.isArray(raw) ? raw : (typeof raw === 'string' ? JSON.parse(raw) : []);
|
||||
parsed = Array.isArray(raw) ? raw : (typeof raw === 'string' ? JSON.parse(raw) : [])
|
||||
} catch {
|
||||
parsed = [];
|
||||
parsed = []
|
||||
}
|
||||
taggedUserIds = parsed
|
||||
.filter((id) => mongoose.Types.ObjectId.isValid(id))
|
||||
.slice(0, 50);
|
||||
.slice(0, 50)
|
||||
}
|
||||
|
||||
// اعتبارسنجی همهی آیتمهای قابللینک (پکیج/پروژه/بیلبورد/فروشگاه/کالا/رزرو) از یک تابع
|
||||
// مشترک — همون شرط مالکیت+وضعیت که قبلاً اینجا پراکنده بود، حالا با استوری هم به اشتراک
|
||||
// گذاشته میشه (utils/resolveLinkedEntity.js)
|
||||
const linkedCourseId = await resolveLinkedEntity('pkg', req.body.linked_course_id, userId);
|
||||
const linkedProjectId = await resolveLinkedEntity('project', req.body.linked_project_id, userId);
|
||||
const linkedBillboardId = await resolveLinkedEntity('billboard', req.body.linked_billboard_id, userId);
|
||||
const linkedShopId = await resolveLinkedEntity('shop', req.body.linked_shop_id, userId);
|
||||
const linkedShopProductId = await resolveLinkedEntity('shopproduct', req.body.linked_shop_product_id, userId);
|
||||
const linkedBookingId = await resolveLinkedEntity('booking', req.body.linked_booking_id, userId);
|
||||
const linkedCourseId = await resolveLinkedEntity('pkg', req.body.linked_course_id, userId)
|
||||
const linkedProjectId = await resolveLinkedEntity('project', req.body.linked_project_id, userId)
|
||||
const linkedBillboardId = await resolveLinkedEntity('billboard', req.body.linked_billboard_id, userId)
|
||||
const linkedShopId = await resolveLinkedEntity('shop', req.body.linked_shop_id, userId)
|
||||
const linkedShopProductId = await resolveLinkedEntity('shopproduct', req.body.linked_shop_product_id, userId)
|
||||
const linkedBookingId = await resolveLinkedEntity('booking', req.body.linked_booking_id, userId)
|
||||
|
||||
if (!files || files.length === 0) {
|
||||
console.log('DEBUG: No files provided');
|
||||
return res.status(400).json({ error: true, message: 'هیچ فایلی آپلود نشده است' });
|
||||
console.log('DEBUG: No files provided')
|
||||
return res.status(400).json({ error: true, message: 'هیچ فایلی آپلود نشده است' })
|
||||
}
|
||||
|
||||
const captionText =
|
||||
caption != null && String(caption).trim()
|
||||
? String(caption).trim().slice(0, 2000)
|
||||
: null;
|
||||
: null
|
||||
|
||||
const filePaths = files.map((file) => ({
|
||||
path: file.path,
|
||||
type: (file.mimetype || file.type || '').startsWith('video/') ? 'video' : 'image',
|
||||
}));
|
||||
type: (file.mimetype || file.type || '').startsWith('video/') ? 'video' : 'image'
|
||||
}))
|
||||
|
||||
const postMediaType = filePaths.some((file) => file.type === 'video')
|
||||
? 'video'
|
||||
: 'image';
|
||||
: 'image'
|
||||
|
||||
const moderation = resolvePostModerationStatus({ caption: captionText, filePaths });
|
||||
const author = await UserModel.findById(userId)
|
||||
.select('post_location_enabled lat lng verify_badge')
|
||||
.lean()
|
||||
|
||||
const moderation = resolvePostModerationStatus({ caption: captionText, filePaths, verifyBadge: author?.verify_badge })
|
||||
if (moderation.status === 'reject') {
|
||||
return res.status(422).json({
|
||||
error: true,
|
||||
message: 'متن پست با قوانین همخوانی ندارد و ثبت نشد.',
|
||||
});
|
||||
message: 'متن پست با قوانین همخوانی ندارد و ثبت نشد.'
|
||||
})
|
||||
}
|
||||
|
||||
console.log('DEBUG: Saving post to MongoDB, files:', filePaths.length);
|
||||
|
||||
const author = await UserModel.findById(userId)
|
||||
.select('post_location_enabled lat lng')
|
||||
.lean();
|
||||
console.log('DEBUG: Saving post to MongoDB, files:', filePaths.length)
|
||||
|
||||
const postPayload = {
|
||||
user_id: userId,
|
||||
@@ -117,26 +117,26 @@ const createPost = async (req, res) => {
|
||||
files: filePaths,
|
||||
type: postMediaType,
|
||||
tagged_users: taggedUserIds,
|
||||
status: moderation.status,
|
||||
};
|
||||
status: moderation.status
|
||||
}
|
||||
|
||||
if (linkedCourseId) {
|
||||
postPayload.linked_course_id = linkedCourseId;
|
||||
postPayload.linked_course_id = linkedCourseId
|
||||
}
|
||||
if (linkedProjectId) {
|
||||
postPayload.linked_project_id = linkedProjectId;
|
||||
postPayload.linked_project_id = linkedProjectId
|
||||
}
|
||||
if (linkedBillboardId) {
|
||||
postPayload.linked_billboard_id = linkedBillboardId;
|
||||
postPayload.linked_billboard_id = linkedBillboardId
|
||||
}
|
||||
if (linkedShopId) {
|
||||
postPayload.linked_shop_id = linkedShopId;
|
||||
postPayload.linked_shop_id = linkedShopId
|
||||
}
|
||||
if (linkedShopProductId) {
|
||||
postPayload.linked_shop_product_id = linkedShopProductId;
|
||||
postPayload.linked_shop_product_id = linkedShopProductId
|
||||
}
|
||||
if (linkedBookingId) {
|
||||
postPayload.linked_booking_id = linkedBookingId;
|
||||
postPayload.linked_booking_id = linkedBookingId
|
||||
}
|
||||
|
||||
if (
|
||||
@@ -146,77 +146,77 @@ const createPost = async (req, res) => {
|
||||
String(author.lat).trim() &&
|
||||
String(author.lng).trim()
|
||||
) {
|
||||
postPayload.lat = String(author.lat);
|
||||
postPayload.lng = String(author.lng);
|
||||
postPayload.lat = String(author.lat)
|
||||
postPayload.lng = String(author.lng)
|
||||
}
|
||||
|
||||
// کشور/شهر/استان پست — اختیاری، جدا از موقعیت پروفایل کاربر؛ کاربر خودش موقع ثبت پست انتخاب میکنه
|
||||
if (req.body.country_id) {
|
||||
const countryFind = await CountryModel.findOne({ id: req.body.country_id }, { _id: 0 });
|
||||
const countryFind = await CountryModel.findOne({ id: req.body.country_id }, { _id: 0 })
|
||||
if (countryFind) {
|
||||
postPayload.country = { id: countryFind.id, name: countryFind.name_fa, iso2: countryFind.iso2, slug: countryFind.slug };
|
||||
postPayload.country = { id: countryFind.id, name: countryFind.name_fa, iso2: countryFind.iso2, slug: countryFind.slug }
|
||||
}
|
||||
}
|
||||
if (req.body.province_id) {
|
||||
const provinceFind = await ProvinceModel.findOne({ id: req.body.province_id }, { _id: 0 });
|
||||
const provinceFind = await ProvinceModel.findOne({ id: req.body.province_id }, { _id: 0 })
|
||||
if (provinceFind) {
|
||||
postPayload.province = provinceFind;
|
||||
postPayload.province = provinceFind
|
||||
}
|
||||
}
|
||||
if (req.body.city_id) {
|
||||
const cityFind = await CityModel.findOne({ id: req.body.city_id });
|
||||
const cityFind = await CityModel.findOne({ id: req.body.city_id })
|
||||
if (cityFind) {
|
||||
postPayload.city = cityFind;
|
||||
postPayload.city = cityFind
|
||||
}
|
||||
}
|
||||
|
||||
const post = await savePostWithModerationStatus(PostModel, postPayload);
|
||||
console.log('DEBUG: Post saved:', post._id);
|
||||
const post = await savePostWithModerationStatus(PostModel, postPayload)
|
||||
console.log('DEBUG: Post saved:', post._id)
|
||||
|
||||
if (taggedUserIds.length > 0) {
|
||||
await createTagNotifications({
|
||||
taggerId: userId,
|
||||
taggedUserIds,
|
||||
postId: post._id
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
notifyFollowers(userId, post).catch((err) => {
|
||||
console.error('[notifyFollowers] background error:', err.message);
|
||||
});
|
||||
console.error('[notifyFollowers] background error:', err.message)
|
||||
})
|
||||
|
||||
const firstVideo = filePaths.find((file) => file.type === 'video');
|
||||
const firstVideo = filePaths.find((file) => file.type === 'video')
|
||||
if (firstVideo?.path) {
|
||||
processPostVideoInBackground(firstVideo.path, post._id).catch((err) => {
|
||||
console.error('[postVideoProcessing] background error:', err.message);
|
||||
});
|
||||
console.error('[postVideoProcessing] background error:', err.message)
|
||||
})
|
||||
}
|
||||
|
||||
res.status(201).json({
|
||||
message: 'پست ثبت شد و در حالت تایید موقت نمایش داده میشود',
|
||||
postId: post._id,
|
||||
status: post.status,
|
||||
});
|
||||
status: post.status
|
||||
})
|
||||
} catch (err) {
|
||||
console.error('DEBUG: createPost error:', err.message);
|
||||
console.error('DEBUG: createPost error:', err.message)
|
||||
if (err?.name === 'ValidationError') {
|
||||
return res.status(500).json({
|
||||
error: true,
|
||||
message: 'خطا در ثبت پست. مدل پست روی سرور بهروز نیست.',
|
||||
});
|
||||
message: 'خطا در ثبت پست. مدل پست روی سرور بهروز نیست.'
|
||||
})
|
||||
}
|
||||
res.status(500).json({ error: true, message: `خطا در سرور: ${err.message}` });
|
||||
res.status(500).json({ error: true, message: `خطا در سرور: ${err.message}` })
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function toPublicFilePath(filePath) {
|
||||
if (!filePath || typeof filePath !== 'string') return filePath;
|
||||
let s = filePath.replace(/\\/g, '/');
|
||||
const storageIdx = s.indexOf('/storage/');
|
||||
function toPublicFilePath (filePath) {
|
||||
if (!filePath || typeof filePath !== 'string') return filePath
|
||||
const s = filePath.replace(/\\/g, '/')
|
||||
const storageIdx = s.indexOf('/storage/')
|
||||
if (storageIdx >= 0) {
|
||||
return s.slice(storageIdx + '/storage'.length);
|
||||
return s.slice(storageIdx + '/storage'.length)
|
||||
}
|
||||
return s;
|
||||
return s
|
||||
}
|
||||
|
||||
const updatePost = async (req, res) => {
|
||||
@@ -231,148 +231,145 @@ const updatePost = async (req, res) => {
|
||||
}
|
||||
}
|
||||
if (!userId) {
|
||||
return res.status(401).json({ error: true, message: 'دسترسی غیرمجاز' });
|
||||
return res.status(401).json({ error: true, message: 'دسترسی غیرمجاز' })
|
||||
}
|
||||
const { postId, caption } = req.body;
|
||||
const files = req.files || [];
|
||||
const { postId, caption } = req.body
|
||||
const files = req.files || []
|
||||
|
||||
if (!postId || !mongoose.Types.ObjectId.isValid(postId)) {
|
||||
return res.status(400).json({ error: true, message: 'شناسه پست نامعتبر است' });
|
||||
return res.status(400).json({ error: true, message: 'شناسه پست نامعتبر است' })
|
||||
}
|
||||
|
||||
const post = await PostModel.findById(postId);
|
||||
const post = await PostModel.findById(postId)
|
||||
if (!post) {
|
||||
return res.status(404).json({ error: true, message: 'پست یافت نشد' });
|
||||
return res.status(404).json({ error: true, message: 'پست یافت نشد' })
|
||||
}
|
||||
|
||||
if (String(post.user_id) !== String(userId)) {
|
||||
return res.status(403).json({ error: true, message: 'اجازه ویرایش این پست را ندارید' });
|
||||
return res.status(403).json({ error: true, message: 'اجازه ویرایش این پست را ندارید' })
|
||||
}
|
||||
|
||||
let keepFiles = [];
|
||||
let keepFiles = []
|
||||
if (req.body.keep_files) {
|
||||
try {
|
||||
keepFiles = Array.isArray(req.body.keep_files)
|
||||
? req.body.keep_files
|
||||
: JSON.parse(req.body.keep_files);
|
||||
: JSON.parse(req.body.keep_files)
|
||||
} catch {
|
||||
keepFiles = [];
|
||||
keepFiles = []
|
||||
}
|
||||
}
|
||||
|
||||
const existingByPath = new Map(
|
||||
(post.files || []).map((f) => [toPublicFilePath(f.path), f])
|
||||
);
|
||||
)
|
||||
|
||||
const orderedExisting = [];
|
||||
const orderedExisting = []
|
||||
for (const item of keepFiles) {
|
||||
const rawPath = typeof item === 'string' ? item : item?.path;
|
||||
if (!rawPath) continue;
|
||||
const key = toPublicFilePath(rawPath);
|
||||
const rawPath = typeof item === 'string' ? item : item?.path
|
||||
if (!rawPath) continue
|
||||
const key = toPublicFilePath(rawPath)
|
||||
const found = existingByPath.get(key) ||
|
||||
(post.files || []).find((f) => toPublicFilePath(f.path) === key || f.path === rawPath);
|
||||
(post.files || []).find((f) => toPublicFilePath(f.path) === key || f.path === rawPath)
|
||||
if (found) {
|
||||
orderedExisting.push({
|
||||
path: found.path,
|
||||
type: found.type === 'video' ? 'video' : 'image',
|
||||
});
|
||||
type: found.type === 'video' ? 'video' : 'image'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const newFilePaths = (files || []).map((file) => ({
|
||||
path: file.path,
|
||||
type: (file.mimetype || file.type || '').startsWith('video/') ? 'video' : 'image',
|
||||
}));
|
||||
type: (file.mimetype || file.type || '').startsWith('video/') ? 'video' : 'image'
|
||||
}))
|
||||
|
||||
// اگر media_order ارسال شده: existing:index یا new:index
|
||||
let finalFiles = [...orderedExisting, ...newFilePaths];
|
||||
let finalFiles = [...orderedExisting, ...newFilePaths]
|
||||
if (req.body.media_order) {
|
||||
let order = [];
|
||||
let order = []
|
||||
try {
|
||||
order = Array.isArray(req.body.media_order)
|
||||
? req.body.media_order
|
||||
: JSON.parse(req.body.media_order);
|
||||
: JSON.parse(req.body.media_order)
|
||||
} catch {
|
||||
order = [];
|
||||
order = []
|
||||
}
|
||||
if (Array.isArray(order) && order.length) {
|
||||
const rebuilt = [];
|
||||
const rebuilt = []
|
||||
for (const token of order) {
|
||||
const value = String(token || '');
|
||||
const value = String(token || '')
|
||||
if (value.startsWith('existing:')) {
|
||||
const idx = Number(value.slice('existing:'.length));
|
||||
if (orderedExisting[idx]) rebuilt.push(orderedExisting[idx]);
|
||||
const idx = Number(value.slice('existing:'.length))
|
||||
if (orderedExisting[idx]) rebuilt.push(orderedExisting[idx])
|
||||
} else if (value.startsWith('new:')) {
|
||||
const idx = Number(value.slice('new:'.length));
|
||||
if (newFilePaths[idx]) rebuilt.push(newFilePaths[idx]);
|
||||
const idx = Number(value.slice('new:'.length))
|
||||
if (newFilePaths[idx]) rebuilt.push(newFilePaths[idx])
|
||||
}
|
||||
}
|
||||
if (rebuilt.length) finalFiles = rebuilt;
|
||||
if (rebuilt.length) finalFiles = rebuilt
|
||||
}
|
||||
}
|
||||
|
||||
if (!finalFiles.length) {
|
||||
return res.status(400).json({ error: true, message: 'حداقل یک فایل برای پست لازم است' });
|
||||
return res.status(400).json({ error: true, message: 'حداقل یک فایل برای پست لازم است' })
|
||||
}
|
||||
|
||||
if (caption != null) {
|
||||
const captionText = String(caption).trim()
|
||||
? String(caption).trim().slice(0, 2000)
|
||||
: null;
|
||||
: null
|
||||
const moderation = resolvePostModerationStatus({
|
||||
caption: captionText,
|
||||
filePaths: finalFiles,
|
||||
});
|
||||
filePaths: finalFiles
|
||||
})
|
||||
if (moderation.status === 'reject') {
|
||||
return res.status(422).json({
|
||||
error: true,
|
||||
message: 'متن پست با قوانین همخوانی ندارد و ثبت نشد.',
|
||||
});
|
||||
message: 'متن پست با قوانین همخوانی ندارد و ثبت نشد.'
|
||||
})
|
||||
}
|
||||
post.caption = captionText;
|
||||
post.status = moderation.status;
|
||||
post.caption = captionText
|
||||
post.status = moderation.status
|
||||
}
|
||||
|
||||
let taggedUserIds = post.tagged_users || [];
|
||||
let taggedUserIds = post.tagged_users || []
|
||||
if (req.body.tagged_user_ids !== undefined) {
|
||||
const raw = req.body.tagged_user_ids;
|
||||
let parsed = [];
|
||||
const raw = req.body.tagged_user_ids
|
||||
let parsed = []
|
||||
try {
|
||||
parsed = Array.isArray(raw) ? raw : (typeof raw === 'string' ? JSON.parse(raw) : []);
|
||||
parsed = Array.isArray(raw) ? raw : (typeof raw === 'string' ? JSON.parse(raw) : [])
|
||||
} catch {
|
||||
parsed = [];
|
||||
parsed = []
|
||||
}
|
||||
taggedUserIds = parsed
|
||||
.filter((id) => mongoose.Types.ObjectId.isValid(id))
|
||||
.slice(0, 50);
|
||||
post.tagged_users = taggedUserIds;
|
||||
.slice(0, 50)
|
||||
post.tagged_users = taggedUserIds
|
||||
}
|
||||
|
||||
post.files = finalFiles;
|
||||
post.type = finalFiles.some((f) => f.type === 'video') ? 'video' : 'image';
|
||||
post.updatedAt = new Date();
|
||||
await post.save();
|
||||
post.files = finalFiles
|
||||
post.type = finalFiles.some((f) => f.type === 'video') ? 'video' : 'image'
|
||||
post.updatedAt = new Date()
|
||||
await post.save()
|
||||
|
||||
const firstVideo = finalFiles.find((file) => file.type === 'video');
|
||||
const firstVideo = finalFiles.find((file) => file.type === 'video')
|
||||
if (firstVideo?.path) {
|
||||
processPostVideoInBackground(firstVideo.path, post._id).catch((err) => {
|
||||
console.error('[postVideoProcessing] background error:', err.message);
|
||||
});
|
||||
console.error('[postVideoProcessing] background error:', err.message)
|
||||
})
|
||||
}
|
||||
|
||||
return res.status(200).json({
|
||||
message: 'پست با موفقیت ویرایش شد',
|
||||
postId: post._id,
|
||||
status: post.status,
|
||||
});
|
||||
status: post.status
|
||||
})
|
||||
} catch (err) {
|
||||
console.error('DEBUG: updatePost error:', err.message);
|
||||
return res.status(500).json({ error: true, message: `خطا در سرور: ${err.message}` });
|
||||
console.error('DEBUG: updatePost error:', err.message)
|
||||
return res.status(500).json({ error: true, message: `خطا در سرور: ${err.message}` })
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
const getUserPosts = async (req, res, next) => {
|
||||
try {
|
||||
@@ -468,7 +465,7 @@ const getUserPostsWeb = async (req, res, next) => {
|
||||
posts: [],
|
||||
postsCount: 0,
|
||||
totalPages: 0,
|
||||
totalItems: 0,
|
||||
totalItems: 0
|
||||
})
|
||||
}
|
||||
|
||||
@@ -477,7 +474,7 @@ const getUserPostsWeb = async (req, res, next) => {
|
||||
posts: [],
|
||||
postsCount: 0,
|
||||
totalPages: 0,
|
||||
totalItems: 0,
|
||||
totalItems: 0
|
||||
})
|
||||
}
|
||||
|
||||
@@ -492,7 +489,7 @@ const getUserPostsWeb = async (req, res, next) => {
|
||||
postsCount: 0,
|
||||
totalPages: 0,
|
||||
totalItems: 0,
|
||||
privateLocked: true,
|
||||
privateLocked: true
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -524,8 +521,8 @@ const getUserPostsWeb = async (req, res, next) => {
|
||||
$or: [
|
||||
{ report_hidden: false },
|
||||
{ report_hidden: { $exists: false } },
|
||||
{ report_hidden: null },
|
||||
],
|
||||
{ report_hidden: null }
|
||||
]
|
||||
},
|
||||
options
|
||||
)
|
||||
@@ -611,14 +608,14 @@ const getPostByIdWeb = async (req, res, next) => {
|
||||
if (userReqId) {
|
||||
const like = await LikeModel.findOne({
|
||||
userId: userReqId,
|
||||
postId: post._id,
|
||||
postId: post._id
|
||||
}).lean()
|
||||
is_liked = !!like
|
||||
}
|
||||
|
||||
const commentsCount = await CommentModel.countDocuments({
|
||||
post: post._id,
|
||||
status: commentStatusFilter(),
|
||||
status: commentStatusFilter()
|
||||
})
|
||||
|
||||
let enrichedPost = {
|
||||
@@ -635,13 +632,13 @@ const getPostByIdWeb = async (req, res, next) => {
|
||||
profile_image: user.profile_image || '',
|
||||
likesCount: post.likes ? post.likes.length : 0,
|
||||
is_liked,
|
||||
commentsCount,
|
||||
commentsCount
|
||||
}
|
||||
|
||||
enrichedPost = await attachSinglePostEngagement(enrichedPost, userReqId)
|
||||
|
||||
return res.status(200).json({
|
||||
post: enrichedPost,
|
||||
post: enrichedPost
|
||||
})
|
||||
} catch (error) {
|
||||
next(error)
|
||||
|
||||
Reference in New Issue
Block a user