Skip to content

Commit

Permalink
feat(api): more changes
Browse files Browse the repository at this point in the history
  • Loading branch information
tatarco committed Oct 31, 2024
1 parent c0ab421 commit ef94e9a
Show file tree
Hide file tree
Showing 14 changed files with 183 additions and 178 deletions.
2 changes: 1 addition & 1 deletion apps/api/src/app/workflows-v2/clients/workflows-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export const createWorkflowClient = (baseUrl: string, headers: HeadersInit = {})
workflowId: string,
stepId: string
): Promise<NovuRestResult<StepMetadataDto, HttpError>> => {
return await baseClient.safeGet<StepMetadataDto>(`/v2/workflows/${workflowId}/step/${stepId}/metadata`);
return await baseClient.safeGet<StepMetadataDto>(`/v2/workflows/${workflowId}/steps/${stepId}/metadata`);
};
const deleteWorkflow = async (workflowId: string): Promise<NovuRestResult<void, HttpError>> => {
return await baseClient.safeDelete(`/v2/workflows/${workflowId}`);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ActionStepEnum, actionStepSchemas, ChannelStepEnum, channelStepSchemas } from '@novu/framework/internal';
import { JSONSchema } from 'json-schema-to-ts';
import { UiSchema } from '@novu/shared';
import { ControlSchemas } from '@novu/shared';
import { EmailStepControlSchema, EmailStepUiSchema, inAppControlSchema, InAppUiSchema } from './schemas';

