This commit is contained in:
payacom
2026-09-03 16:06:02 +03:30
parent 3f416a7a60
commit 90c5f94b57
31 changed files with 3968 additions and 4283 deletions

View File

@@ -8,8 +8,9 @@ const {
canCreateProject,
respondProjectProfileIncomplete
} = require('../../../utils/projectProfile')
const { isVerifiedBadge } = require('../../../utils/verifyBadge')
async function activateFreeProjectIfEligible(user, project) {
async function activateFreeProjectIfEligible (user, project) {
if (project.project_type !== 'free') return { activated: false }
if (!user.daily_free_request || user.daily_free_request <= 0) {
@@ -22,12 +23,14 @@ async function activateFreeProjectIfEligible(user, project) {
user.daily_free_request -= 1
await user.save()
project.payment_status = 'done'
project.status = 'temp_accept'
// کاربرِ بدون تیک وریفای طلایی/سبز/آبی باید از پنل ادمین تایید بشه تا پروژه‌ش
// مستقیم توی اپ/وب نمایش داده نشه
project.status = isVerifiedBadge(user.verify_badge) ? 'temp_accept' : 'pending'
await project.save()
return { activated: true }
}
function normalizeRoles(roles) {
function normalizeRoles (roles) {
if (!Array.isArray(roles)) return []
return roles.slice(0, 5).map((role) => ({
expertise: role.expertise,
@@ -49,7 +52,7 @@ function normalizeRoles(roles) {
})).filter((role) => role.expertise)
}
function buildAgeLabel(age, ageMin, ageMax) {
function buildAgeLabel (age, ageMin, ageMax) {
if (age) return age
if (ageMin != null && ageMax != null) return `${ageMin}-${ageMax}`
if (ageMin != null) return `${ageMin}+`

View File

@@ -51,8 +51,11 @@ const REQUEST_USER_SELECT =
'user_level first_name last_name user_name is_verified verify_badge user_score rate profile_image'
const enrichProjectsWithRequests = async (projectDocs) => {
// با lean:true دیگه project یه Mongoose document نیست، یه آبجکتِ ساده‌ست —
// پس toObject() نداره و project._doc هم undefined می‌شه (که spread‌کردنش
// آبجکتِ خالی می‌داد و همه‌ی فیلدهای پروژه رو پاک می‌کرد)
const docs = projectDocs.map((project) =>
project.toObject ? project.toObject() : { ...project._doc }
typeof project.toObject === 'function' ? project.toObject() : { ...project }
)
const projectIds = docs
@@ -121,7 +124,8 @@ const getProjects = async (req, res, next) => {
const options = {
page: parseInt(page), // تبدیل صفحه به عدد صحیح
limit: parseInt(limit), // تبدیل محدودیت به عدد صحیح
sort: most_price === 'true' ? { offer_price: -1 } : { requested_users: 'desc' }
sort: most_price === 'true' ? { offer_price: -1 } : { requested_users: 'desc' },
lean: true
}
const projects = await ProjectModel.paginate(filter, options)
@@ -136,7 +140,8 @@ const getProjects = async (req, res, next) => {
const options = {
page: parseInt(page), // تبدیل صفحه به عدد صحیح
limit: parseInt(limit), // تبدیل محدودیت به عدد صحیح
sort: { acceptedAt: -1, createdAt: -1 } // مرتب‌سازی بر اساس acceptedAt و سپس createdAt
sort: { acceptedAt: -1, createdAt: -1 }, // مرتب‌سازی بر اساس acceptedAt و سپس createdAt
lean: true
}
const projects = await ProjectModel.paginate(filter, options)
let newProj = await enrichProjectsWithRequests(projects.docs)

View File

@@ -37,6 +37,8 @@ const saveProjectComment = async ({
return { error: { status: 400, message: 'Rating must be between 1 and 5' } }
}
const creatorUser = await UserModel.findById(creatorId).select('verify_badge').lean()
const newComment = await saveCommentWithModerationStatus(
CommentModel,
{
@@ -45,9 +47,10 @@ const saveProjectComment = async ({
creator: creatorId,
rating: ratingValue,
comment,
comment_for: commentFor,
comment_for: commentFor
},
'comment'
'comment',
creatorUser?.verify_badge
)
if (isNewRating && commentFor === 'user') {