diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/__tests__/resolve-object-metadata-standard-override.util.spec.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/__tests__/resolve-object-metadata-standard-override.util.spec.ts index a4b4be2be..c70d7d172 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/__tests__/resolve-object-metadata-standard-override.util.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/__tests__/resolve-object-metadata-standard-override.util.spec.ts @@ -478,4 +478,53 @@ describe('resolveObjectMetadataStandardOverride', () => { expect(mockI18n._).toHaveBeenCalledWith('auto.translation.id'); }); }); + + describe('Undefined locale handling', () => { + it('should use SOURCE_LOCALE fallback when locale is undefined for standard object', () => { + const objectMetadata = { + labelSingular: 'Standard Label', + labelPlural: 'Standard Labels', + description: 'Standard Description', + icon: 'default-icon', + isCustom: false, + standardOverrides: { + labelSingular: 'Source Override', + }, + }; + + const result = resolveObjectMetadataStandardOverride( + objectMetadata, + 'labelSingular', + undefined, + ); + + expect(result).toBe('Source Override'); + expect(mockGenerateMessageId).not.toHaveBeenCalled(); + expect(mockI18n._).not.toHaveBeenCalled(); + }); + + it('should fall back to auto translation when locale is undefined and no SOURCE_LOCALE override exists', () => { + mockI18n._.mockReturnValue('Auto Translated Label'); + mockGenerateMessageId.mockReturnValue('auto.translation.id'); + + const objectMetadata = { + labelSingular: 'Standard Label', + labelPlural: 'Standard Labels', + description: 'Standard Description', + icon: 'default-icon', + isCustom: false, + standardOverrides: undefined, + }; + + const result = resolveObjectMetadataStandardOverride( + objectMetadata, + 'labelSingular', + undefined, + ); + + expect(result).toBe('Auto Translated Label'); + expect(mockGenerateMessageId).toHaveBeenCalledWith('Standard Label'); + expect(mockI18n._).toHaveBeenCalledWith('auto.translation.id'); + }); + }); }); diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/resolve-object-metadata-standard-override.util.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/resolve-object-metadata-standard-override.util.ts index 42b2801e4..8ae27dac3 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/resolve-object-metadata-standard-override.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/resolve-object-metadata-standard-override.util.ts @@ -19,6 +19,8 @@ export const resolveObjectMetadataStandardOverride = ( labelKey: 'labelPlural' | 'labelSingular' | 'description' | 'icon', locale: keyof typeof APP_LOCALES | undefined, ): string => { + const safeLocale = locale ?? SOURCE_LOCALE; + if (objectMetadata.isCustom) { return objectMetadata[labelKey] ?? ''; } @@ -32,11 +34,10 @@ export const resolveObjectMetadataStandardOverride = ( if ( isDefined(objectMetadata.standardOverrides?.translations) && - isDefined(locale) && labelKey !== 'icon' ) { const translationValue = - objectMetadata.standardOverrides.translations[locale]?.[labelKey]; + objectMetadata.standardOverrides.translations[safeLocale]?.[labelKey]; if (isDefined(translationValue)) { return translationValue; @@ -44,7 +45,7 @@ export const resolveObjectMetadataStandardOverride = ( } if ( - locale === SOURCE_LOCALE && + safeLocale === SOURCE_LOCALE && isNonEmptyString(objectMetadata.standardOverrides?.[labelKey]) ) { return objectMetadata.standardOverrides[labelKey] ?? ''; diff --git a/packages/twenty-server/src/engine/middlewares/middleware.service.ts b/packages/twenty-server/src/engine/middlewares/middleware.service.ts index dbac7a338..890a747d9 100644 --- a/packages/twenty-server/src/engine/middlewares/middleware.service.ts +++ b/packages/twenty-server/src/engine/middlewares/middleware.service.ts @@ -128,6 +128,10 @@ export class MiddlewareService { public async hydrateGraphqlRequest(request: Request) { if (!this.isTokenPresent(request)) { + request.locale = + (request.headers['x-locale'] as keyof typeof APP_LOCALES) ?? + SOURCE_LOCALE; + return; }