Remove versions from logicFunction (#17540)

## Summary

- Remove `latestVersion` and `publishedVersions` columns from
`LogicFunction` entity
- Remove version parameter from logic function execution, build, and
source code retrieval
- Update all related services, DTOs, utilities, and tests
- Add database migration to drop the version columns
This commit is contained in:
Charles Bochet
2026-01-30 14:30:49 +01:00
committed by GitHub
parent 077cfeffca
commit 6eebf6f23a
64 changed files with 55 additions and 480 deletions
@@ -99,7 +99,6 @@ describe('computeWorkflowVersionStepChanges', () => {
settings: {
input: {
logicFunctionId: '',
logicFunctionVersion: '',
logicFunctionInput: {},
},
errorHandlingOptions: {
@@ -37,10 +37,8 @@ describe('WorkflowVersionStepOperationsWorkspaceService', () => {
beforeEach(async () => {
logicFunctionService = {
createOneLogicFunction: jest.fn(),
hasLogicFunctionPublishedVersion: jest.fn(),
deleteOneLogicFunction: jest.fn(),
duplicateLogicFunction: jest.fn(),
createDraftFromPublishedVersion: jest.fn(),
} as unknown as jest.Mocked<LogicFunctionService>;
agentRepository = {
@@ -142,7 +140,6 @@ describe('WorkflowVersionStepOperationsWorkspaceService', () => {
settings: {
input: {
logicFunctionId: 'function-id',
logicFunctionVersion: 'v1',
},
outputSchema: {},
errorHandlingOptions: {
@@ -152,10 +149,6 @@ describe('WorkflowVersionStepOperationsWorkspaceService', () => {
},
} as unknown as WorkflowAction;
logicFunctionService.hasLogicFunctionPublishedVersion.mockResolvedValue(
false,
);
await service.runWorkflowVersionStepDeletionSideEffects({
step,
workspaceId: mockWorkspaceId,
@@ -252,8 +245,6 @@ describe('WorkflowVersionStepOperationsWorkspaceService', () => {
id: 'new-function-id',
name: 'Test Function',
description: 'Test Description',
latestVersion: 'v1',
publishedVersions: [],
workspaceId: mockWorkspaceId,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
@@ -289,13 +280,11 @@ describe('WorkflowVersionStepOperationsWorkspaceService', () => {
settings: {
input: {
logicFunctionId: string;
logicFunctionVersion: string;
};
};
};
expect(codeResult.settings.input.logicFunctionId).toBe('new-function-id');
expect(codeResult.settings.input.logicFunctionVersion).toBe('draft');
});
it('should create form step', async () => {
@@ -320,7 +309,6 @@ describe('WorkflowVersionStepOperationsWorkspaceService', () => {
settings: {
input: {
logicFunctionId: 'function-id',
logicFunctionVersion: 'v1',
},
},
nextStepIds: ['next-step'],
@@ -330,8 +318,6 @@ describe('WorkflowVersionStepOperationsWorkspaceService', () => {
id: 'new-function-id',
name: 'Test Function',
description: 'Test Description',
latestVersion: 'v1',
publishedVersions: [],
workspaceId: mockWorkspaceId,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
@@ -370,13 +356,11 @@ describe('WorkflowVersionStepOperationsWorkspaceService', () => {
settings: {
input: {
logicFunctionId: string;
logicFunctionVersion: string;
};
};
};
expect(codeResult.settings.input.logicFunctionId).toBe('new-function-id');
expect(codeResult.settings.input.logicFunctionVersion).toBe('draft');
expect(duplicateStep.nextStepIds).toEqual([]);
});
@@ -40,7 +40,6 @@ describe('insertStep', () => {
settings: {
input: {
logicFunctionId: 'test',
logicFunctionVersion: '1.0.0',
logicFunctionInput: {},
},
outputSchema: {},
@@ -32,7 +32,6 @@ describe('removeStep', () => {
settings: {
input: {
logicFunctionId: 'test',
logicFunctionVersion: '1.0.0',
logicFunctionInput: {},
},
outputSchema: {},
@@ -86,18 +86,11 @@ export class WorkflowVersionStepOperationsWorkspaceService {
}) {
switch (step.type) {
case WorkflowActionType.CODE: {
if (
!(await this.logicFunctionService.hasLogicFunctionPublishedVersion(
step.settings.input.logicFunctionId,
workspaceId,
))
) {
await this.logicFunctionService.deleteOneLogicFunction({
id: step.settings.input.logicFunctionId,
workspaceId,
softDelete: false,
});
}
await this.logicFunctionService.deleteOneLogicFunction({
id: step.settings.input.logicFunctionId,
workspaceId,
softDelete: false,
});
break;
}
case WorkflowActionType.AI_AGENT: {
@@ -193,7 +186,6 @@ export class WorkflowVersionStepOperationsWorkspaceService {
},
input: {
logicFunctionId: newLogicFunction.id,
logicFunctionVersion: 'draft',
logicFunctionInput: SEED_PROJECT_INPUT_SCHEMA,
},
},
@@ -663,7 +655,6 @@ export class WorkflowVersionStepOperationsWorkspaceService {
const newLogicFunction =
await this.logicFunctionService.duplicateLogicFunction({
id: step.settings.input.logicFunctionId,
version: step.settings.input.logicFunctionVersion,
workspaceId,
});
@@ -677,7 +668,6 @@ export class WorkflowVersionStepOperationsWorkspaceService {
input: {
...step.settings.input,
logicFunctionId: newLogicFunction.id,
logicFunctionVersion: 'draft',
},
},
};
@@ -928,33 +918,10 @@ export class WorkflowVersionStepOperationsWorkspaceService {
async createDraftStep({
step,
workspaceId,
}: {
step: WorkflowAction;
workspaceId: string;
}): Promise<WorkflowAction> {
switch (step.type) {
case WorkflowActionType.CODE: {
await this.logicFunctionService.createDraftFromPublishedVersion({
id: step.settings.input.logicFunctionId,
version: step.settings.input.logicFunctionVersion,
workspaceId,
});
return {
...step,
settings: {
...step.settings,
input: {
...step.settings.input,
logicFunctionVersion: 'draft',
},
},
};
}
default: {
return step;
}
}
return step;
}
}
@@ -243,7 +243,6 @@ describe('shouldExecuteStep', () => {
settings: {
input: {
logicFunctionId: 'mock-function-id',
logicFunctionVersion: 'mock-function-version',
logicFunctionInput: {},
},
errorHandlingOptions: {
@@ -17,7 +17,6 @@ describe('shouldSkipStepExecution', () => {
settings: {
input: {
logicFunctionId: 'mock-function-id',
logicFunctionVersion: 'mock-function-version',
logicFunctionInput: {},
},
errorHandlingOptions: {
@@ -49,7 +49,6 @@ export class CodeWorkflowAction implements WorkflowAction {
id: workflowActionInput.logicFunctionId,
workspaceId,
payload: workflowActionInput.logicFunctionInput,
version: workflowActionInput.logicFunctionVersion,
});
if (result.error) {
@@ -1,6 +1,5 @@
export type WorkflowCodeActionInput = {
logicFunctionId: string;
logicFunctionVersion: string;
logicFunctionInput: {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any;
@@ -52,7 +52,6 @@ describe('shouldExecuteIteratorStep', () => {
settings: {
input: {
logicFunctionId: 'mock-function-id',
logicFunctionVersion: 'mock-function-version',
logicFunctionInput: {},
},
errorHandlingOptions: {
@@ -52,7 +52,6 @@ describe('shouldSkipIteratorStepExecution', () => {
settings: {
input: {
logicFunctionId: 'mock-function-id',
logicFunctionVersion: 'mock-function-version',
logicFunctionInput: {},
},
errorHandlingOptions: {
@@ -67,13 +67,10 @@ export class LogicFunctionWorkflowAction implements WorkflowAction {
);
}
const version = logicFunction.latestVersion ?? 'draft';
const result = await this.logicFunctionService.executeOneLogicFunction({
id: workflowActionInput.logicFunctionId,
workspaceId,
payload: workflowActionInput.logicFunctionInput,
version,
});
if (result.error) {
@@ -81,7 +81,7 @@ describe('WorkflowStatusesUpdate', () => {
provide: getRepositoryToken(LogicFunctionEntity),
useValue: {
findOneOrFail: jest.fn().mockResolvedValue({
latestVersion: 'v2',
id: 'mock-logic-function-id',
}),
},
},
@@ -229,7 +229,6 @@ describe('WorkflowStatusesUpdate', () => {
const mockLogicFunction = {
id: 'logic-function-1',
latestVersion: 'v2',
};
mockWorkflowRepository.findOneOrFail.mockResolvedValue(mockWorkflow);
@@ -262,7 +261,6 @@ describe('WorkflowStatusesUpdate', () => {
settings: {
input: {
logicFunctionId: 'logic-function-1',
logicFunctionVersion: 'v2',
},
},
},
@@ -11,10 +11,6 @@ import { LogicFunctionService } from 'src/engine/metadata-modules/logic-function
import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager';
import { type WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
import { buildSystemAuthContext } from 'src/engine/twenty-orm/utils/build-system-auth-context.util';
import {
WorkflowVersionStepException,
WorkflowVersionStepExceptionCode,
} from 'src/modules/workflow/common/exceptions/workflow-version-step.exception';
import {
WorkflowVersionStatus,
type WorkflowVersionWorkspaceEntity,
@@ -179,25 +175,10 @@ export class WorkflowStatusesUpdateJob {
const newStep = { ...step };
if (step.type === WorkflowActionType.CODE) {
const logicFunction =
await this.logicFunctionService.publishOneLogicFunctionOrFail(
step.settings.input.logicFunctionId,
workspaceId,
);
const newStepSettings = { ...step.settings };
if (!isDefined(logicFunction.latestVersion)) {
throw new WorkflowVersionStepException(
`Fail to publish logic function ${logicFunction.id}. Latest version is null`,
WorkflowVersionStepExceptionCode.CODE_STEP_FAILURE,
);
}
newStepSettings.input.logicFunctionVersion =
logicFunction.latestVersion;
newStep.settings = newStepSettings;
await this.logicFunctionService.publishOneLogicFunctionOrFail(
step.settings.input.logicFunctionId,
workspaceId,
);
}
newSteps.push(newStep);