Fix variable usage in Search Record workflow action (#16147)

Closes https://github.com/twentyhq/twenty/issues/16141

---------

Co-authored-by: prastoin <paul@twenty.com>
This commit is contained in:
Baptiste Devessier
2025-11-27 18:56:56 +01:00
committed by GitHub
parent 2f25922f4c
commit eaac569812
4 changed files with 57 additions and 18 deletions
@@ -68,7 +68,6 @@ type FindRecordsFormData = {
export type FindRecordsActionFilter = {
recordFilterGroups?: RecordFilterGroup[];
recordFilters?: RecordFilter[];
gqlOperationFilter?: JsonValue;
};
export type FindRecordsActionOrderBy = {
@@ -10,7 +10,6 @@ import { type FindRecordsActionFilter } from '@/workflow/workflow-steps/workflow
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
import { useRecoilCallback } from 'recoil';
import { computeRecordGqlOperationFilter } from 'twenty-shared/utils';
export const WorkflowFindRecordsFilters = ({
objectMetadataItem,
@@ -41,25 +40,16 @@ export const WorkflowFindRecordsFilters = ({
currentRecordFiltersCallbackState,
);
const gqlOperationFilter = computeRecordGqlOperationFilter({
fields: objectMetadataItem.fields,
filterValueDependencies: {},
recordFilters: currentRecordFilters,
recordFilterGroups: currentRecordFilterGroups,
});
const newFilter = {
recordFilterGroups: currentRecordFilterGroups,
recordFilters: currentRecordFilters,
gqlOperationFilter,
} as FindRecordsActionFilter;
} satisfies FindRecordsActionFilter;
onChange(newFilter);
},
[
currentRecordFilterGroupsCallbackState,
currentRecordFiltersCallbackState,
objectMetadataItem.fields,
onChange,
],
);
@@ -1,6 +1,14 @@
import { Injectable } from '@nestjs/common';
import { resolveInput } from 'twenty-shared/utils';
import {
FieldMetadataComplexOption,
FieldMetadataDefaultOption,
} from 'twenty-shared/types';
import {
computeRecordGqlOperationFilter,
isDefined,
resolveInput,
} from 'twenty-shared/utils';
import { type WorkflowAction } from 'src/modules/workflow/workflow-executor/interfaces/workflow-action.interface';
@@ -10,6 +18,7 @@ import {
} from 'src/engine/core-modules/record-crud/exceptions/record-crud.exception';
import { FindRecordsService } from 'src/engine/core-modules/record-crud/services/find-records.service';
import { ScopedWorkspaceContextFactory } from 'src/engine/twenty-orm/factories/scoped-workspace-context.factory';
import { WorkflowCommonWorkspaceService } from 'src/modules/workflow/common/workspace-services/workflow-common.workspace-service';
import {
WorkflowStepExecutorException,
WorkflowStepExecutorExceptionCode,
@@ -27,6 +36,7 @@ export class FindRecordsWorkflowAction implements WorkflowAction {
private readonly findRecordsService: FindRecordsService,
private readonly scopedWorkspaceContextFactory: ScopedWorkspaceContextFactory,
private readonly workflowExecutionContextService: WorkflowExecutionContextService,
private readonly workflowCommonWorkspaceService: WorkflowCommonWorkspaceService,
) {}
async execute({
@@ -64,9 +74,49 @@ export class FindRecordsWorkflowAction implements WorkflowAction {
const executionContext =
await this.workflowExecutionContextService.getExecutionContext(runInfo);
const { flatObjectMetadata, flatFieldMetadataMaps } =
await this.workflowCommonWorkspaceService.getObjectMetadataInfo(
workflowActionInput.objectName,
workspaceId,
);
const fields = flatObjectMetadata.fieldMetadataIds
.map((fieldId) => {
const field = flatFieldMetadataMaps.byId[fieldId];
if (!field) {
return null;
}
return {
id: field.id,
name: field.name,
type: field.type,
label: field.label,
// Note: force cast is required until we deprecate the CreateFieldInput and UpdateFieldInput
// type derivation from the FieldMetadataDto
options: field.options as
| (FieldMetadataDefaultOption & { id: string })[]
| (FieldMetadataComplexOption & { id: string })[]
| null,
};
})
.filter(isDefined);
const gqlOperationFilter =
workflowActionInput.filter?.recordFilters &&
workflowActionInput.filter?.recordFilterGroups
? computeRecordGqlOperationFilter({
fields,
recordFilters: workflowActionInput.filter.recordFilters,
recordFilterGroups: workflowActionInput.filter.recordFilterGroups,
filterValueDependencies: {},
})
: {};
const toolOutput = await this.findRecordsService.execute({
objectName: workflowActionInput.objectName,
filter: workflowActionInput.filter?.gqlOperationFilter,
filter: gqlOperationFilter,
orderBy: workflowActionInput.orderBy?.gqlOperationOrderBy,
limit: workflowActionInput.limit,
workspaceId,
@@ -15,13 +15,13 @@ export type TagColor =
export class FieldMetadataDefaultOption {
id?: string;
position!: number;
label!: string;
value!: string;
position: number;
label: string;
value: string;
}
export class FieldMetadataComplexOption extends FieldMetadataDefaultOption {
color!: TagColor;
color: TagColor;
}
type FieldMetadataOptionsMapping = {