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:
+58
-12
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user