Connect/Disconnect - Add Disconnect logic + Migration to query builders (insert/update) (#13271)

Context : 
Large PR with 600+ test files. Enable connect and disconnect logic in
createMany (upsert true) / updateOne / updateMany resolvers

- Add disconnect logic
- Gather disconnect and connect logic -> called relation nested queries
- Move logic to query builder (insert and update one) with a preparation
step in .set/.values and an execution step in .execute
- Add integration tests

Test : 
- Test API call on updateMany, updateOne, createMany (upsert:true) with
connect/disconnect
This commit is contained in:
Etienne
2025-07-24 17:04:38 +02:00
committed by GitHub
parent 7bfa003682
commit 88a6913217
20 changed files with 1182 additions and 445 deletions
@@ -1,11 +1,13 @@
import { Injectable } from '@nestjs/common';
import {
GraphQLBoolean,
GraphQLInputFieldConfig,
GraphQLInputObjectType,
GraphQLInputType,
GraphQLString,
} from 'graphql';
import { RELATION_NESTED_QUERY_KEYWORDS } from 'twenty-shared/constants';
import {
InputTypeDefinition,
@@ -36,6 +38,11 @@ export class RelationConnectInputTypeDefinitionFactory {
kind: InputTypeDefinitionKind.Create,
type: fields,
},
{
target,
kind: InputTypeDefinitionKind.Update,
type: fields,
},
];
}
@@ -45,13 +52,17 @@ export class RelationConnectInputTypeDefinitionFactory {
return new GraphQLInputObjectType({
name: `${pascalCase(objectMetadata.nameSingular)}RelationInput`,
fields: () => ({
connect: {
[RELATION_NESTED_QUERY_KEYWORDS.CONNECT]: {
type: new GraphQLInputObjectType({
name: `${pascalCase(objectMetadata.nameSingular)}ConnectInput`,
fields: this.generateRelationWhereInputType(objectMetadata),
}),
description: `Connect to a ${objectMetadata.nameSingular} record`,
},
[RELATION_NESTED_QUERY_KEYWORDS.DISCONNECT]: {
type: GraphQLBoolean,
description: `Disconnect from a ${objectMetadata.nameSingular} record`,
},
}),
});
}
@@ -127,7 +138,7 @@ export class RelationConnectInputTypeDefinitionFactory {
});
return {
where: {
[RELATION_NESTED_QUERY_KEYWORDS.CONNECT_WHERE]: {
type: new GraphQLInputObjectType({
name: `${pascalCase(objectMetadata.nameSingular)}WhereUniqueInput`,
fields: () => fields,
@@ -200,7 +200,7 @@ const generateRelationField = <
};
if (
[InputTypeDefinitionKind.Create].includes(
[InputTypeDefinitionKind.Create, InputTypeDefinitionKind.Update].includes(
kind as InputTypeDefinitionKind,
) &&
isDefined(fieldMetadata.relationTargetObjectMetadataId)