Skip to content

refactor: stop reading joinColumnName from relation field settings#20304

Open
charlesBochet wants to merge 7 commits intomainfrom
stop-using-join-column-name-from-settings
Open

refactor: stop reading joinColumnName from relation field settings#20304
charlesBochet wants to merge 7 commits intomainfrom
stop-using-join-column-name-from-settings

Conversation

@charlesBochet
Copy link
Copy Markdown
Member

@charlesBochet charlesBochet commented May 5, 2026

Summary

joinColumnName on relation field settings is always derivable from the field name (and the target object name for morph relations). This PR stops reading it from settings anywhere in production code; the stored value is no longer used.

The settings field is not removed from data yet — a follow-up can drop it once we are confident nothing depends on the stored value.

Helpers

The helpers are split by layer because frontend and backend hold morph relations differently: the frontend has a base name plus a morphRelations[] array, the backend has one row per target with the name already morph-resolved.

Helper Layer When to use
computeRelationGqlFieldJoinColumnName Shared / frontend (gqlField) Non-morph relation on the frontend.
computeMorphRelationGqlFieldName Shared / frontend (gqlField) Need the per-target morph gqlField name (e.g. targetCompany).
computeMorphRelationGqlFieldJoinColumnName Shared / frontend (gqlField) Per-target morph join column on the frontend. Prefer over the non-morph helper for any morph field — it forces the per-target inputs.
computeMorphOrRelationFieldJoinColumnName Backend (FlatFieldMetadata.name) Any backend read or write — the flat name is already morph-resolved, so one helper covers both cases.
computeMorphRelationFlatFieldName Backend (FlatFieldMetadata.name) Mutation paths only (create / update / object rename). Reads consume the stored field.name and never call this.

Test plan

  • Typecheck and lint (front, server, shared)
  • Existing unit tests pass
  • CI green

Always compute the foreign key column name from the field name (and the
target object name for morph relations) instead of reading
`joinColumnName` from `FieldMetadataSettings`. The settings field is no
longer read anywhere in production code, but is still kept in the schema
for backward compatibility (data is not migrated yet).

Adds two clearly named, shared utilities in `twenty-shared/utils` so
that frontend and backend use the same logic:

- `computeRelationFieldJoinColumnName({ name })` — appends `Id` to a
  field name (e.g. `company` → `companyId`).
- `computeMorphRelationFieldJoinColumnName({ fieldName, relationType,
  targetObjectMetadataNameSingular, targetObjectMetadataNamePlural })`
  — combines the morph-aware field name with the `Id` suffix
  (e.g. `target` + `opportunity` (MANY_TO_ONE) → `targetOpportunityId`).

Updates all read sites across `twenty-front`, `twenty-server` and
`twenty-shared` to use the computed value, and adjusts a couple of
tests that asserted the legacy `null joinColumnName` behavior.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors relation join-column handling by eliminating production reads of field.settings?.joinColumnName and instead deriving join-column names from field names (and morph target metadata) via new shared utilities in twenty-shared.

Changes:

  • Added shared utilities to compute relation and morph-relation join-column names and re-exported them from twenty-shared/utils.
  • Updated many frontend/backend call sites to compute join-column names instead of reading settings.joinColumnName.
  • Updated/removed tests that relied on legacy joinColumnName: null behavior.

Reviewed changes

