full app
This commit is contained in:
72
models/AdModel.js
Normal file
72
models/AdModel.js
Normal file
@@ -0,0 +1,72 @@
|
||||
const mongoose = require('mongoose')
|
||||
const timestamp = require('mongoose-timestamp')
|
||||
const mongoosePaginate = require('mongoose-paginate-v2')
|
||||
|
||||
// تبلیغِ کاربری — نوعش تعیین میکنه محتواش کجا تزریق میشه: first_post (اول فید)،
|
||||
// first_story (اول نوار استوری)، notification (پوش مستقیم به کاربرهای هدف)، project/
|
||||
// product/shop/billboard (اول لیستِ مربوطه، از utils/adDelivery.js:findActiveAd با همون
|
||||
// ad_type resolve میشه). هدفگذاری (لوکیشن/تخصص/جنسیت) روی همون فیلدهایی که
|
||||
// User/Post/exploreAlgorithm.js از قبل استفاده میکنن سوار شده (province.id عددیه، نه
|
||||
// ObjectId — utils/adPricing.js همین رو resolve میکنه)
|
||||
const AD_TYPES = ['first_post', 'first_story', 'notification', 'project', 'product', 'shop', 'billboard']
|
||||
|
||||
const adSchema = new mongoose.Schema({
|
||||
user_id: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
|
||||
ad_type: { type: String, enum: AD_TYPES, required: true },
|
||||
|
||||
// محتوا — بسته به ad_type فقط یکی از این پر میشه
|
||||
content_post_id: { type: mongoose.Schema.Types.ObjectId, ref: 'Post', default: null },
|
||||
content_project_id: { type: mongoose.Schema.Types.ObjectId, ref: 'Project', default: null },
|
||||
content_shop_product_id: { type: mongoose.Schema.Types.ObjectId, ref: 'ShopProductListing', default: null },
|
||||
content_shop_id: { type: mongoose.Schema.Types.ObjectId, ref: 'Shop', default: null },
|
||||
content_billboard_id: { type: mongoose.Schema.Types.ObjectId, ref: 'Advertising', default: null },
|
||||
// استوریهای واقعی معمولاً ۲۴ساعته منقضی میشن (StoryModel: expires_at) و از فیدِ
|
||||
// استوریِ معمولی حذف میشن، ولی یه کمپینِ تبلیغاتی میتونه چند روز فعال بمونه — پس
|
||||
// مدیا/اورلیها رو موقعِ ساختِ تبلیغ اینجا کپی/اسنپشات میکنیم تا مستقل از عمرِ
|
||||
// طبیعیِ خودِ استوری باشه (content_story_id فقط برای رفرنسِ منبع نگه داشته میشه)
|
||||
content_story_id: { type: mongoose.Schema.Types.ObjectId, ref: 'Story', default: null },
|
||||
content_media_path: { type: String, default: null },
|
||||
content_media_type: { type: String, default: null },
|
||||
content_overlays: { type: mongoose.Schema.Types.Mixed, default: null },
|
||||
notification_title: { type: String, trim: true, default: null },
|
||||
notification_body: { type: String, trim: true, default: null },
|
||||
|
||||
// هدفگذاری
|
||||
target_country_id: { type: Number, default: null },
|
||||
target_province_id: { type: Number, default: null },
|
||||
target_city_id: { type: Number, default: null },
|
||||
target_expertise: { type: String, trim: true, default: null },
|
||||
target_sub_expertise: { type: [String], default: [] },
|
||||
target_gender: { type: String, enum: ['female', 'male', 'any'], default: 'any' },
|
||||
|
||||
// مالی
|
||||
price: { type: Number, required: true },
|
||||
walletAmountUsed: { type: Number, default: 0 },
|
||||
payment_authority: { type: String, default: null },
|
||||
|
||||
status: {
|
||||
type: String,
|
||||
enum: ['pending_payment', 'active', 'expired', 'failed'],
|
||||
default: 'pending_payment'
|
||||
},
|
||||
started_at: { type: Date, default: null },
|
||||
// عین بقیهی کمپینهای اپ، یه مدتزمانِ ثابت (AD_CAMPAIGN_DURATION_DAYS توی
|
||||
// adsController.js) بعد از فعالشدن — بعدش دیگه توی تزریقِ فید/استوری/نوتیف لحاظ نمیشه
|
||||
expires_at: { type: Date, default: null },
|
||||
|
||||
views_count: { type: Number, default: 0 },
|
||||
clicks_count: { type: Number, default: 0 }
|
||||
})
|
||||
|
||||
// تزریق (سرچِ یه تبلیغِ فعالِ منطبق روی فید/استوری) و لیستِ «تبلیغهای من» دو مصرفِ
|
||||
// اصلیِ ایندکسن
|
||||
adSchema.index({ status: 1, ad_type: 1, expires_at: 1 })
|
||||
adSchema.index({ user_id: 1, createdAt: -1 })
|
||||
|
||||
adSchema.plugin(timestamp)
|
||||
adSchema.plugin(mongoosePaginate)
|
||||
const AdModel = mongoose.model('Ad', adSchema)
|
||||
// روی خودِ مدل بهعنوان استاتیک — تا adsController.js/adsPanelController.js بدونِ
|
||||
// require جدا به لیستِ معتبرِ ad_type دسترسی داشته باشن (module.exports همون مدله، نه یه آبجکت)
|
||||
AdModel.AD_TYPES = AD_TYPES
|
||||
module.exports = AdModel
|
||||
Reference in New Issue
Block a user