@mac777/project-pinecone-models 1.1.9 → 1.1.11

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/AuditLog.js CHANGED
@@ -2,13 +2,13 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const mongoose_1 = require("mongoose");
4
4
  const auditLogSchema = new mongoose_1.Schema({
5
- userId: { type: String, required: true },
6
- action: { type: String, required: true },
7
- details: { type: Object, required: true },
8
- performedBy: { type: String, required: true },
9
- targetType: { type: String, required: true },
10
- targetId: { type: String, required: true },
11
- metadata: { type: Object, required: true },
5
+ userId: { type: String },
6
+ action: { type: String },
7
+ details: { type: Object },
8
+ performedBy: { type: String },
9
+ targetType: { type: String },
10
+ targetId: { type: String },
11
+ metadata: { type: Object },
12
12
  timestamp: { type: Date, default: Date.now },
13
13
  });
14
14
  exports.default = auditLogSchema;
package/dist/Order.d.ts CHANGED
@@ -1,8 +1,15 @@
1
- import mongoose from 'mongoose';
2
- declare const orderSchema: mongoose.Schema<any, mongoose.Model<any, any, any, any, any, any>, {}, {}, {}, {}, mongoose.DefaultSchemaOptions, {
1
+ import mongoose from "mongoose";
2
+ declare const _default: mongoose.Model<{
3
3
  userId: mongoose.Types.ObjectId;
4
- createdAt: NativeDate;
5
4
  status: "pending" | "cancelled" | "confirmed" | "refunded";
5
+ pricing: {
6
+ currency: string;
7
+ platformFee: number;
8
+ subtotal: number;
9
+ paymentFee: number;
10
+ total: number;
11
+ hostPayout: number;
12
+ };
6
13
  tickets: mongoose.Types.DocumentArray<{
7
14
  quantity: number;
8
15
  ticketVariantId: mongoose.Types.ObjectId;
@@ -24,40 +31,98 @@ declare const orderSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
24
31
  }>;
25
32
  eventId: mongoose.Types.ObjectId;
26
33
  expiresAt: NativeDate;
27
- orderNumber: string;
28
- requiresManualReview: boolean;
29
- manualReviewReason: string;
34
+ ticketCount: number;
35
+ ticketIds: mongoose.Types.ObjectId[];
30
36
  paymentMethod: "card" | "bkash" | "bank_transfer" | "free";
31
37
  paymentStatus: "pending" | "succeeded" | "failed";
32
- ticketIds: mongoose.Types.ObjectId[];
38
+ requiresManualReview: boolean;
33
39
  buyerEmail: string;
34
40
  paidAt?: NativeDate | null | undefined;
35
- pricing?: {
41
+ refundedAt?: NativeDate | null | undefined;
42
+ paymentId?: string | null | undefined;
43
+ manualReviewReason?: string | null | undefined;
44
+ confirmedAt?: NativeDate | null | undefined;
45
+ cancelledAt?: NativeDate | null | undefined;
46
+ reminderSentAt?: NativeDate | null | undefined;
47
+ buyerPhone?: string | null | undefined;
48
+ ipAddress?: string | null | undefined;
49
+ userAgent?: string | null | undefined;
50
+ orderNumber?: string | null | undefined;
51
+ refund?: {
52
+ reason: "event_cancelled" | "user_request" | "fraud";
53
+ amount: number;
54
+ refundedAt: NativeDate;
55
+ stripeRefundId?: string | null | undefined;
56
+ } | null | undefined;
57
+ } & mongoose.DefaultTimestampProps, {}, {}, {}, mongoose.Document<unknown, {}, {
58
+ userId: mongoose.Types.ObjectId;
59
+ status: "pending" | "cancelled" | "confirmed" | "refunded";
60
+ pricing: {
36
61
  currency: string;
37
62
  platformFee: number;
38
63
  subtotal: number;
39
64
  paymentFee: number;
40
65
  total: number;
41
66
  hostPayout: number;
42
- } | null | undefined;
67
+ };
68
+ tickets: mongoose.Types.DocumentArray<{
69
+ quantity: number;
70
+ ticketVariantId: mongoose.Types.ObjectId;
71
+ variantName: string;
72
+ pricePerTicket: number;
73
+ subtotal: number;
74
+ }, mongoose.Types.Subdocument<mongoose.mongo.BSON.ObjectId, any, {
75
+ quantity: number;
76
+ ticketVariantId: mongoose.Types.ObjectId;
77
+ variantName: string;
78
+ pricePerTicket: number;
79
+ subtotal: number;
80
+ }> & {
81
+ quantity: number;
82
+ ticketVariantId: mongoose.Types.ObjectId;
83
+ variantName: string;
84
+ pricePerTicket: number;
85
+ subtotal: number;
86
+ }>;
87
+ eventId: mongoose.Types.ObjectId;
88
+ expiresAt: NativeDate;
89
+ ticketCount: number;
90
+ ticketIds: mongoose.Types.ObjectId[];
91
+ paymentMethod: "card" | "bkash" | "bank_transfer" | "free";
92
+ paymentStatus: "pending" | "succeeded" | "failed";
93
+ requiresManualReview: boolean;
94
+ buyerEmail: string;
95
+ paidAt?: NativeDate | null | undefined;
43
96
  refundedAt?: NativeDate | null | undefined;
97
+ paymentId?: string | null | undefined;
98
+ manualReviewReason?: string | null | undefined;
44
99
  confirmedAt?: NativeDate | null | undefined;
45
100
  cancelledAt?: NativeDate | null | undefined;
46
101
  reminderSentAt?: NativeDate | null | undefined;
47
102
  buyerPhone?: string | null | undefined;
48
103
  ipAddress?: string | null | undefined;
49
104
  userAgent?: string | null | undefined;
105
+ orderNumber?: string | null | undefined;
50
106
  refund?: {
51
107
  reason: "event_cancelled" | "user_request" | "fraud";
52
108
  amount: number;
53
109
  refundedAt: NativeDate;
54
110
  stripeRefundId?: string | null | undefined;
55
111
  } | null | undefined;
56
- paymentId?: string | null | undefined;
57
- }, mongoose.Document<unknown, {}, mongoose.FlatRecord<{
112
+ } & mongoose.DefaultTimestampProps, {}, {
113
+ timestamps: true;
114
+ strict: true;
115
+ }> & {
58
116
  userId: mongoose.Types.ObjectId;
59
- createdAt: NativeDate;
60
117
  status: "pending" | "cancelled" | "confirmed" | "refunded";
118
+ pricing: {
119
+ currency: string;
120
+ platformFee: number;
121
+ subtotal: number;
122
+ paymentFee: number;
123
+ total: number;
124
+ hostPayout: number;
125
+ };
61
126
  tickets: mongoose.Types.DocumentArray<{
62
127
  quantity: number;
63
128
  ticketVariantId: mongoose.Types.ObjectId;
@@ -79,40 +144,102 @@ declare const orderSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
79
144
  }>;
80
145
  eventId: mongoose.Types.ObjectId;
81
146
  expiresAt: NativeDate;
82
- orderNumber: string;
83
- requiresManualReview: boolean;
84
- manualReviewReason: string;
147
+ ticketCount: number;
148
+ ticketIds: mongoose.Types.ObjectId[];
85
149
  paymentMethod: "card" | "bkash" | "bank_transfer" | "free";
86
150
  paymentStatus: "pending" | "succeeded" | "failed";
87
- ticketIds: mongoose.Types.ObjectId[];
151
+ requiresManualReview: boolean;
88
152
  buyerEmail: string;
89
153
  paidAt?: NativeDate | null | undefined;
90
- pricing?: {
154
+ refundedAt?: NativeDate | null | undefined;
155
+ paymentId?: string | null | undefined;
156
+ manualReviewReason?: string | null | undefined;
157
+ confirmedAt?: NativeDate | null | undefined;
158
+ cancelledAt?: NativeDate | null | undefined;
159
+ reminderSentAt?: NativeDate | null | undefined;
160
+ buyerPhone?: string | null | undefined;
161
+ ipAddress?: string | null | undefined;
162
+ userAgent?: string | null | undefined;
163
+ orderNumber?: string | null | undefined;
164
+ refund?: {
165
+ reason: "event_cancelled" | "user_request" | "fraud";
166
+ amount: number;
167
+ refundedAt: NativeDate;
168
+ stripeRefundId?: string | null | undefined;
169
+ } | null | undefined;
170
+ } & mongoose.DefaultTimestampProps & {
171
+ _id: mongoose.Types.ObjectId;
172
+ } & {
173
+ __v: number;
174
+ }, mongoose.Schema<any, mongoose.Model<any, any, any, any, any, any>, {}, {}, {}, {}, {
175
+ timestamps: true;
176
+ strict: true;
177
+ }, {
178
+ userId: mongoose.Types.ObjectId;
179
+ status: "pending" | "cancelled" | "confirmed" | "refunded";
180
+ pricing: {
91
181
  currency: string;
92
182
  platformFee: number;
93
183
  subtotal: number;
94
184
  paymentFee: number;
95
185
  total: number;
96
186
  hostPayout: number;
97
- } | null | undefined;
187
+ };
188
+ tickets: mongoose.Types.DocumentArray<{
189
+ quantity: number;
190
+ ticketVariantId: mongoose.Types.ObjectId;
191
+ variantName: string;
192
+ pricePerTicket: number;
193
+ subtotal: number;
194
+ }, mongoose.Types.Subdocument<mongoose.mongo.BSON.ObjectId, any, {
195
+ quantity: number;
196
+ ticketVariantId: mongoose.Types.ObjectId;
197
+ variantName: string;
198
+ pricePerTicket: number;
199
+ subtotal: number;
200
+ }> & {
201
+ quantity: number;
202
+ ticketVariantId: mongoose.Types.ObjectId;
203
+ variantName: string;
204
+ pricePerTicket: number;
205
+ subtotal: number;
206
+ }>;
207
+ eventId: mongoose.Types.ObjectId;
208
+ expiresAt: NativeDate;
209
+ ticketCount: number;
210
+ ticketIds: mongoose.Types.ObjectId[];
211
+ paymentMethod: "card" | "bkash" | "bank_transfer" | "free";
212
+ paymentStatus: "pending" | "succeeded" | "failed";
213
+ requiresManualReview: boolean;
214
+ buyerEmail: string;
215
+ paidAt?: NativeDate | null | undefined;
98
216
  refundedAt?: NativeDate | null | undefined;
217
+ paymentId?: string | null | undefined;
218
+ manualReviewReason?: string | null | undefined;
99
219
  confirmedAt?: NativeDate | null | undefined;
100
220
  cancelledAt?: NativeDate | null | undefined;
101
221
  reminderSentAt?: NativeDate | null | undefined;
102
222
  buyerPhone?: string | null | undefined;
103
223
  ipAddress?: string | null | undefined;
104
224
  userAgent?: string | null | undefined;
225
+ orderNumber?: string | null | undefined;
105
226
  refund?: {
106
227
  reason: "event_cancelled" | "user_request" | "fraud";
107
228
  amount: number;
108
229
  refundedAt: NativeDate;
109
230
  stripeRefundId?: string | null | undefined;
110
231
  } | null | undefined;
111
- paymentId?: string | null | undefined;
112
- }>, {}, mongoose.ResolveSchemaOptions<mongoose.DefaultSchemaOptions>> & mongoose.FlatRecord<{
232
+ } & mongoose.DefaultTimestampProps, mongoose.Document<unknown, {}, mongoose.FlatRecord<{
113
233
  userId: mongoose.Types.ObjectId;
114
- createdAt: NativeDate;
115
234
  status: "pending" | "cancelled" | "confirmed" | "refunded";
235
+ pricing: {
236
+ currency: string;
237
+ platformFee: number;
238
+ subtotal: number;
239
+ paymentFee: number;
240
+ total: number;
241
+ hostPayout: number;
242
+ };
116
243
  tickets: mongoose.Types.DocumentArray<{
117
244
  quantity: number;
118
245
  ticketVariantId: mongoose.Types.ObjectId;
@@ -134,39 +261,90 @@ declare const orderSchema: mongoose.Schema<any, mongoose.Model<any, any, any, an
134
261
  }>;
135
262
  eventId: mongoose.Types.ObjectId;
136
263
  expiresAt: NativeDate;
137
- orderNumber: string;
138
- requiresManualReview: boolean;
139
- manualReviewReason: string;
264
+ ticketCount: number;
265
+ ticketIds: mongoose.Types.ObjectId[];
140
266
  paymentMethod: "card" | "bkash" | "bank_transfer" | "free";
141
267
  paymentStatus: "pending" | "succeeded" | "failed";
142
- ticketIds: mongoose.Types.ObjectId[];
268
+ requiresManualReview: boolean;
143
269
  buyerEmail: string;
144
270
  paidAt?: NativeDate | null | undefined;
145
- pricing?: {
271
+ refundedAt?: NativeDate | null | undefined;
272
+ paymentId?: string | null | undefined;
273
+ manualReviewReason?: string | null | undefined;
274
+ confirmedAt?: NativeDate | null | undefined;
275
+ cancelledAt?: NativeDate | null | undefined;
276
+ reminderSentAt?: NativeDate | null | undefined;
277
+ buyerPhone?: string | null | undefined;
278
+ ipAddress?: string | null | undefined;
279
+ userAgent?: string | null | undefined;
280
+ orderNumber?: string | null | undefined;
281
+ refund?: {
282
+ reason: "event_cancelled" | "user_request" | "fraud";
283
+ amount: number;
284
+ refundedAt: NativeDate;
285
+ stripeRefundId?: string | null | undefined;
286
+ } | null | undefined;
287
+ } & mongoose.DefaultTimestampProps>, {}, mongoose.ResolveSchemaOptions<{
288
+ timestamps: true;
289
+ strict: true;
290
+ }>> & mongoose.FlatRecord<{
291
+ userId: mongoose.Types.ObjectId;
292
+ status: "pending" | "cancelled" | "confirmed" | "refunded";
293
+ pricing: {
146
294
  currency: string;
147
295
  platformFee: number;
148
296
  subtotal: number;
149
297
  paymentFee: number;
150
298
  total: number;
151
299
  hostPayout: number;
152
- } | null | undefined;
300
+ };
301
+ tickets: mongoose.Types.DocumentArray<{
302
+ quantity: number;
303
+ ticketVariantId: mongoose.Types.ObjectId;
304
+ variantName: string;
305
+ pricePerTicket: number;
306
+ subtotal: number;
307
+ }, mongoose.Types.Subdocument<mongoose.mongo.BSON.ObjectId, any, {
308
+ quantity: number;
309
+ ticketVariantId: mongoose.Types.ObjectId;
310
+ variantName: string;
311
+ pricePerTicket: number;
312
+ subtotal: number;
313
+ }> & {
314
+ quantity: number;
315
+ ticketVariantId: mongoose.Types.ObjectId;
316
+ variantName: string;
317
+ pricePerTicket: number;
318
+ subtotal: number;
319
+ }>;
320
+ eventId: mongoose.Types.ObjectId;
321
+ expiresAt: NativeDate;
322
+ ticketCount: number;
323
+ ticketIds: mongoose.Types.ObjectId[];
324
+ paymentMethod: "card" | "bkash" | "bank_transfer" | "free";
325
+ paymentStatus: "pending" | "succeeded" | "failed";
326
+ requiresManualReview: boolean;
327
+ buyerEmail: string;
328
+ paidAt?: NativeDate | null | undefined;
153
329
  refundedAt?: NativeDate | null | undefined;
330
+ paymentId?: string | null | undefined;
331
+ manualReviewReason?: string | null | undefined;
154
332
  confirmedAt?: NativeDate | null | undefined;
155
333
  cancelledAt?: NativeDate | null | undefined;
156
334
  reminderSentAt?: NativeDate | null | undefined;
157
335
  buyerPhone?: string | null | undefined;
158
336
  ipAddress?: string | null | undefined;
159
337
  userAgent?: string | null | undefined;
338
+ orderNumber?: string | null | undefined;
160
339
  refund?: {
161
340
  reason: "event_cancelled" | "user_request" | "fraud";
162
341
  amount: number;
163
342
  refundedAt: NativeDate;
164
343
  stripeRefundId?: string | null | undefined;
165
344
  } | null | undefined;
166
- paymentId?: string | null | undefined;
167
- }> & {
345
+ } & mongoose.DefaultTimestampProps> & {
168
346
  _id: mongoose.Types.ObjectId;
169
347
  } & {
170
348
  __v: number;
171
- }>;
172
- export default orderSchema;
349
+ }>>;
350
+ export default _default;
package/dist/Order.js CHANGED
@@ -4,15 +4,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const mongoose_1 = __importDefault(require("mongoose"));
7
- // Order Ticket Schema
7
+ /* ----------------------------------
8
+ * Embedded Schemas
9
+ * ---------------------------------- */
8
10
  const orderTicketSchema = new mongoose_1.default.Schema({
9
11
  ticketVariantId: {
10
12
  type: mongoose_1.default.Schema.Types.ObjectId,
11
- required: true
13
+ required: true,
14
+ ref: "TicketVariant"
12
15
  },
13
16
  variantName: {
14
17
  type: String,
15
- required: true
18
+ required: true,
19
+ trim: true
16
20
  },
17
21
  quantity: {
18
22
  type: Number,
@@ -30,45 +34,19 @@ const orderTicketSchema = new mongoose_1.default.Schema({
30
34
  min: 0
31
35
  }
32
36
  }, { _id: false });
33
- // Pricing Schema
34
37
  const pricingSchema = new mongoose_1.default.Schema({
35
- subtotal: {
36
- type: Number,
37
- required: true,
38
- min: 0
39
- },
40
- platformFee: {
41
- type: Number,
42
- required: true,
43
- min: 0
44
- },
45
- paymentFee: {
46
- type: Number,
47
- required: true,
48
- min: 0
49
- },
50
- total: {
51
- type: Number,
52
- required: true,
53
- min: 0
54
- },
55
- currency: {
56
- type: String,
57
- required: true,
58
- default: 'BDT'
59
- },
60
- hostPayout: {
61
- type: Number,
62
- required: true,
63
- min: 0
64
- }
38
+ subtotal: { type: Number, required: true, min: 0 },
39
+ platformFee: { type: Number, required: true, min: 0 },
40
+ paymentFee: { type: Number, required: true, min: 0 },
41
+ total: { type: Number, required: true, min: 0 },
42
+ currency: { type: String, default: "BDT" },
43
+ hostPayout: { type: Number, required: true, min: 0 }
65
44
  }, { _id: false });
66
- // Refund Schema
67
45
  const refundSchema = new mongoose_1.default.Schema({
68
46
  reason: {
69
47
  type: String,
70
- required: true,
71
- enum: ['event_cancelled', 'user_request', 'fraud']
48
+ enum: ["event_cancelled", "user_request", "fraud"],
49
+ required: true
72
50
  },
73
51
  amount: {
74
52
  type: Number,
@@ -81,104 +59,145 @@ const refundSchema = new mongoose_1.default.Schema({
81
59
  },
82
60
  stripeRefundId: String
83
61
  }, { _id: false });
84
- // Main Order Schema
62
+ /* ----------------------------------
63
+ * Main Order Schema
64
+ * ---------------------------------- */
85
65
  const orderSchema = new mongoose_1.default.Schema({
66
+ /* ---------- Identity ---------- */
86
67
  orderNumber: {
87
68
  type: String,
88
- required: true,
89
69
  unique: true,
70
+ index: true
90
71
  },
91
- // WHO
92
72
  userId: {
93
73
  type: mongoose_1.default.Schema.Types.ObjectId,
74
+ ref: "User",
94
75
  required: true,
76
+ index: true
95
77
  },
96
- // WHAT
97
78
  eventId: {
98
79
  type: mongoose_1.default.Schema.Types.ObjectId,
80
+ ref: "Event",
99
81
  required: true,
82
+ index: true
100
83
  },
101
- paymentId: {
102
- type: String,
103
- required: false,
84
+ /* ---------- Tickets ---------- */
85
+ tickets: {
86
+ type: [orderTicketSchema],
87
+ validate: (v) => v.length > 0
104
88
  },
105
- tickets: [orderTicketSchema],
106
- // MONEY
107
- pricing: pricingSchema,
108
- // STATUS
109
- status: {
110
- type: String,
89
+ ticketCount: {
90
+ type: Number,
111
91
  required: true,
112
- enum: ['pending', 'confirmed', 'cancelled', 'refunded'],
113
- default: 'pending'
114
- },
115
- requiresManualReview: {
116
- type: Boolean,
117
- default: false
92
+ min: 1
118
93
  },
119
- manualReviewReason: {
120
- type: String,
121
- default: null
94
+ ticketIds: [{
95
+ type: mongoose_1.default.Schema.Types.ObjectId,
96
+ ref: "Ticket"
97
+ }],
98
+ /* ---------- Pricing ---------- */
99
+ pricing: {
100
+ type: pricingSchema,
101
+ required: true
122
102
  },
103
+ /* ---------- Payment ---------- */
104
+ paymentId: String,
123
105
  paymentMethod: {
124
106
  type: String,
125
- required: true,
126
- enum: ['card', 'bkash', 'bank_transfer', 'free']
107
+ enum: ["card", "bkash", "bank_transfer", "free"],
108
+ required: true
127
109
  },
128
110
  paymentStatus: {
129
111
  type: String,
130
- required: true,
131
- enum: ['pending', 'succeeded', 'failed'],
132
- default: 'pending'
112
+ enum: ["pending", "succeeded", "failed"],
113
+ default: "pending",
114
+ index: true
133
115
  },
134
116
  paidAt: Date,
135
- // TICKETS ISSUED
136
- ticketIds: [{
137
- type: mongoose_1.default.Schema.Types.ObjectId,
138
- ref: 'Ticket'
139
- }],
140
- // LIFECYCLE
141
- createdAt: {
142
- type: Date,
143
- default: Date.now,
117
+ /* ---------- Order Lifecycle ---------- */
118
+ status: {
119
+ type: String,
120
+ enum: ["pending", "confirmed", "cancelled", "refunded"],
121
+ default: "pending",
144
122
  index: true
145
123
  },
146
- expiresAt: {
147
- type: Date,
148
- required: true
124
+ requiresManualReview: {
125
+ type: Boolean,
126
+ default: false
149
127
  },
128
+ manualReviewReason: String,
150
129
  confirmedAt: Date,
151
130
  cancelledAt: Date,
152
131
  refundedAt: Date,
132
+ expiresAt: {
133
+ type: Date,
134
+ required: true,
135
+ index: true
136
+ },
153
137
  reminderSentAt: Date,
154
- // CONTACT
138
+ /* ---------- Buyer ---------- */
155
139
  buyerEmail: {
156
140
  type: String,
157
- required: true
141
+ required: true,
142
+ lowercase: true,
143
+ trim: true,
144
+ index: true
158
145
  },
159
146
  buyerPhone: String,
160
- // AUDIT
147
+ /* ---------- Refund ---------- */
148
+ refund: {
149
+ type: refundSchema,
150
+ validate: {
151
+ validator(refund) {
152
+ return !refund || refund.amount <= this.pricing.total;
153
+ },
154
+ message: "Refund amount exceeds order total"
155
+ }
156
+ },
157
+ /* ---------- Audit ---------- */
161
158
  ipAddress: String,
162
- userAgent: String,
163
- // REFUND (if applicable)
164
- refund: refundSchema
159
+ userAgent: String
160
+ }, {
161
+ timestamps: true,
162
+ strict: true
163
+ });
164
+ /* ----------------------------------
165
+ * Indexes
166
+ * ---------------------------------- */
167
+ orderSchema.index({ status: 1, createdAt: -1 });
168
+ orderSchema.index({ eventId: 1, status: 1, createdAt: -1 });
169
+ orderSchema.index({ paymentStatus: 1, createdAt: -1 });
170
+ orderSchema.index({ expiresAt: 1 }, {
171
+ expireAfterSeconds: 0,
172
+ partialFilterExpression: { status: "pending" }
165
173
  });
166
- // Indexes for performance
167
- orderSchema.index({ userId: 1, createdAt: -1 });
168
- orderSchema.index({ eventId: 1, status: 1 });
169
- orderSchema.index({ status: 1, expiresAt: 1 });
170
- // Auto-generate order number
171
- orderSchema.pre('save', function (next) {
174
+ /* ----------------------------------
175
+ * Hooks
176
+ * ---------------------------------- */
177
+ // Generate order number
178
+ orderSchema.pre("save", function (next) {
172
179
  if (this.isNew && !this.orderNumber) {
173
- const timestamp = Date.now().toString().slice(-6);
174
- const random = Math.random().toString(36).substring(2, 8).toUpperCase();
175
- this.orderNumber = `ORD-${timestamp}-${random}`;
180
+ const ts = Date.now().toString().slice(-6);
181
+ const rand = Math.random().toString(36).substring(2, 8).toUpperCase();
182
+ this.orderNumber = `ORD-${ts}-${rand}`;
176
183
  }
177
184
  next();
178
185
  });
179
- // Update updatedAt on save
180
- orderSchema.pre('save', function (next) {
181
- // Note: We don't have updatedAt field, but could add if needed
186
+ // Compute ticket count
187
+ orderSchema.pre("validate", function (next) {
188
+ if (this.tickets?.length) {
189
+ this.ticketCount = this.tickets.reduce((sum, t) => sum + t.quantity, 0);
190
+ }
191
+ next();
192
+ });
193
+ // Pricing immutability after confirmation
194
+ orderSchema.pre("save", function (next) {
195
+ if (!this.isNew && this.isModified("pricing") && this.status !== "pending") {
196
+ return next(new Error("Pricing cannot be modified after confirmation"));
197
+ }
182
198
  next();
183
199
  });
184
- exports.default = orderSchema;
200
+ /* ----------------------------------
201
+ * Export
202
+ * ---------------------------------- */
203
+ exports.default = mongoose_1.default.model("Order", orderSchema);
package/dist/Payment.d.ts CHANGED
@@ -2,7 +2,7 @@ import mongoose from 'mongoose';
2
2
  declare const paymentSchema: mongoose.Schema<any, mongoose.Model<any, any, any, any, any, any>, {}, {}, {}, {}, mongoose.DefaultSchemaOptions, {
3
3
  userId: mongoose.Types.ObjectId;
4
4
  createdAt: NativeDate;
5
- status: "pending" | "refunded" | "succeeded" | "failed";
5
+ status: "pending" | "succeeded" | "failed" | "refunded";
6
6
  amount: number;
7
7
  currency: string;
8
8
  paymentId: string;
@@ -20,7 +20,7 @@ declare const paymentSchema: mongoose.Schema<any, mongoose.Model<any, any, any,
20
20
  }, mongoose.Document<unknown, {}, mongoose.FlatRecord<{
21
21
  userId: mongoose.Types.ObjectId;
22
22
  createdAt: NativeDate;
23
- status: "pending" | "refunded" | "succeeded" | "failed";
23
+ status: "pending" | "succeeded" | "failed" | "refunded";
24
24
  amount: number;
25
25
  currency: string;
26
26
  paymentId: string;
@@ -38,7 +38,7 @@ declare const paymentSchema: mongoose.Schema<any, mongoose.Model<any, any, any,
38
38
  }>, {}, mongoose.ResolveSchemaOptions<mongoose.DefaultSchemaOptions>> & mongoose.FlatRecord<{
39
39
  userId: mongoose.Types.ObjectId;
40
40
  createdAt: NativeDate;
41
- status: "pending" | "refunded" | "succeeded" | "failed";
41
+ status: "pending" | "succeeded" | "failed" | "refunded";
42
42
  amount: number;
43
43
  currency: string;
44
44
  paymentId: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mac777/project-pinecone-models",
3
- "version": "1.1.9",
3
+ "version": "1.1.11",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "scripts": {
package/src/AuditLog.ts CHANGED
@@ -12,13 +12,13 @@ export interface IAuditLog extends Document {
12
12
  }
13
13
 
14
14
  const auditLogSchema = new Schema<IAuditLog>({
15
- userId: { type: String, required: true },
16
- action: { type: String, required: true },
17
- details: { type: Object, required: true },
18
- performedBy: { type: String, required: true },
19
- targetType: { type: String, required: true },
20
- targetId: { type: String, required: true },
21
- metadata: { type: Object, required: true },
15
+ userId: { type: String },
16
+ action: { type: String },
17
+ details: { type: Object },
18
+ performedBy: { type: String },
19
+ targetType: { type: String },
20
+ targetId: { type: String },
21
+ metadata: { type: Object },
22
22
  timestamp: { type: Date, default: Date.now },
23
23
  });
24
24
 
package/src/Order.ts CHANGED
@@ -1,201 +1,252 @@
1
- import mongoose from 'mongoose';
1
+ import mongoose from "mongoose";
2
+
3
+ /* ----------------------------------
4
+ * Embedded Schemas
5
+ * ---------------------------------- */
6
+
7
+ const orderTicketSchema = new mongoose.Schema(
8
+ {
9
+ ticketVariantId: {
10
+ type: mongoose.Schema.Types.ObjectId,
11
+ required: true,
12
+ ref: "TicketVariant"
13
+ },
14
+ variantName: {
15
+ type: String,
16
+ required: true,
17
+ trim: true
18
+ },
19
+ quantity: {
20
+ type: Number,
21
+ required: true,
22
+ min: 1
23
+ },
24
+ pricePerTicket: {
25
+ type: Number,
26
+ required: true,
27
+ min: 0
28
+ },
29
+ subtotal: {
30
+ type: Number,
31
+ required: true,
32
+ min: 0
33
+ }
34
+ },
35
+ { _id: false }
36
+ );
37
+
38
+ const pricingSchema = new mongoose.Schema(
39
+ {
40
+ subtotal: { type: Number, required: true, min: 0 },
41
+ platformFee: { type: Number, required: true, min: 0 },
42
+ paymentFee: { type: Number, required: true, min: 0 },
43
+ total: { type: Number, required: true, min: 0 },
44
+ currency: { type: String, default: "BDT" },
45
+ hostPayout: { type: Number, required: true, min: 0 }
46
+ },
47
+ { _id: false }
48
+ );
49
+
50
+ const refundSchema = new mongoose.Schema(
51
+ {
52
+ reason: {
53
+ type: String,
54
+ enum: ["event_cancelled", "user_request", "fraud"],
55
+ required: true
56
+ },
57
+ amount: {
58
+ type: Number,
59
+ required: true,
60
+ min: 0
61
+ },
62
+ refundedAt: {
63
+ type: Date,
64
+ default: Date.now
65
+ },
66
+ stripeRefundId: String
67
+ },
68
+ { _id: false }
69
+ );
70
+
71
+ /* ----------------------------------
72
+ * Main Order Schema
73
+ * ---------------------------------- */
74
+
75
+ const orderSchema = new mongoose.Schema(
76
+ {
77
+ /* ---------- Identity ---------- */
78
+
79
+ orderNumber: {
80
+ type: String,
81
+ unique: true,
82
+ index: true
83
+ },
84
+
85
+ userId: {
86
+ type: mongoose.Schema.Types.ObjectId,
87
+ ref: "User",
88
+ required: true,
89
+ index: true
90
+ },
91
+
92
+ eventId: {
93
+ type: mongoose.Schema.Types.ObjectId,
94
+ ref: "Event",
95
+ required: true,
96
+ index: true
97
+ },
98
+
99
+ /* ---------- Tickets ---------- */
100
+
101
+ tickets: {
102
+ type: [orderTicketSchema],
103
+ validate: (v: any) => v.length > 0
104
+ },
105
+
106
+ ticketCount: {
107
+ type: Number,
108
+ required: true,
109
+ min: 1
110
+ },
111
+
112
+ ticketIds: [{
113
+ type: mongoose.Schema.Types.ObjectId,
114
+ ref: "Ticket"
115
+ }],
116
+
117
+ /* ---------- Pricing ---------- */
118
+
119
+ pricing: {
120
+ type: pricingSchema,
121
+ required: true
122
+ },
123
+
124
+ /* ---------- Payment ---------- */
125
+
126
+ paymentId: String,
127
+
128
+ paymentMethod: {
129
+ type: String,
130
+ enum: ["card", "bkash", "bank_transfer", "free"],
131
+ required: true
132
+ },
133
+
134
+ paymentStatus: {
135
+ type: String,
136
+ enum: ["pending", "succeeded", "failed"],
137
+ default: "pending",
138
+ index: true
139
+ },
140
+
141
+ paidAt: Date,
142
+
143
+ /* ---------- Order Lifecycle ---------- */
144
+
145
+ status: {
146
+ type: String,
147
+ enum: ["pending", "confirmed", "cancelled", "refunded"],
148
+ default: "pending",
149
+ index: true
150
+ },
151
+
152
+ requiresManualReview: {
153
+ type: Boolean,
154
+ default: false
155
+ },
156
+
157
+ manualReviewReason: String,
158
+
159
+ confirmedAt: Date,
160
+ cancelledAt: Date,
161
+ refundedAt: Date,
162
+
163
+ expiresAt: {
164
+ type: Date,
165
+ required: true,
166
+ index: true
167
+ },
168
+
169
+ reminderSentAt: Date,
170
+
171
+ /* ---------- Buyer ---------- */
172
+
173
+ buyerEmail: {
174
+ type: String,
175
+ required: true,
176
+ lowercase: true,
177
+ trim: true,
178
+ index: true
179
+ },
180
+
181
+ buyerPhone: String,
182
+
183
+ /* ---------- Refund ---------- */
184
+
185
+ refund: {
186
+ type: refundSchema,
187
+ validate: {
188
+ validator(refund: any) {
189
+ return !refund || refund.amount <= this.pricing.total;
190
+ },
191
+ message: "Refund amount exceeds order total"
192
+ }
193
+ },
194
+
195
+ /* ---------- Audit ---------- */
2
196
 
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
197
+ ipAddress: String,
198
+ userAgent: String
199
+ },
200
+ {
201
+ timestamps: true,
202
+ strict: true
27
203
  }
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', 'free']
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
204
+ );
205
+
206
+ /* ----------------------------------
207
+ * Indexes
208
+ * ---------------------------------- */
209
+
210
+ orderSchema.index({ status: 1, createdAt: -1 });
211
+ orderSchema.index({ eventId: 1, status: 1, createdAt: -1 });
212
+ orderSchema.index({ paymentStatus: 1, createdAt: -1 });
213
+ orderSchema.index({ expiresAt: 1 }, {
214
+ expireAfterSeconds: 0,
215
+ partialFilterExpression: { status: "pending" }
178
216
  });
179
217
 
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 });
218
+ /* ----------------------------------
219
+ * Hooks
220
+ * ---------------------------------- */
184
221
 
185
- // Auto-generate order number
186
- orderSchema.pre('save', function(next) {
222
+ // Generate order number
223
+ orderSchema.pre("save", function (next) {
187
224
  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}`;
225
+ const ts = Date.now().toString().slice(-6);
226
+ const rand = Math.random().toString(36).substring(2, 8).toUpperCase();
227
+ this.orderNumber = `ORD-${ts}-${rand}`;
228
+ }
229
+ next();
230
+ });
231
+
232
+ // Compute ticket count
233
+ orderSchema.pre("validate", function (next) {
234
+ if (this.tickets?.length) {
235
+ this.ticketCount = this.tickets.reduce((sum, t) => sum + t.quantity, 0);
191
236
  }
192
237
  next();
193
238
  });
194
239
 
195
- // Update updatedAt on save
196
- orderSchema.pre('save', function(next) {
197
- // Note: We don't have updatedAt field, but could add if needed
240
+ // Pricing immutability after confirmation
241
+ orderSchema.pre("save", function (next) {
242
+ if (!this.isNew && this.isModified("pricing") && this.status !== "pending") {
243
+ return next(new Error("Pricing cannot be modified after confirmation"));
244
+ }
198
245
  next();
199
246
  });
200
247
 
201
- export default orderSchema;
248
+ /* ----------------------------------
249
+ * Export
250
+ * ---------------------------------- */
251
+
252
+ export default mongoose.model("Order", orderSchema);