@mac777/project-pinecone-models 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/Event.d.ts CHANGED
@@ -4,7 +4,6 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
4
4
  createdAt: NativeDate;
5
5
  updatedAt: NativeDate;
6
6
  status: "approved" | "rejected" | "draft" | "pending_approval" | "published" | "live" | "ended" | "cancelled";
7
- visibility: "public" | "private" | "unlisted";
8
7
  hostId: mongoose.Types.ObjectId;
9
8
  title: string;
10
9
  categories: string[];
@@ -12,15 +11,14 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
12
11
  languages: string[];
13
12
  tickets: mongoose.Types.DocumentArray<{
14
13
  name: string;
15
- status: "active" | "sold_out" | "inactive";
16
14
  quantity: number;
17
15
  sold: number;
18
- remaining: number;
19
- visibility: "hidden" | "public" | "invite_only";
20
16
  reserved: number;
17
+ isActive: boolean;
18
+ isVisible: boolean;
19
+ wristbandColor: string;
21
20
  benefits: string[];
22
21
  tier: string;
23
- description?: string | null | undefined;
24
22
  price?: {
25
23
  amount: number;
26
24
  currency: string;
@@ -35,15 +33,14 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
35
33
  } | null | undefined;
36
34
  }, mongoose.Types.Subdocument<mongoose.mongo.BSON.ObjectId, any, {
37
35
  name: string;
38
- status: "active" | "sold_out" | "inactive";
39
36
  quantity: number;
40
37
  sold: number;
41
- remaining: number;
42
- visibility: "hidden" | "public" | "invite_only";
43
38
  reserved: number;
39
+ isActive: boolean;
40
+ isVisible: boolean;
41
+ wristbandColor: string;
44
42
  benefits: string[];
45
43
  tier: string;
46
- description?: string | null | undefined;
47
44
  price?: {
48
45
  amount: number;
49
46
  currency: string;
@@ -58,15 +55,14 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
58
55
  } | null | undefined;
59
56
  }> & {
60
57
  name: string;
61
- status: "active" | "sold_out" | "inactive";
62
58
  quantity: number;
63
59
  sold: number;
64
- remaining: number;
65
- visibility: "hidden" | "public" | "invite_only";
66
60
  reserved: number;
61
+ isActive: boolean;
62
+ isVisible: boolean;
63
+ wristbandColor: string;
67
64
  benefits: string[];
68
65
  tier: string;
69
- description?: string | null | undefined;
70
66
  price?: {
71
67
  amount: number;
72
68
  currency: string;
@@ -83,6 +79,7 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
83
79
  termsAccepted: boolean;
84
80
  legalPermissionAccepted: boolean;
85
81
  platformTermsAccepted: boolean;
82
+ visibility: "public" | "private" | "unlisted";
86
83
  history: mongoose.Types.DocumentArray<{
87
84
  timestamp: NativeDate;
88
85
  action?: string | null | undefined;
@@ -195,15 +192,20 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
195
192
  publishedAt?: NativeDate | null | undefined;
196
193
  metrics?: {
197
194
  views: number;
195
+ uniqueViews: number;
196
+ totalOrders: number;
198
197
  ticketsSold: number;
199
198
  revenue: number;
200
199
  checkIns: number;
200
+ uniqueViewers: mongoose.Types.ObjectId[];
201
201
  reviewCount: number;
202
+ conversionRate: number;
203
+ lastViewedAt?: NativeDate | null | undefined;
202
204
  averageRating?: number | null | undefined;
203
205
  } | null | undefined;
204
206
  pricing?: {
207
+ currency: string;
205
208
  platformFee: number;
206
- currency?: string | null | undefined;
207
209
  paymentProcessingFee?: number | null | undefined;
208
210
  } | null | undefined;
209
211
  payout?: {
@@ -244,6 +246,8 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
244
246
  isFlagged: boolean;
245
247
  suspendedUntil?: NativeDate | null | undefined;
246
248
  banReason?: string | null | undefined;
249
+ suspendedAt?: NativeDate | null | undefined;
250
+ suspensionReason?: string | null | undefined;
247
251
  } | null | undefined;
248
252
  seo?: {
249
253
  keywords: string[];
@@ -255,6 +259,8 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
255
259
  isFeatured: boolean;
256
260
  isPremium: boolean;
257
261
  badges: string[];
262
+ featuredPriority: number;
263
+ featuredAt?: NativeDate | null | undefined;
258
264
  } | null | undefined;
259
265
  submittedAt?: NativeDate | null | undefined;
260
266
  deletedAt?: NativeDate | null | undefined;
@@ -265,7 +271,6 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
265
271
  createdAt: NativeDate;
266
272
  updatedAt: NativeDate;
267
273
  status: "approved" | "rejected" | "draft" | "pending_approval" | "published" | "live" | "ended" | "cancelled";
268
- visibility: "public" | "private" | "unlisted";
269
274
  hostId: mongoose.Types.ObjectId;
270
275
  title: string;
271
276
  categories: string[];
@@ -273,15 +278,14 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
273
278
  languages: string[];
274
279
  tickets: mongoose.Types.DocumentArray<{
275
280
  name: string;
276
- status: "active" | "sold_out" | "inactive";
277
281
  quantity: number;
278
282
  sold: number;
279
- remaining: number;
280
- visibility: "hidden" | "public" | "invite_only";
281
283
  reserved: number;
284
+ isActive: boolean;
285
+ isVisible: boolean;
286
+ wristbandColor: string;
282
287
  benefits: string[];
283
288
  tier: string;
284
- description?: string | null | undefined;
285
289
  price?: {
286
290
  amount: number;
287
291
  currency: string;
@@ -296,15 +300,14 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
296
300
  } | null | undefined;
297
301
  }, mongoose.Types.Subdocument<mongoose.mongo.BSON.ObjectId, any, {
298
302
  name: string;
299
- status: "active" | "sold_out" | "inactive";
300
303
  quantity: number;
301
304
  sold: number;
302
- remaining: number;
303
- visibility: "hidden" | "public" | "invite_only";
304
305
  reserved: number;
306
+ isActive: boolean;
307
+ isVisible: boolean;
308
+ wristbandColor: string;
305
309
  benefits: string[];
306
310
  tier: string;
307
- description?: string | null | undefined;
308
311
  price?: {
309
312
  amount: number;
310
313
  currency: string;
@@ -319,15 +322,14 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
319
322
  } | null | undefined;
320
323
  }> & {
321
324
  name: string;
322
- status: "active" | "sold_out" | "inactive";
323
325
  quantity: number;
324
326
  sold: number;
325
- remaining: number;
326
- visibility: "hidden" | "public" | "invite_only";
327
327
  reserved: number;
328
+ isActive: boolean;
329
+ isVisible: boolean;
330
+ wristbandColor: string;
328
331
  benefits: string[];
329
332
  tier: string;
330
- description?: string | null | undefined;
331
333
  price?: {
332
334
  amount: number;
333
335
  currency: string;
@@ -344,6 +346,7 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
344
346
  termsAccepted: boolean;
345
347
  legalPermissionAccepted: boolean;
346
348
  platformTermsAccepted: boolean;
349
+ visibility: "public" | "private" | "unlisted";
347
350
  history: mongoose.Types.DocumentArray<{
348
351
  timestamp: NativeDate;
349
352
  action?: string | null | undefined;
@@ -456,15 +459,20 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
456
459
  publishedAt?: NativeDate | null | undefined;
457
460
  metrics?: {
458
461
  views: number;
462
+ uniqueViews: number;
463
+ totalOrders: number;
459
464
  ticketsSold: number;
460
465
  revenue: number;
461
466
  checkIns: number;
467
+ uniqueViewers: mongoose.Types.ObjectId[];
462
468
  reviewCount: number;
469
+ conversionRate: number;
470
+ lastViewedAt?: NativeDate | null | undefined;
463
471
  averageRating?: number | null | undefined;
464
472
  } | null | undefined;
465
473
  pricing?: {
474
+ currency: string;
466
475
  platformFee: number;
467
- currency?: string | null | undefined;
468
476
  paymentProcessingFee?: number | null | undefined;
469
477
  } | null | undefined;
470
478
  payout?: {
@@ -505,6 +513,8 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
505
513
  isFlagged: boolean;
506
514
  suspendedUntil?: NativeDate | null | undefined;
507
515
  banReason?: string | null | undefined;
516
+ suspendedAt?: NativeDate | null | undefined;
517
+ suspensionReason?: string | null | undefined;
508
518
  } | null | undefined;
509
519
  seo?: {
510
520
  keywords: string[];
@@ -516,6 +526,8 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
516
526
  isFeatured: boolean;
517
527
  isPremium: boolean;
518
528
  badges: string[];
529
+ featuredPriority: number;
530
+ featuredAt?: NativeDate | null | undefined;
519
531
  } | null | undefined;
520
532
  submittedAt?: NativeDate | null | undefined;
521
533
  deletedAt?: NativeDate | null | undefined;
@@ -526,7 +538,6 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
526
538
  createdAt: NativeDate;
527
539
  updatedAt: NativeDate;
528
540
  status: "approved" | "rejected" | "draft" | "pending_approval" | "published" | "live" | "ended" | "cancelled";
529
- visibility: "public" | "private" | "unlisted";
530
541
  hostId: mongoose.Types.ObjectId;
531
542
  title: string;
532
543
  categories: string[];
@@ -534,15 +545,14 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
534
545
  languages: string[];
535
546
  tickets: mongoose.Types.DocumentArray<{
536
547
  name: string;
537
- status: "active" | "sold_out" | "inactive";
538
548
  quantity: number;
539
549
  sold: number;
540
- remaining: number;
541
- visibility: "hidden" | "public" | "invite_only";
542
550
  reserved: number;
551
+ isActive: boolean;
552
+ isVisible: boolean;
553
+ wristbandColor: string;
543
554
  benefits: string[];
544
555
  tier: string;
545
- description?: string | null | undefined;
546
556
  price?: {
547
557
  amount: number;
548
558
  currency: string;
@@ -557,15 +567,14 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
557
567
  } | null | undefined;
558
568
  }, mongoose.Types.Subdocument<mongoose.mongo.BSON.ObjectId, any, {
559
569
  name: string;
560
- status: "active" | "sold_out" | "inactive";
561
570
  quantity: number;
562
571
  sold: number;
563
- remaining: number;
564
- visibility: "hidden" | "public" | "invite_only";
565
572
  reserved: number;
573
+ isActive: boolean;
574
+ isVisible: boolean;
575
+ wristbandColor: string;
566
576
  benefits: string[];
567
577
  tier: string;
568
- description?: string | null | undefined;
569
578
  price?: {
570
579
  amount: number;
571
580
  currency: string;
@@ -580,15 +589,14 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
580
589
  } | null | undefined;
581
590
  }> & {
582
591
  name: string;
583
- status: "active" | "sold_out" | "inactive";
584
592
  quantity: number;
585
593
  sold: number;
586
- remaining: number;
587
- visibility: "hidden" | "public" | "invite_only";
588
594
  reserved: number;
595
+ isActive: boolean;
596
+ isVisible: boolean;
597
+ wristbandColor: string;
589
598
  benefits: string[];
590
599
  tier: string;
591
- description?: string | null | undefined;
592
600
  price?: {
593
601
  amount: number;
594
602
  currency: string;
@@ -605,6 +613,7 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
605
613
  termsAccepted: boolean;
606
614
  legalPermissionAccepted: boolean;
607
615
  platformTermsAccepted: boolean;
616
+ visibility: "public" | "private" | "unlisted";
608
617
  history: mongoose.Types.DocumentArray<{
609
618
  timestamp: NativeDate;
610
619
  action?: string | null | undefined;
@@ -717,15 +726,20 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
717
726
  publishedAt?: NativeDate | null | undefined;
718
727
  metrics?: {
719
728
  views: number;
729
+ uniqueViews: number;
730
+ totalOrders: number;
720
731
  ticketsSold: number;
721
732
  revenue: number;
722
733
  checkIns: number;
734
+ uniqueViewers: mongoose.Types.ObjectId[];
723
735
  reviewCount: number;
736
+ conversionRate: number;
737
+ lastViewedAt?: NativeDate | null | undefined;
724
738
  averageRating?: number | null | undefined;
725
739
  } | null | undefined;
726
740
  pricing?: {
741
+ currency: string;
727
742
  platformFee: number;
728
- currency?: string | null | undefined;
729
743
  paymentProcessingFee?: number | null | undefined;
730
744
  } | null | undefined;
731
745
  payout?: {
@@ -766,6 +780,8 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
766
780
  isFlagged: boolean;
767
781
  suspendedUntil?: NativeDate | null | undefined;
768
782
  banReason?: string | null | undefined;
783
+ suspendedAt?: NativeDate | null | undefined;
784
+ suspensionReason?: string | null | undefined;
769
785
  } | null | undefined;
770
786
  seo?: {
771
787
  keywords: string[];
@@ -777,6 +793,8 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
777
793
  isFeatured: boolean;
778
794
  isPremium: boolean;
779
795
  badges: string[];
796
+ featuredPriority: number;
797
+ featuredAt?: NativeDate | null | undefined;
780
798
  } | null | undefined;
781
799
  submittedAt?: NativeDate | null | undefined;
782
800
  deletedAt?: NativeDate | null | undefined;
package/dist/Event.js CHANGED
@@ -77,24 +77,22 @@ const salesWindowSchema = new mongoose_1.default.Schema({
77
77
  startDate: Date,
78
78
  endDate: Date,
79
79
  }, { _id: false });
80
- const limitsSchema = new mongoose_1.default.Schema({
81
- minPerOrder: { type: Number, default: 1 },
82
- maxPerOrder: { type: Number, default: 10 },
83
- }, { _id: false });
84
80
  const ticketSchema = new mongoose_1.default.Schema({
85
81
  name: { type: String, required: true },
86
- description: String,
87
82
  price: priceSchema,
88
83
  quantity: { type: Number, required: true },
89
84
  sold: { type: Number, default: 0 },
90
- remaining: { type: Number, default: function () { return this.quantity - this.sold; } },
91
- salesWindow: salesWindowSchema,
92
- limits: limitsSchema,
93
- visibility: { type: String, enum: ['public', 'hidden', 'invite_only'], default: 'public' },
94
85
  reserved: { type: Number, default: 0 },
95
- status: { type: String, enum: ['active', 'sold_out', 'inactive'], default: 'active' },
86
+ isActive: { type: Boolean, default: true },
87
+ isVisible: { type: Boolean, default: true },
88
+ wristbandColor: { type: String, default: '#000000' },
89
+ limits: {
90
+ minPerOrder: { type: Number, default: 1 },
91
+ maxPerOrder: { type: Number, default: 10 },
92
+ },
96
93
  benefits: [String],
97
- tier: { type: String, required: true, default: 'regular' },
94
+ tier: { type: String, default: 'regular' },
95
+ salesWindow: salesWindowSchema,
98
96
  });
99
97
  const scheduleSchema = new mongoose_1.default.Schema({
100
98
  startDate: { type: Date, required: true },
@@ -105,16 +103,28 @@ const scheduleSchema = new mongoose_1.default.Schema({
105
103
  }, { _id: false });
106
104
  const metricsSchema = new mongoose_1.default.Schema({
107
105
  views: { type: Number, default: 0 },
106
+ uniqueViews: { type: Number, default: 0 },
107
+ totalOrders: { type: Number, default: 0 },
108
108
  ticketsSold: { type: Number, default: 0 },
109
109
  revenue: { type: Number, default: 0 },
110
110
  checkIns: { type: Number, default: 0 },
111
+ uniqueViewers: {
112
+ type: [mongoose_1.default.Schema.Types.ObjectId],
113
+ default: []
114
+ },
115
+ lastViewedAt: Date, // for trending calculation
116
+ // --- For Review ---
111
117
  averageRating: Number,
112
118
  reviewCount: { type: Number, default: 0 },
119
+ conversionRate: { type: Number, default: 0 }, // (ticketsSold / views) * 100
113
120
  }, { _id: false });
114
121
  const pricingSchema = new mongoose_1.default.Schema({
115
122
  platformFee: { type: Number, default: 5 },
116
123
  paymentProcessingFee: Number,
117
- currency: String,
124
+ currency: {
125
+ type: String,
126
+ default: 'BDT'
127
+ },
118
128
  }, { _id: false });
119
129
  const payoutSchema = new mongoose_1.default.Schema({
120
130
  status: { type: String, enum: ['pending', 'scheduled', 'completed'] },
@@ -144,6 +154,8 @@ const moderationSchema = new mongoose_1.default.Schema({
144
154
  flags: [flagSchema],
145
155
  suspendedUntil: Date,
146
156
  banReason: String,
157
+ suspendedAt: Date,
158
+ suspensionReason: String,
147
159
  }, { _id: false });
148
160
  const seoSchema = new mongoose_1.default.Schema({
149
161
  metaTitle: String,
@@ -155,6 +167,8 @@ const featuresSchema = new mongoose_1.default.Schema({
155
167
  isFeatured: { type: Boolean, default: false },
156
168
  isPremium: { type: Boolean, default: false },
157
169
  badges: [String],
170
+ featuredAt: Date, // timestamp when featured
171
+ featuredPriority: { type: Number, default: 0 }, // for ordering featured events
158
172
  }, { _id: false });
159
173
  const historySchema = new mongoose_1.default.Schema({
160
174
  action: String,
@@ -221,6 +235,17 @@ eventSchema.index({ hostId: 1 });
221
235
  eventSchema.index({ 'schedule.startDate': 1 });
222
236
  eventSchema.index({ type: 1 });
223
237
  eventSchema.index({ categories: 1 });
238
+ // New compound indexes for optimized queries
239
+ // For trending events (recent views + high sales)
240
+ eventSchema.index({ 'metrics.lastViewedAt': -1, 'metrics.ticketsSold': -1 });
241
+ // For featured events
242
+ eventSchema.index({ 'features.isFeatured': 1, 'features.featuredPriority': -1 });
243
+ // For filtering by status + visibility + date
244
+ eventSchema.index({ status: 1, visibility: 1, 'schedule.startDate': 1 });
245
+ // For location-based queries with status
246
+ eventSchema.index({ 'venue.address.city': 1, status: 1 });
247
+ // For host's events with status filter
248
+ eventSchema.index({ hostId: 1, status: 1, updatedAt: -1 });
224
249
  // Validation: sum(tickets.quantity) <= venue.capacity
225
250
  eventSchema.pre('save', function (next) {
226
251
  if (this.tickets && this.tickets.length > 0 && this.venue) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mac777/project-pinecone-models",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "scripts": {
package/src/Event.ts CHANGED
@@ -82,25 +82,22 @@ const salesWindowSchema = new mongoose.Schema({
82
82
  endDate: Date,
83
83
  }, { _id: false });
84
84
 
85
- const limitsSchema = new mongoose.Schema({
86
- minPerOrder: { type: Number, default: 1 },
87
- maxPerOrder: { type: Number, default: 10 },
88
- }, { _id: false });
89
-
90
85
  const ticketSchema = new mongoose.Schema({
91
86
  name: { type: String, required: true },
92
- description: String,
93
87
  price: priceSchema,
94
88
  quantity: { type: Number, required: true },
95
89
  sold: { type: Number, default: 0 },
96
- remaining: { type: Number, default: function(this: any) { return this.quantity - this.sold; } },
97
- salesWindow: salesWindowSchema,
98
- limits: limitsSchema,
99
- visibility: { type: String, enum: ['public', 'hidden', 'invite_only'], default: 'public' },
100
90
  reserved: { type: Number, default: 0 },
101
- status: { type: String, enum: ['active', 'sold_out', 'inactive'], default: 'active' },
91
+ isActive: { type: Boolean, default: true },
92
+ isVisible: { type: Boolean, default: true },
93
+ wristbandColor: { type: String, default: '#000000' },
94
+ limits: {
95
+ minPerOrder: { type: Number, default: 1 },
96
+ maxPerOrder: { type: Number, default: 10 },
97
+ },
102
98
  benefits: [String],
103
- tier: { type: String, required: true, default: 'regular' },
99
+ tier: { type: String, default: 'regular' },
100
+ salesWindow: salesWindowSchema,
104
101
  });
105
102
 
106
103
  const scheduleSchema = new mongoose.Schema({
@@ -113,17 +110,30 @@ const scheduleSchema = new mongoose.Schema({
113
110
 
114
111
  const metricsSchema = new mongoose.Schema({
115
112
  views: { type: Number, default: 0 },
113
+ uniqueViews: { type: Number, default: 0 },
114
+ totalOrders: { type: Number, default: 0 },
116
115
  ticketsSold: { type: Number, default: 0 },
117
116
  revenue: { type: Number, default: 0 },
118
117
  checkIns: { type: Number, default: 0 },
118
+ uniqueViewers: {
119
+ type: [mongoose.Schema.Types.ObjectId],
120
+ default: []
121
+ },
122
+ lastViewedAt: Date, // for trending calculation
123
+
124
+ // --- For Review ---
119
125
  averageRating: Number,
120
126
  reviewCount: { type: Number, default: 0 },
127
+ conversionRate: { type: Number, default: 0 }, // (ticketsSold / views) * 100
121
128
  }, { _id: false });
122
129
 
123
130
  const pricingSchema = new mongoose.Schema({
124
131
  platformFee: { type: Number, default: 5 },
125
132
  paymentProcessingFee: Number,
126
- currency: String,
133
+ currency: {
134
+ type: String,
135
+ default: 'BDT'
136
+ },
127
137
  }, { _id: false });
128
138
 
129
139
  const payoutSchema = new mongoose.Schema({
@@ -158,6 +168,8 @@ const moderationSchema = new mongoose.Schema({
158
168
  flags: [flagSchema],
159
169
  suspendedUntil: Date,
160
170
  banReason: String,
171
+ suspendedAt: Date,
172
+ suspensionReason: String,
161
173
  }, { _id: false });
162
174
 
163
175
  const seoSchema = new mongoose.Schema({
@@ -171,6 +183,8 @@ const featuresSchema = new mongoose.Schema({
171
183
  isFeatured: { type: Boolean, default: false },
172
184
  isPremium: { type: Boolean, default: false },
173
185
  badges: [String],
186
+ featuredAt: Date, // timestamp when featured
187
+ featuredPriority: { type: Number, default: 0 }, // for ordering featured events
174
188
  }, { _id: false });
175
189
 
176
190
  const historySchema = new mongoose.Schema({
@@ -254,6 +268,22 @@ eventSchema.index({ 'schedule.startDate': 1 });
254
268
  eventSchema.index({ type: 1 });
255
269
  eventSchema.index({ categories: 1 });
256
270
 
271
+ // New compound indexes for optimized queries
272
+ // For trending events (recent views + high sales)
273
+ eventSchema.index({ 'metrics.lastViewedAt': -1, 'metrics.ticketsSold': -1 });
274
+
275
+ // For featured events
276
+ eventSchema.index({ 'features.isFeatured': 1, 'features.featuredPriority': -1 });
277
+
278
+ // For filtering by status + visibility + date
279
+ eventSchema.index({ status: 1, visibility: 1, 'schedule.startDate': 1 });
280
+
281
+ // For location-based queries with status
282
+ eventSchema.index({ 'venue.address.city': 1, status: 1 });
283
+
284
+ // For host's events with status filter
285
+ eventSchema.index({ hostId: 1, status: 1, updatedAt: -1 });
286
+
257
287
  // Validation: sum(tickets.quantity) <= venue.capacity
258
288
  eventSchema.pre('save', function(next) {
259
289
  if (this.tickets && this.tickets.length > 0 && this.venue) {