Skip to content

Commit

Permalink
fix(api): fixed deletion + origin bug (#6663)
Browse files Browse the repository at this point in the history
  • Loading branch information
tatarco authored Oct 10, 2024
1 parent c7b6b2b commit 673346b
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 83 deletions.
161 changes: 88 additions & 73 deletions apps/api/src/app/bridge/usecases/sync/sync.usecase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,13 @@ export class Sync {
});
}

const createdWorkflows = await this.createWorkflows(command, discover.workflows);
const persistedWorkflowsInBridge = await this.createWorkflows(command, discover.workflows);

await this.disposeOldWorkflows(command, createdWorkflows);
await this.disposeOldWorkflows(command, persistedWorkflowsInBridge);

await this.updateBridgeUrl(command);

return createdWorkflows;
return persistedWorkflowsInBridge;
}

private async updateBridgeUrl(command: SyncCommand) {
Expand All @@ -100,18 +100,12 @@ export class Sync {
}

private async disposeOldWorkflows(command: SyncCommand, createdWorkflows: NotificationTemplateEntity[]) {
const workflowIds = createdWorkflows.map((i) => i._id);
const persistedWorkflowIdsInBridge = createdWorkflows.map((i) => i._id);

const deletedWorkflows = await this.notificationTemplateRepository.find({
_environmentId: command.environmentId,
type: {
$in: [WorkflowTypeEnum.ECHO, WorkflowTypeEnum.BRIDGE],
},
_id: { $nin: workflowIds },
});
const workflowsToDelete = await this.findAllWorkflowsWithOtherIds(command, persistedWorkflowIdsInBridge);

await Promise.all(
deletedWorkflows?.map((workflow) => {
workflowsToDelete?.map((workflow) => {
return this.deleteWorkflow.execute(
DeleteWorkflowCommand.create({
environmentId: command.environmentId,
Expand All @@ -124,9 +118,22 @@ export class Sync {
);
}

private async createWorkflows(command: SyncCommand, workflows: DiscoverWorkflowOutput[]) {
private async findAllWorkflowsWithOtherIds(command: SyncCommand, persistedWorkflowIdsInBridge: string[]) {
return await this.notificationTemplateRepository.find({
_environmentId: command.environmentId,
type: {
$in: [WorkflowTypeEnum.ECHO, WorkflowTypeEnum.BRIDGE],
},
origin: {
$in: [WorkflowOriginEnum.EXTERNAL, undefined, null],
},
_id: { $nin: persistedWorkflowIdsInBridge },
});
}

private async createWorkflows(command: SyncCommand, workflowsFromBridge: DiscoverWorkflowOutput[]) {
return Promise.all(
workflows.map(async (workflow) => {
workflowsFromBridge.map(async (workflow) => {
const workflowExist = await this.notificationTemplateRepository.findByTriggerIdentifier(
command.environmentId,
workflow.workflowId
Expand All @@ -135,33 +142,7 @@ export class Sync {
let savedWorkflow: NotificationTemplateEntity | undefined;

if (workflowExist) {
savedWorkflow = await this.updateWorkflowUsecase.execute(
UpdateWorkflowCommand.create({
id: workflowExist._id,
environmentId: command.environmentId,
organizationId: command.organizationId,
userId: command.userId,
name: workflow.workflowId,
steps: this.mapSteps(workflow.steps, workflowExist),
inputs: {
schema: workflow.controls?.schema || workflow.inputs.schema,
},
controls: {
schema: workflow.controls?.schema || workflow.inputs.schema,
},
rawData: workflow,
payloadSchema:
(workflow.payload?.schema as Record<string, unknown>) ||
(workflow.options?.payloadSchema as Record<string, unknown>),
type: WorkflowTypeEnum.BRIDGE,
description: this.castToAnyNotSupportedParam(workflow.options).description,
data: this.castToAnyNotSupportedParam(workflow.options)?.data,
tags: workflow.tags,
active: this.castToAnyNotSupportedParam(workflow.options)?.active ?? true,
critical: this.castToAnyNotSupportedParam(workflow.options)?.critical ?? false,
preferenceSettings: this.castToAnyNotSupportedParam(workflow.options)?.preferenceSettings,
})
);
savedWorkflow = await this.updateWorkflow(workflowExist, command, workflow);
} else {
const notificationGroupId = await this.getNotificationGroup(
this.castToAnyNotSupportedParam(workflow.options)?.notificationGroupId,
Expand All @@ -173,38 +154,7 @@ export class Sync {
}
const isWorkflowActive = this.castToAnyNotSupportedParam(workflow.options)?.active ?? true;

savedWorkflow = await this.createWorkflowUsecase.execute(
CreateWorkflowCommand.create({
origin: WorkflowOriginEnum.EXTERNAL,
notificationGroupId,
draft: !isWorkflowActive,
environmentId: command.environmentId,
organizationId: command.organizationId,
userId: command.userId,
name: workflow.workflowId,
__source: WorkflowCreationSourceEnum.BRIDGE,
type: WorkflowTypeEnum.BRIDGE,
steps: this.mapSteps(workflow.steps),
/** @deprecated */
inputs: {
schema: workflow.controls?.schema || workflow.inputs.schema,
},
controls: {
schema: workflow.controls?.schema || workflow.inputs.schema,
},
rawData: workflow as unknown as Record<string, unknown>,
payloadSchema:
(workflow.payload?.schema as Record<string, unknown>) ||
/** @deprecated */
(workflow.options?.payloadSchema as Record<string, unknown>),
active: isWorkflowActive,
description: this.castToAnyNotSupportedParam(workflow.options).description,
data: this.castToAnyNotSupportedParam(workflow).options?.data,
tags: workflow.tags || [],
critical: this.castToAnyNotSupportedParam(workflow.options)?.critical ?? false,
preferenceSettings: this.castToAnyNotSupportedParam(workflow.options)?.preferenceSettings,
})
);
savedWorkflow = await this.createWorkflow(notificationGroupId, isWorkflowActive, command, workflow);
}

const isWorkflowPreferencesEnabled = await this.getFeatureFlag.execute(
Expand Down Expand Up @@ -232,6 +182,71 @@ export class Sync {
);
}

private async createWorkflow(notificationGroupId: string, isWorkflowActive, command: SyncCommand, workflow) {
return await this.createWorkflowUsecase.execute(
CreateWorkflowCommand.create({
origin: WorkflowOriginEnum.EXTERNAL,
type: WorkflowTypeEnum.BRIDGE,
notificationGroupId,
draft: !isWorkflowActive,
environmentId: command.environmentId,
organizationId: command.organizationId,
userId: command.userId,
name: workflow.workflowId,
__source: WorkflowCreationSourceEnum.BRIDGE,
steps: this.mapSteps(workflow.steps),
/** @deprecated */
inputs: {
schema: workflow.controls?.schema || workflow.inputs.schema,
},
controls: {
schema: workflow.controls?.schema || workflow.inputs.schema,
},
rawData: workflow as unknown as Record<string, unknown>,
payloadSchema:
(workflow.payload?.schema as Record<string, unknown>) ||
/** @deprecated */
(workflow.options?.payloadSchema as Record<string, unknown>),
active: isWorkflowActive,
description: this.castToAnyNotSupportedParam(workflow.options).description,
data: this.castToAnyNotSupportedParam(workflow).options?.data,
tags: workflow.tags || [],
critical: this.castToAnyNotSupportedParam(workflow.options)?.critical ?? false,
preferenceSettings: this.castToAnyNotSupportedParam(workflow.options)?.preferenceSettings,
})
);
}

private async updateWorkflow(workflowExist, command: SyncCommand, workflow) {
return await this.updateWorkflowUsecase.execute(
UpdateWorkflowCommand.create({
id: workflowExist._id,
environmentId: command.environmentId,
organizationId: command.organizationId,
userId: command.userId,
name: workflow.workflowId,
steps: this.mapSteps(workflow.steps, workflowExist),
inputs: {
schema: workflow.controls?.schema || workflow.inputs.schema,
},
controls: {
schema: workflow.controls?.schema || workflow.inputs.schema,
},
rawData: workflow,
payloadSchema:
(workflow.payload?.schema as Record<string, unknown>) ||
(workflow.options?.payloadSchema as Record<string, unknown>),
type: WorkflowTypeEnum.BRIDGE,
description: this.castToAnyNotSupportedParam(workflow.options).description,
data: this.castToAnyNotSupportedParam(workflow.options)?.data,
tags: workflow.tags,
active: this.castToAnyNotSupportedParam(workflow.options)?.active ?? true,
critical: this.castToAnyNotSupportedParam(workflow.options)?.critical ?? false,
preferenceSettings: this.castToAnyNotSupportedParam(workflow.options)?.preferenceSettings,
})
);
}

private mapSteps(commandWorkflowSteps: DiscoverStepOutput[], workflow?: NotificationTemplateEntity | undefined) {
const steps: NotificationStep[] = commandWorkflowSteps.map((step) => {
const foundStep = workflow?.steps?.find((workflowStep) => workflowStep.stepId === step.stepId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ export function toResponseWorkflowDto(
steps: getSteps(template, stepIdToControlValuesMap),
name: template.name,
description: template.description,
origin: template.origin || WorkflowOriginEnum.NOVU_CLOUD,
type: template.type || WorkflowTypeEnum.BRIDGE,
origin: template.origin || WorkflowOriginEnum.EXTERNAL,
type: template.type || ('MISSING-TYPE-ISSUE' as unknown as WorkflowTypeEnum),
updatedAt: template.updatedAt || 'Missing Updated At',
createdAt: template.createdAt || 'Missing Create At',
status: WorkflowStatusEnum.ACTIVE,
Expand All @@ -56,8 +56,8 @@ function getSteps(template: NotificationTemplateEntity, controlValuesMap: { [p:

function toMinifiedWorkflowDto(template: NotificationTemplateEntity): WorkflowListResponseDto {
return {
origin: template.origin || WorkflowOriginEnum.NOVU_CLOUD,
type: template.type || WorkflowTypeEnum.BRIDGE,
origin: template.origin || WorkflowOriginEnum.EXTERNAL,
type: template.type || ('MISSING-TYPE-ISSUE' as unknown as WorkflowTypeEnum),
_id: template._id,
name: template.name,
tags: template.tags,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
WorkflowTypeEnum,
} from '@novu/shared';

import { PinoLogger } from 'nestjs-pino';
import {
CreateWorkflowCommand,
NotificationStep,
Expand All @@ -53,13 +54,13 @@ export class CreateWorkflow {
private createChange: CreateChange,
@Inject(forwardRef(() => AnalyticsService))
private analyticsService: AnalyticsService,
private logger: PinoLogger,
protected moduleRef: ModuleRef,
) {}

async execute(usecaseCommand: CreateWorkflowCommand) {
const blueprintCommand = await this.processBlueprint(usecaseCommand);
const command = blueprintCommand ?? usecaseCommand;

this.validatePayload(command);

let triggerIdentifier: string;
Expand Down Expand Up @@ -244,6 +245,8 @@ export class CreateWorkflow {
trigger: INotificationTrigger,
triggerIdentifier: string,
) {
this.logger.info(`Creating workflow ${JSON.stringify(command)}`);

const savedWorkflow = await this.notificationTemplateRepository.create({
_organizationId: command.organizationId,
_creatorId: command.userId,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { WorkflowOriginEnum, WorkflowTypeEnum } from '@novu/shared';
import { WorkflowTypeEnum } from '@novu/shared';
import mongoose, { Schema } from 'mongoose';

import { schemaOptions } from '../schema-default.options';
Expand Down Expand Up @@ -26,10 +26,6 @@ const variantSchemePart = {
type: Schema.Types.String,
default: WorkflowTypeEnum.REGULAR,
},
origin: {
type: Schema.Types.String,
default: WorkflowOriginEnum.NOVU_CLOUD,
},
filters: [
{
isNegated: Schema.Types.Boolean,
Expand Down Expand Up @@ -201,6 +197,9 @@ const notificationTemplateSchema = new Schema<NotificationTemplateDBModel>(
default: true,
},
},
origin: {
type: Schema.Types.String,
},
_environmentId: {
type: Schema.Types.ObjectId,
ref: 'Environment',
Expand Down

0 comments on commit 673346b

Please sign in to comment.