This commit is contained in:
payacom
2026-09-24 21:03:27 +03:30
parent 7f0ddfde70
commit 806471241e
43 changed files with 2166 additions and 144 deletions

View File

@@ -15,6 +15,8 @@ const {
const { resolveCommentModerationStatus } = require('../../../utils/contentModeration')
const { saveCommentWithModerationStatus } = require('../../../utils/commentStatusSave')
const { createCommentNotification, createRatingNotification } = require('../../../utils/commentNotification')
const { runAutoDirectRules } = require('../../../utils/autoDirectTrigger')
const { findActiveAd, buildAdPostItem, trackAdEvent } = require('../../../utils/adDelivery')
const { ProvinceModel, CityModel } = require('../../../models/StateCity')
const OfferModel = require('../../../models/OfferModel')
const PostModel = require('../../../models/PostModel')
@@ -49,6 +51,7 @@ const { buildAppearanceUserFilter } = require('../../../utils/appearanceFilter')
const { paginatePersonalizedExplore } = require('../../../utils/exploreAlgorithm')
const ExploreInteractionModel = require('../../../models/ExploreInteractionModel')
const { attachPostEngagementFields } = require('../../../utils/postEngagement')
const { resolveStoryFlags } = require('../../../utils/storyRingFlags')
const {
getFollowingReelsFeed,
getSavedReelsFeed,
@@ -1353,7 +1356,7 @@ const getPostsWeb = async (req, res, next) => {
explorePosts = await mapPostsWithUsers(explorePosts, usersMap, decodedToken)
const { posts: paginatedPosts, totalItems, isColdStart } =
let { posts: paginatedPosts, totalItems, isColdStart } =
await paginatePersonalizedExplore({
posts: explorePosts,
usersById,
@@ -1366,6 +1369,26 @@ const getPostsWeb = async (req, res, next) => {
cacheScope: reelsMode ? 'reels' : 'explore'
})
// تبلیغِ نوع first_post — فقط صفحه‌ی اول، فقط برای کاربرِ واردشده، خطاش هیچ‌وقت
// نباید فیدِ اصلی رو بشکنه (utils/adDelivery.js)
if (decodedToken?.id && parseInt(page, 10) === 1) {
try {
const viewer = await UserModel.findById(decodedToken.id)
.select('country province city gender expertise sub_expertise')
.lean()
const ad = await findActiveAd('first_post', { ...viewer, _id: decodedToken.id })
if (ad) {
const adPost = await buildAdPostItem(ad)
if (adPost) {
paginatedPosts = [adPost, ...paginatedPosts]
trackAdEvent(ad._id, 'view').catch(() => {})
}
}
} catch (adError) {
console.error('first_post ad injection error:', adError.message)
}
}
return res.status(200).json({
posts: paginatedPosts,
totalPages: Math.ceil(totalItems / limit) || 1,
@@ -2130,6 +2153,12 @@ const getComments = async (req, res, next) => {
return acc
}, {})
const commenterIds = [
...comments.docs.map((c) => c.creator._id),
...repliesRaw.map((r) => r.creator._id)
]
const storyFlags = await resolveStoryFlags(commenterIds, decodedToken.id)
const earliestRatedComments = await CommentModel.find({
user: user_id,
rating: { $ne: null, $gt: 0 }
@@ -2164,7 +2193,9 @@ const getComments = async (req, res, next) => {
user_name: comment.creator.user_name,
is_verified: comment.creator.is_verified,
verify_badge: comment.creator.verify_badge,
_id: comment.creator._id
_id: comment.creator._id,
has_story: storyFlags[creatorId]?.has_story || false,
has_unviewed_story: storyFlags[creatorId]?.has_unviewed_story || false
},
project: comment.project ? comment.project.project_name : null,
post_id: comment.post ? comment.post.toString() : null,
@@ -2307,6 +2338,17 @@ const createUserComment = async (req, res, next) => {
type: commentType
})
if (targetPostId) {
void runAutoDirectRules({
io: req.app.get('io'),
postOwnerId: ownerId,
commenterId: creatorId,
commentId: newComment._id,
postId: targetPostId,
commentText: comment
})
}
if (isNewRating && ratingValue > 0) {
await createRatingNotification({
io: req.app.get('io'),