diff --git a/packages/backend/src/db/migrations/20211106214730_create_steps.ts b/packages/backend/src/db/migrations/20211106214730_create_steps.ts index eaa06eb9..d9135b0f 100644 --- a/packages/backend/src/db/migrations/20211106214730_create_steps.ts +++ b/packages/backend/src/db/migrations/20211106214730_create_steps.ts @@ -1,4 +1,4 @@ -import { Knex } from "knex"; +import { Knex } from 'knex'; export async function up(knex: Knex): Promise { return knex.schema.createTable('steps', (table) => { @@ -7,11 +7,11 @@ export async function up(knex: Knex): Promise { table.string('app_key').notNullable(); table.string('type').notNullable(); table.integer('connection_id').references('id').inTable('connections'); - table.text('parameters') + table.text('parameters'); table.timestamps(true, true); }); -}; +} export async function down(knex: Knex): Promise { return knex.schema.dropTable('steps'); diff --git a/packages/backend/src/db/migrations/20220221225128_alter_columns_of_execution_steps.ts b/packages/backend/src/db/migrations/20220221225128_alter_columns_of_execution_steps.ts new file mode 100644 index 00000000..7574a5d7 --- /dev/null +++ b/packages/backend/src/db/migrations/20220221225128_alter_columns_of_execution_steps.ts @@ -0,0 +1,15 @@ +import { Knex } from 'knex'; + +export async function up(knex: Knex): Promise { + return knex.schema.alterTable('execution_steps', (table) => { + table.jsonb('data_in').alter(); + table.jsonb('data_out').alter(); + }); +} + +export async function down(knex: Knex): Promise { + return knex.schema.alterTable('execution_steps', (table) => { + table.text('data_in').alter(); + table.text('data_out').alter(); + }); +} diff --git a/packages/backend/src/db/migrations/20220221225537_alter_parameters_column_of_steps.ts b/packages/backend/src/db/migrations/20220221225537_alter_parameters_column_of_steps.ts new file mode 100644 index 00000000..0f912860 --- /dev/null +++ b/packages/backend/src/db/migrations/20220221225537_alter_parameters_column_of_steps.ts @@ -0,0 +1,13 @@ +import { Knex } from 'knex'; + +export async function up(knex: Knex): Promise { + return knex.schema.alterTable('steps', (table) => { + table.jsonb('parameters').alter(); + }); +} + +export async function down(knex: Knex): Promise { + return knex.schema.alterTable('steps', (table) => { + table.text('parameters').alter(); + }); +} diff --git a/packages/backend/src/graphql/queries/get-step-with-test-executions.ts b/packages/backend/src/graphql/queries/get-step-with-test-executions.ts new file mode 100644 index 00000000..9a358f8d --- /dev/null +++ b/packages/backend/src/graphql/queries/get-step-with-test-executions.ts @@ -0,0 +1,42 @@ +import { GraphQLNonNull, GraphQLString, GraphQLList } from 'graphql'; +import RequestWithCurrentUser from '../../types/express/request-with-current-user'; +import stepType from '../types/step'; + +type Params = { + stepId: string; +}; + +const getStepWithTestExecutionsResolver = async ( + params: Params, + req: RequestWithCurrentUser +) => { + const step = await req.currentUser + .$relatedQuery('steps') + .findOne({ 'steps.id': params.stepId }) + .throwIfNotFound(); + + const previousStepsWithCurrentStep = await req.currentUser + .$relatedQuery('steps') + .withGraphJoined('executionSteps') + .select('steps.*', 'executionSteps.data_out as output') + .where('flow_id', '=', step.flowId) + .andWhere('position', '<=', step.position) + .distinctOn('executionSteps.step_id') + .orderBy([ + 'executionSteps.step_id', + { column: 'executionSteps.created_at', order: 'desc' }, + ]); + + return previousStepsWithCurrentStep; +}; + +const getStepWithTestExecutions = { + type: GraphQLList(stepType), + args: { + stepId: { type: GraphQLNonNull(GraphQLString) }, + }, + resolve: (_: any, params: Params, req: RequestWithCurrentUser) => + getStepWithTestExecutionsResolver(params, req), +}; + +export default getStepWithTestExecutions; diff --git a/packages/backend/src/graphql/root-query.ts b/packages/backend/src/graphql/root-query.ts index 2059f18e..484fdcd1 100644 --- a/packages/backend/src/graphql/root-query.ts +++ b/packages/backend/src/graphql/root-query.ts @@ -6,6 +6,7 @@ import getAppConnections from './queries/get-app-connections'; import testConnection from './queries/test-connection'; import getFlow from './queries/get-flow'; import getFlows from './queries/get-flows'; +import getStepWithTestExecutions from './queries/get-step-with-test-executions'; const rootQuery = new GraphQLObjectType({ name: 'Query', @@ -17,6 +18,7 @@ const rootQuery = new GraphQLObjectType({ testConnection, getFlow, getFlows, + getStepWithTestExecutions, }, }); diff --git a/packages/backend/src/graphql/types/execution-step.ts b/packages/backend/src/graphql/types/execution-step.ts new file mode 100644 index 00000000..5415c71b --- /dev/null +++ b/packages/backend/src/graphql/types/execution-step.ts @@ -0,0 +1,15 @@ +import { GraphQLObjectType, GraphQLString, GraphQLBoolean } from 'graphql'; +import { GraphQLJSONObject } from 'graphql-type-json'; + +const executionStepType = new GraphQLObjectType({ + name: 'ExecutionStep', + fields: { + executionId: { type: GraphQLString }, + stepId: { type: GraphQLString }, + status: { type: GraphQLString }, + dataIn: { type: GraphQLJSONObject }, + dataOut: { type: GraphQLJSONObject }, + }, +}); + +export default executionStepType; diff --git a/packages/backend/src/graphql/types/step.ts b/packages/backend/src/graphql/types/step.ts index a0800bd1..1e8ef7c3 100644 --- a/packages/backend/src/graphql/types/step.ts +++ b/packages/backend/src/graphql/types/step.ts @@ -5,6 +5,7 @@ import { GraphQLInt, GraphQLInputObjectType, } from 'graphql'; +import { GraphQLJSONObject } from 'graphql-type-json'; import ConnectionType from './connection'; const stepType = new GraphQLObjectType({ @@ -27,9 +28,10 @@ const stepType = new GraphQLObjectType({ }, }), }, - parameters: { type: GraphQLString }, + parameters: { type: GraphQLJSONObject }, connection: { type: ConnectionType }, flow: { type: FlowType }, + output: { type: GraphQLJSONObject }, position: { type: GraphQLInt }, status: { type: GraphQLString }, }; diff --git a/packages/backend/src/models/execution-step.ts b/packages/backend/src/models/execution-step.ts index d4743a99..312c1c43 100644 --- a/packages/backend/src/models/execution-step.ts +++ b/packages/backend/src/models/execution-step.ts @@ -1,5 +1,6 @@ import Base from './base'; import Execution from './execution'; +import Step from './step'; class ExecutionStep extends Base { id!: string; @@ -33,6 +34,14 @@ class ExecutionStep extends Base { to: 'executions.id', }, }, + step: { + relation: Base.BelongsToOneRelation, + modelClass: Step, + join: { + from: 'execution_steps.step_id', + to: 'steps.id', + }, + }, }); } diff --git a/packages/backend/src/models/step.ts b/packages/backend/src/models/step.ts index d5cc776c..83f02f56 100644 --- a/packages/backend/src/models/step.ts +++ b/packages/backend/src/models/step.ts @@ -1,6 +1,7 @@ import Base from './base'; import Flow from './flow'; import Connection from './connection'; +import ExecutionStep from './execution-step'; enum StepEnumType { 'trigger', @@ -19,6 +20,7 @@ class Step extends Base { parameters: string; connection?: Connection; flow?: Flow; + executionSteps?: [ExecutionStep]; static tableName = 'steps'; @@ -56,6 +58,14 @@ class Step extends Base { to: 'connections.id', }, }, + executionSteps: { + relation: Base.HasManyRelation, + modelClass: ExecutionStep, + join: { + from: 'steps.id', + to: 'execution_steps.step_id', + }, + }, }); }