@timardex/cluemart-server-shared 1.0.284 → 1.0.289
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/{chunk-4FWW5CDC.mjs → chunk-KRG2CATM.mjs} +64 -32
- package/dist/chunk-KRG2CATM.mjs.map +1 -0
- package/dist/index.cjs +360 -122
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +39 -1
- package/dist/index.d.ts +39 -1
- package/dist/index.mjs +351 -116
- package/dist/index.mjs.map +1 -1
- package/dist/mongoose/index.cjs +61 -31
- package/dist/mongoose/index.cjs.map +1 -1
- package/dist/mongoose/index.mjs +1 -1
- package/dist/service/index.cjs +358 -120
- package/dist/service/index.cjs.map +1 -1
- package/dist/service/index.d.mts +40 -2
- package/dist/service/index.d.ts +40 -2
- package/dist/service/index.mjs +285 -78
- package/dist/service/index.mjs.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-4FWW5CDC.mjs.map +0 -1
package/dist/mongoose/index.mjs
CHANGED
package/dist/service/index.cjs
CHANGED
|
@@ -33,12 +33,15 @@ __export(service_exports, {
|
|
|
33
33
|
ACTIVE_NOT_DELETED_FILTER: () => ACTIVE_NOT_DELETED_FILTER,
|
|
34
34
|
AFFILIATE_REWARDS: () => AFFILIATE_REWARDS,
|
|
35
35
|
activeAffiliateCodeExists: () => activeAffiliateCodeExists,
|
|
36
|
+
awardAffiliateVendorSubscriptionRewards: () => awardAffiliateVendorSubscriptionRewards,
|
|
36
37
|
connectToDatabase: () => connectToDatabase,
|
|
37
38
|
convertObjectIdsToStrings: () => convertObjectIdsToStrings,
|
|
38
39
|
createAffiliateReward: () => createAffiliateReward,
|
|
39
40
|
didRemoveAnyEventDates: () => didRemoveAnyEventDates,
|
|
40
41
|
findAffiliateByPromoCode: () => findAffiliateByPromoCode,
|
|
41
42
|
findEventOrImportedMarketById: () => findEventOrImportedMarketById,
|
|
43
|
+
getSubscriptionRewardPeriodBounds: () => getSubscriptionRewardPeriodBounds,
|
|
44
|
+
mapVendorLicenceToSubscriptionRewardType: () => mapVendorLicenceToSubscriptionRewardType,
|
|
42
45
|
normalizeAffiliatePromoCodes: () => normalizeAffiliatePromoCodes,
|
|
43
46
|
normalizePromoCode: () => normalizePromoCode,
|
|
44
47
|
saveNotificationsInDb: () => saveNotificationsInDb,
|
|
@@ -3661,14 +3664,14 @@ var EnumGameType = /* @__PURE__ */ ((EnumGameType2) => {
|
|
|
3661
3664
|
EnumGameType2["ODD_ONE_OUT"] = "oddOneOut";
|
|
3662
3665
|
return EnumGameType2;
|
|
3663
3666
|
})(EnumGameType || {});
|
|
3664
|
-
var EnumAffiliateRewardType = /* @__PURE__ */ ((
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
return
|
|
3667
|
+
var EnumAffiliateRewardType = /* @__PURE__ */ ((EnumAffiliateRewardType22) => {
|
|
3668
|
+
EnumAffiliateRewardType22["ACTIVE_EVENT_WITH_VENDOR_REGISTRATIONS"] = "ACTIVE_EVENT_WITH_VENDOR_REGISTRATIONS";
|
|
3669
|
+
EnumAffiliateRewardType22["ACTIVE_VENDOR_BONUS_REWARD"] = "ACTIVE_VENDOR_BONUS_REWARD";
|
|
3670
|
+
EnumAffiliateRewardType22["ACTIVE_VENDOR_PRO_SUBSCRIPTION"] = "ACTIVE_VENDOR_PRO_SUBSCRIPTION";
|
|
3671
|
+
EnumAffiliateRewardType22["ACTIVE_VENDOR_STANDARD_SUBSCRIPTION"] = "ACTIVE_VENDOR_STANDARD_SUBSCRIPTION";
|
|
3672
|
+
EnumAffiliateRewardType22["NEW_EVENT_REGISTRATION"] = "NEW_EVENT_REGISTRATION";
|
|
3673
|
+
EnumAffiliateRewardType22["NEW_VENDOR_REGISTRATION"] = "NEW_VENDOR_REGISTRATION";
|
|
3674
|
+
return EnumAffiliateRewardType22;
|
|
3672
3675
|
})(EnumAffiliateRewardType || {});
|
|
3673
3676
|
var statusOptions = [
|
|
3674
3677
|
...Object.values(EnumInviteStatus).map((status) => ({
|
|
@@ -4707,29 +4710,6 @@ var tagOptions = availableTagTypes.map((tag) => ({
|
|
|
4707
4710
|
label: tag.label,
|
|
4708
4711
|
value: tag.label
|
|
4709
4712
|
}));
|
|
4710
|
-
var stallTypes = [
|
|
4711
|
-
"1.8m table only",
|
|
4712
|
-
"2x2m mini stall",
|
|
4713
|
-
"3x3m tent site",
|
|
4714
|
-
"Corner stall",
|
|
4715
|
-
"Craft stall with power",
|
|
4716
|
-
"Craft stall without power",
|
|
4717
|
-
"Double stall (6x3m)",
|
|
4718
|
-
"Food truck site",
|
|
4719
|
-
"Food vendor with power",
|
|
4720
|
-
"Food vendor without power",
|
|
4721
|
-
"Inside hall stall",
|
|
4722
|
-
"Non-profit/community stall",
|
|
4723
|
-
"Outdoor open area",
|
|
4724
|
-
"Shared table space",
|
|
4725
|
-
"Wall-based vendor",
|
|
4726
|
-
"Workshop/seating area"
|
|
4727
|
-
];
|
|
4728
|
-
var stallTypeOptions = stallTypes.map((type) => ({
|
|
4729
|
-
label: type,
|
|
4730
|
-
price: 0,
|
|
4731
|
-
stallCapacity: 0
|
|
4732
|
-
}));
|
|
4733
4713
|
var emailField = {
|
|
4734
4714
|
helperText: "Enter email address",
|
|
4735
4715
|
keyboardType: "email-address",
|
|
@@ -4754,6 +4734,51 @@ var companyContactFields = [
|
|
|
4754
4734
|
placeholder: "Landline Phone Number"
|
|
4755
4735
|
}
|
|
4756
4736
|
];
|
|
4737
|
+
var bankAccountDetailsFields = [
|
|
4738
|
+
{
|
|
4739
|
+
helperText: "Account holder name *",
|
|
4740
|
+
name: "accountHolderName",
|
|
4741
|
+
placeholder: "Account holder name"
|
|
4742
|
+
},
|
|
4743
|
+
{
|
|
4744
|
+
helperText: "Account number *",
|
|
4745
|
+
keyboardType: "number-pad",
|
|
4746
|
+
name: "accountNumber",
|
|
4747
|
+
placeholder: "Account number"
|
|
4748
|
+
}
|
|
4749
|
+
];
|
|
4750
|
+
var eventInfoPaymentInfo = [
|
|
4751
|
+
...bankAccountDetailsFields,
|
|
4752
|
+
{
|
|
4753
|
+
helperText: "Payment link, where applicants can pay *",
|
|
4754
|
+
keyboardType: "url",
|
|
4755
|
+
name: "link",
|
|
4756
|
+
placeholder: "Payment link"
|
|
4757
|
+
}
|
|
4758
|
+
];
|
|
4759
|
+
var stallTypes = [
|
|
4760
|
+
"1.8m table only",
|
|
4761
|
+
"2x2m mini stall",
|
|
4762
|
+
"3x3m tent site",
|
|
4763
|
+
"Corner stall",
|
|
4764
|
+
"Craft stall with power",
|
|
4765
|
+
"Craft stall without power",
|
|
4766
|
+
"Double stall (6x3m)",
|
|
4767
|
+
"Food truck site",
|
|
4768
|
+
"Food vendor with power",
|
|
4769
|
+
"Food vendor without power",
|
|
4770
|
+
"Inside hall stall",
|
|
4771
|
+
"Non-profit/community stall",
|
|
4772
|
+
"Outdoor open area",
|
|
4773
|
+
"Shared table space",
|
|
4774
|
+
"Wall-based vendor",
|
|
4775
|
+
"Workshop/seating area"
|
|
4776
|
+
];
|
|
4777
|
+
var stallTypeOptions = stallTypes.map((type) => ({
|
|
4778
|
+
label: type,
|
|
4779
|
+
price: 0,
|
|
4780
|
+
stallCapacity: 0
|
|
4781
|
+
}));
|
|
4757
4782
|
var loginFields = [
|
|
4758
4783
|
{
|
|
4759
4784
|
...emailField,
|
|
@@ -7525,8 +7550,10 @@ var AFFILIATE_FIELDS_FRAGMENT = gql`
|
|
|
7525
7550
|
}
|
|
7526
7551
|
createdAt
|
|
7527
7552
|
deletedAt
|
|
7528
|
-
|
|
7529
|
-
|
|
7553
|
+
redeemHistory {
|
|
7554
|
+
redeemedAt
|
|
7555
|
+
rewardValue
|
|
7556
|
+
}
|
|
7530
7557
|
overallPoints
|
|
7531
7558
|
owner {
|
|
7532
7559
|
...OwnerFields
|
|
@@ -9312,6 +9339,13 @@ var affiliateDetailsSchema = new MongooseSchema25(
|
|
|
9312
9339
|
},
|
|
9313
9340
|
{ _id: false }
|
|
9314
9341
|
);
|
|
9342
|
+
var redeemHistorySchema = new MongooseSchema25(
|
|
9343
|
+
{
|
|
9344
|
+
redeemedAt: { required: true, type: Date },
|
|
9345
|
+
rewardValue: { required: true, type: Number }
|
|
9346
|
+
},
|
|
9347
|
+
{ _id: false }
|
|
9348
|
+
);
|
|
9315
9349
|
var schema17 = new MongooseSchema25(
|
|
9316
9350
|
{
|
|
9317
9351
|
active: { default: false, required: true, type: Boolean },
|
|
@@ -9328,16 +9362,15 @@ var schema17 = new MongooseSchema25(
|
|
|
9328
9362
|
type: [affiliateResourceSchema]
|
|
9329
9363
|
},
|
|
9330
9364
|
deletedAt: { default: null, required: false, type: Date },
|
|
9331
|
-
lastRewardRedemptionAt: { default: null, required: false, type: Date },
|
|
9332
|
-
lastRewardRedemptionPoints: {
|
|
9333
|
-
default: null,
|
|
9334
|
-
required: false,
|
|
9335
|
-
type: Number
|
|
9336
|
-
},
|
|
9337
9365
|
overallPoints: { default: 0, required: true, type: Number },
|
|
9338
9366
|
owner: {
|
|
9339
9367
|
required: true,
|
|
9340
9368
|
type: OwnerTypeSchema
|
|
9369
|
+
},
|
|
9370
|
+
redeemHistory: {
|
|
9371
|
+
default: [],
|
|
9372
|
+
required: false,
|
|
9373
|
+
type: [redeemHistorySchema]
|
|
9341
9374
|
}
|
|
9342
9375
|
},
|
|
9343
9376
|
{ timestamps: true }
|
|
@@ -9366,89 +9399,12 @@ async function activeAffiliateCodeExists(affiliateCode) {
|
|
|
9366
9399
|
return existing !== null;
|
|
9367
9400
|
}
|
|
9368
9401
|
|
|
9369
|
-
// src/service/affiliate/createAffiliateReward.ts
|
|
9370
|
-
var AFFILIATE_REWARDS = {
|
|
9371
|
-
[EnumAffiliateRewardType.NEW_EVENT_REGISTRATION]: {
|
|
9372
|
-
description: "10 points for new event registration (one-time reward)",
|
|
9373
|
-
value: 10
|
|
9374
|
-
},
|
|
9375
|
-
[EnumAffiliateRewardType.NEW_VENDOR_REGISTRATION]: {
|
|
9376
|
-
description: "5 points for new vendor registration (one-time reward)",
|
|
9377
|
-
value: 5
|
|
9378
|
-
},
|
|
9379
|
-
[EnumAffiliateRewardType.ACTIVE_VENDOR_PRO_SUBSCRIPTION]: {
|
|
9380
|
-
description: "3 points for active vendor pro subscription (monthly reward)",
|
|
9381
|
-
value: 3
|
|
9382
|
-
},
|
|
9383
|
-
[EnumAffiliateRewardType.ACTIVE_VENDOR_STANDARD_SUBSCRIPTION]: {
|
|
9384
|
-
description: "1 point for active vendor standard subscription (monthly reward)",
|
|
9385
|
-
value: 1
|
|
9386
|
-
},
|
|
9387
|
-
[EnumAffiliateRewardType.ACTIVE_VENDOR_BONUS_REWARD]: {
|
|
9388
|
-
description: "5 bonus points for every 10th active vendor (one-time reward)",
|
|
9389
|
-
value: 5
|
|
9390
|
-
},
|
|
9391
|
-
[EnumAffiliateRewardType.ACTIVE_EVENT_WITH_VENDOR_REGISTRATIONS]: {
|
|
9392
|
-
description: "50 points for active event with vendor registrations (one-time reward)",
|
|
9393
|
-
value: 50
|
|
9394
|
-
}
|
|
9395
|
-
};
|
|
9396
|
-
function createAffiliateReward(rewardType, createdAt) {
|
|
9397
|
-
const reward = AFFILIATE_REWARDS[rewardType];
|
|
9398
|
-
return {
|
|
9399
|
-
createdAt,
|
|
9400
|
-
redeemedAt: null,
|
|
9401
|
-
rewardDescription: reward.description,
|
|
9402
|
-
rewardType,
|
|
9403
|
-
rewardValue: reward.value
|
|
9404
|
-
};
|
|
9405
|
-
}
|
|
9406
|
-
|
|
9407
|
-
// src/service/affiliate/findAffiliateByPromoCode.ts
|
|
9408
|
-
async function findAffiliateByPromoCode(promoCode) {
|
|
9409
|
-
return AffiliateModel.findOne({
|
|
9410
|
-
affiliateCode: promoCode,
|
|
9411
|
-
deletedAt: null
|
|
9412
|
-
}).exec();
|
|
9413
|
-
}
|
|
9414
|
-
|
|
9415
9402
|
// src/service/promoCode/normalizePromoCode.ts
|
|
9416
9403
|
function normalizePromoCode(decoratedPromoCode) {
|
|
9417
9404
|
const normalized = decoratedPromoCode?.trim().toUpperCase();
|
|
9418
9405
|
return normalized || null;
|
|
9419
9406
|
}
|
|
9420
9407
|
|
|
9421
|
-
// src/service/affiliate/normalizeAffiliatePromoCodes.ts
|
|
9422
|
-
function normalizeAffiliatePromoCodes(promoCodes) {
|
|
9423
|
-
const normalized = (promoCodes ?? []).map((code) => normalizePromoCode(code)).filter((code) => code !== null);
|
|
9424
|
-
return [...new Set(normalized)];
|
|
9425
|
-
}
|
|
9426
|
-
|
|
9427
|
-
// src/service/database.ts
|
|
9428
|
-
var import_mongoose28 = __toESM(require("mongoose"));
|
|
9429
|
-
var connectToDatabase = async ({
|
|
9430
|
-
appName,
|
|
9431
|
-
dbName,
|
|
9432
|
-
dbPassword,
|
|
9433
|
-
dbUser,
|
|
9434
|
-
mongodbUri
|
|
9435
|
-
}) => {
|
|
9436
|
-
try {
|
|
9437
|
-
const mongoUri = mongodbUri ? mongodbUri : (
|
|
9438
|
-
// Fallback to MongoDB Atlas connection string
|
|
9439
|
-
`mongodb+srv://${dbUser}:${dbPassword}@${dbName}.mongodb.net/?retryWrites=true&w=majority&appName=${appName}`
|
|
9440
|
-
);
|
|
9441
|
-
await import_mongoose28.default.connect(mongoUri);
|
|
9442
|
-
const connectionType = mongodbUri ? "Local MongoDB" : "MongoDB Atlas";
|
|
9443
|
-
console.log(
|
|
9444
|
-
`${connectionType} connected from server/src/service/database.ts`
|
|
9445
|
-
);
|
|
9446
|
-
} catch (err) {
|
|
9447
|
-
console.error("Error connecting to MongoDB:", err);
|
|
9448
|
-
throw err;
|
|
9449
|
-
}
|
|
9450
|
-
};
|
|
9451
|
-
|
|
9452
9408
|
// src/service/saveNotificationsInDb.ts
|
|
9453
9409
|
async function saveNotificationsInDb(payload) {
|
|
9454
9410
|
const { data, message, title, type, userIds } = payload;
|
|
@@ -9582,6 +9538,285 @@ async function sendPushNotifications({
|
|
|
9582
9538
|
}
|
|
9583
9539
|
}
|
|
9584
9540
|
|
|
9541
|
+
// src/service/affiliate/createAffiliateReward.ts
|
|
9542
|
+
var AFFILIATE_REWARDS = {
|
|
9543
|
+
[EnumAffiliateRewardType.NEW_EVENT_REGISTRATION]: {
|
|
9544
|
+
description: "10 points for new event registration (one-time reward)",
|
|
9545
|
+
value: 10
|
|
9546
|
+
},
|
|
9547
|
+
[EnumAffiliateRewardType.NEW_VENDOR_REGISTRATION]: {
|
|
9548
|
+
description: "5 points for new vendor registration (one-time reward)",
|
|
9549
|
+
value: 5
|
|
9550
|
+
},
|
|
9551
|
+
[EnumAffiliateRewardType.ACTIVE_VENDOR_PRO_SUBSCRIPTION]: {
|
|
9552
|
+
description: "3 points for active vendor pro subscription (monthly reward)",
|
|
9553
|
+
value: 3
|
|
9554
|
+
},
|
|
9555
|
+
[EnumAffiliateRewardType.ACTIVE_VENDOR_STANDARD_SUBSCRIPTION]: {
|
|
9556
|
+
description: "1 point for active vendor standard subscription (monthly reward)",
|
|
9557
|
+
value: 1
|
|
9558
|
+
},
|
|
9559
|
+
[EnumAffiliateRewardType.ACTIVE_VENDOR_BONUS_REWARD]: {
|
|
9560
|
+
description: "5 bonus points for every 10th active vendor (one-time reward)",
|
|
9561
|
+
value: 5
|
|
9562
|
+
},
|
|
9563
|
+
[EnumAffiliateRewardType.ACTIVE_EVENT_WITH_VENDOR_REGISTRATIONS]: {
|
|
9564
|
+
description: "50 points for active event with vendor registrations (one-time reward)",
|
|
9565
|
+
value: 50
|
|
9566
|
+
}
|
|
9567
|
+
};
|
|
9568
|
+
function createAffiliateReward(rewardType, createdAt) {
|
|
9569
|
+
const reward = AFFILIATE_REWARDS[rewardType];
|
|
9570
|
+
return {
|
|
9571
|
+
createdAt,
|
|
9572
|
+
redeemedAt: null,
|
|
9573
|
+
rewardDescription: reward.description,
|
|
9574
|
+
rewardType,
|
|
9575
|
+
rewardValue: reward.value
|
|
9576
|
+
};
|
|
9577
|
+
}
|
|
9578
|
+
|
|
9579
|
+
// src/service/affiliate/vendorSubscriptionRewards.ts
|
|
9580
|
+
function mapVendorLicenceToSubscriptionRewardType(licences, now = /* @__PURE__ */ new Date()) {
|
|
9581
|
+
const validTypes = new Set(
|
|
9582
|
+
(licences ?? []).filter(
|
|
9583
|
+
(licence) => new Date(licence.expiryDate).getTime() > now.getTime()
|
|
9584
|
+
).map((licence) => licence.licenceType)
|
|
9585
|
+
);
|
|
9586
|
+
if (validTypes.has(EnumUserLicence.PRO_VENDOR) || validTypes.has(EnumUserLicence.PRO_PLUS_VENDOR)) {
|
|
9587
|
+
return EnumAffiliateRewardType.ACTIVE_VENDOR_PRO_SUBSCRIPTION;
|
|
9588
|
+
}
|
|
9589
|
+
if (validTypes.has(EnumUserLicence.STANDARD_VENDOR)) {
|
|
9590
|
+
return EnumAffiliateRewardType.ACTIVE_VENDOR_STANDARD_SUBSCRIPTION;
|
|
9591
|
+
}
|
|
9592
|
+
return null;
|
|
9593
|
+
}
|
|
9594
|
+
function getSubscriptionRewardPeriodBounds(now = /* @__PURE__ */ new Date()) {
|
|
9595
|
+
const periodStart = new Date(
|
|
9596
|
+
Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1)
|
|
9597
|
+
);
|
|
9598
|
+
const periodEnd = new Date(
|
|
9599
|
+
Date.UTC(now.getUTCFullYear(), now.getUTCMonth() + 1, 1)
|
|
9600
|
+
);
|
|
9601
|
+
return { periodEnd, periodStart };
|
|
9602
|
+
}
|
|
9603
|
+
|
|
9604
|
+
// src/service/affiliate/awardAffiliateVendorSubscriptionRewards.ts
|
|
9605
|
+
function isEligibleVendorResource(resource) {
|
|
9606
|
+
return resource.resourceType === EnumResourceType.VENDOR && resource.resourceActive === true && resource.resourceDeletedAt == null;
|
|
9607
|
+
}
|
|
9608
|
+
async function findAffiliatesWithActiveVendorReferrals() {
|
|
9609
|
+
return await AffiliateModel.find({
|
|
9610
|
+
affiliateResources: {
|
|
9611
|
+
$elemMatch: {
|
|
9612
|
+
resourceActive: true,
|
|
9613
|
+
resourceDeletedAt: null,
|
|
9614
|
+
resourceType: EnumResourceType.VENDOR
|
|
9615
|
+
}
|
|
9616
|
+
},
|
|
9617
|
+
deletedAt: null
|
|
9618
|
+
}).select("_id affiliateCode affiliateResources owner").lean().exec();
|
|
9619
|
+
}
|
|
9620
|
+
async function findEligibleReferredVendor(resourceId, affiliateCode) {
|
|
9621
|
+
return await VendorModel.findOne({
|
|
9622
|
+
_id: resourceId,
|
|
9623
|
+
active: true,
|
|
9624
|
+
deletedAt: null,
|
|
9625
|
+
promoCodes: affiliateCode
|
|
9626
|
+
}).select("_id name owner.userId").lean().exec();
|
|
9627
|
+
}
|
|
9628
|
+
async function resolveSubscriptionRewardTypeForVendorOwner(vendorOwnerUserId, now) {
|
|
9629
|
+
const vendorOwner = await UserModel.findById(vendorOwnerUserId).select("licences").lean().exec();
|
|
9630
|
+
return mapVendorLicenceToSubscriptionRewardType(vendorOwner?.licences, now);
|
|
9631
|
+
}
|
|
9632
|
+
async function notifyAffiliateOwnerOfSubscriptionReward({
|
|
9633
|
+
affiliateId,
|
|
9634
|
+
affiliateOwnerUserId,
|
|
9635
|
+
resourceName,
|
|
9636
|
+
rewardValue
|
|
9637
|
+
}) {
|
|
9638
|
+
const payload = {
|
|
9639
|
+
data: {
|
|
9640
|
+
resourceId: String(affiliateId),
|
|
9641
|
+
resourceName,
|
|
9642
|
+
resourceType: EnumNotificationResourceType.AFFILIATE_REWARD_RECEIVED
|
|
9643
|
+
},
|
|
9644
|
+
message: `You earned ${rewardValue} points! Your referred vendor "${resourceName}" has an active subscription.`,
|
|
9645
|
+
title: "Affiliate points earned",
|
|
9646
|
+
type: EnumNotificationType.SYSTEM,
|
|
9647
|
+
userIds: [affiliateOwnerUserId]
|
|
9648
|
+
};
|
|
9649
|
+
try {
|
|
9650
|
+
await saveNotificationsInDb(payload);
|
|
9651
|
+
await sendPushNotifications(payload);
|
|
9652
|
+
} catch (error) {
|
|
9653
|
+
console.error(
|
|
9654
|
+
`[affiliate] subscription reward notification failed for affiliate ${String(affiliateId)}:`,
|
|
9655
|
+
error instanceof Error ? error.message : error
|
|
9656
|
+
);
|
|
9657
|
+
}
|
|
9658
|
+
}
|
|
9659
|
+
async function tryAwardSubscriptionReward({
|
|
9660
|
+
affiliate,
|
|
9661
|
+
createdAt,
|
|
9662
|
+
period,
|
|
9663
|
+
resource,
|
|
9664
|
+
rewardType,
|
|
9665
|
+
vendor
|
|
9666
|
+
}) {
|
|
9667
|
+
const reward = createAffiliateReward(rewardType, createdAt);
|
|
9668
|
+
const updateResult = await AffiliateModel.updateOne(
|
|
9669
|
+
{
|
|
9670
|
+
_id: affiliate._id,
|
|
9671
|
+
affiliateResources: {
|
|
9672
|
+
$elemMatch: {
|
|
9673
|
+
resourceActive: true,
|
|
9674
|
+
resourceDeletedAt: null,
|
|
9675
|
+
resourceId: vendor._id,
|
|
9676
|
+
resourceType: EnumResourceType.VENDOR,
|
|
9677
|
+
rewards: {
|
|
9678
|
+
$not: {
|
|
9679
|
+
$elemMatch: {
|
|
9680
|
+
createdAt: {
|
|
9681
|
+
$gte: period.periodStart,
|
|
9682
|
+
$lt: period.periodEnd
|
|
9683
|
+
},
|
|
9684
|
+
rewardType
|
|
9685
|
+
}
|
|
9686
|
+
}
|
|
9687
|
+
}
|
|
9688
|
+
}
|
|
9689
|
+
},
|
|
9690
|
+
deletedAt: null
|
|
9691
|
+
},
|
|
9692
|
+
{
|
|
9693
|
+
$inc: { overallPoints: reward.rewardValue },
|
|
9694
|
+
$push: { "affiliateResources.$.rewards": reward }
|
|
9695
|
+
}
|
|
9696
|
+
).exec();
|
|
9697
|
+
if (updateResult.modifiedCount === 0) {
|
|
9698
|
+
return "skipped";
|
|
9699
|
+
}
|
|
9700
|
+
const affiliateOwnerUserId = affiliate.owner?.userId;
|
|
9701
|
+
if (affiliateOwnerUserId) {
|
|
9702
|
+
await notifyAffiliateOwnerOfSubscriptionReward({
|
|
9703
|
+
affiliateId: affiliate._id,
|
|
9704
|
+
affiliateOwnerUserId,
|
|
9705
|
+
resourceName: resource.resourceName || vendor.name || "vendor",
|
|
9706
|
+
rewardValue: reward.rewardValue
|
|
9707
|
+
});
|
|
9708
|
+
}
|
|
9709
|
+
return "awarded";
|
|
9710
|
+
}
|
|
9711
|
+
async function processAffiliateVendorReferral({
|
|
9712
|
+
affiliate,
|
|
9713
|
+
affiliateCode,
|
|
9714
|
+
createdAt,
|
|
9715
|
+
now,
|
|
9716
|
+
period,
|
|
9717
|
+
resource
|
|
9718
|
+
}) {
|
|
9719
|
+
const vendor = await findEligibleReferredVendor(
|
|
9720
|
+
resource.resourceId,
|
|
9721
|
+
affiliateCode
|
|
9722
|
+
);
|
|
9723
|
+
if (!vendor?.owner?.userId) {
|
|
9724
|
+
return "skipped";
|
|
9725
|
+
}
|
|
9726
|
+
const rewardType = await resolveSubscriptionRewardTypeForVendorOwner(
|
|
9727
|
+
vendor.owner.userId,
|
|
9728
|
+
now
|
|
9729
|
+
);
|
|
9730
|
+
if (!rewardType) {
|
|
9731
|
+
return "skipped";
|
|
9732
|
+
}
|
|
9733
|
+
return tryAwardSubscriptionReward({
|
|
9734
|
+
affiliate,
|
|
9735
|
+
createdAt,
|
|
9736
|
+
period,
|
|
9737
|
+
resource,
|
|
9738
|
+
rewardType,
|
|
9739
|
+
vendor
|
|
9740
|
+
});
|
|
9741
|
+
}
|
|
9742
|
+
async function awardAffiliateVendorSubscriptionRewards(now = /* @__PURE__ */ new Date()) {
|
|
9743
|
+
const period = getSubscriptionRewardPeriodBounds(now);
|
|
9744
|
+
const createdAt = now;
|
|
9745
|
+
const affiliates = await findAffiliatesWithActiveVendorReferrals();
|
|
9746
|
+
let awarded = 0;
|
|
9747
|
+
let skipped = 0;
|
|
9748
|
+
const seenPairs = /* @__PURE__ */ new Set();
|
|
9749
|
+
for (const affiliate of affiliates) {
|
|
9750
|
+
const affiliateCode = normalizePromoCode(affiliate.affiliateCode);
|
|
9751
|
+
if (!affiliateCode) {
|
|
9752
|
+
continue;
|
|
9753
|
+
}
|
|
9754
|
+
for (const resource of affiliate.affiliateResources) {
|
|
9755
|
+
if (!isEligibleVendorResource(resource)) {
|
|
9756
|
+
continue;
|
|
9757
|
+
}
|
|
9758
|
+
const pairKey = `${String(affiliate._id)}:${String(resource.resourceId)}`;
|
|
9759
|
+
if (seenPairs.has(pairKey)) {
|
|
9760
|
+
continue;
|
|
9761
|
+
}
|
|
9762
|
+
seenPairs.add(pairKey);
|
|
9763
|
+
const outcome = await processAffiliateVendorReferral({
|
|
9764
|
+
affiliate,
|
|
9765
|
+
affiliateCode,
|
|
9766
|
+
createdAt,
|
|
9767
|
+
now,
|
|
9768
|
+
period,
|
|
9769
|
+
resource
|
|
9770
|
+
});
|
|
9771
|
+
if (outcome === "awarded") {
|
|
9772
|
+
awarded += 1;
|
|
9773
|
+
} else {
|
|
9774
|
+
skipped += 1;
|
|
9775
|
+
}
|
|
9776
|
+
}
|
|
9777
|
+
}
|
|
9778
|
+
return { awarded, skipped };
|
|
9779
|
+
}
|
|
9780
|
+
|
|
9781
|
+
// src/service/affiliate/findAffiliateByPromoCode.ts
|
|
9782
|
+
async function findAffiliateByPromoCode(promoCode) {
|
|
9783
|
+
return AffiliateModel.findOne({
|
|
9784
|
+
affiliateCode: promoCode,
|
|
9785
|
+
deletedAt: null
|
|
9786
|
+
}).exec();
|
|
9787
|
+
}
|
|
9788
|
+
|
|
9789
|
+
// src/service/affiliate/normalizeAffiliatePromoCodes.ts
|
|
9790
|
+
function normalizeAffiliatePromoCodes(promoCodes) {
|
|
9791
|
+
const normalized = (promoCodes ?? []).map((code) => normalizePromoCode(code)).filter((code) => code !== null);
|
|
9792
|
+
return [...new Set(normalized)];
|
|
9793
|
+
}
|
|
9794
|
+
|
|
9795
|
+
// src/service/database.ts
|
|
9796
|
+
var import_mongoose29 = __toESM(require("mongoose"));
|
|
9797
|
+
var connectToDatabase = async ({
|
|
9798
|
+
appName,
|
|
9799
|
+
dbName,
|
|
9800
|
+
dbPassword,
|
|
9801
|
+
dbUser,
|
|
9802
|
+
mongodbUri
|
|
9803
|
+
}) => {
|
|
9804
|
+
try {
|
|
9805
|
+
const mongoUri = mongodbUri ? mongodbUri : (
|
|
9806
|
+
// Fallback to MongoDB Atlas connection string
|
|
9807
|
+
`mongodb+srv://${dbUser}:${dbPassword}@${dbName}.mongodb.net/?retryWrites=true&w=majority&appName=${appName}`
|
|
9808
|
+
);
|
|
9809
|
+
await import_mongoose29.default.connect(mongoUri);
|
|
9810
|
+
const connectionType = mongodbUri ? "Local MongoDB" : "MongoDB Atlas";
|
|
9811
|
+
console.log(
|
|
9812
|
+
`${connectionType} connected from server/src/service/database.ts`
|
|
9813
|
+
);
|
|
9814
|
+
} catch (err) {
|
|
9815
|
+
console.error("Error connecting to MongoDB:", err);
|
|
9816
|
+
throw err;
|
|
9817
|
+
}
|
|
9818
|
+
};
|
|
9819
|
+
|
|
9585
9820
|
// src/service/updateAdStatus.ts
|
|
9586
9821
|
async function updateAdStatuses() {
|
|
9587
9822
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -9618,9 +9853,9 @@ async function updateAdStatuses() {
|
|
|
9618
9853
|
}
|
|
9619
9854
|
|
|
9620
9855
|
// src/service/associate.ts
|
|
9621
|
-
var
|
|
9856
|
+
var import_mongoose31 = __toESM(require("mongoose"));
|
|
9622
9857
|
function normalizeObjectId(id) {
|
|
9623
|
-
return typeof id === "string" ? new
|
|
9858
|
+
return typeof id === "string" ? new import_mongoose31.default.Types.ObjectId(id) : id;
|
|
9624
9859
|
}
|
|
9625
9860
|
async function getAssociateEmailsForResource({
|
|
9626
9861
|
normalizedResourceId,
|
|
@@ -9772,12 +10007,12 @@ async function updateVendorBasedOnUserLicense(userId, licenceType) {
|
|
|
9772
10007
|
}
|
|
9773
10008
|
|
|
9774
10009
|
// src/service/objectIdToString.ts
|
|
9775
|
-
var
|
|
10010
|
+
var import_mongoose34 = __toESM(require("mongoose"));
|
|
9776
10011
|
function convertObjectIdsToStrings(obj) {
|
|
9777
10012
|
if (obj === null || obj === void 0) {
|
|
9778
10013
|
return obj;
|
|
9779
10014
|
}
|
|
9780
|
-
if (obj instanceof
|
|
10015
|
+
if (obj instanceof import_mongoose34.default.Types.ObjectId) {
|
|
9781
10016
|
return obj.toString();
|
|
9782
10017
|
}
|
|
9783
10018
|
if (obj instanceof Date) {
|
|
@@ -9963,12 +10198,15 @@ function updateRelationDatesToUnavailable(relationDates, eventDateTime) {
|
|
|
9963
10198
|
ACTIVE_NOT_DELETED_FILTER,
|
|
9964
10199
|
AFFILIATE_REWARDS,
|
|
9965
10200
|
activeAffiliateCodeExists,
|
|
10201
|
+
awardAffiliateVendorSubscriptionRewards,
|
|
9966
10202
|
connectToDatabase,
|
|
9967
10203
|
convertObjectIdsToStrings,
|
|
9968
10204
|
createAffiliateReward,
|
|
9969
10205
|
didRemoveAnyEventDates,
|
|
9970
10206
|
findAffiliateByPromoCode,
|
|
9971
10207
|
findEventOrImportedMarketById,
|
|
10208
|
+
getSubscriptionRewardPeriodBounds,
|
|
10209
|
+
mapVendorLicenceToSubscriptionRewardType,
|
|
9972
10210
|
normalizeAffiliatePromoCodes,
|
|
9973
10211
|
normalizePromoCode,
|
|
9974
10212
|
saveNotificationsInDb,
|