From 04502e5abb890f3958471760d27ff5a1b395d53c Mon Sep 17 00:00:00 2001 From: neo773 <62795688+neo773@users.noreply.github.com> Date: Thu, 19 Feb 2026 03:43:47 +0530 Subject: [PATCH] Messages Message Folder Association (#17398) This PR adds Message folder association for message channel messages, Currently under testing phase, not ready yet. --------- Co-authored-by: Claude Opus 4.6 --- CLAUDE.md | 2 + ...sage-association-message-folder.command.ts | 188 ++ .../1-19-upgrade-version-command.module.ts | 22 + .../upgrade-version-command.module.ts | 2 + .../upgrade.command.ts | 9 + .../engine/core-modules/auth/auth.module.ts | 4 +- ...adata-related-entity-ids.util.spec.ts.snap | 1692 +++++++++-------- ...-standard-flat-field-metadata-maps.util.ts | 3 + ...older-standard-flat-field-metadata.util.ts | 159 ++ ...ation-standard-flat-field-metadata.util.ts | 23 + ...older-standard-flat-field-metadata.util.ts | 25 + ...-standard-flat-index-metadata-maps.util.ts | 3 + ...older-standard-flat-index-metadata.util.ts | 66 + ...eate-standard-flat-object-metadata.util.ts | 33 + ...ciation-message-folder.workspace-entity.ts | 11 + ...el-message-association.workspace-entity.ts | 4 + .../message-folder.workspace-entity.ts | 4 + .../parse-and-format-gmail-message.util.ts | 1 + .../services/imap-get-messages.service.ts | 22 +- .../services/imap-message-parser.service.ts | 21 +- .../microsoft-get-messages.service.spec.ts | 9 + .../microsoft-get-messages.service.ts | 5 +- .../messaging-import-manager.module.ts | 2 + ...essaging-delete-folder-messages.service.ts | 97 +- .../messaging-get-message-list.service.ts | 2 +- ...ging-message-folder-association.service.ts | 85 + .../services/messaging-message.service.ts | 26 +- .../messaging-messages-import.service.ts | 19 + ...d-enqueue-contact-creation.service.spec.ts | 9 + ...es-and-enqueue-contact-creation.service.ts | 53 +- .../message-import-manager/types/message.ts | 3 + .../src/metadata/standard-object.constant.ts | 40 + 32 files changed, 1760 insertions(+), 884 deletions(-) create mode 100644 packages/twenty-server/src/database/commands/upgrade-version-command/1-19/1-19-backfill-message-channel-message-association-message-folder.command.ts create mode 100644 packages/twenty-server/src/database/commands/upgrade-version-command/1-19/1-19-upgrade-version-command.module.ts create mode 100644 packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/compute-message-channel-message-association-message-folder-standard-flat-field-metadata.util.ts create mode 100644 packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/index/compute-message-channel-message-association-message-folder-standard-flat-index-metadata.util.ts create mode 100644 packages/twenty-server/src/modules/messaging/common/standard-objects/message-channel-message-association-message-folder.workspace-entity.ts create mode 100644 packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-message-folder-association.service.ts diff --git a/CLAUDE.md b/CLAUDE.md index 520f33036d..97047e7b7c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -28,6 +28,8 @@ npx jest path/to/test.test.ts --config=packages/PROJECT/jest.config.mjs npx nx test twenty-front # Frontend unit tests npx nx test twenty-server # Backend unit tests npx nx run twenty-server:test:integration:with-db-reset # Integration tests with DB reset +# To run an indivual test or a pattern of tests, use the following command: +cd packages/{workspace} && npx jest "pattern or filename" # Storybook npx nx storybook:build twenty-front diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-19/1-19-backfill-message-channel-message-association-message-folder.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-19/1-19-backfill-message-channel-message-association-message-folder.command.ts new file mode 100644 index 0000000000..79aebabb5d --- /dev/null +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-19/1-19-backfill-message-channel-message-association-message-folder.command.ts @@ -0,0 +1,188 @@ +import { InjectRepository } from '@nestjs/typeorm'; + +import { Command } from 'nest-commander'; +import { STANDARD_OBJECTS } from 'twenty-shared/metadata'; +import { isDefined } from 'twenty-shared/utils'; +import { Repository } from 'typeorm'; + +import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; +import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; +import { ApplicationService } from 'src/engine/core-modules/application/services/application.service'; +import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; +import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; +import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; +import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util'; +import { findFlatEntityByUniversalIdentifier } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util'; +import { getSubFlatEntityMapsByApplicationIdsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-by-application-ids-or-throw.util'; +import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; +import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; +import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; +import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service'; +import { computeTwentyStandardApplicationAllFlatEntityMaps } from 'src/engine/workspace-manager/twenty-standard-application/utils/twenty-standard-application-all-flat-entity-maps.constant'; +import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service'; + +@Command({ + name: 'upgrade:1-19:backfill-message-channel-message-association-message-folder', + description: + 'Backfill messageChannelMessageAssociationMessageFolder standard object and its relation fields', +}) +export class BackfillMessageChannelMessageAssociationMessageFolderCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { + constructor( + @InjectRepository(WorkspaceEntity) + protected readonly workspaceRepository: Repository, + protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, + protected readonly dataSourceService: DataSourceService, + private readonly applicationService: ApplicationService, + private readonly workspaceCacheService: WorkspaceCacheService, + private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService, + ) { + super(workspaceRepository, twentyORMGlobalManager, dataSourceService); + } + + private addNewEntitiesToFlatEntityMaps({ + fromMaps, + standardBuilderMaps, + }: { + fromMaps: FlatEntityMaps; + standardBuilderMaps: FlatEntityMaps; + }): FlatEntityMaps { + let toMaps = fromMaps; + + for (const [universalIdentifier, entity] of Object.entries( + standardBuilderMaps.byUniversalIdentifier, + )) { + if ( + !isDefined(entity) || + isDefined(fromMaps.byUniversalIdentifier[universalIdentifier]) + ) { + continue; + } + + toMaps = addFlatEntityToFlatEntityMapsOrThrow({ + flatEntity: entity, + flatEntityMaps: toMaps, + }); + } + + return toMaps; + } + + override async runOnWorkspace({ + workspaceId, + options, + }: RunOnWorkspaceArgs): Promise { + const isDryRun = options.dryRun ?? false; + + this.logger.log( + `${isDryRun ? '[DRY RUN] ' : ''}Starting backfill of messageChannelMessageAssociationMessageFolder for workspace ${workspaceId}`, + ); + + const { flatObjectMetadataMaps, flatFieldMetadataMaps, featureFlagsMap } = + await this.workspaceCacheService.getOrRecompute(workspaceId, [ + 'flatObjectMetadataMaps', + 'flatFieldMetadataMaps', + 'featureFlagsMap', + ]); + + const existingObject = findFlatEntityByUniversalIdentifier({ + flatEntityMaps: flatObjectMetadataMaps, + universalIdentifier: + STANDARD_OBJECTS.messageChannelMessageAssociationMessageFolder + .universalIdentifier, + }); + + if (existingObject) { + this.logger.log( + `messageChannelMessageAssociationMessageFolder object already exists for workspace ${workspaceId}, skipping`, + ); + + return; + } + + if (isDryRun) { + this.logger.log( + `[DRY RUN] Would create messageChannelMessageAssociationMessageFolder object and relation fields for workspace ${workspaceId}`, + ); + + return; + } + + const { twentyStandardFlatApplication } = + await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow( + { workspaceId }, + ); + + const fromFlatObjectMetadataMaps = + getSubFlatEntityMapsByApplicationIdsOrThrow({ + applicationIds: [twentyStandardFlatApplication.id], + flatEntityMaps: flatObjectMetadataMaps, + }); + + const fromFlatFieldMetadataMaps = + getSubFlatEntityMapsByApplicationIdsOrThrow({ + applicationIds: [twentyStandardFlatApplication.id], + flatEntityMaps: flatFieldMetadataMaps, + }); + + const { + allFlatEntityMaps: standardAllFlatEntityMaps, + idByUniversalIdentifierByMetadataName, + } = computeTwentyStandardApplicationAllFlatEntityMaps({ + now: new Date().toISOString(), + workspaceId, + twentyStandardApplicationId: twentyStandardFlatApplication.id, + }); + + const toFlatObjectMetadataMaps = + this.addNewEntitiesToFlatEntityMaps({ + fromMaps: fromFlatObjectMetadataMaps, + standardBuilderMaps: standardAllFlatEntityMaps.flatObjectMetadataMaps, + }); + + const toFlatFieldMetadataMaps = + this.addNewEntitiesToFlatEntityMaps({ + fromMaps: fromFlatFieldMetadataMaps, + standardBuilderMaps: standardAllFlatEntityMaps.flatFieldMetadataMaps, + }); + + const validateAndBuildResult = + await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigrationFromTo( + { + buildOptions: { + isSystemBuild: true, + }, + fromToAllFlatEntityMaps: { + flatObjectMetadataMaps: { + from: fromFlatObjectMetadataMaps, + to: toFlatObjectMetadataMaps, + }, + flatFieldMetadataMaps: { + from: fromFlatFieldMetadataMaps, + to: toFlatFieldMetadataMaps, + }, + }, + workspaceId, + additionalCacheDataMaps: { + featureFlagsMap, + }, + applicationUniversalIdentifier: + twentyStandardFlatApplication.universalIdentifier, + idByUniversalIdentifierByMetadataName, + }, + ); + + if (isDefined(validateAndBuildResult)) { + this.logger.error( + `Failed to create messageChannelMessageAssociationMessageFolder:\n${JSON.stringify(validateAndBuildResult, null, 2)}`, + ); + throw new Error( + `Failed to create messageChannelMessageAssociationMessageFolder for workspace ${workspaceId}`, + ); + } + + this.logger.log( + `Successfully created messageChannelMessageAssociationMessageFolder for workspace ${workspaceId}`, + ); + } +} diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-19/1-19-upgrade-version-command.module.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-19/1-19-upgrade-version-command.module.ts new file mode 100644 index 0000000000..8fa48b35b1 --- /dev/null +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-19/1-19-upgrade-version-command.module.ts @@ -0,0 +1,22 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; + +import { BackfillMessageChannelMessageAssociationMessageFolderCommand } from 'src/database/commands/upgrade-version-command/1-19/1-19-backfill-message-channel-message-association-message-folder.command'; +import { ApplicationModule } from 'src/engine/core-modules/application/application.module'; +import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; +import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; +import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module'; +import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([WorkspaceEntity]), + DataSourceModule, + WorkspaceCacheModule, + ApplicationModule, + WorkspaceMigrationModule, + ], + providers: [BackfillMessageChannelMessageAssociationMessageFolderCommand], + exports: [BackfillMessageChannelMessageAssociationMessageFolderCommand], +}) +export class V1_19_UpgradeVersionCommandModule {} diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade-version-command.module.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade-version-command.module.ts index 20f05bdc83..6b39d0e744 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade-version-command.module.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade-version-command.module.ts @@ -3,6 +3,7 @@ import { TypeOrmModule } from '@nestjs/typeorm'; import { V1_17_UpgradeVersionCommandModule } from 'src/database/commands/upgrade-version-command/1-17/1-17-upgrade-version-command.module'; import { V1_18_UpgradeVersionCommandModule } from 'src/database/commands/upgrade-version-command/1-18/1-18-upgrade-version-command.module'; +import { V1_19_UpgradeVersionCommandModule } from 'src/database/commands/upgrade-version-command/1-19/1-19-upgrade-version-command.module'; import { UpgradeCommand } from 'src/database/commands/upgrade-version-command/upgrade.command'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; @@ -12,6 +13,7 @@ import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-s TypeOrmModule.forFeature([WorkspaceEntity]), V1_17_UpgradeVersionCommandModule, V1_18_UpgradeVersionCommandModule, + V1_19_UpgradeVersionCommandModule, DataSourceModule, ], providers: [UpgradeCommand], diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade.command.ts index 33d535f35f..5d5af01bd0 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade.command.ts @@ -27,6 +27,7 @@ import { MigrateFavoritesToNavigationMenuItemsCommand } from 'src/database/comma import { MigratePersonAvatarFilesCommand } from 'src/database/commands/upgrade-version-command/1-18/1-18-migrate-person-avatar-files.command'; import { MigrateWorkflowSendEmailAttachmentsCommand } from 'src/database/commands/upgrade-version-command/1-18/1-18-migrate-workflow-send-email-attachments.command'; import { MigrateWorkspacePicturesCommand } from 'src/database/commands/upgrade-version-command/1-18/1-18-migrate-workspace-pictures.command'; +import { BackfillMessageChannelMessageAssociationMessageFolderCommand } from 'src/database/commands/upgrade-version-command/1-19/1-19-backfill-message-channel-message-association-message-folder.command'; import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; @@ -67,6 +68,9 @@ export class UpgradeCommand extends UpgradeCommandRunner { protected readonly backfillStandardViewsAndFieldMetadataCommand: BackfillStandardViewsAndFieldMetadataCommand, protected readonly migrateWorkspacePicturesCommand: MigrateWorkspacePicturesCommand, protected readonly migrateWorkflowSendEmailAttachmentsCommand: MigrateWorkflowSendEmailAttachmentsCommand, + + // 1.19 Commands + protected readonly backfillMessageChannelMessageAssociationMessageFolderCommand: BackfillMessageChannelMessageAssociationMessageFolderCommand, ) { super( workspaceRepository, @@ -103,10 +107,15 @@ export class UpgradeCommand extends UpgradeCommandRunner { this.backfillStandardViewsAndFieldMetadataCommand, ]; + const commands_1190: VersionCommands = [ + this.backfillMessageChannelMessageAssociationMessageFolderCommand, + ]; + this.allCommands = { '1.16.0': commands_1160, '1.17.0': commands_1170, '1.18.0': commands_1180, + '1.19.0': commands_1190, }; } diff --git a/packages/twenty-server/src/engine/core-modules/auth/auth.module.ts b/packages/twenty-server/src/engine/core-modules/auth/auth.module.ts index 9d160d6204..29a7fad53d 100644 --- a/packages/twenty-server/src/engine/core-modules/auth/auth.module.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/auth.module.ts @@ -65,7 +65,7 @@ import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/works import { WorkspaceManagerModule } from 'src/engine/workspace-manager/workspace-manager.module'; import { CalendarChannelSyncStatusService } from 'src/modules/calendar/common/services/calendar-channel-sync-status.service'; import { ConnectedAccountModule } from 'src/modules/connected-account/connected-account.module'; -import { MessageChannelSyncStatusService } from 'src/modules/messaging/common/services/message-channel-sync-status.service'; +import { MessagingCommonModule } from 'src/modules/messaging/common/messaging-common.module'; import { MessagingFolderSyncManagerModule } from 'src/modules/messaging/message-folder-manager/messaging-folder-sync-manager.module'; import { AuthResolver } from './auth.resolver'; @@ -101,6 +101,7 @@ import { JwtAuthStrategy } from './strategies/jwt.auth.strategy'; OnboardingModule, WorkspaceDataSourceModule, ConnectedAccountModule, + MessagingCommonModule, MessagingFolderSyncManagerModule, WorkspaceSSOModule, FeatureFlagModule, @@ -145,7 +146,6 @@ import { JwtAuthStrategy } from './strategies/jwt.auth.strategy'; // So far, it's not possible to have controllers in business modules // which forces us to have these services in the auth module // TODO: Move these calendar, message, and connected account services to the business modules once possible - MessageChannelSyncStatusService, CalendarChannelSyncStatusService, CreateMessageChannelService, CreateCalendarChannelService, diff --git a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/__tests__/__snapshots__/get-standard-object-metadata-related-entity-ids.util.spec.ts.snap b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/__tests__/__snapshots__/get-standard-object-metadata-related-entity-ids.util.spec.ts.snap index 92119e6d5f..8bc85f4d4c 100644 --- a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/__tests__/__snapshots__/get-standard-object-metadata-related-entity-ids.util.spec.ts.snap +++ b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/__tests__/__snapshots__/get-standard-object-metadata-related-entity-ids.util.spec.ts.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`getStandardObjectMetadataRelatedEntityIds should return standard object metadata related entity ids 1`] = ` { @@ -708,68 +708,68 @@ exports[`getStandardObjectMetadataRelatedEntityIds should return standard object "message": { "fields": { "createdAt": { - "id": "00000000-0000-0000-0000-000000000287", - }, - "deletedAt": { - "id": "00000000-0000-0000-0000-000000000289", - }, - "direction": { - "id": "00000000-0000-0000-0000-000000000292", - }, - "headerMessageId": { - "id": "00000000-0000-0000-0000-000000000290", - }, - "id": { - "id": "00000000-0000-0000-0000-000000000286", - }, - "messageChannelMessageAssociations": { - "id": "00000000-0000-0000-0000-000000000297", - }, - "messageParticipants": { "id": "00000000-0000-0000-0000-000000000296", }, - "messageThread": { - "id": "00000000-0000-0000-0000-000000000291", + "deletedAt": { + "id": "00000000-0000-0000-0000-000000000298", }, - "receivedAt": { + "direction": { + "id": "00000000-0000-0000-0000-000000000301", + }, + "headerMessageId": { + "id": "00000000-0000-0000-0000-000000000299", + }, + "id": { "id": "00000000-0000-0000-0000-000000000295", }, + "messageChannelMessageAssociations": { + "id": "00000000-0000-0000-0000-000000000306", + }, + "messageParticipants": { + "id": "00000000-0000-0000-0000-000000000305", + }, + "messageThread": { + "id": "00000000-0000-0000-0000-000000000300", + }, + "receivedAt": { + "id": "00000000-0000-0000-0000-000000000304", + }, "subject": { - "id": "00000000-0000-0000-0000-000000000293", + "id": "00000000-0000-0000-0000-000000000302", }, "text": { - "id": "00000000-0000-0000-0000-000000000294", + "id": "00000000-0000-0000-0000-000000000303", }, "updatedAt": { - "id": "00000000-0000-0000-0000-000000000288", + "id": "00000000-0000-0000-0000-000000000297", }, }, - "id": "00000000-0000-0000-0000-000000000306", + "id": "00000000-0000-0000-0000-000000000315", "views": { "allMessages": { - "id": "00000000-0000-0000-0000-000000000305", + "id": "00000000-0000-0000-0000-000000000314", "viewFieldGroups": {}, "viewFields": { "createdAt": { - "id": "00000000-0000-0000-0000-000000000304", + "id": "00000000-0000-0000-0000-000000000313", }, "headerMessageId": { - "id": "00000000-0000-0000-0000-000000000302", + "id": "00000000-0000-0000-0000-000000000311", }, "messageParticipants": { - "id": "00000000-0000-0000-0000-000000000300", + "id": "00000000-0000-0000-0000-000000000309", }, "messageThread": { - "id": "00000000-0000-0000-0000-000000000299", + "id": "00000000-0000-0000-0000-000000000308", }, "receivedAt": { - "id": "00000000-0000-0000-0000-000000000301", + "id": "00000000-0000-0000-0000-000000000310", }, "subject": { - "id": "00000000-0000-0000-0000-000000000298", + "id": "00000000-0000-0000-0000-000000000307", }, "text": { - "id": "00000000-0000-0000-0000-000000000303", + "id": "00000000-0000-0000-0000-000000000312", }, }, "viewGroups": {}, @@ -779,79 +779,79 @@ exports[`getStandardObjectMetadataRelatedEntityIds should return standard object "messageChannel": { "fields": { "connectedAccount": { - "id": "00000000-0000-0000-0000-000000000233", - }, - "contactAutoCreationPolicy": { - "id": "00000000-0000-0000-0000-000000000236", - }, - "createdAt": { - "id": "00000000-0000-0000-0000-000000000228", - }, - "deletedAt": { - "id": "00000000-0000-0000-0000-000000000230", - }, - "excludeGroupEmails": { - "id": "00000000-0000-0000-0000-000000000238", - }, - "excludeNonProfessionalEmails": { - "id": "00000000-0000-0000-0000-000000000237", - }, - "handle": { - "id": "00000000-0000-0000-0000-000000000232", - }, - "id": { - "id": "00000000-0000-0000-0000-000000000227", - }, - "isContactAutoCreationEnabled": { - "id": "00000000-0000-0000-0000-000000000235", - }, - "isSyncEnabled": { - "id": "00000000-0000-0000-0000-000000000243", - }, - "messageChannelMessageAssociations": { - "id": "00000000-0000-0000-0000-000000000239", - }, - "messageFolderImportPolicy": { "id": "00000000-0000-0000-0000-000000000241", }, - "messageFolders": { - "id": "00000000-0000-0000-0000-000000000240", - }, - "pendingGroupEmailsAction": { - "id": "00000000-0000-0000-0000-000000000242", - }, - "syncCursor": { + "contactAutoCreationPolicy": { "id": "00000000-0000-0000-0000-000000000244", }, - "syncStage": { - "id": "00000000-0000-0000-0000-000000000247", + "createdAt": { + "id": "00000000-0000-0000-0000-000000000236", }, - "syncStageStartedAt": { - "id": "00000000-0000-0000-0000-000000000248", + "deletedAt": { + "id": "00000000-0000-0000-0000-000000000238", }, - "syncStatus": { + "excludeGroupEmails": { "id": "00000000-0000-0000-0000-000000000246", }, - "syncedAt": { + "excludeNonProfessionalEmails": { "id": "00000000-0000-0000-0000-000000000245", }, - "throttleFailureCount": { + "handle": { + "id": "00000000-0000-0000-0000-000000000240", + }, + "id": { + "id": "00000000-0000-0000-0000-000000000235", + }, + "isContactAutoCreationEnabled": { + "id": "00000000-0000-0000-0000-000000000243", + }, + "isSyncEnabled": { + "id": "00000000-0000-0000-0000-000000000251", + }, + "messageChannelMessageAssociations": { + "id": "00000000-0000-0000-0000-000000000247", + }, + "messageFolderImportPolicy": { "id": "00000000-0000-0000-0000-000000000249", }, - "throttleRetryAfter": { + "messageFolders": { + "id": "00000000-0000-0000-0000-000000000248", + }, + "pendingGroupEmailsAction": { "id": "00000000-0000-0000-0000-000000000250", }, + "syncCursor": { + "id": "00000000-0000-0000-0000-000000000252", + }, + "syncStage": { + "id": "00000000-0000-0000-0000-000000000255", + }, + "syncStageStartedAt": { + "id": "00000000-0000-0000-0000-000000000256", + }, + "syncStatus": { + "id": "00000000-0000-0000-0000-000000000254", + }, + "syncedAt": { + "id": "00000000-0000-0000-0000-000000000253", + }, + "throttleFailureCount": { + "id": "00000000-0000-0000-0000-000000000257", + }, + "throttleRetryAfter": { + "id": "00000000-0000-0000-0000-000000000258", + }, "type": { - "id": "00000000-0000-0000-0000-000000000234", + "id": "00000000-0000-0000-0000-000000000242", }, "updatedAt": { - "id": "00000000-0000-0000-0000-000000000229", + "id": "00000000-0000-0000-0000-000000000237", }, "visibility": { - "id": "00000000-0000-0000-0000-000000000231", + "id": "00000000-0000-0000-0000-000000000239", }, }, - "id": "00000000-0000-0000-0000-000000000251", + "id": "00000000-0000-0000-0000-000000000259", "views": undefined, }, "messageChannelMessageAssociation": { @@ -877,6 +877,9 @@ exports[`getStandardObjectMetadataRelatedEntityIds should return standard object "messageExternalId": { "id": "00000000-0000-0000-0000-000000000222", }, + "messageFolders": { + "id": "00000000-0000-0000-0000-000000000226", + }, "messageThread": { "id": "00000000-0000-0000-0000-000000000223", }, @@ -887,119 +890,146 @@ exports[`getStandardObjectMetadataRelatedEntityIds should return standard object "id": "00000000-0000-0000-0000-000000000218", }, }, - "id": "00000000-0000-0000-0000-000000000226", + "id": "00000000-0000-0000-0000-000000000227", + "views": undefined, + }, + "messageChannelMessageAssociationMessageFolder": { + "fields": { + "createdAt": { + "id": "00000000-0000-0000-0000-000000000229", + }, + "deletedAt": { + "id": "00000000-0000-0000-0000-000000000231", + }, + "id": { + "id": "00000000-0000-0000-0000-000000000228", + }, + "messageChannelMessageAssociation": { + "id": "00000000-0000-0000-0000-000000000232", + }, + "messageFolder": { + "id": "00000000-0000-0000-0000-000000000233", + }, + "updatedAt": { + "id": "00000000-0000-0000-0000-000000000230", + }, + }, + "id": "00000000-0000-0000-0000-000000000234", "views": undefined, }, "messageFolder": { "fields": { "createdAt": { - "id": "00000000-0000-0000-0000-000000000253", - }, - "deletedAt": { - "id": "00000000-0000-0000-0000-000000000255", - }, - "externalId": { - "id": "00000000-0000-0000-0000-000000000262", - }, - "id": { - "id": "00000000-0000-0000-0000-000000000252", - }, - "isSentFolder": { - "id": "00000000-0000-0000-0000-000000000260", - }, - "isSynced": { "id": "00000000-0000-0000-0000-000000000261", }, - "messageChannel": { - "id": "00000000-0000-0000-0000-000000000258", - }, - "name": { - "id": "00000000-0000-0000-0000-000000000256", - }, - "parentFolderId": { - "id": "00000000-0000-0000-0000-000000000257", - }, - "pendingSyncAction": { + "deletedAt": { "id": "00000000-0000-0000-0000-000000000263", }, + "externalId": { + "id": "00000000-0000-0000-0000-000000000270", + }, + "id": { + "id": "00000000-0000-0000-0000-000000000260", + }, + "isSentFolder": { + "id": "00000000-0000-0000-0000-000000000268", + }, + "isSynced": { + "id": "00000000-0000-0000-0000-000000000269", + }, + "messageChannel": { + "id": "00000000-0000-0000-0000-000000000266", + }, + "messageChannelMessageAssociationMessageFolders": { + "id": "00000000-0000-0000-0000-000000000272", + }, + "name": { + "id": "00000000-0000-0000-0000-000000000264", + }, + "parentFolderId": { + "id": "00000000-0000-0000-0000-000000000265", + }, + "pendingSyncAction": { + "id": "00000000-0000-0000-0000-000000000271", + }, "syncCursor": { - "id": "00000000-0000-0000-0000-000000000259", + "id": "00000000-0000-0000-0000-000000000267", }, "updatedAt": { - "id": "00000000-0000-0000-0000-000000000254", + "id": "00000000-0000-0000-0000-000000000262", }, }, - "id": "00000000-0000-0000-0000-000000000264", + "id": "00000000-0000-0000-0000-000000000273", "views": undefined, }, "messageParticipant": { "fields": { "createdAt": { - "id": "00000000-0000-0000-0000-000000000266", + "id": "00000000-0000-0000-0000-000000000275", }, "deletedAt": { - "id": "00000000-0000-0000-0000-000000000268", + "id": "00000000-0000-0000-0000-000000000277", }, "displayName": { - "id": "00000000-0000-0000-0000-000000000272", + "id": "00000000-0000-0000-0000-000000000281", }, "handle": { - "id": "00000000-0000-0000-0000-000000000271", + "id": "00000000-0000-0000-0000-000000000280", }, "id": { - "id": "00000000-0000-0000-0000-000000000265", - }, - "message": { - "id": "00000000-0000-0000-0000-000000000269", - }, - "person": { - "id": "00000000-0000-0000-0000-000000000273", - }, - "role": { - "id": "00000000-0000-0000-0000-000000000270", - }, - "updatedAt": { - "id": "00000000-0000-0000-0000-000000000267", - }, - "workspaceMember": { "id": "00000000-0000-0000-0000-000000000274", }, + "message": { + "id": "00000000-0000-0000-0000-000000000278", + }, + "person": { + "id": "00000000-0000-0000-0000-000000000282", + }, + "role": { + "id": "00000000-0000-0000-0000-000000000279", + }, + "updatedAt": { + "id": "00000000-0000-0000-0000-000000000276", + }, + "workspaceMember": { + "id": "00000000-0000-0000-0000-000000000283", + }, }, - "id": "00000000-0000-0000-0000-000000000275", + "id": "00000000-0000-0000-0000-000000000284", "views": undefined, }, "messageThread": { "fields": { "createdAt": { - "id": "00000000-0000-0000-0000-000000000277", + "id": "00000000-0000-0000-0000-000000000286", }, "deletedAt": { - "id": "00000000-0000-0000-0000-000000000279", + "id": "00000000-0000-0000-0000-000000000288", }, "id": { - "id": "00000000-0000-0000-0000-000000000276", + "id": "00000000-0000-0000-0000-000000000285", }, "messageChannelMessageAssociations": { - "id": "00000000-0000-0000-0000-000000000281", + "id": "00000000-0000-0000-0000-000000000290", }, "messages": { - "id": "00000000-0000-0000-0000-000000000280", + "id": "00000000-0000-0000-0000-000000000289", }, "updatedAt": { - "id": "00000000-0000-0000-0000-000000000278", + "id": "00000000-0000-0000-0000-000000000287", }, }, - "id": "00000000-0000-0000-0000-000000000285", + "id": "00000000-0000-0000-0000-000000000294", "views": { "allMessageThreads": { - "id": "00000000-0000-0000-0000-000000000284", + "id": "00000000-0000-0000-0000-000000000293", "viewFieldGroups": {}, "viewFields": { "createdAt": { - "id": "00000000-0000-0000-0000-000000000283", + "id": "00000000-0000-0000-0000-000000000292", }, "messages": { - "id": "00000000-0000-0000-0000-000000000282", + "id": "00000000-0000-0000-0000-000000000291", }, }, "viewGroups": {}, @@ -1009,94 +1039,94 @@ exports[`getStandardObjectMetadataRelatedEntityIds should return standard object "note": { "fields": { "attachments": { - "id": "00000000-0000-0000-0000-000000000317", + "id": "00000000-0000-0000-0000-000000000326", }, "bodyV2": { - "id": "00000000-0000-0000-0000-000000000313", + "id": "00000000-0000-0000-0000-000000000322", }, "createdAt": { - "id": "00000000-0000-0000-0000-000000000308", + "id": "00000000-0000-0000-0000-000000000317", }, "createdBy": { - "id": "00000000-0000-0000-0000-000000000314", + "id": "00000000-0000-0000-0000-000000000323", }, "deletedAt": { - "id": "00000000-0000-0000-0000-000000000310", - }, - "favorites": { "id": "00000000-0000-0000-0000-000000000319", }, - "id": { - "id": "00000000-0000-0000-0000-000000000307", + "favorites": { + "id": "00000000-0000-0000-0000-000000000328", }, - "noteTargets": { + "id": { "id": "00000000-0000-0000-0000-000000000316", }, - "position": { - "id": "00000000-0000-0000-0000-000000000311", + "noteTargets": { + "id": "00000000-0000-0000-0000-000000000325", }, - "searchVector": { + "position": { "id": "00000000-0000-0000-0000-000000000320", }, + "searchVector": { + "id": "00000000-0000-0000-0000-000000000329", + }, "timelineActivities": { - "id": "00000000-0000-0000-0000-000000000318", + "id": "00000000-0000-0000-0000-000000000327", }, "title": { - "id": "00000000-0000-0000-0000-000000000312", + "id": "00000000-0000-0000-0000-000000000321", }, "updatedAt": { - "id": "00000000-0000-0000-0000-000000000309", + "id": "00000000-0000-0000-0000-000000000318", }, "updatedBy": { - "id": "00000000-0000-0000-0000-000000000315", + "id": "00000000-0000-0000-0000-000000000324", }, }, - "id": "00000000-0000-0000-0000-000000000334", + "id": "00000000-0000-0000-0000-000000000343", "views": { "allNotes": { - "id": "00000000-0000-0000-0000-000000000326", + "id": "00000000-0000-0000-0000-000000000335", "viewFieldGroups": {}, "viewFields": { "bodyV2": { - "id": "00000000-0000-0000-0000-000000000323", + "id": "00000000-0000-0000-0000-000000000332", }, "createdAt": { - "id": "00000000-0000-0000-0000-000000000325", + "id": "00000000-0000-0000-0000-000000000334", }, "createdBy": { - "id": "00000000-0000-0000-0000-000000000324", + "id": "00000000-0000-0000-0000-000000000333", }, "noteTargets": { - "id": "00000000-0000-0000-0000-000000000322", + "id": "00000000-0000-0000-0000-000000000331", }, "title": { - "id": "00000000-0000-0000-0000-000000000321", + "id": "00000000-0000-0000-0000-000000000330", }, }, "viewGroups": {}, }, "noteRecordPageFields": { - "id": "00000000-0000-0000-0000-000000000333", + "id": "00000000-0000-0000-0000-000000000342", "viewFieldGroups": { "additional": { - "id": "00000000-0000-0000-0000-000000000331", + "id": "00000000-0000-0000-0000-000000000340", }, "general": { - "id": "00000000-0000-0000-0000-000000000330", + "id": "00000000-0000-0000-0000-000000000339", }, "other": { - "id": "00000000-0000-0000-0000-000000000332", + "id": "00000000-0000-0000-0000-000000000341", }, }, "viewFields": { "createdAt": { - "id": "00000000-0000-0000-0000-000000000328", + "id": "00000000-0000-0000-0000-000000000337", }, "createdBy": { - "id": "00000000-0000-0000-0000-000000000329", + "id": "00000000-0000-0000-0000-000000000338", }, "title": { - "id": "00000000-0000-0000-0000-000000000327", + "id": "00000000-0000-0000-0000-000000000336", }, }, "viewGroups": {}, @@ -1106,50 +1136,50 @@ exports[`getStandardObjectMetadataRelatedEntityIds should return standard object "noteTarget": { "fields": { "createdAt": { - "id": "00000000-0000-0000-0000-000000000336", + "id": "00000000-0000-0000-0000-000000000345", }, "deletedAt": { - "id": "00000000-0000-0000-0000-000000000338", + "id": "00000000-0000-0000-0000-000000000347", }, "id": { - "id": "00000000-0000-0000-0000-000000000335", + "id": "00000000-0000-0000-0000-000000000344", }, "note": { - "id": "00000000-0000-0000-0000-000000000339", + "id": "00000000-0000-0000-0000-000000000348", }, "targetCompany": { - "id": "00000000-0000-0000-0000-000000000341", + "id": "00000000-0000-0000-0000-000000000350", }, "targetOpportunity": { - "id": "00000000-0000-0000-0000-000000000342", + "id": "00000000-0000-0000-0000-000000000351", }, "targetPerson": { - "id": "00000000-0000-0000-0000-000000000340", + "id": "00000000-0000-0000-0000-000000000349", }, "updatedAt": { - "id": "00000000-0000-0000-0000-000000000337", + "id": "00000000-0000-0000-0000-000000000346", }, }, - "id": "00000000-0000-0000-0000-000000000349", + "id": "00000000-0000-0000-0000-000000000358", "views": { "allNoteTargets": { - "id": "00000000-0000-0000-0000-000000000348", + "id": "00000000-0000-0000-0000-000000000357", "viewFieldGroups": {}, "viewFields": { "id": { - "id": "00000000-0000-0000-0000-000000000343", + "id": "00000000-0000-0000-0000-000000000352", }, "note": { - "id": "00000000-0000-0000-0000-000000000344", + "id": "00000000-0000-0000-0000-000000000353", }, "targetCompany": { - "id": "00000000-0000-0000-0000-000000000346", + "id": "00000000-0000-0000-0000-000000000355", }, "targetOpportunity": { - "id": "00000000-0000-0000-0000-000000000347", + "id": "00000000-0000-0000-0000-000000000356", }, "targetPerson": { - "id": "00000000-0000-0000-0000-000000000345", + "id": "00000000-0000-0000-0000-000000000354", }, }, "viewGroups": {}, @@ -1159,171 +1189,171 @@ exports[`getStandardObjectMetadataRelatedEntityIds should return standard object "opportunity": { "fields": { "amount": { - "id": "00000000-0000-0000-0000-000000000355", - }, - "attachments": { - "id": "00000000-0000-0000-0000-000000000367", - }, - "closeDate": { - "id": "00000000-0000-0000-0000-000000000356", - }, - "company": { - "id": "00000000-0000-0000-0000-000000000362", - }, - "createdAt": { - "id": "00000000-0000-0000-0000-000000000351", - }, - "createdBy": { - "id": "00000000-0000-0000-0000-000000000359", - }, - "deletedAt": { - "id": "00000000-0000-0000-0000-000000000353", - }, - "favorites": { "id": "00000000-0000-0000-0000-000000000364", }, - "id": { - "id": "00000000-0000-0000-0000-000000000350", + "attachments": { + "id": "00000000-0000-0000-0000-000000000376", }, - "name": { - "id": "00000000-0000-0000-0000-000000000354", - }, - "noteTargets": { - "id": "00000000-0000-0000-0000-000000000366", - }, - "owner": { - "id": "00000000-0000-0000-0000-000000000363", - }, - "pointOfContact": { - "id": "00000000-0000-0000-0000-000000000361", - }, - "position": { - "id": "00000000-0000-0000-0000-000000000358", - }, - "searchVector": { - "id": "00000000-0000-0000-0000-000000000369", - }, - "stage": { - "id": "00000000-0000-0000-0000-000000000357", - }, - "taskTargets": { + "closeDate": { "id": "00000000-0000-0000-0000-000000000365", }, - "timelineActivities": { - "id": "00000000-0000-0000-0000-000000000368", + "company": { + "id": "00000000-0000-0000-0000-000000000371", }, - "updatedAt": { - "id": "00000000-0000-0000-0000-000000000352", - }, - "updatedBy": { + "createdAt": { "id": "00000000-0000-0000-0000-000000000360", }, + "createdBy": { + "id": "00000000-0000-0000-0000-000000000368", + }, + "deletedAt": { + "id": "00000000-0000-0000-0000-000000000362", + }, + "favorites": { + "id": "00000000-0000-0000-0000-000000000373", + }, + "id": { + "id": "00000000-0000-0000-0000-000000000359", + }, + "name": { + "id": "00000000-0000-0000-0000-000000000363", + }, + "noteTargets": { + "id": "00000000-0000-0000-0000-000000000375", + }, + "owner": { + "id": "00000000-0000-0000-0000-000000000372", + }, + "pointOfContact": { + "id": "00000000-0000-0000-0000-000000000370", + }, + "position": { + "id": "00000000-0000-0000-0000-000000000367", + }, + "searchVector": { + "id": "00000000-0000-0000-0000-000000000378", + }, + "stage": { + "id": "00000000-0000-0000-0000-000000000366", + }, + "taskTargets": { + "id": "00000000-0000-0000-0000-000000000374", + }, + "timelineActivities": { + "id": "00000000-0000-0000-0000-000000000377", + }, + "updatedAt": { + "id": "00000000-0000-0000-0000-000000000361", + }, + "updatedBy": { + "id": "00000000-0000-0000-0000-000000000369", + }, }, - "id": "00000000-0000-0000-0000-000000000401", + "id": "00000000-0000-0000-0000-000000000410", "views": { "allOpportunities": { - "id": "00000000-0000-0000-0000-000000000376", + "id": "00000000-0000-0000-0000-000000000385", "viewFieldGroups": {}, "viewFields": { "amount": { - "id": "00000000-0000-0000-0000-000000000371", + "id": "00000000-0000-0000-0000-000000000380", }, "closeDate": { - "id": "00000000-0000-0000-0000-000000000373", + "id": "00000000-0000-0000-0000-000000000382", }, "company": { - "id": "00000000-0000-0000-0000-000000000374", + "id": "00000000-0000-0000-0000-000000000383", }, "createdBy": { - "id": "00000000-0000-0000-0000-000000000372", + "id": "00000000-0000-0000-0000-000000000381", }, "name": { - "id": "00000000-0000-0000-0000-000000000370", + "id": "00000000-0000-0000-0000-000000000379", }, "pointOfContact": { - "id": "00000000-0000-0000-0000-000000000375", + "id": "00000000-0000-0000-0000-000000000384", }, }, "viewGroups": {}, }, "byStage": { - "id": "00000000-0000-0000-0000-000000000388", + "id": "00000000-0000-0000-0000-000000000397", "viewFieldGroups": {}, "viewFields": { "amount": { - "id": "00000000-0000-0000-0000-000000000378", + "id": "00000000-0000-0000-0000-000000000387", }, "closeDate": { - "id": "00000000-0000-0000-0000-000000000380", + "id": "00000000-0000-0000-0000-000000000389", }, "company": { - "id": "00000000-0000-0000-0000-000000000381", + "id": "00000000-0000-0000-0000-000000000390", }, "createdBy": { - "id": "00000000-0000-0000-0000-000000000379", + "id": "00000000-0000-0000-0000-000000000388", }, "name": { - "id": "00000000-0000-0000-0000-000000000377", + "id": "00000000-0000-0000-0000-000000000386", }, "pointOfContact": { - "id": "00000000-0000-0000-0000-000000000382", + "id": "00000000-0000-0000-0000-000000000391", }, }, "viewGroups": { "customer": { - "id": "00000000-0000-0000-0000-000000000387", + "id": "00000000-0000-0000-0000-000000000396", }, "meeting": { - "id": "00000000-0000-0000-0000-000000000385", + "id": "00000000-0000-0000-0000-000000000394", }, "new": { - "id": "00000000-0000-0000-0000-000000000383", + "id": "00000000-0000-0000-0000-000000000392", }, "proposal": { - "id": "00000000-0000-0000-0000-000000000386", + "id": "00000000-0000-0000-0000-000000000395", }, "screening": { - "id": "00000000-0000-0000-0000-000000000384", + "id": "00000000-0000-0000-0000-000000000393", }, }, }, "opportunityRecordPageFields": { - "id": "00000000-0000-0000-0000-000000000400", + "id": "00000000-0000-0000-0000-000000000409", "viewFieldGroups": { "additional": { - "id": "00000000-0000-0000-0000-000000000398", + "id": "00000000-0000-0000-0000-000000000407", }, "general": { - "id": "00000000-0000-0000-0000-000000000397", + "id": "00000000-0000-0000-0000-000000000406", }, "other": { - "id": "00000000-0000-0000-0000-000000000399", + "id": "00000000-0000-0000-0000-000000000408", }, }, "viewFields": { "amount": { - "id": "00000000-0000-0000-0000-000000000389", + "id": "00000000-0000-0000-0000-000000000398", }, "closeDate": { - "id": "00000000-0000-0000-0000-000000000390", + "id": "00000000-0000-0000-0000-000000000399", }, "company": { - "id": "00000000-0000-0000-0000-000000000392", + "id": "00000000-0000-0000-0000-000000000401", }, "createdAt": { - "id": "00000000-0000-0000-0000-000000000395", + "id": "00000000-0000-0000-0000-000000000404", }, "createdBy": { - "id": "00000000-0000-0000-0000-000000000396", + "id": "00000000-0000-0000-0000-000000000405", }, "owner": { - "id": "00000000-0000-0000-0000-000000000394", + "id": "00000000-0000-0000-0000-000000000403", }, "pointOfContact": { - "id": "00000000-0000-0000-0000-000000000393", + "id": "00000000-0000-0000-0000-000000000402", }, "stage": { - "id": "00000000-0000-0000-0000-000000000391", + "id": "00000000-0000-0000-0000-000000000400", }, }, "viewGroups": {}, @@ -1333,166 +1363,166 @@ exports[`getStandardObjectMetadataRelatedEntityIds should return standard object "person": { "fields": { "attachments": { - "id": "00000000-0000-0000-0000-000000000423", + "id": "00000000-0000-0000-0000-000000000432", }, "avatarFile": { - "id": "00000000-0000-0000-0000-000000000414", + "id": "00000000-0000-0000-0000-000000000423", }, "avatarUrl": { - "id": "00000000-0000-0000-0000-000000000413", - }, - "calendarEventParticipants": { - "id": "00000000-0000-0000-0000-000000000425", - }, - "city": { - "id": "00000000-0000-0000-0000-000000000412", - }, - "company": { - "id": "00000000-0000-0000-0000-000000000418", - }, - "createdAt": { - "id": "00000000-0000-0000-0000-000000000403", - }, - "createdBy": { - "id": "00000000-0000-0000-0000-000000000416", - }, - "deletedAt": { - "id": "00000000-0000-0000-0000-000000000405", - }, - "emails": { - "id": "00000000-0000-0000-0000-000000000407", - }, - "favorites": { "id": "00000000-0000-0000-0000-000000000422", }, - "id": { - "id": "00000000-0000-0000-0000-000000000402", + "calendarEventParticipants": { + "id": "00000000-0000-0000-0000-000000000434", }, - "jobTitle": { - "id": "00000000-0000-0000-0000-000000000410", - }, - "linkedinLink": { - "id": "00000000-0000-0000-0000-000000000408", - }, - "messageParticipants": { - "id": "00000000-0000-0000-0000-000000000424", - }, - "name": { - "id": "00000000-0000-0000-0000-000000000406", - }, - "noteTargets": { + "city": { "id": "00000000-0000-0000-0000-000000000421", }, - "phones": { - "id": "00000000-0000-0000-0000-000000000411", - }, - "pointOfContactForOpportunities": { - "id": "00000000-0000-0000-0000-000000000419", - }, - "position": { - "id": "00000000-0000-0000-0000-000000000415", - }, - "searchVector": { + "company": { "id": "00000000-0000-0000-0000-000000000427", }, - "taskTargets": { - "id": "00000000-0000-0000-0000-000000000420", + "createdAt": { + "id": "00000000-0000-0000-0000-000000000412", }, - "timelineActivities": { - "id": "00000000-0000-0000-0000-000000000426", + "createdBy": { + "id": "00000000-0000-0000-0000-000000000425", }, - "updatedAt": { - "id": "00000000-0000-0000-0000-000000000404", + "deletedAt": { + "id": "00000000-0000-0000-0000-000000000414", }, - "updatedBy": { + "emails": { + "id": "00000000-0000-0000-0000-000000000416", + }, + "favorites": { + "id": "00000000-0000-0000-0000-000000000431", + }, + "id": { + "id": "00000000-0000-0000-0000-000000000411", + }, + "jobTitle": { + "id": "00000000-0000-0000-0000-000000000419", + }, + "linkedinLink": { "id": "00000000-0000-0000-0000-000000000417", }, + "messageParticipants": { + "id": "00000000-0000-0000-0000-000000000433", + }, + "name": { + "id": "00000000-0000-0000-0000-000000000415", + }, + "noteTargets": { + "id": "00000000-0000-0000-0000-000000000430", + }, + "phones": { + "id": "00000000-0000-0000-0000-000000000420", + }, + "pointOfContactForOpportunities": { + "id": "00000000-0000-0000-0000-000000000428", + }, + "position": { + "id": "00000000-0000-0000-0000-000000000424", + }, + "searchVector": { + "id": "00000000-0000-0000-0000-000000000436", + }, + "taskTargets": { + "id": "00000000-0000-0000-0000-000000000429", + }, + "timelineActivities": { + "id": "00000000-0000-0000-0000-000000000435", + }, + "updatedAt": { + "id": "00000000-0000-0000-0000-000000000413", + }, + "updatedBy": { + "id": "00000000-0000-0000-0000-000000000426", + }, "xLink": { - "id": "00000000-0000-0000-0000-000000000409", + "id": "00000000-0000-0000-0000-000000000418", }, }, - "id": "00000000-0000-0000-0000-000000000453", + "id": "00000000-0000-0000-0000-000000000462", "views": { "allPeople": { - "id": "00000000-0000-0000-0000-000000000438", + "id": "00000000-0000-0000-0000-000000000447", "viewFieldGroups": {}, "viewFields": { "city": { - "id": "00000000-0000-0000-0000-000000000434", + "id": "00000000-0000-0000-0000-000000000443", }, "company": { - "id": "00000000-0000-0000-0000-000000000431", + "id": "00000000-0000-0000-0000-000000000440", }, "createdAt": { - "id": "00000000-0000-0000-0000-000000000433", + "id": "00000000-0000-0000-0000-000000000442", }, "createdBy": { - "id": "00000000-0000-0000-0000-000000000430", + "id": "00000000-0000-0000-0000-000000000439", }, "emails": { - "id": "00000000-0000-0000-0000-000000000429", + "id": "00000000-0000-0000-0000-000000000438", }, "jobTitle": { - "id": "00000000-0000-0000-0000-000000000435", + "id": "00000000-0000-0000-0000-000000000444", }, "linkedinLink": { - "id": "00000000-0000-0000-0000-000000000436", + "id": "00000000-0000-0000-0000-000000000445", }, "name": { - "id": "00000000-0000-0000-0000-000000000428", + "id": "00000000-0000-0000-0000-000000000437", }, "phones": { - "id": "00000000-0000-0000-0000-000000000432", + "id": "00000000-0000-0000-0000-000000000441", }, "xLink": { - "id": "00000000-0000-0000-0000-000000000437", + "id": "00000000-0000-0000-0000-000000000446", }, }, "viewGroups": {}, }, "personRecordPageFields": { - "id": "00000000-0000-0000-0000-000000000452", + "id": "00000000-0000-0000-0000-000000000461", "viewFieldGroups": { "additional": { - "id": "00000000-0000-0000-0000-000000000450", + "id": "00000000-0000-0000-0000-000000000459", }, "general": { - "id": "00000000-0000-0000-0000-000000000449", + "id": "00000000-0000-0000-0000-000000000458", }, "other": { - "id": "00000000-0000-0000-0000-000000000451", + "id": "00000000-0000-0000-0000-000000000460", }, }, "viewFields": { "avatarUrl": { - "id": "00000000-0000-0000-0000-000000000446", + "id": "00000000-0000-0000-0000-000000000455", }, "city": { - "id": "00000000-0000-0000-0000-000000000445", + "id": "00000000-0000-0000-0000-000000000454", }, "company": { - "id": "00000000-0000-0000-0000-000000000441", + "id": "00000000-0000-0000-0000-000000000450", }, "createdAt": { - "id": "00000000-0000-0000-0000-000000000447", + "id": "00000000-0000-0000-0000-000000000456", }, "createdBy": { - "id": "00000000-0000-0000-0000-000000000448", + "id": "00000000-0000-0000-0000-000000000457", }, "emails": { - "id": "00000000-0000-0000-0000-000000000439", + "id": "00000000-0000-0000-0000-000000000448", }, "jobTitle": { - "id": "00000000-0000-0000-0000-000000000442", + "id": "00000000-0000-0000-0000-000000000451", }, "linkedinLink": { - "id": "00000000-0000-0000-0000-000000000443", + "id": "00000000-0000-0000-0000-000000000452", }, "phones": { - "id": "00000000-0000-0000-0000-000000000440", + "id": "00000000-0000-0000-0000-000000000449", }, "xLink": { - "id": "00000000-0000-0000-0000-000000000444", + "id": "00000000-0000-0000-0000-000000000453", }, }, "viewGroups": {}, @@ -1502,176 +1532,134 @@ exports[`getStandardObjectMetadataRelatedEntityIds should return standard object "task": { "fields": { "assignee": { - "id": "00000000-0000-0000-0000-000000000467", + "id": "00000000-0000-0000-0000-000000000476", }, "attachments": { - "id": "00000000-0000-0000-0000-000000000466", + "id": "00000000-0000-0000-0000-000000000475", }, "bodyV2": { - "id": "00000000-0000-0000-0000-000000000460", - }, - "createdAt": { - "id": "00000000-0000-0000-0000-000000000455", - }, - "createdBy": { - "id": "00000000-0000-0000-0000-000000000463", - }, - "deletedAt": { - "id": "00000000-0000-0000-0000-000000000457", - }, - "dueAt": { - "id": "00000000-0000-0000-0000-000000000461", - }, - "favorites": { "id": "00000000-0000-0000-0000-000000000469", }, - "id": { - "id": "00000000-0000-0000-0000-000000000454", - }, - "position": { - "id": "00000000-0000-0000-0000-000000000458", - }, - "searchVector": { - "id": "00000000-0000-0000-0000-000000000470", - }, - "status": { - "id": "00000000-0000-0000-0000-000000000462", - }, - "taskTargets": { - "id": "00000000-0000-0000-0000-000000000465", - }, - "timelineActivities": { - "id": "00000000-0000-0000-0000-000000000468", - }, - "title": { - "id": "00000000-0000-0000-0000-000000000459", - }, - "updatedAt": { - "id": "00000000-0000-0000-0000-000000000456", - }, - "updatedBy": { + "createdAt": { "id": "00000000-0000-0000-0000-000000000464", }, + "createdBy": { + "id": "00000000-0000-0000-0000-000000000472", + }, + "deletedAt": { + "id": "00000000-0000-0000-0000-000000000466", + }, + "dueAt": { + "id": "00000000-0000-0000-0000-000000000470", + }, + "favorites": { + "id": "00000000-0000-0000-0000-000000000478", + }, + "id": { + "id": "00000000-0000-0000-0000-000000000463", + }, + "position": { + "id": "00000000-0000-0000-0000-000000000467", + }, + "searchVector": { + "id": "00000000-0000-0000-0000-000000000479", + }, + "status": { + "id": "00000000-0000-0000-0000-000000000471", + }, + "taskTargets": { + "id": "00000000-0000-0000-0000-000000000474", + }, + "timelineActivities": { + "id": "00000000-0000-0000-0000-000000000477", + }, + "title": { + "id": "00000000-0000-0000-0000-000000000468", + }, + "updatedAt": { + "id": "00000000-0000-0000-0000-000000000465", + }, + "updatedBy": { + "id": "00000000-0000-0000-0000-000000000473", + }, }, - "id": "00000000-0000-0000-0000-000000000511", + "id": "00000000-0000-0000-0000-000000000520", "views": { "allTasks": { - "id": "00000000-0000-0000-0000-000000000479", + "id": "00000000-0000-0000-0000-000000000488", "viewFieldGroups": {}, "viewFields": { "assignee": { - "id": "00000000-0000-0000-0000-000000000476", - }, - "bodyV2": { - "id": "00000000-0000-0000-0000-000000000477", - }, - "createdAt": { - "id": "00000000-0000-0000-0000-000000000478", - }, - "createdBy": { - "id": "00000000-0000-0000-0000-000000000474", - }, - "dueAt": { - "id": "00000000-0000-0000-0000-000000000475", - }, - "status": { - "id": "00000000-0000-0000-0000-000000000472", - }, - "taskTargets": { - "id": "00000000-0000-0000-0000-000000000473", - }, - "title": { - "id": "00000000-0000-0000-0000-000000000471", - }, - }, - "viewGroups": {}, - }, - "assignedToMe": { - "id": "00000000-0000-0000-0000-000000000491", - "viewFieldGroups": {}, - "viewFields": { - "assignee": { - "id": "00000000-0000-0000-0000-000000000484", - }, - "bodyV2": { "id": "00000000-0000-0000-0000-000000000485", }, - "createdAt": { + "bodyV2": { "id": "00000000-0000-0000-0000-000000000486", }, - "createdBy": { - "id": "00000000-0000-0000-0000-000000000482", + "createdAt": { + "id": "00000000-0000-0000-0000-000000000487", }, - "dueAt": { + "createdBy": { "id": "00000000-0000-0000-0000-000000000483", }, - "taskTargets": { + "dueAt": { + "id": "00000000-0000-0000-0000-000000000484", + }, + "status": { "id": "00000000-0000-0000-0000-000000000481", }, + "taskTargets": { + "id": "00000000-0000-0000-0000-000000000482", + }, "title": { "id": "00000000-0000-0000-0000-000000000480", }, }, - "viewGroups": { - "done": { - "id": "00000000-0000-0000-0000-000000000489", - }, - "empty": { - "id": "00000000-0000-0000-0000-000000000490", - }, - "inProgress": { - "id": "00000000-0000-0000-0000-000000000488", - }, - "todo": { - "id": "00000000-0000-0000-0000-000000000487", - }, - }, + "viewGroups": {}, }, - "byStatus": { + "assignedToMe": { "id": "00000000-0000-0000-0000-000000000500", "viewFieldGroups": {}, "viewFields": { "assignee": { - "id": "00000000-0000-0000-0000-000000000495", - }, - "createdAt": { - "id": "00000000-0000-0000-0000-000000000496", - }, - "dueAt": { - "id": "00000000-0000-0000-0000-000000000494", - }, - "status": { "id": "00000000-0000-0000-0000-000000000493", }, - "title": { + "bodyV2": { + "id": "00000000-0000-0000-0000-000000000494", + }, + "createdAt": { + "id": "00000000-0000-0000-0000-000000000495", + }, + "createdBy": { + "id": "00000000-0000-0000-0000-000000000491", + }, + "dueAt": { "id": "00000000-0000-0000-0000-000000000492", }, + "taskTargets": { + "id": "00000000-0000-0000-0000-000000000490", + }, + "title": { + "id": "00000000-0000-0000-0000-000000000489", + }, }, "viewGroups": { "done": { + "id": "00000000-0000-0000-0000-000000000498", + }, + "empty": { "id": "00000000-0000-0000-0000-000000000499", }, "inProgress": { - "id": "00000000-0000-0000-0000-000000000498", + "id": "00000000-0000-0000-0000-000000000497", }, "todo": { - "id": "00000000-0000-0000-0000-000000000497", + "id": "00000000-0000-0000-0000-000000000496", }, }, }, - "taskRecordPageFields": { - "id": "00000000-0000-0000-0000-000000000510", - "viewFieldGroups": { - "additional": { - "id": "00000000-0000-0000-0000-000000000508", - }, - "general": { - "id": "00000000-0000-0000-0000-000000000507", - }, - "other": { - "id": "00000000-0000-0000-0000-000000000509", - }, - }, + "byStatus": { + "id": "00000000-0000-0000-0000-000000000509", + "viewFieldGroups": {}, "viewFields": { "assignee": { "id": "00000000-0000-0000-0000-000000000504", @@ -1679,19 +1667,61 @@ exports[`getStandardObjectMetadataRelatedEntityIds should return standard object "createdAt": { "id": "00000000-0000-0000-0000-000000000505", }, - "createdBy": { - "id": "00000000-0000-0000-0000-000000000506", - }, "dueAt": { - "id": "00000000-0000-0000-0000-000000000502", + "id": "00000000-0000-0000-0000-000000000503", }, "status": { - "id": "00000000-0000-0000-0000-000000000503", + "id": "00000000-0000-0000-0000-000000000502", }, "title": { "id": "00000000-0000-0000-0000-000000000501", }, }, + "viewGroups": { + "done": { + "id": "00000000-0000-0000-0000-000000000508", + }, + "inProgress": { + "id": "00000000-0000-0000-0000-000000000507", + }, + "todo": { + "id": "00000000-0000-0000-0000-000000000506", + }, + }, + }, + "taskRecordPageFields": { + "id": "00000000-0000-0000-0000-000000000519", + "viewFieldGroups": { + "additional": { + "id": "00000000-0000-0000-0000-000000000517", + }, + "general": { + "id": "00000000-0000-0000-0000-000000000516", + }, + "other": { + "id": "00000000-0000-0000-0000-000000000518", + }, + }, + "viewFields": { + "assignee": { + "id": "00000000-0000-0000-0000-000000000513", + }, + "createdAt": { + "id": "00000000-0000-0000-0000-000000000514", + }, + "createdBy": { + "id": "00000000-0000-0000-0000-000000000515", + }, + "dueAt": { + "id": "00000000-0000-0000-0000-000000000511", + }, + "status": { + "id": "00000000-0000-0000-0000-000000000512", + }, + "title": { + "id": "00000000-0000-0000-0000-000000000510", + }, + }, "viewGroups": {}, }, }, @@ -1699,50 +1729,50 @@ exports[`getStandardObjectMetadataRelatedEntityIds should return standard object "taskTarget": { "fields": { "createdAt": { - "id": "00000000-0000-0000-0000-000000000513", + "id": "00000000-0000-0000-0000-000000000522", }, "deletedAt": { - "id": "00000000-0000-0000-0000-000000000515", + "id": "00000000-0000-0000-0000-000000000524", }, "id": { - "id": "00000000-0000-0000-0000-000000000512", + "id": "00000000-0000-0000-0000-000000000521", }, "targetCompany": { - "id": "00000000-0000-0000-0000-000000000518", + "id": "00000000-0000-0000-0000-000000000527", }, "targetOpportunity": { - "id": "00000000-0000-0000-0000-000000000519", + "id": "00000000-0000-0000-0000-000000000528", }, "targetPerson": { - "id": "00000000-0000-0000-0000-000000000517", + "id": "00000000-0000-0000-0000-000000000526", }, "task": { - "id": "00000000-0000-0000-0000-000000000516", + "id": "00000000-0000-0000-0000-000000000525", }, "updatedAt": { - "id": "00000000-0000-0000-0000-000000000514", + "id": "00000000-0000-0000-0000-000000000523", }, }, - "id": "00000000-0000-0000-0000-000000000526", + "id": "00000000-0000-0000-0000-000000000535", "views": { "allTaskTargets": { - "id": "00000000-0000-0000-0000-000000000525", + "id": "00000000-0000-0000-0000-000000000534", "viewFieldGroups": {}, "viewFields": { "id": { - "id": "00000000-0000-0000-0000-000000000520", + "id": "00000000-0000-0000-0000-000000000529", }, "targetCompany": { - "id": "00000000-0000-0000-0000-000000000523", + "id": "00000000-0000-0000-0000-000000000532", }, "targetOpportunity": { - "id": "00000000-0000-0000-0000-000000000524", + "id": "00000000-0000-0000-0000-000000000533", }, "targetPerson": { - "id": "00000000-0000-0000-0000-000000000522", + "id": "00000000-0000-0000-0000-000000000531", }, "task": { - "id": "00000000-0000-0000-0000-000000000521", + "id": "00000000-0000-0000-0000-000000000530", }, }, "viewGroups": {}, @@ -1752,113 +1782,113 @@ exports[`getStandardObjectMetadataRelatedEntityIds should return standard object "timelineActivity": { "fields": { "createdAt": { - "id": "00000000-0000-0000-0000-000000000528", - }, - "deletedAt": { - "id": "00000000-0000-0000-0000-000000000530", - }, - "happensAt": { - "id": "00000000-0000-0000-0000-000000000531", - }, - "id": { - "id": "00000000-0000-0000-0000-000000000527", - }, - "linkedObjectMetadataId": { - "id": "00000000-0000-0000-0000-000000000546", - }, - "linkedRecordCachedName": { - "id": "00000000-0000-0000-0000-000000000544", - }, - "linkedRecordId": { - "id": "00000000-0000-0000-0000-000000000545", - }, - "name": { - "id": "00000000-0000-0000-0000-000000000532", - }, - "properties": { - "id": "00000000-0000-0000-0000-000000000533", - }, - "targetCompany": { - "id": "00000000-0000-0000-0000-000000000536", - }, - "targetDashboard": { - "id": "00000000-0000-0000-0000-000000000543", - }, - "targetNote": { - "id": "00000000-0000-0000-0000-000000000539", - }, - "targetOpportunity": { "id": "00000000-0000-0000-0000-000000000537", }, - "targetPerson": { - "id": "00000000-0000-0000-0000-000000000535", + "deletedAt": { + "id": "00000000-0000-0000-0000-000000000539", }, - "targetTask": { - "id": "00000000-0000-0000-0000-000000000538", - }, - "targetWorkflow": { + "happensAt": { "id": "00000000-0000-0000-0000-000000000540", }, - "targetWorkflowRun": { - "id": "00000000-0000-0000-0000-000000000542", + "id": { + "id": "00000000-0000-0000-0000-000000000536", }, - "targetWorkflowVersion": { + "linkedObjectMetadataId": { + "id": "00000000-0000-0000-0000-000000000555", + }, + "linkedRecordCachedName": { + "id": "00000000-0000-0000-0000-000000000553", + }, + "linkedRecordId": { + "id": "00000000-0000-0000-0000-000000000554", + }, + "name": { "id": "00000000-0000-0000-0000-000000000541", }, + "properties": { + "id": "00000000-0000-0000-0000-000000000542", + }, + "targetCompany": { + "id": "00000000-0000-0000-0000-000000000545", + }, + "targetDashboard": { + "id": "00000000-0000-0000-0000-000000000552", + }, + "targetNote": { + "id": "00000000-0000-0000-0000-000000000548", + }, + "targetOpportunity": { + "id": "00000000-0000-0000-0000-000000000546", + }, + "targetPerson": { + "id": "00000000-0000-0000-0000-000000000544", + }, + "targetTask": { + "id": "00000000-0000-0000-0000-000000000547", + }, + "targetWorkflow": { + "id": "00000000-0000-0000-0000-000000000549", + }, + "targetWorkflowRun": { + "id": "00000000-0000-0000-0000-000000000551", + }, + "targetWorkflowVersion": { + "id": "00000000-0000-0000-0000-000000000550", + }, "updatedAt": { - "id": "00000000-0000-0000-0000-000000000529", + "id": "00000000-0000-0000-0000-000000000538", }, "workspaceMember": { - "id": "00000000-0000-0000-0000-000000000534", + "id": "00000000-0000-0000-0000-000000000543", }, }, - "id": "00000000-0000-0000-0000-000000000562", + "id": "00000000-0000-0000-0000-000000000571", "views": { "allTimelineActivities": { - "id": "00000000-0000-0000-0000-000000000561", + "id": "00000000-0000-0000-0000-000000000570", "viewFieldGroups": {}, "viewFields": { "happensAt": { - "id": "00000000-0000-0000-0000-000000000548", - }, - "linkedRecordCachedName": { - "id": "00000000-0000-0000-0000-000000000551", - }, - "name": { - "id": "00000000-0000-0000-0000-000000000547", - }, - "properties": { - "id": "00000000-0000-0000-0000-000000000549", - }, - "targetCompany": { - "id": "00000000-0000-0000-0000-000000000553", - }, - "targetDashboard": { - "id": "00000000-0000-0000-0000-000000000560", - }, - "targetNote": { - "id": "00000000-0000-0000-0000-000000000556", - }, - "targetOpportunity": { - "id": "00000000-0000-0000-0000-000000000554", - }, - "targetPerson": { - "id": "00000000-0000-0000-0000-000000000552", - }, - "targetTask": { - "id": "00000000-0000-0000-0000-000000000555", - }, - "targetWorkflow": { "id": "00000000-0000-0000-0000-000000000557", }, - "targetWorkflowRun": { - "id": "00000000-0000-0000-0000-000000000559", + "linkedRecordCachedName": { + "id": "00000000-0000-0000-0000-000000000560", }, - "targetWorkflowVersion": { + "name": { + "id": "00000000-0000-0000-0000-000000000556", + }, + "properties": { "id": "00000000-0000-0000-0000-000000000558", }, + "targetCompany": { + "id": "00000000-0000-0000-0000-000000000562", + }, + "targetDashboard": { + "id": "00000000-0000-0000-0000-000000000569", + }, + "targetNote": { + "id": "00000000-0000-0000-0000-000000000565", + }, + "targetOpportunity": { + "id": "00000000-0000-0000-0000-000000000563", + }, + "targetPerson": { + "id": "00000000-0000-0000-0000-000000000561", + }, + "targetTask": { + "id": "00000000-0000-0000-0000-000000000564", + }, + "targetWorkflow": { + "id": "00000000-0000-0000-0000-000000000566", + }, + "targetWorkflowRun": { + "id": "00000000-0000-0000-0000-000000000568", + }, + "targetWorkflowVersion": { + "id": "00000000-0000-0000-0000-000000000567", + }, "workspaceMember": { - "id": "00000000-0000-0000-0000-000000000550", + "id": "00000000-0000-0000-0000-000000000559", }, }, "viewGroups": {}, @@ -1868,80 +1898,80 @@ exports[`getStandardObjectMetadataRelatedEntityIds should return standard object "workflow": { "fields": { "attachments": { - "id": "00000000-0000-0000-0000-000000000576", + "id": "00000000-0000-0000-0000-000000000585", }, "automatedTriggers": { - "id": "00000000-0000-0000-0000-000000000573", + "id": "00000000-0000-0000-0000-000000000582", }, "createdAt": { - "id": "00000000-0000-0000-0000-000000000564", + "id": "00000000-0000-0000-0000-000000000573", }, "createdBy": { - "id": "00000000-0000-0000-0000-000000000577", + "id": "00000000-0000-0000-0000-000000000586", }, "deletedAt": { - "id": "00000000-0000-0000-0000-000000000566", - }, - "favorites": { - "id": "00000000-0000-0000-0000-000000000574", - }, - "id": { - "id": "00000000-0000-0000-0000-000000000563", - }, - "lastPublishedVersionId": { - "id": "00000000-0000-0000-0000-000000000568", - }, - "name": { - "id": "00000000-0000-0000-0000-000000000567", - }, - "position": { - "id": "00000000-0000-0000-0000-000000000570", - }, - "runs": { - "id": "00000000-0000-0000-0000-000000000572", - }, - "searchVector": { - "id": "00000000-0000-0000-0000-000000000579", - }, - "statuses": { - "id": "00000000-0000-0000-0000-000000000569", - }, - "timelineActivities": { "id": "00000000-0000-0000-0000-000000000575", }, - "updatedAt": { - "id": "00000000-0000-0000-0000-000000000565", + "favorites": { + "id": "00000000-0000-0000-0000-000000000583", }, - "updatedBy": { + "id": { + "id": "00000000-0000-0000-0000-000000000572", + }, + "lastPublishedVersionId": { + "id": "00000000-0000-0000-0000-000000000577", + }, + "name": { + "id": "00000000-0000-0000-0000-000000000576", + }, + "position": { + "id": "00000000-0000-0000-0000-000000000579", + }, + "runs": { + "id": "00000000-0000-0000-0000-000000000581", + }, + "searchVector": { + "id": "00000000-0000-0000-0000-000000000588", + }, + "statuses": { "id": "00000000-0000-0000-0000-000000000578", }, + "timelineActivities": { + "id": "00000000-0000-0000-0000-000000000584", + }, + "updatedAt": { + "id": "00000000-0000-0000-0000-000000000574", + }, + "updatedBy": { + "id": "00000000-0000-0000-0000-000000000587", + }, "versions": { - "id": "00000000-0000-0000-0000-000000000571", + "id": "00000000-0000-0000-0000-000000000580", }, }, - "id": "00000000-0000-0000-0000-000000000587", + "id": "00000000-0000-0000-0000-000000000596", "views": { "allWorkflows": { - "id": "00000000-0000-0000-0000-000000000586", + "id": "00000000-0000-0000-0000-000000000595", "viewFieldGroups": {}, "viewFields": { "createdBy": { - "id": "00000000-0000-0000-0000-000000000583", + "id": "00000000-0000-0000-0000-000000000592", }, "name": { - "id": "00000000-0000-0000-0000-000000000580", + "id": "00000000-0000-0000-0000-000000000589", }, "runs": { - "id": "00000000-0000-0000-0000-000000000585", + "id": "00000000-0000-0000-0000-000000000594", }, "statuses": { - "id": "00000000-0000-0000-0000-000000000581", + "id": "00000000-0000-0000-0000-000000000590", }, "updatedAt": { - "id": "00000000-0000-0000-0000-000000000582", + "id": "00000000-0000-0000-0000-000000000591", }, "versions": { - "id": "00000000-0000-0000-0000-000000000584", + "id": "00000000-0000-0000-0000-000000000593", }, }, "viewGroups": {}, @@ -1951,157 +1981,157 @@ exports[`getStandardObjectMetadataRelatedEntityIds should return standard object "workflowAutomatedTrigger": { "fields": { "createdAt": { - "id": "00000000-0000-0000-0000-000000000589", + "id": "00000000-0000-0000-0000-000000000598", }, "deletedAt": { - "id": "00000000-0000-0000-0000-000000000591", + "id": "00000000-0000-0000-0000-000000000600", }, "id": { - "id": "00000000-0000-0000-0000-000000000588", + "id": "00000000-0000-0000-0000-000000000597", }, "settings": { - "id": "00000000-0000-0000-0000-000000000593", + "id": "00000000-0000-0000-0000-000000000602", }, "type": { - "id": "00000000-0000-0000-0000-000000000592", + "id": "00000000-0000-0000-0000-000000000601", }, "updatedAt": { - "id": "00000000-0000-0000-0000-000000000590", + "id": "00000000-0000-0000-0000-000000000599", }, "workflow": { - "id": "00000000-0000-0000-0000-000000000594", + "id": "00000000-0000-0000-0000-000000000603", }, }, - "id": "00000000-0000-0000-0000-000000000595", + "id": "00000000-0000-0000-0000-000000000604", "views": undefined, }, "workflowRun": { "fields": { "context": { - "id": "00000000-0000-0000-0000-000000000611", + "id": "00000000-0000-0000-0000-000000000620", }, "createdAt": { - "id": "00000000-0000-0000-0000-000000000597", - }, - "createdBy": { - "id": "00000000-0000-0000-0000-000000000608", - }, - "deletedAt": { - "id": "00000000-0000-0000-0000-000000000599", - }, - "endedAt": { - "id": "00000000-0000-0000-0000-000000000605", - }, - "enqueuedAt": { - "id": "00000000-0000-0000-0000-000000000603", - }, - "favorites": { - "id": "00000000-0000-0000-0000-000000000613", - }, - "id": { - "id": "00000000-0000-0000-0000-000000000596", - }, - "name": { - "id": "00000000-0000-0000-0000-000000000600", - }, - "output": { - "id": "00000000-0000-0000-0000-000000000610", - }, - "position": { - "id": "00000000-0000-0000-0000-000000000607", - }, - "searchVector": { - "id": "00000000-0000-0000-0000-000000000615", - }, - "startedAt": { - "id": "00000000-0000-0000-0000-000000000604", - }, - "state": { - "id": "00000000-0000-0000-0000-000000000612", - }, - "status": { "id": "00000000-0000-0000-0000-000000000606", }, - "timelineActivities": { + "createdBy": { + "id": "00000000-0000-0000-0000-000000000617", + }, + "deletedAt": { + "id": "00000000-0000-0000-0000-000000000608", + }, + "endedAt": { "id": "00000000-0000-0000-0000-000000000614", }, - "updatedAt": { - "id": "00000000-0000-0000-0000-000000000598", + "enqueuedAt": { + "id": "00000000-0000-0000-0000-000000000612", }, - "updatedBy": { + "favorites": { + "id": "00000000-0000-0000-0000-000000000622", + }, + "id": { + "id": "00000000-0000-0000-0000-000000000605", + }, + "name": { "id": "00000000-0000-0000-0000-000000000609", }, + "output": { + "id": "00000000-0000-0000-0000-000000000619", + }, + "position": { + "id": "00000000-0000-0000-0000-000000000616", + }, + "searchVector": { + "id": "00000000-0000-0000-0000-000000000624", + }, + "startedAt": { + "id": "00000000-0000-0000-0000-000000000613", + }, + "state": { + "id": "00000000-0000-0000-0000-000000000621", + }, + "status": { + "id": "00000000-0000-0000-0000-000000000615", + }, + "timelineActivities": { + "id": "00000000-0000-0000-0000-000000000623", + }, + "updatedAt": { + "id": "00000000-0000-0000-0000-000000000607", + }, + "updatedBy": { + "id": "00000000-0000-0000-0000-000000000618", + }, "workflow": { - "id": "00000000-0000-0000-0000-000000000602", + "id": "00000000-0000-0000-0000-000000000611", }, "workflowVersion": { - "id": "00000000-0000-0000-0000-000000000601", + "id": "00000000-0000-0000-0000-000000000610", }, }, - "id": "00000000-0000-0000-0000-000000000635", + "id": "00000000-0000-0000-0000-000000000644", "views": { "allWorkflowRuns": { - "id": "00000000-0000-0000-0000-000000000622", + "id": "00000000-0000-0000-0000-000000000631", "viewFieldGroups": {}, "viewFields": { "createdBy": { - "id": "00000000-0000-0000-0000-000000000620", + "id": "00000000-0000-0000-0000-000000000629", }, "name": { - "id": "00000000-0000-0000-0000-000000000616", + "id": "00000000-0000-0000-0000-000000000625", }, "startedAt": { - "id": "00000000-0000-0000-0000-000000000619", + "id": "00000000-0000-0000-0000-000000000628", }, "status": { - "id": "00000000-0000-0000-0000-000000000618", + "id": "00000000-0000-0000-0000-000000000627", }, "workflow": { - "id": "00000000-0000-0000-0000-000000000617", + "id": "00000000-0000-0000-0000-000000000626", }, "workflowVersion": { - "id": "00000000-0000-0000-0000-000000000621", + "id": "00000000-0000-0000-0000-000000000630", }, }, "viewGroups": {}, }, "workflowRunRecordPageFields": { - "id": "00000000-0000-0000-0000-000000000634", + "id": "00000000-0000-0000-0000-000000000643", "viewFieldGroups": { "additional": { - "id": "00000000-0000-0000-0000-000000000632", + "id": "00000000-0000-0000-0000-000000000641", }, "general": { - "id": "00000000-0000-0000-0000-000000000631", + "id": "00000000-0000-0000-0000-000000000640", }, "other": { - "id": "00000000-0000-0000-0000-000000000633", + "id": "00000000-0000-0000-0000-000000000642", }, }, "viewFields": { "createdAt": { - "id": "00000000-0000-0000-0000-000000000629", + "id": "00000000-0000-0000-0000-000000000638", }, "createdBy": { - "id": "00000000-0000-0000-0000-000000000630", + "id": "00000000-0000-0000-0000-000000000639", }, "endedAt": { - "id": "00000000-0000-0000-0000-000000000628", + "id": "00000000-0000-0000-0000-000000000637", }, "name": { - "id": "00000000-0000-0000-0000-000000000623", + "id": "00000000-0000-0000-0000-000000000632", }, "startedAt": { - "id": "00000000-0000-0000-0000-000000000627", + "id": "00000000-0000-0000-0000-000000000636", }, "status": { - "id": "00000000-0000-0000-0000-000000000624", + "id": "00000000-0000-0000-0000-000000000633", }, "workflow": { - "id": "00000000-0000-0000-0000-000000000625", + "id": "00000000-0000-0000-0000-000000000634", }, "workflowVersion": { - "id": "00000000-0000-0000-0000-000000000626", + "id": "00000000-0000-0000-0000-000000000635", }, }, "viewGroups": {}, @@ -2111,100 +2141,100 @@ exports[`getStandardObjectMetadataRelatedEntityIds should return standard object "workflowVersion": { "fields": { "createdAt": { - "id": "00000000-0000-0000-0000-000000000637", - }, - "deletedAt": { - "id": "00000000-0000-0000-0000-000000000639", - }, - "favorites": { - "id": "00000000-0000-0000-0000-000000000647", - }, - "id": { - "id": "00000000-0000-0000-0000-000000000636", - }, - "name": { - "id": "00000000-0000-0000-0000-000000000640", - }, - "position": { - "id": "00000000-0000-0000-0000-000000000644", - }, - "runs": { - "id": "00000000-0000-0000-0000-000000000645", - }, - "searchVector": { - "id": "00000000-0000-0000-0000-000000000649", - }, - "status": { - "id": "00000000-0000-0000-0000-000000000643", - }, - "steps": { "id": "00000000-0000-0000-0000-000000000646", }, - "timelineActivities": { + "deletedAt": { "id": "00000000-0000-0000-0000-000000000648", }, + "favorites": { + "id": "00000000-0000-0000-0000-000000000656", + }, + "id": { + "id": "00000000-0000-0000-0000-000000000645", + }, + "name": { + "id": "00000000-0000-0000-0000-000000000649", + }, + "position": { + "id": "00000000-0000-0000-0000-000000000653", + }, + "runs": { + "id": "00000000-0000-0000-0000-000000000654", + }, + "searchVector": { + "id": "00000000-0000-0000-0000-000000000658", + }, + "status": { + "id": "00000000-0000-0000-0000-000000000652", + }, + "steps": { + "id": "00000000-0000-0000-0000-000000000655", + }, + "timelineActivities": { + "id": "00000000-0000-0000-0000-000000000657", + }, "trigger": { - "id": "00000000-0000-0000-0000-000000000642", + "id": "00000000-0000-0000-0000-000000000651", }, "updatedAt": { - "id": "00000000-0000-0000-0000-000000000638", + "id": "00000000-0000-0000-0000-000000000647", }, "workflow": { - "id": "00000000-0000-0000-0000-000000000641", + "id": "00000000-0000-0000-0000-000000000650", }, }, - "id": "00000000-0000-0000-0000-000000000665", + "id": "00000000-0000-0000-0000-000000000674", "views": { "allWorkflowVersions": { - "id": "00000000-0000-0000-0000-000000000655", + "id": "00000000-0000-0000-0000-000000000664", "viewFieldGroups": {}, "viewFields": { "name": { - "id": "00000000-0000-0000-0000-000000000650", + "id": "00000000-0000-0000-0000-000000000659", }, "runs": { - "id": "00000000-0000-0000-0000-000000000654", + "id": "00000000-0000-0000-0000-000000000663", }, "status": { - "id": "00000000-0000-0000-0000-000000000652", + "id": "00000000-0000-0000-0000-000000000661", }, "updatedAt": { - "id": "00000000-0000-0000-0000-000000000653", + "id": "00000000-0000-0000-0000-000000000662", }, "workflow": { - "id": "00000000-0000-0000-0000-000000000651", + "id": "00000000-0000-0000-0000-000000000660", }, }, "viewGroups": {}, }, "workflowVersionRecordPageFields": { - "id": "00000000-0000-0000-0000-000000000664", + "id": "00000000-0000-0000-0000-000000000673", "viewFieldGroups": { "additional": { - "id": "00000000-0000-0000-0000-000000000662", + "id": "00000000-0000-0000-0000-000000000671", }, "general": { - "id": "00000000-0000-0000-0000-000000000661", + "id": "00000000-0000-0000-0000-000000000670", }, "other": { - "id": "00000000-0000-0000-0000-000000000663", + "id": "00000000-0000-0000-0000-000000000672", }, }, "viewFields": { "createdAt": { - "id": "00000000-0000-0000-0000-000000000660", + "id": "00000000-0000-0000-0000-000000000669", }, "name": { - "id": "00000000-0000-0000-0000-000000000656", + "id": "00000000-0000-0000-0000-000000000665", }, "status": { - "id": "00000000-0000-0000-0000-000000000657", + "id": "00000000-0000-0000-0000-000000000666", }, "trigger": { - "id": "00000000-0000-0000-0000-000000000659", + "id": "00000000-0000-0000-0000-000000000668", }, "workflow": { - "id": "00000000-0000-0000-0000-000000000658", + "id": "00000000-0000-0000-0000-000000000667", }, }, "viewGroups": {}, @@ -2214,122 +2244,122 @@ exports[`getStandardObjectMetadataRelatedEntityIds should return standard object "workspaceMember": { "fields": { "accountOwnerForCompanies": { - "id": "00000000-0000-0000-0000-000000000680", - }, - "assignedTasks": { - "id": "00000000-0000-0000-0000-000000000677", - }, - "avatarUrl": { - "id": "00000000-0000-0000-0000-000000000674", - }, - "blocklist": { - "id": "00000000-0000-0000-0000-000000000683", - }, - "calendarEventParticipants": { - "id": "00000000-0000-0000-0000-000000000684", - }, - "calendarStartDay": { - "id": "00000000-0000-0000-0000-000000000690", - }, - "colorScheme": { - "id": "00000000-0000-0000-0000-000000000672", - }, - "connectedAccounts": { - "id": "00000000-0000-0000-0000-000000000681", - }, - "createdAt": { - "id": "00000000-0000-0000-0000-000000000667", - }, - "dateFormat": { - "id": "00000000-0000-0000-0000-000000000687", - }, - "deletedAt": { - "id": "00000000-0000-0000-0000-000000000669", - }, - "favorites": { - "id": "00000000-0000-0000-0000-000000000679", - }, - "id": { - "id": "00000000-0000-0000-0000-000000000666", - }, - "locale": { - "id": "00000000-0000-0000-0000-000000000673", - }, - "messageParticipants": { - "id": "00000000-0000-0000-0000-000000000682", - }, - "name": { - "id": "00000000-0000-0000-0000-000000000671", - }, - "numberFormat": { - "id": "00000000-0000-0000-0000-000000000691", - }, - "ownedOpportunities": { - "id": "00000000-0000-0000-0000-000000000678", - }, - "position": { - "id": "00000000-0000-0000-0000-000000000670", - }, - "searchVector": { "id": "00000000-0000-0000-0000-000000000689", }, - "timeFormat": { - "id": "00000000-0000-0000-0000-000000000688", - }, - "timeZone": { + "assignedTasks": { "id": "00000000-0000-0000-0000-000000000686", }, - "timelineActivities": { - "id": "00000000-0000-0000-0000-000000000685", + "avatarUrl": { + "id": "00000000-0000-0000-0000-000000000683", }, - "updatedAt": { - "id": "00000000-0000-0000-0000-000000000668", + "blocklist": { + "id": "00000000-0000-0000-0000-000000000692", }, - "userEmail": { - "id": "00000000-0000-0000-0000-000000000675", + "calendarEventParticipants": { + "id": "00000000-0000-0000-0000-000000000693", }, - "userId": { + "calendarStartDay": { + "id": "00000000-0000-0000-0000-000000000699", + }, + "colorScheme": { + "id": "00000000-0000-0000-0000-000000000681", + }, + "connectedAccounts": { + "id": "00000000-0000-0000-0000-000000000690", + }, + "createdAt": { "id": "00000000-0000-0000-0000-000000000676", }, + "dateFormat": { + "id": "00000000-0000-0000-0000-000000000696", + }, + "deletedAt": { + "id": "00000000-0000-0000-0000-000000000678", + }, + "favorites": { + "id": "00000000-0000-0000-0000-000000000688", + }, + "id": { + "id": "00000000-0000-0000-0000-000000000675", + }, + "locale": { + "id": "00000000-0000-0000-0000-000000000682", + }, + "messageParticipants": { + "id": "00000000-0000-0000-0000-000000000691", + }, + "name": { + "id": "00000000-0000-0000-0000-000000000680", + }, + "numberFormat": { + "id": "00000000-0000-0000-0000-000000000700", + }, + "ownedOpportunities": { + "id": "00000000-0000-0000-0000-000000000687", + }, + "position": { + "id": "00000000-0000-0000-0000-000000000679", + }, + "searchVector": { + "id": "00000000-0000-0000-0000-000000000698", + }, + "timeFormat": { + "id": "00000000-0000-0000-0000-000000000697", + }, + "timeZone": { + "id": "00000000-0000-0000-0000-000000000695", + }, + "timelineActivities": { + "id": "00000000-0000-0000-0000-000000000694", + }, + "updatedAt": { + "id": "00000000-0000-0000-0000-000000000677", + }, + "userEmail": { + "id": "00000000-0000-0000-0000-000000000684", + }, + "userId": { + "id": "00000000-0000-0000-0000-000000000685", + }, }, - "id": "00000000-0000-0000-0000-000000000704", + "id": "00000000-0000-0000-0000-000000000713", "views": { "allWorkspaceMembers": { - "id": "00000000-0000-0000-0000-000000000703", + "id": "00000000-0000-0000-0000-000000000712", "viewFieldGroups": {}, "viewFields": { "assignedTasks": { - "id": "00000000-0000-0000-0000-000000000702", + "id": "00000000-0000-0000-0000-000000000711", }, "avatarUrl": { - "id": "00000000-0000-0000-0000-000000000694", + "id": "00000000-0000-0000-0000-000000000703", }, "colorScheme": { - "id": "00000000-0000-0000-0000-000000000695", + "id": "00000000-0000-0000-0000-000000000704", }, "createdAt": { - "id": "00000000-0000-0000-0000-000000000700", + "id": "00000000-0000-0000-0000-000000000709", }, "dateFormat": { - "id": "00000000-0000-0000-0000-000000000698", + "id": "00000000-0000-0000-0000-000000000707", }, "locale": { - "id": "00000000-0000-0000-0000-000000000696", + "id": "00000000-0000-0000-0000-000000000705", }, "name": { - "id": "00000000-0000-0000-0000-000000000692", - }, - "ownedOpportunities": { "id": "00000000-0000-0000-0000-000000000701", }, + "ownedOpportunities": { + "id": "00000000-0000-0000-0000-000000000710", + }, "timeFormat": { - "id": "00000000-0000-0000-0000-000000000699", + "id": "00000000-0000-0000-0000-000000000708", }, "timeZone": { - "id": "00000000-0000-0000-0000-000000000697", + "id": "00000000-0000-0000-0000-000000000706", }, "userEmail": { - "id": "00000000-0000-0000-0000-000000000693", + "id": "00000000-0000-0000-0000-000000000702", }, }, "viewGroups": {}, diff --git a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/build-standard-flat-field-metadata-maps.util.ts b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/build-standard-flat-field-metadata-maps.util.ts index afd85b67f9..f1d49b65b1 100644 --- a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/build-standard-flat-field-metadata-maps.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/build-standard-flat-field-metadata-maps.util.ts @@ -16,6 +16,7 @@ import { buildConnectedAccountStandardFlatFieldMetadatas } from 'src/engine/work import { buildDashboardStandardFlatFieldMetadatas } from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/compute-dashboard-standard-flat-field-metadata.util'; import { buildFavoriteFolderStandardFlatFieldMetadatas } from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/compute-favorite-folder-standard-flat-field-metadata.util'; import { buildFavoriteStandardFlatFieldMetadatas } from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/compute-favorite-standard-flat-field-metadata.util'; +import { buildMessageChannelMessageAssociationMessageFolderStandardFlatFieldMetadatas } from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/compute-message-channel-message-association-message-folder-standard-flat-field-metadata.util'; import { buildMessageChannelMessageAssociationStandardFlatFieldMetadatas } from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/compute-message-channel-message-association-standard-flat-field-metadata.util'; import { buildMessageChannelStandardFlatFieldMetadatas } from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/compute-message-channel-standard-flat-field-metadata.util'; import { buildMessageFolderStandardFlatFieldMetadatas } from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/compute-message-folder-standard-flat-field-metadata.util'; @@ -58,6 +59,8 @@ const STANDARD_FLAT_FIELD_METADATA_BUILDERS_BY_OBJECT_NAME = { messageChannel: buildMessageChannelStandardFlatFieldMetadatas, messageChannelMessageAssociation: buildMessageChannelMessageAssociationStandardFlatFieldMetadatas, + messageChannelMessageAssociationMessageFolder: + buildMessageChannelMessageAssociationMessageFolderStandardFlatFieldMetadatas, messageFolder: buildMessageFolderStandardFlatFieldMetadatas, messageParticipant: buildMessageParticipantStandardFlatFieldMetadatas, messageThread: buildMessageThreadStandardFlatFieldMetadatas, diff --git a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/compute-message-channel-message-association-message-folder-standard-flat-field-metadata.util.ts b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/compute-message-channel-message-association-message-folder-standard-flat-field-metadata.util.ts new file mode 100644 index 0000000000..dee3729b61 --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/compute-message-channel-message-association-message-folder-standard-flat-field-metadata.util.ts @@ -0,0 +1,159 @@ +import { + DateDisplayFormat, + FieldMetadataType, + RelationOnDeleteAction, + RelationType, +} from 'twenty-shared/types'; + +import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; +import { type AllStandardObjectFieldName } from 'src/engine/workspace-manager/twenty-standard-application/types/all-standard-object-field-name.type'; +import { + type CreateStandardFieldArgs, + createStandardFieldFlatMetadata, +} from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-field-flat-metadata.util'; +import { createStandardRelationFieldFlatMetadata } from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-relation-field-flat-metadata.util'; + +export const buildMessageChannelMessageAssociationMessageFolderStandardFlatFieldMetadatas = + ({ + now, + objectName, + workspaceId, + standardObjectMetadataRelatedEntityIds, + dependencyFlatEntityMaps, + twentyStandardApplicationId, + }: Omit< + CreateStandardFieldArgs< + 'messageChannelMessageAssociationMessageFolder', + FieldMetadataType + >, + 'context' + >): Record< + AllStandardObjectFieldName<'messageChannelMessageAssociationMessageFolder'>, + FlatFieldMetadata + > => ({ + id: createStandardFieldFlatMetadata({ + objectName, + workspaceId, + context: { + fieldName: 'id', + type: FieldMetadataType.UUID, + label: 'Id', + description: 'Id', + icon: 'Icon123', + isSystem: true, + isNullable: false, + isUIReadOnly: true, + defaultValue: 'uuid', + }, + standardObjectMetadataRelatedEntityIds, + dependencyFlatEntityMaps, + twentyStandardApplicationId, + now, + }), + createdAt: createStandardFieldFlatMetadata({ + objectName, + workspaceId, + context: { + fieldName: 'createdAt', + type: FieldMetadataType.DATE_TIME, + label: 'Creation date', + description: 'Creation date', + icon: 'IconCalendar', + isNullable: false, + isUIReadOnly: true, + defaultValue: 'now', + settings: { displayFormat: DateDisplayFormat.RELATIVE }, + }, + standardObjectMetadataRelatedEntityIds, + dependencyFlatEntityMaps, + twentyStandardApplicationId, + now, + }), + updatedAt: createStandardFieldFlatMetadata({ + objectName, + workspaceId, + context: { + fieldName: 'updatedAt', + type: FieldMetadataType.DATE_TIME, + label: 'Last update', + description: 'Last time the record was changed', + icon: 'IconCalendarClock', + isNullable: false, + isUIReadOnly: true, + defaultValue: 'now', + settings: { displayFormat: DateDisplayFormat.RELATIVE }, + }, + standardObjectMetadataRelatedEntityIds, + dependencyFlatEntityMaps, + twentyStandardApplicationId, + now, + }), + deletedAt: createStandardFieldFlatMetadata({ + objectName, + workspaceId, + context: { + fieldName: 'deletedAt', + type: FieldMetadataType.DATE_TIME, + label: 'Deleted at', + description: 'Date when the record was deleted', + icon: 'IconCalendarMinus', + isNullable: true, + isUIReadOnly: true, + settings: { displayFormat: DateDisplayFormat.RELATIVE }, + }, + standardObjectMetadataRelatedEntityIds, + dependencyFlatEntityMaps, + twentyStandardApplicationId, + now, + }), + messageChannelMessageAssociation: createStandardRelationFieldFlatMetadata({ + objectName, + workspaceId, + context: { + type: FieldMetadataType.RELATION, + morphId: null, + fieldName: 'messageChannelMessageAssociation', + label: 'Message Channel Message Association', + description: 'Message Channel Message Association', + icon: 'IconMessage', + isNullable: false, + isUIReadOnly: true, + targetObjectName: 'messageChannelMessageAssociation', + targetFieldName: 'messageFolders', + settings: { + relationType: RelationType.MANY_TO_ONE, + onDelete: RelationOnDeleteAction.CASCADE, + joinColumnName: 'messageChannelMessageAssociationId', + }, + }, + standardObjectMetadataRelatedEntityIds, + dependencyFlatEntityMaps, + twentyStandardApplicationId, + now, + }), + messageFolder: createStandardRelationFieldFlatMetadata({ + objectName, + workspaceId, + context: { + type: FieldMetadataType.RELATION, + morphId: null, + fieldName: 'messageFolder', + label: 'Message Folder', + description: 'Message Folder', + icon: 'IconFolder', + isNullable: false, + isUIReadOnly: true, + targetObjectName: 'messageFolder', + targetFieldName: 'messageChannelMessageAssociationMessageFolders', + settings: { + relationType: RelationType.MANY_TO_ONE, + onDelete: RelationOnDeleteAction.CASCADE, + joinColumnName: 'messageFolderId', + }, + }, + standardObjectMetadataRelatedEntityIds, + dependencyFlatEntityMaps, + twentyStandardApplicationId, + now, + }), + }); diff --git a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/compute-message-channel-message-association-standard-flat-field-metadata.util.ts b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/compute-message-channel-message-association-standard-flat-field-metadata.util.ts index 9caabef4c0..add44e26cd 100644 --- a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/compute-message-channel-message-association-standard-flat-field-metadata.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/compute-message-channel-message-association-standard-flat-field-metadata.util.ts @@ -248,4 +248,27 @@ export const buildMessageChannelMessageAssociationStandardFlatFieldMetadatas = twentyStandardApplicationId, now, }), + messageFolders: createStandardRelationFieldFlatMetadata({ + objectName, + workspaceId, + context: { + type: FieldMetadataType.RELATION, + morphId: null, + fieldName: 'messageFolders', + label: 'Message Folders', + description: 'Message Folders (supports multiple folders/labels)', + icon: 'IconFolders', + isNullable: true, + isUIReadOnly: true, + targetObjectName: 'messageChannelMessageAssociationMessageFolder', + targetFieldName: 'messageChannelMessageAssociation', + settings: { + relationType: RelationType.ONE_TO_MANY, + }, + }, + standardObjectMetadataRelatedEntityIds, + dependencyFlatEntityMaps, + twentyStandardApplicationId, + now, + }), }); diff --git a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/compute-message-folder-standard-flat-field-metadata.util.ts b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/compute-message-folder-standard-flat-field-metadata.util.ts index 39b580c791..fe3a748a86 100644 --- a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/compute-message-folder-standard-flat-field-metadata.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/compute-message-folder-standard-flat-field-metadata.util.ts @@ -255,4 +255,29 @@ export const buildMessageFolderStandardFlatFieldMetadatas = ({ twentyStandardApplicationId, now, }), + messageChannelMessageAssociationMessageFolders: + createStandardRelationFieldFlatMetadata({ + objectName, + workspaceId, + context: { + type: FieldMetadataType.RELATION, + morphId: null, + fieldName: 'messageChannelMessageAssociationMessageFolders', + label: 'Message Association Folders', + description: + 'Message Association Folders (supports multiple folders/labels)', + icon: 'IconFolders', + isNullable: true, + isUIReadOnly: true, + targetObjectName: 'messageChannelMessageAssociationMessageFolder', + targetFieldName: 'messageFolder', + settings: { + relationType: RelationType.ONE_TO_MANY, + }, + }, + standardObjectMetadataRelatedEntityIds, + dependencyFlatEntityMaps, + twentyStandardApplicationId, + now, + }), }); diff --git a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/index/build-standard-flat-index-metadata-maps.util.ts b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/index/build-standard-flat-index-metadata-maps.util.ts index 458f3c6887..2f7ddc9da7 100644 --- a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/index/build-standard-flat-index-metadata-maps.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/index/build-standard-flat-index-metadata-maps.util.ts @@ -12,6 +12,7 @@ import { buildCompanyStandardFlatIndexMetadatas } from 'src/engine/workspace-man import { buildConnectedAccountStandardFlatIndexMetadatas } from 'src/engine/workspace-manager/twenty-standard-application/utils/index/compute-connected-account-standard-flat-index-metadata.util'; import { buildDashboardStandardFlatIndexMetadatas } from 'src/engine/workspace-manager/twenty-standard-application/utils/index/compute-dashboard-standard-flat-index-metadata.util'; import { buildFavoriteStandardFlatIndexMetadatas } from 'src/engine/workspace-manager/twenty-standard-application/utils/index/compute-favorite-standard-flat-index-metadata.util'; +import { buildMessageChannelMessageAssociationMessageFolderStandardFlatIndexMetadatas } from 'src/engine/workspace-manager/twenty-standard-application/utils/index/compute-message-channel-message-association-message-folder-standard-flat-index-metadata.util'; import { buildMessageChannelMessageAssociationStandardFlatIndexMetadatas } from 'src/engine/workspace-manager/twenty-standard-application/utils/index/compute-message-channel-message-association-standard-flat-index-metadata.util'; import { buildMessageChannelStandardFlatIndexMetadatas } from 'src/engine/workspace-manager/twenty-standard-application/utils/index/compute-message-channel-standard-flat-index-metadata.util'; import { buildMessageFolderStandardFlatIndexMetadatas } from 'src/engine/workspace-manager/twenty-standard-application/utils/index/compute-message-folder-standard-flat-index-metadata.util'; @@ -51,6 +52,8 @@ const STANDARD_FLAT_INDEX_METADATA_BUILDERS_BY_OBJECT_NAME = { messageChannel: buildMessageChannelStandardFlatIndexMetadatas, messageChannelMessageAssociation: buildMessageChannelMessageAssociationStandardFlatIndexMetadatas, + messageChannelMessageAssociationMessageFolder: + buildMessageChannelMessageAssociationMessageFolderStandardFlatIndexMetadatas, messageFolder: buildMessageFolderStandardFlatIndexMetadatas, messageParticipant: buildMessageParticipantStandardFlatIndexMetadatas, note: buildNoteStandardFlatIndexMetadatas, diff --git a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/index/compute-message-channel-message-association-message-folder-standard-flat-index-metadata.util.ts b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/index/compute-message-channel-message-association-message-folder-standard-flat-index-metadata.util.ts new file mode 100644 index 0000000000..ec51c4b3d5 --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/index/compute-message-channel-message-association-message-folder-standard-flat-index-metadata.util.ts @@ -0,0 +1,66 @@ +import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type'; +import { type AllStandardObjectIndexName } from 'src/engine/workspace-manager/twenty-standard-application/types/all-standard-object-index-name.type'; +import { + type CreateStandardIndexArgs, + createStandardIndexFlatMetadata, +} from 'src/engine/workspace-manager/twenty-standard-application/utils/index/create-standard-index-flat-metadata.util'; + +export const buildMessageChannelMessageAssociationMessageFolderStandardFlatIndexMetadatas = + ({ + now, + objectName, + workspaceId, + standardObjectMetadataRelatedEntityIds, + dependencyFlatEntityMaps, + twentyStandardApplicationId, + }: Omit< + CreateStandardIndexArgs<'messageChannelMessageAssociationMessageFolder'>, + 'context' + >): Record< + AllStandardObjectIndexName<'messageChannelMessageAssociationMessageFolder'>, + FlatIndexMetadata + > => ({ + messageChannelMessageAssociationIdIndex: createStandardIndexFlatMetadata({ + objectName, + workspaceId, + context: { + indexName: 'messageChannelMessageAssociationIdIndex', + relatedFieldNames: ['messageChannelMessageAssociation'], + }, + standardObjectMetadataRelatedEntityIds, + dependencyFlatEntityMaps, + twentyStandardApplicationId, + now, + }), + messageFolderIdIndex: createStandardIndexFlatMetadata({ + objectName, + workspaceId, + context: { + indexName: 'messageFolderIdIndex', + relatedFieldNames: ['messageFolder'], + }, + standardObjectMetadataRelatedEntityIds, + dependencyFlatEntityMaps, + twentyStandardApplicationId, + now, + }), + messageChannelMessageAssociationIdMessageFolderIdUniqueIndex: + createStandardIndexFlatMetadata({ + objectName, + workspaceId, + context: { + indexName: + 'messageChannelMessageAssociationIdMessageFolderIdUniqueIndex', + relatedFieldNames: [ + 'messageChannelMessageAssociation', + 'messageFolder', + ], + isUnique: true, + indexWhereClause: '"deletedAt" IS NULL', + }, + standardObjectMetadataRelatedEntityIds, + dependencyFlatEntityMaps, + twentyStandardApplicationId, + now, + }), + }); diff --git a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/object-metadata/create-standard-flat-object-metadata.util.ts b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/object-metadata/create-standard-flat-object-metadata.util.ts index fa2c6e3c91..01bb10c9db 100644 --- a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/object-metadata/create-standard-flat-object-metadata.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/object-metadata/create-standard-flat-object-metadata.util.ts @@ -416,6 +416,39 @@ export const STANDARD_FLAT_OBJECT_METADATA_BUILDERS_BY_OBJECT_NAME = { twentyStandardApplicationId, now, }), + messageChannelMessageAssociationMessageFolder: ({ + now, + workspaceId, + standardObjectMetadataRelatedEntityIds, + twentyStandardApplicationId, + dependencyFlatEntityMaps, + }: Omit< + CreateStandardObjectArgs<'messageChannelMessageAssociationMessageFolder'>, + 'context' | 'objectName' + >) => + createStandardObjectFlatMetadata({ + objectName: 'messageChannelMessageAssociationMessageFolder', + dependencyFlatEntityMaps, + context: { + universalIdentifier: + STANDARD_OBJECTS.messageChannelMessageAssociationMessageFolder + .universalIdentifier, + nameSingular: 'messageChannelMessageAssociationMessageFolder', + namePlural: 'messageChannelMessageAssociationMessageFolders', + labelSingular: 'Message Channel Message Association Message Folder', + labelPlural: 'Message Channel Message Association Message Folders', + description: + 'Join table linking message channel message associations to message folders', + icon: 'IconFolder', + isSystem: true, + isAuditLogged: false, + labelIdentifierFieldMetadataName: 'id', + }, + workspaceId, + standardObjectMetadataRelatedEntityIds, + twentyStandardApplicationId, + now, + }), messageParticipant: ({ now, workspaceId, diff --git a/packages/twenty-server/src/modules/messaging/common/standard-objects/message-channel-message-association-message-folder.workspace-entity.ts b/packages/twenty-server/src/modules/messaging/common/standard-objects/message-channel-message-association-message-folder.workspace-entity.ts new file mode 100644 index 0000000000..74de2bd52b --- /dev/null +++ b/packages/twenty-server/src/modules/messaging/common/standard-objects/message-channel-message-association-message-folder.workspace-entity.ts @@ -0,0 +1,11 @@ +import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity'; +import { type EntityRelation } from 'src/engine/workspace-manager/workspace-migration/types/entity-relation.interface'; +import { type MessageChannelMessageAssociationWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel-message-association.workspace-entity'; +import { type MessageFolderWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-folder.workspace-entity'; + +export class MessageChannelMessageAssociationMessageFolderWorkspaceEntity extends BaseWorkspaceEntity { + messageChannelMessageAssociation: EntityRelation; + messageChannelMessageAssociationId: string; + messageFolder: EntityRelation; + messageFolderId: string; +} diff --git a/packages/twenty-server/src/modules/messaging/common/standard-objects/message-channel-message-association.workspace-entity.ts b/packages/twenty-server/src/modules/messaging/common/standard-objects/message-channel-message-association.workspace-entity.ts index 29728e6f92..2f1608ec63 100644 --- a/packages/twenty-server/src/modules/messaging/common/standard-objects/message-channel-message-association.workspace-entity.ts +++ b/packages/twenty-server/src/modules/messaging/common/standard-objects/message-channel-message-association.workspace-entity.ts @@ -1,6 +1,7 @@ import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity'; import { type EntityRelation } from 'src/engine/workspace-manager/workspace-migration/types/entity-relation.interface'; import { type MessageDirection } from 'src/modules/messaging/common/enums/message-direction.enum'; +import { type MessageChannelMessageAssociationMessageFolderWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel-message-association-message-folder.workspace-entity'; import { type MessageChannelWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity'; import { type MessageWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message.workspace-entity'; @@ -12,4 +13,7 @@ export class MessageChannelMessageAssociationWorkspaceEntity extends BaseWorkspa messageChannelId: string; message: EntityRelation | null; messageId: string; + messageFolders: EntityRelation< + MessageChannelMessageAssociationMessageFolderWorkspaceEntity[] + >; } diff --git a/packages/twenty-server/src/modules/messaging/common/standard-objects/message-folder.workspace-entity.ts b/packages/twenty-server/src/modules/messaging/common/standard-objects/message-folder.workspace-entity.ts index 513e7073fb..306f41d570 100644 --- a/packages/twenty-server/src/modules/messaging/common/standard-objects/message-folder.workspace-entity.ts +++ b/packages/twenty-server/src/modules/messaging/common/standard-objects/message-folder.workspace-entity.ts @@ -2,6 +2,7 @@ import { registerEnumType } from '@nestjs/graphql'; import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity'; import { type EntityRelation } from 'src/engine/workspace-manager/workspace-migration/types/entity-relation.interface'; +import { type MessageChannelMessageAssociationMessageFolderWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel-message-association-message-folder.workspace-entity'; import { type MessageChannelWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity'; export enum MessageFolderPendingSyncAction { @@ -23,4 +24,7 @@ export class MessageFolderWorkspaceEntity extends BaseWorkspaceEntity { externalId: string | null; pendingSyncAction: MessageFolderPendingSyncAction; messageChannelId: string; + messageChannelMessageAssociationMessageFolders: EntityRelation< + MessageChannelMessageAssociationMessageFolderWorkspaceEntity[] + >; } diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/gmail/utils/parse-and-format-gmail-message.util.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/gmail/utils/parse-and-format-gmail-message.util.ts index 50ba1f9b4e..df0242871d 100644 --- a/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/gmail/utils/parse-and-format-gmail-message.util.ts +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/gmail/utils/parse-and-format-gmail-message.util.ts @@ -84,6 +84,7 @@ export const parseAndFormatGmailMessage = ( participants, text: sanitizeString(textWithoutReplyQuotations), attachments, + messageFolderExternalIds: labelIds, labelIds, }; }; diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/imap/services/imap-get-messages.service.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/imap/services/imap-get-messages.service.ts index b06e203915..0583215d37 100644 --- a/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/imap/services/imap-get-messages.service.ts +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/imap/services/imap-get-messages.service.ts @@ -44,13 +44,11 @@ export class ImapGetMessagesService { const client = await this.imapClientProvider.getClient(connectedAccount); try { - const messages = await this.fetchFromAllFolders( + return await this.fetchFromAllFolders( messagesByFolder, client, connectedAccount, ); - - return messages; } finally { await this.imapClientProvider.closeClient(client); } @@ -112,11 +110,16 @@ export class ImapGetMessagesService { ); const startTime = Date.now(); - const results = await this.messageParser.parseMessagesFromFolder( - messageUids, - folderPath, - client, - ); + const { messages: results, uidValidity } = + await this.messageParser.parseMessagesFromFolder( + messageUids, + folderPath, + client, + ); + + const folderExternalId = uidValidity + ? `${folderPath}:${uidValidity}` + : folderPath; const messages: MessageWithParticipants[] = []; @@ -141,6 +144,7 @@ export class ImapGetMessagesService { result.parsed, result.uid, folderPath, + folderExternalId, connectedAccount, ), ); @@ -157,6 +161,7 @@ export class ImapGetMessagesService { parsed: ParsedMail, uid: number, folderPath: string, + folderExternalId: string, connectedAccount: Pick< ConnectedAccountWorkspaceEntity, 'handle' | 'handleAliases' @@ -179,6 +184,7 @@ export class ImapGetMessagesService { direction: computeMessageDirection(senderAddress, connectedAccount), attachments: this.extractAttachments(parsed), participants: this.extractParticipants(parsed), + messageFolderExternalIds: [folderExternalId], }; } diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/imap/services/imap-message-parser.service.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/imap/services/imap-message-parser.service.ts index 3021bf2024..350645440f 100644 --- a/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/imap/services/imap-message-parser.service.ts +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/imap/services/imap-message-parser.service.ts @@ -9,6 +9,11 @@ export type MessageParseResult = { error?: Error; }; +export type FolderParseResult = { + messages: MessageParseResult[]; + uidValidity: bigint | null; +}; + @Injectable() export class ImapMessageParserService { private readonly logger = new Logger(ImapMessageParserService.name); @@ -17,14 +22,19 @@ export class ImapMessageParserService { messageUids: number[], folderPath: string, client: ImapFlow, - ): Promise { + ): Promise { if (!messageUids.length) { - return []; + return { messages: [], uidValidity: null }; } const lock = await client.getMailboxLock(folderPath); try { + const uidValidity = + client.mailbox && typeof client.mailbox !== 'boolean' + ? client.mailbox.uidValidity + : null; + const uidSet = messageUids.join(','); const startTime = Date.now(); @@ -52,13 +62,16 @@ export class ImapMessageParserService { `Fetched and parsed ${results.length} messages from ${folderPath} in ${Date.now() - startTime}ms`, ); - return results; + return { messages: results, uidValidity }; } catch (error) { this.logger.error( `Failed to parse messages from folder ${folderPath}: ${error.message}`, ); - return this.createErrorResults(messageUids, error as Error); + return { + messages: this.createErrorResults(messageUids, error as Error), + uidValidity: null, + }; } finally { lock.release(); } diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/microsoft/services/microsoft-get-messages.service.spec.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/microsoft/services/microsoft-get-messages.service.spec.ts index da35e1f39f..bb597fc616 100644 --- a/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/microsoft/services/microsoft-get-messages.service.spec.ts +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/microsoft/services/microsoft-get-messages.service.spec.ts @@ -109,6 +109,9 @@ describe('Microsoft get messages service', () => { }, ], attachments: [], + messageFolderExternalIds: responseExample1.body.parentFolderId + ? [responseExample1.body.parentFolderId] + : [], }); const responseExample2 = @@ -152,6 +155,9 @@ describe('Microsoft get messages service', () => { }, ], attachments: [], + messageFolderExternalIds: responseExample2.body.parentFolderId + ? [responseExample2.body.parentFolderId] + : [], }); }); @@ -191,6 +197,9 @@ describe('Microsoft get messages service', () => { }, ], attachments: [], + messageFolderExternalIds: responseExample.body.parentFolderId + ? [responseExample.body.parentFolderId] + : [], }); }); }); diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/microsoft/services/microsoft-get-messages.service.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/microsoft/services/microsoft-get-messages.service.ts index 021957bee9..51853f8bd1 100644 --- a/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/microsoft/services/microsoft-get-messages.service.ts +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/microsoft/services/microsoft-get-messages.service.ts @@ -1,8 +1,8 @@ import { Injectable, Logger } from '@nestjs/common'; import { type EmailAddress } from 'addressparser'; -import { isDefined } from 'twenty-shared/utils'; import { MessageParticipantRole } from 'twenty-shared/types'; +import { isDefined } from 'twenty-shared/utils'; import { type ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity'; import { MessageDirection } from 'src/modules/messaging/common/enums/message-direction.enum'; @@ -151,6 +151,9 @@ export class MicrosoftGetMessagesService { : MessageDirection.INCOMING, participants, attachments: [], + messageFolderExternalIds: response.parentFolderId + ? [response.parentFolderId] + : [], }; }); diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/messaging-import-manager.module.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/messaging-import-manager.module.ts index 5b616fcb87..5f28d291ac 100644 --- a/packages/twenty-server/src/modules/messaging/message-import-manager/messaging-import-manager.module.ts +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/messaging-import-manager.module.ts @@ -42,6 +42,7 @@ import { MessagingDeleteGroupEmailMessagesService } from 'src/modules/messaging/ import { MessagingGetMessageListService } from 'src/modules/messaging/message-import-manager/services/messaging-get-message-list.service'; import { MessagingGetMessagesService } from 'src/modules/messaging/message-import-manager/services/messaging-get-messages.service'; import { MessageImportExceptionHandlerService } from 'src/modules/messaging/message-import-manager/services/messaging-import-exception-handler.service'; +import { MessagingMessageFolderAssociationService } from 'src/modules/messaging/message-import-manager/services/messaging-message-folder-association.service'; import { MessagingMessageListFetchService } from 'src/modules/messaging/message-import-manager/services/messaging-message-list-fetch.service'; import { MessagingMessageService } from 'src/modules/messaging/message-import-manager/services/messaging-message.service'; import { MessagingMessagesImportService } from 'src/modules/messaging/message-import-manager/services/messaging-messages-import.service'; @@ -93,6 +94,7 @@ import { MessagingMonitoringModule } from 'src/modules/messaging/monitoring/mess MessagingMessageImportManagerMessageChannelListener, MessagingCleanCacheJob, MessagingMessageService, + MessagingMessageFolderAssociationService, MessagingMessageListFetchService, MessagingMessagesImportService, MessagingSaveMessagesAndEnqueueContactCreationService, diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-delete-folder-messages.service.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-delete-folder-messages.service.ts index 7638c50ec1..cc2dcbae2b 100644 --- a/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-delete-folder-messages.service.ts +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-delete-folder-messages.service.ts @@ -1,12 +1,17 @@ import { Injectable, Logger } from '@nestjs/common'; -import chunk from 'lodash.chunk'; import { isDefined } from 'twenty-shared/utils'; +import { In } from 'typeorm'; +import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; +import { buildSystemAuthContext } from 'src/engine/twenty-orm/utils/build-system-auth-context.util'; +import { type MessageChannelMessageAssociationMessageFolderWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel-message-association-message-folder.workspace-entity'; +import { type MessageChannelMessageAssociationWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel-message-association.workspace-entity'; import { 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'; import { MessagingMessageCleanerService } from 'src/modules/messaging/message-cleaner/services/messaging-message-cleaner.service'; -import { MessagingGetMessageListService } from 'src/modules/messaging/message-import-manager/services/messaging-get-message-list.service'; + +const BATCH_SIZE = 200; @Injectable() export class MessagingDeleteFolderMessagesService { @@ -16,7 +21,7 @@ export class MessagingDeleteFolderMessagesService { constructor( private readonly messagingMessageCleanerService: MessagingMessageCleanerService, - private readonly messagingGetMessageListService: MessagingGetMessageListService, + private readonly globalWorkspaceOrmManager: GlobalWorkspaceOrmManager, ) {} async deleteFolderMessages( @@ -28,45 +33,81 @@ export class MessagingDeleteFolderMessagesService { `WorkspaceId: ${workspaceId}, MessageChannelId: ${messageChannel.id}, FolderId: ${messageFolder.id} - Deleting messages from folder: ${messageFolder.name}`, ); - const messageLists = - await this.messagingGetMessageListService.getMessageLists( - messageChannel, - [messageFolder], - ); + const authContext = buildSystemAuthContext(workspaceId); let totalDeletedCount = 0; - for (const messageList of messageLists) { - const { messageExternalIds } = messageList; + await this.globalWorkspaceOrmManager.executeInWorkspaceContext(async () => { + const messageFolderAssociationRepository = + await this.globalWorkspaceOrmManager.getRepository( + workspaceId, + 'messageChannelMessageAssociationMessageFolder', + ); - if (messageExternalIds.length === 0) { - continue; - } + const messageChannelMessageAssociationRepository = + await this.globalWorkspaceOrmManager.getRepository( + workspaceId, + 'messageChannelMessageAssociation', + ); - const messageExternalIdsChunks = chunk(messageExternalIds, 200); + let hasMoreData = true; - for (const messageExternalIdsChunk of messageExternalIdsChunks) { - const validExternalIds = messageExternalIdsChunk.filter(isDefined); + while (hasMoreData) { + const folderAssociations = + await messageFolderAssociationRepository.find({ + where: { + messageFolderId: messageFolder.id, + }, + take: BATCH_SIZE, + }); - if (validExternalIds.length === 0) { + if (folderAssociations.length === 0) { + hasMoreData = false; continue; } - await this.messagingMessageCleanerService.deleteMessagesChannelMessageAssociationsAndRelatedOrphans( - { - workspaceId, - messageExternalIds: validExternalIds, - messageChannelId: messageChannel.id, - }, + const folderAssociationIds = folderAssociations.map( + (folderAssociation) => folderAssociation.id, ); - totalDeletedCount += validExternalIds.length; - - this.logger.debug( - `WorkspaceId: ${workspaceId}, MessageChannelId: ${messageChannel.id}, FolderId: ${messageFolder.id} - Processed ${validExternalIds.length} message deletions`, + const messageChannelMessageAssociationIds = folderAssociations.map( + (folderAssociation) => + folderAssociation.messageChannelMessageAssociationId, ); + + const associations = + await messageChannelMessageAssociationRepository.find({ + where: { + id: In(messageChannelMessageAssociationIds), + messageChannelId: messageChannel.id, + }, + }); + + const messageExternalIds = associations + .map((association) => association.messageExternalId) + .filter(isDefined); + + this.logger.log( + `WorkspaceId: ${workspaceId}, MessageChannelId: ${messageChannel.id}, FolderId: ${messageFolder.id} - Deleting ${messageExternalIds.length} messages`, + ); + + if (messageExternalIds.length > 0) { + await this.messagingMessageCleanerService.deleteMessagesChannelMessageAssociationsAndRelatedOrphans( + { + workspaceId, + messageExternalIds, + messageChannelId: messageChannel.id, + }, + ); + + totalDeletedCount += messageExternalIds.length; + } + + await messageFolderAssociationRepository.delete({ + id: In(folderAssociationIds), + }); } - } + }, authContext); this.logger.log( `WorkspaceId: ${workspaceId}, MessageChannelId: ${messageChannel.id}, FolderId: ${messageFolder.id} - Completed deleting ${totalDeletedCount} messages from folder: ${messageFolder.name}`, diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-get-message-list.service.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-get-message-list.service.ts index 512ee6f003..6af7a32847 100644 --- a/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-get-message-list.service.ts +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-get-message-list.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common'; import { ConnectedAccountProvider } from 'twenty-shared/types'; -import { MessageFolder } from 'src/modules/messaging/message-folder-manager/interfaces/message-folder-driver.interface'; +import { type MessageFolder } from 'src/modules/messaging/message-folder-manager/interfaces/message-folder-driver.interface'; import { type MessageChannelWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity'; import { diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-message-folder-association.service.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-message-folder-association.service.ts new file mode 100644 index 0000000000..3950e9dbd3 --- /dev/null +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-message-folder-association.service.ts @@ -0,0 +1,85 @@ +import { Injectable } from '@nestjs/common'; + +import { In } from 'typeorm'; + +import { type WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager'; +import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; +import { buildSystemAuthContext } from 'src/engine/twenty-orm/utils/build-system-auth-context.util'; +import { type MessageChannelMessageAssociationMessageFolderWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel-message-association-message-folder.workspace-entity'; + +export type MessageChannelMessageAssociationFolderAssociation = { + messageChannelMessageAssociationId: string; + messageFolderIds: string[]; +}; + +@Injectable() +export class MessagingMessageFolderAssociationService { + constructor( + private readonly globalWorkspaceOrmManager: GlobalWorkspaceOrmManager, + ) {} + + async saveMessageFolderAssociations( + associations: MessageChannelMessageAssociationFolderAssociation[], + workspaceId: string, + transactionManager?: WorkspaceEntityManager, + ): Promise { + if (associations.length === 0) { + return; + } + + const authContext = buildSystemAuthContext(workspaceId); + + await this.globalWorkspaceOrmManager.executeInWorkspaceContext(async () => { + const repository = + await this.globalWorkspaceOrmManager.getRepository( + workspaceId, + 'messageChannelMessageAssociationMessageFolder', + ); + + const records = associations.flatMap((association) => + association.messageFolderIds.map((folderId) => ({ + messageChannelMessageAssociationId: + association.messageChannelMessageAssociationId, + messageFolderId: folderId, + })), + ); + + if (records.length === 0) { + return; + } + + const associationIds = [ + ...new Set( + records.map((record) => record.messageChannelMessageAssociationId), + ), + ]; + + const existingRecords = await repository.find( + { + where: { + messageChannelMessageAssociationId: In(associationIds), + }, + }, + transactionManager, + ); + + const existingKeys = new Set( + existingRecords.map( + (record) => + `${record.messageChannelMessageAssociationId}:${record.messageFolderId}`, + ), + ); + + const recordsToInsert = records.filter( + (record) => + !existingKeys.has( + `${record.messageChannelMessageAssociationId}:${record.messageFolderId}`, + ), + ); + + if (recordsToInsert.length > 0) { + await repository.insert(recordsToInsert, transactionManager); + } + }, authContext); + } +} diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-message.service.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-message.service.ts index 7a5c07ebe1..84f7a067d9 100644 --- a/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-message.service.ts +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-message.service.ts @@ -28,6 +28,7 @@ type MessageAccumulator = { threadToCreate?: Pick; messageChannelMessageAssociationToCreate?: Pick< MessageChannelMessageAssociationWorkspaceEntity, + | 'id' | 'messageChannelId' | 'messageId' | 'messageExternalId' @@ -51,6 +52,10 @@ export class MessagingMessageService { ): Promise<{ createdMessages: Partial[]; messageExternalIdsAndIdsMap: Map; + messageExternalIdToMessageChannelMessageAssociationIdMap: Map< + string, + string + >; }> { const authContext = buildSystemAuthContext(workspaceId); @@ -176,15 +181,16 @@ export class MessagingMessageService { ) ) { messageAccumulator.messageChannelMessageAssociationToCreate = { + id: v4(), messageChannelId, messageId: newOrExistingMessageId, messageExternalId: message.externalId, messageThreadExternalId: message.messageThreadExternalId, direction: message.direction, }; - - messageAccumulatorMap.set(message.externalId, messageAccumulator); } + + messageAccumulatorMap.set(message.externalId, messageAccumulator); } const messageThreadsToCreate = Array.from( @@ -219,6 +225,8 @@ export class MessagingMessageService { ); const messageExternalIdsAndIdsMap = new Map(); + const messageExternalIdToMessageChannelMessageAssociationIdMap = + new Map(); for (const [ externalId, @@ -237,11 +245,25 @@ export class MessagingMessageService { accumulator.existingMessageInDB.id, ); } + + const createdAssociationId = + accumulator.messageChannelMessageAssociationToCreate?.id; + const existingAssociationId = + accumulator.existingMessageChannelMessageAssociationInDB?.id; + const associationId = createdAssociationId ?? existingAssociationId; + + if (isDefined(associationId)) { + messageExternalIdToMessageChannelMessageAssociationIdMap.set( + externalId, + associationId, + ); + } } return { createdMessages: messagesToCreate, messageExternalIdsAndIdsMap, + messageExternalIdToMessageChannelMessageAssociationIdMap, }; }, authContext, diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-messages-import.service.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-messages-import.service.ts index a9e36ce186..8265adc5bc 100644 --- a/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-messages-import.service.ts +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-messages-import.service.ts @@ -124,6 +124,25 @@ export class MessagingMessagesImportService { messageChannel, ); + // Map external folder IDs to internal folder IDs + const messageFolders = messageChannel.messageFolders ?? []; + const foldersWithExternalId = messageFolders.filter( + (folder): folder is typeof folder & { externalId: string } => + isDefined(folder.externalId), + ); + + const folderExternalToInternalMap = new Map( + foldersWithExternalId.map((folder) => [folder.externalId, folder.id]), + ); + + for (const message of allMessages) { + const externalFolderIds = message.messageFolderExternalIds ?? []; + + message.messageFolderIds = externalFolderIds + .map((externalId) => folderExternalToInternalMap.get(externalId)) + .filter(isDefined); + } + const blocklist = await this.blocklistRepository.getByWorkspaceMemberId( connectedAccountWithFreshTokens.accountOwnerId, workspaceId, diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-save-messages-and-enqueue-contact-creation.service.spec.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-save-messages-and-enqueue-contact-creation.service.spec.ts index c40762f572..609d9e6684 100644 --- a/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-save-messages-and-enqueue-contact-creation.service.spec.ts +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-save-messages-and-enqueue-contact-creation.service.spec.ts @@ -15,6 +15,7 @@ import { MessageChannelContactAutoCreationPolicy, type MessageChannelWorkspaceEntity, } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity'; +import { MessagingMessageFolderAssociationService } from 'src/modules/messaging/message-import-manager/services/messaging-message-folder-association.service'; import { MessagingMessageService } from 'src/modules/messaging/message-import-manager/services/messaging-message.service'; import { MessagingSaveMessagesAndEnqueueContactCreationService } from 'src/modules/messaging/message-import-manager/services/messaging-save-messages-and-enqueue-contact-creation.service'; import { type MessageWithParticipants } from 'src/modules/messaging/message-import-manager/types/message'; @@ -151,6 +152,14 @@ describe('MessagingSaveMessagesAndEnqueueContactCreationService', () => { saveMessageParticipants: jest.fn().mockResolvedValue(undefined), }, }, + { + provide: MessagingMessageFolderAssociationService, + useValue: { + saveMessageFolderAssociations: jest + .fn() + .mockResolvedValue(undefined), + }, + }, { provide: GlobalWorkspaceOrmManager, useValue: { diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-save-messages-and-enqueue-contact-creation.service.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-save-messages-and-enqueue-contact-creation.service.ts index 505e7f82fb..9a684ee002 100644 --- a/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-save-messages-and-enqueue-contact-creation.service.ts +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-save-messages-and-enqueue-contact-creation.service.ts @@ -1,6 +1,7 @@ import { Injectable } from '@nestjs/common'; import { FieldActorSource, MessageParticipantRole } from 'twenty-shared/types'; +import { isDefined } from 'twenty-shared/utils'; import { InjectMessageQueue } from 'src/engine/core-modules/message-queue/decorators/message-queue.decorator'; import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants'; @@ -21,6 +22,10 @@ import { type Participant, type ParticipantWithMessageId, } from 'src/modules/messaging/message-import-manager/drivers/gmail/types/gmail-message.type'; +import { + type MessageChannelMessageAssociationFolderAssociation, + MessagingMessageFolderAssociationService, +} from 'src/modules/messaging/message-import-manager/services/messaging-message-folder-association.service'; import { MessagingMessageService } from 'src/modules/messaging/message-import-manager/services/messaging-message.service'; import { type MessageWithParticipants } from 'src/modules/messaging/message-import-manager/types/message'; import { MessagingMessageParticipantService } from 'src/modules/messaging/message-participant-manager/services/messaging-message-participant.service'; @@ -33,6 +38,7 @@ export class MessagingSaveMessagesAndEnqueueContactCreationService { private readonly messageQueueService: MessageQueueService, private readonly messageService: MessagingMessageService, private readonly messageParticipantService: MessagingMessageParticipantService, + private readonly messageFolderAssociationService: MessagingMessageFolderAssociationService, private readonly globalWorkspaceOrmManager: GlobalWorkspaceOrmManager, ) {} @@ -53,13 +59,15 @@ export class MessagingSaveMessagesAndEnqueueContactCreationService { return workspaceDataSource?.transaction( async (transactionManager: WorkspaceEntityManager) => { - const { messageExternalIdsAndIdsMap } = - await this.messageService.saveMessagesWithinTransaction( - messagesToSave, - messageChannel.id, - transactionManager, - workspaceId, - ); + const { + messageExternalIdsAndIdsMap, + messageExternalIdToMessageChannelMessageAssociationIdMap, + } = await this.messageService.saveMessagesWithinTransaction( + messagesToSave, + messageChannel.id, + transactionManager, + workspaceId, + ); const participantsWithMessageId: (ParticipantWithMessageId & { shouldCreateContact: boolean; @@ -112,6 +120,37 @@ export class MessagingSaveMessagesAndEnqueueContactCreationService { transactionManager, ); + const folderAssociations: MessageChannelMessageAssociationFolderAssociation[] = + messagesToSave.flatMap((message) => { + const messageFolderIds = message.messageFolderIds ?? []; + + if (messageFolderIds.length === 0) { + return []; + } + + const associationId = + messageExternalIdToMessageChannelMessageAssociationIdMap.get( + message.externalId, + ); + + if (!isDefined(associationId)) { + return []; + } + + return [ + { + messageChannelMessageAssociationId: associationId, + messageFolderIds, + }, + ]; + }); + + await this.messageFolderAssociationService.saveMessageFolderAssociations( + folderAssociations, + workspaceId, + transactionManager, + ); + return participantsWithMessageId; }, ); diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/types/message.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/types/message.ts index e833e92808..96d2efbed1 100644 --- a/packages/twenty-server/src/modules/messaging/message-import-manager/types/message.ts +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/types/message.ts @@ -11,6 +11,7 @@ export type Message = Omit< | 'messageParticipants' | 'messageThread' | 'messageThreadId' + | 'messageFolders' | 'id' > & { attachments: { @@ -19,6 +20,8 @@ export type Message = Omit< externalId: string; messageThreadExternalId: string; direction: MessageDirection; + messageFolderIds?: string[]; + messageFolderExternalIds?: string[]; labelIds?: string[]; }; diff --git a/packages/twenty-shared/src/metadata/standard-object.constant.ts b/packages/twenty-shared/src/metadata/standard-object.constant.ts index 475ed27df1..f21fe0cca9 100644 --- a/packages/twenty-shared/src/metadata/standard-object.constant.ts +++ b/packages/twenty-shared/src/metadata/standard-object.constant.ts @@ -780,6 +780,9 @@ export const STANDARD_OBJECTS = { direction: { universalIdentifier: '75c9b0f7-9e76-44d4-a2f9-47051e61eec7', }, + messageFolders: { + universalIdentifier: '20202020-c3d4-e5f6-a7b8-901234567890', + }, }, indexes: { messageChannelIdIndex: { @@ -793,6 +796,40 @@ export const STANDARD_OBJECTS = { }, }, }, + messageChannelMessageAssociationMessageFolder: { + universalIdentifier: '20202020-a1b0-40b0-8ab0-5b6c7d8e9f0a', + fields: { + id: { + universalIdentifier: '20202020-a1b2-40b1-8ab1-6b7c8d9e0f1a', + }, + createdAt: { + universalIdentifier: '20202020-a1b3-40b2-9bb2-7c8d9e0f1a2b', + }, + updatedAt: { + universalIdentifier: '20202020-a1b4-40b3-8cb3-8d9e0f1a2b3c', + }, + deletedAt: { + universalIdentifier: '20202020-a1b5-40b4-9db4-9e0f1a2b3c4d', + }, + messageChannelMessageAssociation: { + universalIdentifier: '20202020-d4e5-f6a7-b8c9-012345678901', + }, + messageFolder: { + universalIdentifier: '20202020-e5f6-a7b8-c9d0-123456789012', + }, + }, + indexes: { + messageChannelMessageAssociationIdIndex: { + universalIdentifier: '2b38d3e7-5779-4c1f-4e0f-78c9d70d1de9', + }, + messageFolderIdIndex: { + universalIdentifier: '3c49e4f8-6880-4d2a-5f1a-89d0e81e2ef0', + }, + messageChannelMessageAssociationIdMessageFolderIdUniqueIndex: { + universalIdentifier: '4d50f5a9-7991-4e3b-6a2b-90e1f92f3f01', + }, + }, + }, messageChannel: { universalIdentifier: '20202020-fe8c-40bc-a681-b80b771449b7', fields: { @@ -906,6 +943,9 @@ export const STANDARD_OBJECTS = { pendingSyncAction: { universalIdentifier: '20202020-4f97-4c79-9517-16387fe237f7', }, + messageChannelMessageAssociationMessageFolders: { + universalIdentifier: '20202020-f6a7-b8c9-d0e1-234567890123', + }, }, indexes: { messageChannelIdIndex: {