@lyxa.ai/marketing 1.0.64 → 1.0.65

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 (311) hide show
  1. package/dist/lib/event/event-initializations.d.ts.map +1 -1
  2. package/dist/lib/event/event-initializations.js +0 -1
  3. package/dist/lib/event/event-initializations.js.map +1 -1
  4. package/dist/lib/event/event-listeners/event-listeners.d.ts +0 -1
  5. package/dist/lib/event/event-listeners/event-listeners.d.ts.map +1 -1
  6. package/dist/lib/event/event-listeners/event-listeners.js +12 -62
  7. package/dist/lib/event/event-listeners/event-listeners.js.map +1 -1
  8. package/dist/lib/event/events/marketing-product-seed.event.d.ts +2 -1
  9. package/dist/lib/event/events/marketing-product-seed.event.d.ts.map +1 -1
  10. package/dist/lib/event/events/marketing-product-seed.event.js.map +1 -1
  11. package/dist/lib/index.d.ts +21 -12030
  12. package/dist/lib/index.d.ts.map +1 -1
  13. package/dist/lib/index.js.map +1 -1
  14. package/dist/lib/modules/coupon/routers/coupon.router.d.ts +1101 -27
  15. package/dist/lib/modules/coupon/routers/coupon.router.d.ts.map +1 -1
  16. package/dist/lib/modules/coupon/services/coupon.service.d.ts +1 -1
  17. package/dist/lib/modules/coupon/services/coupon.service.js +1 -1
  18. package/dist/lib/modules/coupon/services/coupon.service.js.map +1 -1
  19. package/dist/lib/modules/coupon/services/patterns/repository/CouponMetricsRepository.d.ts.map +1 -1
  20. package/dist/lib/modules/coupon/services/patterns/repository/CouponMetricsRepository.js +21 -6
  21. package/dist/lib/modules/coupon/services/patterns/repository/CouponMetricsRepository.js.map +1 -1
  22. package/dist/lib/modules/coupon/services/referral-reward-coupon.service.d.ts.map +1 -1
  23. package/dist/lib/modules/coupon/services/referral-reward-coupon.service.js +1 -0
  24. package/dist/lib/modules/coupon/services/referral-reward-coupon.service.js.map +1 -1
  25. package/dist/lib/modules/coupon/transformers/coupon.transformer.d.ts +50 -0
  26. package/dist/lib/modules/coupon/transformers/coupon.transformer.d.ts.map +1 -1
  27. package/dist/lib/modules/coupon/validations/all-coupons.validation.d.ts +828 -6
  28. package/dist/lib/modules/coupon/validations/all-coupons.validation.d.ts.map +1 -1
  29. package/dist/lib/modules/coupon/validations/coupon.validation.d.ts +30 -30
  30. package/dist/lib/modules/coupon/validations/create-coupon.validation.d.ts +98 -0
  31. package/dist/lib/modules/coupon/validations/create-coupon.validation.d.ts.map +1 -1
  32. package/dist/lib/modules/coupon/validations/referral-reward-coupon.validation.d.ts +374 -0
  33. package/dist/lib/modules/coupon/validations/referral-reward-coupon.validation.d.ts.map +1 -1
  34. package/dist/lib/modules/coupon/validations/referral-reward-coupon.validation.js +2 -0
  35. package/dist/lib/modules/coupon/validations/referral-reward-coupon.validation.js.map +1 -1
  36. package/dist/lib/modules/deal-setting/routers/deal-setting.router.d.ts +9 -9
  37. package/dist/lib/modules/deal-setting/routers/deal-setting.router.d.ts.map +1 -1
  38. package/dist/lib/modules/deal-setting/validations/deal-setting.validation.d.ts +6 -6
  39. package/dist/lib/modules/featured-setting/routers/featured-setting.router.d.ts +8 -8
  40. package/dist/lib/modules/featured-setting/routers/featured-setting.router.d.ts.map +1 -1
  41. package/dist/lib/modules/featured-setting/validations/featured-setting.validation.d.ts +6 -6
  42. package/dist/lib/modules/limited-time-offer/campaign/campaign.router.d.ts +7 -7
  43. package/dist/lib/modules/limited-time-offer/campaign/campaign.router.d.ts.map +1 -1
  44. package/dist/lib/modules/limited-time-offer/campaign/campaign.router.js +2 -0
  45. package/dist/lib/modules/limited-time-offer/campaign/campaign.router.js.map +1 -1
  46. package/dist/lib/modules/limited-time-offer/campaign/jobs/index.d.ts.map +1 -1
  47. package/dist/lib/modules/limited-time-offer/campaign/jobs/index.js +4 -1
  48. package/dist/lib/modules/limited-time-offer/campaign/jobs/index.js.map +1 -1
  49. package/dist/lib/modules/limited-time-offer/campaign/limited-time-offer-campaign.validation.d.ts +36 -36
  50. package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-lifecycle.service.d.ts.map +1 -1
  51. package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-lifecycle.service.js +7 -2
  52. package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-lifecycle.service.js.map +1 -1
  53. package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.d.ts +1 -0
  54. package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.d.ts.map +1 -1
  55. package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.js +13 -2
  56. package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.js.map +1 -1
  57. package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign.service.d.ts.map +1 -1
  58. package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign.service.js +7 -2
  59. package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign.service.js.map +1 -1
  60. package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.validation.d.ts +6 -6
  61. package/dist/lib/modules/limited-time-offer/config/limited-time-offer.router.d.ts +3 -3
  62. package/dist/lib/modules/limited-time-offer/limited-time-offer.router.d.ts +18 -18
  63. package/dist/lib/modules/limited-time-offer/limited-time-offer.service.d.ts.map +1 -1
  64. package/dist/lib/modules/limited-time-offer/limited-time-offer.service.js +3 -0
  65. package/dist/lib/modules/limited-time-offer/limited-time-offer.service.js.map +1 -1
  66. package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.router.d.ts +7 -7
  67. package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.router.d.ts.map +1 -1
  68. package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.router.js +5 -0
  69. package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.router.js.map +1 -1
  70. package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.service.d.ts +1 -0
  71. package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.service.d.ts.map +1 -0
  72. package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.service.js +2 -0
  73. package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.service.js.map +1 -0
  74. package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.validation.d.ts +19 -19
  75. package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.d.ts +1 -0
  76. package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.d.ts.map +1 -1
  77. package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.js +18 -1
  78. package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.js.map +1 -1
  79. package/dist/lib/modules/marketing/routers/marketing.router.d.ts +14 -3
  80. package/dist/lib/modules/marketing/routers/marketing.router.d.ts.map +1 -1
  81. package/dist/lib/modules/marketing/routers/marketing.router.js +4 -0
  82. package/dist/lib/modules/marketing/routers/marketing.router.js.map +1 -1
  83. package/dist/lib/modules/marketing/services/marketing.service.d.ts +1 -2
  84. package/dist/lib/modules/marketing/services/marketing.service.d.ts.map +1 -1
  85. package/dist/lib/modules/marketing/services/marketing.service.js +85 -77
  86. package/dist/lib/modules/marketing/services/marketing.service.js.map +1 -1
  87. package/dist/lib/modules/marketing/services/product-marketing.service.d.ts +3 -1
  88. package/dist/lib/modules/marketing/services/product-marketing.service.d.ts.map +1 -1
  89. package/dist/lib/modules/marketing/services/product-marketing.service.js +13 -10
  90. package/dist/lib/modules/marketing/services/product-marketing.service.js.map +1 -1
  91. package/dist/lib/modules/marketing/services/spend-to-get-progress.service.d.ts +13 -0
  92. package/dist/lib/modules/marketing/services/spend-to-get-progress.service.d.ts.map +1 -1
  93. package/dist/lib/modules/marketing/services/spend-to-get-progress.service.js +24 -0
  94. package/dist/lib/modules/marketing/services/spend-to-get-progress.service.js.map +1 -1
  95. package/dist/lib/modules/marketing/services/synchronize-product-marketing.service.d.ts.map +1 -1
  96. package/dist/lib/modules/marketing/services/synchronize-product-marketing.service.js +27 -95
  97. package/dist/lib/modules/marketing/services/synchronize-product-marketing.service.js.map +1 -1
  98. package/dist/lib/modules/marketing/validations/all-marketings.validation.d.ts +4 -4
  99. package/dist/lib/modules/marketing/validations/buy1-get1-marketing.validation.d.ts +3 -3
  100. package/dist/lib/modules/marketing/validations/discount-marketing.validation.d.ts +3 -3
  101. package/dist/lib/modules/marketing/validations/marketing.validation.d.ts +8 -0
  102. package/dist/lib/modules/marketing/validations/marketing.validation.d.ts.map +1 -1
  103. package/dist/lib/modules/marketing/validations/marketing.validation.js +4 -1
  104. package/dist/lib/modules/marketing/validations/marketing.validation.js.map +1 -1
  105. package/dist/lib/modules/marketing/validations/product-marketing.validation.d.ts +2 -2
  106. package/dist/lib/modules/marketing/validations/punch-marketing.validation.d.ts +4 -4
  107. package/dist/lib/modules/punch-marketing-history/routers/punch-marketing-history.router.d.ts +12 -12
  108. package/dist/lib/modules/punch-marketing-history/routers/punch-marketing-history.router.d.ts.map +1 -1
  109. package/dist/lib/modules/punch-marketing-history/validations/punch-marketing-history.validation.d.ts +8 -8
  110. package/dist/lib/modules/referral-setting/routers/referral-setting.router.d.ts +4 -4
  111. package/dist/lib/modules/referral-setting/validations/referral-setting.validation.d.ts +6 -6
  112. package/dist/lib/modules/referral-setting/validations/referral-setting.validation.d.ts.map +1 -1
  113. package/dist/lib/modules/referral-setting/validations/referral-setting.validation.js.map +1 -1
  114. package/dist/lib/modules/spend-to-get-history/spend-to-get-history.repository.d.ts +3 -2
  115. package/dist/lib/modules/spend-to-get-history/spend-to-get-history.repository.d.ts.map +1 -1
  116. package/dist/lib/modules/spend-to-get-history/spend-to-get-history.repository.js +11 -3
  117. package/dist/lib/modules/spend-to-get-history/spend-to-get-history.repository.js.map +1 -1
  118. package/dist/lib/modules/spend-to-get-history/spend-to-get-history.router.d.ts +26 -10
  119. package/dist/lib/modules/spend-to-get-history/spend-to-get-history.router.d.ts.map +1 -1
  120. package/dist/lib/modules/spend-to-get-history/spend-to-get-history.service.d.ts +2 -2
  121. package/dist/lib/modules/spend-to-get-history/spend-to-get-history.service.d.ts.map +1 -1
  122. package/dist/lib/modules/spend-to-get-history/spend-to-get-history.service.js.map +1 -1
  123. package/dist/lib/modules/spend-to-get-history/spend-to-get-history.validation.d.ts +25 -6
  124. package/dist/lib/modules/spend-to-get-history/spend-to-get-history.validation.d.ts.map +1 -1
  125. package/dist/lib/modules/spend-to-get-history/spend-to-get-history.validation.js +1 -0
  126. package/dist/lib/modules/spend-to-get-history/spend-to-get-history.validation.js.map +1 -1
  127. package/dist/lib/modules/tournament/config/config.router.d.ts +4 -4
  128. package/dist/lib/modules/tournament/config/config.validation.d.ts +12 -12
  129. package/dist/lib/modules/tournament/match/match.router.d.ts +5 -5
  130. package/dist/lib/modules/tournament/match/match.validation.d.ts +12 -12
  131. package/dist/lib/modules/tournament/participant/participant.router.d.ts +3 -3
  132. package/dist/lib/modules/tournament/participant/participant.validation.d.ts +24 -24
  133. package/dist/lib/modules/tournament/prediction/prediction.router.d.ts +3 -3
  134. package/dist/lib/modules/tournament/prediction/prediction.validation.d.ts +18 -18
  135. package/dist/lib/modules/tournament/score/score.router.d.ts +1 -1
  136. package/dist/lib/modules/tournament/score/score.validation.d.ts +6 -6
  137. package/dist/lib/modules/tournament/statistics/statistics.router.d.ts +1 -1
  138. package/dist/lib/modules/tournament/statistics/statistics.validation.d.ts +6 -6
  139. package/dist/lib/modules/tournament/team/team.router.d.ts +3 -3
  140. package/dist/lib/modules/tournament/team/team.validation.d.ts +18 -18
  141. package/dist/lib/modules/tournament/tournament.router.d.ts +21 -21
  142. package/dist/lib/modules/tournament/tournament.validation.d.ts +6 -6
  143. package/dist/lib/utility/feature-flags.d.ts +3 -0
  144. package/dist/lib/utility/feature-flags.d.ts.map +1 -0
  145. package/dist/lib/utility/feature-flags.js +16 -0
  146. package/dist/lib/utility/feature-flags.js.map +1 -0
  147. package/dist/types/event/event-initializations.d.ts.map +1 -1
  148. package/dist/types/event/event-listeners/event-listeners.d.ts +0 -1
  149. package/dist/types/event/event-listeners/event-listeners.d.ts.map +1 -1
  150. package/dist/types/event/events/marketing-product-seed.event.d.ts +2 -1
  151. package/dist/types/event/events/marketing-product-seed.event.d.ts.map +1 -1
  152. package/dist/types/index.d.ts +21 -12030
  153. package/dist/types/index.d.ts.map +1 -1
  154. package/dist/types/modules/coupon/routers/coupon.router.d.ts +1101 -27
  155. package/dist/types/modules/coupon/routers/coupon.router.d.ts.map +1 -1
  156. package/dist/types/modules/coupon/services/coupon.service.d.ts +1 -1
  157. package/dist/types/modules/coupon/services/patterns/repository/CouponMetricsRepository.d.ts.map +1 -1
  158. package/dist/types/modules/coupon/services/referral-reward-coupon.service.d.ts.map +1 -1
  159. package/dist/types/modules/coupon/transformers/coupon.transformer.d.ts +50 -0
  160. package/dist/types/modules/coupon/transformers/coupon.transformer.d.ts.map +1 -1
  161. package/dist/types/modules/coupon/validations/all-coupons.validation.d.ts +828 -6
  162. package/dist/types/modules/coupon/validations/all-coupons.validation.d.ts.map +1 -1
  163. package/dist/types/modules/coupon/validations/coupon.validation.d.ts +30 -30
  164. package/dist/types/modules/coupon/validations/create-coupon.validation.d.ts +98 -0
  165. package/dist/types/modules/coupon/validations/create-coupon.validation.d.ts.map +1 -1
  166. package/dist/types/modules/coupon/validations/referral-reward-coupon.validation.d.ts +374 -0
  167. package/dist/types/modules/coupon/validations/referral-reward-coupon.validation.d.ts.map +1 -1
  168. package/dist/types/modules/deal-setting/routers/deal-setting.router.d.ts +9 -9
  169. package/dist/types/modules/deal-setting/routers/deal-setting.router.d.ts.map +1 -1
  170. package/dist/types/modules/deal-setting/validations/deal-setting.validation.d.ts +6 -6
  171. package/dist/types/modules/featured-setting/routers/featured-setting.router.d.ts +8 -8
  172. package/dist/types/modules/featured-setting/routers/featured-setting.router.d.ts.map +1 -1
  173. package/dist/types/modules/featured-setting/validations/featured-setting.validation.d.ts +6 -6
  174. package/dist/types/modules/limited-time-offer/campaign/campaign.router.d.ts +7 -7
  175. package/dist/types/modules/limited-time-offer/campaign/campaign.router.d.ts.map +1 -1
  176. package/dist/types/modules/limited-time-offer/campaign/jobs/index.d.ts.map +1 -1
  177. package/dist/types/modules/limited-time-offer/campaign/limited-time-offer-campaign.validation.d.ts +36 -36
  178. package/dist/types/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-lifecycle.service.d.ts.map +1 -1
  179. package/dist/types/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.d.ts +1 -0
  180. package/dist/types/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.d.ts.map +1 -1
  181. package/dist/types/modules/limited-time-offer/campaign/services/limited-time-offer-campaign.service.d.ts.map +1 -1
  182. package/dist/types/modules/limited-time-offer/config/limited-time-offer-config.validation.d.ts +6 -6
  183. package/dist/types/modules/limited-time-offer/config/limited-time-offer.router.d.ts +3 -3
  184. package/dist/types/modules/limited-time-offer/limited-time-offer.router.d.ts +18 -18
  185. package/dist/types/modules/limited-time-offer/limited-time-offer.service.d.ts.map +1 -1
  186. package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.router.d.ts +7 -7
  187. package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.router.d.ts.map +1 -1
  188. package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.validation.d.ts +19 -19
  189. package/dist/types/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.d.ts +1 -0
  190. package/dist/types/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.d.ts.map +1 -1
  191. package/dist/types/modules/marketing/routers/marketing.router.d.ts +14 -3
  192. package/dist/types/modules/marketing/routers/marketing.router.d.ts.map +1 -1
  193. package/dist/types/modules/marketing/services/marketing.service.d.ts +1 -2
  194. package/dist/types/modules/marketing/services/marketing.service.d.ts.map +1 -1
  195. package/dist/types/modules/marketing/services/product-marketing.service.d.ts +3 -1
  196. package/dist/types/modules/marketing/services/product-marketing.service.d.ts.map +1 -1
  197. package/dist/types/modules/marketing/services/spend-to-get-progress.service.d.ts +18 -0
  198. package/dist/types/modules/marketing/services/spend-to-get-progress.service.d.ts.map +1 -1
  199. package/dist/types/modules/marketing/services/synchronize-product-marketing.service.d.ts.map +1 -1
  200. package/dist/types/modules/marketing/validations/all-marketings.validation.d.ts +4 -4
  201. package/dist/types/modules/marketing/validations/buy1-get1-marketing.validation.d.ts +3 -3
  202. package/dist/types/modules/marketing/validations/discount-marketing.validation.d.ts +3 -3
  203. package/dist/types/modules/marketing/validations/marketing.validation.d.ts +8 -0
  204. package/dist/types/modules/marketing/validations/marketing.validation.d.ts.map +1 -1
  205. package/dist/types/modules/marketing/validations/product-marketing.validation.d.ts +2 -2
  206. package/dist/types/modules/marketing/validations/punch-marketing.validation.d.ts +4 -4
  207. package/dist/types/modules/punch-marketing-history/routers/punch-marketing-history.router.d.ts +12 -12
  208. package/dist/types/modules/punch-marketing-history/routers/punch-marketing-history.router.d.ts.map +1 -1
  209. package/dist/types/modules/punch-marketing-history/validations/punch-marketing-history.validation.d.ts +8 -8
  210. package/dist/types/modules/referral-setting/routers/referral-setting.router.d.ts +4 -4
  211. package/dist/types/modules/referral-setting/validations/referral-setting.validation.d.ts +6 -6
  212. package/dist/types/modules/referral-setting/validations/referral-setting.validation.d.ts.map +1 -1
  213. package/dist/types/modules/spend-to-get-history/spend-to-get-history.repository.d.ts +3 -2
  214. package/dist/types/modules/spend-to-get-history/spend-to-get-history.repository.d.ts.map +1 -1
  215. package/dist/types/modules/spend-to-get-history/spend-to-get-history.router.d.ts +26 -10
  216. package/dist/types/modules/spend-to-get-history/spend-to-get-history.router.d.ts.map +1 -1
  217. package/dist/types/modules/spend-to-get-history/spend-to-get-history.service.d.ts +2 -2
  218. package/dist/types/modules/spend-to-get-history/spend-to-get-history.service.d.ts.map +1 -1
  219. package/dist/types/modules/spend-to-get-history/spend-to-get-history.validation.d.ts +25 -6
  220. package/dist/types/modules/spend-to-get-history/spend-to-get-history.validation.d.ts.map +1 -1
  221. package/dist/types/modules/tournament/config/config.router.d.ts +4 -4
  222. package/dist/types/modules/tournament/config/config.validation.d.ts +12 -12
  223. package/dist/types/modules/tournament/match/match.router.d.ts +5 -5
  224. package/dist/types/modules/tournament/match/match.validation.d.ts +12 -12
  225. package/dist/types/modules/tournament/participant/participant.router.d.ts +3 -3
  226. package/dist/types/modules/tournament/participant/participant.validation.d.ts +24 -24
  227. package/dist/types/modules/tournament/prediction/prediction.router.d.ts +3 -3
  228. package/dist/types/modules/tournament/prediction/prediction.validation.d.ts +18 -18
  229. package/dist/types/modules/tournament/score/score.router.d.ts +1 -1
  230. package/dist/types/modules/tournament/score/score.validation.d.ts +6 -6
  231. package/dist/types/modules/tournament/statistics/statistics.router.d.ts +1 -1
  232. package/dist/types/modules/tournament/statistics/statistics.validation.d.ts +6 -6
  233. package/dist/types/modules/tournament/team/team.router.d.ts +3 -3
  234. package/dist/types/modules/tournament/team/team.validation.d.ts +18 -18
  235. package/dist/types/modules/tournament/tournament.router.d.ts +21 -21
  236. package/dist/types/modules/tournament/tournament.validation.d.ts +6 -6
  237. package/dist/types/utility/feature-flags.d.ts +12 -0
  238. package/dist/types/utility/feature-flags.d.ts.map +1 -0
  239. package/package.json +2 -2
  240. package/dist/lib/modules/spend-to-get-history/routers/index.d.ts +0 -2
  241. package/dist/lib/modules/spend-to-get-history/routers/index.d.ts.map +0 -1
  242. package/dist/lib/modules/spend-to-get-history/routers/index.js +0 -18
  243. package/dist/lib/modules/spend-to-get-history/routers/index.js.map +0 -1
  244. package/dist/lib/modules/spend-to-get-history/routers/spend-to-get-history.router.js +0 -62
  245. package/dist/lib/modules/spend-to-get-history/routers/spend-to-get-history.router.js.map +0 -1
  246. package/dist/lib/modules/spend-to-get-history/services/index.d.ts +0 -2
  247. package/dist/lib/modules/spend-to-get-history/services/index.d.ts.map +0 -1
  248. package/dist/lib/modules/spend-to-get-history/services/index.js +0 -18
  249. package/dist/lib/modules/spend-to-get-history/services/index.js.map +0 -1
  250. package/dist/lib/modules/spend-to-get-history/services/spend-to-get-history.service.d.ts +0 -24
  251. package/dist/lib/modules/spend-to-get-history/services/spend-to-get-history.service.d.ts.map +0 -1
  252. package/dist/lib/modules/spend-to-get-history/services/spend-to-get-history.service.js +0 -136
  253. package/dist/lib/modules/spend-to-get-history/services/spend-to-get-history.service.js.map +0 -1
  254. package/dist/lib/modules/spend-to-get-history/validations/index.d.ts +0 -2
  255. package/dist/lib/modules/spend-to-get-history/validations/index.d.ts.map +0 -1
  256. package/dist/lib/modules/spend-to-get-history/validations/index.js +0 -18
  257. package/dist/lib/modules/spend-to-get-history/validations/index.js.map +0 -1
  258. package/dist/lib/modules/spend-to-get-history/validations/spend-to-get-history.validation.d.ts +0 -232
  259. package/dist/lib/modules/spend-to-get-history/validations/spend-to-get-history.validation.d.ts.map +0 -1
  260. package/dist/lib/modules/spend-to-get-history/validations/spend-to-get-history.validation.js +0 -30
  261. package/dist/lib/modules/spend-to-get-history/validations/spend-to-get-history.validation.js.map +0 -1
  262. package/dist/lib/modules/tournament/match/events/match-ended.consumer.d.ts +0 -2
  263. package/dist/lib/modules/tournament/match/events/match-ended.consumer.d.ts.map +0 -1
  264. package/dist/lib/modules/tournament/match/events/match-ended.consumer.js +0 -15
  265. package/dist/lib/modules/tournament/match/events/match-ended.consumer.js.map +0 -1
  266. package/dist/lib/modules/tournament/match/events/match-ended.event.d.ts +0 -14
  267. package/dist/lib/modules/tournament/match/events/match-ended.event.d.ts.map +0 -1
  268. package/dist/lib/modules/tournament/match/events/match-ended.event.js +0 -12
  269. package/dist/lib/modules/tournament/match/events/match-ended.event.js.map +0 -1
  270. package/dist/lib/modules/tournament/notification/jobs/notification.producer.d.ts +0 -10
  271. package/dist/lib/modules/tournament/notification/jobs/notification.producer.d.ts.map +0 -1
  272. package/dist/lib/modules/tournament/notification/jobs/notification.producer.js +0 -23
  273. package/dist/lib/modules/tournament/notification/jobs/notification.producer.js.map +0 -1
  274. package/dist/lib/modules/tournament/notification/jobs/notification.worker.d.ts +0 -9
  275. package/dist/lib/modules/tournament/notification/jobs/notification.worker.d.ts.map +0 -1
  276. package/dist/lib/modules/tournament/notification/jobs/notification.worker.js +0 -82
  277. package/dist/lib/modules/tournament/notification/jobs/notification.worker.js.map +0 -1
  278. package/dist/lib/modules/tournament/notification/notification.schedule.config.d.ts +0 -10
  279. package/dist/lib/modules/tournament/notification/notification.schedule.config.d.ts.map +0 -1
  280. package/dist/lib/modules/tournament/notification/notification.schedule.config.js +0 -15
  281. package/dist/lib/modules/tournament/notification/notification.schedule.config.js.map +0 -1
  282. package/dist/lib/modules/tournament/notification/notification.scheduler.service.d.ts +0 -10
  283. package/dist/lib/modules/tournament/notification/notification.scheduler.service.d.ts.map +0 -1
  284. package/dist/lib/modules/tournament/notification/notification.scheduler.service.js +0 -73
  285. package/dist/lib/modules/tournament/notification/notification.scheduler.service.js.map +0 -1
  286. package/dist/types/events/event-initializations.d.ts +0 -2
  287. package/dist/types/events/event-initializations.d.ts.map +0 -1
  288. package/dist/types/modules/spend-to-get-history/routers/index.d.ts +0 -2
  289. package/dist/types/modules/spend-to-get-history/routers/index.d.ts.map +0 -1
  290. package/dist/types/modules/spend-to-get-history/services/index.d.ts +0 -2
  291. package/dist/types/modules/spend-to-get-history/services/index.d.ts.map +0 -1
  292. package/dist/types/modules/spend-to-get-history/services/spend-to-get-history.service.d.ts +0 -56
  293. package/dist/types/modules/spend-to-get-history/services/spend-to-get-history.service.d.ts.map +0 -1
  294. package/dist/types/modules/spend-to-get-history/validations/index.d.ts +0 -2
  295. package/dist/types/modules/spend-to-get-history/validations/index.d.ts.map +0 -1
  296. package/dist/types/modules/spend-to-get-history/validations/spend-to-get-history.validation.d.ts +0 -241
  297. package/dist/types/modules/spend-to-get-history/validations/spend-to-get-history.validation.d.ts.map +0 -1
  298. package/dist/types/modules/tournament/config/tournament-config.validation.d.ts +0 -201
  299. package/dist/types/modules/tournament/config/tournament-config.validation.d.ts.map +0 -1
  300. package/dist/types/modules/tournament/match/events/match-ended.consumer.d.ts +0 -2
  301. package/dist/types/modules/tournament/match/events/match-ended.consumer.d.ts.map +0 -1
  302. package/dist/types/modules/tournament/match/events/match-ended.event.d.ts +0 -14
  303. package/dist/types/modules/tournament/match/events/match-ended.event.d.ts.map +0 -1
  304. package/dist/types/modules/tournament/notification/jobs/notification.producer.d.ts +0 -10
  305. package/dist/types/modules/tournament/notification/jobs/notification.producer.d.ts.map +0 -1
  306. package/dist/types/modules/tournament/notification/jobs/notification.worker.d.ts +0 -9
  307. package/dist/types/modules/tournament/notification/jobs/notification.worker.d.ts.map +0 -1
  308. package/dist/types/modules/tournament/notification/notification.schedule.config.d.ts +0 -10
  309. package/dist/types/modules/tournament/notification/notification.schedule.config.d.ts.map +0 -1
  310. package/dist/types/modules/tournament/notification/notification.scheduler.service.d.ts +0 -10
  311. package/dist/types/modules/tournament/notification/notification.scheduler.service.d.ts.map +0 -1
