@lyxa.ai/marketing 1.0.54 → 1.0.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/index.d.ts +1289 -0
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +1 -1
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/modules/coupon/routers/coupon.router.d.ts +1289 -0
- package/dist/lib/modules/coupon/routers/coupon.router.d.ts.map +1 -1
- package/dist/lib/modules/coupon/routers/coupon.router.js +14 -0
- package/dist/lib/modules/coupon/routers/coupon.router.js.map +1 -1
- package/dist/lib/modules/coupon/services/coupon.service.d.ts +30 -2
- package/dist/lib/modules/coupon/services/coupon.service.d.ts.map +1 -1
- package/dist/lib/modules/coupon/services/coupon.service.js +34 -1
- package/dist/lib/modules/coupon/services/coupon.service.js.map +1 -1
- package/dist/lib/modules/coupon/services/custom-coupon.service.d.ts +5 -0
- package/dist/lib/modules/coupon/services/custom-coupon.service.d.ts.map +1 -1
- package/dist/lib/modules/coupon/services/helper.service.d.ts +5 -0
- package/dist/lib/modules/coupon/services/helper.service.d.ts.map +1 -1
- package/dist/lib/modules/coupon/services/individual-store-coupon.service.d.ts +5 -0
- package/dist/lib/modules/coupon/services/individual-store-coupon.service.d.ts.map +1 -1
- package/dist/lib/modules/coupon/services/patterns/repository/CouponMetricsRepository.d.ts +2 -0
- package/dist/lib/modules/coupon/services/patterns/repository/CouponMetricsRepository.d.ts.map +1 -1
- package/dist/lib/modules/coupon/services/patterns/repository/CouponMetricsRepository.js +77 -7
- package/dist/lib/modules/coupon/services/patterns/repository/CouponMetricsRepository.js.map +1 -1
- package/dist/lib/modules/coupon/services/patterns/repository/CouponRepository.d.ts +17 -0
- package/dist/lib/modules/coupon/services/patterns/repository/CouponRepository.d.ts.map +1 -1
- package/dist/lib/modules/coupon/services/patterns/repository/CouponRepository.js +135 -0
- package/dist/lib/modules/coupon/services/patterns/repository/CouponRepository.js.map +1 -1
- package/dist/lib/modules/coupon/services/shops-categories-coupon.service.d.ts +5 -0
- package/dist/lib/modules/coupon/services/shops-categories-coupon.service.d.ts.map +1 -1
- package/dist/lib/modules/coupon/validations/coupon.validation.d.ts +76 -0
- package/dist/lib/modules/coupon/validations/coupon.validation.d.ts.map +1 -1
- package/dist/lib/modules/coupon/validations/coupon.validation.js +27 -1
- package/dist/lib/modules/coupon/validations/coupon.validation.js.map +1 -1
- package/dist/lib/modules/coupon/validations/create-coupon.validation.d.ts.map +1 -1
- package/dist/lib/modules/coupon/validations/create-coupon.validation.js +4 -1
- package/dist/lib/modules/coupon/validations/create-coupon.validation.js.map +1 -1
- package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.validation.d.ts +9 -1
- package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.validation.d.ts.map +1 -1
- package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.validation.js +26 -3
- package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.validation.js.map +1 -1
- package/dist/lib/modules/tournament/match/events/evaluate-predictions.consumer.js +1 -1
- package/dist/lib/modules/tournament/match/events/evaluate-predictions.consumer.js.map +1 -1
- package/dist/lib/modules/tournament/notification/__tests__/notification.service.spec.d.ts +2 -0
- package/dist/lib/modules/tournament/notification/__tests__/notification.service.spec.d.ts.map +1 -0
- package/dist/lib/modules/tournament/notification/__tests__/notification.service.spec.js +266 -0
- package/dist/lib/modules/tournament/notification/__tests__/notification.service.spec.js.map +1 -0
- package/dist/lib/modules/tournament/notification/notification.service.d.ts +14 -3
- package/dist/lib/modules/tournament/notification/notification.service.d.ts.map +1 -1
- package/dist/lib/modules/tournament/notification/notification.service.js +89 -31
- package/dist/lib/modules/tournament/notification/notification.service.js.map +1 -1
- package/dist/lib/modules/tournament/participant/participant.repository.d.ts +1 -0
- package/dist/lib/modules/tournament/participant/participant.repository.d.ts.map +1 -1
- package/dist/lib/modules/tournament/participant/participant.repository.js +9 -0
- package/dist/lib/modules/tournament/participant/participant.repository.js.map +1 -1
- package/dist/lib/modules/tournament/participant/participant.service.d.ts +1 -0
- package/dist/lib/modules/tournament/participant/participant.service.d.ts.map +1 -1
- package/dist/lib/modules/tournament/participant/participant.service.js +6 -0
- package/dist/lib/modules/tournament/participant/participant.service.js.map +1 -1
- package/dist/lib/modules/tournament/reward/reward.builder.d.ts.map +1 -1
- package/dist/lib/modules/tournament/reward/reward.builder.js +3 -3
- package/dist/lib/modules/tournament/reward/reward.builder.js.map +1 -1
- package/dist/lib/modules/tournament/reward/reward.types.d.ts +1 -0
- package/dist/lib/modules/tournament/reward/reward.types.d.ts.map +1 -1
- package/dist/lib/modules/tournament/reward/reward.types.js.map +1 -1
- package/dist/lib/modules/tournament/schedule/schedule.service.d.ts +7 -0
- package/dist/lib/modules/tournament/schedule/schedule.service.d.ts.map +1 -1
- package/dist/lib/modules/tournament/schedule/schedule.service.js +52 -19
- package/dist/lib/modules/tournament/schedule/schedule.service.js.map +1 -1
- package/dist/lib/utility/utils.js +2 -2
- package/dist/lib/utility/utils.js.map +1 -1
- package/dist/types/index.d.ts +1289 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/modules/coupon/routers/coupon.router.d.ts +1289 -0
- package/dist/types/modules/coupon/routers/coupon.router.d.ts.map +1 -1
- package/dist/types/modules/coupon/services/coupon.service.d.ts +30 -2
- package/dist/types/modules/coupon/services/coupon.service.d.ts.map +1 -1
- package/dist/types/modules/coupon/services/custom-coupon.service.d.ts +5 -0
- package/dist/types/modules/coupon/services/custom-coupon.service.d.ts.map +1 -1
- package/dist/types/modules/coupon/services/helper.service.d.ts +5 -0
- package/dist/types/modules/coupon/services/helper.service.d.ts.map +1 -1
- package/dist/types/modules/coupon/services/individual-store-coupon.service.d.ts +5 -0
- package/dist/types/modules/coupon/services/individual-store-coupon.service.d.ts.map +1 -1
- package/dist/types/modules/coupon/services/patterns/repository/CouponMetricsRepository.d.ts +2 -0
- package/dist/types/modules/coupon/services/patterns/repository/CouponMetricsRepository.d.ts.map +1 -1
- package/dist/types/modules/coupon/services/patterns/repository/CouponRepository.d.ts +17 -0
- package/dist/types/modules/coupon/services/patterns/repository/CouponRepository.d.ts.map +1 -1
- package/dist/types/modules/coupon/services/shops-categories-coupon.service.d.ts +5 -0
- package/dist/types/modules/coupon/services/shops-categories-coupon.service.d.ts.map +1 -1
- package/dist/types/modules/coupon/validations/coupon.validation.d.ts +76 -0
- package/dist/types/modules/coupon/validations/coupon.validation.d.ts.map +1 -1
- package/dist/types/modules/coupon/validations/create-coupon.validation.d.ts.map +1 -1
- package/dist/types/modules/limited-time-offer/config/limited-time-offer-config.validation.d.ts +9 -1
- package/dist/types/modules/limited-time-offer/config/limited-time-offer-config.validation.d.ts.map +1 -1
- package/dist/types/modules/tournament/notification/notification.service.d.ts +14 -3
- package/dist/types/modules/tournament/notification/notification.service.d.ts.map +1 -1
- package/dist/types/modules/tournament/participant/participant.repository.d.ts +1 -0
- package/dist/types/modules/tournament/participant/participant.repository.d.ts.map +1 -1
- package/dist/types/modules/tournament/participant/participant.service.d.ts +1 -0
- package/dist/types/modules/tournament/participant/participant.service.d.ts.map +1 -1
- package/dist/types/modules/tournament/reward/reward.builder.d.ts.map +1 -1
- package/dist/types/modules/tournament/reward/reward.types.d.ts +1 -0
- package/dist/types/modules/tournament/reward/reward.types.d.ts.map +1 -1
- package/dist/types/modules/tournament/schedule/schedule.service.d.ts +7 -0
- package/dist/types/modules/tournament/schedule/schedule.service.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -44,6 +44,7 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
44
44
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
45
|
exports.tournamentNotificationService = exports.TournamentNotificationService = void 0;
|
|
46
46
|
const typedi_1 = __importStar(require("typedi"));
|
|
47
|
+
const core_1 = require("@lyxa.ai/core");
|
|
47
48
|
const event_1 = require("@lyxa.ai/core/dist/libraries/event");
|
|
48
49
|
const notification_1 = require("@lyxa.ai/core/dist/libraries/notification");
|
|
49
50
|
const enum_1 = require("@lyxa.ai/core/dist/utilities/enum");
|
|
@@ -59,9 +60,6 @@ let TournamentNotificationService = class TournamentNotificationService {
|
|
|
59
60
|
throw new Error(`No notification template for tag: ${tag}`);
|
|
60
61
|
return t;
|
|
61
62
|
}
|
|
62
|
-
hasNotPredicted(participant, matchId) {
|
|
63
|
-
return !participant.predictions.some(p => p.matchId.toString() === matchId.toString());
|
|
64
|
-
}
|
|
65
63
|
async notifyGlobal(notification) {
|
|
66
64
|
await (0, event_1.publishEvent)(new notification_1.NotificationGlobalEvent({
|
|
67
65
|
title: notification.title,
|
|
@@ -77,37 +75,97 @@ let TournamentNotificationService = class TournamentNotificationService {
|
|
|
77
75
|
}));
|
|
78
76
|
}
|
|
79
77
|
async notifyUsers(notification, userIds) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
78
|
+
const logger = (0, core_1.getLibraries)().getLoggerKit();
|
|
79
|
+
try {
|
|
80
|
+
await Promise.all(userIds.map(recipientId => (0, event_1.publishEvent)(new notification_1.NotificationEvent({
|
|
81
|
+
title: notification.title,
|
|
82
|
+
body: notification.body,
|
|
83
|
+
data: {
|
|
84
|
+
saveNotification: true,
|
|
85
|
+
accountType: enum_1.NotificationAccountType.USER,
|
|
86
|
+
recipientId,
|
|
87
|
+
isGlobal: false,
|
|
88
|
+
isClickable: true,
|
|
89
|
+
clickType: enum_1.ClickType.CLICKABLE_TOURNAMENT,
|
|
90
|
+
...notification,
|
|
91
|
+
},
|
|
92
|
+
}))));
|
|
93
|
+
logger.info('Tournament user notifications dispatched', {
|
|
94
|
+
tag: 'notification.queue.tournament',
|
|
95
|
+
data: {
|
|
96
|
+
payload: {
|
|
97
|
+
saveNotification: true,
|
|
98
|
+
accountType: enum_1.NotificationAccountType.USER,
|
|
99
|
+
userIds,
|
|
100
|
+
isGlobal: false,
|
|
101
|
+
isClickable: true,
|
|
102
|
+
clickType: enum_1.ClickType.CLICKABLE_TOURNAMENT,
|
|
103
|
+
...notification,
|
|
104
|
+
},
|
|
105
|
+
tournamentId: notification.tournamentId,
|
|
106
|
+
type: notification.tournamentNotificationType,
|
|
107
|
+
recipientCount: userIds.length,
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
logger.error('Failed to dispatch tournament user notifications', error, {
|
|
113
|
+
tag: 'notification.queue.tournament',
|
|
114
|
+
data: {
|
|
115
|
+
tournamentId: notification.tournamentId,
|
|
116
|
+
type: notification.tournamentNotificationType,
|
|
117
|
+
recipientCount: userIds.length,
|
|
118
|
+
payload: {
|
|
119
|
+
saveNotification: true,
|
|
120
|
+
accountType: enum_1.NotificationAccountType.USER,
|
|
121
|
+
userIds,
|
|
122
|
+
isGlobal: false,
|
|
123
|
+
isClickable: true,
|
|
124
|
+
clickType: enum_1.ClickType.CLICKABLE_TOURNAMENT,
|
|
125
|
+
...notification,
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
}
|
|
93
130
|
}
|
|
94
|
-
async
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
131
|
+
async dispatchScheduledReminder(ctx) {
|
|
132
|
+
if (ctx.target === enum_1.TournamentScheduledNotificationTarget.GLOBAL) {
|
|
133
|
+
await this.notifyGlobal(this.buildBaseMessage(ctx));
|
|
134
|
+
return;
|
|
98
135
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
deepLinkRoute,
|
|
109
|
-
}, unpredicted.map(p => p.userId));
|
|
136
|
+
const recipients = await this.resolveReminderRecipients(ctx);
|
|
137
|
+
if (!recipients.length)
|
|
138
|
+
return;
|
|
139
|
+
await this.notifyUsers(this.buildTargetedMessage(ctx), recipients.map(p => p.userId));
|
|
140
|
+
}
|
|
141
|
+
resolveReminderRecipients(ctx) {
|
|
142
|
+
const { tournament, match, type } = ctx;
|
|
143
|
+
if (type === enum_1.TournamentNotificationTag.PREDICTION_REMINDER_1_HOUR) {
|
|
144
|
+
return this.participantService.getPredicted(tournament._id, match._id);
|
|
110
145
|
}
|
|
146
|
+
return this.participantService.getUnpredicted(tournament._id, [match.team1.teamId, match.team2.teamId], match._id);
|
|
147
|
+
}
|
|
148
|
+
buildBaseMessage(ctx) {
|
|
149
|
+
const { title, body } = this.getTemplate(ctx.templates, ctx.type);
|
|
150
|
+
return {
|
|
151
|
+
title: this.withTeamNames(title, ctx.match),
|
|
152
|
+
body: this.withTeamNames(body, ctx.match),
|
|
153
|
+
tournamentNotificationType: ctx.type,
|
|
154
|
+
tournamentId: ctx.tournament._id.toString(),
|
|
155
|
+
deepLinkRoute: ctx.tournament.deepLinkRoute,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
buildTargetedMessage(ctx) {
|
|
159
|
+
return {
|
|
160
|
+
...this.buildBaseMessage(ctx),
|
|
161
|
+
matchId: ctx.match._id.toString(),
|
|
162
|
+
predictionExpiryTime: ctx.match.startingDate,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
withTeamNames(text, match) {
|
|
166
|
+
return text
|
|
167
|
+
.replace(/{team1}/g, match.team1.name)
|
|
168
|
+
.replace(/{team2}/g, match.team2.name);
|
|
111
169
|
}
|
|
112
170
|
};
|
|
113
171
|
exports.TournamentNotificationService = TournamentNotificationService;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notification.service.js","sourceRoot":"/","sources":["modules/tournament/notification/notification.service.ts"],"names":[],"mappings":"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","sourcesContent":["import Container, {Service} from 'typedi';\nimport {mongoose} from '@typegoose/typegoose';\nimport {publishEvent} from '@lyxa.ai/core/dist/libraries/event';\nimport {NotificationEvent, NotificationGlobalEvent} from '@lyxa.ai/core/dist/libraries/notification';\nimport {\n ClickType,\n NotificationAccountType,\n TournamentNotificationTag,\n TournamentScheduledNotificationTarget\n} from '@lyxa.ai/core/dist/utilities/enum';\nimport {NotificationMessage} from '@lyxa.ai/core/dist/libraries/mongo/models';\nimport {ParticipantService} from '../participant/participant.service';\nimport {TournamentParticipantOutputDTO} from '../participant/participant.validation';\nimport {NotificationObject} from './notification.config';\n\n@Service()\nexport class TournamentNotificationService {\n private participantService: ParticipantService;\n\n constructor() {\n this.participantService = Container.get(ParticipantService);\n }\n\n private getTemplate(templates: Map<string, NotificationMessage>, tag: string): NotificationMessage {\n const t = templates.get(tag);\n if (!t) throw new Error(`No notification template for tag: ${tag}`);\n return t;\n }\n\n private hasNotPredicted(participant: TournamentParticipantOutputDTO, matchId: mongoose.Types.ObjectId): boolean {\n return !participant.predictions.some(p => p.matchId.toString() === matchId.toString());\n }\n\n public async notifyGlobal(notification: NotificationObject): Promise<void> {\n await publishEvent(\n new NotificationGlobalEvent({\n title: notification.title,\n body: notification.body,\n data: {\n saveNotification: true,\n accountType: NotificationAccountType.USER,\n isGlobal: true,\n isClickable: true,\n clickType: ClickType.CLICKABLE_TOURNAMENT,\n ...notification,\n },\n })\n );\n }\n\n public async notifyUsers(notification: NotificationObject, userIds: mongoose.Types.ObjectId[]): Promise<void> {\n await Promise.all(\n userIds.map(recipientId =>\n publishEvent(\n new NotificationEvent({\n title: notification.title,\n body: notification.body,\n data: {\n saveNotification: true,\n accountType: NotificationAccountType.USER,\n recipientId,\n isGlobal: false,\n isClickable: true,\n clickType: ClickType.CLICKABLE_TOURNAMENT,\n ...notification,\n },\n })\n )\n )\n );\n }\n\n public async dispatchScheduledJob(\n type: TournamentNotificationTag,\n target: TournamentScheduledNotificationTarget,\n templates: Map<TournamentNotificationTag, NotificationMessage>,\n tournamentId: mongoose.Types.ObjectId,\n teamIds: mongoose.Types.ObjectId[],\n matchId: mongoose.Types.ObjectId,\n matchStartTime: Date,\n deepLinkRoute?: string\n ): Promise<void> {\n const {title, body} = this.getTemplate(templates, type);\n\n if (target === TournamentScheduledNotificationTarget.GLOBAL) {\n await this.notifyGlobal({title, body, tournamentNotificationType: type, tournamentId: tournamentId.toString(), deepLinkRoute});\n } else {\n const unpredicted = await this.participantService.getUnpredicted(tournamentId, teamIds, matchId);\n await this.notifyUsers(\n {\n title,\n body,\n tournamentNotificationType: type,\n predictionExpiryTime: matchStartTime,\n matchId: matchId.toString(),\n tournamentId: tournamentId.toString(),\n deepLinkRoute,\n },\n unpredicted.map(p => p.userId)\n );\n }\n }\n}\n\nexport const tournamentNotificationService = Container.get(TournamentNotificationService);\n"]}
|
|
1
|
+
{"version":3,"file":"notification.service.js","sourceRoot":"/","sources":["modules/tournament/notification/notification.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iDAA0C;AAE1C,wCAA2C;AAC3C,8DAAgE;AAChE,4EAAqG;AACrG,4DAK2C;AAE3C,4EAAsE;AAc/D,IAAM,6BAA6B,GAAnC,MAAM,6BAA6B;IAC9B,kBAAkB,CAAqB;IAE/C;QACI,IAAI,CAAC,kBAAkB,GAAG,gBAAS,CAAC,GAAG,CAAC,wCAAkB,CAAC,CAAC;IAChE,CAAC;IAEO,WAAW,CAAC,SAA2C,EAAE,GAAW;QACxE,MAAM,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,GAAG,EAAE,CAAC,CAAC;QACpE,OAAO,CAAC,CAAC;IACb,CAAC;IAEM,KAAK,CAAC,YAAY,CAAC,YAAgC;QACtD,MAAM,IAAA,oBAAY,EACd,IAAI,sCAAuB,CAAC;YACxB,KAAK,EAAE,YAAY,CAAC,KAAK;YACzB,IAAI,EAAE,YAAY,CAAC,IAAI;YACvB,IAAI,EAAE;gBACF,gBAAgB,EAAE,IAAI;gBACtB,WAAW,EAAE,8BAAuB,CAAC,IAAI;gBACzC,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,IAAI;gBACjB,SAAS,EAAE,gBAAS,CAAC,oBAAoB;gBACzC,GAAG,YAAY;aAClB;SACJ,CAAC,CACL,CAAC;IACN,CAAC;IAEM,KAAK,CAAC,WAAW,CAAC,YAAgC,EAAE,OAAkC;QACzF,MAAM,MAAM,GAAG,IAAA,mBAAY,GAAE,CAAC,YAAY,EAAE,CAAC;QAC7C,IAAI,CAAC;YACD,MAAM,OAAO,CAAC,GAAG,CACb,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CACtB,IAAA,oBAAY,EACR,IAAI,gCAAiB,CAAC;gBAClB,KAAK,EAAE,YAAY,CAAC,KAAK;gBACzB,IAAI,EAAE,YAAY,CAAC,IAAI;gBACvB,IAAI,EAAE;oBACF,gBAAgB,EAAE,IAAI;oBACtB,WAAW,EAAE,8BAAuB,CAAC,IAAI;oBACzC,WAAW;oBACX,QAAQ,EAAE,KAAK;oBACf,WAAW,EAAE,IAAI;oBACjB,SAAS,EAAE,gBAAS,CAAC,oBAAoB;oBACzC,GAAG,YAAY;iBAClB;aACJ,CAAC,CACL,CACJ,CACJ,CAAC;YAEF,MAAM,CAAC,IAAI,CAAC,0CAA0C,EAAE;gBACpD,GAAG,EAAE,+BAA+B;gBACpC,IAAI,EAAE;oBACF,OAAO,EAAE;wBACL,gBAAgB,EAAE,IAAI;wBACtB,WAAW,EAAE,8BAAuB,CAAC,IAAI;wBACzC,OAAO;wBACP,QAAQ,EAAE,KAAK;wBACf,WAAW,EAAE,IAAI;wBACjB,SAAS,EAAE,gBAAS,CAAC,oBAAoB;wBACzC,GAAG,YAAY;qBAClB;oBACD,YAAY,EAAE,YAAY,CAAC,YAAY;oBACvC,IAAI,EAAE,YAAY,CAAC,0BAA0B;oBAC7C,cAAc,EAAE,OAAO,CAAC,MAAM;iBACjC;aACJ,CAAC,CAAC;QACP,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,CAAC,KAAK,CAAC,kDAAkD,EAAE,KAAK,EAAE;gBACpE,GAAG,EAAE,+BAA+B;gBACpC,IAAI,EAAE;oBACF,YAAY,EAAE,YAAY,CAAC,YAAY;oBACvC,IAAI,EAAE,YAAY,CAAC,0BAA0B;oBAC7C,cAAc,EAAE,OAAO,CAAC,MAAM;oBAC9B,OAAO,EAAE;wBACL,gBAAgB,EAAE,IAAI;wBACtB,WAAW,EAAE,8BAAuB,CAAC,IAAI;wBACzC,OAAO;wBACP,QAAQ,EAAE,KAAK;wBACf,WAAW,EAAE,IAAI;wBACjB,SAAS,EAAE,gBAAS,CAAC,oBAAoB;wBACzC,GAAG,YAAY;qBAClB;iBACJ;aACJ,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IAEM,KAAK,CAAC,yBAAyB,CAAC,GAA6B;QAChE,IAAI,GAAG,CAAC,MAAM,KAAK,4CAAqC,CAAC,MAAM,EAAE,CAAC;YAC9D,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;YACpD,OAAO;QACX,CAAC;QAED,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,CAAC;QAC7D,IAAI,CAAC,UAAU,CAAC,MAAM;YAAE,OAAO;QAE/B,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1F,CAAC;IAEO,yBAAyB,CAAC,GAA6B;QAC3D,MAAM,EAAC,UAAU,EAAE,KAAK,EAAE,IAAI,EAAC,GAAG,GAAG,CAAC;QAEtC,IAAI,IAAI,KAAK,gCAAyB,CAAC,0BAA0B,EAAE,CAAC;YAChE,OAAO,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3E,CAAC;QAED,OAAO,IAAI,CAAC,kBAAkB,CAAC,cAAc,CACzC,UAAU,CAAC,GAAG,EACd,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,EACxC,KAAK,CAAC,GAAG,CACZ,CAAC;IACN,CAAC;IAEO,gBAAgB,CAAC,GAA6B;QAClD,MAAM,EAAC,KAAK,EAAE,IAAI,EAAC,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QAChE,OAAO;YACH,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC;YAC3C,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC;YACzC,0BAA0B,EAAE,GAAG,CAAC,IAAI;YACpC,YAAY,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE;YAC3C,aAAa,EAAE,GAAG,CAAC,UAAU,CAAC,aAAa;SAC9C,CAAC;IACN,CAAC;IAEO,oBAAoB,CAAC,GAA6B;QACtD,OAAO;YACH,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC;YAC7B,OAAO,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE;YACjC,oBAAoB,EAAE,GAAG,CAAC,KAAK,CAAC,YAAY;SAC/C,CAAC;IACN,CAAC;IAEO,aAAa,CAAC,IAAY,EAAE,KAAsB;QACtD,OAAO,IAAI;aACN,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC;aACrC,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/C,CAAC;CACJ,CAAA;AA7IY,sEAA6B;wCAA7B,6BAA6B;IADzC,IAAA,gBAAO,GAAE;;GACG,6BAA6B,CA6IzC;AAEY,QAAA,6BAA6B,GAAG,gBAAS,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC","sourcesContent":["import Container, {Service} from 'typedi';\nimport {mongoose} from '@typegoose/typegoose';\nimport {getLibraries} from '@lyxa.ai/core';\nimport {publishEvent} from '@lyxa.ai/core/dist/libraries/event';\nimport {NotificationEvent, NotificationGlobalEvent} from '@lyxa.ai/core/dist/libraries/notification';\nimport {\n ClickType,\n NotificationAccountType,\n TournamentNotificationTag,\n TournamentScheduledNotificationTarget\n} from '@lyxa.ai/core/dist/utilities/enum';\nimport {NotificationMessage, TournamentMatch} from '@lyxa.ai/core/dist/libraries/mongo/models';\nimport {ParticipantService} from '../participant/participant.service';\nimport {TournamentParticipantOutputDTO} from '../participant/participant.validation';\nimport {TournamentDocument} from '../config/config.types';\nimport {NotificationObject} from './notification.config';\n\nexport interface ScheduledReminderContext {\n type: TournamentNotificationTag;\n target: TournamentScheduledNotificationTarget;\n templates: Map<TournamentNotificationTag, NotificationMessage>;\n tournament: TournamentDocument;\n match: TournamentMatch;\n}\n\n@Service()\nexport class TournamentNotificationService {\n private participantService: ParticipantService;\n\n constructor() {\n this.participantService = Container.get(ParticipantService);\n }\n\n private getTemplate(templates: Map<string, NotificationMessage>, tag: string): NotificationMessage {\n const t = templates.get(tag);\n if (!t) throw new Error(`No notification template for tag: ${tag}`);\n return t;\n }\n\n public async notifyGlobal(notification: NotificationObject): Promise<void> {\n await publishEvent(\n new NotificationGlobalEvent({\n title: notification.title,\n body: notification.body,\n data: {\n saveNotification: true,\n accountType: NotificationAccountType.USER,\n isGlobal: true,\n isClickable: true,\n clickType: ClickType.CLICKABLE_TOURNAMENT,\n ...notification,\n },\n })\n );\n }\n\n public async notifyUsers(notification: NotificationObject, userIds: mongoose.Types.ObjectId[]): Promise<void> {\n const logger = getLibraries().getLoggerKit();\n try {\n await Promise.all(\n userIds.map(recipientId =>\n publishEvent(\n new NotificationEvent({\n title: notification.title,\n body: notification.body,\n data: {\n saveNotification: true,\n accountType: NotificationAccountType.USER,\n recipientId,\n isGlobal: false,\n isClickable: true,\n clickType: ClickType.CLICKABLE_TOURNAMENT,\n ...notification,\n },\n })\n )\n )\n );\n\n logger.info('Tournament user notifications dispatched', {\n tag: 'notification.queue.tournament',\n data: {\n payload: {\n saveNotification: true,\n accountType: NotificationAccountType.USER,\n userIds,\n isGlobal: false,\n isClickable: true,\n clickType: ClickType.CLICKABLE_TOURNAMENT,\n ...notification,\n },\n tournamentId: notification.tournamentId,\n type: notification.tournamentNotificationType,\n recipientCount: userIds.length,\n },\n });\n } catch (error) {\n logger.error('Failed to dispatch tournament user notifications', error, {\n tag: 'notification.queue.tournament',\n data: {\n tournamentId: notification.tournamentId,\n type: notification.tournamentNotificationType,\n recipientCount: userIds.length,\n payload: {\n saveNotification: true,\n accountType: NotificationAccountType.USER,\n userIds,\n isGlobal: false,\n isClickable: true,\n clickType: ClickType.CLICKABLE_TOURNAMENT,\n ...notification,\n },\n },\n });\n }\n }\n\n public async dispatchScheduledReminder(ctx: ScheduledReminderContext): Promise<void> {\n if (ctx.target === TournamentScheduledNotificationTarget.GLOBAL) {\n await this.notifyGlobal(this.buildBaseMessage(ctx));\n return;\n }\n\n const recipients = await this.resolveReminderRecipients(ctx);\n if (!recipients.length) return;\n\n await this.notifyUsers(this.buildTargetedMessage(ctx), recipients.map(p => p.userId));\n }\n\n private resolveReminderRecipients(ctx: ScheduledReminderContext): Promise<TournamentParticipantOutputDTO[]> {\n const {tournament, match, type} = ctx;\n\n if (type === TournamentNotificationTag.PREDICTION_REMINDER_1_HOUR) {\n return this.participantService.getPredicted(tournament._id, match._id);\n }\n\n return this.participantService.getUnpredicted(\n tournament._id,\n [match.team1.teamId, match.team2.teamId],\n match._id\n );\n }\n\n private buildBaseMessage(ctx: ScheduledReminderContext): NotificationObject {\n const {title, body} = this.getTemplate(ctx.templates, ctx.type);\n return {\n title: this.withTeamNames(title, ctx.match),\n body: this.withTeamNames(body, ctx.match),\n tournamentNotificationType: ctx.type,\n tournamentId: ctx.tournament._id.toString(),\n deepLinkRoute: ctx.tournament.deepLinkRoute,\n };\n }\n\n private buildTargetedMessage(ctx: ScheduledReminderContext): NotificationObject {\n return {\n ...this.buildBaseMessage(ctx),\n matchId: ctx.match._id.toString(),\n predictionExpiryTime: ctx.match.startingDate,\n };\n }\n\n private withTeamNames(text: string, match: TournamentMatch): string {\n return text\n .replace(/{team1}/g, match.team1.name)\n .replace(/{team2}/g, match.team2.name);\n }\n}\n\nexport const tournamentNotificationService = Container.get(TournamentNotificationService);\n"]}
|
|
@@ -11,6 +11,7 @@ export declare class TournamentParticipantRepository {
|
|
|
11
11
|
updateToJoined(userId: mongoose.Types.ObjectId, tournamentId: mongoose.Types.ObjectId, teamId: mongoose.Types.ObjectId): Promise<TournamentParticipantOutputDTO | null>;
|
|
12
12
|
createIfAbsent(userId: mongoose.Types.ObjectId, tournamentId: mongoose.Types.ObjectId, status: string): Promise<void>;
|
|
13
13
|
findByTournamentWithoutPrediction(tournamentId: mongoose.Types.ObjectId, teamIds: mongoose.Types.ObjectId[], matchId: mongoose.Types.ObjectId): Promise<TournamentParticipantOutputDTO[]>;
|
|
14
|
+
findByTournamentWithPrediction(tournamentId: mongoose.Types.ObjectId, matchId: mongoose.Types.ObjectId): Promise<TournamentParticipantOutputDTO[]>;
|
|
14
15
|
}
|
|
15
16
|
export declare const tournamentParticipantRepository: TournamentParticipantRepository;
|
|
16
17
|
//# sourceMappingURL=participant.repository.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"participant.repository.d.ts","sourceRoot":"/","sources":["modules/tournament/participant/participant.repository.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AAE1E,qBACa,+BAA+B;IACxC,OAAO,CAAC,gBAAgB,CAAoC;;IAMtD,yBAAyB,CAC3B,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAC/B,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GACtC,OAAO,CAAC,OAAO,CAAC;IAIb,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,8BAA8B,CAAC;IAK9D,uBAAuB,CACzB,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAC/B,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GACtC,OAAO,CAAC,8BAA8B,GAAG,IAAI,CAAC;IAI3C,gBAAgB,CAAC,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,8BAA8B,EAAE,CAAC;IAIlG,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,8BAA8B,GAAG,IAAI,CAAC;IAO3F,cAAc,CAChB,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAC/B,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EACrC,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAChC,OAAO,CAAC,8BAA8B,GAAG,IAAI,CAAC;IAM3C,cAAc,CAChB,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAC/B,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EACrC,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAQH,iCAAiC,CAC1C,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EACrC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,EAClC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GACjC,OAAO,CAAC,8BAA8B,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"participant.repository.d.ts","sourceRoot":"/","sources":["modules/tournament/participant/participant.repository.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AAE1E,qBACa,+BAA+B;IACxC,OAAO,CAAC,gBAAgB,CAAoC;;IAMtD,yBAAyB,CAC3B,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAC/B,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GACtC,OAAO,CAAC,OAAO,CAAC;IAIb,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,8BAA8B,CAAC;IAK9D,uBAAuB,CACzB,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAC/B,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GACtC,OAAO,CAAC,8BAA8B,GAAG,IAAI,CAAC;IAI3C,gBAAgB,CAAC,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,8BAA8B,EAAE,CAAC;IAIlG,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,8BAA8B,GAAG,IAAI,CAAC;IAO3F,cAAc,CAChB,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAC/B,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EACrC,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAChC,OAAO,CAAC,8BAA8B,GAAG,IAAI,CAAC;IAM3C,cAAc,CAChB,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAC/B,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EACrC,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAQH,iCAAiC,CAC1C,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EACrC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,EAClC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GACjC,OAAO,CAAC,8BAA8B,EAAE,CAAC;IAW/B,8BAA8B,CACvC,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EACrC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GACjC,OAAO,CAAC,8BAA8B,EAAE,CAAC;CAU/C;AAED,eAAO,MAAM,+BAA+B,iCAAiD,CAAC"}
|
|
@@ -87,6 +87,15 @@ let TournamentParticipantRepository = class TournamentParticipantRepository {
|
|
|
87
87
|
.lean()
|
|
88
88
|
.exec();
|
|
89
89
|
}
|
|
90
|
+
async findByTournamentWithPrediction(tournamentId, matchId) {
|
|
91
|
+
return this.participantModel
|
|
92
|
+
.find({
|
|
93
|
+
tournamentId,
|
|
94
|
+
'predictions.matchId': matchId,
|
|
95
|
+
})
|
|
96
|
+
.lean()
|
|
97
|
+
.exec();
|
|
98
|
+
}
|
|
90
99
|
};
|
|
91
100
|
exports.TournamentParticipantRepository = TournamentParticipantRepository;
|
|
92
101
|
exports.TournamentParticipantRepository = TournamentParticipantRepository = __decorate([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"participant.repository.js","sourceRoot":"/","sources":["modules/tournament/participant/participant.repository.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iDAA4C;AAE5C,sEAAuF;AAIhF,IAAM,+BAA+B,GAArC,MAAM,+BAA+B;IAChC,gBAAgB,CAAoC;IAE5D;QACI,IAAI,CAAC,gBAAgB,GAAG,mCAA0B,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,yBAAyB,CAC3B,MAA+B,EAC/B,YAAqC;QAErC,OAAO,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;IAC5E,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAa;QACtB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACtD,OAAO,GAAG,CAAC,QAAQ,EAA+C,CAAC;IACvE,CAAC;IAED,KAAK,CAAC,uBAAuB,CACzB,MAA+B,EAC/B,YAAqC;QAErC,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC,IAAI,EAAoD,CAAC;IAC5H,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,YAAqC;QACxD,OAAO,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,IAAI,EAA+C,CAAC;IAC5G,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,MAA+B;QAC5C,OAAO,IAAI,CAAC,gBAAgB;aACvB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;aACnB,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC;aACvB,IAAI,EAAoD,CAAC;IAClE,CAAC;IAED,KAAK,CAAC,cAAc,CAChB,MAA+B,EAC/B,YAAqC,EACrC,MAA+B;QAE/B,OAAO,IAAI,CAAC,gBAAgB;aACvB,gBAAgB,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;aACjG,IAAI,EAAoD,CAAC;IAClE,CAAC;IAED,KAAK,CAAC,cAAc,CAChB,MAA+B,EAC/B,YAAqC,EACrC,MAAc;QAEd,MAAM,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,CACxC,EAAE,MAAM,EAAE,YAAY,EAAE,EACxB,EAAE,YAAY,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EACnE,EAAE,MAAM,EAAE,IAAI,EAAE,CACnB,CAAC;IACN,CAAC;IAEM,KAAK,CAAC,iCAAiC,CAC1C,YAAqC,EACrC,OAAkC,EAClC,OAAgC;QAEhC,OAAO,IAAI,CAAC,gBAAgB;aACvB,IAAI,CAAC;YACF,YAAY;YACZ,MAAM,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE;YACxB,qBAAqB,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE;SAC1C,CAAC;aACD,IAAI,EAAE;aACN,IAAI,EAA+C,CAAC;IAC7D,CAAC;CAEJ,CAAA;
|
|
1
|
+
{"version":3,"file":"participant.repository.js","sourceRoot":"/","sources":["modules/tournament/participant/participant.repository.ts"],"names":[],"mappings":"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","sourcesContent":["import Container, { Service } from 'typedi';\nimport { mongoose } from '@typegoose/typegoose';\nimport { TournamentParticipantModel } from '@lyxa.ai/core/dist/libraries/mongo/models';\nimport { TournamentParticipantOutputDTO } from './participant.validation';\n\n@Service()\nexport class TournamentParticipantRepository {\n private participantModel: typeof TournamentParticipantModel;\n\n constructor() {\n this.participantModel = TournamentParticipantModel;\n }\n\n async existsByUserAndTournament(\n userId: mongoose.Types.ObjectId,\n tournamentId: mongoose.Types.ObjectId\n ): Promise<boolean> {\n return !!(await this.participantModel.exists({ userId, tournamentId }));\n }\n\n async create(input: object): Promise<TournamentParticipantOutputDTO> {\n const doc = await this.participantModel.create(input);\n return doc.toObject() as unknown as TournamentParticipantOutputDTO;\n }\n\n async findByUserAndTournament(\n userId: mongoose.Types.ObjectId,\n tournamentId: mongoose.Types.ObjectId\n ): Promise<TournamentParticipantOutputDTO | null> {\n return this.participantModel.findOne({ userId, tournamentId }).lean() as Promise<TournamentParticipantOutputDTO | null>;\n }\n\n async findByTournament(tournamentId: mongoose.Types.ObjectId): Promise<TournamentParticipantOutputDTO[]> {\n return this.participantModel.find({ tournamentId }).lean() as Promise<TournamentParticipantOutputDTO[]>;\n }\n\n async findByUser(userId: mongoose.Types.ObjectId): Promise<TournamentParticipantOutputDTO | null> {\n return this.participantModel\n .findOne({ userId })\n .sort({ createdAt: -1 })\n .lean() as Promise<TournamentParticipantOutputDTO | null>;\n }\n\n async updateToJoined(\n userId: mongoose.Types.ObjectId,\n tournamentId: mongoose.Types.ObjectId,\n teamId: mongoose.Types.ObjectId\n ): Promise<TournamentParticipantOutputDTO | null> {\n return this.participantModel\n .findOneAndUpdate({ userId, tournamentId }, { $set: { status: 'joined', teamId } }, { new: true })\n .lean() as Promise<TournamentParticipantOutputDTO | null>;\n }\n\n async createIfAbsent(\n userId: mongoose.Types.ObjectId,\n tournamentId: mongoose.Types.ObjectId,\n status: string\n ): Promise<void> {\n await this.participantModel.findOneAndUpdate(\n { userId, tournamentId },\n { $setOnInsert: { userId, tournamentId, predictions: [], status } },\n { upsert: true }\n );\n }\n\n public async findByTournamentWithoutPrediction(\n tournamentId: mongoose.Types.ObjectId,\n teamIds: mongoose.Types.ObjectId[],\n matchId: mongoose.Types.ObjectId\n ): Promise<TournamentParticipantOutputDTO[]> {\n return this.participantModel\n .find({\n tournamentId,\n teamId: { $in: teamIds },\n 'predictions.matchId': { $ne: matchId },\n })\n .lean()\n .exec() as Promise<TournamentParticipantOutputDTO[]>;\n }\n\n public async findByTournamentWithPrediction(\n tournamentId: mongoose.Types.ObjectId,\n matchId: mongoose.Types.ObjectId\n ): Promise<TournamentParticipantOutputDTO[]> {\n return this.participantModel\n .find({\n tournamentId,\n 'predictions.matchId': matchId,\n })\n .lean()\n .exec() as Promise<TournamentParticipantOutputDTO[]>;\n }\n\n}\n\nexport const tournamentParticipantRepository = Container.get(TournamentParticipantRepository);\n"]}
|
|
@@ -10,6 +10,7 @@ export declare class ParticipantService {
|
|
|
10
10
|
getByUserAndTournament(userId: mongoose.Types.ObjectId, tournamentId: mongoose.Types.ObjectId): Promise<TournamentParticipantOutputDTO>;
|
|
11
11
|
getAll(tournamentId: mongoose.Types.ObjectId): Promise<TournamentParticipantOutputDTO[]>;
|
|
12
12
|
getUnpredicted(tournamentId: mongoose.Types.ObjectId, teamIds: mongoose.Types.ObjectId[], matchId: mongoose.Types.ObjectId): Promise<TournamentParticipantOutputDTO[]>;
|
|
13
|
+
getPredicted(tournamentId: mongoose.Types.ObjectId, matchId: mongoose.Types.ObjectId): Promise<TournamentParticipantOutputDTO[]>;
|
|
13
14
|
}
|
|
14
15
|
export declare const participantService: ParticipantService;
|
|
15
16
|
//# sourceMappingURL=participant.service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"participant.service.d.ts","sourceRoot":"/","sources":["modules/tournament/participant/participant.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAG9C,OAAO,EACH,sBAAsB,EACtB,0BAA0B,EAC1B,8BAA8B,EACjC,MAAM,0BAA0B,CAAC;AAOlC,qBACa,kBAAkB;IAC3B,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,eAAe,CAA4B;;IAOnD,OAAO,CAAC,gBAAgB;IAKX,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,8BAA8B,CAAC;IAuB7G,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,0BAA0B,GAAG,OAAO,CAAC,IAAI,CAAC;IAO3F,sBAAsB,CAC/B,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAC/B,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GACtC,OAAO,CAAC,8BAA8B,CAAC;IAM7B,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,8BAA8B,EAAE,CAAC;IAMxF,cAAc,CACvB,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EACrC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,EAClC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GACjC,OAAO,CAAC,8BAA8B,EAAE,CAAC;CAM/C;AAED,eAAO,MAAM,kBAAkB,oBAAoC,CAAC"}
|
|
1
|
+
{"version":3,"file":"participant.service.d.ts","sourceRoot":"/","sources":["modules/tournament/participant/participant.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAG9C,OAAO,EACH,sBAAsB,EACtB,0BAA0B,EAC1B,8BAA8B,EACjC,MAAM,0BAA0B,CAAC;AAOlC,qBACa,kBAAkB;IAC3B,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,eAAe,CAA4B;;IAOnD,OAAO,CAAC,gBAAgB;IAKX,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,8BAA8B,CAAC;IAuB7G,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,0BAA0B,GAAG,OAAO,CAAC,IAAI,CAAC;IAO3F,sBAAsB,CAC/B,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAC/B,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GACtC,OAAO,CAAC,8BAA8B,CAAC;IAM7B,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,8BAA8B,EAAE,CAAC;IAMxF,cAAc,CACvB,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EACrC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,EAClC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GACjC,OAAO,CAAC,8BAA8B,EAAE,CAAC;IAM/B,YAAY,CACrB,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EACrC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GACjC,OAAO,CAAC,8BAA8B,EAAE,CAAC;CAM/C;AAED,eAAO,MAAM,kBAAkB,oBAAoC,CAAC"}
|
|
@@ -105,6 +105,12 @@ let ParticipantService = class ParticipantService {
|
|
|
105
105
|
throw (0, error_common_1.notFoundError)('Tournament not found');
|
|
106
106
|
return this.repository.findByTournamentWithoutPrediction(tournamentId, teamIds, matchId);
|
|
107
107
|
}
|
|
108
|
+
async getPredicted(tournamentId, matchId) {
|
|
109
|
+
const tournament = await this.matchRepository.findById(tournamentId);
|
|
110
|
+
if (!tournament)
|
|
111
|
+
throw (0, error_common_1.notFoundError)('Tournament not found');
|
|
112
|
+
return this.repository.findByTournamentWithPrediction(tournamentId, matchId);
|
|
113
|
+
}
|
|
108
114
|
};
|
|
109
115
|
exports.ParticipantService = ParticipantService;
|
|
110
116
|
exports.ParticipantService = ParticipantService = __decorate([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"participant.service.js","sourceRoot":"/","sources":["modules/tournament/participant/participant.service.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"participant.service.js","sourceRoot":"/","sources":["modules/tournament/participant/participant.service.ts"],"names":[],"mappings":"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","sourcesContent":["import Container, {Service} from 'typedi';\nimport {TRPCError} from '@trpc/server';\nimport {mongoose} from '@typegoose/typegoose';\nimport {badRequestError, conflictError, notFoundError} from '@lyxa.ai/core/dist/utilities/error-common';\nimport {TournamentParticipantRepository} from './participant.repository';\nimport {\n JoinTournamentInputDTO,\n MarkSeenTournamentInputDTO,\n TournamentParticipantOutputDTO,\n} from './participant.validation';\nimport {TournamentMatchRepository} from '../match/match.repository';\nimport {Tournament as TournamentType} from '@lyxa.ai/core/dist/libraries/mongo/models';\nimport {ensureCampaignActive} from '../tournament.utils';\nimport {ParticipantBuilder} from './participant.builder';\nimport {TournamentParticipantStatus} from '@lyxa.ai/core/dist/utilities/enum';\n\n@Service()\nexport class ParticipantService {\n private repository: TournamentParticipantRepository;\n private matchRepository: TournamentMatchRepository;\n\n constructor() {\n this.repository = Container.get(TournamentParticipantRepository);\n this.matchRepository = Container.get(TournamentMatchRepository);\n }\n\n private ensureTeamExists(tournament: TournamentType, teamId: mongoose.Types.ObjectId) {\n const exists = tournament.teams.some(team => team._id.toString() === teamId.toString());\n if (!exists) throw badRequestError('Selected team does not exist in this tournament');\n }\n\n public async join(userId: mongoose.Types.ObjectId, input: JoinTournamentInputDTO): Promise<TournamentParticipantOutputDTO> {\n const tournament = await this.matchRepository.findById(input.tournamentId);\n if (!tournament) throw notFoundError('Tournament not found');\n\n ensureCampaignActive(tournament);\n this.ensureTeamExists(tournament, input.teamId);\n\n const existing = await this.repository.findByUserAndTournament(userId, input.tournamentId);\n if (existing?.status === TournamentParticipantStatus.JOINED) throw conflictError('You have already joined this tournament');\n\n if (existing) {\n const updated = await this.repository.updateToJoined(userId, input.tournamentId, input.teamId);\n if (!updated) throw new TRPCError({code: 'INTERNAL_SERVER_ERROR', message: 'Failed to join tournament'});\n return updated;\n }\n\n const result = await this.repository.create(\n ParticipantBuilder.buildNewParticipant(userId, input.tournamentId, input.teamId)\n );\n\n return result;\n }\n\n public async markSeen(userId: mongoose.Types.ObjectId, input: MarkSeenTournamentInputDTO): Promise<void> {\n const exists = await this.matchRepository.findById(input.tournamentId);\n if (!exists) throw notFoundError('Tournament not found');\n\n await this.repository.createIfAbsent(userId, input.tournamentId, TournamentParticipantStatus.SEEN);\n }\n\n public async getByUserAndTournament(\n userId: mongoose.Types.ObjectId,\n tournamentId: mongoose.Types.ObjectId\n ): Promise<TournamentParticipantOutputDTO> {\n const participant = await this.repository.findByUserAndTournament(userId, tournamentId);\n if (!participant) throw notFoundError('You have not joined this tournament');\n return participant;\n }\n\n public async getAll(tournamentId: mongoose.Types.ObjectId): Promise<TournamentParticipantOutputDTO[]> {\n const tournament = await this.matchRepository.findById(tournamentId);\n if (!tournament) throw notFoundError('Tournament not found');\n return this.repository.findByTournament(tournamentId);\n }\n\n public async getUnpredicted(\n tournamentId: mongoose.Types.ObjectId,\n teamIds: mongoose.Types.ObjectId[],\n matchId: mongoose.Types.ObjectId\n ): Promise<TournamentParticipantOutputDTO[]> {\n const tournament = await this.matchRepository.findById(tournamentId);\n if (!tournament) throw notFoundError('Tournament not found');\n return this.repository.findByTournamentWithoutPrediction(tournamentId, teamIds, matchId);\n }\n\n public async getPredicted(\n tournamentId: mongoose.Types.ObjectId,\n matchId: mongoose.Types.ObjectId\n ): Promise<TournamentParticipantOutputDTO[]> {\n const tournament = await this.matchRepository.findById(tournamentId);\n if (!tournament) throw notFoundError('Tournament not found');\n return this.repository.findByTournamentWithPrediction(tournamentId, matchId);\n }\n\n}\n\nexport const participantService = Container.get(ParticipantService);\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reward.builder.d.ts","sourceRoot":"/","sources":["modules/tournament/reward/reward.builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAE9C,OAAO,EAAC,kBAAkB,EAAE,mBAAmB,EAAE,aAAa,EAAC,MAAM,gBAAgB,CAAC;AAEtF,OAAO,EAAC,6BAA6B,EAAC,MAAM,+DAA+D,CAAC;
|
|
1
|
+
{"version":3,"file":"reward.builder.d.ts","sourceRoot":"/","sources":["modules/tournament/reward/reward.builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAE9C,OAAO,EAAC,kBAAkB,EAAE,mBAAmB,EAAE,aAAa,EAAC,MAAM,gBAAgB,CAAC;AAEtF,OAAO,EAAC,6BAA6B,EAAC,MAAM,+DAA+D,CAAC;AAc5G,qBAAa,aAAa;IACtB,MAAM,CAAC,wBAAwB,CAC3B,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAChC,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EACrC,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,EACpC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,kBAAkB,GAC3B,aAAa;IAUhB,MAAM,CAAC,gBAAgB,CACnB,OAAO,EAAE,mBAAmB,EAC5B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAG,GACnC,6BAA6B;IAWhC,OAAO,CAAC,MAAM,CAAC,kBAAkB;CAsBpC"}
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.RewardBuilder = void 0;
|
|
4
4
|
const enum_1 = require("@lyxa.ai/core/dist/utilities/enum");
|
|
5
5
|
const tournament_utils_1 = require("../tournament.utils");
|
|
6
|
-
const FWC_MIN_ORDER_VALUE = 5;
|
|
7
6
|
const FWC_ORDER_LIMIT_PER_USER = 1;
|
|
8
7
|
const FWC_COUPON_DURATION_MONTHS = 1;
|
|
9
8
|
const FWC_ELIGIBLE_ITEM_TYPES = [
|
|
@@ -44,14 +43,15 @@ class RewardBuilder {
|
|
|
44
43
|
valueType: enum_1.ValueType.PERCENTAGE,
|
|
45
44
|
value: config.percentage,
|
|
46
45
|
maxDiscountLimit: config.maxDiscountPerOrder,
|
|
46
|
+
isMaxDiscountLimitEnabled: true,
|
|
47
47
|
couponNamePrefix: config.couponNamePrefix,
|
|
48
48
|
duration: { start: now, end: expiresAt },
|
|
49
49
|
isSpendLimitEnabled: false,
|
|
50
50
|
spendLimit: null,
|
|
51
51
|
isOrderLimitPerUserEnabled: true,
|
|
52
52
|
orderLimitPerUser: FWC_ORDER_LIMIT_PER_USER,
|
|
53
|
-
isMinOrderValueEnabled:
|
|
54
|
-
minOrderValue:
|
|
53
|
+
isMinOrderValueEnabled: false,
|
|
54
|
+
minOrderValue: 0,
|
|
55
55
|
itemTypes: FWC_ELIGIBLE_ITEM_TYPES,
|
|
56
56
|
};
|
|
57
57
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reward.builder.js","sourceRoot":"/","sources":["modules/tournament/reward/reward.builder.ts"],"names":[],"mappings":";;;AACA,4DAAkF;AAElF,0DAA2C;AAG3C,MAAM,
|
|
1
|
+
{"version":3,"file":"reward.builder.js","sourceRoot":"/","sources":["modules/tournament/reward/reward.builder.ts"],"names":[],"mappings":";;;AACA,4DAAkF;AAElF,0DAA2C;AAG3C,MAAM,wBAAwB,GAAG,CAAC,CAAC;AACnC,MAAM,0BAA0B,GAAG,CAAC,CAAC;AACrC,MAAM,uBAAuB,GAAe;IACxC,eAAQ,CAAC,IAAI;IACb,eAAQ,CAAC,OAAO;IAChB,eAAQ,CAAC,QAAQ;IACjB,eAAQ,CAAC,MAAM;IACf,eAAQ,CAAC,MAAM;IACf,eAAQ,CAAC,GAAG;IACZ,eAAQ,CAAC,cAAc;CAC1B,CAAC;AAEF,MAAa,aAAa;IACtB,MAAM,CAAC,wBAAwB,CAC3B,OAAgC,EAChC,YAAqC,EACrC,SAAoC,EACpC,WAAmB,EACnB,MAA0B;QAE1B,OAAO;YACH,OAAO,EAAE,SAAS;YAClB,YAAY;YACZ,OAAO;YACP,WAAW;YACX,OAAO,EAAE,aAAa,CAAC,kBAAkB,CAAC,MAAM,CAAC;SACpD,CAAC;IACN,CAAC;IAED,MAAM,CAAC,gBAAgB,CACnB,OAA4B,EAC5B,IAAY,EACZ,MAAkC;QAElC,MAAM,EAAC,gBAAgB,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAC,GAAG,OAAO,CAAC;QACtD,OAAO;YACH,GAAG,IAAI;YACP,IAAI;YACJ,KAAK,EAAE,MAAM;YACb,KAAK,EAAE,EAAE;YACT,OAAO,EAAE,EAAE;SAC8B,CAAC;IAClD,CAAC;IAEO,MAAM,CAAC,kBAAkB,CAAC,MAA0B;QACxD,MAAM,GAAG,GAAG,IAAA,yBAAM,GAAE,CAAC;QACrB,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;QAChC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,GAAG,0BAA0B,CAAC,CAAC;QAEtE,OAAO;YACH,UAAU,EAAE,iBAAU,CAAC,eAAe;YACtC,SAAS,EAAE,gBAAS,CAAC,UAAU;YAC/B,KAAK,EAAE,MAAM,CAAC,UAAU;YACxB,gBAAgB,EAAE,MAAM,CAAC,mBAAmB;YAC5C,yBAAyB,EAAE,IAAI;YAC/B,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;YACzC,QAAQ,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAC;YACtC,mBAAmB,EAAE,KAAK;YAC1B,UAAU,EAAE,IAAI;YAChB,0BAA0B,EAAE,IAAI;YAChC,iBAAiB,EAAE,wBAAwB;YAC3C,sBAAsB,EAAE,KAAK;YAC7B,aAAa,EAAE,CAAC;YAChB,SAAS,EAAE,uBAAuB;SACrC,CAAC;IACN,CAAC;CACJ;AAtDD,sCAsDC","sourcesContent":["import {mongoose} from '@typegoose/typegoose';\nimport {CouponType, ItemType, ValueType} from '@lyxa.ai/core/dist/utilities/enum';\nimport {CouponRewardConfig, CouponRewardPayload, RewardContext} from './reward.types';\nimport {utcNow} from '../tournament.utils';\nimport {CreateIndividualUserCouponDTO} from '@modules/coupon/validations/individual-user-coupon.validation';\n\nconst FWC_ORDER_LIMIT_PER_USER = 1;\nconst FWC_COUPON_DURATION_MONTHS = 1;\nconst FWC_ELIGIBLE_ITEM_TYPES: ItemType[] = [\n ItemType.FOOD,\n ItemType.GROCERY,\n ItemType.PHARMACY,\n ItemType.COFFEE,\n ItemType.FLOWER,\n ItemType.PET,\n ItemType.HEALTHY_CORNER,\n];\n\nexport class RewardBuilder {\n static buildCouponRewardContext(\n matchId: mongoose.Types.ObjectId,\n tournamentId: mongoose.Types.ObjectId,\n winnerIds: mongoose.Types.ObjectId[],\n matchNumber: number,\n config: CouponRewardConfig\n ): RewardContext {\n return {\n userIds: winnerIds,\n tournamentId,\n matchId,\n matchNumber,\n payload: RewardBuilder.buildCouponPayload(config),\n };\n }\n\n static buildCouponInput(\n payload: CouponRewardPayload,\n code: string,\n userId: mongoose.Types.ObjectId []\n ): CreateIndividualUserCouponDTO {\n const {couponNamePrefix: _ignored, ...rest} = payload;\n return {\n ...rest,\n code,\n users: userId,\n shops: [],\n vendors: [],\n } as unknown as CreateIndividualUserCouponDTO;\n }\n\n private static buildCouponPayload(config: CouponRewardConfig): CouponRewardPayload {\n const now = utcNow();\n const expiresAt = new Date(now);\n expiresAt.setMonth(expiresAt.getMonth() + FWC_COUPON_DURATION_MONTHS);\n\n return {\n couponType: CouponType.INDIVIDUAL_USER,\n valueType: ValueType.PERCENTAGE,\n value: config.percentage,\n maxDiscountLimit: config.maxDiscountPerOrder,\n isMaxDiscountLimitEnabled: true,\n couponNamePrefix: config.couponNamePrefix,\n duration: {start: now, end: expiresAt},\n isSpendLimitEnabled: false,\n spendLimit: null,\n isOrderLimitPerUserEnabled: true,\n orderLimitPerUser: FWC_ORDER_LIMIT_PER_USER,\n isMinOrderValueEnabled: false,\n minOrderValue: 0,\n itemTypes: FWC_ELIGIBLE_ITEM_TYPES,\n };\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reward.types.d.ts","sourceRoot":"/","sources":["modules/tournament/reward/reward.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAC,MAAM,mCAAmC,CAAC;AAElF,oBAAY,UAAU;IAClB,MAAM,WAAW;CACpB;AAED,MAAM,WAAW,kBAAkB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gBAAgB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACjC,KAAK,EAAE,IAAI,CAAC;IACZ,GAAG,EAAE,IAAI,CAAC;CACb;AAED,MAAM,WAAW,mBAAmB;IAChC,UAAU,EAAE,UAAU,CAAC,eAAe,CAAC;IACvC,SAAS,EAAE,SAAS,CAAC,UAAU,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,0BAA0B,EAAE,OAAO,CAAC;IACpC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,sBAAsB,EAAE,OAAO,CAAC;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,QAAQ,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"reward.types.d.ts","sourceRoot":"/","sources":["modules/tournament/reward/reward.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAC,MAAM,mCAAmC,CAAC;AAElF,oBAAY,UAAU;IAClB,MAAM,WAAW;CACpB;AAED,MAAM,WAAW,kBAAkB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gBAAgB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACjC,KAAK,EAAE,IAAI,CAAC;IACZ,GAAG,EAAE,IAAI,CAAC;CACb;AAED,MAAM,WAAW,mBAAmB;IAChC,UAAU,EAAE,UAAU,CAAC,eAAe,CAAC;IACvC,SAAS,EAAE,SAAS,CAAC,UAAU,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,0BAA0B,EAAE,OAAO,CAAC;IACpC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,sBAAsB,EAAE,OAAO,CAAC;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,yBAAyB,EAAE,OAAO,CAAA;CACrC;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,GAAG,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC;CAChC,CAAC;AAEF,MAAM,WAAW,aAAa,CAAC,CAAC,GAAG,mBAAmB;IAClD,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;IACnC,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC;IACtC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,CAAC,CAAC;CACd"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reward.types.js","sourceRoot":"/","sources":["modules/tournament/reward/reward.types.ts"],"names":[],"mappings":";;;AAGA,IAAY,UAEX;AAFD,WAAY,UAAU;IAClB,+BAAiB,CAAA;AACrB,CAAC,EAFW,UAAU,0BAAV,UAAU,QAErB","sourcesContent":["import {mongoose} from '@typegoose/typegoose';\nimport {CouponType, ItemType, ValueType} from '@lyxa.ai/core/dist/utilities/enum';\n\nexport enum RewardType {\n COUPON = 'coupon',\n}\n\nexport interface CouponRewardConfig {\n percentage: number;\n maxDiscountPerOrder: number;\n couponNamePrefix: string;\n}\n\nexport interface CouponRewardDuration {\n start: Date;\n end: Date;\n}\n\nexport interface CouponRewardPayload {\n couponType: CouponType.INDIVIDUAL_USER;\n valueType: ValueType.PERCENTAGE;\n value: number;\n maxDiscountLimit: number;\n couponNamePrefix: string;\n duration: CouponRewardDuration;\n isSpendLimitEnabled: boolean;\n spendLimit: number | null;\n isOrderLimitPerUserEnabled: boolean;\n orderLimitPerUser: number;\n isMinOrderValueEnabled: boolean;\n minOrderValue: number;\n itemTypes: ItemType[];\n}\n\nexport type CouponRewardResult = {\n code: string;\n duration: CouponRewardDuration;\n couponOfferLabel: string;\n couponValidityLabel: string;\n _id: mongoose.Types.ObjectId;\n};\n\nexport interface RewardContext<P = CouponRewardPayload> {\n userIds: mongoose.Types.ObjectId[];\n tournamentId: mongoose.Types.ObjectId;\n matchId: mongoose.Types.ObjectId;\n matchNumber: number;\n payload: P;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"reward.types.js","sourceRoot":"/","sources":["modules/tournament/reward/reward.types.ts"],"names":[],"mappings":";;;AAGA,IAAY,UAEX;AAFD,WAAY,UAAU;IAClB,+BAAiB,CAAA;AACrB,CAAC,EAFW,UAAU,0BAAV,UAAU,QAErB","sourcesContent":["import {mongoose} from '@typegoose/typegoose';\nimport {CouponType, ItemType, ValueType} from '@lyxa.ai/core/dist/utilities/enum';\n\nexport enum RewardType {\n COUPON = 'coupon',\n}\n\nexport interface CouponRewardConfig {\n percentage: number;\n maxDiscountPerOrder: number;\n couponNamePrefix: string;\n}\n\nexport interface CouponRewardDuration {\n start: Date;\n end: Date;\n}\n\nexport interface CouponRewardPayload {\n couponType: CouponType.INDIVIDUAL_USER;\n valueType: ValueType.PERCENTAGE;\n value: number;\n maxDiscountLimit: number;\n couponNamePrefix: string;\n duration: CouponRewardDuration;\n isSpendLimitEnabled: boolean;\n spendLimit: number | null;\n isOrderLimitPerUserEnabled: boolean;\n orderLimitPerUser: number;\n isMinOrderValueEnabled: boolean;\n minOrderValue: number;\n itemTypes: ItemType[];\n isMaxDiscountLimitEnabled: boolean\n}\n\nexport type CouponRewardResult = {\n code: string;\n duration: CouponRewardDuration;\n couponOfferLabel: string;\n couponValidityLabel: string;\n _id: mongoose.Types.ObjectId;\n};\n\nexport interface RewardContext<P = CouponRewardPayload> {\n userIds: mongoose.Types.ObjectId[];\n tournamentId: mongoose.Types.ObjectId;\n matchId: mongoose.Types.ObjectId;\n matchNumber: number;\n payload: P;\n}\n"]}
|
|
@@ -7,7 +7,14 @@ export declare class ScheduleService {
|
|
|
7
7
|
private userModel;
|
|
8
8
|
constructor();
|
|
9
9
|
private dispatchTournamentActivationNotification;
|
|
10
|
+
private static readonly REMINDER_TYPES;
|
|
10
11
|
dispatchPending(): Promise<void>;
|
|
12
|
+
private dispatchDueReminders;
|
|
13
|
+
private dispatchReminder;
|
|
14
|
+
private isDue;
|
|
15
|
+
private alreadySent;
|
|
16
|
+
private canSendNow;
|
|
17
|
+
private isCompanyOpen;
|
|
11
18
|
}
|
|
12
19
|
export declare const scheduleDispatchService: ScheduleService;
|
|
13
20
|
//# sourceMappingURL=schedule.service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schedule.service.d.ts","sourceRoot":"/","sources":["modules/tournament/schedule/schedule.service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"schedule.service.d.ts","sourceRoot":"/","sources":["modules/tournament/schedule/schedule.service.ts"],"names":[],"mappings":"AAoBA,qBACa,eAAe;IAC3B,OAAO,CAAC,gBAAgB,CAA6B;IACrD,OAAO,CAAC,eAAe,CAA4B;IACnD,OAAO,CAAC,qBAAqB,CAAkC;IAC/D,OAAO,CAAC,kBAAkB,CAAiC;IAC3D,OAAO,CAAC,mBAAmB,CAAgC;IAC3D,OAAO,CAAC,SAAS,CAA2C;;YA0D9C,wCAAwC;IAuBtD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAInC;IAEU,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;YAU/B,oBAAoB;YAapB,gBAAgB;IAuB9B,OAAO,CAAC,KAAK;IAKb,OAAO,CAAC,WAAW;YAOL,UAAU;YAKV,aAAa;CAM3B;AAED,eAAO,MAAM,uBAAuB,iBAAiC,CAAC"}
|
|
@@ -41,17 +41,21 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
41
41
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
42
42
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
43
43
|
};
|
|
44
|
+
var ScheduleService_1;
|
|
44
45
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
46
|
exports.scheduleDispatchService = exports.ScheduleService = void 0;
|
|
46
47
|
const typedi_1 = __importStar(require("typedi"));
|
|
48
|
+
const core_1 = require("@lyxa.ai/core");
|
|
47
49
|
const models_1 = require("@lyxa.ai/core/dist/libraries/mongo/models");
|
|
48
50
|
const enum_1 = require("@lyxa.ai/core/dist/utilities/enum");
|
|
51
|
+
const workHourSetting_1 = require("@lyxa.ai/core/dist/utilities/workHourSetting");
|
|
49
52
|
const config_repository_1 = require("../config/config.repository");
|
|
50
53
|
const match_repository_1 = require("../match/match.repository");
|
|
51
54
|
const participant_repository_1 = require("../participant/participant.repository");
|
|
52
55
|
const notification_template_repository_1 = require("../notification/notification-template.repository");
|
|
53
56
|
const notification_service_1 = require("../notification/notification.service");
|
|
54
57
|
let ScheduleService = class ScheduleService {
|
|
58
|
+
static { ScheduleService_1 = this; }
|
|
55
59
|
configRepository;
|
|
56
60
|
matchRepository;
|
|
57
61
|
participantRepository;
|
|
@@ -82,33 +86,62 @@ let ScheduleService = class ScheduleService {
|
|
|
82
86
|
});
|
|
83
87
|
await this.configRepository.setNotificationFlag(tournament._id, enum_1.TournamentNotificationTag.TOURNAMENT_ACTIVATION);
|
|
84
88
|
}
|
|
89
|
+
static REMINDER_TYPES = new Set([
|
|
90
|
+
enum_1.TournamentNotificationTag.PREDICTION_REMINDER_15_MINUTES,
|
|
91
|
+
enum_1.TournamentNotificationTag.PREDICTION_REMINDER_3_HOURS,
|
|
92
|
+
enum_1.TournamentNotificationTag.PREDICTION_REMINDER_1_HOUR,
|
|
93
|
+
]);
|
|
85
94
|
async dispatchPending() {
|
|
86
95
|
const tournament = await this.configRepository.findActiveFull();
|
|
87
96
|
if (!tournament)
|
|
88
97
|
return;
|
|
89
|
-
const
|
|
90
|
-
const templates = await this.templateRepository.findTemplates(tournamentId);
|
|
91
|
-
const now = Date.now();
|
|
98
|
+
const templates = await this.templateRepository.findTemplates(tournament._id);
|
|
92
99
|
await this.dispatchTournamentActivationNotification(tournament, templates);
|
|
93
|
-
await
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
100
|
+
await this.dispatchDueReminders(tournament, templates);
|
|
101
|
+
}
|
|
102
|
+
async dispatchDueReminders(tournament, templates) {
|
|
103
|
+
await Promise.all(tournament.matches.flatMap(match => tournament.scheduledNotifications.map(scheduled => this.dispatchReminder(tournament, match, scheduled, templates))));
|
|
104
|
+
}
|
|
105
|
+
async dispatchReminder(tournament, match, scheduled, templates) {
|
|
106
|
+
const { type, target, durationMins } = scheduled;
|
|
107
|
+
if (!ScheduleService_1.REMINDER_TYPES.has(type))
|
|
108
|
+
return;
|
|
109
|
+
if (this.alreadySent(match, type))
|
|
110
|
+
return;
|
|
111
|
+
if (!this.isDue(match, durationMins))
|
|
112
|
+
return;
|
|
113
|
+
if (await this.canSendNow(type))
|
|
114
|
+
await this.notificationService.dispatchScheduledReminder({
|
|
115
|
+
tournament,
|
|
116
|
+
match,
|
|
117
|
+
templates,
|
|
118
|
+
type,
|
|
119
|
+
target
|
|
120
|
+
});
|
|
121
|
+
await this.matchRepository.setNotificationFlag(tournament._id, match._id, type);
|
|
122
|
+
}
|
|
123
|
+
isDue(match, durationMins) {
|
|
124
|
+
const notificationTime = new Date(match.startingDate).getTime() - durationMins * 60 * 1000;
|
|
125
|
+
return Date.now() >= notificationTime;
|
|
126
|
+
}
|
|
127
|
+
alreadySent(match, type) {
|
|
128
|
+
const flags = match.notificationFlags;
|
|
129
|
+
return flags?.[type] === true;
|
|
130
|
+
}
|
|
131
|
+
async canSendNow(type) {
|
|
132
|
+
if (type !== enum_1.TournamentNotificationTag.PREDICTION_REMINDER_1_HOUR)
|
|
133
|
+
return true;
|
|
134
|
+
return this.isCompanyOpen();
|
|
135
|
+
}
|
|
136
|
+
async isCompanyOpen() {
|
|
137
|
+
const settings = (await (0, core_1.getLibraries)().getCachedSettingsService().getSettings());
|
|
138
|
+
if (!settings?.workHourSetting)
|
|
139
|
+
return false;
|
|
140
|
+
return (0, workHourSetting_1.isLyxaOpen)(settings.workHourSetting);
|
|
108
141
|
}
|
|
109
142
|
};
|
|
110
143
|
exports.ScheduleService = ScheduleService;
|
|
111
|
-
exports.ScheduleService = ScheduleService = __decorate([
|
|
144
|
+
exports.ScheduleService = ScheduleService = ScheduleService_1 = __decorate([
|
|
112
145
|
(0, typedi_1.Service)(),
|
|
113
146
|
__metadata("design:paramtypes", [])
|
|
114
147
|
], ScheduleService);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schedule.service.js","sourceRoot":"/","sources":["modules/tournament/schedule/schedule.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iDAA4C;AAG5C,sEAAiG;AACjG,4DAA8E;AAC9E,mEAAyE;AACzE,gEAAsE;AACtE,kFAAwF;AACxF,uGAAkG;AAClG,+EAAqF;AAI9E,IAAM,eAAe,GAArB,MAAM,eAAe;IACnB,gBAAgB,CAA6B;IAC7C,eAAe,CAA4B;IAC3C,qBAAqB,CAAkC;IACvD,kBAAkB,CAAiC;IACnD,mBAAmB,CAAgC;IACnD,SAAS,CAA2C;IAE5D;QACC,IAAI,CAAC,gBAAgB,GAAG,gBAAS,CAAC,GAAG,CAAC,8CAA0B,CAAC,CAAC;QAClE,IAAI,CAAC,eAAe,GAAG,gBAAS,CAAC,GAAG,CAAC,4CAAyB,CAAC,CAAC;QAChE,IAAI,CAAC,qBAAqB,GAAG,gBAAS,CAAC,GAAG,CAAC,wDAA+B,CAAC,CAAC;QAC5E,IAAI,CAAC,kBAAkB,GAAG,gBAAS,CAAC,GAAG,CAAC,iEAA8B,CAAC,CAAC;QACxE,IAAI,CAAC,mBAAmB,GAAG,gBAAS,CAAC,GAAG,CAAC,oDAA6B,CAAC,CAAC;QACxE,IAAI,CAAC,SAAS,GAAG,kBAAqD,CAAC;IACxE,CAAC;IAiDO,KAAK,CAAC,wCAAwC,CACrD,UAA8B,EAC9B,SAA8D;QAE9D,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,iBAAiB,IAAI,EAAE,CAAgD,CAAC,CAAC;QACzH,IAAI,KAAK,CAAC,GAAG,CAAC,gCAAyB,CAAC,qBAAqB,CAAC,KAAK,IAAI;YAAE,OAAO;QAEhF,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,gCAAyB,CAAC,qBAAqB,CAAC,CAAC;QAChF,IAAI,CAAC,QAAQ;YAAE,OAAO;QAEtB,MAAM,IAAI,CAAC,mBAAmB,CAAC,YAAY,CAAC;YAC3C,KAAK,EAAE,QAAQ,CAAC,KAAK;YACrB,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,0BAA0B,EAAE,gCAAyB,CAAC,qBAAqB;YAC3E,YAAY,EAAE,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE;YACvC,aAAa,EAAE,UAAU,CAAC,aAAa;SACvC,CAAC,CAAC;QACH,MAAM,IAAI,CAAC,gBAAgB,CAAC,mBAAmB,CAC9C,UAAU,CAAC,GAAG,EACd,gCAAyB,CAAC,qBAAqB,CAC/C,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,eAAe;QAC3B,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,cAAc,EAAE,CAAC;QAChE,IAAI,CAAC,UAAU;YAAE,OAAO;QAExB,MAAM,YAAY,GAAG,UAAU,CAAC,GAAG,CAAC;QACpC,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;QAC5E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEvB,MAAM,IAAI,CAAC,wCAAwC,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAE3E,MAAM,OAAO,CAAC,GAAG,CAChB,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAC9B,OAAO,CAAC,GAAG,CACV,UAAU,CAAC,sBAAsB,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,EAAE;YAC9E,IACC,CAAC;gBACA,gCAAyB,CAAC,8BAA8B;gBACxD,gCAAyB,CAAC,2BAA2B;aACrD,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAEhB,OAAO;YAER,MAAM,gBAAgB,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,GAAG,YAAY,GAAG,EAAE,GAAG,IAAI,CAAC;YAC3F,MAAM,KAAK,GAAG,KAAK,CAAC,iBAAmE,CAAC;YAExF,IAAI,GAAG,GAAG,gBAAgB;gBAAE,OAAO;YACnC,IAAI,KAAK,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI;gBAAE,OAAO;YAEnC,MAAM,IAAI,CAAC,mBAAmB,CAAC,oBAAoB,CAClD,IAAI,EACJ,MAAM,EACN,SAAS,EACT,YAAY,EACZ,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,EACxC,KAAK,CAAC,GAAG,EACY,KAAK,CAAC,YAAY,EACvC,UAAU,CAAC,aAAa,CACxB,CAAC;YACF,MAAM,IAAI,CAAC,eAAe,CAAC,mBAAmB,CAAC,YAAY,EAAE,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC/E,CAAC,CAAC,CACF,CACD,CACD,CAAC;IACH,CAAC;CACD,CAAA;AAnIY,0CAAe;0BAAf,eAAe;IAD3B,IAAA,gBAAO,GAAE;;GACG,eAAe,CAmI3B;AAEY,QAAA,uBAAuB,GAAG,gBAAS,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC","sourcesContent":["import Container, { Service } from 'typedi';\nimport { mongoose } from '@typegoose/typegoose';\nimport { SoftDeleteModel } from '@lyxa.ai/core/dist/libraries/mongo/plugins/soft-delete-plugin';\nimport { NotificationMessage, User, UserModel } from '@lyxa.ai/core/dist/libraries/mongo/models';\nimport { TournamentNotificationTag } from '@lyxa.ai/core/dist/utilities/enum';\nimport { TournamentConfigRepository } from '../config/config.repository';\nimport { TournamentMatchRepository } from '../match/match.repository';\nimport { TournamentParticipantRepository } from '../participant/participant.repository';\nimport { NotificationTemplateRepository } from '../notification/notification-template.repository';\nimport { TournamentNotificationService } from '../notification/notification.service';\nimport { TournamentDocument } from '../config/config.types';\n\n@Service()\nexport class ScheduleService {\n\tprivate configRepository: TournamentConfigRepository;\n\tprivate matchRepository: TournamentMatchRepository;\n\tprivate participantRepository: TournamentParticipantRepository;\n\tprivate templateRepository: NotificationTemplateRepository;\n\tprivate notificationService: TournamentNotificationService;\n\tprivate userModel: typeof UserModel & SoftDeleteModel<User>;\n\n\tconstructor() {\n\t\tthis.configRepository = Container.get(TournamentConfigRepository);\n\t\tthis.matchRepository = Container.get(TournamentMatchRepository);\n\t\tthis.participantRepository = Container.get(TournamentParticipantRepository);\n\t\tthis.templateRepository = Container.get(NotificationTemplateRepository);\n\t\tthis.notificationService = Container.get(TournamentNotificationService);\n\t\tthis.userModel = UserModel as typeof UserModel & SoftDeleteModel<User>;\n\t}\n\n\t// NOTE: there is a huge possibility we will not use this feature, left it out in case they want it back\n\t//\n\t// public async dispatchPreTournamentReminders(): Promise<void> {\n\t// \tconst tournaments = await this.configRepository.findPendingReminderTournaments();\n\t// \tif (!tournaments.length) return;\n\t//\n\t// \tawait Promise.all(\n\t// \t\ttournaments.map(async tournament => {\n\t// \t\t\tconst templates = await this.templateRepository.findTemplates(tournament._id);\n\t// \t\t\tconst reminderTemplate = templates.get(TournamentNotificationTag.TEAM_SELECTION_REMINDER_1_DAY);\n\t// \t\t\tif (!reminderTemplate) return;\n\t//\n\t// \t\t\tconst participants = await this.participantRepository.findByTournament(tournament._id);\n\t// \t\t\tconst usersWithTeam = participants\n\t// \t\t\t\t.filter(participant => participant.teamId)\n\t// \t\t\t\t.map(participant => participant.userId);\n\t// \t\t\tconst recipients = await this.userModel\n\t// \t\t\t\t.find({ _id: { $nin: usersWithTeam } })\n\t// \t\t\t\t.select('_id')\n\t// \t\t\t\t.lean();\n\t//\n\t// \t\t\tif (!recipients.length) {\n\t// \t\t\t\tawait this.configRepository.setNotificationFlag(\n\t// \t\t\t\t\ttournament._id,\n\t// \t\t\t\t\tTournamentNotificationTag.TEAM_SELECTION_REMINDER_1_DAY\n\t// \t\t\t\t);\n\t// \t\t\t\treturn;\n\t// \t\t\t}\n\t//\n\t// \t\t\tawait this.notificationService.notifyUsers(\n\t// \t\t\t\t{\n\t// \t\t\t\t\ttitle: reminderTemplate.title,\n\t// \t\t\t\t\tbody: reminderTemplate.body,\n\t// \t\t\t\t\ttournamentNotificationType: TournamentNotificationTag.TEAM_SELECTION_REMINDER_1_DAY,\n\t// \t\t\t\t\ttournamentId: tournament._id.toString(),\n\t// \t\t\t\t\tdeepLinkRoute: tournament.deepLinkRoute,\n\t// \t\t\t\t},\n\t// \t\t\t\trecipients.map(user => user._id as mongoose.Types.ObjectId)\n\t// \t\t\t);\n\t// \t\t\tawait this.configRepository.setNotificationFlag(\n\t// \t\t\t\ttournament._id,\n\t// \t\t\t\tTournamentNotificationTag.TEAM_SELECTION_REMINDER_1_DAY\n\t// \t\t\t);\n\t// \t\t})\n\t// \t);\n\t// }\n\n\tprivate async dispatchTournamentActivationNotification(\n\t\ttournament: TournamentDocument,\n\t\ttemplates: Map<TournamentNotificationTag, NotificationMessage>\n\t): Promise<void> {\n\t\tconst flags = new Map(Object.entries(tournament.notificationFlags || {}) as Array<[TournamentNotificationTag, boolean]>);\n\t\tif (flags.get(TournamentNotificationTag.TOURNAMENT_ACTIVATION) === true) return;\n\n\t\tconst template = templates.get(TournamentNotificationTag.TOURNAMENT_ACTIVATION);\n\t\tif (!template) return;\n\n\t\tawait this.notificationService.notifyGlobal({\n\t\t\ttitle: template.title,\n\t\t\tbody: template.body,\n\t\t\ttournamentNotificationType: TournamentNotificationTag.TOURNAMENT_ACTIVATION,\n\t\t\ttournamentId: tournament._id.toString(),\n\t\t\tdeepLinkRoute: tournament.deepLinkRoute,\n\t\t});\n\t\tawait this.configRepository.setNotificationFlag(\n\t\t\ttournament._id,\n\t\t\tTournamentNotificationTag.TOURNAMENT_ACTIVATION\n\t\t);\n\t}\n\n\tpublic async dispatchPending(): Promise<void> {\n\t\tconst tournament = await this.configRepository.findActiveFull();\n\t\tif (!tournament) return;\n\n\t\tconst tournamentId = tournament._id;\n\t\tconst templates = await this.templateRepository.findTemplates(tournamentId);\n\t\tconst now = Date.now();\n\n\t\tawait this.dispatchTournamentActivationNotification(tournament, templates);\n\n\t\tawait Promise.all(\n\t\t\ttournament.matches.map(match =>\n\t\t\t\tPromise.all(\n\t\t\t\t\ttournament.scheduledNotifications.map(async ({ type, durationMins, target }) => {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t![\n\t\t\t\t\t\t\t\tTournamentNotificationTag.PREDICTION_REMINDER_15_MINUTES,\n\t\t\t\t\t\t\t\tTournamentNotificationTag.PREDICTION_REMINDER_3_HOURS,\n\t\t\t\t\t\t\t].includes(type)\n\t\t\t\t\t\t)\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\tconst notificationTime = new Date(match.startingDate).getTime() - durationMins * 60 * 1000;\n\t\t\t\t\t\tconst flags = match.notificationFlags as unknown as Record<string, boolean> | undefined;\n\n\t\t\t\t\t\tif (now < notificationTime) return;\n\t\t\t\t\t\tif (flags?.[type] === true) return;\n\n\t\t\t\t\t\tawait this.notificationService.dispatchScheduledJob(\n\t\t\t\t\t\t\ttype,\n\t\t\t\t\t\t\ttarget,\n\t\t\t\t\t\t\ttemplates,\n\t\t\t\t\t\t\ttournamentId,\n\t\t\t\t\t\t\t[match.team1.teamId, match.team2.teamId],\n\t\t\t\t\t\t\tmatch._id,\n match.startingDate,\n\t\t\t\t\t\t\ttournament.deepLinkRoute,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tawait this.matchRepository.setNotificationFlag(tournamentId, match._id, type);\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t}\n}\n\nexport const scheduleDispatchService = Container.get(ScheduleService);\n"]}
|
|
1
|
+
{"version":3,"file":"schedule.service.js","sourceRoot":"/","sources":["modules/tournament/schedule/schedule.service.ts"],"names":[],"mappings":"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","sourcesContent":["import Container, {Service} from 'typedi';\nimport {getLibraries} from '@lyxa.ai/core';\nimport {SoftDeleteModel} from '@lyxa.ai/core/dist/libraries/mongo/plugins/soft-delete-plugin';\nimport {\n\tNotificationMessage,\n\tScheduledNotificationConfig,\n\tSetting,\n\tTournamentMatch,\n\tUser,\n\tUserModel,\n} from '@lyxa.ai/core/dist/libraries/mongo/models';\nimport {TournamentNotificationTag} from '@lyxa.ai/core/dist/utilities/enum';\nimport {isLyxaOpen} from '@lyxa.ai/core/dist/utilities/workHourSetting';\nimport {TournamentConfigRepository} from '../config/config.repository';\nimport {TournamentMatchRepository} from '../match/match.repository';\nimport {TournamentParticipantRepository} from '../participant/participant.repository';\nimport {NotificationTemplateRepository} from '../notification/notification-template.repository';\nimport {TournamentNotificationService} from '../notification/notification.service';\nimport {TournamentDocument} from '../config/config.types';\n\n@Service()\nexport class ScheduleService {\n\tprivate configRepository: TournamentConfigRepository;\n\tprivate matchRepository: TournamentMatchRepository;\n\tprivate participantRepository: TournamentParticipantRepository;\n\tprivate templateRepository: NotificationTemplateRepository;\n\tprivate notificationService: TournamentNotificationService;\n\tprivate userModel: typeof UserModel & SoftDeleteModel<User>;\n\n\tconstructor() {\n\t\tthis.configRepository = Container.get(TournamentConfigRepository);\n\t\tthis.matchRepository = Container.get(TournamentMatchRepository);\n\t\tthis.participantRepository = Container.get(TournamentParticipantRepository);\n\t\tthis.templateRepository = Container.get(NotificationTemplateRepository);\n\t\tthis.notificationService = Container.get(TournamentNotificationService);\n\t\tthis.userModel = UserModel as typeof UserModel & SoftDeleteModel<User>;\n\t}\n\n\t// NOTE: there is a huge possibility we will not use this feature, left it out in case they want it back\n\t//\n\t// public async dispatchPreTournamentReminders(): Promise<void> {\n\t// \tconst tournaments = await this.configRepository.findPendingReminderTournaments();\n\t// \tif (!tournaments.length) return;\n\t//\n\t// \tawait Promise.all(\n\t// \t\ttournaments.map(async tournament => {\n\t// \t\t\tconst templates = await this.templateRepository.findTemplates(tournament._id);\n\t// \t\t\tconst reminderTemplate = templates.get(TournamentNotificationTag.TEAM_SELECTION_REMINDER_1_DAY);\n\t// \t\t\tif (!reminderTemplate) return;\n\t//\n\t// \t\t\tconst participants = await this.participantRepository.findByTournament(tournament._id);\n\t// \t\t\tconst usersWithTeam = participants\n\t// \t\t\t\t.filter(participant => participant.teamId)\n\t// \t\t\t\t.map(participant => participant.userId);\n\t// \t\t\tconst recipients = await this.userModel\n\t// \t\t\t\t.find({ _id: { $nin: usersWithTeam } })\n\t// \t\t\t\t.select('_id')\n\t// \t\t\t\t.lean();\n\t//\n\t// \t\t\tif (!recipients.length) {\n\t// \t\t\t\tawait this.configRepository.setNotificationFlag(\n\t// \t\t\t\t\ttournament._id,\n\t// \t\t\t\t\tTournamentNotificationTag.TEAM_SELECTION_REMINDER_1_DAY\n\t// \t\t\t\t);\n\t// \t\t\t\treturn;\n\t// \t\t\t}\n\t//\n\t// \t\t\tawait this.notificationService.notifyUsers(\n\t// \t\t\t\t{\n\t// \t\t\t\t\ttitle: reminderTemplate.title,\n\t// \t\t\t\t\tbody: reminderTemplate.body,\n\t// \t\t\t\t\ttournamentNotificationType: TournamentNotificationTag.TEAM_SELECTION_REMINDER_1_DAY,\n\t// \t\t\t\t\ttournamentId: tournament._id.toString(),\n\t// \t\t\t\t\tdeepLinkRoute: tournament.deepLinkRoute,\n\t// \t\t\t\t},\n\t// \t\t\t\trecipients.map(user => user._id as mongoose.Types.ObjectId)\n\t// \t\t\t);\n\t// \t\t\tawait this.configRepository.setNotificationFlag(\n\t// \t\t\t\ttournament._id,\n\t// \t\t\t\tTournamentNotificationTag.TEAM_SELECTION_REMINDER_1_DAY\n\t// \t\t\t);\n\t// \t\t})\n\t// \t);\n\t// }\n\n\tprivate async dispatchTournamentActivationNotification(\n\t\ttournament: TournamentDocument,\n\t\ttemplates: Map<TournamentNotificationTag, NotificationMessage>\n\t): Promise<void> {\n\t\tconst flags = new Map(Object.entries(tournament.notificationFlags || {}) as Array<[TournamentNotificationTag, boolean]>);\n\t\tif (flags.get(TournamentNotificationTag.TOURNAMENT_ACTIVATION) === true) return;\n\n\t\tconst template = templates.get(TournamentNotificationTag.TOURNAMENT_ACTIVATION);\n\t\tif (!template) return;\n\n\t\tawait this.notificationService.notifyGlobal({\n\t\t\ttitle: template.title,\n\t\t\tbody: template.body,\n\t\t\ttournamentNotificationType: TournamentNotificationTag.TOURNAMENT_ACTIVATION,\n\t\t\ttournamentId: tournament._id.toString(),\n\t\t\tdeepLinkRoute: tournament.deepLinkRoute,\n\t\t});\n\t\tawait this.configRepository.setNotificationFlag(\n\t\t\ttournament._id,\n\t\t\tTournamentNotificationTag.TOURNAMENT_ACTIVATION\n\t\t);\n\t}\n\n\tprivate static readonly REMINDER_TYPES: ReadonlySet<TournamentNotificationTag> = new Set([\n\t\tTournamentNotificationTag.PREDICTION_REMINDER_15_MINUTES,\n\t\tTournamentNotificationTag.PREDICTION_REMINDER_3_HOURS,\n\t\tTournamentNotificationTag.PREDICTION_REMINDER_1_HOUR,\n\t]);\n\n\tpublic async dispatchPending(): Promise<void> {\n\t\tconst tournament = await this.configRepository.findActiveFull();\n\t\tif (!tournament) return;\n\n\t\tconst templates = await this.templateRepository.findTemplates(tournament._id);\n\n\t\tawait this.dispatchTournamentActivationNotification(tournament, templates);\n\t\tawait this.dispatchDueReminders(tournament, templates);\n\t}\n\n\tprivate async dispatchDueReminders(\n\t\ttournament: TournamentDocument,\n\t\ttemplates: Map<TournamentNotificationTag, NotificationMessage>\n\t): Promise<void> {\n\t\tawait Promise.all(\n\t\t\ttournament.matches.flatMap(match =>\n\t\t\t\ttournament.scheduledNotifications.map(scheduled =>\n\t\t\t\t\tthis.dispatchReminder(tournament, match, scheduled, templates)\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t}\n\n\tprivate async dispatchReminder(\n\t\ttournament: TournamentDocument,\n\t\tmatch: TournamentMatch,\n\t\tscheduled: ScheduledNotificationConfig,\n\t\ttemplates: Map<TournamentNotificationTag, NotificationMessage>\n\t): Promise<void> {\n\t\tconst {type, target, durationMins} = scheduled;\n\n\t\tif (!ScheduleService.REMINDER_TYPES.has(type)) return;\n\t\tif (this.alreadySent(match, type)) return;\n\t\tif (!this.isDue(match, durationMins)) return;\n\n\t\tif (await this.canSendNow(type)) await this.notificationService.dispatchScheduledReminder({\n\t\t\ttournament,\n\t\t\tmatch,\n\t\t\ttemplates,\n\t\t\ttype,\n\t\t\ttarget\n\t\t});\n\n\t\tawait this.matchRepository.setNotificationFlag(tournament._id, match._id, type);\n\t}\n\n\tprivate isDue(match: TournamentMatch, durationMins: number): boolean {\n\t\tconst notificationTime = new Date(match.startingDate).getTime() - durationMins * 60 * 1000;\n\t\treturn Date.now() >= notificationTime;\n\t}\n\n\tprivate alreadySent(match: TournamentMatch, type: TournamentNotificationTag): boolean {\n\t\tconst flags = match.notificationFlags as unknown as Record<string, boolean> | undefined;\n\t\treturn flags?.[type] === true;\n\t}\n\n\t// The 1-hour reminder targets users who already predicted, so it's only worth sending while Lyxa\n\t// is open. Every other reminder can go out at any time.\n\tprivate async canSendNow(type: TournamentNotificationTag): Promise<boolean> {\n\t\tif (type !== TournamentNotificationTag.PREDICTION_REMINDER_1_HOUR) return true;\n\t\treturn this.isCompanyOpen();\n\t}\n\n\tprivate async isCompanyOpen(): Promise<boolean> {\n\t\tconst settings = (await getLibraries().getCachedSettingsService().getSettings()) as Setting | null;\n\t\t// Without configured working hours we can't confirm we're open, so hold the reminder for a later run.\n\t\tif (!settings?.workHourSetting) return false;\n\t\treturn isLyxaOpen(settings.workHourSetting);\n\t}\n}\n\nexport const scheduleDispatchService = Container.get(ScheduleService);\n"]}
|
|
@@ -10,8 +10,8 @@ function fillMissingPeriods(results, startDate, endDate, type, defaultFields) {
|
|
|
10
10
|
resultMap.set(item.date, item);
|
|
11
11
|
}
|
|
12
12
|
const fieldKeys = Object.keys(defaultFields);
|
|
13
|
-
const unit = type === enum_1.GraphType.MONTHLY ? 'month' : 'day';
|
|
14
|
-
const dateFormat = type === enum_1.GraphType.MONTHLY ? 'YYYY-MM' : 'YYYY-MM-DD';
|
|
13
|
+
const unit = type === enum_1.GraphType.YEARLY ? 'year' : type === enum_1.GraphType.MONTHLY ? 'month' : 'day';
|
|
14
|
+
const dateFormat = type === enum_1.GraphType.YEARLY ? 'YYYY' : type === enum_1.GraphType.MONTHLY ? 'YYYY-MM' : 'YYYY-MM-DD';
|
|
15
15
|
let current = (0, dayjs_1.dayjs)(startDate).startOf(unit);
|
|
16
16
|
const end = (0, dayjs_1.dayjs)(endDate).startOf(unit);
|
|
17
17
|
while (current.isBefore(end) || current.isSame(end)) {
|