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.
Files changed (38) hide show
  1. package/auth.js +14 -0
  2. package/config.js +1 -0
  3. package/db_connection.js +23 -0
  4. package/index.js +127 -0
  5. package/info.txt +1 -0
  6. package/models/AdminEmail.model.js +36 -0
  7. package/models/LiveStreamInteraction.model.js +93 -0
  8. package/models/ProductInteraction.model.js +42 -0
  9. package/models/Review.model.js +121 -0
  10. package/models/SearchAnalytics.js +22 -0
  11. package/models/ShoppableInteraction.model.js +89 -0
  12. package/models/Wishlist.model.js +30 -0
  13. package/models/admin.model.js +27 -0
  14. package/models/appUpdate.model.js +18 -0
  15. package/models/assets.model.js +32 -0
  16. package/models/blockedRegion.models.js +27 -0
  17. package/models/category.model.js +29 -0
  18. package/models/chat.model.js +496 -0
  19. package/models/coHostInvitation.model.js +56 -0
  20. package/models/follow.model.js +37 -0
  21. package/models/loginlogs.model.js +25 -0
  22. package/models/notification.model.js +116 -0
  23. package/models/order.modal.js +285 -0
  24. package/models/productListing.model.js +132 -0
  25. package/models/profileInteractions.model.js +45 -0
  26. package/models/registerShow.model.js +28 -0
  27. package/models/seller.model.js +299 -0
  28. package/models/settings.model.js +18 -0
  29. package/models/shipper.model.js +128 -0
  30. package/models/shoppableVideo.model.js +177 -0
  31. package/models/shoppableVideoComment.model.js +58 -0
  32. package/models/shoppableVideoLike.model.js +30 -0
  33. package/models/shoppableVideoSave.model.js +28 -0
  34. package/models/shows.model.js +315 -0
  35. package/models/stock.model.js +128 -0
  36. package/models/ticket.model.js +115 -0
  37. package/models/user.model.js +229 -0
  38. package/package.json +18 -0