@@ -53,6 +53,7 @@ const limited_time_offer_participant_repository_1 = require("../../../limited-ti
53
53
  const limited_time_offer_participant_builder_1 = require("../../../limited-time-offer/participant/limited-time-offer-participant.builder");
54
54
  const limited_time_offer_campaign_session_service_1 = require("../../../limited-time-offer/session/limited-time-offer-campaign-session.service");
55
55
  const limited_time_offer_campaign_builder_1 = require("../limited-time-offer-campaign.builder");
56
+ const feature_flags_1 = require("../../../../utility/feature-flags");
56
57
  let LtoCampaignLifecycleService = class LtoCampaignLifecycleService {
57
58
  repository;
58
59
  scheduler;
@@ -73,7 +74,7 @@ let LtoCampaignLifecycleService = class LtoCampaignLifecycleService {
73
74
  const campaign = await this.repository.findById(campaignId);
74
75
  if (!campaign)
75
76
  throw (0, error_common_1.notFoundError)('Campaign not found');
76
- const isRecurring = (campaign.repeatDays ?? []).length > 0;
77
+ const isRecurring = (await (0, feature_flags_1.isLtoScheduleEnabled)()) && (campaign.repeatDays ?? []).length > 0;
77
78
  if (isRecurring) {
78
79
  await this.expireRecurring(campaign);
79
80
  }
@@ -91,7 +92,9 @@ let LtoCampaignLifecycleService = class LtoCampaignLifecycleService {
91
92
  const campaign = await this.repository.findById(campaignId);
92
93
  if (!campaign)
93
94
  throw (0, error_common_1.notFoundError)('Campaign not found');
94
- if ((campaign.repeatDays ?? []).length > 0 && campaign.status === enum_1.LimitedTimeOfferCampaignStatus.ACTIVE) {
95
+ if ((await (0, feature_flags_1.isLtoScheduleEnabled)()) &&
96
+ (campaign.repeatDays ?? []).length > 0 &&
97
+ campaign.status === enum_1.LimitedTimeOfferCampaignStatus.ACTIVE) {
95
98
  const shopCount = await this.participantRepository.countNonWithdrawnByCampaign(campaign._id);
96
99
  await this.sessionService.logSession(campaign, shopCount);
97
100
  }
@@ -100,6 +103,8 @@ let LtoCampaignLifecycleService = class LtoCampaignLifecycleService {
100
103
  }
101
104
  async revertParticipantEffects(campaignId) {
102
105
  await this.marketingService.removeAllCampaignMarketings(campaignId);
106
+ if (!(await (0, feature_flags_1.isLtoScheduleEnabled)()))
107
+ return;
103
108
  const pausedMarketingIds = await this.participantRepository.findPausedMarketingIdsByCampaign(campaignId);
104
109
  await this.marketingService.resumeMarketings(pausedMarketingIds);
105
110
  const participants = await this.participantRepository.findAllActiveByCampaign(campaignId);
@@ -1 +1 @@
1
- {"version":3,"file":"limited-time-offer-campaign-lifecycle.service.js","sourceRoot":"/","sources":["modules/limited-time-offer/campaign/services/limited-time-offer-campaign-lifecycle.service.ts"],"names":[],"mappings":"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","sourcesContent":["import Container, {Service} from 'typedi';\nimport {DocumentType, mongoose} from '@typegoose/typegoose';\nimport {LimitedTimeOfferCampaign} from '@lyxa.ai/core/dist/libraries/mongo/models';\nimport {LimitedTimeOfferCampaignStatus} from '@lyxa.ai/core/dist/utilities/enum';\nimport {notFoundError} from '@lyxa.ai/core/dist/utilities/error-common';\nimport {LtoCampaignRepository} from '@modules/limited-time-offer/campaign/limited-time-offer-campaign.repository';\nimport {LtoCampaignSchedulerService} from './limited-time-offer-campaign-scheduler.service';\nimport {\n LtoParticipantMarketingService\n} from '@modules/limited-time-offer/participant/services/limited-time-offer-participant-marketing.service';\nimport {\n LtoParticipantRepository\n} from '@modules/limited-time-offer/participant/limited-time-offer-participant.repository';\nimport {\n LtoParticipantQueryBuilder\n} from '@modules/limited-time-offer/participant/limited-time-offer-participant.builder';\nimport {\n LtoCampaignSessionService\n} from '@modules/limited-time-offer/session/limited-time-offer-campaign-session.service';\nimport {nextOccurrenceDate} from '../limited-time-offer-campaign.builder';\n\n@Service()\nexport class LtoCampaignLifecycleService {\n private repository: LtoCampaignRepository;\n private scheduler: LtoCampaignSchedulerService;\n private participantRepository: LtoParticipantRepository;\n private marketingService: LtoParticipantMarketingService;\n private sessionService: LtoCampaignSessionService;\n\n constructor() {\n this.repository = Container.get(LtoCampaignRepository);\n this.scheduler = Container.get(LtoCampaignSchedulerService);\n this.participantRepository = Container.get(LtoParticipantRepository);\n this.marketingService = Container.get(LtoParticipantMarketingService);\n this.sessionService = Container.get(LtoCampaignSessionService);\n }\n\n public async activateCampaign(campaignId: mongoose.Types.ObjectId): Promise<void> {\n await this.repository.setStatus(campaignId, LimitedTimeOfferCampaignStatus.ACTIVE);\n }\n\n // Returns whether the ended campaign was recurring (a fresh scheduled occurrence was spawned).\n public async expireCampaign(campaignId: mongoose.Types.ObjectId): Promise<boolean> {\n const campaign = await this.repository.findById(campaignId);\n if (!campaign) throw notFoundError('Campaign not found');\n\n const isRecurring = (campaign.repeatDays ?? []).length > 0;\n if (isRecurring) {\n await this.expireRecurring(campaign);\n } else {\n await this.repository.setStatus(campaignId, LimitedTimeOfferCampaignStatus.EXPIRED, true);\n }\n\n await this.revertParticipantEffects(campaignId);\n return isRecurring;\n }\n\n // Undoes live-campaign effects when postponed back to SCHEDULED: same participants, same campaign\n // doc, no cloning. Reuses the same revert logic cancel/expire rely on, then clears the participants'\n // stale marketing/pause snapshots — safe to skip for cancel/expire since those either end the\n // participant's lifecycle or clone into fresh docs that already omit these fields.\n public async demoteToScheduled(campaignId: mongoose.Types.ObjectId): Promise<void> {\n await this.revertParticipantEffects(campaignId);\n await this.participantRepository.clearLiveEffects(campaignId);\n }\n\n public async cancelCampaign(campaignId: mongoose.Types.ObjectId): Promise<void> {\n const campaign = await this.repository.findById(campaignId);\n if (!campaign) throw notFoundError('Campaign not found');\n\n // Deleting a live recurring session logs that day's session before archiving the campaign.\n if ((campaign.repeatDays ?? []).length > 0 && campaign.status === LimitedTimeOfferCampaignStatus.ACTIVE) {\n const shopCount = await this.participantRepository.countNonWithdrawnByCampaign(campaign._id);\n await this.sessionService.logSession(campaign, shopCount);\n }\n\n await this.repository.setStatus(campaignId, LimitedTimeOfferCampaignStatus.CANCELLED, true);\n await this.revertParticipantEffects(campaignId);\n }\n\n // Undoes everything the campaign imposed on its participant shops: deletes the LTO discounts,\n // resumes the shops' own paused discounts, and restores each shop's saved order capacity. Runs on\n // every end-of-campaign path (scheduled expiry, admin immediate-expiry, and cancel) so the shops\n // are always reset — for a recurring campaign the next occurrence re-applies them at its activation.\n private async revertParticipantEffects(campaignId: mongoose.Types.ObjectId): Promise<void> {\n await this.marketingService.removeAllCampaignMarketings(campaignId);\n\n const pausedMarketingIds = await this.participantRepository.findPausedMarketingIdsByCampaign(campaignId);\n await this.marketingService.resumeMarketings(pausedMarketingIds);\n\n const participants = await this.participantRepository.findAllActiveByCampaign(campaignId);\n for (const participant of participants) {\n await this.participantRepository.restoreShopOrderCapacity(\n participant.shop as mongoose.Types.ObjectId,\n participant.pausedOrderCapacity,\n participant.pausedOrderCapacityEnabled\n );\n }\n }\n\n private async expireRecurring(campaign: DocumentType<LimitedTimeOfferCampaign>): Promise<void> {\n const shopCount = await this.participantRepository.countNonWithdrawnByCampaign(campaign._id);\n await this.sessionService.logSession(campaign, shopCount);\n\n await this.repository.setStatus(campaign._id, LimitedTimeOfferCampaignStatus.EXPIRED, true);\n\n const {startDate, endDate} = nextOccurrenceDate(campaign.repeatDays, campaign.startDate, campaign.endDate);\n const nextCampaign = await this.createNextOccurrence(campaign, startDate, endDate);\n await this.cloneParticipants(campaign._id, nextCampaign._id);\n\n await this.scheduler.scheduleActivation(nextCampaign._id, startDate);\n await this.scheduler.scheduleExpiry(nextCampaign._id, endDate);\n }\n\n private async createNextOccurrence(\n campaign: DocumentType<LimitedTimeOfferCampaign>,\n startDate: Date,\n endDate: Date,\n ): Promise<DocumentType<LimitedTimeOfferCampaign>> {\n return this.repository.create({\n campaignNumber: await this.repository.nextCampaignNumber(),\n title: campaign.title,\n subTitle: campaign.subTitle,\n startDate,\n endDate,\n status: LimitedTimeOfferCampaignStatus.SCHEDULED,\n campaignType: campaign.campaignType,\n discountOptions: campaign.discountOptions,\n maxDiscountCaps: campaign.maxDiscountCaps,\n repeatDays: campaign.repeatDays,\n });\n }\n\n private async cloneParticipants(\n fromCampaignId: mongoose.Types.ObjectId,\n toCampaignId: mongoose.Types.ObjectId,\n ): Promise<void> {\n const participants = await this.participantRepository.findAllActiveByCampaign(fromCampaignId);\n for (const participant of participants) {\n await this.participantRepository.create(\n LtoParticipantQueryBuilder.buildCloneInput(toCampaignId, participant),\n );\n }\n }\n}\n\nexport const ltoCampaignLifecycleService = Container.get(LtoCampaignLifecycleService);\n"]}
1
+ {"version":3,"file":"limited-time-offer-campaign-lifecycle.service.js","sourceRoot":"/","sources":["modules/limited-time-offer/campaign/services/limited-time-offer-campaign-lifecycle.service.ts"],"names":[],"mappings":"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","sourcesContent":["import Container, {Service} from 'typedi';\nimport {DocumentType, mongoose} from '@typegoose/typegoose';\nimport {LimitedTimeOfferCampaign} from '@lyxa.ai/core/dist/libraries/mongo/models';\nimport {LimitedTimeOfferCampaignStatus} from '@lyxa.ai/core/dist/utilities/enum';\nimport {notFoundError} from '@lyxa.ai/core/dist/utilities/error-common';\nimport {LtoCampaignRepository} from '@modules/limited-time-offer/campaign/limited-time-offer-campaign.repository';\nimport {LtoCampaignSchedulerService} from './limited-time-offer-campaign-scheduler.service';\nimport {\n LtoParticipantMarketingService\n} from '@modules/limited-time-offer/participant/services/limited-time-offer-participant-marketing.service';\nimport {\n LtoParticipantRepository\n} from '@modules/limited-time-offer/participant/limited-time-offer-participant.repository';\nimport {\n LtoParticipantQueryBuilder\n} from '@modules/limited-time-offer/participant/limited-time-offer-participant.builder';\nimport {\n LtoCampaignSessionService\n} from '@modules/limited-time-offer/session/limited-time-offer-campaign-session.service';\nimport {nextOccurrenceDate} from '../limited-time-offer-campaign.builder';\nimport {isLtoScheduleEnabled} from '@utility/feature-flags';\n\n@Service()\nexport class LtoCampaignLifecycleService {\n private repository: LtoCampaignRepository;\n private scheduler: LtoCampaignSchedulerService;\n private participantRepository: LtoParticipantRepository;\n private marketingService: LtoParticipantMarketingService;\n private sessionService: LtoCampaignSessionService;\n\n constructor() {\n this.repository = Container.get(LtoCampaignRepository);\n this.scheduler = Container.get(LtoCampaignSchedulerService);\n this.participantRepository = Container.get(LtoParticipantRepository);\n this.marketingService = Container.get(LtoParticipantMarketingService);\n this.sessionService = Container.get(LtoCampaignSessionService);\n }\n\n public async activateCampaign(campaignId: mongoose.Types.ObjectId): Promise<void> {\n await this.repository.setStatus(campaignId, LimitedTimeOfferCampaignStatus.ACTIVE);\n }\n\n // Returns whether the ended campaign was recurring (a fresh scheduled occurrence was spawned).\n public async expireCampaign(campaignId: mongoose.Types.ObjectId): Promise<boolean> {\n const campaign = await this.repository.findById(campaignId);\n if (!campaign) throw notFoundError('Campaign not found');\n\n const isRecurring = (await isLtoScheduleEnabled()) && (campaign.repeatDays ?? []).length > 0;\n if (isRecurring) {\n await this.expireRecurring(campaign);\n } else {\n await this.repository.setStatus(campaignId, LimitedTimeOfferCampaignStatus.EXPIRED, true);\n }\n\n await this.revertParticipantEffects(campaignId);\n return isRecurring;\n }\n\n // Undoes live-campaign effects when postponed back to SCHEDULED: same participants, same campaign\n // doc, no cloning. Reuses the same revert logic cancel/expire rely on, then clears the participants'\n // stale marketing/pause snapshots — safe to skip for cancel/expire since those either end the\n // participant's lifecycle or clone into fresh docs that already omit these fields.\n public async demoteToScheduled(campaignId: mongoose.Types.ObjectId): Promise<void> {\n await this.revertParticipantEffects(campaignId);\n await this.participantRepository.clearLiveEffects(campaignId);\n }\n\n public async cancelCampaign(campaignId: mongoose.Types.ObjectId): Promise<void> {\n const campaign = await this.repository.findById(campaignId);\n if (!campaign) throw notFoundError('Campaign not found');\n\n // Deleting a live recurring session logs that day's session before archiving the campaign.\n if (\n (await isLtoScheduleEnabled()) &&\n (campaign.repeatDays ?? []).length > 0 &&\n campaign.status === LimitedTimeOfferCampaignStatus.ACTIVE\n ) {\n const shopCount = await this.participantRepository.countNonWithdrawnByCampaign(campaign._id);\n await this.sessionService.logSession(campaign, shopCount);\n }\n\n await this.repository.setStatus(campaignId, LimitedTimeOfferCampaignStatus.CANCELLED, true);\n await this.revertParticipantEffects(campaignId);\n }\n\n // Undoes everything the campaign imposed on its participant shops: deletes the LTO discounts,\n // resumes the shops' own paused discounts, and restores each shop's saved order capacity. Runs on\n // every end-of-campaign path (scheduled expiry, admin immediate-expiry, and cancel) so the shops\n // are always reset — for a recurring campaign the next occurrence re-applies them at its activation.\n private async revertParticipantEffects(campaignId: mongoose.Types.ObjectId): Promise<void> {\n await this.marketingService.removeAllCampaignMarketings(campaignId);\n\n if (!(await isLtoScheduleEnabled())) return;\n\n const pausedMarketingIds = await this.participantRepository.findPausedMarketingIdsByCampaign(campaignId);\n await this.marketingService.resumeMarketings(pausedMarketingIds);\n\n const participants = await this.participantRepository.findAllActiveByCampaign(campaignId);\n for (const participant of participants) {\n await this.participantRepository.restoreShopOrderCapacity(\n participant.shop as mongoose.Types.ObjectId,\n participant.pausedOrderCapacity,\n participant.pausedOrderCapacityEnabled\n );\n }\n }\n\n private async expireRecurring(campaign: DocumentType<LimitedTimeOfferCampaign>): Promise<void> {\n const shopCount = await this.participantRepository.countNonWithdrawnByCampaign(campaign._id);\n await this.sessionService.logSession(campaign, shopCount);\n\n await this.repository.setStatus(campaign._id, LimitedTimeOfferCampaignStatus.EXPIRED, true);\n\n const {startDate, endDate} = nextOccurrenceDate(campaign.repeatDays, campaign.startDate, campaign.endDate);\n const nextCampaign = await this.createNextOccurrence(campaign, startDate, endDate);\n await this.cloneParticipants(campaign._id, nextCampaign._id);\n\n await this.scheduler.scheduleActivation(nextCampaign._id, startDate);\n await this.scheduler.scheduleExpiry(nextCampaign._id, endDate);\n }\n\n private async createNextOccurrence(\n campaign: DocumentType<LimitedTimeOfferCampaign>,\n startDate: Date,\n endDate: Date,\n ): Promise<DocumentType<LimitedTimeOfferCampaign>> {\n return this.repository.create({\n campaignNumber: await this.repository.nextCampaignNumber(),\n title: campaign.title,\n subTitle: campaign.subTitle,\n startDate,\n endDate,\n status: LimitedTimeOfferCampaignStatus.SCHEDULED,\n campaignType: campaign.campaignType,\n discountOptions: campaign.discountOptions,\n maxDiscountCaps: campaign.maxDiscountCaps,\n repeatDays: campaign.repeatDays,\n });\n }\n\n private async cloneParticipants(\n fromCampaignId: mongoose.Types.ObjectId,\n toCampaignId: mongoose.Types.ObjectId,\n ): Promise<void> {\n const participants = await this.participantRepository.findAllActiveByCampaign(fromCampaignId);\n for (const participant of participants) {\n await this.participantRepository.create(\n LtoParticipantQueryBuilder.buildCloneInput(toCampaignId, participant),\n );\n }\n }\n}\n\nexport const ltoCampaignLifecycleService = Container.get(LtoCampaignLifecycleService);\n"]}
@@ -4,6 +4,7 @@ export declare class LtoCampaignSchedulerService {
4
4
  constructor();
5
5
  scheduleActivation(campaignId: mongoose.Types.ObjectId, startDate: Date): Promise<void>;
6
6
  scheduleExpiry(campaignId: mongoose.Types.ObjectId, endDate: Date): Promise<void>;
7
+ private resolveJobDelay;
7
8
  cancelJobs(campaignId: mongoose.Types.ObjectId): Promise<void>;
8
9
  rescheduleOrphanedRecurring(): Promise<void>;
9
10
  private activationJobId;
@@ -1 +1 @@
1
- {"version":3,"file":"limited-time-offer-campaign-scheduler.service.d.ts","sourceRoot":"/","sources":["modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAKhD,qBACa,2BAA2B;IACpC,OAAO,CAAC,UAAU,CAAwB;;IAM7B,kBAAkB,CAAC,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAWvF,cAAc,CAAC,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAWjF,UAAU,CAAC,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAK9D,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC;IAwBzD,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,WAAW;CAGtB"}
1
+ {"version":3,"file":"limited-time-offer-campaign-scheduler.service.d.ts","sourceRoot":"/","sources":["modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAMhD,qBACa,2BAA2B;IACpC,OAAO,CAAC,UAAU,CAAwB;;IAM7B,kBAAkB,CAAC,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAWvF,cAAc,CAAC,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;YAahF,eAAe;IAMhB,UAAU,CAAC,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAK9D,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC;IAwBzD,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,WAAW;CAGtB"}
@@ -46,21 +46,32 @@ exports.LtoCampaignSchedulerService = void 0;
46
46
  const typedi_1 = __importStar(require("typedi"));
47
47
  const limited_time_offer_campaign_producer_1 = require("../../../limited-time-offer/campaign/jobs/limited-time-offer-campaign.producer");
48
48
  const limited_time_offer_campaign_repository_1 = require("../../../limited-time-offer/campaign/limited-time-offer-campaign.repository");
49
+ const feature_flags_1 = require("../../../../utility/feature-flags");
49
50
  let LtoCampaignSchedulerService = class LtoCampaignSchedulerService {
50
51
  repository;
51
52
  constructor() {
52
53
  this.repository = typedi_1.default.get(limited_time_offer_campaign_repository_1.LtoCampaignRepository);
53
54
  }
54
55
  async scheduleActivation(campaignId, startDate) {
55
- const delay = Math.max(0, startDate.getTime() - Date.now());
56
+ const delay = await this.resolveJobDelay(startDate.getTime());
57
+ if (delay === null)
58
+ return;
56
59
  await (0, limited_time_offer_campaign_producer_1.removeLtoCampaignJob)(this.activationJobId(campaignId));
57
60
  await (0, limited_time_offer_campaign_producer_1.addLtoCampaignJob)(limited_time_offer_campaign_producer_1.LtoCampaignJobName.ACTIVATE, { campaignId: campaignId.toString() }, { delay, jobId: this.activationJobId(campaignId), removeOnComplete: true });
58
61
  }
59
62
  async scheduleExpiry(campaignId, endDate) {
60
- const delay = Math.max(0, endDate.getTime() - Date.now());
63
+ const delay = await this.resolveJobDelay(endDate.getTime());
64
+ if (delay === null)
65
+ return;
61
66
  await (0, limited_time_offer_campaign_producer_1.removeLtoCampaignJob)(this.expiryJobId(campaignId));
62
67
  await (0, limited_time_offer_campaign_producer_1.addLtoCampaignJob)(limited_time_offer_campaign_producer_1.LtoCampaignJobName.EXPIRE, { campaignId: campaignId.toString() }, { delay, jobId: this.expiryJobId(campaignId), removeOnComplete: true });
63
68
  }
69
+ async resolveJobDelay(targetTime) {
70
+ const delay = targetTime - Date.now();
71
+ if (await (0, feature_flags_1.isLtoScheduleEnabled)())
72
+ return Math.max(0, delay);
73
+ return delay > 0 ? delay : null;
74
+ }
64
75
  async cancelJobs(campaignId) {
65
76
  await (0, limited_time_offer_campaign_producer_1.removeLtoCampaignJob)(this.activationJobId(campaignId));
66
77
  await (0, limited_time_offer_campaign_producer_1.removeLtoCampaignJob)(this.expiryJobId(campaignId));
@@ -1 +1 @@
1
- {"version":3,"file":"limited-time-offer-campaign-scheduler.service.js","sourceRoot":"/","sources":["modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.ts"],"names":[],"mappings":"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","sourcesContent":["import Container, { Service } from 'typedi';\nimport { mongoose } from '@typegoose/typegoose';\nimport { LimitedTimeOfferCampaignStatus } from '@lyxa.ai/core/dist/utilities/enum';\nimport { LtoCampaignJobName, addLtoCampaignJob, removeLtoCampaignJob, getLtoCampaignQueue } from '@modules/limited-time-offer/campaign/jobs/limited-time-offer-campaign.producer';\nimport { LtoCampaignRepository } from '@modules/limited-time-offer/campaign/limited-time-offer-campaign.repository';\n\n@Service()\nexport class LtoCampaignSchedulerService {\n private repository: LtoCampaignRepository;\n\n constructor() {\n this.repository = Container.get(LtoCampaignRepository);\n }\n\n public async scheduleActivation(campaignId: mongoose.Types.ObjectId, startDate: Date): Promise<void> {\n // ponytail: clamp to 0 so a start time that already passed (e.g. during downtime) fires immediately.\n const delay = Math.max(0, startDate.getTime() - Date.now());\n await removeLtoCampaignJob(this.activationJobId(campaignId));\n await addLtoCampaignJob(\n LtoCampaignJobName.ACTIVATE,\n { campaignId: campaignId.toString() },\n { delay, jobId: this.activationJobId(campaignId), removeOnComplete: true }\n );\n }\n\n public async scheduleExpiry(campaignId: mongoose.Types.ObjectId, endDate: Date): Promise<void> {\n // ponytail: clamp to 0 so an end time that already passed fires immediately (recovery -> recurrence).\n const delay = Math.max(0, endDate.getTime() - Date.now());\n await removeLtoCampaignJob(this.expiryJobId(campaignId));\n await addLtoCampaignJob(\n LtoCampaignJobName.EXPIRE,\n { campaignId: campaignId.toString() },\n { delay, jobId: this.expiryJobId(campaignId), removeOnComplete: true }\n );\n }\n\n public async cancelJobs(campaignId: mongoose.Types.ObjectId): Promise<void> {\n await removeLtoCampaignJob(this.activationJobId(campaignId));\n await removeLtoCampaignJob(this.expiryJobId(campaignId));\n }\n\n public async rescheduleOrphanedRecurring(): Promise<void> {\n const queue = getLtoCampaignQueue();\n const delayed = await queue.getDelayed();\n const existingJobIds = new Set(delayed.map(j => j.opts.jobId).filter(Boolean));\n\n const scheduled = await this.repository.findScheduledRecurring();\n for (const campaign of scheduled) {\n if (!existingJobIds.has(this.activationJobId(campaign._id))) {\n await this.scheduleActivation(campaign._id, campaign.startDate);\n }\n if (!existingJobIds.has(this.expiryJobId(campaign._id))) {\n await this.scheduleExpiry(campaign._id, campaign.endDate);\n }\n }\n\n // An ACTIVE recurring campaign whose expiry job was lost would otherwise hang forever.\n const active = await this.repository.findActiveRecurring();\n for (const campaign of active) {\n if (!existingJobIds.has(this.expiryJobId(campaign._id))) {\n await this.scheduleExpiry(campaign._id, campaign.endDate);\n }\n }\n }\n\n private activationJobId(campaignId: mongoose.Types.ObjectId): string {\n return `lto-activate-${campaignId.toString()}`;\n }\n\n private expiryJobId(campaignId: mongoose.Types.ObjectId): string {\n return `lto-expire-${campaignId.toString()}`;\n }\n}\n"]}
1
+ {"version":3,"file":"limited-time-offer-campaign-scheduler.service.js","sourceRoot":"/","sources":["modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.ts"],"names":[],"mappings":"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","sourcesContent":["import Container, { Service } from 'typedi';\nimport { mongoose } from '@typegoose/typegoose';\nimport { LimitedTimeOfferCampaignStatus } from '@lyxa.ai/core/dist/utilities/enum';\nimport { LtoCampaignJobName, addLtoCampaignJob, removeLtoCampaignJob, getLtoCampaignQueue } from '@modules/limited-time-offer/campaign/jobs/limited-time-offer-campaign.producer';\nimport { LtoCampaignRepository } from '@modules/limited-time-offer/campaign/limited-time-offer-campaign.repository';\nimport { isLtoScheduleEnabled } from '@utility/feature-flags';\n\n@Service()\nexport class LtoCampaignSchedulerService {\n private repository: LtoCampaignRepository;\n\n constructor() {\n this.repository = Container.get(LtoCampaignRepository);\n }\n\n public async scheduleActivation(campaignId: mongoose.Types.ObjectId, startDate: Date): Promise<void> {\n const delay = await this.resolveJobDelay(startDate.getTime());\n if (delay === null) return;\n await removeLtoCampaignJob(this.activationJobId(campaignId));\n await addLtoCampaignJob(\n LtoCampaignJobName.ACTIVATE,\n { campaignId: campaignId.toString() },\n { delay, jobId: this.activationJobId(campaignId), removeOnComplete: true }\n );\n }\n\n public async scheduleExpiry(campaignId: mongoose.Types.ObjectId, endDate: Date): Promise<void> {\n const delay = await this.resolveJobDelay(endDate.getTime());\n if (delay === null) return;\n await removeLtoCampaignJob(this.expiryJobId(campaignId));\n await addLtoCampaignJob(\n LtoCampaignJobName.EXPIRE,\n { campaignId: campaignId.toString() },\n { delay, jobId: this.expiryJobId(campaignId), removeOnComplete: true }\n );\n }\n\n // Flag on: clamp to 0 so a start/end time that already passed (e.g. during downtime) fires\n // immediately. Flag off: reproduce master by skipping any job whose time has already passed.\n private async resolveJobDelay(targetTime: number): Promise<number | null> {\n const delay = targetTime - Date.now();\n if (await isLtoScheduleEnabled()) return Math.max(0, delay);\n return delay > 0 ? delay : null;\n }\n\n public async cancelJobs(campaignId: mongoose.Types.ObjectId): Promise<void> {\n await removeLtoCampaignJob(this.activationJobId(campaignId));\n await removeLtoCampaignJob(this.expiryJobId(campaignId));\n }\n\n public async rescheduleOrphanedRecurring(): Promise<void> {\n const queue = getLtoCampaignQueue();\n const delayed = await queue.getDelayed();\n const existingJobIds = new Set(delayed.map(j => j.opts.jobId).filter(Boolean));\n\n const scheduled = await this.repository.findScheduledRecurring();\n for (const campaign of scheduled) {\n if (!existingJobIds.has(this.activationJobId(campaign._id))) {\n await this.scheduleActivation(campaign._id, campaign.startDate);\n }\n if (!existingJobIds.has(this.expiryJobId(campaign._id))) {\n await this.scheduleExpiry(campaign._id, campaign.endDate);\n }\n }\n\n // An ACTIVE recurring campaign whose expiry job was lost would otherwise hang forever.\n const active = await this.repository.findActiveRecurring();\n for (const campaign of active) {\n if (!existingJobIds.has(this.expiryJobId(campaign._id))) {\n await this.scheduleExpiry(campaign._id, campaign.endDate);\n }\n }\n }\n\n private activationJobId(campaignId: mongoose.Types.ObjectId): string {\n return `lto-activate-${campaignId.toString()}`;\n }\n\n private expiryJobId(campaignId: mongoose.Types.ObjectId): string {\n return `lto-expire-${campaignId.toString()}`;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"limited-time-offer-campaign.service.d.ts","sourceRoot":"/","sources":["modules/limited-time-offer/campaign/services/limited-time-offer-campaign.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,YAAY,EAAE,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAC,wBAAwB,IAAI,KAAK,EAAC,MAAM,2CAA2C,CAAC;AAC5F,OAAO,EAAC,8BAA8B,EAAgB,MAAM,mCAAmC,CAAC;AAEhG,OAAO,EACH,oBAAoB,EACpB,wBAAwB,EACxB,oBAAoB,EACpB,oBAAoB,EACvB,MAAM,2CAA2C,CAAC;AASnD,qBACa,kBAAkB;IAC3B,OAAO,CAAC,UAAU,CAAwB;IAC1C,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,aAAa,CAAgC;;IASxC,MAAM,CAAC,GAAG,EAAE,oBAAoB;IAyB7C,OAAO,CAAC,oBAAoB;IAMf,UAAU;IAIV,SAAS,IAAI,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAajD,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ;IAM3C,UAAU,CAAC,GAAG,EAAE,wBAAwB;;;;;;;;;;;;;;;;IAaxC,MAAM,CAAC,GAAG,EAAE,oBAAoB;IAsChC,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IASvE,OAAO,CAAC,mBAAmB;IAY3B,OAAO,CAAC,uBAAuB;YAIjB,oBAAoB;YASpB,wBAAwB;YAiBxB,uBAAuB;IAMrC,OAAO,CAAC,cAAc;YAMR,kBAAkB;CAWnC;AAED,eAAO,MAAM,kBAAkB,oBAAoC,CAAC"}
1
+ {"version":3,"file":"limited-time-offer-campaign.service.d.ts","sourceRoot":"/","sources":["modules/limited-time-offer/campaign/services/limited-time-offer-campaign.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,YAAY,EAAE,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAC,wBAAwB,IAAI,KAAK,EAAC,MAAM,2CAA2C,CAAC;AAC5F,OAAO,EAAC,8BAA8B,EAAgB,MAAM,mCAAmC,CAAC;AAEhG,OAAO,EACH,oBAAoB,EACpB,wBAAwB,EACxB,oBAAoB,EACpB,oBAAoB,EACvB,MAAM,2CAA2C,CAAC;AAUnD,qBACa,kBAAkB;IAC3B,OAAO,CAAC,UAAU,CAAwB;IAC1C,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,aAAa,CAAgC;;IASxC,MAAM,CAAC,GAAG,EAAE,oBAAoB;IAyB7C,OAAO,CAAC,oBAAoB;IAMf,UAAU;IAIV,SAAS,IAAI,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAajD,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ;IAM3C,UAAU,CAAC,GAAG,EAAE,wBAAwB;;;;;;;;;;;;;;;;IAaxC,MAAM,CAAC,GAAG,EAAE,oBAAoB;IA6ChC,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IASvE,OAAO,CAAC,mBAAmB;IAY3B,OAAO,CAAC,uBAAuB;YAIjB,oBAAoB;YASpB,wBAAwB;YAiBxB,uBAAuB;IAMrC,OAAO,CAAC,cAAc;YAMR,kBAAkB;CAWnC;AAED,eAAO,MAAM,kBAAkB,oBAAoC,CAAC"}
@@ -51,6 +51,7 @@ const limited_time_offer_campaign_scheduler_service_1 = require("./limited-time-
51
51
  const limited_time_offer_campaign_repository_1 = require("../../../limited-time-offer/campaign/limited-time-offer-campaign.repository");
52
52
  const limited_time_offer_campaign_builder_1 = require("../../../limited-time-offer/campaign/limited-time-offer-campaign.builder");
53
53
  const limited_time_offer_config_service_1 = require("../../../limited-time-offer/config/limited-time-offer-config.service");
54
+ const feature_flags_1 = require("../../../../utility/feature-flags");
54
55
  const ACTIVE_STATUSES = [enum_1.LimitedTimeOfferCampaignStatus.SCHEDULED, enum_1.LimitedTimeOfferCampaignStatus.ACTIVE];
55
56
  let LtoCampaignService = class LtoCampaignService {
56
57
  repository;
@@ -128,8 +129,11 @@ let LtoCampaignService = class LtoCampaignService {
128
129
  if (this.shouldExpireImmediately(campaign.status, dto.endDate)) {
129
130
  return this.applyImmediateExpiry(dto._id, updates);
130
131
  }
132
+ const ltoScheduleEnabled = await (0, feature_flags_1.isLtoScheduleEnabled)();
131
133
  const repeatDays = (updates.repeatDays ?? campaign.repeatDays ?? []);
132
- if (updates.status === enum_1.LimitedTimeOfferCampaignStatus.SCHEDULED && repeatDays.length > 0) {
134
+ if (ltoScheduleEnabled &&
135
+ updates.status === enum_1.LimitedTimeOfferCampaignStatus.SCHEDULED &&
136
+ repeatDays.length > 0) {
133
137
  const occurrence = (0, limited_time_offer_campaign_builder_1.nextOccurrenceDate)(repeatDays, dto.startDate, dto.endDate);
134
138
  updates.startDate = occurrence.startDate;
135
139
  updates.endDate = occurrence.endDate;
@@ -137,7 +141,8 @@ let LtoCampaignService = class LtoCampaignService {
137
141
  const result = await this.repository.updateById(dto._id, updates);
138
142
  if (!result)
139
143
  throw (0, error_common_1.notFoundError)('Campaign not found after update');
140
- if (campaign.status === enum_1.LimitedTimeOfferCampaignStatus.ACTIVE &&
144
+ if (ltoScheduleEnabled &&
145
+ campaign.status === enum_1.LimitedTimeOfferCampaignStatus.ACTIVE &&
141
146
  result.status === enum_1.LimitedTimeOfferCampaignStatus.SCHEDULED) {
142
147
  await this.lifecycle.demoteToScheduled(dto._id);
143
148
  }
@@ -1 +1 @@
1
- {"version":3,"file":"limited-time-offer-campaign.service.js","sourceRoot":"/","sources":["modules/limited-time-offer/campaign/services/limited-time-offer-campaign.service.ts"],"names":[],"mappings":"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","sourcesContent":["import Container, {Service} from 'typedi';\nimport {DocumentType, mongoose} from '@typegoose/typegoose';\nimport {LimitedTimeOfferCampaign as Model} from '@lyxa.ai/core/dist/libraries/mongo/models';\nimport {LimitedTimeOfferCampaignStatus, MarketingType} from '@lyxa.ai/core/dist/utilities/enum';\nimport {badRequestError, conflictError, notFoundError} from '@lyxa.ai/core/dist/utilities/error-common';\nimport {\n CreateLtoCampaignDTO,\n GetLtoCampaignHistoryDTO,\n LtoActiveCampaignDTO,\n UpdateLtoCampaignDTO,\n} from '../limited-time-offer-campaign.validation';\nimport {LtoCampaignLifecycleService} from './limited-time-offer-campaign-lifecycle.service';\nimport {LtoCampaignSchedulerService} from './limited-time-offer-campaign-scheduler.service';\nimport {LtoCampaignRepository} from '@modules/limited-time-offer/campaign/limited-time-offer-campaign.repository';\nimport {LtoCampaignQueryBuilder, nextOccurrenceDate} from '@modules/limited-time-offer/campaign/limited-time-offer-campaign.builder';\nimport {LimitedTimeOfferConfigService} from '@modules/limited-time-offer/config/limited-time-offer-config.service';\n\nconst ACTIVE_STATUSES = [LimitedTimeOfferCampaignStatus.SCHEDULED, LimitedTimeOfferCampaignStatus.ACTIVE];\n\n@Service()\nexport class LtoCampaignService {\n private repository: LtoCampaignRepository;\n private scheduler: LtoCampaignSchedulerService;\n private lifecycle: LtoCampaignLifecycleService;\n private configService: LimitedTimeOfferConfigService;\n\n constructor() {\n this.repository = Container.get(LtoCampaignRepository);\n this.scheduler = Container.get(LtoCampaignSchedulerService);\n this.lifecycle = Container.get(LtoCampaignLifecycleService);\n this.configService = Container.get(LimitedTimeOfferConfigService);\n }\n\n public async create(dto: CreateLtoCampaignDTO) {\n await this.assertNoCampaignRunning();\n\n const config = await this.loadConfigSnapshot();\n\n const status = this.deriveCampaignStatus(dto.startDate);\n const campaign = await this.repository.create(\n LtoCampaignQueryBuilder.buildCreateInput({\n dto,\n status,\n campaignNumber: await this.repository.nextCampaignNumber(),\n config,\n startDate: dto.startDate,\n endDate: dto.endDate,\n })\n );\n\n if (status === LimitedTimeOfferCampaignStatus.SCHEDULED) {\n await this.scheduler.scheduleActivation(campaign._id, dto.startDate);\n }\n await this.scheduler.scheduleExpiry(campaign._id, dto.endDate);\n\n return campaign;\n }\n\n private deriveCampaignStatus(startDate: Date) {\n return startDate <= new Date()\n ? LimitedTimeOfferCampaignStatus.ACTIVE\n : LimitedTimeOfferCampaignStatus.SCHEDULED;\n }\n\n public async getCurrent() {\n return this.repository.findCurrent();\n }\n\n public async getActive(): Promise<LtoActiveCampaignDTO | null> {\n const campaign = await this.repository.findActive();\n if (!campaign) return null;\n\n return {\n _id: campaign._id,\n title: campaign.title,\n subtitle: campaign.subTitle,\n startTime: campaign.startDate,\n endTime: campaign.endDate,\n };\n }\n\n public async getById(campaignId: mongoose.Types.ObjectId) {\n const campaign = await this.repository.findById(campaignId);\n if (!campaign) throw notFoundError('Campaign not found');\n return campaign;\n }\n\n public async getHistory(dto: GetLtoCampaignHistoryDTO) {\n const {documents, total} = await this.repository.findHistory(dto);\n return {\n documents,\n metadata: {\n page: dto.page,\n size: dto.size,\n totalElements: total,\n totalPages: Math.ceil(total / dto.size),\n },\n };\n }\n\n public async update(dto: UpdateLtoCampaignDTO) {\n const campaign = await this.repository.findById(dto._id);\n if (!campaign) throw notFoundError('Campaign not found');\n\n this.assertUpdateAllowed(campaign, dto);\n\n const updates = LtoCampaignQueryBuilder.buildUpdateInput(campaign, dto);\n\n if (this.shouldExpireImmediately(campaign.status, dto.endDate)) {\n return this.applyImmediateExpiry(dto._id, updates);\n }\n\n // For a scheduled recurring campaign, snap the schedule to the next selected weekday so the\n // selected days stay authoritative — an active session keeps the dto dates (takes effect now).\n const repeatDays = (updates.repeatDays ?? campaign.repeatDays ?? []) as number[];\n if (updates.status === LimitedTimeOfferCampaignStatus.SCHEDULED && repeatDays.length > 0) {\n const occurrence = nextOccurrenceDate(repeatDays, dto.startDate, dto.endDate);\n updates.startDate = occurrence.startDate;\n updates.endDate = occurrence.endDate;\n }\n\n const result = await this.repository.updateById(dto._id, updates);\n if (!result) throw notFoundError('Campaign not found after update');\n\n // Postponing a live campaign back to SCHEDULED must undo what activation applied — otherwise\n // the shops' own discounts stay paused until the campaign eventually cancels or expires.\n if (\n campaign.status === LimitedTimeOfferCampaignStatus.ACTIVE &&\n result.status === LimitedTimeOfferCampaignStatus.SCHEDULED\n ) {\n await this.lifecycle.demoteToScheduled(dto._id);\n }\n\n await this.rescheduleIfDatesChanged(result, campaign);\n\n return result;\n }\n\n public async cancel(campaignId: mongoose.Types.ObjectId): Promise<void> {\n const campaign = await this.repository.findById(campaignId);\n if (!campaign) throw notFoundError('Campaign not found');\n\n this.assertEditable(campaign.status);\n await this.scheduler.cancelJobs(campaignId);\n await this.lifecycle.cancelCampaign(campaignId);\n }\n\n private assertUpdateAllowed(campaign: DocumentType<Model>, dto: UpdateLtoCampaignDTO): void {\n this.assertEditable(campaign.status);\n\n if (campaign.status === LimitedTimeOfferCampaignStatus.ACTIVE && !dto.confirmActive) {\n throw badRequestError('Set confirmActive=true to confirm editing a live campaign.');\n }\n\n if (dto.startDate < new Date() && campaign.status === LimitedTimeOfferCampaignStatus.SCHEDULED) {\n throw badRequestError('Start date cannot be in the past.');\n }\n }\n\n private shouldExpireImmediately(status: LimitedTimeOfferCampaignStatus, endDate: Date): boolean {\n return status === LimitedTimeOfferCampaignStatus.ACTIVE && endDate <= new Date();\n }\n\n private async applyImmediateExpiry(campaignId: mongoose.Types.ObjectId, updates: object) {\n await this.scheduler.cancelJobs(campaignId);\n await this.repository.updateById(campaignId, updates);\n await this.lifecycle.expireCampaign(campaignId);\n const result = await this.repository.findById(campaignId);\n if (!result) throw notFoundError('Campaign not found after expiry');\n return result;\n }\n\n private async rescheduleIfDatesChanged(\n result: DocumentType<Model>,\n original: DocumentType<Model>\n ): Promise<void> {\n const datesChanged =\n result.startDate!.getTime() !== original.startDate!.getTime() ||\n result.endDate!.getTime() !== original.endDate!.getTime();\n\n if (!datesChanged) return;\n\n await this.scheduler.cancelJobs(result._id);\n if (result.status === LimitedTimeOfferCampaignStatus.SCHEDULED) {\n await this.scheduler.scheduleActivation(result._id, result.startDate!);\n }\n await this.scheduler.scheduleExpiry(result._id, result.endDate!);\n }\n\n private async assertNoCampaignRunning(): Promise<void> {\n if (await this.repository.hasActiveCampaign()) {\n throw conflictError('A campaign is already scheduled or active. Delete it before creating a new one.');\n }\n }\n\n private assertEditable(status: LimitedTimeOfferCampaignStatus): void {\n if (!ACTIVE_STATUSES.includes(status)) {\n throw badRequestError('Only SCHEDULED or ACTIVE campaigns can be modified.');\n }\n }\n\n private async loadConfigSnapshot() {\n const config = await this.configService.getByType(MarketingType.DISCOUNT).catch(() => {\n throw badRequestError('Global config is incomplete. Set discount options and max caps first.');\n });\n\n if (config.discountOptions.length === 0 || config.maxDiscountCaps.length === 0) {\n throw badRequestError('Global config is incomplete. Set discount options and max caps first.');\n }\n\n return config;\n }\n}\n\nexport const ltoCampaignService = Container.get(LtoCampaignService);\n"]}
1
+ {"version":3,"file":"limited-time-offer-campaign.service.js","sourceRoot":"/","sources":["modules/limited-time-offer/campaign/services/limited-time-offer-campaign.service.ts"],"names":[],"mappings":"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","sourcesContent":["import Container, {Service} from 'typedi';\nimport {DocumentType, mongoose} from '@typegoose/typegoose';\nimport {LimitedTimeOfferCampaign as Model} from '@lyxa.ai/core/dist/libraries/mongo/models';\nimport {LimitedTimeOfferCampaignStatus, MarketingType} from '@lyxa.ai/core/dist/utilities/enum';\nimport {badRequestError, conflictError, notFoundError} from '@lyxa.ai/core/dist/utilities/error-common';\nimport {\n CreateLtoCampaignDTO,\n GetLtoCampaignHistoryDTO,\n LtoActiveCampaignDTO,\n UpdateLtoCampaignDTO,\n} from '../limited-time-offer-campaign.validation';\nimport {LtoCampaignLifecycleService} from './limited-time-offer-campaign-lifecycle.service';\nimport {LtoCampaignSchedulerService} from './limited-time-offer-campaign-scheduler.service';\nimport {LtoCampaignRepository} from '@modules/limited-time-offer/campaign/limited-time-offer-campaign.repository';\nimport {LtoCampaignQueryBuilder, nextOccurrenceDate} from '@modules/limited-time-offer/campaign/limited-time-offer-campaign.builder';\nimport {LimitedTimeOfferConfigService} from '@modules/limited-time-offer/config/limited-time-offer-config.service';\nimport {isLtoScheduleEnabled} from '@utility/feature-flags';\n\nconst ACTIVE_STATUSES = [LimitedTimeOfferCampaignStatus.SCHEDULED, LimitedTimeOfferCampaignStatus.ACTIVE];\n\n@Service()\nexport class LtoCampaignService {\n private repository: LtoCampaignRepository;\n private scheduler: LtoCampaignSchedulerService;\n private lifecycle: LtoCampaignLifecycleService;\n private configService: LimitedTimeOfferConfigService;\n\n constructor() {\n this.repository = Container.get(LtoCampaignRepository);\n this.scheduler = Container.get(LtoCampaignSchedulerService);\n this.lifecycle = Container.get(LtoCampaignLifecycleService);\n this.configService = Container.get(LimitedTimeOfferConfigService);\n }\n\n public async create(dto: CreateLtoCampaignDTO) {\n await this.assertNoCampaignRunning();\n\n const config = await this.loadConfigSnapshot();\n\n const status = this.deriveCampaignStatus(dto.startDate);\n const campaign = await this.repository.create(\n LtoCampaignQueryBuilder.buildCreateInput({\n dto,\n status,\n campaignNumber: await this.repository.nextCampaignNumber(),\n config,\n startDate: dto.startDate,\n endDate: dto.endDate,\n })\n );\n\n if (status === LimitedTimeOfferCampaignStatus.SCHEDULED) {\n await this.scheduler.scheduleActivation(campaign._id, dto.startDate);\n }\n await this.scheduler.scheduleExpiry(campaign._id, dto.endDate);\n\n return campaign;\n }\n\n private deriveCampaignStatus(startDate: Date) {\n return startDate <= new Date()\n ? LimitedTimeOfferCampaignStatus.ACTIVE\n : LimitedTimeOfferCampaignStatus.SCHEDULED;\n }\n\n public async getCurrent() {\n return this.repository.findCurrent();\n }\n\n public async getActive(): Promise<LtoActiveCampaignDTO | null> {\n const campaign = await this.repository.findActive();\n if (!campaign) return null;\n\n return {\n _id: campaign._id,\n title: campaign.title,\n subtitle: campaign.subTitle,\n startTime: campaign.startDate,\n endTime: campaign.endDate,\n };\n }\n\n public async getById(campaignId: mongoose.Types.ObjectId) {\n const campaign = await this.repository.findById(campaignId);\n if (!campaign) throw notFoundError('Campaign not found');\n return campaign;\n }\n\n public async getHistory(dto: GetLtoCampaignHistoryDTO) {\n const {documents, total} = await this.repository.findHistory(dto);\n return {\n documents,\n metadata: {\n page: dto.page,\n size: dto.size,\n totalElements: total,\n totalPages: Math.ceil(total / dto.size),\n },\n };\n }\n\n public async update(dto: UpdateLtoCampaignDTO) {\n const campaign = await this.repository.findById(dto._id);\n if (!campaign) throw notFoundError('Campaign not found');\n\n this.assertUpdateAllowed(campaign, dto);\n\n const updates = LtoCampaignQueryBuilder.buildUpdateInput(campaign, dto);\n\n if (this.shouldExpireImmediately(campaign.status, dto.endDate)) {\n return this.applyImmediateExpiry(dto._id, updates);\n }\n\n const ltoScheduleEnabled = await isLtoScheduleEnabled();\n\n // For a scheduled recurring campaign, snap the schedule to the next selected weekday so the\n // selected days stay authoritative — an active session keeps the dto dates (takes effect now).\n const repeatDays = (updates.repeatDays ?? campaign.repeatDays ?? []) as number[];\n if (\n ltoScheduleEnabled &&\n updates.status === LimitedTimeOfferCampaignStatus.SCHEDULED &&\n repeatDays.length > 0\n ) {\n const occurrence = nextOccurrenceDate(repeatDays, dto.startDate, dto.endDate);\n updates.startDate = occurrence.startDate;\n updates.endDate = occurrence.endDate;\n }\n\n const result = await this.repository.updateById(dto._id, updates);\n if (!result) throw notFoundError('Campaign not found after update');\n\n // Postponing a live campaign back to SCHEDULED must undo what activation applied — otherwise\n // the shops' own discounts stay paused until the campaign eventually cancels or expires.\n if (\n ltoScheduleEnabled &&\n campaign.status === LimitedTimeOfferCampaignStatus.ACTIVE &&\n result.status === LimitedTimeOfferCampaignStatus.SCHEDULED\n ) {\n await this.lifecycle.demoteToScheduled(dto._id);\n }\n\n await this.rescheduleIfDatesChanged(result, campaign);\n\n return result;\n }\n\n public async cancel(campaignId: mongoose.Types.ObjectId): Promise<void> {\n const campaign = await this.repository.findById(campaignId);\n if (!campaign) throw notFoundError('Campaign not found');\n\n this.assertEditable(campaign.status);\n await this.scheduler.cancelJobs(campaignId);\n await this.lifecycle.cancelCampaign(campaignId);\n }\n\n private assertUpdateAllowed(campaign: DocumentType<Model>, dto: UpdateLtoCampaignDTO): void {\n this.assertEditable(campaign.status);\n\n if (campaign.status === LimitedTimeOfferCampaignStatus.ACTIVE && !dto.confirmActive) {\n throw badRequestError('Set confirmActive=true to confirm editing a live campaign.');\n }\n\n if (dto.startDate < new Date() && campaign.status === LimitedTimeOfferCampaignStatus.SCHEDULED) {\n throw badRequestError('Start date cannot be in the past.');\n }\n }\n\n private shouldExpireImmediately(status: LimitedTimeOfferCampaignStatus, endDate: Date): boolean {\n return status === LimitedTimeOfferCampaignStatus.ACTIVE && endDate <= new Date();\n }\n\n private async applyImmediateExpiry(campaignId: mongoose.Types.ObjectId, updates: object) {\n await this.scheduler.cancelJobs(campaignId);\n await this.repository.updateById(campaignId, updates);\n await this.lifecycle.expireCampaign(campaignId);\n const result = await this.repository.findById(campaignId);\n if (!result) throw notFoundError('Campaign not found after expiry');\n return result;\n }\n\n private async rescheduleIfDatesChanged(\n result: DocumentType<Model>,\n original: DocumentType<Model>\n ): Promise<void> {\n const datesChanged =\n result.startDate!.getTime() !== original.startDate!.getTime() ||\n result.endDate!.getTime() !== original.endDate!.getTime();\n\n if (!datesChanged) return;\n\n await this.scheduler.cancelJobs(result._id);\n if (result.status === LimitedTimeOfferCampaignStatus.SCHEDULED) {\n await this.scheduler.scheduleActivation(result._id, result.startDate!);\n }\n await this.scheduler.scheduleExpiry(result._id, result.endDate!);\n }\n\n private async assertNoCampaignRunning(): Promise<void> {\n if (await this.repository.hasActiveCampaign()) {\n throw conflictError('A campaign is already scheduled or active. Delete it before creating a new one.');\n }\n }\n\n private assertEditable(status: LimitedTimeOfferCampaignStatus): void {\n if (!ACTIVE_STATUSES.includes(status)) {\n throw badRequestError('Only SCHEDULED or ACTIVE campaigns can be modified.');\n }\n }\n\n private async loadConfigSnapshot() {\n const config = await this.configService.getByType(MarketingType.DISCOUNT).catch(() => {\n throw badRequestError('Global config is incomplete. Set discount options and max caps first.');\n });\n\n if (config.discountOptions.length === 0 || config.maxDiscountCaps.length === 0) {\n throw badRequestError('Global config is incomplete. Set discount options and max caps first.');\n }\n\n return config;\n }\n}\n\nexport const ltoCampaignService = Container.get(LtoCampaignService);\n"]}
@@ -68,13 +68,13 @@ export declare const LimitedTimeOfferConfigResponseSchema: z.ZodObject<{
68
68
  totalElements: z.ZodNumber;
69
69
  totalPages: z.ZodNumber;
70
70
  }, "strip", z.ZodTypeAny, {
71
- page: number;
72
71
  size: number;
72
+ page: number;
73
73
  totalElements: number;
74
74
  totalPages: number;
75
75
  }, {
76
- page: number;
77
76
  size: number;
77
+ page: number;
78
78
  totalElements: number;
79
79
  totalPages: number;
80
80
  }>>;
@@ -103,8 +103,8 @@ export declare const LimitedTimeOfferConfigResponseSchema: z.ZodObject<{
103
103
  maxDiscountCaps?: number[] | undefined;
104
104
  }[];
105
105
  metadata?: {
106
- page: number;
107
106
  size: number;
107
+ page: number;
108
108
  totalElements: number;
109
109
  totalPages: number;
110
110
  } | undefined;
@@ -118,8 +118,8 @@ export declare const LimitedTimeOfferConfigResponseSchema: z.ZodObject<{
118
118
  maxDiscountCaps?: number[] | undefined;
119
119
  }[];
120
120
  metadata?: {
121
- page: number;
122
121
  size: number;
122
+ page: number;
123
123
  totalElements: number;
124
124
  totalPages: number;
125
125
  } | undefined;
@@ -158,8 +158,8 @@ export declare const LimitedTimeOfferConfigResponseSchema: z.ZodObject<{
158
158
  maxDiscountCaps?: number[] | undefined;
159
159
  }[];
160
160
  metadata?: {
161
- page: number;
162
161
  size: number;
162
+ page: number;
163
163
  totalElements: number;
164
164
  totalPages: number;
165
165
  } | undefined;
@@ -184,8 +184,8 @@ export declare const LimitedTimeOfferConfigResponseSchema: z.ZodObject<{
184
184
  maxDiscountCaps?: number[] | undefined;
185
185
  }[];
186
186
  metadata?: {
187
- page: number;
188
187
  size: number;
188
+ page: number;
189
189
  totalElements: number;
190
190
  totalPages: number;
191
191
  } | undefined;
@@ -41,8 +41,8 @@ export declare const configRouter: import("@trpc/server").TRPCBuiltRouter<{
41
41
  maxDiscountCaps?: number[] | undefined;
42
42
  }[];
43
43
  metadata?: {
44
- page: number;
45
44
  size: number;
45
+ page: number;
46
46
  totalElements: number;
47
47
  totalPages: number;
48
48
  } | undefined;
@@ -74,8 +74,8 @@ export declare const configRouter: import("@trpc/server").TRPCBuiltRouter<{
74
74
  maxDiscountCaps?: number[] | undefined;
75
75
  }[];
76
76
  metadata?: {
77
- page: number;
78
77
  size: number;
78
+ page: number;
79
79
  totalElements: number;
80
80
  totalPages: number;
81
81
  } | undefined;
@@ -109,8 +109,8 @@ export declare const configRouter: import("@trpc/server").TRPCBuiltRouter<{
109
109
  maxDiscountCaps?: number[] | undefined;
110
110
  }[];
111
111
  metadata?: {
112
- page: number;
113
112
  size: number;
113
+ page: number;
114
114
  totalElements: number;
115
115
  totalPages: number;
116
116
  } | undefined;
@@ -37,8 +37,8 @@ export declare const limitedTimeOfferRouter: import("@trpc/server").TRPCBuiltRou
37
37
  endTime?: Date | null | undefined;
38
38
  } | null)[];
39
39
  metadata?: {
40
- page: number;
41
40
  size: number;
41
+ page: number;
42
42
  totalElements: number;
43
43
  totalPages: number;
44
44
  } | undefined;
@@ -98,8 +98,8 @@ export declare const limitedTimeOfferRouter: import("@trpc/server").TRPCBuiltRou
98
98
  maxDiscountCaps?: number[] | undefined;
99
99
  }[];
100
100
  metadata?: {
101
- page: number;
102
101
  size: number;
102
+ page: number;
103
103
  totalElements: number;
104
104
  totalPages: number;
105
105
  } | undefined;
@@ -131,8 +131,8 @@ export declare const limitedTimeOfferRouter: import("@trpc/server").TRPCBuiltRou
131
131
  maxDiscountCaps?: number[] | undefined;
132
132
  }[];
133
133
  metadata?: {
134
- page: number;
135
134
  size: number;
135
+ page: number;
136
136
  totalElements: number;
137
137
  totalPages: number;
138
138
  } | undefined;
@@ -166,8 +166,8 @@ export declare const limitedTimeOfferRouter: import("@trpc/server").TRPCBuiltRou
166
166
  maxDiscountCaps?: number[] | undefined;
167
167
  }[];
168
168
  metadata?: {
169
- page: number;
170
169
  size: number;
170
+ page: number;
171
171
  totalElements: number;
172
172
  totalPages: number;
173
173
  } | undefined;
@@ -235,8 +235,8 @@ export declare const limitedTimeOfferRouter: import("@trpc/server").TRPCBuiltRou
235
235
  archivedAt?: Date | null | undefined;
236
236
  }[];
237
237
  metadata?: {
238
- page: number;
239
238
  size: number;
239
+ page: number;
240
240
  totalElements: number;
241
241
  totalPages: number;
242
242
  } | undefined;
@@ -280,8 +280,8 @@ export declare const limitedTimeOfferRouter: import("@trpc/server").TRPCBuiltRou
280
280
  archivedAt?: Date | null | undefined;
281
281
  } | null)[];
282
282
  metadata?: {
283
- page: number;
284
283
  size: number;
284
+ page: number;
285
285
  totalElements: number;
286
286
  totalPages: number;
287
287
  } | undefined;
@@ -327,8 +327,8 @@ export declare const limitedTimeOfferRouter: import("@trpc/server").TRPCBuiltRou
327
327
  archivedAt?: Date | null | undefined;
328
328
  }[];
329
329
  metadata?: {
330
- page: number;
331
330
  size: number;
331
+ page: number;
332
332
  totalElements: number;
333
333
  totalPages: number;
334
334
  } | undefined;
@@ -364,8 +364,8 @@ export declare const limitedTimeOfferRouter: import("@trpc/server").TRPCBuiltRou
364
364
  endDateTime?: Date | null | undefined;
365
365
  }[];
366
366
  metadata?: {
367
- page: number;
368
367
  size: number;
368
+ page: number;
369
369
  totalElements: number;
370
370
  totalPages: number;
371
371
  } | undefined;
@@ -419,8 +419,8 @@ export declare const limitedTimeOfferRouter: import("@trpc/server").TRPCBuiltRou
419
419
  archivedAt?: Date | null | undefined;
420
420
  }[];
421
421
  metadata?: {
422
- page: number;
423
422
  size: number;
423
+ page: number;
424
424
  totalElements: number;
425
425
  totalPages: number;
426
426
  } | undefined;
@@ -451,8 +451,8 @@ export declare const limitedTimeOfferRouter: import("@trpc/server").TRPCBuiltRou
451
451
  endTime?: Date | null | undefined;
452
452
  } | null)[];
453
453
  metadata?: {
454
- page: number;
455
454
  size: number;
455
+ page: number;
456
456
  totalElements: number;
457
457
  totalPages: number;
458
458
  } | undefined;
@@ -486,8 +486,8 @@ export declare const limitedTimeOfferRouter: import("@trpc/server").TRPCBuiltRou
486
486
  campaign: string | import("mongoose").Types.ObjectId;
487
487
  }[];
488
488
  metadata?: {
489
- page: number;
490
489
  size: number;
490
+ page: number;
491
491
  totalElements: number;
492
492
  totalPages: number;
493
493
  } | undefined;
@@ -568,8 +568,8 @@ export declare const limitedTimeOfferRouter: import("@trpc/server").TRPCBuiltRou
568
568
  withdrawnAt?: Date | null | undefined;
569
569
  }[];
570
570
  metadata?: {
571
- page: number;
572
571
  size: number;
572
+ page: number;
573
573
  totalElements: number;
574
574
  totalPages: number;
575
575
  } | undefined;
@@ -623,8 +623,8 @@ export declare const limitedTimeOfferRouter: import("@trpc/server").TRPCBuiltRou
623
623
  withdrawnAt?: Date | null | undefined;
624
624
  }[];
625
625
  metadata?: {
626
- page: number;
627
626
  size: number;
627
+ page: number;
628
628
  totalElements: number;
629
629
  totalPages: number;
630
630
  } | undefined;
@@ -690,8 +690,8 @@ export declare const limitedTimeOfferRouter: import("@trpc/server").TRPCBuiltRou
690
690
  } | undefined;
691
691
  }[];
692
692
  metadata?: {
693
- page: number;
694
693
  size: number;
694
+ page: number;
695
695
  totalElements: number;
696
696
  totalPages: number;
697
697
  } | undefined;
@@ -748,8 +748,8 @@ export declare const limitedTimeOfferRouter: import("@trpc/server").TRPCBuiltRou
748
748
  withdrawnAt?: Date | null | undefined;
749
749
  }[][];
750
750
  metadata?: {
751
- page: number;
752
751
  size: number;
752
+ page: number;
753
753
  totalElements: number;
754
754
  totalPages: number;
755
755
  } | undefined;
@@ -804,8 +804,8 @@ export declare const limitedTimeOfferRouter: import("@trpc/server").TRPCBuiltRou
804
804
  withdrawnAt?: Date | null | undefined;
805
805
  }[];
806
806
  metadata?: {
807
- page: number;
808
807
  size: number;
808
+ page: number;
809
809
  totalElements: number;
810
810
  totalPages: number;
811
811
  } | undefined;
@@ -850,8 +850,8 @@ export declare const limitedTimeOfferRouter: import("@trpc/server").TRPCBuiltRou
850
850
  discountPercentage?: number | undefined;
851
851
  }[];
