diff --git a/controllers/application/shop-products/shopProductController.js b/controllers/application/shop-products/shopProductController.js index b0e373f..70f7023 100644 --- a/controllers/application/shop-products/shopProductController.js +++ b/controllers/application/shop-products/shopProductController.js @@ -58,12 +58,13 @@ const searchCatalog = async (req, res, next) => { return res.json({ products: [] }) } - const products = await ProductCatalogModel.find( - { $text: { $search: q } }, - { score: { $meta: 'textScore' } } - ) - .sort({ score: { $meta: 'textScore' } }) - .limit(20) + // قبلاً $text (جستجوی متنیِ کاملِ مونگو) بود که فقط با کلمه‌ی کامل/ریشه‌شده مچ می‌شد، + // نه با بخشی از یه کلمه — با اینکه کاربر دقیقاً خواسته بود «قسمتی از نام کالا رو + // وارد کنی» (عینِ جستجوی کاربر که $regex استفاده می‌کنه، نه $text) + const escaped = q.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + const products = await ProductCatalogModel.find({ + name: { $regex: escaped, $options: 'i' } + }).limit(20) return res.json({ products }) } catch (error) { @@ -169,7 +170,12 @@ const createShopProduct = async (req, res, next) => { category: clonedFields.category || null, sub_category: clonedFields.sub_category || null, sub_sub_category: clonedFields.sub_sub_category || null, - status: isCloned ? 'pending_shop_approval' : (shop.status === 'active' ? 'active' : 'pending_shop_approval') + // قبلاً اگه خودِ فروشگاه active بود، کالای تازه‌ساخته (همین قدمِ اول، فقط نام — بدون + // واریانت/تصویر/دسته‌بندی) بلافاصله status:'active' می‌گرفت و توی فیدِ دیسکاور عمومی + // نمایش داده می‌شد، با اینکه هنوز کاربر ویزارد رو تموم نکرده بود (کالاهای نیمه‌کاره/ + // آزمایشی مثل عنوانِ خالی یا فقط یه عدد). الان همیشه pending می‌مونه تا قدمِ آخرِ + // ویزارد (NewProductVariantsScreen.tsx submit) صریحاً status:'active' رو ست کنه + status: 'pending_shop_approval' }) return res.json({ message: 'کالا با موفقیت ثبت شد', listing, catalogProduct }) @@ -312,9 +318,10 @@ const getShopProducts = async (req, res, next) => { const getShopProductById = async (req, res, next) => { try { - const listing = await ShopProductListingModel.findById(req.params.id).populate( - 'catalogProduct shop' - ) + const listing = await ShopProductListingModel.findById(req.params.id).populate([ + { path: 'catalogProduct' }, + { path: 'shop', populate: { path: 'owner', select: 'verify_badge' } } + ]) if (!listing) return productError(res, 404, 'کالا یافت نشد') return res.json({ listing }) } catch (error) { @@ -337,7 +344,10 @@ const getCatalogListings = async (req, res, next) => { const listings = await ShopProductListingModel.find({ catalogProduct: catalogId, status: 'active' - }).populate('shop catalogProduct') + }).populate([ + { path: 'shop', populate: { path: 'owner', select: 'verify_badge' } }, + { path: 'catalogProduct' } + ]) const visible = listings.filter((listing) => listing.shop?.status === 'active') visible.sort((a, b) => cheapestVariantPrice(a) - cheapestVariantPrice(b)) @@ -449,7 +459,7 @@ const getDiscoverFeed = async (req, res, next) => { ...validTaggedPosts.map((p) => String(p.linked_shop_product_id.shop)) ]) ] - const shops = await ShopModel.find({ _id: { $in: shopIds } }) + const shops = await ShopModel.find({ _id: { $in: shopIds } }).populate('owner', 'verify_badge') const shopMap = new Map(shops.map((s) => [String(s._id), s])) const catalogIds = [...new Set(docs.map((d) => String(d.catalogProduct)).filter(Boolean))] diff --git a/controllers/application/shops/shopController.js b/controllers/application/shops/shopController.js index d8e65d4..9834e3e 100644 --- a/controllers/application/shops/shopController.js +++ b/controllers/application/shops/shopController.js @@ -176,6 +176,7 @@ const getShopById = async (req, res, next) => { const { shop, error } = await findOwnedShop(req.params.id, req.user._id) if (error === 'NOT_FOUND') return shopError(res, 404, 'فروشگاه یافت نشد') if (error === 'FORBIDDEN') return shopError(res, 403, 'شما مالک این فروشگاه نیستید') + await shop.populate('owner', 'verify_badge') return res.json({ shop }) } catch (error) { next(error) @@ -202,7 +203,7 @@ const updateShopBasic = async (req, res, next) => { /** Public shop profile: visible to any visitor once active; owner can preview it before that. */ const getShopPublic = async (req, res, next) => { try { - const shop = await ShopModel.findById(req.params.id).populate('owner', 'user_name first_name last_name profile_image') + const shop = await ShopModel.findById(req.params.id).populate('owner', 'user_name first_name last_name profile_image verify_badge') if (!shop) return shopError(res, 404, 'فروشگاه یافت نشد') const currentUserId = getOptionalUserId(req)