@@ -0,0 +1,299 @@
1
+
2
+
3
+ import mongoose from "mongoose";
4
+ const { Schema } = mongoose;
5
+
6
+
7
+ const dropshipperConnectionSchema = new Schema({
8
+ _id: false,
9
+ dropshipperId: {
10
+ type: mongoose.Schema.Types.ObjectId,
11
+ ref: "dropshippers",
12
+ required: true,
13
+ },
14
+ status: {
15
+ type: String,
16
+ enum: [
17
+ "pending",
18
+ "approved",
19
+ "rejected",
20
+ "revoked_by_seller",
21
+ "revoked_by_dropshipper",
22
+ ],
23
+ required: true,
24
+ default: "pending",
25
+ },
26
+ commissionRate: {
27
+ type: Number, // Store as percentage, e.g., 15 for 15%
28
+ min: 0,
29
+ max: 100,
30
+ default: null, // Or a platform default? Needs discussion
31
+ },
32
+ agreementDetails: {
33
+ type: String,
34
+ maxLength: 500,
35
+ default: null,
36
+ },
37
+ requestedAt: {
38
+ type: Date,
39
+ default: Date.now,
40
+ },
41
+ respondedAt: {
42
+ type: Date,
43
+ default: null,
44
+ },
45
+ });
46
+
47
+ const RedFlagsSchema = new mongoose.Schema({
48
+ type: { type: String, required: true },
49
+ description: { type: String, required: true },
50
+ severity: { type: String, enum: ['low', 'medium', 'high'], required: true }
51
+ }, { _id: false })
52
+
53
+ const ScoringSchema = new mongoose.Schema({
54
+ totalScore: { type: Number, default: 0, min: 0 },
55
+ breakdown: { type: mongoose.Schema.Types.Mixed, default: {} },
56
+ redFlags: [RedFlagsSchema],
57
+ manualChecks: [String],
58
+ recommendation: { type: String, enum: ['auto_approved', 'auto_rejected', 'manual_review'] },
59
+ rejectedReason: { type: String, default: null }
60
+ }, { _id: false })
61
+
62
+ const SellerSchema = new mongoose.Schema(
63
+ {
64
+ userInfo: {
65
+ type: mongoose.Schema.Types.ObjectId,
66
+ ref: "users",
67
+ required: true,
68
+ },
69
+ dropshipperConnections: [
70
+ dropshipperConnectionSchema
71
+ ],
72
+ isAdult: {
73
+ type: Boolean,
74
+ // required: function (){
75
+ // return this.sellerType === 'social'
76
+ // }
77
+ },
78
+ companyName: {
79
+ type: String,
80
+ maxLength: 50,
81
+ },
82
+ mobileNumber: {
83
+ type: String,
84
+ maxLength: 15,
85
+ },
86
+ email: {
87
+ type: String,
88
+ trim: true,
89
+ // required: true,
90
+ maxLength: 60,
91
+ },
92
+ sellerType: {
93
+ type: String,
94
+ enum: ["brand", "social"],
95
+ // required: true,
96
+ },
97
+ businessType: {
98
+ type: String,
99
+ enum: [
100
+ "Individual",
101
+ "Sole Proprietor",
102
+ "Private Limited",
103
+ "LLP",
104
+ "Partnership",
105
+ ],
106
+ // required: true,
107
+ },
108
+ productCategories: [
109
+ {
110
+ type: String,
111
+ },
112
+ ],
113
+ fssaiCertificateFileName: {
114
+ type: String
115
+ },
116
+ productCatalog: {
117
+ link: { type: String },
118
+ file: { type: String }, // for old sellers
119
+ files: [{ type: String }] // for new sellers
120
+ },
121
+ wantToSell: [
122
+ { type: String }
123
+ ],
124
+ sellerExperienceInfo: {
125
+ online: [
126
+ {
127
+ platform: { type: String },
128
+ profile: { type: String },
129
+ },
130
+ ],
131
+ offline: [{ type: String }],
132
+ experience: {
133
+ type: String,
134
+ trim: true,
135
+ },
136
+ },
137
+ gstInfo: {
138
+ hasGST: {
139
+ type: Boolean,
140
+ default: null,
141
+ },
142
+ gstDeclaration: {
143
+ type: String,
144
+ default: null,
145
+ },
146
+ gstNumber: {
147
+ type: String,
148
+ trim: true,
149
+ maxLength: 25,
150
+ default: null,
151
+ },
152
+ gstDocument: {
153
+ type: String,
154
+ trim: true,
155
+ default: null,
156
+ },
157
+ },
158
+ aadhaarInfo: {
159
+ aadhaarNumber: {
160
+ type: String,
161
+ // required: true,
162
+ trim: true,
163
+ maxLength: 12,
164
+ },
165
+ aadhaarFront: {
166
+ type: String,
167
+ default: null,
168
+ trim: true,
169
+ },
170
+ aadhaarBack: {
171
+ type: String,
172
+ default: null,
173
+ trim: true,
174
+ },
175
+ },
176
+ panInfo: {
177
+ panNumber: {
178
+ type: String,
179
+ // required: true,
180
+ trim: true,
181
+ },
182
+ panFront: {
183
+ type: String,
184
+ default: null,
185
+ trim: true,
186
+ },
187
+ },
188
+ shippingInfo: {
189
+ preferredShipping: {
190
+ type: String,
191
+ },
192
+ dispatchTime: {
193
+ type: String,
194
+ },
195
+ returnPolicy: {
196
+ type: String,
197
+ },
198
+ courierPartner: {
199
+ type: String,
200
+ },
201
+ },
202
+ readiness: {
203
+ liveSellingFrequency: {
204
+ type: String,
205
+ },
206
+ cameraSetup: {
207
+ type: Boolean,
208
+ },
209
+ isWillingToGoLive: {
210
+ type: Boolean
211
+ }
212
+ },
213
+ promotions: {
214
+ promoteLiveSelling: {
215
+ type: Boolean,
216
+ default: false
217
+ },
218
+ brandPromotion: {
219
+ type: Boolean,
220
+ default: false
221
+ },
222
+ flykupCollab: {
223
+ type: Boolean,
224
+ default: false
225
+ }
226
+ },
227
+ address: {
228
+ addressLine1: {
229
+ type: String,
230
+ // required: true,
231
+ trim: true,
232
+ maxLength: 150,
233
+ },
234
+ addressLine2: {
235
+ type: String,
236
+ trim: true,
237
+ maxLength: 150,
238
+ },
239
+ city: {
240
+ type: String,
241
+ // required: true,
242
+ trim: true,
243
+ maxLength: 50,
244
+ },
245
+ state: {
246
+ type: String,
247
+ // required: true,
248
+ trim: true,
249
+ maxLength: 50,
250
+ },
251
+ pincode: {
252
+ type: String,
253
+ // required: true,
254
+ trim: true,
255
+ maxLength: 6,
256
+ },
257
+ },
258
+ // Terms Acceptance
259
+ generalAccepted: { type: Boolean, default: false },
260
+ sellerAccepted: { type: Boolean, default: false },
261
+ digitalAccepted: { type: Boolean, default: false },
262
+ approvalStatus: {
263
+ type: String,
264
+ enum: [
265
+ "pending",
266
+ "auto_approved",
267
+ "auto_rejected",
268
+ "manual_review",
269
+ "approved",
270
+ "rejected",
271
+ ],
272
+ default: "pending",
273
+ },
274
+ rejectedReason: {
275
+ type: String,
276
+ default: null,
277
+ },
278
+ rejectedTimes: { type: Number, default: 0 },
279
+ azureMigrationStatus: {
280
+ type: String,
281
+ enum: ['pending', 'completed', 'failed'],
282
+ default: 'pending',
283
+ },
284
+ scoring: { type: ScoringSchema, default: {} },
285
+ chatSupport: {
286
+ isAvailable: { type: Boolean, default: true },
287
+ responseTime: { type: String, default: 'within 24 hours' },
288
+ supportHours: {
289
+ start: { type: String, default: '09:00' },
290
+ end: { type: String, default: '18:00' }
291
+ }
292
+ }
293
+ },
294
+ { timestamps: true, strict: true }
295
+ );
296
+
297
+ const Seller = mongoose.model("sellers", SellerSchema);
298
+
299
+ export default Seller;
@@ -0,0 +1,18 @@
1
+ import mongoose from 'mongoose';
2
+
3
+ const SettingsSchema = new mongoose.Schema({
4
+ appSettings: {
5
+ sellerAppVersion: {
6
+ type: String,
7
+ default: '0.0.1'
8
+ },
9
+ userAppVersion: {
10
+ type: String,
11
+ default: '0.0.1'
12
+ }
13
+ }
14
+ });
15
+
16
+ const Settings = mongoose.model('Settings', SettingsSchema);
17
+
18
+ export default Settings;
@@ -0,0 +1,128 @@
1
+ import mongoose from "mongoose";
2
+ const { Schema } = mongoose;
3
+
4
+ const dropshipperConnectionSchema = new Schema({
5
+ _id: false,
6
+ sellerId: {
7
+ type: mongoose.Schema.Types.ObjectId,
8
+ ref: "sellers",
9
+ required: true,
10
+ },
11
+ status: {
12
+ type: String,
13
+ enum: [
14
+ "pending",
15
+ "approved",
16
+ "rejected",
17
+ "revoked_by_seller",
18
+ "revoked_by_dropshipper",
19
+ ],
20
+ required: true,
21
+ default: "pending",
22
+ },
23
+ commissionRate: {
24
+ type: Number, // Store as percentage, e.g., 15 for 15%
25
+ min: 0,
26
+ max: 100,
27
+ default: null, // Or a platform default? Needs discussion
28
+ },
29
+ agreementDetails: {
30
+ type: String,
31
+ maxLength: 500,
32
+ default: null,
33
+ },
34
+ requestedAt: {
35
+ type: Date,
36
+ default: Date.now,
37
+ },
38
+ respondedAt: {
39
+ type: Date,
40
+ default: null,
41
+ },
42
+ });
43
+
44
+ const DropshipperSchema = new Schema(
45
+ {
46
+ userInfo: {
47
+ type: mongoose.Schema.Types.ObjectId,
48
+ ref: "users",
49
+ required: true,
50
+ unique: true, // Ensure one user is only one dropshipper
51
+ index: true,
52
+ },
53
+ // Dropshipper specific info (can mirror Seller or be simpler)
54
+ businessName: {
55
+ // Optional: If they operate under a different name
56
+ type: String,
57
+ maxLength: 60,
58
+ trim: true,
59
+ },
60
+ mobileNumber: {
61
+ // May differ from user's primary mobile
62
+ type: String,
63
+ maxLength: 15,
64
+ trim: true,
65
+ },
66
+ email: {
67
+ // May differ from user's primary email
68
+ type: String,
69
+ trim: true,
70
+ maxLength: 60,
71
+ },
72
+ // Connections managed by the Dropshipper
73
+ connectedSellers: [dropshipperConnectionSchema],
74
+
75
+ // Address might be needed for correspondence or legal reasons
76
+ address: {
77
+ addressLine1: { type: String, trim: true, maxLength: 150 },
78
+ addressLine2: { type: String, trim: true, maxLength: 150 },
79
+ city: { type: String, trim: true, maxLength: 50 },
80
+ state: { type: String, trim: true, maxLength: 50 },
81
+ pincode: { type: String, trim: true, maxLength: 6 },
82
+ },
83
+
84
+ // Payout information (CRUCIAL for dropshippers)
85
+ bankDetails: {
86
+ accountHolderName: { type: String, trim: true },
87
+ accountNumber: { type: String, trim: true },
88
+ ifscCode: { type: String, trim: true },
89
+ bankName: { type: String, trim: true },
90
+ // Add UPI details if needed
91
+ },
92
+
93
+ // Admin approval status for the dropshipper account itself
94
+ approvalStatus: {
95
+ type: String,
96
+ enum: ["pending", "approved", "rejected", "suspended"],
97
+ default: "pending",
98
+ },
99
+ rejectedReason: {
100
+ type: String,
101
+ maxLength: 200,
102
+ default: null,
103
+ },
104
+ // Add other relevant fields like readiness for live selling etc.
105
+ // e.g., experience, social media links if relevant
106
+ },
107
+ { timestamps: true, strict: true } // Use strict: true to prevent undefined fields
108
+ );
109
+
110
+ // Pre-hook (Example): Ensure user role is updated when dropshipper is created/approved
111
+ // This logic might be better placed in the controller after successful creation/approval
112
+ // DropshipperSchema.pre('save', async function (next) {
113
+ // if (this.isNew || this.isModified('approvalStatus')) {
114
+ // try {
115
+ // const User = mongoose.model('users'); // Avoid circular dependency if possible
116
+ // await User.findByIdAndUpdate(this.userInfo, {
117
+ // $set: { role: this.approvalStatus === 'approved' ? 'dropshipper' : 'user' } // Adjust logic as needed
118
+ // });
119
+ // } catch (error) {
120
+ // return next(error);
121
+ // }
122
+ // }
123
+ // next();
124
+ // });
125
+
126
+ const Dropshipper = mongoose.model("dropshippers", DropshipperSchema);
127
+
128
+ export default Dropshipper;
@@ -0,0 +1,177 @@
1
+
2
+
3
+ import { Schema, model } from "mongoose";
4
+
5
+
6
+
7
+ // Define the Rendition sub-schema
8
+ const RenditionSchema = new Schema({
9
+ resolution: { type: String, required: false }, // e.g. "1080p"
10
+ bitrate: { type: Number, required: false }, // e.g. 3000000 (bps)
11
+ playlistKey: { type: String, required: false }, // e.g. "video123/1080p.m3u8"
12
+ hlsUrl: { type: String, required: false }, // Full HLS URL for this rendition
13
+ size: { type: Number, required: false }, // bytes of all .ts + playlist
14
+ ratio: { type: Number, required: false }, // size/originalSize
15
+ }, { _id: false }); // No separate _id for subdocuments unless needed
16
+
17
+ const ShoppableVideoSchema = new Schema(
18
+ {
19
+ host: {
20
+ type: Schema.Types.ObjectId,
21
+ required: true,
22
+ refPath: 'hostModel'
23
+ },
24
+ hostModel: {
25
+ type: String,
26
+ required: true,
27
+ enum: ['sellers', 'dropshippers'],
28
+ index: true
29
+ },
30
+ title: {
31
+ type: String,
32
+ trim: true,
33
+ required: true,
34
+ },
35
+ description: {
36
+ type: String,
37
+ required: true,
38
+ trim: true,
39
+ },
40
+ category: { type: String, required: true, trim: true },
41
+ subcategory: { type: String, required: true, trim: true },
42
+ // thumbnailURL might be set initially or updated by the processing service
43
+ thumbnailURL: {
44
+ type: String,
45
+ },
46
+ isProductsAvailable : { type : Boolean, required : true, default : true },
47
+ productsListed: {
48
+ type: [
49
+ {
50
+ type: Schema.Types.ObjectId,
51
+ ref: "productlistings",
52
+ },
53
+ ],
54
+ default: [],
55
+ },
56
+ hashTags: {
57
+ type: [
58
+ {
59
+ type: String,
60
+ trim: true
61
+ }
62
+ ]
63
+ },
64
+ processingStatus: {
65
+ type: String,
66
+ enum: ["queued", "processing", "published", "failed", "transcoding_complete","uploaded"], // Added new status
67
+ default: "uploaded",
68
+ index: true,
69
+ },
70
+ visibility: {
71
+ type: String,
72
+ enum: ["public", "private", "deleted"],
73
+ default: "public",
74
+ index: true,
75
+ },
76
+ thumbnailBlobName: {
77
+ type: String,
78
+ default: null,
79
+ },
80
+ originalVideoBlobName: {
81
+ type: String,
82
+ default: null,
83
+ },
84
+ originalFileSize: {
85
+ type: Number,
86
+ default: null,
87
+ },
88
+ optimizedKey: {
89
+ type: String,
90
+ default: null,
91
+ },
92
+ processingError: {
93
+ type: String,
94
+ default: null,
95
+ },
96
+ optimizedSize: {
97
+ type: Number,
98
+ default: null,
99
+ },
100
+ durationSeconds: {
101
+ type: Number,
102
+ default: null,
103
+ },
104
+
105
+ // === NEW FIELDS FOR VIDEO PROCESSING CALLBACK ===
106
+ renditions: {
107
+ type: [RenditionSchema], // Array of rendition objects
108
+ default: [],
109
+ },
110
+ videoId: { // Optimized video URL for playback from other db
111
+ type: String,
112
+ default: null,
113
+ trim: true,
114
+ },
115
+ optimizationStatus: { // Status of optimization process
116
+ type: String,
117
+ enum: ["success", "failed","progress"],
118
+ default: "progress",
119
+
120
+ },
121
+ reductionPercentage:{
122
+ type:String,
123
+ default: null,
124
+ trim: true,
125
+ },
126
+ masterPlaylistKey: { // Key for the master playlist in the public container
127
+ type: String,
128
+ default: null,
129
+ trim: true,
130
+ },
131
+ durationTook: {
132
+ type: String, // Duration took for the optimization process
133
+ trim: true,
134
+ default: null, // Duration in seconds for the optimization process
135
+ },
136
+ commentsCount: {
137
+ type: Number,
138
+ default: 0
139
+ },
140
+ shares: {
141
+ type: Number,
142
+ default: 0
143
+ },
144
+ // Analytics new fields
145
+ viewCount: {
146
+ type: Number,
147
+ default: 0
148
+ },
149
+ uniqueViewCount: {
150
+ type: Number,
151
+ default: 0
152
+ },
153
+ totalWatchDuration: {
154
+ type: Number,
155
+ default: 0
156
+ },
157
+ totalCompletionPercentageSum: {
158
+ type: Number,
159
+ default: 0
160
+ },
161
+ isEligibleToPlay : {
162
+ type: Boolean,
163
+ default: false, // Default to true, can be set to false if video is not eligible for playback
164
+ index: true // Index for quick lookups
165
+ }
166
+ },
167
+ { timestamps: true }
168
+ );
169
+
170
+ // Index for querying videos that need processing status updates
171
+ ShoppableVideoSchema.index({ processingStatus: 1, updatedAt: 1 });
172
+ // Index for host and their videos
173
+ ShoppableVideoSchema.index({ host: 1, hostModel: 1 });
174
+
175
+ const ShoppableVideo = model("shoppablevideos", ShoppableVideoSchema);
176
+
177
+ export default ShoppableVideo;
@@ -0,0 +1,58 @@
1
+ import mongoose from "mongoose";
2
+
3
+
4
+ const ShoppableVideoCommentSchema = new mongoose.Schema({
5
+ videoId: {
6
+ type: mongoose.Schema.Types.ObjectId,
7
+ ref: "ShoppableVideo",
8
+ required: true
9
+ },
10
+ userId: {
11
+ type: mongoose.Schema.Types.ObjectId,
12
+ ref: "users", // Must match exactly with your model name
13
+ required: true
14
+ },
15
+ text: {
16
+ type: String,
17
+ required: true,
18
+ trim: true
19
+ },
20
+ likes: {
21
+ type: Number,
22
+ default: 0
23
+ },
24
+ likedBy: [{
25
+ type: mongoose.Schema.Types.ObjectId,
26
+ ref: "users"
27
+ }],
28
+ isReply: {
29
+ type: Boolean,
30
+ default: false
31
+ },
32
+ parentCommentId: {
33
+ type: mongoose.Schema.Types.ObjectId,
34
+ ref: "ShoppableVideoComment"
35
+ },
36
+ repliesCount: {
37
+ type: Number,
38
+ default: 0
39
+ }
40
+ }, {
41
+ timestamps: true,
42
+ toJSON: { virtuals: true },
43
+ toObject: { virtuals: true }
44
+ });
45
+
46
+ // Corrected virtual field
47
+ ShoppableVideoCommentSchema.virtual('isLiked').get(function() {
48
+ return this.likedBy ? this.likedBy.includes(this.userId) : false;
49
+ });
50
+
51
+ // Indexes
52
+ ShoppableVideoCommentSchema.index({ videoId: 1, createdAt: -1 });
53
+ ShoppableVideoCommentSchema.index({ parentCommentId: 1, createdAt: -1 });
54
+ ShoppableVideoCommentSchema.index({ userId: 1 });
55
+ ShoppableVideoCommentSchema.index({ videoId: 1, isReply: 1 });
56
+
57
+ const ShoppableVideoComment = mongoose.model("ShoppableVideoComment", ShoppableVideoCommentSchema);
58
+ export default ShoppableVideoComment;
@@ -0,0 +1,30 @@
1
+ import mongoose from "mongoose";
2
+
3
+ const shoppableVideoLikeSchema = new mongoose.Schema(
4
+ {
5
+ videoId: {
6
+ type: mongoose.Schema.Types.ObjectId,
7
+ ref: "ShoppableVideo",
8
+ required: true,
9
+ },
10
+ userId: {
11
+ type: mongoose.Schema.Types.ObjectId,
12
+ ref: "User", // Adjust to your User model name
13
+ required: true,
14
+ }
15
+ },
16
+ {
17
+ timestamps: true,
18
+ }
19
+ );
20
+
21
+ // Create compound index to ensure one like per user per video
22
+ shoppableVideoLikeSchema.index({ videoId: 1, userId: 1 }, { unique: true });
23
+
24
+ // Index for efficient queries
25
+ shoppableVideoLikeSchema.index({ videoId: 1, createdAt: -1 });
26
+ shoppableVideoLikeSchema.index({ userId: 1, createdAt: -1 });
27
+
28
+ const ShoppableVideoLike = mongoose.model("ShoppableVideoLike", shoppableVideoLikeSchema);
29
+
30
+ export default ShoppableVideoLike;