852
852
  metadata?: {
853
- page: number;
854
853
  size: number;
854
+ page: number;
855
855
  totalElements: number;
856
856
  totalPages: number;
857
857
  } | undefined;
@@ -911,8 +911,8 @@ export declare const limitedTimeOfferRouter: import("@trpc/server").TRPCBuiltRou
911
911
  } | undefined;
912
912
  }[];
913
913
  metadata?: {
914
- page: number;
915
914
  size: number;
915
+ page: number;
916
916
  totalElements: number;
917
917
  totalPages: number;
918
918
  } | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"limited-time-offer.service.d.ts","sourceRoot":"/","sources":["modules/limited-time-offer/limited-time-offer.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAQ9C,OAAO,EAAC,oBAAoB,EAAC,MAAM,6EAA6E,CAAC;AAejH,qBACa,uBAAuB;IAChC,OAAO,CAAC,eAAe,CAAqB;IAC5C,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,kBAAkB,CAAqC;IAC/D,OAAO,CAAC,mBAAmB,CAAsC;;IASpD,gBAAgB,CAAC,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IASpE,iBAAiB,CAAC,KAAK,EAAE,oBAAoB;;;;;;;IAQ7C,cAAc,CAAC,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAOlE,cAAc,CAAC,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAGlF;AAED,eAAO,MAAM,uBAAuB,yBAAyC,CAAC"}
