const mongoose = require('mongoose'); const notificationSchema = new mongoose.Schema( { user: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: [true, 'Notification must belong to a user'], index: true, }, title: { type: String, required: [true, 'Notification must have a title'], trim: true, }, message: { type: String, required: [true, 'Notification must have a message'], }, type: { type: String, enum: [ 'order_created', 'order_confirmed', 'order_shipped', 'order_delivered', 'order_cancelled', 'product_out_of_stock', 'product_back_in_stock', 'promo_code', 'newsletter', 'review_response', 'system', 'general', ], default: 'general', }, relatedId: { type: mongoose.Schema.Types.ObjectId, // This can reference different collections based on type (Order, Product, etc.) }, relatedModel: { type: String, enum: ['Order', 'Product', 'PromoCode', 'Review', null], }, isRead: { type: Boolean, default: false, index: true, }, readAt: { type: Date, }, priority: { type: String, enum: ['low', 'medium', 'high'], default: 'medium', }, metadata: { type: mongoose.Schema.Types.Mixed, // Additional data specific to notification type }, }, { timestamps: true, toJSON: { virtuals: true }, toObject: { virtuals: true }, }, ); // Indexes for better query performance notificationSchema.index({ user: 1, createdAt: -1 }); notificationSchema.index({ user: 1, isRead: 1 }); // Middleware to update readAt when isRead changes to true notificationSchema.pre('save', function (next) { if (this.isModified('isRead') && this.isRead && !this.readAt) { this.readAt = new Date(); } next(); }); const Notification = mongoose.model('Notification', notificationSchema); module.exports = Notification;