From 0234c8d7079677b59c26679a8f796054ae01587f Mon Sep 17 00:00:00 2001 From: Weiko Date: Tue, 18 Feb 2025 14:43:42 +0100 Subject: [PATCH] Fix featureFlag N+1 queries (#10261) ## Context Regression was introduced 3 weeks ago when we added relations v2. Because the relation logic is recursive during the life of a request, we were querying the featureFlags many times. We are now always using the featureFlag map and it's now available in the base resolver so we don't need to query it everywhere, preferably passing it as a parameter instead. Note: We should introduce a cache for featureFlags in the future, this is something easy to control and invalidate when needed. --- .../process-nested-relations.helper.ts | 20 +++++++++++------- .../interfaces/base-resolver-service.ts | 21 +++++++++---------- ...phql-query-create-many-resolver.service.ts | 9 ++++---- ...aphql-query-create-one-resolver.service.ts | 9 ++++---- ...phql-query-delete-many-resolver.service.ts | 9 ++++---- ...aphql-query-delete-one-resolver.service.ts | 9 ++++---- ...hql-query-destroy-many-resolver.service.ts | 9 ++++---- ...phql-query-destroy-one-resolver.service.ts | 9 ++++---- ...-query-find-duplicates-resolver.service.ts | 9 +++----- ...raphql-query-find-many-resolver.service.ts | 9 ++++---- ...graphql-query-find-one-resolver.service.ts | 9 ++++---- ...hql-query-restore-many-resolver.service.ts | 9 ++++---- ...phql-query-restore-one-resolver.service.ts | 9 ++++---- .../graphql-query-search-resolver.service.ts | 11 +++++----- ...phql-query-update-many-resolver.service.ts | 9 ++++---- ...aphql-query-update-one-resolver.service.ts | 9 ++++---- 16 files changed, 78 insertions(+), 91 deletions(-) diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/helpers/process-nested-relations.helper.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/helpers/process-nested-relations.helper.ts index 26ee3bc2322..52e3d7ac8e1 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/helpers/process-nested-relations.helper.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/helpers/process-nested-relations.helper.ts @@ -21,8 +21,6 @@ import { } from 'src/engine/api/graphql/graphql-query-runner/utils/get-relation-object-metadata.util'; import { AggregationField } from 'src/engine/api/graphql/workspace-schema-builder/utils/get-available-aggregations-from-object-fields.util'; import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type'; -import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; -import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service'; import { ObjectMetadataItemWithFieldMaps } from 'src/engine/metadata-modules/types/object-metadata-item-with-field-maps'; import { ObjectMetadataMaps } from 'src/engine/metadata-modules/types/object-metadata-maps'; import { getObjectMetadataMapItemByNameSingular } from 'src/engine/metadata-modules/utils/get-object-metadata-map-item-by-name-singular.util'; @@ -34,7 +32,6 @@ export class ProcessNestedRelationsHelper { constructor( private readonly processNestedRelationsV2Helper: ProcessNestedRelationsV2Helper, private readonly processAggregateHelper: ProcessAggregateHelper, - private readonly featureFlagService: FeatureFlagService, ) {} public async processNestedRelations({ @@ -47,6 +44,7 @@ export class ProcessNestedRelationsHelper { limit, authContext, dataSource, + isNewRelationEnabled, }: { objectMetadataMaps: ObjectMetadataMaps; parentObjectMetadataItem: ObjectMetadataItemWithFieldMaps; @@ -57,12 +55,8 @@ export class ProcessNestedRelationsHelper { limit: number; authContext: AuthContext; dataSource: DataSource; + isNewRelationEnabled: boolean; }): Promise { - const isNewRelationEnabled = await this.featureFlagService.isFeatureEnabled( - FeatureFlagKey.IsNewRelationEnabled, - authContext.workspace.id, - ); - if (isNewRelationEnabled) { return this.processNestedRelationsV2Helper.processNestedRelations({ objectMetadataMaps, @@ -90,6 +84,7 @@ export class ProcessNestedRelationsHelper { limit, authContext, dataSource, + isNewRelationEnabled, }), ); @@ -107,6 +102,7 @@ export class ProcessNestedRelationsHelper { limit, authContext, dataSource, + isNewRelationEnabled, }: { objectMetadataMaps: ObjectMetadataMaps; parentObjectMetadataItem: ObjectMetadataItemWithFieldMaps; @@ -118,6 +114,7 @@ export class ProcessNestedRelationsHelper { limit: number; authContext: any; dataSource: DataSource; + isNewRelationEnabled: boolean; }): Promise { const relationFieldMetadata = parentObjectMetadataItem.fieldsByName[relationName]; @@ -143,6 +140,7 @@ export class ProcessNestedRelationsHelper { limit, authContext, dataSource, + isNewRelationEnabled, }); } @@ -157,6 +155,7 @@ export class ProcessNestedRelationsHelper { limit, authContext, dataSource, + isNewRelationEnabled, }: { objectMetadataMaps: ObjectMetadataMaps; parentObjectMetadataItem: ObjectMetadataItemWithFieldMaps; @@ -168,6 +167,7 @@ export class ProcessNestedRelationsHelper { limit: number; authContext: any; dataSource: DataSource; + isNewRelationEnabled: boolean; }): Promise { const { inverseRelationName, referenceObjectMetadata } = this.getRelationMetadata({ @@ -235,6 +235,7 @@ export class ProcessNestedRelationsHelper { limit, authContext, dataSource, + isNewRelationEnabled, }); } } @@ -250,6 +251,7 @@ export class ProcessNestedRelationsHelper { limit, authContext, dataSource, + isNewRelationEnabled, }: { objectMetadataMaps: ObjectMetadataMaps; parentObjectMetadataItem: ObjectMetadataItemWithFieldMaps; @@ -261,6 +263,7 @@ export class ProcessNestedRelationsHelper { limit: number; authContext: any; dataSource: DataSource; + isNewRelationEnabled: boolean; }): Promise { const { referenceObjectMetadata } = this.getRelationMetadata({ objectMetadataMaps, @@ -326,6 +329,7 @@ export class ProcessNestedRelationsHelper { limit, authContext, dataSource, + isNewRelationEnabled, }); } } diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/interfaces/base-resolver-service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/interfaces/base-resolver-service.ts index 0fc0f519043..37f7d340c60 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/interfaces/base-resolver-service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/interfaces/base-resolver-service.ts @@ -83,13 +83,13 @@ export abstract class GraphqlQueryBaseResolverService< await this.validate(args, options); - const permissionsEnabled = await this.featureFlagService.isFeatureEnabled( - FeatureFlagKey.IsPermissionsEnabled, - authContext.workspace.id, - ); + const featureFlagsMap = + await this.featureFlagService.getWorkspaceFeatureFlagsMap( + authContext.workspace.id, + ); if ( - permissionsEnabled === true && + featureFlagsMap[FeatureFlagKey.IsPermissionsEnabled] && objectMetadataItemWithFieldMaps.isSystem === true ) { await this.validateSystemObjectPermissions(options); @@ -118,11 +118,6 @@ export abstract class GraphqlQueryBaseResolverService< objectMetadataItemWithFieldMaps.nameSingular, ); - const featureFlagsMap = - await this.featureFlagService.getWorkspaceFeatureFlagsMap( - authContext.workspace.id, - ); - const graphqlQueryParser = new GraphqlQueryParser( objectMetadataItemWithFieldMaps.fieldsByName, options.objectMetadataMaps, @@ -146,7 +141,10 @@ export abstract class GraphqlQueryBaseResolverService< graphqlQuerySelectedFieldsResult, }; - const results = await this.resolve(graphqlQueryResolverExecutionArgs); + const results = await this.resolve( + graphqlQueryResolverExecutionArgs, + featureFlagsMap, + ); const resultWithGetters = await this.queryResultGettersFactory.create( results, @@ -214,6 +212,7 @@ export abstract class GraphqlQueryBaseResolverService< protected abstract resolve( executionArgs: GraphqlQueryResolverExecutionArgs, + featureFlagsMap: Record, ): Promise; protected abstract validate( diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-create-many-resolver.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-create-many-resolver.service.ts index 297b014d1b9..07a110016a6 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-create-many-resolver.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-create-many-resolver.service.ts @@ -13,6 +13,7 @@ import { CreateManyResolverArgs } from 'src/engine/api/graphql/workspace-resolve import { QUERY_MAX_RECORDS } from 'src/engine/api/graphql/graphql-query-runner/constants/query-max-records.constant'; import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper'; import { assertIsValidUuid } from 'src/engine/api/graphql/workspace-query-runner/utils/assert-is-valid-uuid.util'; +import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; import { assertMutationNotOnRemoteObject } from 'src/engine/metadata-modules/object-metadata/utils/assert-mutation-not-on-remote-object.util'; import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; @@ -23,6 +24,7 @@ export class GraphqlQueryCreateManyResolverService extends GraphqlQueryBaseResol > { async resolve( executionArgs: GraphqlQueryResolverExecutionArgs, + featureFlagsMap: Record, ): Promise { const { authContext, objectMetadataItemWithFieldMaps, objectMetadataMaps } = executionArgs.options; @@ -66,14 +68,11 @@ export class GraphqlQueryCreateManyResolverService extends GraphqlQueryBaseResol limit: QUERY_MAX_RECORDS, authContext, dataSource: executionArgs.dataSource, + isNewRelationEnabled: + featureFlagsMap[FeatureFlagKey.IsNewRelationEnabled], }); } - const featureFlagsMap = - await this.featureFlagService.getWorkspaceFeatureFlagsMap( - authContext.workspace.id, - ); - const typeORMObjectRecordsParser = new ObjectRecordsToGraphqlConnectionHelper( objectMetadataMaps, diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-create-one-resolver.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-create-one-resolver.service.ts index f7d15a46e9c..9ae8e3ae086 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-create-one-resolver.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-create-one-resolver.service.ts @@ -13,6 +13,7 @@ import { CreateOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver import { QUERY_MAX_RECORDS } from 'src/engine/api/graphql/graphql-query-runner/constants/query-max-records.constant'; import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper'; import { assertIsValidUuid } from 'src/engine/api/graphql/workspace-query-runner/utils/assert-is-valid-uuid.util'; +import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; import { assertMutationNotOnRemoteObject } from 'src/engine/metadata-modules/object-metadata/utils/assert-mutation-not-on-remote-object.util'; import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; @@ -23,6 +24,7 @@ export class GraphqlQueryCreateOneResolverService extends GraphqlQueryBaseResolv > { async resolve( executionArgs: GraphqlQueryResolverExecutionArgs, + featureFlagsMap: Record, ): Promise { const { authContext, objectMetadataMaps, objectMetadataItemWithFieldMaps } = executionArgs.options; @@ -66,14 +68,11 @@ export class GraphqlQueryCreateOneResolverService extends GraphqlQueryBaseResolv limit: QUERY_MAX_RECORDS, authContext, dataSource: executionArgs.dataSource, + isNewRelationEnabled: + featureFlagsMap[FeatureFlagKey.IsNewRelationEnabled], }); } - const featureFlagsMap = - await this.featureFlagService.getWorkspaceFeatureFlagsMap( - authContext.workspace.id, - ); - const typeORMObjectRecordsParser = new ObjectRecordsToGraphqlConnectionHelper( objectMetadataMaps, diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-delete-many-resolver.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-delete-many-resolver.service.ts index 6331035756a..89878fd5ad2 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-delete-many-resolver.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-delete-many-resolver.service.ts @@ -11,6 +11,7 @@ import { DeleteManyResolverArgs } from 'src/engine/api/graphql/workspace-resolve import { QUERY_MAX_RECORDS } from 'src/engine/api/graphql/graphql-query-runner/constants/query-max-records.constant'; import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper'; import { assertIsValidUuid } from 'src/engine/api/graphql/workspace-query-runner/utils/assert-is-valid-uuid.util'; +import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; import { assertMutationNotOnRemoteObject } from 'src/engine/metadata-modules/object-metadata/utils/assert-mutation-not-on-remote-object.util'; import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; import { computeTableName } from 'src/engine/utils/compute-table-name.util'; @@ -22,6 +23,7 @@ export class GraphqlQueryDeleteManyResolverService extends GraphqlQueryBaseResol > { async resolve( executionArgs: GraphqlQueryResolverExecutionArgs, + featureFlagsMap: Record, ): Promise { const { authContext, objectMetadataItemWithFieldMaps, objectMetadataMaps } = executionArgs.options; @@ -67,14 +69,11 @@ export class GraphqlQueryDeleteManyResolverService extends GraphqlQueryBaseResol limit: QUERY_MAX_RECORDS, authContext, dataSource: executionArgs.dataSource, + isNewRelationEnabled: + featureFlagsMap[FeatureFlagKey.IsNewRelationEnabled], }); } - const featureFlagsMap = - await this.featureFlagService.getWorkspaceFeatureFlagsMap( - authContext.workspace.id, - ); - const typeORMObjectRecordsParser = new ObjectRecordsToGraphqlConnectionHelper( objectMetadataMaps, diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-delete-one-resolver.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-delete-one-resolver.service.ts index 581c0143e71..e8ade85afdc 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-delete-one-resolver.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-delete-one-resolver.service.ts @@ -15,6 +15,7 @@ import { } from 'src/engine/api/graphql/graphql-query-runner/errors/graphql-query-runner.exception'; import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper'; import { assertIsValidUuid } from 'src/engine/api/graphql/workspace-query-runner/utils/assert-is-valid-uuid.util'; +import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; import { assertMutationNotOnRemoteObject } from 'src/engine/metadata-modules/object-metadata/utils/assert-mutation-not-on-remote-object.util'; import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; @@ -25,6 +26,7 @@ export class GraphqlQueryDeleteOneResolverService extends GraphqlQueryBaseResolv > { async resolve( executionArgs: GraphqlQueryResolverExecutionArgs, + featureFlagsMap: Record, ): Promise { const { authContext, objectMetadataItemWithFieldMaps, objectMetadataMaps } = executionArgs.options; @@ -69,14 +71,11 @@ export class GraphqlQueryDeleteOneResolverService extends GraphqlQueryBaseResolv limit: QUERY_MAX_RECORDS, authContext, dataSource: executionArgs.dataSource, + isNewRelationEnabled: + featureFlagsMap[FeatureFlagKey.IsNewRelationEnabled], }); } - const featureFlagsMap = - await this.featureFlagService.getWorkspaceFeatureFlagsMap( - authContext.workspace.id, - ); - const typeORMObjectRecordsParser = new ObjectRecordsToGraphqlConnectionHelper( objectMetadataMaps, diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-destroy-many-resolver.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-destroy-many-resolver.service.ts index d618cc30c5b..4cf46a6da36 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-destroy-many-resolver.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-destroy-many-resolver.service.ts @@ -10,6 +10,7 @@ import { DestroyManyResolverArgs } from 'src/engine/api/graphql/workspace-resolv import { QUERY_MAX_RECORDS } from 'src/engine/api/graphql/graphql-query-runner/constants/query-max-records.constant'; import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper'; +import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; import { computeTableName } from 'src/engine/utils/compute-table-name.util'; @@ -20,6 +21,7 @@ export class GraphqlQueryDestroyManyResolverService extends GraphqlQueryBaseReso > { async resolve( executionArgs: GraphqlQueryResolverExecutionArgs, + featureFlagsMap: Record, ): Promise { const { authContext, objectMetadataItemWithFieldMaps, objectMetadataMaps } = executionArgs.options; @@ -65,14 +67,11 @@ export class GraphqlQueryDestroyManyResolverService extends GraphqlQueryBaseReso limit: QUERY_MAX_RECORDS, authContext, dataSource: executionArgs.dataSource, + isNewRelationEnabled: + featureFlagsMap[FeatureFlagKey.IsNewRelationEnabled], }); } - const featureFlagsMap = - await this.featureFlagService.getWorkspaceFeatureFlagsMap( - authContext.workspace.id, - ); - const typeORMObjectRecordsParser = new ObjectRecordsToGraphqlConnectionHelper( objectMetadataMaps, diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-destroy-one-resolver.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-destroy-one-resolver.service.ts index 6071e3853dc..7c58da6e2e1 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-destroy-one-resolver.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-destroy-one-resolver.service.ts @@ -14,6 +14,7 @@ import { GraphqlQueryRunnerExceptionCode, } from 'src/engine/api/graphql/graphql-query-runner/errors/graphql-query-runner.exception'; import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper'; +import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; @Injectable() @@ -23,6 +24,7 @@ export class GraphqlQueryDestroyOneResolverService extends GraphqlQueryBaseResol > { async resolve( executionArgs: GraphqlQueryResolverExecutionArgs, + featureFlagsMap: Record, ): Promise { const { authContext, objectMetadataItemWithFieldMaps, objectMetadataMaps } = executionArgs.options; @@ -65,14 +67,11 @@ export class GraphqlQueryDestroyOneResolverService extends GraphqlQueryBaseResol limit: QUERY_MAX_RECORDS, authContext, dataSource: executionArgs.dataSource, + isNewRelationEnabled: + featureFlagsMap[FeatureFlagKey.IsNewRelationEnabled], }); } - const featureFlagsMap = - await this.featureFlagService.getWorkspaceFeatureFlagsMap( - authContext.workspace.id, - ); - const typeORMObjectRecordsParser = new ObjectRecordsToGraphqlConnectionHelper( objectMetadataMaps, diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-duplicates-resolver.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-duplicates-resolver.service.ts index 61aab2d8980..d3189dacf47 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-duplicates-resolver.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-duplicates-resolver.service.ts @@ -23,6 +23,7 @@ import { import { GraphqlQueryParser } from 'src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query.parser'; import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper'; import { settings } from 'src/engine/constants/settings'; +import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; import { ObjectMetadataItemWithFieldMaps } from 'src/engine/metadata-modules/types/object-metadata-item-with-field-maps'; import { getObjectMetadataMapItemByNameSingular } from 'src/engine/metadata-modules/utils/get-object-metadata-map-item-by-name-singular.util'; import { formatData } from 'src/engine/twenty-orm/utils/format-data.util'; @@ -38,8 +39,9 @@ export class GraphqlQueryFindDuplicatesResolverService extends GraphqlQueryBaseR > { async resolve( executionArgs: GraphqlQueryResolverExecutionArgs, + featureFlagsMap: Record, ): Promise[]> { - const { objectMetadataItemWithFieldMaps, objectMetadataMaps, authContext } = + const { objectMetadataItemWithFieldMaps, objectMetadataMaps } = executionArgs.options; const existingRecordsQueryBuilder = @@ -60,11 +62,6 @@ export class GraphqlQueryFindDuplicatesResolverService extends GraphqlQueryBaseR ); } - const featureFlagsMap = - await this.featureFlagService.getWorkspaceFeatureFlagsMap( - authContext.workspace.id, - ); - const graphqlQueryParser = new GraphqlQueryParser( objectMetadataItemWithFieldsMaps?.fieldsByName, objectMetadataMaps, diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-many-resolver.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-many-resolver.service.ts index c379e61a015..e9d8064aed7 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-many-resolver.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-many-resolver.service.ts @@ -28,6 +28,7 @@ import { getCursor, getPaginationInfo, } from 'src/engine/api/graphql/graphql-query-runner/utils/cursors.util'; +import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; @Injectable() @@ -41,6 +42,7 @@ export class GraphqlQueryFindManyResolverService extends GraphqlQueryBaseResolve async resolve( executionArgs: GraphqlQueryResolverExecutionArgs, + featureFlagsMap: Record, ): Promise> { const { authContext, objectMetadataItemWithFieldMaps, objectMetadataMaps } = executionArgs.options; @@ -152,14 +154,11 @@ export class GraphqlQueryFindManyResolverService extends GraphqlQueryBaseResolve limit, authContext, dataSource: executionArgs.dataSource, + isNewRelationEnabled: + featureFlagsMap[FeatureFlagKey.IsNewRelationEnabled], }); } - const featureFlagsMap = - await this.featureFlagService.getWorkspaceFeatureFlagsMap( - authContext.workspace.id, - ); - const typeORMObjectRecordsParser = new ObjectRecordsToGraphqlConnectionHelper( objectMetadataMaps, diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-one-resolver.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-one-resolver.service.ts index d68ba1d80f1..cc44c3e5458 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-one-resolver.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-one-resolver.service.ts @@ -21,6 +21,7 @@ import { WorkspaceQueryRunnerException, WorkspaceQueryRunnerExceptionCode, } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.exception'; +import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; @Injectable() @@ -30,6 +31,7 @@ export class GraphqlQueryFindOneResolverService extends GraphqlQueryBaseResolver > { async resolve( executionArgs: GraphqlQueryResolverExecutionArgs, + featureFlagsMap: Record, ): Promise { const { authContext, objectMetadataItemWithFieldMaps, objectMetadataMaps } = executionArgs.options; @@ -75,14 +77,11 @@ export class GraphqlQueryFindOneResolverService extends GraphqlQueryBaseResolver limit: QUERY_MAX_RECORDS, authContext, dataSource: executionArgs.dataSource, + isNewRelationEnabled: + featureFlagsMap[FeatureFlagKey.IsNewRelationEnabled], }); } - const featureFlagsMap = - await this.featureFlagService.getWorkspaceFeatureFlagsMap( - authContext.workspace.id, - ); - const typeORMObjectRecordsParser = new ObjectRecordsToGraphqlConnectionHelper( objectMetadataMaps, diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-restore-many-resolver.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-restore-many-resolver.service.ts index 154a6f9857a..2ba9ec21155 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-restore-many-resolver.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-restore-many-resolver.service.ts @@ -11,6 +11,7 @@ import { RestoreManyResolverArgs } from 'src/engine/api/graphql/workspace-resolv import { QUERY_MAX_RECORDS } from 'src/engine/api/graphql/graphql-query-runner/constants/query-max-records.constant'; import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper'; import { assertIsValidUuid } from 'src/engine/api/graphql/workspace-query-runner/utils/assert-is-valid-uuid.util'; +import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; import { assertMutationNotOnRemoteObject } from 'src/engine/metadata-modules/object-metadata/utils/assert-mutation-not-on-remote-object.util'; import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; import { computeTableName } from 'src/engine/utils/compute-table-name.util'; @@ -22,6 +23,7 @@ export class GraphqlQueryRestoreManyResolverService extends GraphqlQueryBaseReso > { async resolve( executionArgs: GraphqlQueryResolverExecutionArgs, + featureFlagsMap: Record, ): Promise { const { authContext, objectMetadataItemWithFieldMaps, objectMetadataMaps } = executionArgs.options; @@ -67,14 +69,11 @@ export class GraphqlQueryRestoreManyResolverService extends GraphqlQueryBaseReso limit: QUERY_MAX_RECORDS, authContext, dataSource: executionArgs.dataSource, + isNewRelationEnabled: + featureFlagsMap[FeatureFlagKey.IsNewRelationEnabled], }); } - const featureFlagsMap = - await this.featureFlagService.getWorkspaceFeatureFlagsMap( - authContext.workspace.id, - ); - const typeORMObjectRecordsParser = new ObjectRecordsToGraphqlConnectionHelper( objectMetadataMaps, diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-restore-one-resolver.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-restore-one-resolver.service.ts index fb6c3462565..9bc1df3f10d 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-restore-one-resolver.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-restore-one-resolver.service.ts @@ -15,6 +15,7 @@ import { } from 'src/engine/api/graphql/graphql-query-runner/errors/graphql-query-runner.exception'; import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper'; import { assertIsValidUuid } from 'src/engine/api/graphql/workspace-query-runner/utils/assert-is-valid-uuid.util'; +import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; import { assertMutationNotOnRemoteObject } from 'src/engine/metadata-modules/object-metadata/utils/assert-mutation-not-on-remote-object.util'; import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; @@ -25,6 +26,7 @@ export class GraphqlQueryRestoreOneResolverService extends GraphqlQueryBaseResol > { async resolve( executionArgs: GraphqlQueryResolverExecutionArgs, + featureFlagsMap: Record, ): Promise { const { authContext, objectMetadataItemWithFieldMaps, objectMetadataMaps } = executionArgs.options; @@ -69,14 +71,11 @@ export class GraphqlQueryRestoreOneResolverService extends GraphqlQueryBaseResol limit: QUERY_MAX_RECORDS, authContext, dataSource: executionArgs.dataSource, + isNewRelationEnabled: + featureFlagsMap[FeatureFlagKey.IsNewRelationEnabled], }); } - const featureFlagsMap = - await this.featureFlagService.getWorkspaceFeatureFlagsMap( - authContext.workspace.id, - ); - const typeORMObjectRecordsParser = new ObjectRecordsToGraphqlConnectionHelper( objectMetadataMaps, diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-search-resolver.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-search-resolver.service.ts index 1ab52158c75..89c20426ff8 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-search-resolver.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-search-resolver.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@nestjs/common'; -import { Brackets } from 'typeorm'; import { isDefined } from 'twenty-shared'; +import { Brackets } from 'typeorm'; import { GraphqlQueryBaseResolverService, @@ -18,6 +18,7 @@ import { SearchResolverArgs } from 'src/engine/api/graphql/workspace-resolver-bu import { QUERY_MAX_RECORDS } from 'src/engine/api/graphql/graphql-query-runner/constants/query-max-records.constant'; import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper'; +import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; import { SEARCH_VECTOR_FIELD } from 'src/engine/metadata-modules/constants/search-vector-field.constants'; import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; @@ -28,15 +29,11 @@ export class GraphqlQuerySearchResolverService extends GraphqlQueryBaseResolverS > { async resolve( executionArgs: GraphqlQueryResolverExecutionArgs, + featureFlagsMap: Record, ): Promise> { const { authContext, objectMetadataMaps, objectMetadataItemWithFieldMaps } = executionArgs.options; - const featureFlagsMap = - await this.featureFlagService.getWorkspaceFeatureFlagsMap( - authContext.workspace.id, - ); - const typeORMObjectRecordsParser = new ObjectRecordsToGraphqlConnectionHelper( objectMetadataMaps, @@ -137,6 +134,8 @@ export class GraphqlQuerySearchResolverService extends GraphqlQueryBaseResolverS limit, authContext, dataSource: executionArgs.dataSource, + isNewRelationEnabled: + featureFlagsMap[FeatureFlagKey.IsNewRelationEnabled], }); } diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-update-many-resolver.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-update-many-resolver.service.ts index 0b0b368054b..6d6c0314807 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-update-many-resolver.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-update-many-resolver.service.ts @@ -11,6 +11,7 @@ import { UpdateManyResolverArgs } from 'src/engine/api/graphql/workspace-resolve import { QUERY_MAX_RECORDS } from 'src/engine/api/graphql/graphql-query-runner/constants/query-max-records.constant'; import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper'; import { assertIsValidUuid } from 'src/engine/api/graphql/workspace-query-runner/utils/assert-is-valid-uuid.util'; +import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; import { assertMutationNotOnRemoteObject } from 'src/engine/metadata-modules/object-metadata/utils/assert-mutation-not-on-remote-object.util'; import { formatData } from 'src/engine/twenty-orm/utils/format-data.util'; import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; @@ -23,6 +24,7 @@ export class GraphqlQueryUpdateManyResolverService extends GraphqlQueryBaseResol > { async resolve( executionArgs: GraphqlQueryResolverExecutionArgs, + featureFlagsMap: Record, ): Promise { const { authContext, objectMetadataItemWithFieldMaps, objectMetadataMaps } = executionArgs.options; @@ -91,14 +93,11 @@ export class GraphqlQueryUpdateManyResolverService extends GraphqlQueryBaseResol limit: QUERY_MAX_RECORDS, authContext, dataSource: executionArgs.dataSource, + isNewRelationEnabled: + featureFlagsMap[FeatureFlagKey.IsNewRelationEnabled], }); } - const featureFlagsMap = - await this.featureFlagService.getWorkspaceFeatureFlagsMap( - authContext.workspace.id, - ); - const typeORMObjectRecordsParser = new ObjectRecordsToGraphqlConnectionHelper( objectMetadataMaps, diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-update-one-resolver.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-update-one-resolver.service.ts index 79255d8e11d..62361d7196d 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-update-one-resolver.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-update-one-resolver.service.ts @@ -15,6 +15,7 @@ import { } from 'src/engine/api/graphql/graphql-query-runner/errors/graphql-query-runner.exception'; import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper'; import { assertIsValidUuid } from 'src/engine/api/graphql/workspace-query-runner/utils/assert-is-valid-uuid.util'; +import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; import { assertMutationNotOnRemoteObject } from 'src/engine/metadata-modules/object-metadata/utils/assert-mutation-not-on-remote-object.util'; import { formatData } from 'src/engine/twenty-orm/utils/format-data.util'; import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; @@ -26,6 +27,7 @@ export class GraphqlQueryUpdateOneResolverService extends GraphqlQueryBaseResolv > { async resolve( executionArgs: GraphqlQueryResolverExecutionArgs, + featureFlagsMap: Record, ): Promise { const { authContext, objectMetadataItemWithFieldMaps, objectMetadataMaps } = executionArgs.options; @@ -89,14 +91,11 @@ export class GraphqlQueryUpdateOneResolverService extends GraphqlQueryBaseResolv limit: QUERY_MAX_RECORDS, authContext, dataSource: executionArgs.dataSource, + isNewRelationEnabled: + featureFlagsMap[FeatureFlagKey.IsNewRelationEnabled], }); } - const featureFlagsMap = - await this.featureFlagService.getWorkspaceFeatureFlagsMap( - authContext.workspace.id, - ); - const typeORMObjectRecordsParser = new ObjectRecordsToGraphqlConnectionHelper( objectMetadataMaps,