Copilot reviewed 42 out of 42 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/twenty-shared/src/utils/index.ts Re-exports the new shared join-column computation utilities.
packages/twenty-shared/src/utils/fieldMetadata/compute-relation-field-join-column-name.ts Introduces shared join-column name computation helpers for relation and morph relation fields.
packages/twenty-shared/src/utils/fieldMetadata/tests/computeRelationFieldJoinColumnName.test.ts Adds unit tests for the new shared utilities.
packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/generate-column-definitions.util.ts Computes relation column names from field names for MANY_TO_ONE fields.
packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/index/utils/index-action-handler.utils.ts Uses computed join-column names when deriving index column names.
packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/field/services/update-field-action-handler.service.ts Removes joinColumnName-rename logic and relies on computed join column + field rename handling.
packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/field/services/create-field-action-handler.service.ts Computes FK join-column name from field name for MANY_TO_ONE relations.
packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/utils/build-universal-flat-object-field-by-name-and-join-column-maps.util.ts Builds join-column maps by computing join-column names for MANY_TO_ONE relations.
packages/twenty-server/src/engine/twenty-orm/utils/is-record-matching-rls-row-level-permission-predicate.util.ts Matches RLS predicates against computed join-column names instead of settings.
packages/twenty-server/src/engine/twenty-orm/utils/format-column-name-for-relation-field.util.ts Formats MANY_TO_ONE relation columns using computed join-column names.
packages/twenty-server/src/engine/twenty-orm/utils/determine-schema-relation-details.util.ts Uses computed join-column name when building TypeORM relation details for MANY_TO_ONE.
packages/twenty-server/src/engine/twenty-orm/factories/entity-schema-column.factory.ts Builds entity schema join columns using computed join-column names.
packages/twenty-server/src/engine/metadata-modules/index-metadata/utils/generate-flat-index.util.ts Generates index metadata column names using computed join-column names.
packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/get-object-field-names-and-join-column-names.util.ts Produces join-column name lists by computing join-column names for MANY_TO_ONE.
packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/compute-morph-or-relation-field-join-column-name.util.ts Keeps server wrapper but delegates to shared join-column util.
packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/extract-graphql-relation-field-names.util.ts Computes join-column names for GraphQL schema generation.
packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/build-columns-to-select.ts Ensures join-column columns are selected by computing join-column names.
packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/tests/build-columns-to-select.spec.ts Removes legacy test that expected behavior when joinColumnName was null.
packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-selected-fields/graphql-selected-fields.parser.ts Detects join-column selections via computed join-column names.
packages/twenty-server/src/engine/api/common/common-select-fields/utils/get-is-flat-field-a-junction-relation-field.ts Treats MANY_TO_ONE relation fields as junction relations without reading joinColumnName.
packages/twenty-server/src/engine/api/common/common-query-runners/common-merge-many-query-runner.service.ts Supplies computed join-column names to merge logic for MANY_TO_ONE relations.
packages/twenty-server/src/engine/api/common/common-nested-relations-processor/process-nested-relations-v2.helper.ts Computes join-column names for nested relation processing instead of reading settings.
packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/data-arg-processor.service.ts Uses computed join-column name when validating relation write inputs.
packages/twenty-front/src/modules/object-record/utils/sanitizeRecordInput.ts Detects relation join-column fields via computed join-column names.
packages/twenty-front/src/modules/object-record/utils/prefillRecord.ts Uses computed join-column names when pre-filling relation ID fields.
packages/twenty-front/src/modules/object-record/utils/computeOptimisticRecordFromInput.ts Detects/computes relation ID field names using computed join-column names.
packages/twenty-front/src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsForm.tsx Uses computed join-column name for MANY_TO_ONE relation edits.
packages/twenty-front/src/modules/object-record/record-filter/utils/isRecordMatchingFilter.ts Matches filters against computed join-column names instead of settings.
packages/twenty-front/src/modules/object-record/record-field/ui/utils/junction/getSourceJoinColumnName.ts Computes join-column names for sources, including morph-target-aware join columns.
packages/twenty-front/src/modules/object-record/record-field/ui/utils/junction/getJoinColumnNameOrThrow.ts Updates helper signature to take a field (name) and compute join-column name.
packages/twenty-front/src/modules/object-record/record-field/ui/utils/junction/getJoinColumnName.ts Computes join-column name from field name rather than reading settings.
packages/twenty-front/src/modules/object-record/record-field/ui/utils/junction/findTargetFieldInfo.ts Computes join-column name for morph and relation targets.
packages/twenty-front/src/modules/object-record/record-field/ui/utils/tests/getJoinColumnName.test.ts Updates tests to reflect join-column computation from field name.
packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/RelationOneToManyFieldInput.tsx Uses updated getJoinColumnName API (field-based).
packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/hooks/useRelationToOneFieldDisplay.ts Computes join-column name from field name for display/lookup.
packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationSectionDropdownToMany.tsx Uses updated getJoinColumnName API (field-based).
packages/twenty-front/src/modules/object-record/cache/utils/getRecordNodeFromRecord.ts Detects join-column keys via computed join-column names.
packages/twenty-front/src/modules/object-record/cache/utils/getFieldMetadataFromGqlField.ts Maps gql field names to metadata via computed join-column names.
packages/twenty-front/src/modules/object-metadata/utils/shouldFieldBeQueried.ts Treats join-column gql fields via computed join-column names.
packages/twenty-front/src/modules/object-metadata/utils/mapObjectMetadataToGraphQLQuery.ts Adds join-column gql fields by computing join-column names (and morph join-column names).
packages/twenty-front/src/modules/object-metadata/utils/mapFieldMetadataToGraphQLQuery.ts Recognizes join-column gql fields via computed join-column names.
packages/twenty-front/src/modules/object-metadata/utils/tests/shouldFieldBeQueried.test.ts Updates test inputs to match join-column derivation from field name.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 42 to 48
const name = isMorphOrRelationUniversalFlatFieldMetadata(
relatedFlatFieldMetadata,
)
? (relatedFlatFieldMetadata.universalSettings.joinColumnName ??
relatedFlatFieldMetadata.name)
? computeRelationFieldJoinColumnName({
name: relatedFlatFieldMetadata.name,
})
: relatedFlatFieldMetadata.name;
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 42 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/build-columns-to-select.ts">

