Fix custom-only attachment timeline upgrades in v2.35 (#24679)
## Context The production v2.34 upgrade completed for 5,653 workspaces but deterministically failed for two workspaces whose attachment target morph groups contain only custom-object fields. The v2.34 command correctly looked for another morph member when the canonical `attachment.targetPerson` field was absent, but workspace-migration validation scoped its dependency maps to the Twenty standard application. The selected custom-app-owned field was therefore missing from the validator's view. This is a valid legacy metadata shape, not customer corruption. ## Changes - add an idempotent v2.35 workspace command that repairs missing `attachmentLinked` and `attachmentUnlinked` timeline activity types - prefer the canonical standard attachment target relation when present; otherwise select a valid custom morph member deterministically - require a complete active many-to-one morph relation before using it - preserve partial progress by creating only missing definitions - support dry-run and skip workspaces without timeline metadata or a valid attachment morph target - include the application owning a timeline activity type's soft-referenced target relation in workspace-migration dependency maps - register the new v2.35 command module without modifying any committed v2.34 command The dependency-map change is required in addition to the v2.35 command: standard upgrade sequencing encounters the failed v2.34 command before it can execute v2.35. Loading the referenced field's application lets the existing v2.34 command validate and allows both hosted and self-hosted upgrades to progress normally. ## Verification - focused Jest suites: 8 tests passed - direct twenty-server typecheck passed with declaration output disabled (the clean worktree's shared dependency symlink otherwise produces unrelated non-portable declaration-path diagnostics) - oxlint: 0 warnings, 0 errors across all seven changed TypeScript files - oxfmt and `git diff --check` passed - no locale catalogs or generated translation files included ## Production rollout After deployment: 1. dry-run the v2.35 repair for the two affected workspace IDs 2. rerun the normal upgrade for only those two workspaces 3. refresh `upgrade:status` and confirm zero workspaces behind or failed 4. verify attachment linked/unlinked activities on the active custom-only workspace No global rerun or direct database write is required. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/24679?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. -->
F
Félix Malfait committed
6ab1e699e9311fdef85c6569390f57e814b4b861
Parent: eecdbd0
Committed by GitHub <noreply@github.com>
on 8/24/2026, 12:25:57 PM