feat: rename RICH_TEXT_V2 → RICH_TEXT in codebase (keep DB value) (#18628)

## Summary

- Renames the `FieldMetadataType` enum key from `RICH_TEXT_V2` to
`RICH_TEXT` across the entire codebase, while keeping the underlying
string value as `'RICH_TEXT_V2'` to maintain PostgreSQL database
compatibility
- Renames all related types, guards, hooks, components, and files from
`*RichTextV2*` / `*rich-text-v2*` to `*RichText*` / `*rich-text*` (e.g.
`FormRichTextV2FieldInput` → `FormRichTextFieldInput`,
`isFieldRichTextV2` → `isFieldRichText`)
- Updates generated files (GraphQL schema, SDK types) to use the new key
while preserving the `RICH_TEXT_V2` string value for DB/API layer
- Updates i18n locale files, test snapshots, and integration tests to
reflect the rename

## Context

The legacy `RICH_TEXT` (V1) field type was deprecated and migrated to
`TEXT` in a previous PR (#18623). With V1 gone, the `RICH_TEXT_V2`
naming is no longer necessary — `RICH_TEXT` is now the canonical name.
The DB enum value stays `'RICH_TEXT_V2'` to avoid confusion with the
just-deprecated V1 type and to prevent a database migration.

## Test plan

- [x] `twenty-server` typecheck passes
- [x] `twenty-front` typecheck passes (only pre-existing Apollo client
errors remain)
- [x] `twenty-server` lint passes
- [x] `twenty-front` lint passes
- [x] `twenty-shared` build passes
- [ ] CI passes


Made with [Cursor](https://cursor.com)
This commit is contained in:
Charles Bochet
2026-03-13 19:07:55 +01:00
committed by GitHub
parent 3054679411
commit d9eb317bb5
129 changed files with 452 additions and 401 deletions
@@ -1,10 +1,12 @@
import { InjectDataSource, InjectRepository } from '@nestjs/typeorm';
import { Command } from 'nest-commander';
import { FeatureFlagKey } from 'twenty-shared/types';
import { DataSource, Repository } from 'typeorm';
import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner';
import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner';
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
import { getMetadataFlatEntityMapsKey } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-flat-entity-maps-key.util';
@@ -18,7 +20,7 @@ import { type WorkspaceCacheKeyName } from 'src/engine/workspace-cache/types/wor
@Command({
name: 'upgrade:1-20:migrate-rich-text-to-text',
description:
'Migrate deprecated RICH_TEXT field metadata type to TEXT. The underlying column type is already text, so only the metadata needs updating.',
'Migrate deprecated RICH_TEXT (V1) to TEXT and rename RICH_TEXT_V2 to RICH_TEXT. The underlying column type is already text, so only the metadata needs updating.',
})
export class MigrateRichTextToTextCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner {
constructor(
@@ -28,6 +30,7 @@ export class MigrateRichTextToTextCommand extends ActiveOrSuspendedWorkspacesMig
private readonly coreDataSource: DataSource,
protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager,
protected readonly dataSourceService: DataSourceService,
private readonly featureFlagService: FeatureFlagService,
private readonly workspaceCacheService: WorkspaceCacheService,
private readonly workspaceCacheStorageService: WorkspaceCacheStorageService,
private readonly workspaceMetadataVersionService: WorkspaceMetadataVersionService,
@@ -39,26 +42,38 @@ export class MigrateRichTextToTextCommand extends ActiveOrSuspendedWorkspacesMig
workspaceId,
options,
}: RunOnWorkspaceArgs): Promise<void> {
const dryRun = options?.dryRun ?? false;
this.logger.log(
`${dryRun ? '[DRY RUN] ' : ''}Migrating RICH_TEXT fields to TEXT in workspace ${workspaceId}`,
const isMigrated = await this.featureFlagService.isFeatureEnabled(
FeatureFlagKey.IS_RICH_TEXT_V1_MIGRATED,
workspaceId,
);
if (dryRun) {
if (isMigrated) {
this.logger.log(
`[DRY RUN] Would update RICH_TEXT -> TEXT in core.fieldMetadata for workspace ${workspaceId}. Skipping.`,
`Rich text migration already completed for workspace ${workspaceId}. Skipping.`,
);
return;
}
const dryRun = options?.dryRun ?? false;
if (dryRun) {
this.logger.log(
`[DRY RUN] Would update RICH_TEXT -> TEXT and RICH_TEXT_V2 -> RICH_TEXT in core.fieldMetadata for workspace ${workspaceId}. Skipping.`,
);
return;
}
this.logger.log(`Migrating RICH_TEXT fields in workspace ${workspaceId}`);
const queryRunner = this.coreDataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const result = await queryRunner.query(
const v1Result = await queryRunner.query(
`UPDATE core."fieldMetadata"
SET "type" = 'TEXT'
WHERE "workspaceId" = $1
@@ -67,18 +82,48 @@ export class MigrateRichTextToTextCommand extends ActiveOrSuspendedWorkspacesMig
[workspaceId],
);
const updatedCount = result.length;
const v1Count = v1Result.length;
if (updatedCount > 0) {
const renameResult = await queryRunner.query(
`UPDATE core."fieldMetadata"
SET "type" = 'RICH_TEXT'
WHERE "workspaceId" = $1
AND "type" = 'RICH_TEXT_V2'
RETURNING "id"`,
[workspaceId],
);
const renameCount = renameResult.length;
await queryRunner.commitTransaction();
if (v1Count > 0) {
this.logger.log(
`Migrated ${updatedCount} RICH_TEXT field(s) to TEXT in workspace ${workspaceId}`,
`Migrated ${v1Count} RICH_TEXT (V1) field(s) to TEXT in workspace ${workspaceId}`,
);
}
if (renameCount > 0) {
this.logger.log(
`Renamed ${renameCount} RICH_TEXT_V2 field(s) to RICH_TEXT in workspace ${workspaceId}`,
);
}
await this.featureFlagService.enableFeatureFlags(
[FeatureFlagKey.IS_RICH_TEXT_V1_MIGRATED],
workspaceId,
);
if (v1Count > 0 || renameCount > 0) {
await this.invalidateCaches(workspaceId);
} else {
this.logger.log(
`No RICH_TEXT fields found in workspace ${workspaceId}`,
`No RICH_TEXT or RICH_TEXT_V2 fields found in workspace ${workspaceId}`,
);
}
} catch (error) {
await queryRunner.rollbackTransaction();
throw error;
} finally {
await queryRunner.release();
}
@@ -94,6 +139,7 @@ export class MigrateRichTextToTextCommand extends ActiveOrSuspendedWorkspacesMig
.map(getMetadataFlatEntityMapsKey),
),
'ORMEntityMetadatas',
'featureFlagsMap',
];
await this.workspaceCacheService.invalidateAndRecompute(