1
+ {"version":3,"file":"limited-time-offer.service.d.ts","sourceRoot":"/","sources":["modules/limited-time-offer/limited-time-offer.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAQ9C,OAAO,EAAC,oBAAoB,EAAC,MAAM,6EAA6E,CAAC;AAgBjH,qBACa,uBAAuB;IAChC,OAAO,CAAC,eAAe,CAAqB;IAC5C,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,kBAAkB,CAAqC;IAC/D,OAAO,CAAC,mBAAmB,CAAsC;;IASpD,gBAAgB,CAAC,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAUpE,iBAAiB,CAAC,KAAK,EAAE,oBAAoB;;;;;;;IAQ7C,cAAc,CAAC,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAOlE,cAAc,CAAC,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAGlF;AAED,eAAO,MAAM,uBAAuB,yBAAyC,CAAC"}
@@ -49,6 +49,7 @@ const limited_time_offer_campaign_lifecycle_service_1 = require("../limited-time
49
49
  const limited_time_offer_participant_service_1 = require("../limited-time-offer/participant/services/limited-time-offer-participant.service");
50
50
  const limited_time_offer_notification_service_1 = require("../limited-time-offer/notification/limited-time-offer-notification.service");
51
51
  const limited_time_offer_notification_constants_1 = require("../limited-time-offer/notification/limited-time-offer-notification.constants");
52
+ const feature_flags_1 = require("../../utility/feature-flags");
52
53
  let LimitedTimeOfferService = class LimitedTimeOfferService {
53
54
  campaignService;
54
55
  lifecycle;
@@ -63,6 +64,8 @@ let LimitedTimeOfferService = class LimitedTimeOfferService {
63
64
  async activateCampaign(campaignId) {
64
65
  const campaign = await this.campaignService.getById(campaignId);
65
66
  await this.lifecycle.activateCampaign(campaignId);
67
+ if (!(await (0, feature_flags_1.isLtoScheduleEnabled)()))
68
+ return;
66
69
  await this.participantService.applyLiveEffectsToParticipants(campaign);
67
70
  }
68
71
  async getActiveCampaign(input) {
@@ -1 +1 @@
1
- {"version":3,"file":"limited-time-offer.service.js","sourceRoot":"/","sources":["modules/limited-time-offer/limited-time-offer.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iDAA0C;AAE1C,2IAG2F;AAC3F,+JAEqG;AAErG,oJAGiG;AACjG,8IAE0F;AAC1F,kJAAoH;AAQ7G,IAAM,uBAAuB,GAA7B,MAAM,uBAAuB;IACxB,eAAe,CAAqB;IACpC,SAAS,CAA8B;IACvC,kBAAkB,CAAqC;IACvD,mBAAmB,CAAsC;IAEjE;QACI,IAAI,CAAC,eAAe,GAAG,wDAAkB,CAAC;QAC1C,IAAI,CAAC,SAAS,GAAG,gBAAS,CAAC,GAAG,CAAC,2EAA2B,CAAC,CAAC;QAC5D,IAAI,CAAC,kBAAkB,GAAG,8DAAqB,CAAC;QAChD,IAAI,CAAC,mBAAmB,GAAG,gBAAS,CAAC,GAAG,CAAC,6EAAmC,CAAC,CAAC;IAClF,CAAC;IAEM,KAAK,CAAC,gBAAgB,CAAC,UAAmC;QAC7D,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAChE,MAAM,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAIlD,MAAM,IAAI,CAAC,kBAAkB,CAAC,8BAA8B,CAAC,QAAQ,CAAC,CAAC;IAC3E,CAAC;IAEM,KAAK,CAAC,iBAAiB,CAAC,KAA2B;QACtD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,CAAC;QACxD,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAE3B,MAAM,kBAAkB,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACxF,OAAO,kBAAkB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3D,CAAC;IAEM,KAAK,CAAC,cAAc,CAAC,UAAmC;QAE3D,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,6BAA6B,CAAC,UAAU,CAAC,CAAC;QAC/F,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC9C,MAAM,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,4DAAgB,CAAC,MAAM,EAAE,cAAc,EAAE,EAAC,UAAU,EAAC,CAAC,CAAC;IAC/F,CAAC;IAEM,KAAK,CAAC,cAAc,CAAC,UAAmC;QAC3D,MAAM,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;IACpD,CAAC;CACJ,CAAA;AAxCY,0DAAuB;kCAAvB,uBAAuB;IADnC,IAAA,gBAAO,GAAE;;GACG,uBAAuB,CAwCnC;AAEY,QAAA,uBAAuB,GAAG,gBAAS,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC","sourcesContent":["import Container, {Service} from 'typedi';\nimport {mongoose} from '@typegoose/typegoose';\nimport {\n ltoCampaignService,\n LtoCampaignService,\n} from '@modules/limited-time-offer/campaign/services/limited-time-offer-campaign.service';\nimport {\n LtoCampaignLifecycleService,\n} from '@modules/limited-time-offer/campaign/services/limited-time-offer-campaign-lifecycle.service';\nimport {GetActiveCampaignDTO} from '@modules/limited-time-offer/campaign/limited-time-offer-campaign.validation';\nimport {\n LimitedTimeOfferParticipantService,\n ltoParticipantService,\n} from '@modules/limited-time-offer/participant/services/limited-time-offer-participant.service';\nimport {\n LimitedTimeOfferNotificationService\n} from \"@modules/limited-time-offer/notification/limited-time-offer-notification.service\";\nimport {NotificationType} from \"@modules/limited-time-offer/notification/limited-time-offer-notification.constants\";\n\n/**\n * Application/orchestration layer for the Limited Time Offer module. Owns every flow that spans the\n * campaign and participant aggregates so neither domain service has to reach across the boundary.\n * Pure single-aggregate operations stay on their respective domain services.\n */\n@Service()\nexport class LimitedTimeOfferService {\n private campaignService: LtoCampaignService;\n private lifecycle: LtoCampaignLifecycleService;\n private participantService: LimitedTimeOfferParticipantService;\n private notificationService: LimitedTimeOfferNotificationService;\n\n constructor() {\n this.campaignService = ltoCampaignService;\n this.lifecycle = Container.get(LtoCampaignLifecycleService);\n this.participantService = ltoParticipantService;\n this.notificationService = Container.get(LimitedTimeOfferNotificationService);\n }\n\n public async activateCampaign(campaignId: mongoose.Types.ObjectId): Promise<void> {\n const campaign = await this.campaignService.getById(campaignId);\n await this.lifecycle.activateCampaign(campaignId);\n // Now that the campaign is live, apply the effects that join deferred while it was scheduled\n // (pause the shops' clashing discounts, override order capacity) for every participant —\n // including recurrence clones, whose marketing is (re)created here.\n await this.participantService.applyLiveEffectsToParticipants(campaign);\n }\n\n public async getActiveCampaign(input: GetActiveCampaignDTO) {\n const campaign = await this.campaignService.getActive();\n if (!campaign) return null;\n\n const nearbyParticipants = await this.participantService.getNearby(campaign._id, input);\n return nearbyParticipants.length > 0 ? campaign : null;\n }\n\n public async cancelCampaign(campaignId: mongoose.Types.ObjectId): Promise<void> {\n // Capture participants before cancelling reverts their effects, so the notification still reaches them.\n const participantIds = await this.participantService.getParticipantIdsByCampaignId(campaignId);\n await this.campaignService.cancel(campaignId);\n await this.notificationService.send(NotificationType.Cancel, participantIds, {campaignId});\n }\n\n public async expireCampaign(campaignId: mongoose.Types.ObjectId): Promise<void> {\n await this.lifecycle.expireCampaign(campaignId);\n }\n}\n\nexport const limitedTimeOfferService = Container.get(LimitedTimeOfferService);\n"]}
1
+ {"version":3,"file":"limited-time-offer.service.js","sourceRoot":"/","sources":["modules/limited-time-offer/limited-time-offer.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iDAA0C;AAE1C,2IAG2F;AAC3F,+JAEqG;AAErG,oJAGiG;AACjG,8IAE0F;AAC1F,kJAAoH;AACpH,0DAA4D;AAQrD,IAAM,uBAAuB,GAA7B,MAAM,uBAAuB;IACxB,eAAe,CAAqB;IACpC,SAAS,CAA8B;IACvC,kBAAkB,CAAqC;IACvD,mBAAmB,CAAsC;IAEjE;QACI,IAAI,CAAC,eAAe,GAAG,wDAAkB,CAAC;QAC1C,IAAI,CAAC,SAAS,GAAG,gBAAS,CAAC,GAAG,CAAC,2EAA2B,CAAC,CAAC;QAC5D,IAAI,CAAC,kBAAkB,GAAG,8DAAqB,CAAC;QAChD,IAAI,CAAC,mBAAmB,GAAG,gBAAS,CAAC,GAAG,CAAC,6EAAmC,CAAC,CAAC;IAClF,CAAC;IAEM,KAAK,CAAC,gBAAgB,CAAC,UAAmC;QAC7D,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAChE,MAAM,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAClD,IAAI,CAAC,CAAC,MAAM,IAAA,oCAAoB,GAAE,CAAC;YAAE,OAAO;QAI5C,MAAM,IAAI,CAAC,kBAAkB,CAAC,8BAA8B,CAAC,QAAQ,CAAC,CAAC;IAC3E,CAAC;IAEM,KAAK,CAAC,iBAAiB,CAAC,KAA2B;QACtD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,CAAC;QACxD,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAE3B,MAAM,kBAAkB,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACxF,OAAO,kBAAkB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3D,CAAC;IAEM,KAAK,CAAC,cAAc,CAAC,UAAmC;QAE3D,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,6BAA6B,CAAC,UAAU,CAAC,CAAC;QAC/F,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC9C,MAAM,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,4DAAgB,CAAC,MAAM,EAAE,cAAc,EAAE,EAAC,UAAU,EAAC,CAAC,CAAC;IAC/F,CAAC;IAEM,KAAK,CAAC,cAAc,CAAC,UAAmC;QAC3D,MAAM,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;IACpD,CAAC;CACJ,CAAA;AAzCY,0DAAuB;kCAAvB,uBAAuB;IADnC,IAAA,gBAAO,GAAE;;GACG,uBAAuB,CAyCnC;AAEY,QAAA,uBAAuB,GAAG,gBAAS,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC","sourcesContent":["import Container, {Service} from 'typedi';\nimport {mongoose} from '@typegoose/typegoose';\nimport {\n ltoCampaignService,\n LtoCampaignService,\n} from '@modules/limited-time-offer/campaign/services/limited-time-offer-campaign.service';\nimport {\n LtoCampaignLifecycleService,\n} from '@modules/limited-time-offer/campaign/services/limited-time-offer-campaign-lifecycle.service';\nimport {GetActiveCampaignDTO} from '@modules/limited-time-offer/campaign/limited-time-offer-campaign.validation';\nimport {\n LimitedTimeOfferParticipantService,\n ltoParticipantService,\n} from '@modules/limited-time-offer/participant/services/limited-time-offer-participant.service';\nimport {\n LimitedTimeOfferNotificationService\n} from \"@modules/limited-time-offer/notification/limited-time-offer-notification.service\";\nimport {NotificationType} from \"@modules/limited-time-offer/notification/limited-time-offer-notification.constants\";\nimport {isLtoScheduleEnabled} from '@utility/feature-flags';\n\n/**\n * Application/orchestration layer for the Limited Time Offer module. Owns every flow that spans the\n * campaign and participant aggregates so neither domain service has to reach across the boundary.\n * Pure single-aggregate operations stay on their respective domain services.\n */\n@Service()\nexport class LimitedTimeOfferService {\n private campaignService: LtoCampaignService;\n private lifecycle: LtoCampaignLifecycleService;\n private participantService: LimitedTimeOfferParticipantService;\n private notificationService: LimitedTimeOfferNotificationService;\n\n constructor() {\n this.campaignService = ltoCampaignService;\n this.lifecycle = Container.get(LtoCampaignLifecycleService);\n this.participantService = ltoParticipantService;\n this.notificationService = Container.get(LimitedTimeOfferNotificationService);\n }\n\n public async activateCampaign(campaignId: mongoose.Types.ObjectId): Promise<void> {\n const campaign = await this.campaignService.getById(campaignId);\n await this.lifecycle.activateCampaign(campaignId);\n if (!(await isLtoScheduleEnabled())) return;\n // Now that the campaign is live, apply the effects that join deferred while it was scheduled\n // (pause the shops' clashing discounts, override order capacity) for every participant —\n // including recurrence clones, whose marketing is (re)created here.\n await this.participantService.applyLiveEffectsToParticipants(campaign);\n }\n\n public async getActiveCampaign(input: GetActiveCampaignDTO) {\n const campaign = await this.campaignService.getActive();\n if (!campaign) return null;\n\n const nearbyParticipants = await this.participantService.getNearby(campaign._id, input);\n return nearbyParticipants.length > 0 ? campaign : null;\n }\n\n public async cancelCampaign(campaignId: mongoose.Types.ObjectId): Promise<void> {\n // Capture participants before cancelling reverts their effects, so the notification still reaches them.\n const participantIds = await this.participantService.getParticipantIdsByCampaignId(campaignId);\n await this.campaignService.cancel(campaignId);\n await this.notificationService.send(NotificationType.Cancel, participantIds, {campaignId});\n }\n\n public async expireCampaign(campaignId: mongoose.Types.ObjectId): Promise<void> {\n await this.lifecycle.expireCampaign(campaignId);\n }\n}\n\nexport const limitedTimeOfferService = Container.get(LimitedTimeOfferService);\n"]}