@mac777/project-pinecone-models 1.0.1 → 1.0.3

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,14 +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
- description?: string | null | undefined;
21
+ tier: string;
23
22
  price?: {
24
23
  amount: number;
25
24
  currency: string;
@@ -32,17 +31,16 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
32
31
  minPerOrder: number;
33
32
  maxPerOrder: number;
34
33
  } | null | undefined;
35
- tier?: "early_bird" | "regular" | "vip" | 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
- description?: string | null | undefined;
43
+ tier: string;
46
44
  price?: {
47
45
  amount: number;
48
46
  currency: string;
@@ -55,17 +53,16 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
55
53
  minPerOrder: number;
56
54
  maxPerOrder: number;
57
55
  } | null | undefined;
58
- tier?: "early_bird" | "regular" | "vip" | 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
- description?: string | null | undefined;
65
+ tier: string;
69
66
  price?: {
70
67
  amount: number;
71
68
  currency: string;
@@ -78,11 +75,11 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
78
75
  minPerOrder: number;
79
76
  maxPerOrder: number;
80
77
  } | null | undefined;
81
- tier?: "early_bird" | "regular" | "vip" | null | undefined;
82
78
  }>;
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: string[];
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,14 +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
- description?: string | null | undefined;
288
+ tier: string;
284
289
  price?: {
285
290
  amount: number;
286
291
  currency: string;
@@ -293,17 +298,16 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
293
298
  minPerOrder: number;
294
299
  maxPerOrder: number;
295
300
  } | null | undefined;
296
- tier?: "early_bird" | "regular" | "vip" | 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
- description?: string | null | undefined;
310
+ tier: string;
307
311
  price?: {
308
312
  amount: number;
309
313
  currency: string;
@@ -316,17 +320,16 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
316
320
  minPerOrder: number;
317
321
  maxPerOrder: number;
318
322
  } | null | undefined;
319
- tier?: "early_bird" | "regular" | "vip" | 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
- description?: string | null | undefined;
332
+ tier: string;
330
333
  price?: {
331
334
  amount: number;
332
335
  currency: string;
@@ -339,11 +342,11 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
339
342
  minPerOrder: number;
340
343
  maxPerOrder: number;
341
344
  } | null | undefined;
342
- tier?: "early_bird" | "regular" | "vip" | null | undefined;
343
345
  }>;
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: string[];
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,14 +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
- description?: string | null | undefined;
555
+ tier: string;
545
556
  price?: {
546
557
  amount: number;
547
558
  currency: string;
@@ -554,17 +565,16 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
554
565
  minPerOrder: number;
555
566
  maxPerOrder: number;
556
567
  } | null | undefined;
557
- tier?: "early_bird" | "regular" | "vip" | 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
- description?: string | null | undefined;
577
+ tier: string;
568
578
  price?: {
569
579
  amount: number;
570
580
  currency: string;
@@ -577,17 +587,16 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
577
587
  minPerOrder: number;
578
588
  maxPerOrder: number;
579
589
  } | null | undefined;
580
- tier?: "early_bird" | "regular" | "vip" | 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
- description?: string | null | undefined;
599
+ tier: string;
591
600
  price?: {
592
601
  amount: number;
593
602
  currency: string;
@@ -600,11 +609,11 @@ declare const eventSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
600
609
  minPerOrder: number;
601
610
  maxPerOrder: number;
602
611
  } | null | undefined;
603
- tier?: "early_bird" | "regular" | "vip" | null | undefined;
604
612
  }>;
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: string[];
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, enum: ['early_bird', 'regular', 'vip'] },
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,25 @@ 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: [String],
112
+ lastViewedAt: Date, // for trending calculation
113
+ // --- For Review ---
111
114
  averageRating: Number,
112
115
  reviewCount: { type: Number, default: 0 },
116
+ conversionRate: { type: Number, default: 0 }, // (ticketsSold / views) * 100
113
117
  }, { _id: false });
114
118
  const pricingSchema = new mongoose_1.default.Schema({
115
119
  platformFee: { type: Number, default: 5 },
116
120
  paymentProcessingFee: Number,
117
- currency: String,
121
+ currency: {
122
+ type: String,
123
+ default: 'BDT'
124
+ },
118
125
  }, { _id: false });
