Refactor workflow-logic-function-interaction (#17699)

# Refactor workflow–logic function interaction

## Why

Workflow code steps and standalone logic functions shared the same build
layer and DB layer, which blurred two use cases: code steps belong to a
workflow version; standalone functions are deployable units. That made
workflow code steps harder to own and evolve.

## Goal

Treat code steps as **workflow-owned**: build and run them in workflow
context, and expose workflow-scoped APIs so the editor can load, test,
and save code step source without going through the generic
logic-function layer.
This commit is contained in:
Charles Bochet
2026-02-05 01:46:55 +01:00
committed by GitHub
parent 752359335e
commit 67a98f77e3
77 changed files with 1750 additions and 1336 deletions
@@ -38,6 +38,12 @@ export class CreateLogicFunctionInput {
@HideField()
universalIdentifier?: string;
@HideField()
id?: string;
@HideField()
checksum?: string;
@Field(() => graphqlTypeJson, { nullable: true })
@IsObject()
@IsOptional()
@@ -1,12 +1,18 @@
import { Field, InputType } from '@nestjs/graphql';
import { IsNotEmpty, IsObject, IsUUID } from 'class-validator';
import {
IsBoolean,
IsNotEmpty,
IsObject,
IsOptional,
IsUUID,
} from 'class-validator';
import graphqlTypeJson from 'graphql-type-json';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
@InputType()
export class ExecuteLogicFunctionInput {
export class ExecuteOneLogicFunctionInput {
@Field(() => UUIDScalarType, {
description: 'Id of the logic function to execute',
})
@@ -19,4 +25,12 @@ export class ExecuteLogicFunctionInput {
})
@IsObject()
payload: JSON;
@Field(() => Boolean, {
description: 'Force rebuild from source before executing',
nullable: true,
})
@IsOptional()
@IsBoolean()
forceRebuild?: boolean;
}
@@ -0,0 +1,25 @@
import { Field, InputType } from '@nestjs/graphql';
import { IsNotEmpty, IsObject, IsUUID } from 'class-validator';
import graphqlTypeJson from 'graphql-type-json';
import type { Sources } from 'twenty-shared/types';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
@InputType()
export class UpdateLogicFunctionSourceInput {
@Field(() => UUIDScalarType, {
description: 'The id of the logic function.',
})
@IsNotEmpty()
@IsUUID()
id!: string;
@Field(() => graphqlTypeJson, {
description:
'The source code (Sources) to write. Only updates source files.',
})
@IsObject()
code!: Sources;
}
@@ -38,9 +38,10 @@ class UpdateLogicFunctionInputUpdates {
@IsOptional()
timeoutSeconds?: number;
@Field(() => graphqlTypeJson)
@Field(() => graphqlTypeJson, { nullable: true })
@IsObject()
code: Sources;
@IsOptional()
code?: Sources;
@IsString()
@Field({ nullable: true })