fix: prevent NUMERIC field type creation via API (#16038)

Block users from creating NUMERIC, POSITION, and TS_VECTOR fields via
the API as these are system-only types. Users should use NUMBER instead
of NUMERIC.

/closes #16023
This commit is contained in:
neo773
2025-11-25 14:21:48 +05:30
committed by GitHub
parent 7109abc311
commit 316aec3c40
5 changed files with 303 additions and 10 deletions
@@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common';
import { msg } from '@lingui/core/macro';
import { isDefined } from 'class-validator';
import { FieldMetadataType } from 'twenty-shared/types';
import { FieldMetadataExceptionCode } from 'src/engine/metadata-modules/field-metadata/field-metadata.exception';
import { FlatEntityPropertiesUpdates } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
@@ -20,6 +21,32 @@ export type GenericValidateFlatFieldMetadataTypeSpecificitiesArgs =
updates?: FlatEntityPropertiesUpdates<'fieldMetadata'>;
};
const rejectUserCreation = (
fieldType: FieldMetadataType,
message: string,
userFriendlyMessage: ReturnType<typeof msg>,
) => {
return async (
args: GenericValidateFlatFieldMetadataTypeSpecificitiesArgs,
): Promise<FlatFieldMetadataValidationError[]> => {
const isCreation = !isDefined(args.updates);
const isCustomField = args.flatEntityToValidate.isCustom;
if (isCreation && isCustomField) {
return [
{
code: FieldMetadataExceptionCode.INVALID_FIELD_INPUT,
message,
value: fieldType,
userFriendlyMessage,
},
];
}
return [];
};
};
@Injectable()
export class FlatFieldMetadataTypeValidatorService {
constructor() {}
@@ -37,14 +64,26 @@ export class FlatFieldMetadataTypeValidatorService {
FULL_NAME: DEFAULT_NO_VALIDATION,
LINKS: DEFAULT_NO_VALIDATION,
NUMBER: DEFAULT_NO_VALIDATION,
NUMERIC: DEFAULT_NO_VALIDATION,
NUMERIC: rejectUserCreation(
FieldMetadataType.NUMERIC,
'Field type NUMERIC is not supported for field creation. Use NUMBER instead.',
msg`Field type NUMERIC is not supported. Use Number instead.`,
),
PHONES: DEFAULT_NO_VALIDATION,
POSITION: DEFAULT_NO_VALIDATION,
POSITION: rejectUserCreation(
FieldMetadataType.POSITION,
'Field type POSITION is a system type and cannot be created manually.',
msg`Field type POSITION is a system type and cannot be created manually.`,
),
RAW_JSON: DEFAULT_NO_VALIDATION,
RICH_TEXT: DEFAULT_NO_VALIDATION,
RICH_TEXT_V2: DEFAULT_NO_VALIDATION,
TEXT: DEFAULT_NO_VALIDATION,
TS_VECTOR: DEFAULT_NO_VALIDATION,
TS_VECTOR: rejectUserCreation(
FieldMetadataType.TS_VECTOR,
'Field type TS_VECTOR is a system type and cannot be created manually.',
msg`Field type TS_VECTOR is a system type and cannot be created manually.`,
),
UUID: DEFAULT_NO_VALIDATION,
MORPH_RELATION: async (args) => {