App logic function as step (#17525)

- Add logic function as step
- Rename previous one as Code

<img width="494" height="573" alt="Capture d’écran 2026-01-28 à 16 15
29"
src="https://github.com/user-attachments/assets/82f7e720-20da-4926-b5bc-94a33cd1f53a"
/>
<img width="494" height="264" alt="Capture d’écran 2026-01-28 à 16 15
39"
src="https://github.com/user-attachments/assets/a0444ae9-8c50-418d-8c5f-68c4da08fce7"
/>
<img width="494" height="264" alt="Capture d’écran 2026-01-28 à 16 15
58"
src="https://github.com/user-attachments/assets/3025db09-4e59-421e-8dc5-f3a7a7326554"
/>

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
This commit is contained in:
Thomas Trompette
2026-01-29 11:59:24 +01:00
committed by GitHub
parent 22c7e207e3
commit 3ad7a9ac94
42 changed files with 551 additions and 90 deletions
@@ -535,7 +535,7 @@ export class WorkflowVersionEdgeWorkspaceService {
input: {
...sourceStep.settings.input,
initialLoopStepIds: currentInitialLoopStepIds.filter(
(id) => id !== target,
(id: string) => id !== target,
),
},
},
@@ -198,7 +198,7 @@ const updateStepsWithOptions = ({
initialLoopStepIds: [
...new Set([
...(step.settings.input.initialLoopStepIds?.filter(
(id) => id !== nextStepId,
(id: string) => id !== nextStepId,
) || []),
insertedStepId,
]),
@@ -11,8 +11,8 @@ import {
import { computeWorkflowVersionStepChanges } from 'src/modules/workflow/workflow-builder/utils/compute-workflow-version-step-updates.util';
import { WorkflowSchemaWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-schema/workflow-schema.workspace-service';
import { insertStep } from 'src/modules/workflow/workflow-builder/workflow-version-step/utils/insert-step';
import { WorkflowVersionStepOperationsWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step-operations.workspace-service';
import { WorkflowVersionStepHelpersWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step-helpers.workspace-service';
import { WorkflowVersionStepOperationsWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step-operations.workspace-service';
import { type WorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
@Injectable()
@@ -38,6 +38,8 @@ export class WorkflowVersionStepCreationWorkspaceService {
position,
parentStepConnectionOptions,
id,
logicFunctionId,
name,
} = input;
const workflowVersion =
@@ -59,6 +61,8 @@ export class WorkflowVersionStepCreationWorkspaceService {
position,
workflowVersionId,
id,
logicFunctionId,
name,
},
);
@@ -20,9 +20,9 @@ import { type WorkflowStepPositionInput } from 'src/engine/core-modules/workflow
import { AiAgentRoleService } from 'src/engine/metadata-modules/ai/ai-agent-role/ai-agent-role.service';
import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity';
import { DEFAULT_SMART_MODEL } from 'src/engine/metadata-modules/ai/ai-models/constants/ai-models.const';
import { LogicFunctionService } from 'src/engine/metadata-modules/logic-function/logic-function.service';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { LogicFunctionService } from 'src/engine/metadata-modules/logic-function/logic-function.service';
import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager';
import { buildSystemAuthContext } from 'src/engine/twenty-orm/utils/build-system-auth-context.util';
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
@@ -135,12 +135,16 @@ export class WorkflowVersionStepOperationsWorkspaceService {
workflowVersionId,
position,
id,
logicFunctionId,
name,
}: {
type: WorkflowActionType;
workspaceId: string;
workflowVersionId: string;
position?: WorkflowStepPositionInput;
id?: string;
logicFunctionId?: string;
name?: string;
}): Promise<{
builtStep: WorkflowAction;
additionalCreatedSteps?: WorkflowAction[];
@@ -195,6 +199,29 @@ export class WorkflowVersionStepOperationsWorkspaceService {
},
};
}
case WorkflowActionType.LOGIC_FUNCTION: {
if (!logicFunctionId) {
throw new WorkflowVersionStepException(
'Logic function ID is required for LOGIC_FUNCTION step',
WorkflowVersionStepExceptionCode.INVALID_REQUEST,
);
}
return {
builtStep: {
...baseStep,
name: name ?? 'Logic Function',
type: WorkflowActionType.LOGIC_FUNCTION,
settings: {
...BASE_STEP_DEFINITION,
input: {
logicFunctionId,
logicFunctionInput: {},
},
},
},
};
}
case WorkflowActionType.SEND_EMAIL: {
return {
builtStep: {
@@ -288,7 +288,7 @@ export class WorkflowVersionWorkspaceService {
...remappedStep.settings.input,
initialLoopStepIds:
source.settings.input.initialLoopStepIds.map(
(oldId) => oldToNewIdMap.get(oldId) ?? oldId,
(oldId: string) => oldToNewIdMap.get(oldId) ?? oldId,
),
},
};