diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver.factory.ts index 15722ca67c..7b4fc435b9 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver.factory.ts @@ -17,6 +17,7 @@ import { AuthExceptionCode, } from 'src/engine/core-modules/auth/auth.exception'; import { type 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 { ObjectMetadataMaps } from 'src/engine/metadata-modules/types/object-metadata-maps'; import { getResolverName } from 'src/engine/utils/get-resolver-name.util'; @@ -115,8 +116,15 @@ export class WorkspaceResolverFactory { continue; } + const isGroupByEnabled = + workspaceFeatureFlagsMap[FeatureFlagKey.IS_GROUP_BY_ENABLED]; + // Generate query resolvers for (const methodName of workspaceResolverBuilderMethods.queries) { + if (methodName === 'groupBy' && !isGroupByEnabled) { + continue; + } + const resolverName = getResolverName(objectMetadata, methodName); const resolverFactory = factories.get(methodName); diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/gql-type.generator.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/gql-type.generator.ts index 71934c8f43..bf95730f08 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/gql-type.generator.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/gql-type.generator.ts @@ -40,12 +40,18 @@ export class GqlTypeGenerator { private readonly mutationTypeGenerator: MutationTypeGenerator, ) {} - buildAndStore(objectMetadataCollection: ObjectMetadataEntity[]) { + async buildAndStore( + objectMetadataCollection: ObjectMetadataEntity[], + workspaceId: string, + ) { const compositeTypeCollection = [...compositeTypeDefinitions.values()]; this.buildAndStoreCompositeFieldMetadataGqlTypes(compositeTypeCollection); this.buildAndStoreObjectMetadataGqlTypes(objectMetadataCollection); - this.queryTypeGenerator.buildAndStore(objectMetadataCollection); + await this.queryTypeGenerator.buildAndStore( + objectMetadataCollection, + workspaceId, + ); this.mutationTypeGenerator.buildAndStore(objectMetadataCollection); } diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/root-types/query-type.generator.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/root-types/query-type.generator.ts index cf1e228719..4ed380949b 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/root-types/query-type.generator.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/root-types/query-type.generator.ts @@ -6,6 +6,8 @@ import { workspaceResolverBuilderMethodNames } from 'src/engine/api/graphql/work import { GqlOperation } from 'src/engine/api/graphql/workspace-schema-builder/enums/gql-operation.enum'; import { RootTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/root-types/root-type.generator'; import { GqlTypesStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/gql-types.storage'; +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 { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; @Injectable() @@ -13,12 +15,23 @@ export class QueryTypeGenerator { constructor( private readonly rootTypeGenerator: RootTypeGenerator, private readonly gqlTypesStorage: GqlTypesStorage, + private readonly featureFlagService: FeatureFlagService, ) {} - buildAndStore(objectMetadataCollection: ObjectMetadataEntity[]) { + async buildAndStore( + objectMetadataCollection: ObjectMetadataEntity[], + workspaceId: string, + ) { + const isGroupByEnabled = await this.featureFlagService.isFeatureEnabled( + FeatureFlagKey.IS_GROUP_BY_ENABLED, + workspaceId, + ); + return this.rootTypeGenerator.buildAndStore( objectMetadataCollection, - [...workspaceResolverBuilderMethodNames.queries], + [...workspaceResolverBuilderMethodNames.queries].filter( + (methodName) => methodName !== 'groupBy' || isGroupByEnabled, + ), GqlOperation.Query, ); } diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/workspace-graphql-schema.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/workspace-graphql-schema.factory.ts index 1aac4fcc64..69cdaf5adb 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/workspace-graphql-schema.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/workspace-graphql-schema.factory.ts @@ -17,10 +17,14 @@ export class WorkspaceGraphQLSchemaGenerator { private readonly orphanedTypesGenerator: OrphanedTypesGenerator, ) {} - generateSchema( + async generateSchema( objectMetadataCollection: ObjectMetadataEntity[], - ): GraphQLSchema { - this.gqlTypeGenerator.buildAndStore(objectMetadataCollection); + workspaceId: string, + ): Promise { + await this.gqlTypeGenerator.buildAndStore( + objectMetadataCollection, + workspaceId, + ); // Assemble schema const schema = new GraphQLSchema({ diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema.factory.ts index 8ce76f31e1..8a2ffc4f5c 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema.factory.ts @@ -106,8 +106,9 @@ export class WorkspaceSchemaFactory { // If typeDefs are not cached, generate them if (!typeDefs || !usedScalarNames) { const autoGeneratedSchema = - this.workspaceGraphQLSchemaGenerator.generateSchema( + await this.workspaceGraphQLSchemaGenerator.generateSchema( objectMetadataCollection, + workspaceId, ); usedScalarNames =