Skip to content

Commit

Permalink
bug(api): 2XX issues
Browse files Browse the repository at this point in the history
  • Loading branch information
tatarco committed Nov 7, 2024
1 parent 4e7a429 commit 9245910
Show file tree
Hide file tree
Showing 24 changed files with 542 additions and 112 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ export class StepMissingControlsException extends InternalServerErrorException {
super({ message: 'Step cannot be found using the UUID Supplied', stepDatabaseId, step });
}
}
export class StepMissingStepIdException extends InternalServerErrorException {
constructor(stepDatabaseId: string, step: any) {
super({ message: 'Step Missing StepId', stepDatabaseId, step });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import {
DEFAULT_WORKFLOW_PREFERENCES,
PreferencesResponseDto,
PreferencesTypeEnum,
RuntimeIssue,
ShortIsPrefixEnum,
StepResponseDto,
StepTypeEnum,
WorkflowCreateAndUpdateKeys,
WorkflowListResponseDto,
WorkflowOriginEnum,
WorkflowResponseDto,
Expand Down Expand Up @@ -39,6 +41,7 @@ export function toResponseWorkflowDto(
updatedAt: template.updatedAt || 'Missing Updated At',
createdAt: template.createdAt || 'Missing Create At',
status: WorkflowStatusEnum.ACTIVE,
issues: template.issues as unknown as Record<WorkflowCreateAndUpdateKeys, RuntimeIssue>,
};
}

Expand Down Expand Up @@ -73,15 +76,16 @@ export function toWorkflowsMinifiedDtos(templates: NotificationTemplateEntity[])
return templates.map(toMinifiedWorkflowDto);
}

function toStepResponseDto(step: NotificationStepEntity): StepResponseDto {
const stepName = step.name || 'Missing Name';
function toStepResponseDto(persistedStep: NotificationStepEntity): StepResponseDto {
const stepName = persistedStep.name || 'Missing Name';

return {
_id: step._templateId,
slug: buildSlug(stepName, ShortIsPrefixEnum.STEP, step._templateId),
_id: persistedStep._templateId,
slug: buildSlug(stepName, ShortIsPrefixEnum.STEP, persistedStep._templateId),
name: stepName,
stepId: step.stepId || 'Missing Step Id',
type: step.template?.type || StepTypeEnum.EMAIL,
stepId: persistedStep.stepId || 'Missing Step Id',
type: persistedStep.template?.type || StepTypeEnum.EMAIL,
issues: persistedStep.issues,
} satisfies StepResponseDto;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable no-param-reassign */
import { Injectable } from '@nestjs/common';
import { ControlPreviewIssue, ControlPreviewIssueTypeEnum, PreviewPayload } from '@novu/shared';
import { ContentIssue, PreviewPayload, StepContentIssueEnum } from '@novu/shared';
import { BaseCommand } from '@novu/application-generic';
import _ = require('lodash');
import { CreateMockPayloadForSingleControlValueUseCase } from '../placeholder-enrichment/payload-preview-value-generator.usecase';
Expand All @@ -16,7 +16,7 @@ export class BuildDefaultPayloadUseCase {

execute(command: BuildDefaultPayloadCommand): {
previewPayload: PreviewPayload;
issues: Record<string, ControlPreviewIssue[]>;
issues: Record<string, ContentIssue[]>;
} {
let aggregatedDefaultValues = {};
const aggregatedDefaultValuesForControl: Record<string, Record<string, unknown>> = {};
Expand Down Expand Up @@ -96,13 +96,13 @@ export class BuildDefaultPayloadUseCase {
private buildPayloadIssues(
missingVariables: string[],
variableToControlValueKeys: Record<string, string[]>
): Record<string, ControlPreviewIssue[]> {
const record: Record<string, ControlPreviewIssue[]> = {};
): Record<string, ContentIssue[]> {
const record: Record<string, ContentIssue[]> = {};
missingVariables.forEach((missingVariable) => {
variableToControlValueKeys[missingVariable].forEach((controlValueKey) => {
record[controlValueKey] = [
{
issueType: ControlPreviewIssueTypeEnum.MISSING_VARIABLE_IN_PAYLOAD,
issueType: StepContentIssueEnum.MISSING_VARIABLE_IN_PAYLOAD,
message: `Variable payload.${missingVariable} is missing in payload`,
variableName: `payload.${missingVariable}`,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { Injectable } from '@nestjs/common';
import {
ChannelTypeEnum,
ControlPreviewIssue,
ControlPreviewIssueTypeEnum,
ContentIssue,
ControlSchemas,
GeneratePreviewResponseDto,
JobStatusEnum,
JSONSchemaDto,
PreviewPayload,
StepContentIssueEnum,
StepTypeEnum,
WorkflowOriginEnum,
} from '@novu/shared';
Expand All @@ -16,19 +15,19 @@ import _ = require('lodash');
import { GeneratePreviewCommand } from './generate-preview-command';
import { PreviewStep, PreviewStepCommand } from '../../../bridge/usecases/preview-step';
import { StepMissingControlsException, StepNotFoundException } from '../../exceptions/step-not-found-exception';
import { ExtractDefaultsUsecase } from '../get-default-values-from-schema/extract-defaults.usecase';
import { GetWorkflowByIdsUseCase } from '../get-workflow-by-ids/get-workflow-by-ids.usecase';
import { OriginMissingException, StepIdMissingException } from './step-id-missing.exception';
import { BuildDefaultPayloadUseCase } from '../build-payload-from-placeholder';
import { FrameworkPreviousStepsOutputState } from '../../../bridge/usecases/preview-step/preview-step.command';
import { ValidateControlValuesAndConstructPassableStructureUsecase } from '../validate-control-values/build-default-control-values-usecase.service';

@Injectable()
export class GeneratePreviewUsecase {
constructor(
private legacyPreviewStepUseCase: PreviewStep,
private getWorkflowByIdsUseCase: GetWorkflowByIdsUseCase,
private extractDefaultsUseCase: ExtractDefaultsUsecase,
private constructPayloadUseCase: BuildDefaultPayloadUseCase
private constructPayloadUseCase: BuildDefaultPayloadUseCase,
private controlValuesUsecase: ValidateControlValuesAndConstructPassableStructureUsecase
) {}

async execute(command: GeneratePreviewCommand): Promise<GeneratePreviewResponseDto> {
Expand Down Expand Up @@ -63,16 +62,11 @@ export class GeneratePreviewUsecase {
return { previewPayload, issues };
}

3;
private addMissingValuesToControlValues(command: GeneratePreviewCommand, stepControlSchema: ControlSchemas) {
const defaultValues = this.extractDefaultsUseCase.execute({
jsonSchemaDto: stepControlSchema.schema as JSONSchemaDto,
return this.controlValuesUsecase.execute({
controlSchema: stepControlSchema,
controlValues: command.generatePreviewRequestDto.controlValues || {},
});

return {
augmentedControlValues: merge(defaultValues, command.generatePreviewRequestDto.controlValues),
issuesMissingValues: this.buildMissingControlValuesIssuesList(defaultValues, command),
};
}

private buildMissingControlValuesIssuesList(defaultValues: Record<string, any>, command: GeneratePreviewCommand) {
Expand All @@ -81,16 +75,16 @@ export class GeneratePreviewUsecase {
command.generatePreviewRequestDto.controlValues || {}
);

return this.buildControlPreviewIssues(missingRequiredControlValues);
return this.buildContentIssues(missingRequiredControlValues);
}

private buildControlPreviewIssues(keys: string[]): Record<string, ControlPreviewIssue[]> {
const record: Record<string, ControlPreviewIssue[]> = {};
private buildContentIssues(keys: string[]): Record<string, ContentIssue[]> {
const record: Record<string, ContentIssue[]> = {};

keys.forEach((key) => {
record[key] = [
{
issueType: ControlPreviewIssueTypeEnum.MISSING_VALUE,
issueType: StepContentIssueEnum.MISSING_VALUE,
message: `Value is missing on a required control`,
},
];
Expand All @@ -115,7 +109,6 @@ export class GeneratePreviewUsecase {
}

const state = buildState(hydratedPayload.steps);
console.log('state', JSON.stringify(state, null, 2));

return await this.legacyPreviewStepUseCase.execute(
PreviewStepCommand.create({
Expand Down Expand Up @@ -158,8 +151,8 @@ export class GeneratePreviewUsecase {
}

function buildResponse(
missingValuesIssue: Record<string, ControlPreviewIssue[]>,
missingPayloadVariablesIssue: Record<string, ControlPreviewIssue[]>,
missingValuesIssue: Record<string, ContentIssue[]>,
missingPayloadVariablesIssue: Record<string, ContentIssue[]>,
executionOutput,
stepType: StepTypeEnum,
augmentedPayload: PreviewPayload
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import { toResponseWorkflowDto } from '../../mappers/notification-template-mappe
import { GetWorkflowByIdsUseCase } from '../get-workflow-by-ids/get-workflow-by-ids.usecase';
import { GetWorkflowByIdsCommand } from '../get-workflow-by-ids/get-workflow-by-ids.command';
import { stepTypeToDefaultDashboardControlSchema } from '../../shared';
import { ValidateAndPersistWorkflowIssuesUsecase } from './validate-and-persist-workflow-issues.usecase';

function buildUpsertControlValuesCommand(
command: UpsertWorkflowCommand,
Expand All @@ -69,16 +70,24 @@ export class UpsertWorkflowUseCase {
private notificationGroupRepository: NotificationGroupRepository,
private upsertPreferencesUsecase: UpsertPreferences,
private upsertControlValuesUseCase: UpsertControlValuesUseCase,
private validateWorkflowUsecase: ValidateAndPersistWorkflowIssuesUsecase,
private getWorkflowByIdsUseCase: GetWorkflowByIdsUseCase,
private getPreferencesUseCase: GetPreferences
) {}
async execute(command: UpsertWorkflowCommand): Promise<WorkflowResponseDto> {
const workflowForUpdate = await this.queryWorkflow(command);

const workflow = await this.createOrUpdateWorkflow(workflowForUpdate, command);
await this.upsertControlValues(workflow, command);
const stepIdToControlValuesMap = await this.upsertControlValues(workflow, command);
const preferences = await this.upsertPreference(command, workflow);

return toResponseWorkflowDto(workflow, preferences);
const validatedWorkflowWithIssues = await this.validateWorkflowUsecase.execute({
user: command.user,
workflow,
preferences,
stepIdToControlValuesMap,
});

return toResponseWorkflowDto(validatedWorkflowWithIssues, preferences);
}

private async queryWorkflow(command: UpsertWorkflowCommand): Promise<NotificationTemplateEntity | null> {
Expand Down
Loading

0 comments on commit 9245910

Please sign in to comment.