From 347e855b1fc6ae2c3cd28885f8e63c9fc07f1d0f Mon Sep 17 00:00:00 2001 From: neo773 <62795688+neo773@users.noreply.github.com> Date: Tue, 18 Nov 2025 21:29:15 +0530 Subject: [PATCH] update default message folder import policy to ALL_FOLDERS (#15858) --- .../message-channel.workspace-entity.ts | 2 +- .../message-folder-query-hook.module.ts | 9 ++ ...essage-folder-update-one.pre-query.hook.ts | 103 ++++++++++++++++++ .../src/modules/messaging/messaging.module.ts | 2 + 4 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 packages/twenty-server/src/modules/messaging/message-folder-manager/query-hooks/message-folder-query-hook.module.ts create mode 100644 packages/twenty-server/src/modules/messaging/message-folder-manager/query-hooks/message-folder-update-one.pre-query.hook.ts diff --git a/packages/twenty-server/src/modules/messaging/common/standard-objects/message-channel.workspace-entity.ts b/packages/twenty-server/src/modules/messaging/common/standard-objects/message-channel.workspace-entity.ts index 081d0af3f2..3fbe66fccc 100644 --- a/packages/twenty-server/src/modules/messaging/common/standard-objects/message-channel.workspace-entity.ts +++ b/packages/twenty-server/src/modules/messaging/common/standard-objects/message-channel.workspace-entity.ts @@ -233,7 +233,7 @@ export class MessageChannelWorkspaceEntity extends BaseWorkspaceEntity { color: 'blue', }, ], - defaultValue: `'${MessageFolderImportPolicy.SELECTED_FOLDERS}'`, + defaultValue: `'${MessageFolderImportPolicy.ALL_FOLDERS}'`, }) messageFolderImportPolicy: MessageFolderImportPolicy; diff --git a/packages/twenty-server/src/modules/messaging/message-folder-manager/query-hooks/message-folder-query-hook.module.ts b/packages/twenty-server/src/modules/messaging/message-folder-manager/query-hooks/message-folder-query-hook.module.ts new file mode 100644 index 0000000000..a28e074ec4 --- /dev/null +++ b/packages/twenty-server/src/modules/messaging/message-folder-manager/query-hooks/message-folder-query-hook.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; + +import { MessageFolderUpdateOnePreQueryHook } from 'src/modules/messaging/message-folder-manager/query-hooks/message-folder-update-one.pre-query.hook'; + +@Module({ + providers: [MessageFolderUpdateOnePreQueryHook], + exports: [MessageFolderUpdateOnePreQueryHook], +}) +export class MessageFolderQueryHookModule {} diff --git a/packages/twenty-server/src/modules/messaging/message-folder-manager/query-hooks/message-folder-update-one.pre-query.hook.ts b/packages/twenty-server/src/modules/messaging/message-folder-manager/query-hooks/message-folder-update-one.pre-query.hook.ts new file mode 100644 index 0000000000..57679e6744 --- /dev/null +++ b/packages/twenty-server/src/modules/messaging/message-folder-manager/query-hooks/message-folder-update-one.pre-query.hook.ts @@ -0,0 +1,103 @@ +import { msg } from '@lingui/core/macro'; +import { isNumber } from '@sniptt/guards'; +import { assertIsDefinedOrThrow, isDefined } from 'twenty-shared/utils'; + +import { type WorkspacePreQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface'; +import { type UpdateOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; + +import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator'; +import { + WorkspaceQueryRunnerException, + WorkspaceQueryRunnerExceptionCode, +} from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.exception'; +import { type AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type'; +import { WorkspaceNotFoundDefaultError } from 'src/engine/core-modules/workspace/workspace.exception'; +import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; +import { + MessageFolderImportPolicy, + type MessageChannelWorkspaceEntity, +} from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity'; +import { type MessageFolderWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-folder.workspace-entity'; + +@WorkspaceQueryHook(`messageFolder.updateOne`) +export class MessageFolderUpdateOnePreQueryHook + implements WorkspacePreQueryHookInstance +{ + constructor( + private readonly twentyORMGlobalManager: TwentyORMGlobalManager, + ) {} + + async execute( + authContext: AuthContext, + _objectName: string, + payload: UpdateOneResolverArgs, + ): Promise> { + const workspace = authContext.workspace; + + assertIsDefinedOrThrow(workspace, WorkspaceNotFoundDefaultError); + + const messageFolderRepository = + await this.twentyORMGlobalManager.getRepositoryForWorkspace( + workspace.id, + 'messageFolder', + ); + + const messageFolder = await messageFolderRepository.findOne({ + where: { id: payload.id }, + }); + + if (!messageFolder) { + throw new WorkspaceQueryRunnerException( + 'Message folder not found', + WorkspaceQueryRunnerExceptionCode.DATA_NOT_FOUND, + { + userFriendlyMessage: msg`Message folder not found`, + }, + ); + } + + if (payload.data.isSynced !== false) { + return payload; + } + + const messageChannelRepository = + await this.twentyORMGlobalManager.getRepositoryForWorkspace( + workspace.id, + 'messageChannel', + ); + + const messageChannel = await messageChannelRepository.findOne({ + where: { id: messageFolder.messageChannelId }, + }); + + if ( + messageChannel?.messageFolderImportPolicy !== + MessageFolderImportPolicy.SELECTED_FOLDERS + ) { + return payload; + } + + const syncedFoldersCount = await messageFolderRepository.count({ + where: { + messageChannelId: messageFolder.messageChannelId, + isSynced: true, + }, + }); + + if ( + isDefined(syncedFoldersCount) && + isNumber(syncedFoldersCount) && + syncedFoldersCount <= 1 + ) { + throw new WorkspaceQueryRunnerException( + 'Cannot unsync the last folder when folder import policy is set to selected folders', + WorkspaceQueryRunnerExceptionCode.INVALID_QUERY_INPUT, + { + userFriendlyMessage: msg`At least one folder must be synced.`, + }, + ); + } + + return payload; + } +} diff --git a/packages/twenty-server/src/modules/messaging/messaging.module.ts b/packages/twenty-server/src/modules/messaging/messaging.module.ts index afc27cf2f2..50c605f369 100644 --- a/packages/twenty-server/src/modules/messaging/messaging.module.ts +++ b/packages/twenty-server/src/modules/messaging/messaging.module.ts @@ -3,6 +3,7 @@ import { Module } from '@nestjs/common'; import { MessagingBlocklistManagerModule } from 'src/modules/messaging/blocklist-manager/messaging-blocklist-manager.module'; import { MessageChannelQueryHookModule } from 'src/modules/messaging/message-channel-manager/query-hooks/message-channel-query-hook.module'; import { MessagingMessageCleanerModule } from 'src/modules/messaging/message-cleaner/messaging-message-cleaner.module'; +import { MessageFolderQueryHookModule } from 'src/modules/messaging/message-folder-manager/query-hooks/message-folder-query-hook.module'; import { MessagingImportManagerModule } from 'src/modules/messaging/message-import-manager/messaging-import-manager.module'; import { MessageParticipantManagerModule } from 'src/modules/messaging/message-participant-manager/message-participant-manager.module'; import { MessagingMonitoringModule } from 'src/modules/messaging/monitoring/messaging-monitoring.module'; @@ -15,6 +16,7 @@ import { MessagingMonitoringModule } from 'src/modules/messaging/monitoring/mess MessagingBlocklistManagerModule, MessagingMonitoringModule, MessageChannelQueryHookModule, + MessageFolderQueryHookModule, ], providers: [], exports: [MessagingImportManagerModule],