119
126
  const payoutSchema = new mongoose_1.default.Schema({
120
127
  status: { type: String, enum: ['pending', 'scheduled', 'completed'] },
@@ -144,6 +151,8 @@ const moderationSchema = new mongoose_1.default.Schema({
144
151
  flags: [flagSchema],
145
152
  suspendedUntil: Date,
146
153
  banReason: String,
154
+ suspendedAt: Date,
155
+ suspensionReason: String,
147
156
  }, { _id: false });
148
157
  const seoSchema = new mongoose_1.default.Schema({
149
158
  metaTitle: String,
@@ -155,6 +164,8 @@ const featuresSchema = new mongoose_1.default.Schema({
155
164
  isFeatured: { type: Boolean, default: false },
156
165
  isPremium: { type: Boolean, default: false },
157
166
  badges: [String],
167
+ featuredAt: Date, // timestamp when featured
168
+ featuredPriority: { type: Number, default: 0 }, // for ordering featured events
158
169
  }, { _id: false });
159
170
  const historySchema = new mongoose_1.default.Schema({
160
171
  action: String,
@@ -221,6 +232,17 @@ eventSchema.index({ hostId: 1 });
221
232
  eventSchema.index({ 'schedule.startDate': 1 });
222
233
  eventSchema.index({ type: 1 });
223
234
  eventSchema.index({ categories: 1 });
235
+ // New compound indexes for optimized queries
236
+ // For trending events (recent views + high sales)
237
+ eventSchema.index({ 'metrics.lastViewedAt': -1, 'metrics.ticketsSold': -1 });
238
+ // For featured events
239
+ eventSchema.index({ 'features.isFeatured': 1, 'features.featuredPriority': -1 });
240
+ // For filtering by status + visibility + date
241
+ eventSchema.index({ status: 1, visibility: 1, 'schedule.startDate': 1 });
242
+ // For location-based queries with status
243
+ eventSchema.index({ 'venue.address.city': 1, status: 1 });
244
+ // For host's events with status filter
245
+ eventSchema.index({ hostId: 1, status: 1, updatedAt: -1 });
224
246
  // Validation: sum(tickets.quantity) <= venue.capacity
225
247
  eventSchema.pre('save', function (next) {
226
248
  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.1",
3
+ "version": "1.0.3",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "scripts": {
@@ -12,10 +12,6 @@
12
12
  "zod": "^3.22.4",
13
13
  "zxcvbn": "^4.4.2"
14
14
  },
15
- "files": ["dist"],
16
- "publishConfig": {
17
- "access": "public"
18
- },
19
15
  "devDependencies": {
20
16
  "typescript": "^5.0.0"
21
17
  }
package/src/Bkash.ts ADDED
@@ -0,0 +1,10 @@
1
+ import mongoose from 'mongoose';
2
+
3
+ const bkashSchema = new mongoose.Schema({
4
+ auth_token: {
5
+ type: String,
6
+ required: true,
7
+ }
8
+ }, { timestamps: true });
9
+
10
+ export default bkashSchema;
package/src/Event.ts ADDED
@@ -0,0 +1,301 @@
1
+ import mongoose from 'mongoose';
2
+
3
+ const mediaSchema = new mongoose.Schema({
4
+ coverImage: {
5
+ url: String,
6
+ thumbnailUrl: String,
7
+ alt: String,
8
+ },
9
+ gallery: [{
10
+ url: String,
11
+ caption: String,
12
+ order: Number,
13
+ }],
14
+ }, { _id: false });
15
+
16
+ const addressSchema = new mongoose.Schema({
17
+ street: String,
18
+ city: { type: String, required: true },
19
+ state: String,
20
+ postalCode: String,
21
+ country: { type: String, required: true },
22
+ }, { _id: false });
23
+
24
+ const venueSchema = new mongoose.Schema({
25
+ name: { type: String, required: true },
26
+ address: addressSchema,
27
+ coordinates: {
28
+ type: {
29
+ type: String,
30
+ enum: ['Point'],
31
+ default: 'Point'
32
+ },
33
+ coordinates: [Number] // [lng, lat]
34
+ },
35
+ capacity: { type: Number, required: true, min: 10, max: 100000 },
36
+ type: { type: String, enum: ['indoor', 'outdoor', 'hybrid'] },
37
+ parking: Boolean,
38
+ publicTransit: String,
39
+ }, { _id: false });
40
+
41
+ const contactPersonSchema = new mongoose.Schema({
42
+ name: { type: String, required: true },
43
+ phone: { type: String, required: true },
44
+ email: { type: String, required: true },
45
+ designation: String,
46
+ }, { _id: false });
47
+
48
+ const organizerSchema = new mongoose.Schema({
49
+ role: { type: String, enum: ['event_organizer', 'venue_owner', 'authorized_rep', 'artist'] },
50
+ companyName: String,
51
+ contactPerson: contactPersonSchema,
52
+ }, { _id: false });
53
+
54
+ const documentSchema = new mongoose.Schema({
55
+ type: { type: String, enum: ['venue_booking', 'permit', 'insurance', 'license', 'portfolio', 'other'] },
56
+ url: String,
57
+ filename: String,
58
+ objectKey: String,
59
+ uploadedAt: Date,
60
+ status: { type: String, enum: ['pending', 'approved', 'rejected'] },
61
+ rejectionReason: String,
62
+ }, { _id: false });
63
+
64
+ const verificationSchema = new mongoose.Schema({
65
+ status: { type: String, enum: ['unverified', 'pending', 'verified', 'rejected', 'needs_info'], default: 'unverified' },
66
+ documents: [documentSchema],
67
+ additionalInfo: String,
68
+ adminNotes: String,
69
+ reviewedBy: mongoose.Schema.Types.ObjectId,
70
+ reviewedAt: Date,
71
+ rejectionReason: String,
72
+ requestedInfo: String,
73
+ }, { _id: false });
74
+
75
+ const priceSchema = new mongoose.Schema({
76
+ amount: { type: Number, required: true },
77
+ currency: { type: String, default: 'USD' },
78
+ }, { _id: false });
79
+
80
+ const salesWindowSchema = new mongoose.Schema({
81
+ startDate: Date,
82
+ endDate: Date,
83
+ }, { _id: false });
84
+
85
+ const ticketSchema = new mongoose.Schema({
86
+ name: { type: String, required: true },
87
+ price: priceSchema,
88
+ quantity: { type: Number, required: true },
89
+ sold: { type: Number, default: 0 },
90
+ reserved: { type: Number, default: 0 },
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
+ },
98
+ benefits: [String],
99
+ tier: { type: String, default: 'regular' },
100
+ salesWindow: salesWindowSchema,
101
+ });
102
+
103
+ const scheduleSchema = new mongoose.Schema({
104
+ startDate: { type: Date, required: true },
105
+ endDate: { type: Date, required: true },
106
+ timezone: String,
107
+ isMultiDay: Boolean,
108
+ doors: String,
109
+ }, { _id: false });
110
+
111
+ const metricsSchema = new mongoose.Schema({
112
+ views: { type: Number, default: 0 },
113
+ uniqueViews: { type: Number, default: 0 },
114
+ totalOrders: { type: Number, default: 0 },
115
+ ticketsSold: { type: Number, default: 0 },
116
+ revenue: { type: Number, default: 0 },
117
+ checkIns: { type: Number, default: 0 },
118
+ uniqueViewers: [String],
119
+ lastViewedAt: Date, // for trending calculation
120
+
121
+ // --- For Review ---
122
+ averageRating: Number,
123
+ reviewCount: { type: Number, default: 0 },
124
+ conversionRate: { type: Number, default: 0 }, // (ticketsSold / views) * 100
125
+ }, { _id: false });
126
+
127
+ const pricingSchema = new mongoose.Schema({
128
+ platformFee: { type: Number, default: 5 },
129
+ paymentProcessingFee: Number,
130
+ currency: {
131
+ type: String,
132
+ default: 'BDT'
133
+ },
134
+ }, { _id: false });
135
+
136
+ const payoutSchema = new mongoose.Schema({
137
+ status: { type: String, enum: ['pending', 'scheduled', 'completed'] },
138
+ amount: Number,
139
+ scheduledDate: Date,
140
+ paidAt: Date,
141
+ stripePayoutId: String,
142
+ }, { _id: false });
143
+
144
+ const cancellationSchema = new mongoose.Schema({
145
+ allowed: { type: Boolean, default: true },
146
+ refundPercentage: { type: Number, default: 100 },
147
+ deadlineHours: Number,
148
+ }, { _id: false });
149
+
150
+ const policiesSchema = new mongoose.Schema({
151
+ cancellation: cancellationSchema,
152
+ transferable: { type: Boolean, default: false },
153
+ }, { _id: false });
154
+
155
+ const flagSchema = new mongoose.Schema({
156
+ reportedBy: mongoose.Schema.Types.ObjectId,
157
+ reason: String,
158
+ description: String,
159
+ createdAt: { type: Date, default: Date.now },
160
+ status: { type: String, enum: ['pending', 'resolved', 'dismissed'], default: 'pending' },
161
+ }, { _id: false });
162
+
163
+ const moderationSchema = new mongoose.Schema({
164
+ isFlagged: { type: Boolean, default: false },
165
+ flags: [flagSchema],
166
+ suspendedUntil: Date,
167
+ banReason: String,
168
+ suspendedAt: Date,
169
+ suspensionReason: String,
170
+ }, { _id: false });
171
+
172
+ const seoSchema = new mongoose.Schema({
173
+ metaTitle: String,
174
+ metaDescription: String,
175
+ keywords: [String],
176
+ ogImage: String,
177
+ }, { _id: false });
178
+
179
+ const featuresSchema = new mongoose.Schema({
180
+ isFeatured: { type: Boolean, default: false },
181
+ isPremium: { type: Boolean, default: false },
182
+ badges: [String],
183
+ featuredAt: Date, // timestamp when featured
184
+ featuredPriority: { type: Number, default: 0 }, // for ordering featured events
185
+ }, { _id: false });
186
+
187
+ const historySchema = new mongoose.Schema({
188
+ action: String,
189
+ performedBy: mongoose.Schema.Types.ObjectId,
190
+ timestamp: { type: Date, default: Date.now },
191
+ changes: mongoose.Schema.Types.Mixed,
192
+ }, { _id: false });
193
+
194
+ const eventSchema = new mongoose.Schema({
195
+ hostId: { type: mongoose.Schema.Types.ObjectId, required: true },
196
+ slug: String,
197
+
198
+ // STEP 1: BASICS
199
+ title: { type: String, required: true, minlength: 10, maxlength: 100 },
200
+ type: { type: String, enum: ['concert', 'sports', 'conference', 'festival', 'theater', 'comedy', 'networking', 'workshop', 'other'], required: true },
201
+ categories: [{ type: String }],
202
+ tagline: { type: String, maxlength: 150 },
203
+
204
+ // STEP 2: DETAILS
205
+ description: { type: String, minlength: 50, maxlength: 5000 },
206
+ highlights: [{ type: String }],
207
+ languages: [String],
208
+ ageRestriction: { type: String, enum: ['all_ages', '18+', '21+'] },
209
+ dressCode: String,
210
+
211
+ media: mediaSchema,
212
+
213
+ // STEP 3: DATE, TIME & LOCATION
214
+ schedule: scheduleSchema,
215
+ venue: venueSchema,
216
+
217
+ // STEP 4: VERIFICATION
218
+ organizer: organizerSchema,
219
+ verification: verificationSchema,
220
+
221
+ // STEP 5: TICKETS
222
+ tickets: [ticketSchema],
223
+ termsAccepted: { type: Boolean, default: false },
224
+ legalPermissionAccepted: { type: Boolean, default: false },
225
+ platformTermsAccepted: { type: Boolean, default: false },
226
+ // STATUS & WORKFLOW
227
+ status: { type: String, enum: ['draft', 'pending_approval', 'approved', 'rejected', 'published', 'live', 'ended', 'cancelled'], default: 'draft' },
228
+ rejectionReason: String,
229
+ visibility: { type: String, enum: ['public', 'private', 'unlisted'], default: 'public' },
230
+ publishedAt: Date,
231
+
232
+ // METRICS
233
+ metrics: metricsSchema,
234
+
235
+ // BUSINESS
236
+ pricing: pricingSchema,
237
+ payout: payoutSchema,
238
+
239
+ // POLICIES
240
+ policies: policiesSchema,
241
+
242
+ // MODERATION
243
+ moderation: moderationSchema,
244
+
245
+ // SEO
246
+ seo: seoSchema,
247
+
248
+ // FEATURES
249
+ features: featuresSchema,
250
+
251
+ // AUDIT
252
+ createdAt: { type: Date, default: Date.now },
253
+ updatedAt: { type: Date, default: Date.now },
254
+ submittedAt: Date,
255
+ history: [historySchema],
256
+ deletedAt: Date,
257
+ });
258
+
259
+ // Indexes
260
+ eventSchema.index({ slug: 1 });
261
+ eventSchema.index({ 'venue.coordinates': '2dsphere' });
262
+ eventSchema.index({ status: 1, visibility: 1 });
263
+ eventSchema.index({ hostId: 1 });
264
+ eventSchema.index({ 'schedule.startDate': 1 });
265
+ eventSchema.index({ type: 1 });
266
+ eventSchema.index({ categories: 1 });
267
+
268
+ // New compound indexes for optimized queries
269
+ // For trending events (recent views + high sales)
270
+ eventSchema.index({ 'metrics.lastViewedAt': -1, 'metrics.ticketsSold': -1 });
271
+
272
+ // For featured events
273
+ eventSchema.index({ 'features.isFeatured': 1, 'features.featuredPriority': -1 });
274
+
275
+ // For filtering by status + visibility + date
276
+ eventSchema.index({ status: 1, visibility: 1, 'schedule.startDate': 1 });
277
+
278
+ // For location-based queries with status
279
+ eventSchema.index({ 'venue.address.city': 1, status: 1 });
280
+
281
+ // For host's events with status filter
282
+ eventSchema.index({ hostId: 1, status: 1, updatedAt: -1 });
283
+
284
+ // Validation: sum(tickets.quantity) <= venue.capacity
285
+ eventSchema.pre('save', function(next) {
286
+ if (this.tickets && this.tickets.length > 0 && this.venue) {
287
+ const totalCapacity = this.tickets.reduce((sum, ticket) => sum + ticket.quantity, 0);
288
+ if (totalCapacity > this.venue.capacity) {
289
+ return next(new Error('Total ticket quantity exceeds venue capacity'));
290
+ }
291
+ }
292
+ next();
293
+ });
294
+
295
+ // Update updatedAt on save
296
+ eventSchema.pre('save', function(next) {
297
+ this.updatedAt = new Date();
298
+ next();
299
+ });
300
+
301
+ export default eventSchema;
package/src/Media.ts ADDED
@@ -0,0 +1,36 @@
1
+ import mongoose from 'mongoose';
2
+
3
+ const mediaSchema = new mongoose.Schema({
4
+ userId: { type: mongoose.Schema.Types.ObjectId, required: true },
5
+ type: { type: String, enum: ['event_cover', 'event_gallery', 'verification_doc'], required: true },
6
+ provider: { type: String, enum: ['imagekit', 'backblaze'], required: true },
7
+ status: { type: String, enum: ['temp', 'permanent', 'deleted'], required: true },
8
+
9
+ // ImageKit specific
10
+ fileId: String,
11
+ url: String,
12
+ thumbnailUrl: String,
13
+
14
+ // Backblaze specific
15
+ bucketName: String,
16
+ objectKey: String,
17
+
18
+ // Metadata
19
+ filename: { type: String, required: true },
20
+ mimeType: { type: String, required: true },
21
+ size: { type: Number, required: false },
22
+
23
+ // Lifecycle
24
+ uploadedAt: { type: Date, default: Date.now },
25
+ movedToPermanentAt: Date,
26
+ expiresAt: Date, // For temp files
27
+ deletedAt: Date,
28
+ });
29
+
30
+ // Indexes
31
+ mediaSchema.index({ userId: 1 });
32
+ mediaSchema.index({ status: 1 });
33
+ mediaSchema.index({ expiresAt: 1 });
34
+ mediaSchema.index({ uploadedAt: 1 });
35
+
36
+ export default mediaSchema;
package/src/Order.ts ADDED
@@ -0,0 +1,201 @@
1
+ import mongoose from 'mongoose';
2
+
3
+ // Order Ticket Schema
4
+ const orderTicketSchema = new mongoose.Schema({
5
+ ticketVariantId: {
6
+ type: mongoose.Schema.Types.ObjectId,
7
+ required: true
8
+ },
9
+ variantName: {
10
+ type: String,
11
+ required: true
12
+ },
13
+ quantity: {
14
+ type: Number,
15
+ required: true,
16
+ min: 1
17
+ },
18
+ pricePerTicket: {
19
+ type: Number,
20
+ required: true,
21
+ min: 0
22
+ },
23
+ subtotal: {
24
+ type: Number,
25
+ required: true,
26
+ min: 0
27
+ }
28
+ }, { _id: false });
29
+
30
+ // Pricing Schema
31
+ const pricingSchema = new mongoose.Schema({
32
+ subtotal: {
33
+ type: Number,
34
+ required: true,
35
+ min: 0
36
+ },
37
+ platformFee: {
38
+ type: Number,
39
+ required: true,
40
+ min: 0
41
+ },
42
+ paymentFee: {
43
+ type: Number,
44
+ required: true,
45
+ min: 0
46
+ },
47
+ total: {
48
+ type: Number,
49
+ required: true,
50
+ min: 0
51
+ },
52
+ currency: {
53
+ type: String,
54
+ required: true,
55
+ default: 'BDT'
56
+ },
57
+ hostPayout: {
58
+ type: Number,
59
+ required: true,
60
+ min: 0
61
+ }
62
+ }, { _id: false });
63
+
64
+ // Refund Schema
65
+ const refundSchema = new mongoose.Schema({
66
+ reason: {
67
+ type: String,
68
+ required: true,
69
+ enum: ['event_cancelled', 'user_request', 'fraud']
70
+ },
71
+ amount: {
72
+ type: Number,
73
+ required: true,
74
+ min: 0
75
+ },
76
+ refundedAt: {
77
+ type: Date,
78
+ default: Date.now
79
+ },
80
+ stripeRefundId: String
81
+ }, { _id: false });
82
+
83
+ // Main Order Schema
84
+ const orderSchema = new mongoose.Schema({
85
+ orderNumber: {
86
+ type: String,
87
+ required: true,
88
+ unique: true,
89
+ },
90
+
91
+ // WHO
92
+ userId: {
93
+ type: mongoose.Schema.Types.ObjectId,
94
+ required: true,
95
+ },
96
+
97
+ // WHAT
98
+ eventId: {
99
+ type: mongoose.Schema.Types.ObjectId,
100
+ required: true,
101
+ },
102
+
103
+ paymentId: {
104
+ type: String,
105
+ required: false,
106
+ },
107
+
108
+ tickets: [orderTicketSchema],
109
+
110
+ // MONEY
111
+ pricing: pricingSchema,
112
+
113
+ // STATUS
114
+ status: {
115
+ type: String,
116
+ required: true,
117
+ enum: ['pending', 'confirmed', 'cancelled', 'refunded'],
118
+ default: 'pending'
119
+ },
120
+
121
+ requiresManualReview: {
122
+ type: Boolean,
123
+ default: false
124
+ },
125
+
126
+ manualReviewReason: {
127
+ type: String,
128
+ default: null
129
+ },
130
+
131
+ paymentMethod: {
132
+ type: String,
133
+ required: true,
134
+ enum: ['card', 'bkash', 'bank_transfer']
135
+ },
136
+ paymentStatus: {
137
+ type: String,
138
+ required: true,
139
+ enum: ['pending', 'succeeded', 'failed'],
140
+ default: 'pending'
141
+ },
142
+ paidAt: Date,
143
+
144
+ // TICKETS ISSUED
145
+ ticketIds: [{
146
+ type: mongoose.Schema.Types.ObjectId,
147
+ ref: 'Ticket'
148
+ }],
149
+
150
+ // LIFECYCLE
151
+ createdAt: {
152
+ type: Date,
153
+ default: Date.now,
154
+ index: true
155
+ },
156
+ expiresAt: {
157
+ type: Date,
158
+ required: true
159
+ },
160
+ confirmedAt: Date,
161
+ cancelledAt: Date,
162
+ refundedAt: Date,
163
+ reminderSentAt: Date,
164
+
165
+ // CONTACT
166
+ buyerEmail: {
167
+ type: String,
168
+ required: true
169
+ },
170
+ buyerPhone: String,
171
+
172
+ // AUDIT
173
+ ipAddress: String,
174
+ userAgent: String,
175
+
176
+ // REFUND (if applicable)
177
+ refund: refundSchema
178
+ });
179
+
180
+ // Indexes for performance
181
+ orderSchema.index({ userId: 1, createdAt: -1 });
182
+ orderSchema.index({ eventId: 1, status: 1 });
183
+ orderSchema.index({ status: 1, expiresAt: 1 });
184
+
185
+ // Auto-generate order number
186
+ orderSchema.pre('save', function(next) {
187
+ if (this.isNew && !this.orderNumber) {
188
+ const timestamp = Date.now().toString().slice(-6);
189
+ const random = Math.random().toString(36).substring(2, 8).toUpperCase();
190
+ this.orderNumber = `ORD-${timestamp}-${random}`;
191
+ }
192
+ next();
193
+ });
194
+
195
+ // Update updatedAt on save
196
+ orderSchema.pre('save', function(next) {
197
+ // Note: We don't have updatedAt field, but could add if needed
198
+ next();
199
+ });
200
+
201
+ export default orderSchema;
package/src/Payment.ts ADDED
@@ -0,0 +1,61 @@
1
+ import mongoose from 'mongoose';
2
+
3
+ // Payment schema for transaction logging
4
+ const paymentSchema = new mongoose.Schema({
5
+ // LINKS
6
+ orderId: { type: mongoose.Schema.Types.ObjectId, required: true, index: true }, // Which order
7
+ userId: { type: mongoose.Schema.Types.ObjectId, required: true, index: true }, // Who paid
8
+
9
+ paymentId: { type: String, required: true, unique: true, index: true }, // Stripe PI (unique)
10
+
11
+ // MONEY
12
+ amount: { type: Number, required: true },
13
+ currency: { type: String, required: true, default: 'BDT' },
14
+
15
+ // STATUS
16
+ status: {
17
+ type: String,
18
+ required: true,
19
+ enum: ['pending', 'succeeded', 'failed', 'refunded'],
20
+ default: 'pending'
21
+ },
22
+
23
+ // METADATA
24
+ paymentMethod: { type: String, required: true, enum: ['bkash', 'card'] },
25
+ last4: String, // Card last 4 digits (for receipt)
26
+ brand: { type: String, enum: ['visa', 'mastercard', 'amex', 'discover'] }, // Card brand
27
+
28
+ // FAILURE (if failed)
29
+ failureCode: String, // "insufficient_funds", "card_declined", etc.
30
+ failureMessage: String,
31
+
32
+ // REFUND (if refunded)
33
+ refundId: String, // Stripe refund ID
34
+ refundAmount: Number,
35
+ refundedAt: Date,
36
+
37
+ // TIMESTAMPS
38
+ createdAt: { type: Date, default: Date.now },
39
+ succeededAt: Date,
40
+ failedAt: Date,
41
+ });
42
+
43
+ // Indexes for performance
44
+ paymentSchema.index({ orderId: 1 });
45
+ paymentSchema.index({ userId: 1, createdAt: -1 });
46
+ paymentSchema.index({ status: 1, createdAt: -1 });
47
+
48
+ // Pre-save middleware to set timestamps based on status
49
+ paymentSchema.pre('save', function(next) {
50
+ if (this.isModified('status')) {
51
+ const now = new Date();
52
+ if (this.status === 'succeeded' && !this.succeededAt) {
53
+ this.succeededAt = now;
54
+ } else if (this.status === 'failed' && !this.failedAt) {
55
+ this.failedAt = now;
56
+ }
57
+ }
58
+ next();
59
+ });
60
+
61
+ export default paymentSchema;
package/src/Ticket.ts ADDED
@@ -0,0 +1,105 @@
1
+ import mongoose from 'mongoose';
2
+
3
+ // Ticket schema for individual issued tickets
4
+ const ticketSchema = new mongoose.Schema({
5
+ ticketNumber: { type: String, required: true, unique: true, index: true }, // Human-readable: "TKT-EVT123-A3K9-01"
6
+
7
+ // BELONGS TO
8
+ orderId: { type: mongoose.Schema.Types.ObjectId, required: true, index: true }, // Parent order
9
+ eventId: { type: mongoose.Schema.Types.ObjectId, required: true, index: true }, // Which event
10
+ userId: { type: mongoose.Schema.Types.ObjectId, required: true, index: true }, // Owner
11
+ ticketVariantId: { type: mongoose.Schema.Types.ObjectId, required: true }, // Which type (VIP, GA, etc)
12
+
13
+ // DETAILS (denormalized for speed)
14
+ eventTitle: { type: String, required: true },
15
+ eventDate: { type: Date, required: true },
16
+ eventVenue: { type: String, required: true },
17
+ ticketType: { type: String, required: true }, // "VIP Pass"
18
+ price: { type: Number, required: true },
19
+
20
+ // QR CODE
21
+ qrCode: { type: String, unique: true, required: true }, // Unique hash: SHA256(ticketId + secret)
22
+ qrCodeUrl: { type: String, required: true }, // ImageKit/S3 URL to QR image
23
+
24
+ // STATUS
25
+ status: {
26
+ type: String,
27
+ required: true,
28
+ enum: ['valid', 'used', 'cancelled', 'refunded', 'transferred'],
29
+ default: 'valid',
30
+ index: true
31
+ },
32
+
33
+ // CHECK-IN
34
+ checkInStatus: {
35
+ type: String,
36
+ required: true,
37
+ enum: ['not_checked_in', 'checked_in'],
38
+ default: 'not_checked_in'
39
+ },
40
+ checkedInAt: Date,
41
+ checkedInBy: mongoose.Schema.Types.ObjectId, // Staff/scanner user ID
42
+
43
+ // TRANSFER (if user transfers ticket to friend)
44
+ transferredTo: mongoose.Schema.Types.ObjectId, // New owner user ID
45
+ transferredAt: Date,
46
+
47
+ // LIFECYCLE
48
+ issuedAt: { type: Date, default: Date.now }, // When ticket was created
49
+ validUntil: { type: Date, required: true }, // Event end date (after this, ticket expires)
50
+
51
+ // SECURITY
52
+ secretHash: { type: String, required: true }, // Internal validation hash (never exposed)
53
+ });
54
+
55
+
56
+ // Pre-save middleware to set default validUntil if not provided
57
+ ticketSchema.pre('save', function(next) {
58
+ if (this.isNew && !this.validUntil && this.eventDate) {
59
+ // Set validUntil to end of event day if eventDate is provided
60
+ const eventEnd = new Date(this.eventDate);
61
+ eventEnd.setHours(23, 59, 59, 999); // End of the event day
62
+ this.validUntil = eventEnd;
63
+ }
64
+ next();
65
+ });
66
+
67
+ // Virtual for checking if ticket is expired
68
+ ticketSchema.virtual('isExpired').get(function() {
69
+ return new Date() > this.validUntil;
70
+ });
71
+
72
+ // Method to check if ticket can be used
73
+ ticketSchema.methods.canBeUsed = function() {
74
+ return this.status === 'valid' &&
75
+ this.checkInStatus === 'not_checked_in' &&
76
+ !this.isExpired;
77
+ };
78
+
79
+ // Method to mark as used (check-in)
80
+ ticketSchema.methods.checkIn = function(staffUserId: string) {
81
+ if (!this.canBeUsed()) {
82
+ throw new Error('Ticket cannot be checked in');
83
+ }
84
+
85
+ this.checkInStatus = 'checked_in';
86
+ this.checkedInAt = new Date();
87
+ this.checkedInBy = new mongoose.Types.ObjectId(staffUserId);
88
+
89
+ return this.save();
90
+ };
91
+
92
+ // Method to transfer ticket
93
+ ticketSchema.methods.transfer = function(newOwnerId: string) {
94
+ if (this.status !== 'valid') {
95
+ throw new Error('Only valid tickets can be transferred');
96
+ }
97
+
98
+ this.transferredTo = new mongoose.Types.ObjectId(newOwnerId);
99
+ this.transferredAt = new Date();
100
+ this.userId = new mongoose.Types.ObjectId(newOwnerId); // Update ownership
101
+
102
+ return this.save();
103
+ };
104
+
105
+ export default ticketSchema;
package/src/User.ts ADDED
@@ -0,0 +1,47 @@
1
+ import mongoose from "mongoose";
2
+
3
+ const userSchema = new mongoose.Schema({
4
+ firstName: {
5
+ type: String,
6
+ required: true
7
+ },
8
+ lastName: {
9
+ type: String,
10
+ required: true
11
+ },
12
+ email: {
13
+ type: String,
14
+ required: true,
15
+ unique: true
16
+ },
17
+ password: {
18
+ type: String,
19
+ required: false
20
+ },
21
+ organization: {
22
+ type: String,
23
+ required: false
24
+ },
25
+ role: {
26
+ type: String,
27
+ enum: ['user', 'host', 'admin'],
28
+ default: 'user'
29
+ },
30
+ refreshToken: {
31
+ type: String,
32
+ required: false
33
+ },
34
+ provider: {
35
+ type: String,
36
+ enum: ['google', 'local'],
37
+ default: 'local'
38
+ },
39
+ googleId: {
40
+ type: String,
41
+ required: false
42
+ }
43
+ }, {
44
+ timestamps: true
45
+ })
46
+
47
+ export default userSchema;
package/src/index.ts ADDED
@@ -0,0 +1,9 @@
1
+ // Shared database models for Pinecone microservices
2
+ export { default as eventSchema } from './Event';
3
+ export { default as ticketSchema } from './Ticket';
4
+ export { default as mediaSchema } from './Media';
5
+ export { default as bkashSchema } from './Bkash';
6
+ export { default as paymentSchema } from './Payment';
7
+ export { default as orderSchema } from './Order';
8
+ export { default as userSchema } from './User';
9
+
package/tsconfig.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "CommonJS",
5
+ "moduleResolution": "node",
6
+ "declaration": true,
7
+ "outDir": "dist",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "resolveJsonModule": true
13
+ },
14
+ "include": ["src/**/*"],
15
+ "exclude": ["node_modules", "dist", "**/*.test.ts"]
16
+ }