<violation number="1" location="packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/build-columns-to-select.ts:99">
P1: MORPH_RELATION join columns are now added without restricting to MANY_TO_ONE, which can select non-existent `...Id` columns for ONE_TO_MANY morph fields.</violation>
</file>

<file name="packages/twenty-front/src/modules/object-metadata/utils/shouldFieldBeQueried.ts">

<violation number="1" location="packages/twenty-front/src/modules/object-metadata/utils/shouldFieldBeQueried.ts:25">
P1: Morph-relation join columns are matched with the non-morph `${fieldName}Id` helper, so morph join-column fields can be skipped from default GraphQL queries.

(Based on your team's feedback about computing morph/relation join column names at runtime.) [FEEDBACK_USED]</violation>
</file>

Tip: cubic used a learning from your PR history. Let your coding agent read cubic learnings directly with the cubic MCP.

Comment thread packages/twenty-front/src/modules/object-metadata/utils/shouldFieldBeQueried.ts Outdated
@twenty-ci-bot-public
Copy link
Copy Markdown

twenty-ci-bot-public Bot commented May 5, 2026

📊 API Changes Report

GraphQL Schema Changes

GraphQL Schema Changes

[error] Error: Unable to read JSON file: /home/runner/work/twenty/twenty/main-schema-introspection.json: Not valid JSON content
at JsonFileLoader.handleFileContent (/opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/json-file-loader/cjs/index.js:147:19)
at /opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/json-file-loader/cjs/index.js:95:43
at async Promise.all (index 0)
at async JsonFileLoader.load (/opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/json-file-loader/cjs/index.js:88:9)
at async /opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/load/cjs/load-typedefs/load-file.js:15:39
at async Promise.all (index 4)
at async loadFile (/opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/load/cjs/load-typedefs/load-file.js:13:9)
at async /opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/load/cjs/load-typedefs/collect-sources.js:200:25
Error: Unable to read JSON file: /home/runner/work/twenty/twenty/main-schema-introspection.json: Not valid JSON content
at JsonFileLoader.handleFileContent (/opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/json-file-loader/cjs/index.js:147:19)
at /opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/json-file-loader/cjs/index.js:95:43
at async Promise.all (index 0)
at async JsonFileLoader.load (/opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/json-file-loader/cjs/index.js:88:9)
at async /opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/load/cjs/load-typedefs/load-file.js:15:39
at async Promise.all (index 4)
at async loadFile (/opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/load/cjs/load-typedefs/load-file.js:13:9)
at async /opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/load/cjs/load-typedefs/collect-sources.js:200:25
⚠️ Breaking changes or errors detected in GraphQL schema

[error] Error: Unable to read JSON file: /home/runner/work/twenty/twenty/main-schema-introspection.json: Not valid JSON content
    at JsonFileLoader.handleFileContent (/opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/json-file-loader/cjs/index.js:147:19)
    at /opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/json-file-loader/cjs/index.js:95:43
    at async Promise.all (index 0)
    at async JsonFileLoader.load (/opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/json-file-loader/cjs/index.js:88:9)
    at async /opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/load/cjs/load-typedefs/load-file.js:15:39
    at async Promise.all (index 4)
    at async loadFile (/opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/load/cjs/load-typedefs/load-file.js:13:9)
    at async /opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/load/cjs/load-typedefs/collect-sources.js:200:25
Error generating diff

GraphQL Metadata Schema Changes

GraphQL Metadata Schema Changes

[error] Error: Unable to read JSON file: /home/runner/work/twenty/twenty/main-metadata-schema-introspection.json: Not valid JSON content
at JsonFileLoader.handleFileContent (/opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/json-file-loader/cjs/index.js:147:19)
at /opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/json-file-loader/cjs/index.js:95:43
at async Promise.all (index 0)
at async JsonFileLoader.load (/opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/json-file-loader/cjs/index.js:88:9)
at async /opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/load/cjs/load-typedefs/load-file.js:15:39
at async Promise.all (index 4)
at async loadFile (/opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/load/cjs/load-typedefs/load-file.js:13:9)
at async /opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/load/cjs/load-typedefs/collect-sources.js:200:25
Error: Unable to read JSON file: /home/runner/work/twenty/twenty/main-metadata-schema-introspection.json: Not valid JSON content
at JsonFileLoader.handleFileContent (/opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/json-file-loader/cjs/index.js:147:19)
at /opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/json-file-loader/cjs/index.js:95:43
at async Promise.all (index 0)
at async JsonFileLoader.load (/opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/json-file-loader/cjs/index.js:88:9)
at async /opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/load/cjs/load-typedefs/load-file.js:15:39
at async Promise.all (index 4)
at async loadFile (/opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/load/cjs/load-typedefs/load-file.js:13:9)
at async /opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/load/cjs/load-typedefs/collect-sources.js:200:25
⚠️ Breaking changes or errors detected in GraphQL metadata schema

[error] Error: Unable to read JSON file: /home/runner/work/twenty/twenty/main-metadata-schema-introspection.json: Not valid JSON content
    at JsonFileLoader.handleFileContent (/opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/json-file-loader/cjs/index.js:147:19)
    at /opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/json-file-loader/cjs/index.js:95:43
    at async Promise.all (index 0)
    at async JsonFileLoader.load (/opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/json-file-loader/cjs/index.js:88:9)
    at async /opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/load/cjs/load-typedefs/load-file.js:15:39
    at async Promise.all (index 4)
    at async loadFile (/opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/load/cjs/load-typedefs/load-file.js:13:9)
    at async /opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/@graphql-inspector/cli/node_modules/@graphql-tools/load/cjs/load-typedefs/collect-sources.js:200:25
Error generating diff

REST API Analysis Error

⚠️ Error occurred while analyzing REST API changes

Error Output

REST Metadata API Analysis Error

⚠️ Error occurred while analyzing REST Metadata API changes

Error Output

⚠️ Please review these API changes carefully before merging.

@twenty-ci-bot-public
Copy link
Copy Markdown

twenty-ci-bot-public Bot commented May 5, 2026

🚀 Preview Environment Ready!

Your preview environment is available at: http://bore.pub:57756

This environment will automatically shut down after 5 hours.

…tests

- Removes the frontend `getJoinColumnName` / `getJoinColumnNameOrThrow`
  wrappers (and their test) and the backend
  `computeMorphOrRelationFieldJoinColumnName` thin wrapper. All call
  sites now import `computeRelationFieldJoinColumnName` directly from
  `twenty-shared/utils`.
- Expands the shared util test suite to cover edge cases: camelCase
  field names, morph-aware field names, simple/irregular plurals, and
  invalid relation types (which throw).
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 19 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/twenty-server/src/modules/workflow/workflow-executor/utils/format-workflow-record-relation-fields.util.ts">

<violation number="1" location="packages/twenty-server/src/modules/workflow/workflow-executor/utils/format-workflow-record-relation-fields.util.ts:64">
P2: `computeRelationFieldJoinColumnName` only handles non-morph relations. This code now applies it to morph relations too, which will generate the wrong join column name (missing the morph target segment). Morph MANY_TO_ONE fields should use the morph-aware join column computation or be excluded here.</violation>
</file>

<file name="packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/data-arg-processor.service.ts">

<violation number="1" location="packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/data-arg-processor.service.ts:247">
P2: This uses the non-morph join column helper even when `fieldMetadata.type` is `MORPH_RELATION`, which ignores the target-specific naming (e.g., `targetOpportunityId`). That will cause morph join-column keys to be rejected or mismatched. Use the morph-aware join column computation for morph relations.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Address review feedback: avoid generating ${name}Id for relation/morph
fields that don't have a database column.

- build-columns-to-select / index handlers / generate-flat-index now
  only compute join column names when relationType is MANY_TO_ONE.
- shouldFieldBeQueried matches morph join columns by iterating
  morphRelations and using the morph-aware join column helper.
- process-nested-relations throws if a one-to-many's target relation
  cannot be resolved instead of computing 'Id'.
Make the abstraction explicit so callers can't accidentally use the
non-morph helper on a frontend morph FieldMetadataItem (which carries the
base name + morphRelations[]).

- twenty-shared/utils now exposes only gqlField-aware helpers:
  computeRelationGqlFieldJoinColumnName,
  computeMorphRelationGqlFieldJoinColumnName.
- twenty-server reintroduces computeMorphOrRelationFieldJoinColumnName,
  used everywhere in the backend since FlatFieldMetadata.name is already
  morph-resolved at the db layer.
- All call sites updated; tests/typecheck/lint clean.
Mirror the gqlField/flat split already in place for join column helpers:

- twenty-shared: rename `computeMorphRelationFieldName` to
  `computeMorphRelationGqlFieldName` (frontend / GraphQL field name).
- twenty-server: introduce `computeMorphRelationFlatFieldName` that
  produces a `FlatFieldMetadata.name` and is only used in metadata
  mutation paths (create / update / object rename).

Backend reads keep consuming the already-resolved `field.name` and never
recompute it, so the new util's scope is the write path only.
Copy link
Copy Markdown
Contributor

@ijreilly ijreilly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice !

…n-name-from-settings

# Conflicts:
#	packages/twenty-front/src/modules/object-record/graphql/record-gql-fields/utils/generateDepthRecordGqlFieldsFromFields.ts
@charlesBochet charlesBochet enabled auto-merge May 6, 2026 09:47
@charlesBochet charlesBochet added this pull request to the merge queue May 6, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks May 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants