Skip to content

Commit

Permalink
feat(api): Complete email preview logic (#6772)
Browse files Browse the repository at this point in the history
  • Loading branch information
tatarco authored Nov 6, 2024
1 parent 5e08299 commit 05dec8b
Show file tree
Hide file tree
Showing 47 changed files with 1,693 additions and 732 deletions.
1 change: 1 addition & 0 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,7 @@
"projectIds"
],
"ignorePaths": [
"apps/api/src/app/workflows-v2/maily-test-data.ts",
"apps/api/src/.env.test",
"apps/ws/src/.env.test",
"apps/ws/src/.example.env",
Expand Down
1 change: 1 addition & 0 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .source
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { EnvironmentWithUserCommand } from '@novu/application-generic';
import { Subscriber } from '@novu/framework/internal';
import { WorkflowOriginEnum } from '@novu/shared';
import { JobStatusEnum, WorkflowOriginEnum } from '@novu/shared';

export class PreviewStepCommand extends EnvironmentWithUserCommand {
workflowId: string;
Expand All @@ -9,4 +9,13 @@ export class PreviewStepCommand extends EnvironmentWithUserCommand {
payload: Record<string, unknown>;
subscriber?: Subscriber;
workflowOrigin: WorkflowOriginEnum;
state?: FrameworkPreviousStepsOutputState[];
}
export type FrameworkPreviousStepsOutputState = {
stepId: string;
outputs: Record<string, unknown>;
state: {
status: JobStatusEnum;
error?: string;
};
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Injectable } from '@nestjs/common';
import { Event, ExecuteOutput, HttpQueryKeysEnum, JobStatusEnum, PostActionEnum } from '@novu/framework/internal';
import { Event, ExecuteOutput, HttpQueryKeysEnum, PostActionEnum } from '@novu/framework/internal';
import { ExecuteBridgeRequest, ExecuteBridgeRequestCommand } from '@novu/application-generic';

import { PreviewStepCommand } from './preview-step.command';
Expand Down Expand Up @@ -35,7 +35,7 @@ export class PreviewStep {
return {
controls: command.controls || {},
payload: command.payload || {},
state: [],
state: command.state || [],
subscriber: command.subscriber || {},
stepId: command.stepId,
workflowId: command.workflowId,
Expand Down
3 changes: 2 additions & 1 deletion apps/api/src/app/environments-v1/novu-bridge-client.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Inject, Injectable, Scope } from '@nestjs/common';
import type { Request, Response } from 'express';
import { PostActionEnum, type Workflow } from '@novu/framework/internal';
import { Client, NovuRequestHandler, NovuHandler } from '@novu/framework/nest';
import { Client, NovuHandler, NovuRequestHandler } from '@novu/framework/nest';
import { GetDecryptedSecretKey, GetDecryptedSecretKeyCommand } from '@novu/application-generic';
import { ConstructFrameworkWorkflow, ConstructFrameworkWorkflowCommand } from './usecases/construct-framework-workflow';

Expand Down Expand Up @@ -45,6 +45,7 @@ export class NovuBridgeClient {
environmentId: req.params.environmentId,
workflowId: req.query.workflowId as string,
controlValues: req.body.controls,
action: req.query.action as PostActionEnum,
})
);

Expand Down
8 changes: 5 additions & 3 deletions apps/api/src/app/environments-v1/novu-bridge.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ import { ConstructFrameworkWorkflow } from './usecases/construct-framework-workf
import { NovuBridgeController } from './novu-bridge.controller';
import {
ChatOutputRendererUsecase,
EmailOutputRendererUsecase,
ExpandEmailEditorSchemaUsecase,
HydrateEmailSchemaUseCase,
InAppOutputRendererUsecase,
PushOutputRendererUsecase,
RenderEmailOutputUsecase,
SmsOutputRendererUsecase,
} from './usecases/output-renderers';

Expand All @@ -28,12 +29,13 @@ import {
ConstructFrameworkWorkflow,
GetDecryptedSecretKey,
InAppOutputRendererUsecase,
EmailOutputRendererUsecase,
RenderEmailOutputUsecase,
SmsOutputRendererUsecase,
ChatOutputRendererUsecase,
PushOutputRendererUsecase,
EmailOutputRendererUsecase,
RenderEmailOutputUsecase,
ExpandEmailEditorSchemaUsecase,
HydrateEmailSchemaUseCase,
],
})
export class NovuBridgeModule {}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { EnvironmentLevelCommand } from '@novu/application-generic';
import { IsDefined, IsObject, IsString } from 'class-validator';
import { IsDefined, IsEnum, IsObject, IsString } from 'class-validator';
import { PostActionEnum } from '@novu/framework/internal';

export class ConstructFrameworkWorkflowCommand extends EnvironmentLevelCommand {
@IsString()
Expand All @@ -9,4 +10,7 @@ export class ConstructFrameworkWorkflowCommand extends EnvironmentLevelCommand {
@IsObject()
@IsDefined()
controlValues: Record<string, unknown>;

@IsEnum(PostActionEnum)
action: PostActionEnum;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Injectable, InternalServerErrorException } from '@nestjs/common';
import { Injectable, InternalServerErrorException, Logger } from '@nestjs/common';
import { workflow } from '@novu/framework/express';
import {
ActionStep,
Expand All @@ -15,9 +15,10 @@ import { StepTypeEnum } from '@novu/shared';
import { ConstructFrameworkWorkflowCommand } from './construct-framework-workflow.command';
import {
ChatOutputRendererUsecase,
EmailOutputRendererUsecase,
FullPayloadForRender,
InAppOutputRendererUsecase,
PushOutputRendererUsecase,
RenderEmailOutputUsecase,
SmsOutputRendererUsecase,
} from '../output-renderers';

Expand All @@ -26,7 +27,7 @@ export class ConstructFrameworkWorkflow {
constructor(
private workflowsRepository: NotificationTemplateRepository,
private inAppOutputRendererUseCase: InAppOutputRendererUsecase,
private emailOutputRendererUseCase: EmailOutputRendererUsecase,
private emailOutputRendererUseCase: RenderEmailOutputUsecase,
private smsOutputRendererUseCase: SmsOutputRendererUsecase,
private chatOutputRendererUseCase: ChatOutputRendererUsecase,
private pushOutputRendererUseCase: PushOutputRendererUsecase
Expand All @@ -40,15 +41,21 @@ export class ConstructFrameworkWorkflow {
}
}

return this.constructFrameworkWorkflow(dbWorkflow);
return this.constructFrameworkWorkflow(dbWorkflow, command.action);
}

private constructFrameworkWorkflow(newWorkflow: NotificationTemplateEntity): Workflow {
private constructFrameworkWorkflow(newWorkflow, action) {
return workflow(
newWorkflow.triggers[0].identifier,
async ({ step }) => {
async ({ step, payload, subscriber }) => {
const fullPayloadForRender: FullPayloadForRender = { payload, subscriber, steps: {} };
for await (const staticStep of newWorkflow.steps) {
await this.constructStep(step, staticStep);
try {
const stepOutputs = await this.constructStep(step, staticStep, fullPayloadForRender);
fullPayloadForRender.steps[staticStep.stepId || staticStep._templateId] = stepOutputs;
} catch (e) {
Logger.log(`Cannot Construct Step ${staticStep.stepId || staticStep._templateId}`, e);
}
}
},
{
Expand All @@ -66,7 +73,11 @@ export class ConstructFrameworkWorkflow {
);
}

private constructStep(step: Step, staticStep: NotificationStepEntity): StepOutput<Record<string, unknown>> {
private constructStep(
step: Step,
staticStep: NotificationStepEntity,
fullPayloadForRender: FullPayloadForRender
): StepOutput<Record<string, unknown>> {
const stepTemplate = staticStep.template;

if (!stepTemplate) {
Expand All @@ -91,7 +102,7 @@ export class ConstructFrameworkWorkflow {
stepId,
// The step callback function. Takes controls and returns the step outputs
async (controlValues) => {
return this.inAppOutputRendererUseCase.execute({ controlValues });
return this.inAppOutputRendererUseCase.execute({ controlValues, fullPayloadForRender });
},
// Step options
this.constructChannelStepOptions(staticStep)
Expand All @@ -100,31 +111,31 @@ export class ConstructFrameworkWorkflow {
return step.email(
stepId,
async (controlValues) => {
return this.emailOutputRendererUseCase.execute({ controlValues });
return this.emailOutputRendererUseCase.execute({ controlValues, fullPayloadForRender });
},
this.constructChannelStepOptions(staticStep)
);
case StepTypeEnum.SMS:
return step.inApp(
stepId,
async (controlValues) => {
return this.smsOutputRendererUseCase.execute({ controlValues });
return this.smsOutputRendererUseCase.execute({ controlValues, fullPayloadForRender });
},
this.constructChannelStepOptions(staticStep)
);
case StepTypeEnum.CHAT:
return step.inApp(
stepId,
async (controlValues) => {
return this.chatOutputRendererUseCase.execute({ controlValues });
return this.chatOutputRendererUseCase.execute({ controlValues, fullPayloadForRender });
},
this.constructChannelStepOptions(staticStep)
);
case StepTypeEnum.PUSH:
return step.inApp(
stepId,
async (controlValues) => {
return this.pushOutputRendererUseCase.execute({ controlValues });
return this.pushOutputRendererUseCase.execute({ controlValues, fullPayloadForRender });
},
this.constructChannelStepOptions(staticStep)
);
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Define the command interface

import { BaseCommand } from '@novu/application-generic';
import { FullPayloadForRender } from './render-command';

export class ExpandEmailEditorSchemaCommand extends BaseCommand {
body: string;
fullPayloadForRender: FullPayloadForRender;
}
Loading

0 comments on commit 05dec8b

Please sign in to comment.