Skip to content

Commit 4fafba4

Browse files
Merge branch 'next' into nv-6927-contextual-help-drawer-docs-support-quick-links
2 parents dec974f + 7faa7cf commit 4fafba4

File tree

150 files changed

+5265
-3681
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

150 files changed

+5265
-3681
lines changed

.cspell.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -776,7 +776,8 @@
776776
"fanout",
777777
"adminconsent",
778778
"Arik",
779-
"Chakma"
779+
"Chakma",
780+
"selectednode"
780781
],
781782
"flagWords": [],
782783
"patterns": [

apps/api/src/app/events/e2e/throttle-events.e2e.ts

Lines changed: 36 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,7 @@
11
import { Novu } from '@novu/api';
2-
import {
3-
CreateWorkflowDto,
4-
StepTypeEnum,
5-
WorkflowCreationSourceEnum,
6-
WorkflowResponseDto,
7-
} from '@novu/api/models/components';
8-
import {
9-
JobRepository,
10-
JobStatusEnum,
11-
MessageRepository,
12-
NotificationTemplateRepository,
13-
SubscriberEntity,
14-
} from '@novu/dal';
2+
import { CreateWorkflowDto, WorkflowCreationSourceEnum } from '@novu/api/models/components';
3+
import { JobRepository, JobStatusEnum, MessageRepository, SubscriberEntity } from '@novu/dal';
4+
import { StepTypeEnum } from '@novu/shared';
155
import { SubscribersService, UserSession } from '@novu/testing';
166
import { expect } from 'chai';
177
import { initNovuClassSdk } from '../../shared/helpers/e2e/sdk/e2e-sdk.helper';
@@ -23,7 +13,6 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
2313
let subscriberService: SubscribersService;
2414
const jobRepository = new JobRepository();
2515
const messageRepository = new MessageRepository();
26-
const templateRepository = new NotificationTemplateRepository();
2716
let novuClient: Novu;
2817

2918
beforeEach(async () => {
@@ -64,7 +53,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
6453
source: WorkflowCreationSourceEnum.Dashboard,
6554
steps: [
6655
{
67-
type: StepTypeEnum.Throttle,
56+
type: StepTypeEnum.THROTTLE,
6857
name: 'Throttle Step',
6958
controlValues: {
7059
type: 'fixed',
@@ -74,7 +63,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
7463
},
7564
},
7665
{
77-
type: StepTypeEnum.InApp,
66+
type: StepTypeEnum.IN_APP,
7867
name: 'In-App Message',
7968
controlValues: {
8069
body: 'Hello world {{payload.customVar}}',
@@ -99,7 +88,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
9988
const throttleJobs = await jobRepository.find({
10089
_environmentId: session.environment._id,
10190
_templateId: workflow.id,
102-
type: StepTypeEnum.Throttle,
91+
type: StepTypeEnum.THROTTLE,
10392
});
10493

10594
expect(throttleJobs?.length).to.equal(2);
@@ -112,7 +101,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
112101
const messages = await messageRepository.find({
113102
_environmentId: session.environment._id,
114103
_subscriberId: subscriber._id,
115-
channel: StepTypeEnum.InApp,
104+
channel: StepTypeEnum.IN_APP,
116105
});
117106

118107
expect(messages?.length).to.equal(2);
@@ -131,7 +120,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
131120
source: WorkflowCreationSourceEnum.Dashboard,
132121
steps: [
133122
{
134-
type: StepTypeEnum.Throttle,
123+
type: StepTypeEnum.THROTTLE,
135124
name: 'Throttle Step',
136125
controlValues: {
137126
type: 'fixed',
@@ -141,7 +130,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
141130
},
142131
},
143132
{
144-
type: StepTypeEnum.InApp,
133+
type: StepTypeEnum.IN_APP,
145134
name: 'In-App Message',
146135
controlValues: {
147136
body: 'Hello world {{payload.customVar}}',
@@ -170,7 +159,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
170159
const throttleJobs = await jobRepository.find({
171160
_environmentId: session.environment._id,
172161
_templateId: workflow.id,
173-
type: StepTypeEnum.Throttle,
162+
type: StepTypeEnum.THROTTLE,
174163
});
175164

176165
expect(throttleJobs?.length).to.equal(3);
@@ -194,7 +183,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
194183
const messages = await messageRepository.find({
195184
_environmentId: session.environment._id,
196185
_subscriberId: subscriber._id,
197-
channel: StepTypeEnum.InApp,
186+
channel: StepTypeEnum.IN_APP,
198187
});
199188

200189
expect(messages?.length).to.equal(2);
@@ -208,7 +197,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
208197
source: WorkflowCreationSourceEnum.Dashboard,
209198
steps: [
210199
{
211-
type: StepTypeEnum.Throttle,
200+
type: StepTypeEnum.THROTTLE,
212201
name: 'Throttle Step',
213202
controlValues: {
214203
type: 'fixed',
@@ -218,7 +207,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
218207
},
219208
},
220209
{
221-
type: StepTypeEnum.InApp,
210+
type: StepTypeEnum.IN_APP,
222211
name: 'In-App Message',
223212
controlValues: {
224213
body: 'Throttled message {{payload.customVar}}',
@@ -250,7 +239,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
250239
query: {
251240
_environmentId: session.environment._id,
252241
_templateId: workflow.id,
253-
type: 'throttle' as any,
242+
type: StepTypeEnum.THROTTLE,
254243
},
255244
findMultiple: true,
256245
});
@@ -275,7 +264,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
275264
const messages = await messageRepository.find({
276265
_environmentId: session.environment._id,
277266
_subscriberId: subscriber._id,
278-
channel: StepTypeEnum.InApp,
267+
channel: StepTypeEnum.IN_APP,
279268
});
280269

281270
expect(messages?.length).to.equal(1);
@@ -289,7 +278,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
289278
source: WorkflowCreationSourceEnum.Dashboard,
290279
steps: [
291280
{
292-
type: StepTypeEnum.Throttle,
281+
type: StepTypeEnum.THROTTLE,
293282
name: 'Throttle Step',
294283
controlValues: {
295284
type: 'fixed',
@@ -300,7 +289,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
300289
},
301290
},
302291
{
303-
type: StepTypeEnum.InApp,
292+
type: StepTypeEnum.IN_APP,
304293
name: 'In-App Message',
305294
controlValues: {
306295
body: 'Hello user {{payload.userId}}',
@@ -329,7 +318,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
329318
const throttleJobs = await jobRepository.find({
330319
_environmentId: session.environment._id,
331320
_templateId: workflow.id,
332-
type: StepTypeEnum.Throttle,
321+
type: StepTypeEnum.THROTTLE,
333322
});
334323

335324
expect(throttleJobs?.length).to.equal(3);
@@ -345,7 +334,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
345334
const messages = await messageRepository.find({
346335
_environmentId: session.environment._id,
347336
_subscriberId: subscriber._id,
348-
channel: StepTypeEnum.InApp,
337+
channel: StepTypeEnum.IN_APP,
349338
});
350339

351340
expect(messages?.length).to.equal(2);
@@ -367,7 +356,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
367356
active: true,
368357
steps: [
369358
{
370-
type: StepTypeEnum.Throttle,
359+
type: StepTypeEnum.THROTTLE,
371360
name: 'Throttle Step',
372361
controlValues: {
373362
type: 'dynamic',
@@ -376,7 +365,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
376365
},
377366
},
378367
{
379-
type: StepTypeEnum.InApp,
368+
type: StepTypeEnum.IN_APP,
380369
name: 'In-App Message',
381370
controlValues: {
382371
body: 'Dynamic throttled by timestamp {{payload.customVar}}',
@@ -404,7 +393,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
404393
const throttleJobs = await jobRepository.find({
405394
_environmentId: session.environment._id,
406395
_templateId: workflow.id,
407-
type: StepTypeEnum.Throttle,
396+
type: StepTypeEnum.THROTTLE,
408397
});
409398

410399
const completedThrottleJobs = throttleJobs.filter((job) => job.status === JobStatusEnum.COMPLETED);
@@ -416,7 +405,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
416405
const messages = await messageRepository.find({
417406
_environmentId: session.environment._id,
418407
_subscriberId: subscriber._id,
419-
channel: StepTypeEnum.InApp,
408+
channel: StepTypeEnum.IN_APP,
420409
});
421410

422411
expect(messages?.length).to.equal(1);
@@ -430,7 +419,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
430419
active: true,
431420
steps: [
432421
{
433-
type: StepTypeEnum.Throttle,
422+
type: StepTypeEnum.THROTTLE,
434423
name: 'Throttle Step',
435424
controlValues: {
436425
type: 'dynamic',
@@ -439,7 +428,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
439428
},
440429
},
441430
{
442-
type: StepTypeEnum.InApp,
431+
type: StepTypeEnum.IN_APP,
443432
name: 'In-App Message',
444433
controlValues: {
445434
body: 'Dynamic throttled by duration {{payload.customVar}}',
@@ -467,7 +456,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
467456
const throttleJobs = await jobRepository.find({
468457
_environmentId: session.environment._id,
469458
_templateId: workflow.id,
470-
type: StepTypeEnum.Throttle,
459+
type: StepTypeEnum.THROTTLE,
471460
});
472461

473462
const completedThrottleJobs = throttleJobs.filter((job) => job.status === JobStatusEnum.COMPLETED);
@@ -479,7 +468,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
479468
const messages = await messageRepository.find({
480469
_environmentId: session.environment._id,
481470
_subscriberId: subscriber._id,
482-
channel: StepTypeEnum.InApp,
471+
channel: StepTypeEnum.IN_APP,
483472
});
484473

485474
expect(messages?.length).to.equal(1);
@@ -493,7 +482,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
493482
source: WorkflowCreationSourceEnum.Dashboard,
494483
steps: [
495484
{
496-
type: StepTypeEnum.Throttle,
485+
type: StepTypeEnum.THROTTLE,
497486
name: 'Throttle Step',
498487
controlValues: {
499488
type: 'fixed',
@@ -503,7 +492,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
503492
},
504493
},
505494
{
506-
type: StepTypeEnum.InApp,
495+
type: StepTypeEnum.IN_APP,
507496
name: 'In-App Message',
508497
controlValues: {
509498
body: 'Throttled by minutes {{payload.customVar}}',
@@ -532,7 +521,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
532521
const throttleJobs = await jobRepository.find({
533522
_environmentId: session.environment._id,
534523
_templateId: workflow.id,
535-
type: StepTypeEnum.Throttle,
524+
type: StepTypeEnum.THROTTLE,
536525
});
537526

538527
expect(throttleJobs?.length).to.equal(3);
@@ -550,7 +539,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
550539
const messages = await messageRepository.find({
551540
_environmentId: session.environment._id,
552541
_subscriberId: subscriber._id,
553-
channel: StepTypeEnum.InApp,
542+
channel: StepTypeEnum.IN_APP,
554543
});
555544

556545
expect(messages?.length).to.equal(2);
@@ -564,7 +553,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
564553
source: WorkflowCreationSourceEnum.Dashboard,
565554
steps: [
566555
{
567-
type: StepTypeEnum.Throttle,
556+
type: StepTypeEnum.THROTTLE,
568557
name: 'Throttle Step',
569558
controlValues: {
570559
type: 'fixed',
@@ -574,14 +563,14 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
574563
},
575564
},
576565
{
577-
type: StepTypeEnum.InApp,
566+
type: StepTypeEnum.IN_APP,
578567
name: 'In-App Message',
579568
controlValues: {
580569
body: 'First message {{payload.customVar}}',
581570
},
582571
},
583572
{
584-
type: StepTypeEnum.Email,
573+
type: StepTypeEnum.EMAIL,
585574
name: 'Email Message',
586575
controlValues: {
587576
subject: 'Follow-up email',
@@ -626,7 +615,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
626615
expect(skippedJobs?.length).to.equal(3);
627616

628617
// Verify throttle jobs behavior
629-
const throttleJobs = allJobs.filter((job) => job.type === StepTypeEnum.Throttle);
618+
const throttleJobs = allJobs.filter((job) => job.type === StepTypeEnum.THROTTLE);
630619
expect(throttleJobs?.length).to.equal(2);
631620

632621
// First throttle should be completed, second should be skipped (threshold=1)
@@ -639,7 +628,7 @@ describe('Trigger event - Throttle triggered events - /v1/events/trigger (POST)
639628
const inAppMessages = await messageRepository.find({
640629
_environmentId: session.environment._id,
641630
_subscriberId: subscriber._id,
642-
channel: StepTypeEnum.InApp,
631+
channel: StepTypeEnum.IN_APP,
643632
});
644633

645634
expect(inAppMessages?.length).to.equal(1);

apps/api/src/app/inbox/dtos/bulk-update-preferences-request.dto.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
import { Type } from 'class-transformer';
2-
import { IsArray, IsDefined, IsString, ValidateNested } from 'class-validator';
2+
import { IsArray, IsDefined, IsOptional, IsString, ValidateNested } from 'class-validator';
33

44
import { UpdatePreferencesRequestDto } from './update-preferences-request.dto';
55

66
export class BulkUpdatePreferenceItemDto extends UpdatePreferencesRequestDto {
77
@IsDefined()
88
@IsString()
99
readonly workflowId: string;
10+
11+
@IsOptional()
12+
@IsString()
13+
readonly subscriptionIdOrIdentifier?: string;
1014
}
1115

1216
export class BulkUpdatePreferencesRequestDto {

apps/api/src/app/inbox/dtos/create-topic-subscription-request.dto.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export class CreateTopicSubscriptionRequestDto {
4343
@IsOptional()
4444
topic?: TopicIdentifierDto;
4545

46-
@ApiProperty({
46+
@ApiPropertyOptional({
4747
description:
4848
'The preferences of the topic. Can be a simple workflow ID string, workflow preference object, or group filter object',
4949
type: 'array',

apps/api/src/app/inbox/dtos/update-preferences-request.dto.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import { ApiProperty } from '@nestjs/swagger';
12
import { Type } from 'class-transformer';
2-
import { IsBoolean, IsOptional, ValidateNested } from 'class-validator';
3+
import { IsBoolean, IsObject, IsOptional, ValidateNested } from 'class-validator';
4+
import { RulesLogic } from 'json-logic-js';
35
import { ScheduleDto } from '../../shared/dtos/schedule';
46

57
export class UpdatePreferencesRequestDto {
@@ -27,4 +29,23 @@ export class UpdatePreferencesRequestDto {
2729
@ValidateNested()
2830
@Type(() => ScheduleDto)
2931
readonly schedule?: ScheduleDto;
32+
33+
@ApiProperty({
34+
description: 'Whether the preference is enabled',
35+
type: Boolean,
36+
example: true,
37+
})
38+
@IsBoolean()
39+
@IsOptional()
40+
readonly enabled?: boolean;
41+
42+
@ApiProperty({
43+
description: 'Condition using JSON Logic rules',
44+
type: 'object',
45+
additionalProperties: true,
46+
example: { and: [{ '===': [{ var: 'tier' }, 'premium'] }] },
47+
})
48+
@IsObject()
49+
@IsOptional()
50+
readonly condition?: RulesLogic;
3051
}

0 commit comments

Comments
 (0)