@timardex/cluemart-server-shared 1.1.33 → 1.1.35

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.
@@ -27,7 +27,7 @@ type AwardAffiliateVendorSubscriptionRewardsResult = {
27
27
  * Awards monthly vendor subscription rewards to affiliates with active referred vendors.
28
28
  *
29
29
  * Eligibility per affiliate resource:
30
- * - Affiliate is not soft-deleted
30
+ * - Affiliate is active and not soft-deleted
31
31
  * - Linked `affiliateResources` entry is vendor, `resourceActive`, and not deleted
32
32
  * - Vendor is active, not deleted, and `owner.userId` matches
33
33
  * `affiliateResources.resourceOwner.userId`
@@ -38,7 +38,8 @@ type AwardAffiliateVendorSubscriptionRewardsResult = {
38
38
  * - Pro / Pro+ without paying Stripe → `ACTIVE_VENDOR_STANDARD_SUBSCRIPTION` (1 pt)
39
39
  * - Standard → `ACTIVE_VENDOR_STANDARD_SUBSCRIPTION` (1 pt)
40
40
  *
41
- * Idempotent per affiliate + vendor + reward type + calendar month.
41
+ * Idempotent per affiliate + vendor + calendar month a mid-month licence
42
+ * upgrade (Standard → paying Pro) takes effect from the following month.
42
43
  * On successful award, notifies the affiliate owner (best-effort).
43
44
  *
44
45
  * @param now - Reference time for month bounds and licence expiry (defaults to now).
@@ -75,6 +76,8 @@ declare function findAffiliateByPromoCode(promoCode: PromoCodeType): Promise<(mo
75
76
  */
76
77
  declare function normalizeAffiliatePromoCodes(promoCodes: PromoCodeType[] | null | undefined): PromoCodeType[];
77
78
 
79
+ /** Timezone the monthly reward window aligns to (matches the cron scheduler's `tz`). */
80
+ declare const SUBSCRIPTION_REWARD_TIMEZONE = "Pacific/Auckland";
78
81
  /**
79
82
  * Maps a vendor owner's highest valid vendor licence to a monthly subscription reward.
80
83
  *
@@ -84,7 +87,7 @@ declare function normalizeAffiliatePromoCodes(promoCodes: PromoCodeType[] | null
84
87
  * Returns `null` when no non-expired vendor licence applies.
85
88
  */
86
89
  declare function mapVendorLicenceToSubscriptionRewardType(userId: ObjectId | string, now?: Date): Promise<EnumAffiliateRewardType | null>;
87
- /** Inclusive start / exclusive end of the UTC calendar month containing `now`. */
90
+ /** Inclusive start / exclusive end of the {@link SUBSCRIPTION_REWARD_TIMEZONE} calendar month containing `now`. */
88
91
  declare function getSubscriptionRewardPeriodBounds(now?: Date): {
89
92
  periodEnd: Date;
90
93
  periodStart: Date;
@@ -212,4 +215,4 @@ declare function getPayingVendorStripeSubscriptionPlan(userId: ObjectId | string
212
215
  */
213
216
  declare function getPayingEventStripeSubscriptionPlan(userId: ObjectId | string, now?: Date): Promise<PayingStripeSubscriptionPlanResult>;
214
217
 
215
- export { ACTIVE_NOT_DELETED_FILTER, type AwardAffiliateVendorSubscriptionRewardsResult, type NotificationPubSub, activeAffiliateCodeExists, awardAffiliateVendorSubscriptionRewards, connectToDatabase, convertObjectIdsToStrings, didRemoveAnyEventDates, findAffiliateByPromoCode, findEventOrImportedMarketById, getPayingEventStripeSubscriptionPlan, getPayingStripeSubscriptionPlan, getPayingVendorStripeSubscriptionPlan, getSubscriptionRewardPeriodBounds, isValidObjectId, mapVendorLicenceToSubscriptionRewardType, normalizeAffiliatePromoCodes, normalizePromoCode, notifyUsers, publishNotificationEvents, saveNotificationsInDb, sendPushNotifications, updateAdStatuses, updateAllEventDateTimeStatuses, updateRelationDatesToUnavailable, updateSingleDateTimeStatus, updateVendorBasedOnUserLicense };
218
+ export { ACTIVE_NOT_DELETED_FILTER, type AwardAffiliateVendorSubscriptionRewardsResult, type NotificationPubSub, SUBSCRIPTION_REWARD_TIMEZONE, activeAffiliateCodeExists, awardAffiliateVendorSubscriptionRewards, connectToDatabase, convertObjectIdsToStrings, didRemoveAnyEventDates, findAffiliateByPromoCode, findEventOrImportedMarketById, getPayingEventStripeSubscriptionPlan, getPayingStripeSubscriptionPlan, getPayingVendorStripeSubscriptionPlan, getSubscriptionRewardPeriodBounds, isValidObjectId, mapVendorLicenceToSubscriptionRewardType, normalizeAffiliatePromoCodes, normalizePromoCode, notifyUsers, publishNotificationEvents, saveNotificationsInDb, sendPushNotifications, updateAdStatuses, updateAllEventDateTimeStatuses, updateRelationDatesToUnavailable, updateSingleDateTimeStatus, updateVendorBasedOnUserLicense };
@@ -27,7 +27,7 @@ type AwardAffiliateVendorSubscriptionRewardsResult = {
27
27
  * Awards monthly vendor subscription rewards to affiliates with active referred vendors.
28
28
  *
29
29
  * Eligibility per affiliate resource:
30
- * - Affiliate is not soft-deleted
30
+ * - Affiliate is active and not soft-deleted
31
31
  * - Linked `affiliateResources` entry is vendor, `resourceActive`, and not deleted
32
32
  * - Vendor is active, not deleted, and `owner.userId` matches
33
33
  * `affiliateResources.resourceOwner.userId`
@@ -38,7 +38,8 @@ type AwardAffiliateVendorSubscriptionRewardsResult = {
38
38
  * - Pro / Pro+ without paying Stripe → `ACTIVE_VENDOR_STANDARD_SUBSCRIPTION` (1 pt)
39
39
  * - Standard → `ACTIVE_VENDOR_STANDARD_SUBSCRIPTION` (1 pt)
40
40
  *
41
- * Idempotent per affiliate + vendor + reward type + calendar month.
41
+ * Idempotent per affiliate + vendor + calendar month a mid-month licence
42
+ * upgrade (Standard → paying Pro) takes effect from the following month.
42
43
  * On successful award, notifies the affiliate owner (best-effort).
43
44
  *
44
45
  * @param now - Reference time for month bounds and licence expiry (defaults to now).
@@ -75,6 +76,8 @@ declare function findAffiliateByPromoCode(promoCode: PromoCodeType): Promise<(mo
75
76
  */
76
77
  declare function normalizeAffiliatePromoCodes(promoCodes: PromoCodeType[] | null | undefined): PromoCodeType[];
77
78
 
79
+ /** Timezone the monthly reward window aligns to (matches the cron scheduler's `tz`). */
80
+ declare const SUBSCRIPTION_REWARD_TIMEZONE = "Pacific/Auckland";
78
81
  /**
79
82
  * Maps a vendor owner's highest valid vendor licence to a monthly subscription reward.
80
83
  *
@@ -84,7 +87,7 @@ declare function normalizeAffiliatePromoCodes(promoCodes: PromoCodeType[] | null
84
87
  * Returns `null` when no non-expired vendor licence applies.
85
88
  */
86
89
  declare function mapVendorLicenceToSubscriptionRewardType(userId: ObjectId | string, now?: Date): Promise<EnumAffiliateRewardType | null>;
87
- /** Inclusive start / exclusive end of the UTC calendar month containing `now`. */
90
+ /** Inclusive start / exclusive end of the {@link SUBSCRIPTION_REWARD_TIMEZONE} calendar month containing `now`. */
88
91
  declare function getSubscriptionRewardPeriodBounds(now?: Date): {
89
92
  periodEnd: Date;
90
93
  periodStart: Date;
@@ -212,4 +215,4 @@ declare function getPayingVendorStripeSubscriptionPlan(userId: ObjectId | string
212
215
  */
213
216
  declare function getPayingEventStripeSubscriptionPlan(userId: ObjectId | string, now?: Date): Promise<PayingStripeSubscriptionPlanResult>;
214
217
 
215
- export { ACTIVE_NOT_DELETED_FILTER, type AwardAffiliateVendorSubscriptionRewardsResult, type NotificationPubSub, activeAffiliateCodeExists, awardAffiliateVendorSubscriptionRewards, connectToDatabase, convertObjectIdsToStrings, didRemoveAnyEventDates, findAffiliateByPromoCode, findEventOrImportedMarketById, getPayingEventStripeSubscriptionPlan, getPayingStripeSubscriptionPlan, getPayingVendorStripeSubscriptionPlan, getSubscriptionRewardPeriodBounds, isValidObjectId, mapVendorLicenceToSubscriptionRewardType, normalizeAffiliatePromoCodes, normalizePromoCode, notifyUsers, publishNotificationEvents, saveNotificationsInDb, sendPushNotifications, updateAdStatuses, updateAllEventDateTimeStatuses, updateRelationDatesToUnavailable, updateSingleDateTimeStatus, updateVendorBasedOnUserLicense };
218
+ export { ACTIVE_NOT_DELETED_FILTER, type AwardAffiliateVendorSubscriptionRewardsResult, type NotificationPubSub, SUBSCRIPTION_REWARD_TIMEZONE, activeAffiliateCodeExists, awardAffiliateVendorSubscriptionRewards, connectToDatabase, convertObjectIdsToStrings, didRemoveAnyEventDates, findAffiliateByPromoCode, findEventOrImportedMarketById, getPayingEventStripeSubscriptionPlan, getPayingStripeSubscriptionPlan, getPayingVendorStripeSubscriptionPlan, getSubscriptionRewardPeriodBounds, isValidObjectId, mapVendorLicenceToSubscriptionRewardType, normalizeAffiliatePromoCodes, normalizePromoCode, notifyUsers, publishNotificationEvents, saveNotificationsInDb, sendPushNotifications, updateAdStatuses, updateAllEventDateTimeStatuses, updateRelationDatesToUnavailable, updateSingleDateTimeStatus, updateVendorBasedOnUserLicense };
@@ -23,7 +23,7 @@ import {
23
23
  VendorModel,
24
24
  dateFormat,
25
25
  timeFormat
26
- } from "../chunk-WLOHVSV6.mjs";
26
+ } from "../chunk-ZVXL6B3M.mjs";
27
27
  import "../chunk-6PNG5BI5.mjs";
28
28
 
29
29
  // src/service/promoCode/constants.ts
@@ -96,7 +96,7 @@ var SHARE_RESOURCE_LABEL = {
96
96
  school: "School"
97
97
  };
98
98
 
99
- // node_modules/@timardex/cluemart-shared/dist/chunk-FGVNX6EN.mjs
99
+ // node_modules/@timardex/cluemart-shared/dist/chunk-364EX22V.mjs
100
100
  var PROMO_CODE_PREFIX = "CM-";
101
101
  var OBJECT_ID_PATH_SEGMENT = "[a-f0-9]{24}";
102
102
  var OBJECT_ID_PATH_SEGMENT_END = `${OBJECT_ID_PATH_SEGMENT}$`;
@@ -109,7 +109,7 @@ var gameScreenIdentifierList = [
109
109
  {
110
110
  clue: "Where you can find your loyalties.",
111
111
  id: "coupons",
112
- match: "/coupons"
112
+ match: "/profile/account/coupons"
113
113
  },
114
114
  {
115
115
  clue: "A single moment worth showing up for.",
@@ -139,7 +139,7 @@ var gameScreenIdentifierList = [
139
139
  {
140
140
  clue: "Where fun becomes a challenge.",
141
141
  id: "games",
142
- match: "/games"
142
+ match: "/profile/account/games"
143
143
  },
144
144
  {
145
145
  clue: "Your starting point for everything.",
@@ -208,7 +208,7 @@ var gameScreenIdentifierList = [
208
208
  }
209
209
  ];
210
210
 
211
- // node_modules/@timardex/cluemart-shared/dist/chunk-UPFNTXDX.mjs
211
+ // node_modules/@timardex/cluemart-shared/dist/chunk-5RXL62LO.mjs
212
212
  import dayjs2 from "dayjs";
213
213
  var statusOptions = [
214
214
  ...Object.values(EnumInviteStatus2).map((status) => ({
@@ -1385,6 +1385,11 @@ async function sendPushNotifications({
1385
1385
  }
1386
1386
  }
1387
1387
 
1388
+ // src/service/affiliate/vendorSubscriptionRewards.ts
1389
+ import dayjs3 from "dayjs";
1390
+ import timezone2 from "dayjs/plugin/timezone";
1391
+ import utc2 from "dayjs/plugin/utc";
1392
+
1388
1393
  // src/service/license.ts
1389
1394
  var PRO_EVENT_PLANS = /* @__PURE__ */ new Set([
1390
1395
  EnumUserLicence2.PRO_EVENT,
@@ -1431,6 +1436,9 @@ async function getPayingEventStripeSubscriptionPlan(userId, now = /* @__PURE__ *
1431
1436
  }
1432
1437
 
1433
1438
  // src/service/affiliate/vendorSubscriptionRewards.ts
1439
+ dayjs3.extend(utc2);
1440
+ dayjs3.extend(timezone2);
1441
+ var SUBSCRIPTION_REWARD_TIMEZONE = "Pacific/Auckland";
1434
1442
  async function mapVendorLicenceToSubscriptionRewardType(userId, now = /* @__PURE__ */ new Date()) {
1435
1443
  const { hasSubscription, validTypes } = await getPayingVendorStripeSubscriptionPlan(userId, now);
1436
1444
  if (validTypes.has(EnumUserLicence.PRO_VENDOR) || validTypes.has(EnumUserLicence.PRO_PLUS_VENDOR)) {
@@ -1445,12 +1453,8 @@ async function mapVendorLicenceToSubscriptionRewardType(userId, now = /* @__PURE
1445
1453
  return null;
1446
1454
  }
1447
1455
  function getSubscriptionRewardPeriodBounds(now = /* @__PURE__ */ new Date()) {
1448
- const periodStart = new Date(
1449
- Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1)
1450
- );
1451
- const periodEnd = new Date(
1452
- Date.UTC(now.getUTCFullYear(), now.getUTCMonth() + 1, 1)
1453
- );
1456
+ const periodStart = dayjs3(now).tz(SUBSCRIPTION_REWARD_TIMEZONE).startOf("month").toDate();
1457
+ const periodEnd = dayjs3(now).tz(SUBSCRIPTION_REWARD_TIMEZONE).startOf("month").add(1, "month").toDate();
1454
1458
  return { periodEnd, periodStart };
1455
1459
  }
1456
1460
 
@@ -1460,6 +1464,7 @@ function isEligibleVendorResource(resource) {
1460
1464
  }
1461
1465
  async function findAffiliatesWithActiveVendorReferrals() {
1462
1466
  return await AffiliateModel.find({
1467
+ active: true,
1463
1468
  affiliateResources: {
1464
1469
  $elemMatch: {
1465
1470
  resourceActive: true,
@@ -1532,8 +1537,7 @@ async function tryAwardSubscriptionReward({
1532
1537
  createdAt: {
1533
1538
  $gte: period.periodStart,
1534
1539
  $lt: period.periodEnd
1535
- },
1536
- rewardType
1540
+ }
1537
1541
  }
1538
1542
  }
1539
1543
  }
@@ -1814,11 +1818,11 @@ function convertObjectIdsToStrings(obj) {
1814
1818
  }
1815
1819
 
1816
1820
  // src/service/event/updateAllEventDateTimeStatuses.ts
1817
- import dayjs3 from "dayjs";
1821
+ import dayjs4 from "dayjs";
1818
1822
  import customParseFormat2 from "dayjs/plugin/customParseFormat";
1819
1823
  import isoWeek from "dayjs/plugin/isoWeek";
1820
- dayjs3.extend(customParseFormat2);
1821
- dayjs3.extend(isoWeek);
1824
+ dayjs4.extend(customParseFormat2);
1825
+ dayjs4.extend(isoWeek);
1822
1826
  function getFutureEventStatus(startDateTime, now) {
1823
1827
  const hoursUntilStart = startDateTime.diff(now, "hour", true);
1824
1828
  if (hoursUntilStart > 0 && hoursUntilStart <= 4) {
@@ -1838,14 +1842,14 @@ function getFutureEventStatus(startDateTime, now) {
1838
1842
  }
1839
1843
  return EnumEventDateStatus.UPCOMING;
1840
1844
  }
1841
- function updateSingleDateTimeStatus(dateTime, now = dayjs3()) {
1845
+ function updateSingleDateTimeStatus(dateTime, now = dayjs4()) {
1842
1846
  const dateTimeFormat = `${dateFormat} ${timeFormat}`;
1843
- const startDateTime = dayjs3(
1847
+ const startDateTime = dayjs4(
1844
1848
  `${dateTime.startDate} ${dateTime.startTime}`,
1845
1849
  dateTimeFormat,
1846
1850
  true
1847
1851
  );
1848
- const endDateTime = dayjs3(
1852
+ const endDateTime = dayjs4(
1849
1853
  `${dateTime.endDate} ${dateTime.endTime}`,
1850
1854
  dateTimeFormat,
1851
1855
  true
@@ -1927,7 +1931,7 @@ async function updateModelDateTimeStatuses(model, now) {
1927
1931
  return updated;
1928
1932
  }
1929
1933
  async function updateAllEventDateTimeStatuses() {
1930
- const now = dayjs3();
1934
+ const now = dayjs4();
1931
1935
  const [eventCount, marketCount] = await Promise.all([
1932
1936
  updateModelDateTimeStatuses(EventModel, now),
1933
1937
  updateModelDateTimeStatuses(
@@ -1977,6 +1981,7 @@ function updateRelationDatesToUnavailable(relationDates, eventDateTime) {
1977
1981
  }
1978
1982
  export {
1979
1983
  ACTIVE_NOT_DELETED_FILTER,
1984
+ SUBSCRIPTION_REWARD_TIMEZONE,
1980
1985
  activeAffiliateCodeExists,
1981
1986
  awardAffiliateVendorSubscriptionRewards,
1982
1987
  connectToDatabase,