fix logo upload during workspace onboarding (#18905)

Logo upload during onboarding failed because it required the Twenty
Standard Application, which doesn't exist yet at that point

We only need custom app's universalIdentifier
(workspace.workspaceCustomApplicationId, available from sign up) so we
can safely remove ApplicationService dependency


https://github.com/user-attachments/assets/a18599ee-0b91-4629-ad77-2f708351449a


/closes #18829

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
neo773
2026-03-25 13:32:08 +05:30
committed by GitHub
parent 2bfd2f6b85
commit 3295f5ee07
2 changed files with 31 additions and 26 deletions
@@ -1,8 +1,6 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ApplicationEntity } from 'src/engine/core-modules/application/application.entity';
import { ApplicationModule } from 'src/engine/core-modules/application/application.module';
import { FileStorageModule } from 'src/engine/core-modules/file-storage/file-storage.module';
import { FileEntity } from 'src/engine/core-modules/file/entities/file.entity';
import { FileCorePictureResolver } from 'src/engine/core-modules/file/file-core-picture/resolvers/file-core-picture.resolver';
@@ -16,10 +14,9 @@ import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permi
@Module({
imports: [
JwtModule,
TypeOrmModule.forFeature([FileEntity, WorkspaceEntity, ApplicationEntity]),
TypeOrmModule.forFeature([FileEntity, WorkspaceEntity]),
PermissionsModule,
FileStorageModule,
ApplicationModule,
FileUrlModule,
SecureHttpClientModule,
],
@@ -11,7 +11,10 @@ import { isDefined } from 'twenty-shared/utils';
import { Like, type QueryRunner, Repository } from 'typeorm';
import { v4 } from 'uuid';
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
import {
ApplicationException,
ApplicationExceptionCode,
} from 'src/engine/core-modules/application/application.exception';
import { FileStorageService } from 'src/engine/core-modules/file-storage/file-storage.service';
import { FileWithSignedUrlDTO } from 'src/engine/core-modules/file/dtos/file-with-sign-url.dto';
import { FileEntity } from 'src/engine/core-modules/file/entities/file.entity';
@@ -29,7 +32,6 @@ export class FileCorePictureService {
constructor(
private readonly fileStorageService: FileStorageService,
private readonly applicationService: ApplicationService,
@InjectRepository(WorkspaceEntity)
private readonly workspaceRepository: Repository<WorkspaceEntity>,
@InjectRepository(FileEntity)
@@ -38,6 +40,25 @@ export class FileCorePictureService {
private readonly secureHttpClientService: SecureHttpClientService,
) {}
private async findCustomApplicationUniversalIdentifier(
workspaceId: string,
): Promise<string> {
const workspace = await this.workspaceRepository.findOne({
where: { id: workspaceId },
select: ['workspaceCustomApplicationId'],
withDeleted: true,
});
if (!isDefined(workspace)) {
throw new ApplicationException(
`Could not find workspace ${workspaceId}`,
ApplicationExceptionCode.APPLICATION_NOT_FOUND,
);
}
return workspace.workspaceCustomApplicationId;
}
private async uploadCorePicture({
file,
filename,
@@ -59,11 +80,7 @@ export class FileCorePictureService {
const universalIdentifier =
applicationUniversalIdentifier ??
(
await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow(
{ workspaceId },
)
).workspaceCustomFlatApplication.universalIdentifier;
(await this.findCustomApplicationUniversalIdentifier(workspaceId));
const savedFile = await this.fileStorageService.writeFile({
sourceFile: sanitizedFile,
@@ -169,17 +186,12 @@ export class FileCorePictureService {
},
});
const { workspaceCustomFlatApplication } =
await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow(
{
workspaceId,
},
);
const customApplicationUniversalIdentifier =
await this.findCustomApplicationUniversalIdentifier(workspaceId);
await this.fileStorageService.delete({
workspaceId,
applicationUniversalIdentifier:
workspaceCustomFlatApplication.universalIdentifier,
applicationUniversalIdentifier: customApplicationUniversalIdentifier,
fileFolder: FileFolder.CorePicture,
resourcePath: removeFileFolderFromFileEntityPath(file.path),
});
@@ -286,16 +298,12 @@ export class FileCorePictureService {
},
});
const { workspaceCustomFlatApplication: sourceApplication } =
await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow(
{
workspaceId: sourceWorkspaceId,
},
);
const sourceApplicationUniversalIdentifier =
await this.findCustomApplicationUniversalIdentifier(sourceWorkspaceId);
const fileStream = await this.fileStorageService.readFile({
workspaceId: sourceWorkspaceId,
applicationUniversalIdentifier: sourceApplication.universalIdentifier,
applicationUniversalIdentifier: sourceApplicationUniversalIdentifier,
fileFolder: FileFolder.CorePicture,
resourcePath: removeFileFolderFromFileEntityPath(sourceFile.path),
});