From ef8789fad683be6bf82af49ef27893f298f7b5b9 Mon Sep 17 00:00:00 2001 From: neo773 <62795688+neo773@users.noreply.github.com> Date: Mon, 30 Mar 2026 16:41:38 +0530 Subject: [PATCH] fix: convert empty parentFolderId to null in messageFolder core dual-write (#19110) --- .../message-folder-data-access.service.ts | 52 ++++++++++++++----- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/packages/twenty-server/src/engine/metadata-modules/message-folder/data-access/services/message-folder-data-access.service.ts b/packages/twenty-server/src/engine/metadata-modules/message-folder/data-access/services/message-folder-data-access.service.ts index 5937cbef604..fb716632e00 100644 --- a/packages/twenty-server/src/engine/metadata-modules/message-folder/data-access/services/message-folder-data-access.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/message-folder/data-access/services/message-folder-data-access.service.ts @@ -1,7 +1,9 @@ import { Injectable, Logger } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; +import { isNonEmptyString } from '@sniptt/guards'; import { FeatureFlagKey } from 'twenty-shared/types'; +import { isDefined } from 'twenty-shared/utils'; import { validate as uuidValidate } from 'uuid'; import { type FindOneOptions, @@ -33,28 +35,50 @@ export class MessageFolderDataAccessService { ); } - // Workspace stores parentFolderId as an externalId (text), - // core stores it as a uuid FK. Resolve during dual-write. + private async resolveParentFolderIdForCore( + workspaceId: string, + parentFolderId: string | null, + messageChannelId: string | undefined, + ): Promise { + if (!isNonEmptyString(parentFolderId)) { + return null; + } + + if (uuidValidate(parentFolderId)) { + return parentFolderId; + } + + if (!isDefined(messageChannelId)) { + return null; + } + + const parentFolder = await this.coreRepository.findOne({ + where: { + workspaceId, + messageChannelId, + externalId: parentFolderId, + }, + select: ['id'], + }); + + return parentFolder?.id ?? null; + } + private async toCore( workspaceId: string, data: Partial, messageChannelId?: string, ): Promise> { const coreData: Record = { ...data, workspaceId }; - const parentFolderId = coreData.parentFolderId as string | null; + const channelId = (coreData.messageChannelId as string) ?? messageChannelId; - if (parentFolderId && !uuidValidate(parentFolderId) && channelId) { - const parentFolder = await this.coreRepository.findOne({ - where: { - workspaceId, - messageChannelId: channelId, - externalId: parentFolderId, - }, - select: ['id'], - }); - - coreData.parentFolderId = parentFolder?.id ?? null; + if ('parentFolderId' in coreData) { + coreData.parentFolderId = await this.resolveParentFolderIdForCore( + workspaceId, + coreData.parentFolderId as string | null, + channelId, + ); } return coreData;