Migrate favorites to navigation menu items (1.17 upgrade) (#17477)

**What this PR does:**
- Migrates existing `Favorite` and `FavoriteFolder` entities to the new
`NavigationMenuItem` structure
- Preserves user-level vs workspace-level ownership
- Preserves folder structure, positions, and relationships
- Handles both view-based favorites (linked to views) and record-based
favorites (linked to records)
- Soft-deletes original favorites and folders after successful migration
- Enables the `IS_NAVIGATION_MENU_ITEM_ENABLED` feature flag
post-migration
- Skips migration if the feature flag is already enabled
- Idempotent: checks for existing navigation menu items to prevent
duplicates

**Migration flow:**
1. Migrate favorite folders first (creates folder mapping)
2. Migrate favorites
3. Soft-delete migrated favorites and folders
4. Enable feature flag

**What's next:**
- After all workspaces are migrated and the navigation menu item feature
is fully rolled out, we can:
- Remove the old `Favorite` and `FavoriteFolder` entities and related
code
- Remove the feature flag check and make navigation menu items the
default
  - Clean up any deprecated favorites-related code paths in the frontend

---------

Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
This commit is contained in:
Abdul Rahman
2026-02-06 19:12:20 +05:30
committed by GitHub
parent 7074d9ce1b
commit f6beb06364
6 changed files with 800 additions and 84 deletions
@@ -15,6 +15,7 @@ import { FixMorphRelationFieldNamesCommand } from 'src/database/commands/upgrade
import { IdentifyWebhookMetadataCommand } from 'src/database/commands/upgrade-version-command/1-17/1-17-identify-webhook-metadata.command';
import { MakeWebhookUniversalIdentifierAndApplicationIdNotNullableMigrationCommand } from 'src/database/commands/upgrade-version-command/1-17/1-17-make-webhook-universal-identifier-and-application-id-not-nullable-migration.command';
import { MigrateAttachmentToMorphRelationsCommand } from 'src/database/commands/upgrade-version-command/1-17/1-17-migrate-attachment-to-morph-relations.command';
import { MigrateFavoritesToNavigationMenuItemsCommand } from 'src/database/commands/upgrade-version-command/1-17/1-17-migrate-favorites-to-navigation-menu-items.command';
import { MigrateNoteTargetToMorphRelationsCommand } from 'src/database/commands/upgrade-version-command/1-17/1-17-migrate-note-target-to-morph-relations.command';
import { MigrateTaskTargetToMorphRelationsCommand } from 'src/database/commands/upgrade-version-command/1-17/1-17-migrate-task-target-to-morph-relations.command';
import { MigrateWorkflowCodeStepsCommand } from 'src/database/commands/upgrade-version-command/1-17/1-17-migrate-workflow-code-steps.command';
@@ -42,6 +43,7 @@ export class UpgradeCommand extends UpgradeCommandRunner {
protected readonly backfillApplicationPackageFilesCommand: BackfillApplicationPackageFilesCommand,
protected readonly deleteFileRecordsCommand: DeleteFileRecordsCommand,
protected readonly migrateAttachmentToMorphRelationsCommand: MigrateAttachmentToMorphRelationsCommand,
protected readonly migrateFavoritesToNavigationMenuItemsCommand: MigrateFavoritesToNavigationMenuItemsCommand,
protected readonly migrateNoteTargetToMorphRelationsCommand: MigrateNoteTargetToMorphRelationsCommand,
protected readonly migrateTaskTargetToMorphRelationsCommand: MigrateTaskTargetToMorphRelationsCommand,
protected readonly identifyWebhookMetadataCommand: IdentifyWebhookMetadataCommand,
@@ -62,6 +64,7 @@ export class UpgradeCommand extends UpgradeCommandRunner {
const commands_1170: VersionCommands = [
this.migrateAttachmentToMorphRelationsCommand,
this.migrateFavoritesToNavigationMenuItemsCommand,
this.migrateNoteTargetToMorphRelationsCommand,
this.migrateTaskTargetToMorphRelationsCommand,
this.identifyWebhookMetadataCommand,