fix: restore isCustom gate in metadata label resolvers (#21432)

## Context

#21228 removed the stored `isCustom` column and, with it, the `isCustom`
early-return in `resolveObjectMetadataStandardOverride` /
`resolveFieldMetadataStandardOverride`, on the assumption that falling
through the `standardOverrides` checks was equivalent.

It isn't: custom object/field labels now reach the Lingui lookup. A
custom label that collides with a standard catalog string (e.g. a custom
field labeled "Status") gets translated for non-English locales against
the user's intent, and every other custom label pays a hash + catalog
miss — and, in production, an "Uncompiled message detected" warning
(#21415) — on each metadata resolution.

## Fix

Restore the gate. `isCustom` is no longer stored, so call sites that
build the resolver input from flat entities (dataloader,
minimal-metadata, view controller, command-menu-item navigation context)
derive it via `belongsToTwentyStandardApp`; GraphQL resolvers keep
passing DTOs, which already carry the derived value.

## Testing

- Unit tests for both resolvers, including a new regression test: a
custom label matching a standard catalog entry is returned verbatim,
Lingui never called.

---------

Co-authored-by: Weiko <corentin@twenty.com>
This commit is contained in:
Félix Malfait
2026-06-11 18:10:53 +02:00
committed by GitHub
parent cfb9772179
commit 69a7e614ff
11 changed files with 126 additions and 6 deletions
@@ -11,6 +11,7 @@ import {
} from 'src/engine/metadata-modules/flat-command-menu-item/utils/build-navigation-flat-command-menu-item.util';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import { enrichCommandMenuItemEventWithResolvedNavigation } from 'src/engine/subscriptions/metadata-event/utils/enrich-command-menu-item-event-with-resolved-navigation.util';
import { TWENTY_STANDARD_APPLICATION } from 'src/engine/workspace-manager/twenty-standard-application/constants/twenty-standard-applications';
const mockI18nInstance = {
_: (messageId: string) => messageId,
@@ -26,6 +27,8 @@ const makeFlatObjectMetadata = (
universalIdentifier: 'obj-uid-1',
workspaceId: 'ws-1',
applicationId: 'app-1',
applicationUniversalIdentifier:
TWENTY_STANDARD_APPLICATION.universalIdentifier,
labelPlural: 'People',
labelSingular: 'Person',
icon: 'IconUser',
@@ -12,6 +12,7 @@ import { FlatCommandMenuItem } from 'src/engine/metadata-modules/flat-command-me
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import { belongsToTwentyStandardApp } from 'src/engine/metadata-modules/utils/belongs-to-twenty-standard-app.util';
type EnrichCommandMenuItemEventArgs = {
record: FlatCommandMenuItem;
@@ -48,7 +49,10 @@ export const enrichCommandMenuItemEventWithResolvedNavigation = ({
}
const context = buildNavigationInterpolationContext({
objectMetadata: flatObjectMetadata,
objectMetadata: {
...flatObjectMetadata,
isCustom: !belongsToTwentyStandardApp(flatObjectMetadata),
},
locale,
i18nInstance,
});