diff --git a/packages/twenty-server/src/engine/core-modules/file-storage/__tests__/file-storage.service.spec.ts b/packages/twenty-server/src/engine/core-modules/file-storage/__tests__/file-storage.service.spec.ts index 3f4a036c686..2e86f3c8f8f 100644 --- a/packages/twenty-server/src/engine/core-modules/file-storage/__tests__/file-storage.service.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/file-storage/__tests__/file-storage.service.spec.ts @@ -16,6 +16,8 @@ describe('FileStorageService', () => { const mockFileRepository = { save: jest.fn(), + findOneOrFail: jest.fn(), + delete: jest.fn(), }; const mockApplicationRepository = { @@ -193,6 +195,51 @@ describe('FileStorageService', () => { }); }); + describe('deleteByFileId', () => { + it('should build the correct storage path using applicationUniversalIdentifier', async () => { + const fileId = 'file-uuid'; + const workspaceId = 'ws-uuid'; + const applicationId = 'app-uuid'; + const applicationUniversalIdentifier = 'twenty-standard'; + + mockFileRepository.findOneOrFail.mockResolvedValue({ + id: fileId, + workspaceId, + applicationId, + path: 'files-field/field-uid/file-uuid.pdf', + }); + + mockApplicationRepository.findOneOrFail.mockResolvedValue({ + id: applicationId, + universalIdentifier: applicationUniversalIdentifier, + workspaceId, + }); + + mockDriver.delete.mockResolvedValue(undefined); + mockFileRepository.delete.mockResolvedValue(undefined); + + await service.deleteByFileId({ + fileId, + workspaceId, + fileFolder: 'files-field' as any, + }); + + expect(mockApplicationRepository.findOneOrFail).toHaveBeenCalledWith({ + where: { + id: applicationId, + workspaceId, + }, + }); + + expect(mockDriver.delete).toHaveBeenCalledWith({ + folderPath: `${workspaceId}/${applicationUniversalIdentifier}/files-field/field-uid`, + filename: 'file-uuid.pdf', + }); + + expect(mockFileRepository.delete).toHaveBeenCalledWith(fileId); + }); + }); + describe('checkFolderExistsLegacy', () => { it('should delegate to the current driver and return true', async () => { const checkParams = { diff --git a/packages/twenty-server/src/engine/core-modules/file-storage/file-storage.service.ts b/packages/twenty-server/src/engine/core-modules/file-storage/file-storage.service.ts index c27390d4412..0585d539d77 100644 --- a/packages/twenty-server/src/engine/core-modules/file-storage/file-storage.service.ts +++ b/packages/twenty-server/src/engine/core-modules/file-storage/file-storage.service.ts @@ -224,11 +224,28 @@ export class FileStorageService { path: Like(`${fileFolder}/%`), }, }); + + const application = await this.applicationRepository.findOneOrFail({ + where: { + id: file.applicationId, + workspaceId, + }, + }); + + const resourcePath = file.path.replace(`${fileFolder}/`, ''); + + const onStoragePath = this.buildOnStoragePath({ + workspaceId, + applicationUniversalIdentifier: application.universalIdentifier, + fileFolder, + resourcePath, + }); + const driver = this.fileStorageDriverFactory.getCurrentDriver(); await driver.delete({ - folderPath: `${file.workspaceId}/${file.applicationId}`, - filename: file.path, + folderPath: dirname(onStoragePath), + filename: basename(onStoragePath), }); await this.fileRepository.delete(fileId);