@mac777/project-pinecone-models 1.1.11 → 1.1.13

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.
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const mongoose_1 = __importDefault(require("mongoose"));
7
+ /* ----------------------------------
8
+ * Subschemas
9
+ * ---------------------------------- */
10
+ const contactSchema = new mongoose_1.default.Schema({
11
+ email: {
12
+ type: String,
13
+ required: true,
14
+ lowercase: true,
15
+ trim: true,
16
+ index: true
17
+ },
18
+ emailVerified: {
19
+ type: Boolean,
20
+ default: false
21
+ },
22
+ emailVerification: {
23
+ token: String,
24
+ expiresAt: Date
25
+ },
26
+ phone: {
27
+ type: String
28
+ },
29
+ phoneVerified: {
30
+ type: Boolean,
31
+ default: false
32
+ },
33
+ phoneVerification: {
34
+ token: String,
35
+ expiresAt: Date
36
+ }
37
+ }, { _id: false });
38
+ const identitySchema = new mongoose_1.default.Schema({
39
+ nidNumber: String,
40
+ nidVerified: {
41
+ type: Boolean,
42
+ default: false
43
+ },
44
+ verifiedAt: Date
45
+ }, { _id: false });
46
+ const payoutSchema = new mongoose_1.default.Schema({
47
+ method: {
48
+ type: String,
49
+ enum: ["bkash", "bank_transfer"],
50
+ default: "bkash"
51
+ },
52
+ bkash: {
53
+ number: String
54
+ },
55
+ bank: {
56
+ bankName: String,
57
+ accountName: String,
58
+ accountNumber: String,
59
+ branchName: String,
60
+ routingNumber: String
61
+ },
62
+ verified: {
63
+ type: Boolean,
64
+ default: false
65
+ },
66
+ verifiedAt: Date
67
+ }, { _id: false });
68
+ const profileSchema = new mongoose_1.default.Schema({
69
+ firstName: {
70
+ type: String,
71
+ required: true,
72
+ trim: true
73
+ },
74
+ lastName: {
75
+ type: String,
76
+ required: true,
77
+ trim: true
78
+ },
79
+ organization: String,
80
+ avatar: {
81
+ url: String,
82
+ publicId: String // S3 / Cloudinary
83
+ }
84
+ }, { _id: false });
85
+ const authSchema = new mongoose_1.default.Schema({
86
+ provider: {
87
+ type: String,
88
+ enum: ["local", "google"],
89
+ default: "local"
90
+ },
91
+ password: {
92
+ type: String,
93
+ select: false
94
+ },
95
+ googleId: {
96
+ type: String,
97
+ index: true
98
+ },
99
+ refreshToken: {
100
+ type: String,
101
+ select: false
102
+ }
103
+ }, { _id: false });
104
+ /* ----------------------------------
105
+ * Main User Schema
106
+ * ---------------------------------- */
107
+ const userSchema = new mongoose_1.default.Schema({
108
+ profile: profileSchema,
109
+ contact: contactSchema,
110
+ identity: identitySchema,
111
+ payout: payoutSchema,
112
+ auth: authSchema,
113
+ role: {
114
+ type: String,
115
+ enum: ["user", "host", "admin"],
116
+ default: "user",
117
+ index: true
118
+ },
119
+ status: {
120
+ type: String,
121
+ enum: ["active", "suspended", "deleted"],
122
+ default: "active",
123
+ index: true
124
+ },
125
+ lastLoginAt: Date
126
+ }, {
127
+ timestamps: true,
128
+ strict: true
129
+ });
130
+ /* ----------------------------------
131
+ * Indexes
132
+ * ---------------------------------- */
133
+ userSchema.index({ "contact.email": 1 }, { unique: true });
134
+ userSchema.index({ "auth.googleId": 1 }, { sparse: true });
135
+ userSchema.index({ role: 1, status: 1 });
136
+ /* ----------------------------------
137
+ * Virtuals
138
+ * ---------------------------------- */
139
+ userSchema.virtual("fullName").get(function () {
140
+ return `${this.profile?.firstName || ""} ${this.profile?.lastName || ""}`;
141
+ });
142
+ /* ----------------------------------
143
+ * Export
144
+ * ---------------------------------- */
145
+ exports.default = userSchema;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mac777/project-pinecone-models",
3
- "version": "1.1.11",
3
+ "version": "1.1.13",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "scripts": {
package/src/Event.ts CHANGED
@@ -203,7 +203,7 @@ const historySchema = new mongoose.Schema({
203
203
  }, { _id: false });
204
204
 
205
205
  const eventSchema = new mongoose.Schema({
206
- hostId: { type: mongoose.Schema.Types.ObjectId, required: true },
206
+ hostId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
207
207
  slug: String,
208
208
 
209
209
  // STEP 1: BASICS
package/src/Media.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import mongoose from 'mongoose';
2
2
 
3
3
  const mediaSchema = new mongoose.Schema({
4
- userId: { type: mongoose.Schema.Types.ObjectId, required: true },
4
+ userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
5
5
  type: { type: String, enum: ['event_cover', 'event_gallery', 'verification_doc'], required: true },
6
6
  provider: { type: String, enum: ['imagekit', 'backblaze'], required: true },
7
7
  status: { type: String, enum: ['temp', 'permanent', 'deleted'], required: true },
package/src/Order.ts CHANGED
@@ -1,252 +1,204 @@
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 ---------- */
1
+ import mongoose from 'mongoose';
196
2
 
197
- ipAddress: String,
198
- userAgent: String
199
- },
200
- {
201
- timestamps: true,
202
- strict: true
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
203
27
  }
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" }
216
- });
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
+ ref: 'User',
95
+ required: true,
96
+ },
217
97
 
218
- /* ----------------------------------
219
- * Hooks
220
- * ---------------------------------- */
98
+ // WHAT
99
+ eventId: {
100
+ type: mongoose.Schema.Types.ObjectId,
101
+ ref: 'Event',
102
+ required: true,
103
+ },
221
104
 
222
- // Generate order number
223
- orderSchema.pre("save", function (next) {
224
- if (this.isNew && !this.orderNumber) {
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();
105
+ paymentId: {
106
+ type: String,
107
+ ref: 'Payment',
108
+ required: false,
109
+ },
110
+
111
+ tickets: [orderTicketSchema],
112
+
113
+ // MONEY
114
+ pricing: pricingSchema,
115
+
116
+ // STATUS
117
+ status: {
118
+ type: String,
119
+ required: true,
120
+ enum: ['pending', 'confirmed', 'cancelled', 'refunded'],
121
+ default: 'pending'
122
+ },
123
+
124
+ requiresManualReview: {
125
+ type: Boolean,
126
+ default: false
127
+ },
128
+
129
+ manualReviewReason: {
130
+ type: String,
131
+ default: null
132
+ },
133
+
134
+ paymentMethod: {
135
+ type: String,
136
+ required: true,
137
+ enum: ['card', 'bkash', 'bank_transfer', 'free']
138
+ },
139
+ paymentStatus: {
140
+ type: String,
141
+ required: true,
142
+ enum: ['pending', 'succeeded', 'failed'],
143
+ default: 'pending'
144
+ },
145
+ paidAt: Date,
146
+
147
+ // TICKETS ISSUED
148
+ ticketIds: [{
149
+ type: mongoose.Schema.Types.ObjectId,
150
+ ref: 'Ticket'
151
+ }],
152
+
153
+ // LIFECYCLE
154
+ createdAt: {
155
+ type: Date,
156
+ default: Date.now,
157
+ index: true
158
+ },
159
+ expiresAt: {
160
+ type: Date,
161
+ required: true
162
+ },
163
+ confirmedAt: Date,
164
+ cancelledAt: Date,
165
+ refundedAt: Date,
166
+ reminderSentAt: Date,
167
+
168
+ // CONTACT
169
+ buyerEmail: {
170
+ type: String,
171
+ required: true
172
+ },
173
+ buyerPhone: String,
174
+
175
+ // AUDIT
176
+ ipAddress: String,
177
+ userAgent: String,
178
+
179
+ // REFUND (if applicable)
180
+ refund: refundSchema
230
181
  });
231
182
 
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);
183
+ // Indexes for performance
184
+ orderSchema.index({ userId: 1, createdAt: -1 });
185
+ orderSchema.index({ eventId: 1, status: 1 });
186
+ orderSchema.index({ status: 1, expiresAt: 1 });
187
+
188
+ // Auto-generate order number
189
+ orderSchema.pre('save', function(next) {
190
+ if (this.isNew && !this.orderNumber) {
191
+ const timestamp = Date.now().toString().slice(-6);
192
+ const random = Math.random().toString(36).substring(2, 8).toUpperCase();
193
+ this.orderNumber = `ORD-${timestamp}-${random}`;
236
194
  }
237
195
  next();
238
196
  });
239
197
 
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
+ // Update updatedAt on save
199
+ orderSchema.pre('save', function(next) {
200
+ // Note: We don't have updatedAt field, but could add if needed
245
201
  next();
246
202
  });
247
203
 
248
- /* ----------------------------------
249
- * Export
250
- * ---------------------------------- */
251
-
252
- export default mongoose.model("Order", orderSchema);
204
+ export default orderSchema;