Skip to content

Commit

Permalink
feat(api): expose payload schema on get step response (#6867)
Browse files Browse the repository at this point in the history
Co-authored-by: GalT <[email protected]>
  • Loading branch information
djabarovgeorge and tatarco authored Nov 6, 2024
1 parent 0cea280 commit 6b79915
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import { GetStepDataCommand } from './get-step-data.command';
import { mapStepTypeToResult } from '../../shared';
import { GetWorkflowByIdsUseCase } from '../get-workflow-by-ids/get-workflow-by-ids.usecase';
import { InvalidStepException } from '../../exceptions/invalid-step.exception';
import { BuildDefaultPayloadUseCase } from '../build-payload-from-placeholder';

@Injectable()
export class GetStepDataUsecase {
constructor(
private getWorkflowByIdsUseCase: GetWorkflowByIdsUseCase,
private buildDefaultPayloadUseCase: BuildDefaultPayloadUseCase,
private controlValuesRepository: ControlValuesRepository
) {}

Expand All @@ -21,20 +23,30 @@ export class GetStepDataUsecase {
if (!currentStep.name || !currentStep._templateId || !currentStep.stepId) {
throw new InvalidStepException(currentStep);
}
const controlValues = await this.getValues(command, currentStep, workflow._id);
const payloadSchema = this.buildPayloadSchema(controlValues);

return {
controls: {
dataSchema: currentStep.template?.controls?.schema,
uiSchema: currentStep.template?.controls?.uiSchema,
values: await this.getValues(command, currentStep, workflow._id),
values: controlValues,
},
variables: buildVariablesSchema(previousSteps),
variables: buildVariablesSchema(previousSteps, payloadSchema),
name: currentStep.name,
_id: currentStep._templateId,
stepId: currentStep.stepId,
};
}

private buildPayloadSchema(controlValues: Record<string, any>) {
const payloadVariables = this.buildDefaultPayloadUseCase.execute({
controlValues,
}).previewPayload.payload;

return buildStringSchema(payloadVariables || {});
}

private async fetchWorkflow(command: GetStepDataCommand) {
const workflow = await this.getWorkflowByIdsUseCase.execute({
identifierOrInternalId: command.identifierOrInternalId,
Expand Down Expand Up @@ -108,12 +120,16 @@ const buildSubscriberSchema = () =>
additionalProperties: false,
}) as const satisfies JSONSchema;

function buildVariablesSchema(previousSteps?: NotificationStepEntity[]): JSONSchema {
function buildVariablesSchema(
previousSteps: NotificationStepEntity[] | undefined,
payloadSchema: JSONSchema
): JSONSchema {
return {
type: 'object',
properties: {
subscriber: buildSubscriberSchema(),
steps: buildPreviousStepsSchema(previousSteps),
payload: payloadSchema,
},
additionalProperties: false,
} as const satisfies JSONSchema;
Expand Down Expand Up @@ -142,3 +158,22 @@ function buildPreviousStepsSchema(previousSteps: NotificationStepEntity[] | unde
description: 'Previous Steps Results',
} as const satisfies JSONSchema;
}

/**
* Builds a JSON schema object where each variable becomes a string property.
*/
function buildStringSchema(variables: Record<string, unknown>): JSONSchema {
const properties: Record<string, JSONSchema> = {};

for (const [variableKey, variableValue] of Object.entries(variables)) {
properties[variableKey] = {
type: 'string',
default: variableValue,
};
}

return {
type: 'object',
properties,
};
}
38 changes: 38 additions & 0 deletions apps/api/src/app/workflows-v2/workflow.controller.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,44 @@ describe('Workflow Controller E2E API Testing', () => {
const stepRetrievedByStepIdentifier = await getStepData(internalWorkflowId, stepIdentifier);
expect(stepRetrievedByStepIdentifier._id).to.equal(stepId);
});

it('should get step payload variables', async () => {
const steps = [
{
...buildEmailStep(),
controlValues: {
body: 'Welcome to our newsletter {{bodyText}}{{bodyText2}}{{payload.prefixBodyText}}',
subject: 'Welcome to our newsletter {{subjectText}} {{payload.prefixSubjectText}}',
},
},
{ ...buildInAppStep(), controlValues: { subject: 'Welcome to our newsletter {{inAppSubjectText}}' } },
];
const createWorkflowDto: CreateWorkflowDto = buildCreateWorkflowDto('', { steps });
const res = await session.testAgent.post(`${v2Prefix}/workflows`).send(createWorkflowDto);
expect(res.status).to.be.equal(201);
const workflowCreated: WorkflowResponseDto = res.body.data;
const stepData = await getStepData(workflowCreated._id, workflowCreated.steps[0]._id);
const { variables } = stepData;

if (typeof variables === 'boolean') throw new Error('Variables is not an object');
const { properties } = variables;
expect(properties).to.be.ok;
if (!properties) throw new Error('Payload schema is not valid');

expect(properties.payload).to.deep.equal({
type: 'object',
properties: {
prefixSubjectText: {
type: 'string',
default: '{{payload.prefixSubjectText}}',
},
prefixBodyText: {
type: 'string',
default: '{{payload.prefixBodyText}}',
},
},
});
});
});

async function updateWorkflowRest(id: string, workflow: UpdateWorkflowDto): Promise<WorkflowResponseDto> {
Expand Down

0 comments on commit 6b79915

Please sign in to comment.