feat: new relation in graphql-query-runner (#9883)

Fix https://github.com/twentyhq/core-team-issues/issues/300

Within GraphQLQueryRunner the new relation format will be used when the
feature flag `IsNewRelationEnabled` is set to true.
This commit is contained in:
Jérémy M
2025-01-29 17:04:39 +01:00
committed by GitHub
parent 29745c6756
commit 07197d1e6d
31 changed files with 729 additions and 138 deletions
@@ -6,6 +6,7 @@ import {
} from 'typeorm';
import { ObjectRecordFilter } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
import { FeatureFlagMap } from 'src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface';
import { FieldMetadataMap } from 'src/engine/metadata-modules/types/field-metadata-map';
@@ -15,10 +16,14 @@ export class GraphqlQueryFilterConditionParser {
private fieldMetadataMapByName: FieldMetadataMap;
private queryFilterFieldParser: GraphqlQueryFilterFieldParser;
constructor(fieldMetadataMapByName: FieldMetadataMap) {
constructor(
fieldMetadataMapByName: FieldMetadataMap,
featureFlagsMap: FeatureFlagMap,
) {
this.fieldMetadataMapByName = fieldMetadataMapByName;
this.queryFilterFieldParser = new GraphqlQueryFilterFieldParser(
this.fieldMetadataMapByName,
featureFlagsMap,
);
}
@@ -1,6 +1,7 @@
import { capitalize } from 'twenty-shared';
import { WhereExpressionBuilder } from 'typeorm';
import { FeatureFlagMap } from 'src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface';
import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface';
import {
@@ -17,9 +18,14 @@ const ARRAY_OPERATORS = ['in', 'contains', 'notContains'];
export class GraphqlQueryFilterFieldParser {
private fieldMetadataMapByName: FieldMetadataMap;
private featureFlagsMap: FeatureFlagMap;
constructor(fieldMetadataMapByName: FieldMetadataMap) {
constructor(
fieldMetadataMapByName: FieldMetadataMap,
featureFlagsMap: FeatureFlagMap,
) {
this.fieldMetadataMapByName = fieldMetadataMapByName;
this.featureFlagsMap = featureFlagsMap;
}
public parse(
@@ -4,6 +4,7 @@ import {
ObjectRecordOrderBy,
OrderByDirection,
} from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
import { FeatureFlagMap } from 'src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface';
import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface';
import {
@@ -16,9 +17,14 @@ import { FieldMetadataMap } from 'src/engine/metadata-modules/types/field-metada
import { CompositeFieldMetadataType } from 'src/engine/metadata-modules/workspace-migration/factories/composite-column-action.factory';
export class GraphqlQueryOrderFieldParser {
private fieldMetadataMapByName: FieldMetadataMap;
private featureFlagsMap: FeatureFlagMap;
constructor(fieldMetadataMapByName: FieldMetadataMap) {
constructor(
fieldMetadataMapByName: FieldMetadataMap,
featureFlagsMap: FeatureFlagMap,
) {
this.fieldMetadataMapByName = fieldMetadataMapByName;
this.featureFlagsMap = featureFlagsMap;
}
parse(
@@ -1,3 +1,4 @@
import { FeatureFlagMap } from 'src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface';
import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface';
import {
@@ -5,13 +6,20 @@ import {
GraphqlQuerySelectedFieldsResult,
} from 'src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-selected-fields/graphql-selected-fields.parser';
import { getRelationObjectMetadata } from 'src/engine/api/graphql/graphql-query-runner/utils/get-relation-object-metadata.util';
import { getTargetObjectMetadataOrThrow } from 'src/engine/api/graphql/graphql-query-runner/utils/get-target-object-metadata.util';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { ObjectMetadataMaps } from 'src/engine/metadata-modules/types/object-metadata-maps';
export class GraphqlQuerySelectedFieldsRelationParser {
private objectMetadataMaps: ObjectMetadataMaps;
private featureFlagsMap: FeatureFlagMap;
constructor(objectMetadataMaps: ObjectMetadataMaps) {
constructor(
objectMetadataMaps: ObjectMetadataMaps,
featureFlagsMap: FeatureFlagMap,
) {
this.objectMetadataMaps = objectMetadataMaps;
this.featureFlagsMap = featureFlagsMap;
}
parseRelationField(
@@ -26,16 +34,19 @@ export class GraphqlQuerySelectedFieldsRelationParser {
accumulator.relations[fieldKey] = true;
const referencedObjectMetadata = getRelationObjectMetadata(
fieldMetadata,
this.objectMetadataMaps,
);
const isNewRelationEnabled =
this.featureFlagsMap[FeatureFlagKey.IsNewRelationEnabled];
const relationFields = referencedObjectMetadata.fieldsByName;
const targetObjectMetadata = isNewRelationEnabled
? getTargetObjectMetadataOrThrow(fieldMetadata, this.objectMetadataMaps)
: getRelationObjectMetadata(fieldMetadata, this.objectMetadataMaps);
const targetFields = targetObjectMetadata.fieldsByName;
const fieldParser = new GraphqlQuerySelectedFieldsParser(
this.objectMetadataMaps,
this.featureFlagsMap,
);
const relationAccumulator = fieldParser.parse(fieldValue, relationFields);
const relationAccumulator = fieldParser.parse(fieldValue, targetFields);
accumulator.select[fieldKey] = {
id: true,
@@ -1,5 +1,6 @@
import { capitalize } from 'twenty-shared';
import { FeatureFlagMap } from 'src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface';
import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface';
import { GraphqlQuerySelectedFieldsAggregateParser } from 'src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-selected-fields/graphql-selected-fields-aggregate.parser';
@@ -20,9 +21,15 @@ export class GraphqlQuerySelectedFieldsParser {
private graphqlQuerySelectedFieldsRelationParser: GraphqlQuerySelectedFieldsRelationParser;
private aggregateParser: GraphqlQuerySelectedFieldsAggregateParser;
constructor(objectMetadataMaps: ObjectMetadataMaps) {
constructor(
objectMetadataMaps: ObjectMetadataMaps,
featureFlagsMap: FeatureFlagMap,
) {
this.graphqlQuerySelectedFieldsRelationParser =
new GraphqlQuerySelectedFieldsRelationParser(objectMetadataMaps);
new GraphqlQuerySelectedFieldsRelationParser(
objectMetadataMaps,
featureFlagsMap,
);
this.aggregateParser = new GraphqlQuerySelectedFieldsAggregateParser();
}
@@ -9,6 +9,7 @@ import {
ObjectRecordFilter,
ObjectRecordOrderBy,
} from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
import { FeatureFlagMap } from 'src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface';
import { GraphqlQueryFilterConditionParser } from 'src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-filter/graphql-query-filter-condition.parser';
import { GraphqlQueryOrderFieldParser } from 'src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-order/graphql-query-order.parser';
@@ -26,18 +27,23 @@ export class GraphqlQueryParser {
private objectMetadataMaps: ObjectMetadataMaps;
private filterConditionParser: GraphqlQueryFilterConditionParser;
private orderFieldParser: GraphqlQueryOrderFieldParser;
private featureFlagsMap: FeatureFlagMap;
constructor(
fieldMetadataMapByName: FieldMetadataMap,
objectMetadataMaps: ObjectMetadataMaps,
featureFlagsMap: FeatureFlagMap,
) {
this.objectMetadataMaps = objectMetadataMaps;
this.fieldMetadataMapByName = fieldMetadataMapByName;
this.featureFlagsMap = featureFlagsMap;
this.filterConditionParser = new GraphqlQueryFilterConditionParser(
this.fieldMetadataMapByName,
featureFlagsMap,
);
this.orderFieldParser = new GraphqlQueryOrderFieldParser(
this.fieldMetadataMapByName,
featureFlagsMap,
);
}
@@ -122,6 +128,7 @@ export class GraphqlQueryParser {
const selectedFieldsParser = new GraphqlQuerySelectedFieldsParser(
this.objectMetadataMaps,
this.featureFlagsMap,
);
return selectedFieldsParser.parse(graphqlSelectedFields, parentFields);