Deprecate legacy RICH_TEXT field metadata type (#18623)
## Summary - Removes the deprecated `RICH_TEXT` (V1) field metadata type from the codebase entirely - Adds a 1.20 upgrade command that migrates existing `RICH_TEXT` fields to `TEXT` in `core.fieldMetadata` - Cleans up ~70 files across `twenty-shared`, `twenty-server`, `twenty-front`, `twenty-sdk`, and `twenty-zapier` ## Context `RICH_TEXT` was a legacy field type that stored rich text as a single `text` column. It was already **read-only** — writes threw errors directing users to `RICH_TEXT_V2` instead. `RICH_TEXT_V2` is the current approach: a composite type with `blocknote` (editor JSON) and `markdown` subfields. Keeping the deprecated type added maintenance burden without any value. Since the underlying database column type for `RICH_TEXT` was already `text` (same as `TEXT`), the migration only needs to update the metadata — no data migration or column changes required. ## Changes ### Upgrade command (new) - `1-20-migrate-rich-text-to-text.command.ts` — runs `UPDATE core."fieldMetadata" SET "type" = 'TEXT' WHERE "type" = 'RICH_TEXT'` per workspace, with cache invalidation ### Enum & shared types - Removed `RICH_TEXT` from `FieldMetadataType` enum - Removed from `FieldMetadataDefaultValueMapping`, `isFieldMetadataTextKind` ### Server (~30 files) - Removed from type mapper (scalar, filter, order-by), data processors, input transformer, filter operators, zod schemas, column type mapping, searchable fields, RLS matching, OpenAPI schema, fake value generators - Removed from field creation flow and field metadata type validator - Updated dev seeder Pet `bio` field to `TEXT` - Cleaned up mocks, snapshots, integration tests ### Frontend (~25 files) - Deleted: `RichTextFieldDisplay`, `isFieldRichText`, `isFieldRichTextValue`, `useRichTextFieldDisplay` - Removed from `FieldDisplay`, `usePersistField`, `isFieldValueEmpty`, `isRecordMatchingFilter`, `generateEmptyFieldValue`, `isFieldCellSupported`, spreadsheet import, workflow fake values - Removed from settings types, field type configs, and field creation exclusion list - Updated tests, mocks, and stories ### SDK & Zapier - Removed from generated GraphQL schema and TypeScript types - Removed from Zapier `computeInputFields`
This commit is contained in:
-2
@@ -172,8 +172,6 @@ exports[`DataArgProcessorService failing inputs validation RELATION should throw
|
||||
|
||||
exports[`DataArgProcessorService failing inputs validation RELATION should throw for invalid input #5: "non-uuid" 1`] = `"Invalid UUID value 'non-uuid' for field "manyToOneRelationFieldId""`;
|
||||
|
||||
exports[`DataArgProcessorService failing inputs validation RICH_TEXT should throw for invalid input #1: "test" 1`] = `"richTextField RICH_TEXT-typed field does not support write operations"`;
|
||||
|
||||
exports[`DataArgProcessorService failing inputs validation RICH_TEXT_V2 should throw for invalid input #1: "not-a-rich-text" 1`] = `"Invalid rich text v2 value 'not-a-rich-text' for field "richTextV2Field" - Should be an object"`;
|
||||
|
||||
exports[`DataArgProcessorService failing inputs validation RICH_TEXT_V2 should throw for invalid input #2: 1 1`] = `"Invalid rich text v2 value 1 for field "richTextV2Field" - Should be an object"`;
|
||||
|
||||
-1
@@ -96,7 +96,6 @@ export const failingInputsByFieldMetadataType: {
|
||||
{ input: { booleanField: 'string' } },
|
||||
{ input: { booleanField: 1 } },
|
||||
],
|
||||
[FieldMetadataType.RICH_TEXT]: [{ input: { richTextField: 'test' } }],
|
||||
[FieldMetadataType.ADDRESS]: [
|
||||
{ input: { addressField: 'not-an-address' } },
|
||||
{ input: { addressField: 1 } },
|
||||
|
||||
-5
@@ -139,11 +139,6 @@ export const fieldMetadataConfigByFieldName: Record<
|
||||
type: FieldMetadataType.RICH_TEXT_V2,
|
||||
isNullable: true,
|
||||
},
|
||||
richTextField: {
|
||||
name: 'richTextField',
|
||||
type: FieldMetadataType.RICH_TEXT,
|
||||
isNullable: true,
|
||||
},
|
||||
position: {
|
||||
name: 'position',
|
||||
type: FieldMetadataType.POSITION,
|
||||
|
||||
-1
@@ -312,7 +312,6 @@ export class DataArgProcessorService {
|
||||
|
||||
return transformLinksValue(validatedValue);
|
||||
}
|
||||
case FieldMetadataType.RICH_TEXT:
|
||||
case FieldMetadataType.TS_VECTOR:
|
||||
throw new CommonQueryRunnerException(
|
||||
`${key} ${fieldMetadata.type}-typed field does not support write operations`,
|
||||
|
||||
-4
@@ -140,10 +140,6 @@ exports[`FilterArgProcessorService failing filter inputs validation RELATION sho
|
||||
|
||||
exports[`FilterArgProcessorService failing filter inputs validation RELATION should throw for invalid filter #3: {"manyToOneRelationFieldId":{}} 1`] = `"Filter for field "manyToOneRelationFieldId" must have exactly one operator"`;
|
||||
|
||||
exports[`FilterArgProcessorService failing filter inputs validation RICH_TEXT should throw for invalid filter #1: {"richTextField":{"invalidOperator":"test"}} 1`] = `"Operator "invalidOperator" is not valid for field "richTextField" of type RICH_TEXT - Allowed operators: eq, neq, gt, gte, lt, lte, in, is, like, ilike, startsWith, endsWith"`;
|
||||
|
||||
exports[`FilterArgProcessorService failing filter inputs validation RICH_TEXT should throw for invalid filter #2: {"richTextField":{}} 1`] = `"Filter for field "richTextField" must have exactly one operator"`;
|
||||
|
||||
exports[`FilterArgProcessorService failing filter inputs validation RICH_TEXT_V2 should throw for invalid filter #1: {"richTextV2Field":{"invalidOperator":"test"}} 1`] = `"Sub field "invalidOperator" not found for composite type: RICH_TEXT_V2"`;
|
||||
|
||||
exports[`FilterArgProcessorService failing filter inputs validation RICH_TEXT_V2 should throw for invalid filter #2: {"richTextV2Field":{"markdown":{"invalidOperator":"test"}}} 1`] = `"Operator "invalidOperator" is not valid for field "richTextV2Field.markdown" of type TEXT - Allowed operators: eq, neq, gt, gte, lt, lte, in, is, like, ilike, startsWith, endsWith"`;
|
||||
|
||||
-4
@@ -11,10 +11,6 @@ export const failingFilterInputsByFieldMetadataType: {
|
||||
{ filter: { textField: { eq: 'test', neq: 'test' } } },
|
||||
{ filter: { textField: {} } },
|
||||
],
|
||||
[FieldMetadataType.RICH_TEXT]: [
|
||||
{ filter: { richTextField: { invalidOperator: 'test' } } },
|
||||
{ filter: { richTextField: {} } },
|
||||
],
|
||||
[FieldMetadataType.NUMBER]: [
|
||||
{ filter: { numberField: { eq: 'not-a-number' } } },
|
||||
{ filter: { numberField: { eq: {} } } },
|
||||
|
||||
-7
@@ -21,13 +21,6 @@ export const successfulFilterInputsByFieldMetadataType: {
|
||||
{ filter: { textField: { is: 'NOT_NULL' } } },
|
||||
{ filter: { textField: { eq: null } } },
|
||||
],
|
||||
[FieldMetadataType.RICH_TEXT]: [
|
||||
{ filter: { richTextField: { eq: 'test' } } },
|
||||
{ filter: { richTextField: { like: '%test%' } } },
|
||||
{ filter: { richTextField: { ilike: '%test%' } } },
|
||||
{ filter: { richTextField: { is: 'NULL' } } },
|
||||
{ filter: { richTextField: { is: 'NOT_NULL' } } },
|
||||
],
|
||||
[FieldMetadataType.NUMBER]: [
|
||||
{ filter: { numberField: { eq: 1 } } },
|
||||
{ filter: { numberField: { neq: 1 } } },
|
||||
|
||||
-1
@@ -20,7 +20,6 @@ export const getOperatorsForFieldType = (
|
||||
): FilterOperator[] => {
|
||||
switch (fieldType) {
|
||||
case FieldMetadataType.TEXT:
|
||||
case FieldMetadataType.RICH_TEXT:
|
||||
return STRING_FILTER_OPERATORS;
|
||||
|
||||
case FieldMetadataType.NUMBER:
|
||||
|
||||
Reference in New Issue
Block a user