flykup_model_production 1.0.0
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/auth.js +14 -0
- package/config.js +1 -0
- package/db_connection.js +23 -0
- package/index.js +127 -0
- package/info.txt +1 -0
- package/models/AdminEmail.model.js +36 -0
- package/models/LiveStreamInteraction.model.js +93 -0
- package/models/ProductInteraction.model.js +42 -0
- package/models/Review.model.js +121 -0
- package/models/SearchAnalytics.js +22 -0
- package/models/ShoppableInteraction.model.js +89 -0
- package/models/Wishlist.model.js +30 -0
- package/models/admin.model.js +27 -0
- package/models/appUpdate.model.js +18 -0
- package/models/assets.model.js +32 -0
- package/models/blockedRegion.models.js +27 -0
- package/models/category.model.js +29 -0
- package/models/chat.model.js +496 -0
- package/models/coHostInvitation.model.js +56 -0
- package/models/follow.model.js +37 -0
- package/models/loginlogs.model.js +25 -0
- package/models/notification.model.js +116 -0
- package/models/order.modal.js +285 -0
- package/models/productListing.model.js +132 -0
- package/models/profileInteractions.model.js +45 -0
- package/models/registerShow.model.js +28 -0
- package/models/seller.model.js +299 -0
- package/models/settings.model.js +18 -0
- package/models/shipper.model.js +128 -0
- package/models/shoppableVideo.model.js +177 -0
- package/models/shoppableVideoComment.model.js +58 -0
- package/models/shoppableVideoLike.model.js +30 -0
- package/models/shoppableVideoSave.model.js +28 -0
- package/models/shows.model.js +315 -0
- package/models/stock.model.js +128 -0
- package/models/ticket.model.js +115 -0
- package/models/user.model.js +229 -0
- package/package.json +18 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import mongoose from 'mongoose';
|
|
2
|
+
|
|
3
|
+
const blockedRegionSchema = new mongoose.Schema({
|
|
4
|
+
region: {
|
|
5
|
+
type: String,
|
|
6
|
+
trim: true,
|
|
7
|
+
},
|
|
8
|
+
regionName: {
|
|
9
|
+
type: String,
|
|
10
|
+
trim: true,
|
|
11
|
+
},
|
|
12
|
+
country: {
|
|
13
|
+
type: String,
|
|
14
|
+
trim: true,
|
|
15
|
+
},
|
|
16
|
+
countryName: {
|
|
17
|
+
type: String,
|
|
18
|
+
trim: true,
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
}, {
|
|
22
|
+
timestamps: true
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const BlockedRegion = mongoose.model('BlockedRegion', blockedRegionSchema);
|
|
26
|
+
|
|
27
|
+
export default BlockedRegion;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import mongoose from 'mongoose';
|
|
2
|
+
|
|
3
|
+
const SubcategorySchema = new mongoose.Schema({
|
|
4
|
+
name: {
|
|
5
|
+
type: String,
|
|
6
|
+
required: true,
|
|
7
|
+
},
|
|
8
|
+
minFee: {
|
|
9
|
+
type: Number,
|
|
10
|
+
required: true,
|
|
11
|
+
},
|
|
12
|
+
maxFee: {
|
|
13
|
+
type: Number,
|
|
14
|
+
required: true,
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const CategorySchema = new mongoose.Schema({
|
|
19
|
+
|
|
20
|
+
categoryName: {
|
|
21
|
+
type: String,
|
|
22
|
+
required: true,
|
|
23
|
+
},
|
|
24
|
+
subcategories: [SubcategorySchema],
|
|
25
|
+
}, { timestamps: true });
|
|
26
|
+
|
|
27
|
+
const Category = mongoose.model('Category', CategorySchema);
|
|
28
|
+
|
|
29
|
+
export default Category;
|
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
import mongoose from "mongoose";
|
|
2
|
+
|
|
3
|
+
// Chat Room Schema - Handles different types of conversations
|
|
4
|
+
const ChatRoomSchema = new mongoose.Schema({
|
|
5
|
+
// Room identification
|
|
6
|
+
roomType: {
|
|
7
|
+
type: String,
|
|
8
|
+
enum: [
|
|
9
|
+
'direct_message', // 1-on-1 chat
|
|
10
|
+
'group_chat', // Group conversations
|
|
11
|
+
'live_stream_chat', // Chat during live streams
|
|
12
|
+
'product_inquiry', // Product-specific conversations
|
|
13
|
+
'seller_support', // Seller support conversations
|
|
14
|
+
'order_related' // Order-related conversations
|
|
15
|
+
],
|
|
16
|
+
required: true
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
// Participants
|
|
20
|
+
participants: [{
|
|
21
|
+
userId: {
|
|
22
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
23
|
+
ref: 'users',
|
|
24
|
+
required: true
|
|
25
|
+
},
|
|
26
|
+
userType: {
|
|
27
|
+
type: String,
|
|
28
|
+
enum: ['user', 'seller', 'admin'],
|
|
29
|
+
required: true
|
|
30
|
+
},
|
|
31
|
+
joinedAt: {
|
|
32
|
+
type: Date,
|
|
33
|
+
default: Date.now
|
|
34
|
+
},
|
|
35
|
+
leftAt: {
|
|
36
|
+
type: Date,
|
|
37
|
+
default: null
|
|
38
|
+
},
|
|
39
|
+
role: {
|
|
40
|
+
type: String,
|
|
41
|
+
enum: ['member', 'moderator', 'admin'],
|
|
42
|
+
default: 'member'
|
|
43
|
+
},
|
|
44
|
+
// Notification settings per participant
|
|
45
|
+
notifications: {
|
|
46
|
+
enabled: { type: Boolean, default: true },
|
|
47
|
+
mentions: { type: Boolean, default: true },
|
|
48
|
+
messages: { type: Boolean, default: true }
|
|
49
|
+
},
|
|
50
|
+
// Read receipts
|
|
51
|
+
lastReadMessageId: {
|
|
52
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
53
|
+
ref: 'chatmessages',
|
|
54
|
+
default: null
|
|
55
|
+
},
|
|
56
|
+
lastReadAt: {
|
|
57
|
+
type: Date,
|
|
58
|
+
default: null
|
|
59
|
+
},
|
|
60
|
+
isFavorite: {
|
|
61
|
+
type: Boolean,
|
|
62
|
+
default: false
|
|
63
|
+
},
|
|
64
|
+
favoritedAt: {
|
|
65
|
+
type: Date,
|
|
66
|
+
default: null
|
|
67
|
+
},
|
|
68
|
+
isPinned: { type: Boolean, default: false }, // Add this field
|
|
69
|
+
pinnedAt: Date, // Add this field
|
|
70
|
+
}],
|
|
71
|
+
|
|
72
|
+
// Room metadata
|
|
73
|
+
roomName: {
|
|
74
|
+
type: String,
|
|
75
|
+
maxLength: 100,
|
|
76
|
+
default: null // For group chats
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
roomDescription: {
|
|
80
|
+
type: String,
|
|
81
|
+
maxLength: 500,
|
|
82
|
+
default: null
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
// Room settings
|
|
86
|
+
settings: {
|
|
87
|
+
isPrivate: { type: Boolean, default: false },
|
|
88
|
+
allowFileSharing: { type: Boolean, default: true },
|
|
89
|
+
allowVoiceMessages: { type: Boolean, default: true },
|
|
90
|
+
maxParticipants: { type: Number, default: 100 },
|
|
91
|
+
autoDeleteMessages: { type: Boolean, default: false },
|
|
92
|
+
autoDeleteAfterDays: { type: Number, default: 30 },
|
|
93
|
+
moderationEnabled: { type: Boolean, default: false }
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
// Context-specific data
|
|
97
|
+
contextData: {
|
|
98
|
+
// For product inquiries
|
|
99
|
+
productId: {
|
|
100
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
101
|
+
ref: 'productlistings',
|
|
102
|
+
default: null
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
// For live stream chats
|
|
106
|
+
liveStreamId: {
|
|
107
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
108
|
+
ref: 'shows',
|
|
109
|
+
default: null
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
// For order-related chats
|
|
113
|
+
// orderId: {
|
|
114
|
+
// type: mongoose.Schema.Types.ObjectId,
|
|
115
|
+
// ref: 'orders',
|
|
116
|
+
// default: null
|
|
117
|
+
// },
|
|
118
|
+
|
|
119
|
+
// For seller support
|
|
120
|
+
supportTicketId: {
|
|
121
|
+
type: String,
|
|
122
|
+
default: null
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
// Last activity
|
|
127
|
+
lastActivity: {
|
|
128
|
+
lastMessageId: {
|
|
129
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
130
|
+
ref: 'chatmessages',
|
|
131
|
+
default: null
|
|
132
|
+
},
|
|
133
|
+
lastMessageAt: {
|
|
134
|
+
type: Date,
|
|
135
|
+
default: Date.now
|
|
136
|
+
},
|
|
137
|
+
lastMessagePreview: {
|
|
138
|
+
type: String,
|
|
139
|
+
maxLength: 200,
|
|
140
|
+
default: null
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
// Room status
|
|
145
|
+
status: {
|
|
146
|
+
type: String,
|
|
147
|
+
enum: ['active', 'archived', 'blocked', 'deleted'],
|
|
148
|
+
default: 'active'
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
// Created by
|
|
152
|
+
createdBy: {
|
|
153
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
154
|
+
ref: 'users',
|
|
155
|
+
required: true
|
|
156
|
+
}
|
|
157
|
+
}, {
|
|
158
|
+
timestamps: true,
|
|
159
|
+
strict: true
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// Chat Message Schema
|
|
163
|
+
const ChatMessageSchema = new mongoose.Schema({
|
|
164
|
+
// Message identification
|
|
165
|
+
chatRoomId: {
|
|
166
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
167
|
+
ref: 'chatrooms',
|
|
168
|
+
required: true,
|
|
169
|
+
index: true
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
// Sender information
|
|
173
|
+
senderId: {
|
|
174
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
175
|
+
ref: 'users',
|
|
176
|
+
required: true,
|
|
177
|
+
index: true
|
|
178
|
+
},
|
|
179
|
+
|
|
180
|
+
senderType: {
|
|
181
|
+
type: String,
|
|
182
|
+
enum: ['user', 'seller', 'admin', 'system'],
|
|
183
|
+
required: true
|
|
184
|
+
},
|
|
185
|
+
|
|
186
|
+
// Message content
|
|
187
|
+
messageType: {
|
|
188
|
+
type: String,
|
|
189
|
+
enum: [
|
|
190
|
+
'text',
|
|
191
|
+
'image',
|
|
192
|
+
'video',
|
|
193
|
+
'audio',
|
|
194
|
+
'file',
|
|
195
|
+
'product_share',
|
|
196
|
+
'live_stream_share',
|
|
197
|
+
'location',
|
|
198
|
+
'contact',
|
|
199
|
+
'system_message',
|
|
200
|
+
'emoji_reaction',
|
|
201
|
+
'poll',
|
|
202
|
+
'payment_request'
|
|
203
|
+
],
|
|
204
|
+
required: true
|
|
205
|
+
},
|
|
206
|
+
|
|
207
|
+
content: {
|
|
208
|
+
// For text messages
|
|
209
|
+
text: {
|
|
210
|
+
type: String,
|
|
211
|
+
maxLength: 2000,
|
|
212
|
+
default: null
|
|
213
|
+
},
|
|
214
|
+
|
|
215
|
+
// For media messages
|
|
216
|
+
media: {
|
|
217
|
+
type: {
|
|
218
|
+
type: String,
|
|
219
|
+
enum: ['image', 'video', 'audio', 'file'],
|
|
220
|
+
default: null
|
|
221
|
+
},
|
|
222
|
+
url: { type: String, default: null },
|
|
223
|
+
thumbnail: { type: String, default: null },
|
|
224
|
+
fileName: { type: String, default: null },
|
|
225
|
+
fileSize: { type: Number, default: null },
|
|
226
|
+
duration: { type: Number, default: null }, // For audio/video
|
|
227
|
+
dimensions: {
|
|
228
|
+
width: { type: Number, default: null },
|
|
229
|
+
height: { type: Number, default: null }
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
|
|
233
|
+
// For product shares
|
|
234
|
+
productShare: {
|
|
235
|
+
productId: {
|
|
236
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
237
|
+
ref: 'products',
|
|
238
|
+
default: null
|
|
239
|
+
},
|
|
240
|
+
productName: { type: String, default: null },
|
|
241
|
+
productImage: { type: String, default: null },
|
|
242
|
+
productPrice: { type: Number, default: null }
|
|
243
|
+
},
|
|
244
|
+
|
|
245
|
+
// For live stream shares
|
|
246
|
+
liveStreamShare: {
|
|
247
|
+
liveStreamId: {
|
|
248
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
249
|
+
ref: 'livestreams',
|
|
250
|
+
default: null
|
|
251
|
+
},
|
|
252
|
+
streamTitle: { type: String, default: null },
|
|
253
|
+
streamThumbnail: { type: String, default: null },
|
|
254
|
+
isLive: { type: Boolean, default: false }
|
|
255
|
+
},
|
|
256
|
+
|
|
257
|
+
// For location sharing
|
|
258
|
+
location: {
|
|
259
|
+
latitude: { type: Number, default: null },
|
|
260
|
+
longitude: { type: Number, default: null },
|
|
261
|
+
address: { type: String, default: null }
|
|
262
|
+
},
|
|
263
|
+
|
|
264
|
+
// For system messages
|
|
265
|
+
systemMessage: {
|
|
266
|
+
type: { type: String, default: null },
|
|
267
|
+
data: { type: mongoose.Schema.Types.Mixed, default: null }
|
|
268
|
+
},
|
|
269
|
+
|
|
270
|
+
// For polls
|
|
271
|
+
poll: {
|
|
272
|
+
question: { type: String, default: null },
|
|
273
|
+
options: [{ type: String }],
|
|
274
|
+
allowMultiple: { type: Boolean, default: false },
|
|
275
|
+
expiresAt: { type: Date, default: null }
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
|
|
279
|
+
// Message metadata
|
|
280
|
+
metadata: {
|
|
281
|
+
// Reply to another message
|
|
282
|
+
replyToMessageId: {
|
|
283
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
284
|
+
ref: 'chatmessages',
|
|
285
|
+
default: null
|
|
286
|
+
},
|
|
287
|
+
|
|
288
|
+
// Forward information
|
|
289
|
+
forwardedFrom: {
|
|
290
|
+
chatRoomId: {
|
|
291
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
292
|
+
ref: 'chatrooms',
|
|
293
|
+
default: null
|
|
294
|
+
},
|
|
295
|
+
originalMessageId: {
|
|
296
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
297
|
+
ref: 'chatmessages',
|
|
298
|
+
default: null
|
|
299
|
+
}
|
|
300
|
+
},
|
|
301
|
+
|
|
302
|
+
// Mentions
|
|
303
|
+
mentions: [{
|
|
304
|
+
userId: {
|
|
305
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
306
|
+
ref: 'users'
|
|
307
|
+
},
|
|
308
|
+
userName: { type: String }
|
|
309
|
+
}],
|
|
310
|
+
|
|
311
|
+
// Hashtags
|
|
312
|
+
hashtags: [{ type: String }],
|
|
313
|
+
|
|
314
|
+
// Message editing
|
|
315
|
+
isEdited: { type: Boolean, default: false },
|
|
316
|
+
editedAt: { type: Date, default: null },
|
|
317
|
+
editHistory: [{
|
|
318
|
+
content: { type: String },
|
|
319
|
+
editedAt: { type: Date }
|
|
320
|
+
}]
|
|
321
|
+
},
|
|
322
|
+
|
|
323
|
+
// Message status
|
|
324
|
+
status: {
|
|
325
|
+
type: String,
|
|
326
|
+
enum: ['sent', 'delivered', 'read', 'failed', 'deleted'],
|
|
327
|
+
default: 'sent'
|
|
328
|
+
},
|
|
329
|
+
|
|
330
|
+
// Delivery and read receipts
|
|
331
|
+
deliveryStatus: [{
|
|
332
|
+
userId: {
|
|
333
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
334
|
+
ref: 'users'
|
|
335
|
+
},
|
|
336
|
+
deliveredAt: { type: Date },
|
|
337
|
+
readAt: { type: Date }
|
|
338
|
+
}],
|
|
339
|
+
|
|
340
|
+
// Message reactions
|
|
341
|
+
reactions: [{
|
|
342
|
+
userId: {
|
|
343
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
344
|
+
ref: 'users'
|
|
345
|
+
},
|
|
346
|
+
emoji: { type: String },
|
|
347
|
+
reactedAt: { type: Date, default: Date.now }
|
|
348
|
+
}],
|
|
349
|
+
|
|
350
|
+
// Moderation
|
|
351
|
+
moderation: {
|
|
352
|
+
isReported: { type: Boolean, default: false },
|
|
353
|
+
reportCount: { type: Number, default: 0 },
|
|
354
|
+
isBlocked: { type: Boolean, default: false },
|
|
355
|
+
blockedReason: { type: String, default: null },
|
|
356
|
+
moderatedBy: {
|
|
357
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
358
|
+
ref: 'users',
|
|
359
|
+
default: null
|
|
360
|
+
}
|
|
361
|
+
},
|
|
362
|
+
|
|
363
|
+
// Scheduled messages
|
|
364
|
+
scheduledFor: {
|
|
365
|
+
type: Date,
|
|
366
|
+
default: null
|
|
367
|
+
},
|
|
368
|
+
|
|
369
|
+
// Auto-delete
|
|
370
|
+
expiresAt: {
|
|
371
|
+
type: Date,
|
|
372
|
+
default: null
|
|
373
|
+
}
|
|
374
|
+
}, {
|
|
375
|
+
timestamps: true,
|
|
376
|
+
strict: true
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
// Chat Room Member Schema - For tracking membership history
|
|
380
|
+
const ChatRoomMemberSchema = new mongoose.Schema({
|
|
381
|
+
chatRoomId: {
|
|
382
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
383
|
+
ref: 'chatrooms',
|
|
384
|
+
required: true
|
|
385
|
+
},
|
|
386
|
+
|
|
387
|
+
userId: {
|
|
388
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
389
|
+
ref: 'users',
|
|
390
|
+
required: true
|
|
391
|
+
},
|
|
392
|
+
|
|
393
|
+
userType: {
|
|
394
|
+
type: String,
|
|
395
|
+
enum: ['user', 'seller', 'admin'],
|
|
396
|
+
required: true
|
|
397
|
+
},
|
|
398
|
+
|
|
399
|
+
role: {
|
|
400
|
+
type: String,
|
|
401
|
+
enum: ['member', 'moderator', 'admin'],
|
|
402
|
+
default: 'member'
|
|
403
|
+
},
|
|
404
|
+
|
|
405
|
+
joinedAt: {
|
|
406
|
+
type: Date,
|
|
407
|
+
default: Date.now
|
|
408
|
+
},
|
|
409
|
+
|
|
410
|
+
leftAt: {
|
|
411
|
+
type: Date,
|
|
412
|
+
default: null
|
|
413
|
+
},
|
|
414
|
+
|
|
415
|
+
addedBy: {
|
|
416
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
417
|
+
ref: 'users',
|
|
418
|
+
default: null
|
|
419
|
+
},
|
|
420
|
+
|
|
421
|
+
removedBy: {
|
|
422
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
423
|
+
ref: 'users',
|
|
424
|
+
default: null
|
|
425
|
+
},
|
|
426
|
+
|
|
427
|
+
status: {
|
|
428
|
+
type: String,
|
|
429
|
+
enum: ['active', 'left', 'removed', 'banned'],
|
|
430
|
+
default: 'active'
|
|
431
|
+
}
|
|
432
|
+
}, {
|
|
433
|
+
timestamps: true
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
// Block/Mute Schema - For user blocking and muting
|
|
437
|
+
const ChatBlockSchema = new mongoose.Schema({
|
|
438
|
+
blockerId: {
|
|
439
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
440
|
+
ref: 'users',
|
|
441
|
+
required: true
|
|
442
|
+
},
|
|
443
|
+
|
|
444
|
+
blockedUserId: {
|
|
445
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
446
|
+
ref: 'users',
|
|
447
|
+
required: true
|
|
448
|
+
},
|
|
449
|
+
|
|
450
|
+
blockType: {
|
|
451
|
+
type: String,
|
|
452
|
+
enum: ['block', 'mute'],
|
|
453
|
+
required: true
|
|
454
|
+
},
|
|
455
|
+
|
|
456
|
+
reason: {
|
|
457
|
+
type: String,
|
|
458
|
+
maxLength: 500,
|
|
459
|
+
default: null
|
|
460
|
+
},
|
|
461
|
+
|
|
462
|
+
expiresAt: {
|
|
463
|
+
type: Date,
|
|
464
|
+
default: null // null means permanent
|
|
465
|
+
},
|
|
466
|
+
|
|
467
|
+
isActive: {
|
|
468
|
+
type: Boolean,
|
|
469
|
+
default: true
|
|
470
|
+
}
|
|
471
|
+
}, {
|
|
472
|
+
timestamps: true
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
// Indexes for better performance
|
|
476
|
+
ChatRoomSchema.index({ 'participants.userId': 1, roomType: 1 });
|
|
477
|
+
ChatRoomSchema.index({ 'contextData.productId': 1 });
|
|
478
|
+
ChatRoomSchema.index({ 'contextData.liveStreamId': 1 });
|
|
479
|
+
ChatRoomSchema.index({ 'lastActivity.lastMessageAt': -1 });
|
|
480
|
+
|
|
481
|
+
ChatMessageSchema.index({ chatRoomId: 1, createdAt: -1 });
|
|
482
|
+
ChatMessageSchema.index({ senderId: 1, createdAt: -1 });
|
|
483
|
+
ChatMessageSchema.index({ 'metadata.mentions.userId': 1 });
|
|
484
|
+
|
|
485
|
+
ChatRoomMemberSchema.index({ chatRoomId: 1, userId: 1 });
|
|
486
|
+
ChatRoomMemberSchema.index({ userId: 1, status: 1 });
|
|
487
|
+
|
|
488
|
+
ChatBlockSchema.index({ blockerId: 1, blockedUserId: 1 });
|
|
489
|
+
|
|
490
|
+
// Models
|
|
491
|
+
const ChatRoom = mongoose.model('chatrooms', ChatRoomSchema);
|
|
492
|
+
const ChatMessage = mongoose.model('chatmessages', ChatMessageSchema);
|
|
493
|
+
const ChatRoomMember = mongoose.model('chatroommembers', ChatRoomMemberSchema);
|
|
494
|
+
const ChatBlock = mongoose.model('chatblocks', ChatBlockSchema);
|
|
495
|
+
|
|
496
|
+
export { ChatRoom, ChatMessage, ChatRoomMember, ChatBlock };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import mongoose, { Schema } from "mongoose";
|
|
2
|
+
|
|
3
|
+
const coHostInviteSchema = new Schema(
|
|
4
|
+
{
|
|
5
|
+
show: { type: Schema.Types.ObjectId, ref: "shows", required: true },
|
|
6
|
+
host: {
|
|
7
|
+
userId: { type: Schema.Types.ObjectId, ref: "users", required: true },
|
|
8
|
+
hostId: {
|
|
9
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
10
|
+
required: true,
|
|
11
|
+
refPath: "host.hostModel",
|
|
12
|
+
},
|
|
13
|
+
hostModel: {
|
|
14
|
+
type: String,
|
|
15
|
+
required: true,
|
|
16
|
+
enum: {
|
|
17
|
+
values: ["sellers", "dropshippers"],
|
|
18
|
+
message: `{VALUE} is invalid host model`,
|
|
19
|
+
},
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
cohost: {
|
|
23
|
+
userId: { type: Schema.Types.ObjectId, ref: "users", required: true },
|
|
24
|
+
hostId: {
|
|
25
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
26
|
+
required: true,
|
|
27
|
+
refPath: "cohost.hostModel",
|
|
28
|
+
},
|
|
29
|
+
hostModel: {
|
|
30
|
+
type: String,
|
|
31
|
+
required: true,
|
|
32
|
+
enum: {
|
|
33
|
+
values: ["sellers", "dropshippers"],
|
|
34
|
+
message: `{VALUE} is invalid cohost model`,
|
|
35
|
+
},
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
status: {
|
|
39
|
+
type: String,
|
|
40
|
+
enum: ["pending", "accepted", "rejected", "cancelled", "left"],
|
|
41
|
+
default: "pending",
|
|
42
|
+
index: true
|
|
43
|
+
},
|
|
44
|
+
joinedAt: Date,
|
|
45
|
+
leftAt: Date,
|
|
46
|
+
liveStreamId: String,
|
|
47
|
+
},
|
|
48
|
+
{ timestamps: true }
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
coHostInviteSchema.index({ show: 1, status: 1 });
|
|
52
|
+
coHostInviteSchema.index({ "cohost.userId": 1, status: 1 });
|
|
53
|
+
|
|
54
|
+
const CoHostInvite = mongoose.model("cohostinvites", coHostInviteSchema);
|
|
55
|
+
|
|
56
|
+
export default CoHostInvite;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import mongoose from "mongoose";
|
|
2
|
+
|
|
3
|
+
const FollowSchema = new mongoose.Schema(
|
|
4
|
+
{
|
|
5
|
+
follower: {
|
|
6
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
7
|
+
ref: "users",
|
|
8
|
+
required: true,
|
|
9
|
+
},
|
|
10
|
+
following: {
|
|
11
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
12
|
+
ref: "users",
|
|
13
|
+
required: true,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
{ timestamps: true }
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
// Prevent duplicate follows
|
|
20
|
+
FollowSchema.index({ follower: 1, following: 1 }, { unique: true });
|
|
21
|
+
|
|
22
|
+
// Add helpful indexes for efficient querying
|
|
23
|
+
FollowSchema.index({ follower: 1 });
|
|
24
|
+
FollowSchema.index({ following: 1 });
|
|
25
|
+
|
|
26
|
+
FollowSchema.pre('save', function(next) {
|
|
27
|
+
if (this.follower.equals(this.following)) {
|
|
28
|
+
const err = new Error("Cannot follow yourself");
|
|
29
|
+
next(err);
|
|
30
|
+
} else {
|
|
31
|
+
next();
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const Follow = mongoose.model("follows", FollowSchema);
|
|
36
|
+
|
|
37
|
+
export default Follow;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import mongoose from 'mongoose';
|
|
2
|
+
|
|
3
|
+
const loginLogSchema = new mongoose.Schema({
|
|
4
|
+
userId: {
|
|
5
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
6
|
+
ref: "users",
|
|
7
|
+
required: true,
|
|
8
|
+
},
|
|
9
|
+
ip: { type: String, required: true },
|
|
10
|
+
country: String,
|
|
11
|
+
region: String,
|
|
12
|
+
city: String,
|
|
13
|
+
location: String,
|
|
14
|
+
device: Object,
|
|
15
|
+
browser: Object,
|
|
16
|
+
os: Object,
|
|
17
|
+
loginType: String,
|
|
18
|
+
status: { type: String, enum: ['active', 'loggedOut'], default: 'active' }, // 🔥 new field
|
|
19
|
+
lastActivity: { type: Date, default: Date.now }, // 🔥 to track token refresh or other actions
|
|
20
|
+
time: { type: Date, default: Date.now }
|
|
21
|
+
}, { timestamps: true });
|
|
22
|
+
|
|
23
|
+
const LoginLog = mongoose.model('LoginLog', loginLogSchema);
|
|
24
|
+
|
|
25
|
+
export default LoginLog;
|