flykup_model_production 1.0.16 → 1.0.18

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