From 7c3e82870c204d0f74010d0da6866f324babd4fb Mon Sep 17 00:00:00 2001 From: Marie <51697796+ijreilly@users.noreply.github.com> Date: Tue, 7 May 2024 16:30:25 +0200 Subject: [PATCH] [fix] Increment cache version after object/field/relation update (#5316) Fixes #5276. Updates were not triggering a cache version incrementation because they do not trigger migrations while that is where the caching version logic was. We have decided to move the cache incrementation logic to the services. --- .../src/generated-metadata/gql.ts | 4 +-- .../src/generated-metadata/graphql.ts | 11 ++++---- .../object-metadata/graphql/mutations.ts | 2 +- .../useFilteredObjectMetadataItems.ts | 2 +- .../hooks/useUpdateOneObjectMetadataItem.ts | 6 ++-- .../settingsUpdateObjectInputSchema.test.ts | 4 +-- .../settingsUpdateObjectInputSchema.ts | 4 +-- .../field-metadata/field-metadata.module.ts | 2 ++ .../field-metadata/field-metadata.service.ts | 10 +++++++ .../dtos/update-object.input.ts | 26 +++++++++++++++-- .../hooks/before-update-one-object.hook.ts | 6 ++-- .../object-metadata/object-metadata.module.ts | 10 +++---- .../object-metadata.resolver.ts | 9 ++++++ .../object-metadata.service.ts | 21 ++++++++++++++ .../validate-object-metadata-input.util.ts | 4 +-- .../dtos/delete-relation.input.ts | 13 +++++++++ .../relation-metadata.module.ts | 7 +++-- .../relation-metadata.resolver.ts | 28 +++++++++++++++++++ .../relation-metadata.service.ts | 20 ++++++++++--- .../workspace-migration-runner.service.ts | 3 -- .../workspace-sync-metadata.module.ts | 2 ++ .../workspace-sync-metadata.service.ts | 5 ++++ 22 files changed, 160 insertions(+), 39 deletions(-) create mode 100644 packages/twenty-server/src/engine/metadata-modules/relation-metadata/dtos/delete-relation.input.ts create mode 100644 packages/twenty-server/src/engine/metadata-modules/relation-metadata/relation-metadata.resolver.ts diff --git a/packages/twenty-front/src/generated-metadata/gql.ts b/packages/twenty-front/src/generated-metadata/gql.ts index 8d2ccc33726..c632dfedc65 100644 --- a/packages/twenty-front/src/generated-metadata/gql.ts +++ b/packages/twenty-front/src/generated-metadata/gql.ts @@ -27,7 +27,7 @@ const documents = { "\n mutation CreateOneFieldMetadataItem($input: CreateOneFieldMetadataInput!) {\n createOneField(input: $input) {\n id\n type\n name\n label\n description\n icon\n isCustom\n isActive\n isNullable\n createdAt\n updatedAt\n defaultValue\n options\n }\n }\n": types.CreateOneFieldMetadataItemDocument, "\n mutation CreateOneRelationMetadata($input: CreateOneRelationInput!) {\n createOneRelation(input: $input) {\n id\n relationType\n fromObjectMetadataId\n toObjectMetadataId\n fromFieldMetadataId\n toFieldMetadataId\n createdAt\n updatedAt\n }\n }\n": types.CreateOneRelationMetadataDocument, "\n mutation UpdateOneFieldMetadataItem(\n $idToUpdate: UUID!\n $updatePayload: UpdateFieldInput!\n ) {\n updateOneField(input: { id: $idToUpdate, update: $updatePayload }) {\n id\n type\n name\n label\n description\n icon\n isCustom\n isActive\n isNullable\n createdAt\n updatedAt\n }\n }\n": types.UpdateOneFieldMetadataItemDocument, - "\n mutation UpdateOneObjectMetadataItem(\n $idToUpdate: UUID!\n $updatePayload: UpdateObjectInput!\n ) {\n updateOneObject(input: { id: $idToUpdate, update: $updatePayload }) {\n id\n dataSourceId\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n isCustom\n isActive\n createdAt\n updatedAt\n labelIdentifierFieldMetadataId\n imageIdentifierFieldMetadataId\n }\n }\n": types.UpdateOneObjectMetadataItemDocument, + "\n mutation UpdateOneObjectMetadataItem(\n $idToUpdate: UUID!\n $updatePayload: UpdateObjectPayload!\n ) {\n updateOneObject(input: { id: $idToUpdate, update: $updatePayload }) {\n id\n dataSourceId\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n isCustom\n isActive\n createdAt\n updatedAt\n labelIdentifierFieldMetadataId\n imageIdentifierFieldMetadataId\n }\n }\n": types.UpdateOneObjectMetadataItemDocument, "\n mutation DeleteOneObjectMetadataItem($idToDelete: UUID!) {\n deleteOneObject(input: { id: $idToDelete }) {\n id\n dataSourceId\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n isCustom\n isActive\n createdAt\n updatedAt\n labelIdentifierFieldMetadataId\n imageIdentifierFieldMetadataId\n }\n }\n": types.DeleteOneObjectMetadataItemDocument, "\n mutation DeleteOneFieldMetadataItem($idToDelete: UUID!) {\n deleteOneField(input: { id: $idToDelete }) {\n id\n type\n name\n label\n description\n icon\n isCustom\n isActive\n isNullable\n createdAt\n updatedAt\n }\n }\n": types.DeleteOneFieldMetadataItemDocument, "\n query ObjectMetadataItems(\n $objectFilter: objectFilter\n $fieldFilter: fieldFilter\n ) {\n objects(paging: { first: 1000 }, filter: $objectFilter) {\n edges {\n node {\n id\n dataSourceId\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n isCustom\n isRemote\n isActive\n isSystem\n createdAt\n updatedAt\n labelIdentifierFieldMetadataId\n imageIdentifierFieldMetadataId\n fields(paging: { first: 1000 }, filter: $fieldFilter) {\n edges {\n node {\n id\n type\n name\n label\n description\n icon\n isCustom\n isActive\n isSystem\n isNullable\n createdAt\n updatedAt\n fromRelationMetadata {\n id\n relationType\n toObjectMetadata {\n id\n dataSourceId\n nameSingular\n namePlural\n isSystem\n isRemote\n }\n toFieldMetadataId\n }\n toRelationMetadata {\n id\n relationType\n fromObjectMetadata {\n id\n dataSourceId\n nameSingular\n namePlural\n isSystem\n isRemote\n }\n fromFieldMetadataId\n }\n defaultValue\n options\n relationDefinition {\n direction\n sourceObjectMetadata {\n id\n nameSingular\n namePlural\n }\n sourceFieldMetadata {\n id\n name\n }\n targetObjectMetadata {\n id\n nameSingular\n namePlural\n }\n targetFieldMetadata {\n id\n name\n }\n }\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n": types.ObjectMetadataItemsDocument, @@ -106,7 +106,7 @@ export function graphql(source: "\n mutation UpdateOneFieldMetadataItem(\n $ /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "\n mutation UpdateOneObjectMetadataItem(\n $idToUpdate: UUID!\n $updatePayload: UpdateObjectInput!\n ) {\n updateOneObject(input: { id: $idToUpdate, update: $updatePayload }) {\n id\n dataSourceId\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n isCustom\n isActive\n createdAt\n updatedAt\n labelIdentifierFieldMetadataId\n imageIdentifierFieldMetadataId\n }\n }\n"): (typeof documents)["\n mutation UpdateOneObjectMetadataItem(\n $idToUpdate: UUID!\n $updatePayload: UpdateObjectInput!\n ) {\n updateOneObject(input: { id: $idToUpdate, update: $updatePayload }) {\n id\n dataSourceId\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n isCustom\n isActive\n createdAt\n updatedAt\n labelIdentifierFieldMetadataId\n imageIdentifierFieldMetadataId\n }\n }\n"]; +export function graphql(source: "\n mutation UpdateOneObjectMetadataItem(\n $idToUpdate: UUID!\n $updatePayload: UpdateObjectPayload!\n ) {\n updateOneObject(input: { id: $idToUpdate, update: $updatePayload }) {\n id\n dataSourceId\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n isCustom\n isActive\n createdAt\n updatedAt\n labelIdentifierFieldMetadataId\n imageIdentifierFieldMetadataId\n }\n }\n"): (typeof documents)["\n mutation UpdateOneObjectMetadataItem(\n $idToUpdate: UUID!\n $updatePayload: UpdateObjectPayload!\n ) {\n updateOneObject(input: { id: $idToUpdate, update: $updatePayload }) {\n id\n dataSourceId\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n isCustom\n isActive\n createdAt\n updatedAt\n labelIdentifierFieldMetadataId\n imageIdentifierFieldMetadataId\n }\n }\n"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts index 591d37e4acf..dda468a38d1 100644 --- a/packages/twenty-front/src/generated-metadata/graphql.ts +++ b/packages/twenty-front/src/generated-metadata/graphql.ts @@ -978,7 +978,7 @@ export type UpdateFieldInput = { settings?: InputMaybe; }; -export type UpdateObjectInput = { +export type UpdateObjectPayload = { description?: InputMaybe; icon?: InputMaybe; imageIdentifierFieldMetadataId?: InputMaybe; @@ -998,10 +998,9 @@ export type UpdateOneFieldMetadataInput = { }; export type UpdateOneObjectInput = { - /** The id of the record to update */ + /** The id of the object to update */ id: Scalars['UUID']['input']; - /** The update to apply. */ - update: UpdateObjectInput; + update: UpdateObjectPayload; }; export type UpdateRemoteServerInput = { @@ -1344,7 +1343,7 @@ export type UpdateOneFieldMetadataItemMutation = { __typename?: 'Mutation', upda export type UpdateOneObjectMetadataItemMutationVariables = Exact<{ idToUpdate: Scalars['UUID']['input']; - updatePayload: UpdateObjectInput; + updatePayload: UpdateObjectPayload; }>; @@ -1386,7 +1385,7 @@ export const CreateOneObjectMetadataItemDocument = {"kind":"Document","definitio export const CreateOneFieldMetadataItemDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateOneFieldMetadataItem"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CreateOneFieldMetadataInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createOneField"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"label"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"isCustom"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"isNullable"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"defaultValue"}},{"kind":"Field","name":{"kind":"Name","value":"options"}}]}}]}}]} as unknown as DocumentNode; export const CreateOneRelationMetadataDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateOneRelationMetadata"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CreateOneRelationInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createOneRelation"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"relationType"}},{"kind":"Field","name":{"kind":"Name","value":"fromObjectMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"toObjectMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"fromFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"toFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode; export const UpdateOneFieldMetadataItemDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateOneFieldMetadataItem"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"idToUpdate"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"updatePayload"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateFieldInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateOneField"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"idToUpdate"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"update"},"value":{"kind":"Variable","name":{"kind":"Name","value":"updatePayload"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"label"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"isCustom"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"isNullable"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode; -export const UpdateOneObjectMetadataItemDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateOneObjectMetadataItem"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"idToUpdate"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"updatePayload"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateObjectInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateOneObject"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"idToUpdate"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"update"},"value":{"kind":"Variable","name":{"kind":"Name","value":"updatePayload"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"dataSourceId"}},{"kind":"Field","name":{"kind":"Name","value":"nameSingular"}},{"kind":"Field","name":{"kind":"Name","value":"namePlural"}},{"kind":"Field","name":{"kind":"Name","value":"labelSingular"}},{"kind":"Field","name":{"kind":"Name","value":"labelPlural"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"isCustom"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"labelIdentifierFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"imageIdentifierFieldMetadataId"}}]}}]}}]} as unknown as DocumentNode; +export const UpdateOneObjectMetadataItemDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateOneObjectMetadataItem"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"idToUpdate"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"updatePayload"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateObjectPayload"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateOneObject"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"idToUpdate"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"update"},"value":{"kind":"Variable","name":{"kind":"Name","value":"updatePayload"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"dataSourceId"}},{"kind":"Field","name":{"kind":"Name","value":"nameSingular"}},{"kind":"Field","name":{"kind":"Name","value":"namePlural"}},{"kind":"Field","name":{"kind":"Name","value":"labelSingular"}},{"kind":"Field","name":{"kind":"Name","value":"labelPlural"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"isCustom"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"labelIdentifierFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"imageIdentifierFieldMetadataId"}}]}}]}}]} as unknown as DocumentNode; export const DeleteOneObjectMetadataItemDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteOneObjectMetadataItem"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"idToDelete"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteOneObject"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"idToDelete"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"dataSourceId"}},{"kind":"Field","name":{"kind":"Name","value":"nameSingular"}},{"kind":"Field","name":{"kind":"Name","value":"namePlural"}},{"kind":"Field","name":{"kind":"Name","value":"labelSingular"}},{"kind":"Field","name":{"kind":"Name","value":"labelPlural"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"isCustom"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"labelIdentifierFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"imageIdentifierFieldMetadataId"}}]}}]}}]} as unknown as DocumentNode; export const DeleteOneFieldMetadataItemDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteOneFieldMetadataItem"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"idToDelete"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteOneField"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"idToDelete"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"label"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"isCustom"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"isNullable"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode; export const ObjectMetadataItemsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ObjectMetadataItems"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"objectFilter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"objectFilter"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"fieldFilter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"fieldFilter"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"objects"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"paging"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"first"},"value":{"kind":"IntValue","value":"1000"}}]}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"objectFilter"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"dataSourceId"}},{"kind":"Field","name":{"kind":"Name","value":"nameSingular"}},{"kind":"Field","name":{"kind":"Name","value":"namePlural"}},{"kind":"Field","name":{"kind":"Name","value":"labelSingular"}},{"kind":"Field","name":{"kind":"Name","value":"labelPlural"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"isCustom"}},{"kind":"Field","name":{"kind":"Name","value":"isRemote"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"isSystem"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"labelIdentifierFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"imageIdentifierFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"fields"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"paging"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"first"},"value":{"kind":"IntValue","value":"1000"}}]}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"fieldFilter"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"label"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"isCustom"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"isSystem"}},{"kind":"Field","name":{"kind":"Name","value":"isNullable"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"fromRelationMetadata"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"relationType"}},{"kind":"Field","name":{"kind":"Name","value":"toObjectMetadata"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"dataSourceId"}},{"kind":"Field","name":{"kind":"Name","value":"nameSingular"}},{"kind":"Field","name":{"kind":"Name","value":"namePlural"}},{"kind":"Field","name":{"kind":"Name","value":"isSystem"}},{"kind":"Field","name":{"kind":"Name","value":"isRemote"}}]}},{"kind":"Field","name":{"kind":"Name","value":"toFieldMetadataId"}}]}},{"kind":"Field","name":{"kind":"Name","value":"toRelationMetadata"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"relationType"}},{"kind":"Field","name":{"kind":"Name","value":"fromObjectMetadata"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"dataSourceId"}},{"kind":"Field","name":{"kind":"Name","value":"nameSingular"}},{"kind":"Field","name":{"kind":"Name","value":"namePlural"}},{"kind":"Field","name":{"kind":"Name","value":"isSystem"}},{"kind":"Field","name":{"kind":"Name","value":"isRemote"}}]}},{"kind":"Field","name":{"kind":"Name","value":"fromFieldMetadataId"}}]}},{"kind":"Field","name":{"kind":"Name","value":"defaultValue"}},{"kind":"Field","name":{"kind":"Name","value":"options"}},{"kind":"Field","name":{"kind":"Name","value":"relationDefinition"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"direction"}},{"kind":"Field","name":{"kind":"Name","value":"sourceObjectMetadata"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"nameSingular"}},{"kind":"Field","name":{"kind":"Name","value":"namePlural"}}]}},{"kind":"Field","name":{"kind":"Name","value":"sourceFieldMetadata"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"targetObjectMetadata"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"nameSingular"}},{"kind":"Field","name":{"kind":"Name","value":"namePlural"}}]}},{"kind":"Field","name":{"kind":"Name","value":"targetFieldMetadata"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"pageInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hasNextPage"}},{"kind":"Field","name":{"kind":"Name","value":"hasPreviousPage"}},{"kind":"Field","name":{"kind":"Name","value":"startCursor"}},{"kind":"Field","name":{"kind":"Name","value":"endCursor"}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"pageInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hasNextPage"}},{"kind":"Field","name":{"kind":"Name","value":"hasPreviousPage"}},{"kind":"Field","name":{"kind":"Name","value":"startCursor"}},{"kind":"Field","name":{"kind":"Name","value":"endCursor"}}]}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/packages/twenty-front/src/modules/object-metadata/graphql/mutations.ts b/packages/twenty-front/src/modules/object-metadata/graphql/mutations.ts index 2fce4c3b2a2..e73bcabd4c7 100644 --- a/packages/twenty-front/src/modules/object-metadata/graphql/mutations.ts +++ b/packages/twenty-front/src/modules/object-metadata/graphql/mutations.ts @@ -80,7 +80,7 @@ export const UPDATE_ONE_FIELD_METADATA_ITEM = gql` export const UPDATE_ONE_OBJECT_METADATA_ITEM = gql` mutation UpdateOneObjectMetadataItem( $idToUpdate: UUID! - $updatePayload: UpdateObjectInput! + $updatePayload: UpdateObjectPayload! ) { updateOneObject(input: { id: $idToUpdate, update: $updatePayload }) { id diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/__mocks__/useFilteredObjectMetadataItems.ts b/packages/twenty-front/src/modules/object-metadata/hooks/__mocks__/useFilteredObjectMetadataItems.ts index fa99fc04c4d..a2419898a78 100644 --- a/packages/twenty-front/src/modules/object-metadata/hooks/__mocks__/useFilteredObjectMetadataItems.ts +++ b/packages/twenty-front/src/modules/object-metadata/hooks/__mocks__/useFilteredObjectMetadataItems.ts @@ -3,7 +3,7 @@ import { gql } from '@apollo/client'; export const query = gql` mutation UpdateOneObjectMetadataItem( $idToUpdate: UUID! - $updatePayload: UpdateObjectInput! + $updatePayload: UpdateObjectPayload! ) { updateOneObject(input: { id: $idToUpdate, update: $updatePayload }) { id diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/useUpdateOneObjectMetadataItem.ts b/packages/twenty-front/src/modules/object-metadata/hooks/useUpdateOneObjectMetadataItem.ts index aaa7b0ae775..aa02b1e730f 100644 --- a/packages/twenty-front/src/modules/object-metadata/hooks/useUpdateOneObjectMetadataItem.ts +++ b/packages/twenty-front/src/modules/object-metadata/hooks/useUpdateOneObjectMetadataItem.ts @@ -2,7 +2,7 @@ import { useMutation } from '@apollo/client'; import { getOperationName } from '@apollo/client/utilities'; import { - UpdateObjectInput, + UpdateOneObjectInput, UpdateOneObjectMetadataItemMutation, UpdateOneObjectMetadataItemMutationVariables, } from '~/generated-metadata/graphql'; @@ -27,8 +27,8 @@ export const useUpdateOneObjectMetadataItem = () => { idToUpdate, updatePayload, }: { - idToUpdate: UpdateOneObjectMetadataItemMutationVariables['idToUpdate']; - updatePayload: UpdateObjectInput; + idToUpdate: UpdateOneObjectInput['id']; + updatePayload: UpdateOneObjectInput['update']; }) => { return await mutate({ variables: { diff --git a/packages/twenty-front/src/modules/settings/data-model/validation-schemas/__tests__/settingsUpdateObjectInputSchema.test.ts b/packages/twenty-front/src/modules/settings/data-model/validation-schemas/__tests__/settingsUpdateObjectInputSchema.test.ts index 0147790fed9..676850f6a4e 100644 --- a/packages/twenty-front/src/modules/settings/data-model/validation-schemas/__tests__/settingsUpdateObjectInputSchema.test.ts +++ b/packages/twenty-front/src/modules/settings/data-model/validation-schemas/__tests__/settingsUpdateObjectInputSchema.test.ts @@ -1,6 +1,6 @@ import { SafeParseSuccess } from 'zod'; -import { UpdateObjectInput } from '~/generated-metadata/graphql'; +import { UpdateObjectPayload } from '~/generated-metadata/graphql'; import { settingsUpdateObjectInputSchema } from '../settingsUpdateObjectInputSchema'; @@ -20,7 +20,7 @@ describe('settingsUpdateObjectInputSchema', () => { // Then expect(result.success).toBe(true); - expect((result as SafeParseSuccess).data).toEqual({ + expect((result as SafeParseSuccess).data).toEqual({ description: validInput.description, icon: validInput.icon, labelIdentifierFieldMetadataId: validInput.labelIdentifierFieldMetadataId, diff --git a/packages/twenty-front/src/modules/settings/data-model/validation-schemas/settingsUpdateObjectInputSchema.ts b/packages/twenty-front/src/modules/settings/data-model/validation-schemas/settingsUpdateObjectInputSchema.ts index 553fb2edcc5..5a9a2cf1a36 100644 --- a/packages/twenty-front/src/modules/settings/data-model/validation-schemas/settingsUpdateObjectInputSchema.ts +++ b/packages/twenty-front/src/modules/settings/data-model/validation-schemas/settingsUpdateObjectInputSchema.ts @@ -1,5 +1,5 @@ import { objectMetadataItemSchema } from '@/object-metadata/validation-schemas/objectMetadataItemSchema'; -import { UpdateObjectInput } from '~/generated-metadata/graphql'; +import { UpdateObjectPayload } from '~/generated-metadata/graphql'; import { formatMetadataLabelToMetadataNameOrThrows } from '~/pages/settings/data-model/utils/format-metadata-label-to-name.util'; export const settingsUpdateObjectInputSchema = objectMetadataItemSchema @@ -13,7 +13,7 @@ export const settingsUpdateObjectInputSchema = objectMetadataItemSchema labelSingular: true, }) .partial() - .transform((value) => ({ + .transform((value) => ({ ...value, nameSingular: value.labelSingular ? formatMetadataLabelToMetadataNameOrThrows(value.labelSingular) diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.module.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.module.ts index 9e741e29f3b..bcf9159b993 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.module.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.module.ts @@ -17,6 +17,7 @@ import { IsFieldMetadataDefaultValue } from 'src/engine/metadata-modules/field-m import { FieldMetadataResolver } from 'src/engine/metadata-modules/field-metadata/field-metadata.resolver'; import { FieldMetadataDTO } from 'src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto'; import { IsFieldMetadataOptions } from 'src/engine/metadata-modules/field-metadata/validators/is-field-metadata-options.validator'; +import { WorkspaceCacheVersionModule } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.module'; import { FieldMetadataService } from './field-metadata.service'; import { FieldMetadataEntity } from './field-metadata.entity'; @@ -31,6 +32,7 @@ import { UpdateFieldInput } from './dtos/update-field.input'; NestjsQueryTypeOrmModule.forFeature([FieldMetadataEntity], 'metadata'), WorkspaceMigrationModule, WorkspaceMigrationRunnerModule, + WorkspaceCacheVersionModule, ObjectMetadataModule, DataSourceModule, TypeORMModule, diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.service.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.service.ts index ee790edeec4..417064b481a 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.service.ts @@ -41,6 +41,7 @@ import { computeColumnName } from 'src/engine/metadata-modules/field-metadata/ut import { assertMutationNotOnRemoteObject } from 'src/engine/metadata-modules/object-metadata/utils/assert-mutation-not-on-remote-object.util'; import { InvalidStringException } from 'src/engine/metadata-modules/errors/InvalidStringException'; import { validateMetadataName } from 'src/engine/metadata-modules/utils/validate-metadata-name.utils'; +import { WorkspaceCacheVersionService } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service'; import { FieldMetadataEntity, @@ -64,6 +65,7 @@ export class FieldMetadataService extends TypeOrmQueryService UpdateObjectPayload) + update: UpdateObjectPayload; + + @IsNotEmpty() + @Field(() => UUIDScalarType, { + description: 'The id of the object to update', + }) + @IsUUID() + id!: string; +} diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/hooks/before-update-one-object.hook.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/hooks/before-update-one-object.hook.ts index 831637c200b..74b18f8059c 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/hooks/before-update-one-object.hook.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/hooks/before-update-one-object.hook.ts @@ -12,12 +12,12 @@ import { import { Equal, In, Repository } from 'typeorm'; import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; -import { UpdateObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/update-object.input'; +import { UpdateObjectPayload } from 'src/engine/metadata-modules/object-metadata/dtos/update-object.input'; import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; @Injectable() -export class BeforeUpdateOneObject +export class BeforeUpdateOneObject implements BeforeUpdateOneHook { constructor( @@ -108,7 +108,7 @@ export class BeforeUpdateOneObject // This is temporary until we properly use the MigrationRunner to update column names private checkIfFieldIsEditable( - update: UpdateObjectInput, + update: UpdateObjectPayload, objectMetadata: ObjectMetadataEntity, ) { if ( diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.module.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.module.ts index 33779655943..20c15c9be27 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.module.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.module.ts @@ -18,12 +18,13 @@ import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-met import { ObjectMetadataResolver } from 'src/engine/metadata-modules/object-metadata/object-metadata.resolver'; import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module'; import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; +import { WorkspaceCacheVersionModule } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.module'; import { ObjectMetadataService } from './object-metadata.service'; import { ObjectMetadataEntity } from './object-metadata.entity'; import { CreateObjectInput } from './dtos/create-object.input'; -import { UpdateObjectInput } from './dtos/update-object.input'; +import { UpdateObjectPayload } from './dtos/update-object.input'; import { ObjectMetadataDTO } from './dtos/object-metadata.dto'; @Module({ @@ -39,6 +40,7 @@ import { ObjectMetadataDTO } from './dtos/object-metadata.dto'; DataSourceModule, WorkspaceMigrationModule, WorkspaceMigrationRunnerModule, + WorkspaceCacheVersionModule, FeatureFlagModule, ], services: [ObjectMetadataService], @@ -47,7 +49,7 @@ import { ObjectMetadataDTO } from './dtos/object-metadata.dto'; EntityClass: ObjectMetadataEntity, DTOClass: ObjectMetadataDTO, CreateDTOClass: CreateObjectInput, - UpdateDTOClass: UpdateObjectInput, + UpdateDTOClass: UpdateObjectPayload, ServiceClass: ObjectMetadataService, pagingStrategy: PagingStrategies.CURSOR, read: { @@ -56,9 +58,7 @@ import { ObjectMetadataDTO } from './dtos/object-metadata.dto'; create: { many: { disabled: true }, }, - update: { - many: { disabled: true }, - }, + update: { disabled: true }, delete: { disabled: true }, guards: [JwtAuthGuard], }, diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.resolver.ts index 002ab0a2b05..67e6305bd4d 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.resolver.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.resolver.ts @@ -7,6 +7,7 @@ import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard'; import { ObjectMetadataDTO } from 'src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto'; import { DeleteOneObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/delete-object.input'; import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; +import { UpdateOneObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/update-object.input'; @UseGuards(JwtAuthGuard) @Resolver(() => ObjectMetadataDTO) @@ -20,4 +21,12 @@ export class ObjectMetadataResolver { ) { return this.objectMetadataService.deleteOneObject(input, workspaceId); } + + @Mutation(() => ObjectMetadataDTO) + updateOneObject( + @Args('input') input: UpdateOneObjectInput, + @AuthWorkspace() { id: workspaceId }: Workspace, + ) { + return this.objectMetadataService.updateOneObject(input, workspaceId); + } } diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts index 8f01d80bd9a..93d00531c2f 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts @@ -60,6 +60,8 @@ import { computeColumnName } from 'src/engine/metadata-modules/field-metadata/ut import { DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity'; import { validateObjectMetadataInput } from 'src/engine/metadata-modules/object-metadata/utils/validate-object-metadata-input.util'; import { mapUdtNameToFieldType } from 'src/engine/metadata-modules/remote-server/remote-table/utils/udt-name-mapper.util'; +import { WorkspaceCacheVersionService } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service'; +import { UpdateOneObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/update-object.input'; import { ObjectMetadataEntity } from './object-metadata.entity'; @@ -81,6 +83,7 @@ export class ObjectMetadataService extends TypeOrmQueryService { + const updatedObject = await super.updateOne(input.id, input.update); + + await this.workspaceCacheVersionService.incrementVersion(workspaceId); + + return updatedObject; + } + public async findOneWithinWorkspace( workspaceId: string, options: FindOneOptions, @@ -475,6 +495,7 @@ export class ObjectMetadataService extends TypeOrmQueryService( objectMetadataInput: T, ): void => { diff --git a/packages/twenty-server/src/engine/metadata-modules/relation-metadata/dtos/delete-relation.input.ts b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/dtos/delete-relation.input.ts new file mode 100644 index 00000000000..ec11fa3e66a --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/dtos/delete-relation.input.ts @@ -0,0 +1,13 @@ +import { InputType } from '@nestjs/graphql'; + +import { IDField } from '@ptc-org/nestjs-query-graphql'; + +import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; + +@InputType() +export class DeleteOneRelationInput { + @IDField(() => UUIDScalarType, { + description: 'The id of the relation to delete.', + }) + id!: string; +} diff --git a/packages/twenty-server/src/engine/metadata-modules/relation-metadata/relation-metadata.module.ts b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/relation-metadata.module.ts index f0be7bc7df9..ef218dd3691 100644 --- a/packages/twenty-server/src/engine/metadata-modules/relation-metadata/relation-metadata.module.ts +++ b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/relation-metadata.module.ts @@ -11,6 +11,8 @@ import { FieldMetadataModule } from 'src/engine/metadata-modules/field-metadata/ import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module'; import { WorkspaceMigrationModule } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.module'; import { WorkspaceMigrationRunnerModule } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.module'; +import { WorkspaceCacheVersionModule } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.module'; +import { RelationMetadataResolver } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.resolver'; import { RelationMetadataService } from './relation-metadata.service'; import { RelationMetadataEntity } from './relation-metadata.entity'; @@ -30,6 +32,7 @@ import { RelationMetadataDTO } from './dtos/relation-metadata.dto'; FieldMetadataModule, WorkspaceMigrationRunnerModule, WorkspaceMigrationModule, + WorkspaceCacheVersionModule, ], services: [RelationMetadataService], resolvers: [ @@ -41,13 +44,13 @@ import { RelationMetadataDTO } from './dtos/relation-metadata.dto'; pagingStrategy: PagingStrategies.CURSOR, create: { many: { disabled: true } }, update: { disabled: true }, - delete: { many: { disabled: true } }, + delete: { disabled: true }, guards: [JwtAuthGuard], }, ], }), ], - providers: [RelationMetadataService], + providers: [RelationMetadataService, RelationMetadataResolver], exports: [RelationMetadataService], }) export class RelationMetadataModule {} diff --git a/packages/twenty-server/src/engine/metadata-modules/relation-metadata/relation-metadata.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/relation-metadata.resolver.ts new file mode 100644 index 00000000000..c7eb414987b --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/relation-metadata.resolver.ts @@ -0,0 +1,28 @@ +import { UseGuards } from '@nestjs/common'; +import { Args, Mutation, Resolver } from '@nestjs/graphql'; + +import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard'; +import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; +import { RelationMetadataService } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.service'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { RelationMetadataDTO } from 'src/engine/metadata-modules/relation-metadata/dtos/relation-metadata.dto'; +import { DeleteOneRelationInput } from 'src/engine/metadata-modules/relation-metadata/dtos/delete-relation.input'; + +@UseGuards(JwtAuthGuard) +@Resolver() +export class RelationMetadataResolver { + constructor( + private readonly relationMetadataService: RelationMetadataService, + ) {} + + @Mutation(() => RelationMetadataDTO) + deleteOneRelation( + @Args('input') input: DeleteOneRelationInput, + @AuthWorkspace() { id: workspaceId }: Workspace, + ) { + return this.relationMetadataService.deleteOneRelation( + input.id, + workspaceId, + ); + } +} diff --git a/packages/twenty-server/src/engine/metadata-modules/relation-metadata/relation-metadata.service.ts b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/relation-metadata.service.ts index eef856794a4..f885c0e5667 100644 --- a/packages/twenty-server/src/engine/metadata-modules/relation-metadata/relation-metadata.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/relation-metadata.service.ts @@ -26,6 +26,7 @@ import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util'; import { InvalidStringException } from 'src/engine/metadata-modules/errors/InvalidStringException'; import { validateMetadataName } from 'src/engine/metadata-modules/utils/validate-metadata-name.utils'; +import { WorkspaceCacheVersionService } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service'; import { RelationMetadataEntity, @@ -42,6 +43,7 @@ export class RelationMetadataService extends TypeOrmQueryService { + public async deleteOneRelation( + id: string, + workspaceId: string, + ): Promise { // TODO: This logic is duplicated with the BeforeDeleteOneRelation hook const relationMetadata = await this.relationMetadataRepository.findOne({ where: { id }, @@ -318,10 +327,10 @@ export class RelationMetadataService extends TypeOrmQueryService