export const PERMISSIVE_EMPTY_SCHEMA = {
Expand All @@ -10,38 +9,32 @@ export const PERMISSIVE_EMPTY_SCHEMA = {
additionalProperties: true,
} as const;

export const mapStepTypeToControlSchema: Record<
ChannelStepEnum | ActionStepEnum,
{
dataSchema?: JSONSchema;
uiSchema?: UiSchema;
}
> = {
export const stepTypeToDefaultDashboardControlSchema: Record<ChannelStepEnum | ActionStepEnum, ControlSchemas> = {
[ChannelStepEnum.IN_APP]: {
dataSchema: inAppControlSchema,
schema: inAppControlSchema,
uiSchema: InAppUiSchema,
},
[ChannelStepEnum.EMAIL]: {
dataSchema: EmailStepControlSchema,
schema: EmailStepControlSchema,
uiSchema: EmailStepUiSchema,
},
[ChannelStepEnum.SMS]: {
dataSchema: channelStepSchemas[ChannelStepEnum.SMS].output,
schema: channelStepSchemas[ChannelStepEnum.SMS].output,
},
[ChannelStepEnum.PUSH]: {
dataSchema: channelStepSchemas[ChannelStepEnum.PUSH].output,
schema: channelStepSchemas[ChannelStepEnum.PUSH].output,
},
[ChannelStepEnum.CHAT]: {
dataSchema: channelStepSchemas[ChannelStepEnum.CHAT].output,
schema: channelStepSchemas[ChannelStepEnum.CHAT].output,
},

[ActionStepEnum.DELAY]: {
dataSchema: actionStepSchemas[ActionStepEnum.DELAY].output,
schema: actionStepSchemas[ActionStepEnum.DELAY].output,
},
[ActionStepEnum.DIGEST]: {
dataSchema: actionStepSchemas[ActionStepEnum.DIGEST].output,
schema: actionStepSchemas[ActionStepEnum.DIGEST].output,
},
[ActionStepEnum.CUSTOM]: {
dataSchema: PERMISSIVE_EMPTY_SCHEMA,
schema: PERMISSIVE_EMPTY_SCHEMA,
},
};
104 changes: 63 additions & 41 deletions apps/api/src/app/workflows-v2/shared/schemas/workflow-zod-schemas.ts
Original file line number Diff line number Diff line change
@@ -1,63 +1,85 @@
import { z } from 'zod';
import { StepTypeEnum, WorkflowCreationSourceEnum, WorkflowOriginEnum, WorkflowStatusEnum } from '@novu/shared';
import { ChannelTypeEnum, StepTypeEnum } from '@novu/shared';

export const stepDtoSchema = z.object({
name: z.string().min(1),
// Define the StepDto schema
const StepDtoSchema = z.object({
name: z.string().nonempty(),
type: z.nativeEnum(StepTypeEnum),
});

export const stepResponseDtoSchema = stepDtoSchema.extend({
_id: z.string().min(1),
slug: z.string().min(1),
stepId: z.string().min(1),
// Define the WorkflowCommonsFields schema
const WorkflowCommonsFieldsSchema = z.object({
tags: z.array(z.string()).optional(),
active: z.boolean().optional(),
name: z.string().nonempty(),
workflowId: z.string().nonempty(),
description: z.string().optional(),
});

export const stepCreateDtoSchema = stepDtoSchema.extend({
controlValues: z.record(z.unknown()),
// Define the PreferencesRequestDto schema
const PreferencesRequestDtoSchema = z.object({
user: z.union([z.lazy(() => WorkflowPreferencesSchema), z.null()]),
workflow: z.union([z.lazy(() => WorkflowPreferencesSchema), z.null()]).optional(),
});

export const stepUpdateDtoSchema = stepCreateDtoSchema.extend({
_id: z.string().min(1),
// Define the WorkflowPreferences schema
const WorkflowPreferenceSchema = z.object({
enabled: z.boolean().default(true),
readOnly: z.boolean().default(false),
});

export const preferencesResponseDtoSchema = z.object({
user: z.union([z.lazy(() => z.object({})), z.null()]),
default: z.object({}),
const ChannelPreferenceSchema = z.object({
enabled: z.boolean().default(true),
});

export const preferencesRequestDtoSchema = z.object({
user: z.union([z.lazy(() => z.object({})), z.null()]),
workflow: z.union([z.lazy(() => z.object({})), z.null()]).optional(),
const WorkflowPreferencesSchema = z.object({
all: WorkflowPreferenceSchema,
channels: z.record(z.nativeEnum(ChannelTypeEnum), ChannelPreferenceSchema),
});

export const workflowCommonsFieldsSchema = z.object({
tags: z.array(z.string()).optional(),
active: z.boolean().optional(),
name: z.string().min(1),
workflowId: z.string().min(1),
description: z.string().optional(),
// Define the StepCreateDto schema
const StepCreateDtoSchema = StepDtoSchema.extend({
controlValues: z.record(z.string()).optional(),
});

export const workflowResponseDtoSchema = workflowCommonsFieldsSchema.extend({
_id: z.string().min(1),
slug: z.string().min(1),
updatedAt: z.string().min(1),
createdAt: z.string().min(1),
steps: z.array(stepResponseDtoSchema).min(1),
origin: z.nativeEnum(WorkflowOriginEnum),
preferences: preferencesResponseDtoSchema,
status: z.nativeEnum(WorkflowStatusEnum),
issues: z.record(z.unknown()).optional(),
// Define the StepUpdateDto schema
const StepUpdateDtoSchema = StepCreateDtoSchema.extend({
_id: z.string().nonempty(),
});

export const updateWorkflowDtoSchema = workflowCommonsFieldsSchema.extend({
updatedAt: z.string().min(1),
steps: z.array(z.union([stepCreateDtoSchema, stepUpdateDtoSchema])).min(1),
preferences: preferencesRequestDtoSchema,
// Define the UpdateWorkflowDto schema
const UpdateWorkflowDtoSchema = WorkflowCommonsFieldsSchema.extend({
updatedAt: z.string().nonempty(), // Assuming updatedAt is a string representing a date
steps: z.array(z.union([StepCreateDtoSchema, StepUpdateDtoSchema])),
preferences: PreferencesRequestDtoSchema,
});

export const createWorkflowDtoSchema = workflowCommonsFieldsSchema.extend({
steps: z.array(stepCreateDtoSchema).min(1),
__source: z.nativeEnum(WorkflowCreationSourceEnum),
preferences: preferencesRequestDtoSchema.optional(),
// Define the ListWorkflowResponse schema
const ListWorkflowResponseSchema = z.object({
workflows: z.array(
z.object({
name: z.string(),
tags: z.array(z.string()),
updatedAt: z.string(),
createdAt: z.string(),
_id: z.string(),
slug: z.string(),
status: z.string(),
origin: z.string(),
stepTypeOverviews: z.array(z.nativeEnum(StepTypeEnum)),
})
),
totalCount: z.number(),
});

// Export all schemas for use in other parts of the application
export {
StepDtoSchema,
WorkflowCommonsFieldsSchema,
PreferencesRequestDtoSchema,
WorkflowPreferencesSchema,
StepCreateDtoSchema,
StepUpdateDtoSchema,
UpdateWorkflowDtoSchema,
ListWorkflowResponseSchema,
};
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { BadRequestException, Injectable } from '@nestjs/common';
import { ControlValuesLevelEnum, StepMetadataDto, StepType, StepTypeEnum } from '@novu/shared';
import { JSONSchema } from 'json-schema-to-ts';
import { ControlValuesRepository, NotificationStepEntity, NotificationTemplateRepository } from '@novu/dal';
import { ControlValuesRepository, NotificationStepEntity } from '@novu/dal';
import { GetStepSchemaCommand } from './get-step-schema.command';
import { mapStepTypeToResult } from '../../shared';
import { GetWorkflowByIdsUseCase } from '../get-workflow-by-ids/get-workflow-by-ids.usecase';

@Injectable()
export class GetStepMetadataUseCase {
constructor(
private notificationTemplateRepository: NotificationTemplateRepository,
private getWorkflowByIdsUseCase: GetWorkflowByIdsUseCase,
private controlValuesRepository: ControlValuesRepository
) {}

Expand All @@ -28,8 +29,8 @@ export class GetStepMetadataUseCase {

private async getValues(command: GetStepSchemaCommand, currentStep: NotificationStepEntity) {
const controlValuesEntity = await this.controlValuesRepository.findFirst({
_environmentId: command.environmentId,
_organizationId: command.organizationId,
_environmentId: command.user.environmentId,
_organizationId: command.user.organizationId,
_workflowId: command.workflowId,
_stepId: currentStep._templateId,
level: ControlValuesLevelEnum.STEP_CONTROLS,
Expand All @@ -42,7 +43,6 @@ export class GetStepMetadataUseCase {
if (!currentStep.template?.type) {
throw new BadRequestException('No step type found');
}

if (!currentStep.template?.controls?.schema) {
throw new BadRequestException('No controls schema found');
}
Expand All @@ -56,9 +56,9 @@ export class GetStepMetadataUseCase {
}

private async findSteps(command: GetStepSchemaCommand) {
const workflow = await this.notificationTemplateRepository.findByIdQuery({
id: command.workflowId,
environmentId: command.environmentId,
const workflow = await this.getWorkflowByIdsUseCase.execute({
identifierOrInternalId: command.workflowId,
user: command.user,
});

if (!workflow) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { EnvironmentWithUserCommand } from '@novu/application-generic';
import { EnvironmentWithUserObjectCommand } from '@novu/application-generic';
import { IsNotEmpty, IsString } from 'class-validator';

export class GetStepSchemaCommand extends EnvironmentWithUserCommand {
export class GetStepSchemaCommand extends EnvironmentWithUserObjectCommand {
@IsString()
@IsNotEmpty()
workflowId: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ export class SyncToEnvironmentUseCase {
preferences: PreferencesEntity[]
): Promise<UpdateWorkflowDto> {
return {
updatedAt: new Date().toISOString(),
workflowId: workflow.triggers[0].identifier,
name: workflow.name,
active: workflow.active,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import { StepUpsertMechanismFailedMissingIdException } from '../../exceptions/st
import { toResponseWorkflowDto } from '../../mappers/notification-template-mapper';
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 { mapStepTypeToControlSchema } from '../../shared';
import { stepTypeToDefaultDashboardControlSchema } from '../../shared';

function buildUpsertControlValuesCommand(
command: UpsertWorkflowCommand,
Expand Down Expand Up @@ -298,7 +298,7 @@ export class UpsertWorkflowUseCase {
template: {
type: step.type,
name: step.name,
controls: foundPersistedStep?.template?.controls || mapStepTypeToControlSchema[step.type],
controls: foundPersistedStep?.template?.controls || stepTypeToDefaultDashboardControlSchema[step.type],
content: '',
},
stepId: slugify(step.name),
Expand Down
Loading

0 comments on commit ef94e9a

Please sign in to comment.