diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts index 4fe6f916fa..e1f294b146 100644 --- a/packages/twenty-front/src/generated-metadata/graphql.ts +++ b/packages/twenty-front/src/generated-metadata/graphql.ts @@ -1287,7 +1287,6 @@ export enum FeatureFlagKey { IS_GLOBAL_WORKSPACE_DATASOURCE_ENABLED = 'IS_GLOBAL_WORKSPACE_DATASOURCE_ENABLED', IS_IMAP_SMTP_CALDAV_ENABLED = 'IS_IMAP_SMTP_CALDAV_ENABLED', IS_JSON_FILTER_ENABLED = 'IS_JSON_FILTER_ENABLED', - IS_NULL_EQUIVALENCE_ENABLED = 'IS_NULL_EQUIVALENCE_ENABLED', IS_PAGE_LAYOUT_ENABLED = 'IS_PAGE_LAYOUT_ENABLED', IS_POSTGRESQL_INTEGRATION_ENABLED = 'IS_POSTGRESQL_INTEGRATION_ENABLED', IS_PUBLIC_DOMAIN_ENABLED = 'IS_PUBLIC_DOMAIN_ENABLED', diff --git a/packages/twenty-front/src/generated/graphql.ts b/packages/twenty-front/src/generated/graphql.ts index 417a6a9d48..bdefcc69f3 100644 --- a/packages/twenty-front/src/generated/graphql.ts +++ b/packages/twenty-front/src/generated/graphql.ts @@ -1270,7 +1270,6 @@ export enum FeatureFlagKey { IS_GLOBAL_WORKSPACE_DATASOURCE_ENABLED = 'IS_GLOBAL_WORKSPACE_DATASOURCE_ENABLED', IS_IMAP_SMTP_CALDAV_ENABLED = 'IS_IMAP_SMTP_CALDAV_ENABLED', IS_JSON_FILTER_ENABLED = 'IS_JSON_FILTER_ENABLED', - IS_NULL_EQUIVALENCE_ENABLED = 'IS_NULL_EQUIVALENCE_ENABLED', IS_PAGE_LAYOUT_ENABLED = 'IS_PAGE_LAYOUT_ENABLED', IS_POSTGRESQL_INTEGRATION_ENABLED = 'IS_POSTGRESQL_INTEGRATION_ENABLED', IS_PUBLIC_DOMAIN_ENABLED = 'IS_PUBLIC_DOMAIN_ENABLED', diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-12/1-12-clean-null-equivalent-values.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-12/1-12-clean-null-equivalent-values.ts index b4271af8eb..ad80618a8b 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-12/1-12-clean-null-equivalent-values.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-12/1-12-clean-null-equivalent-values.ts @@ -13,7 +13,6 @@ import { 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 { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; @@ -83,22 +82,6 @@ export class CleanNullEquivalentValuesCommand extends ActiveOrSuspendedWorkspace this.logger.log('Dry run mode: No changes will be applied'); } - const featureFlag = await this.featureFlagRepository.findOne({ - where: { - key: FeatureFlagKey.IS_NULL_EQUIVALENCE_ENABLED, - value: true, - workspaceId, - }, - }); - - if (isDefined(featureFlag)) { - this.logger.log( - `Feature flag ${FeatureFlagKey.IS_NULL_EQUIVALENCE_ENABLED} already enabled for workspace ${workspaceId}`, - ); - - return; - } - const objectMetadataItems = await this.objectMetadataRepository.find({ where: { workspaceId }, relations: [ @@ -278,20 +261,6 @@ export class CleanNullEquivalentValuesCommand extends ActiveOrSuspendedWorkspace } } } - if (!isDryRun) { - await this.featureFlagRepository.upsert( - { - key: FeatureFlagKey.IS_NULL_EQUIVALENCE_ENABLED, - value: true, - workspaceId, - }, - ['key', 'workspaceId'], - ); - - this.logger.log( - `Switched on feature flag ${FeatureFlagKey.IS_NULL_EQUIVALENCE_ENABLED} for workspace ${workspaceId}`, - ); - } } private objectEquals(obj1: unknown, obj2: unknown): boolean { diff --git a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/data-arg.processor.ts b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/data-arg.processor.ts index b289262100..85bd811e21 100644 --- a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/data-arg.processor.ts +++ b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/data-arg.processor.ts @@ -44,7 +44,6 @@ import { CommonQueryRunnerExceptionCode, } from 'src/engine/api/common/common-query-runners/errors/common-query-runner.exception'; import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type'; -import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service'; import { RecordPositionService } from 'src/engine/core-modules/record-position/services/record-position.service'; import { transformEmailsValue } from 'src/engine/core-modules/record-transformer/utils/transform-emails-value.util'; @@ -85,12 +84,6 @@ export class DataArgProcessor { assertIsDefinedOrThrow(workspace, WorkspaceNotFoundDefaultError); - const isNullEquivalenceEnabled = - await this.featureFlagService.isFeatureEnabled( - FeatureFlagKey.IS_NULL_EQUIVALENCE_ENABLED, - workspace.id, - ); - const { fieldIdByName, fieldIdByJoinColumnName } = buildFieldMapsFromFlatObjectMetadata( flatFieldMetadataMaps, @@ -141,7 +134,6 @@ export class DataArgProcessor { fieldMetadata, key, value, - isNullEquivalenceEnabled, ); } processedRecords.push(processedRecord); @@ -166,7 +158,6 @@ export class DataArgProcessor { fieldMetadata: FlatFieldMetadata, key: string, value: unknown, - isNullEquivalenceEnabled: boolean, ): Promise { switch (fieldMetadata.type) { case FieldMetadataType.POSITION: @@ -182,7 +173,7 @@ export class DataArgProcessor { case FieldMetadataType.TEXT: { const validatedValue = validateTextFieldOrThrow(value, key); - return transformTextField(validatedValue, isNullEquivalenceEnabled); + return transformTextField(validatedValue); } case FieldMetadataType.DATE_TIME: case FieldMetadataType.DATE: @@ -207,19 +198,19 @@ export class DataArgProcessor { fieldMetadata.options?.map((option) => option.value), ); - return transformArrayField(validatedValue, isNullEquivalenceEnabled); + return transformArrayField(validatedValue); } case FieldMetadataType.UUID: return validateUUIDFieldOrThrow(value, key); case FieldMetadataType.ARRAY: { const validatedValue = validateArrayFieldOrThrow(value, key); - return transformArrayField(validatedValue, isNullEquivalenceEnabled); + return transformArrayField(validatedValue); } case FieldMetadataType.RAW_JSON: { const validatedValue = validateRawJsonFieldOrThrow(value, key); - return transformRawJsonField(validatedValue, isNullEquivalenceEnabled); + return transformRawJsonField(validatedValue); } case FieldMetadataType.RELATION: case FieldMetadataType.MORPH_RELATION: { @@ -250,18 +241,18 @@ export class DataArgProcessor { case FieldMetadataType.EMAILS: { const validatedValue = validateEmailsFieldOrThrow(value, key); - return transformEmailsValue(validatedValue, isNullEquivalenceEnabled); + return transformEmailsValue(validatedValue); } case FieldMetadataType.FULL_NAME: { const validatedValue = validateFullNameFieldOrThrow(value, key); - return transformFullNameField(validatedValue, isNullEquivalenceEnabled); + return transformFullNameField(validatedValue); } case FieldMetadataType.ADDRESS: { const validatedValue = validateAddressFieldOrThrow(value, key); - return transformAddressField(validatedValue, isNullEquivalenceEnabled); + return transformAddressField(validatedValue); } case FieldMetadataType.CURRENCY: { const validatedValue = validateCurrencyFieldOrThrow(value, key); @@ -271,7 +262,7 @@ export class DataArgProcessor { case FieldMetadataType.ACTOR: { const validatedValue = validateActorFieldOrThrow(value, key); - return transformActorField(validatedValue, isNullEquivalenceEnabled); + return transformActorField(validatedValue); } case FieldMetadataType.RICH_TEXT_V2: { const validatedValue = validateRichTextV2FieldOrThrow(value, key); diff --git a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/__tests__/transform-actor-field.util.spec.ts b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/__tests__/transform-actor-field.util.spec.ts index 20bbfc6b05..985f47ce44 100644 --- a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/__tests__/transform-actor-field.util.spec.ts +++ b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/__tests__/transform-actor-field.util.spec.ts @@ -4,18 +4,15 @@ import { transformActorField } from 'src/engine/api/common/common-args-processor describe('transformActorField', () => { it('should return null when value is null', () => { - const result = transformActorField(null, true); + const result = transformActorField(null); expect(result).toBeNull(); }); it('should transform actor with source only', () => { - const result = transformActorField( - { - source: FieldActorSource.EMAIL, - }, - true, - ); + const result = transformActorField({ + source: FieldActorSource.EMAIL, + }); expect(result).toEqual({ source: FieldActorSource.EMAIL, @@ -23,13 +20,10 @@ describe('transformActorField', () => { }); it('should transform actor with source and context', () => { - const result = transformActorField( - { - source: FieldActorSource.WORKFLOW, - context: { workflowId: '123', stepId: 'step-1' }, - }, - true, - ); + const result = transformActorField({ + source: FieldActorSource.WORKFLOW, + context: { workflowId: '123', stepId: 'step-1' }, + }); expect(result).toEqual({ source: FieldActorSource.WORKFLOW, @@ -38,13 +32,10 @@ describe('transformActorField', () => { }); it('should transform actor with null source', () => { - const result = transformActorField( - { - source: null, - context: { userId: '456' }, - }, - true, - ); + const result = transformActorField({ + source: null, + context: { userId: '456' }, + }); expect(result).toEqual({ source: null, @@ -53,13 +44,10 @@ describe('transformActorField', () => { }); it('should transform actor with null context', () => { - const result = transformActorField( - { - source: FieldActorSource.API, - context: null, - }, - true, - ); + const result = transformActorField({ + source: FieldActorSource.API, + context: null, + }); expect(result).toEqual({ source: FieldActorSource.API, @@ -68,13 +56,10 @@ describe('transformActorField', () => { }); it('should transform empty context object to null', () => { - const result = transformActorField( - { - source: FieldActorSource.EMAIL, - context: {}, - }, - true, - ); + const result = transformActorField({ + source: FieldActorSource.EMAIL, + context: {}, + }); expect(result).toEqual({ source: FieldActorSource.EMAIL, diff --git a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/__tests__/transform-array-field.util.spec.ts b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/__tests__/transform-array-field.util.spec.ts index b140022234..ec0923ffbd 100644 --- a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/__tests__/transform-array-field.util.spec.ts +++ b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/__tests__/transform-array-field.util.spec.ts @@ -2,25 +2,25 @@ import { transformArrayField } from 'src/engine/api/common/common-args-processor describe('transformArrayField', () => { it('should return null when value is null', () => { - const result = transformArrayField(null, true); + const result = transformArrayField(null); expect(result).toBeNull(); }); it('should return null when value is an empty array', () => { - const result = transformArrayField([], true); + const result = transformArrayField([]); expect(result).toBeNull(); }); it('should return an array when value is a string', () => { - const result = transformArrayField('singleString', true); + const result = transformArrayField('singleString'); expect(result).toEqual(['singleString']); }); it('should return an array when value is an array of strings', () => { - const result = transformArrayField(['string1', 'string2', 'string3'], true); + const result = transformArrayField(['string1', 'string2', 'string3']); expect(result).toEqual(['string1', 'string2', 'string3']); }); diff --git a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/__tests__/transform-full-name-field.util.spec.ts b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/__tests__/transform-full-name-field.util.spec.ts index 2f2716509b..f3f724e120 100644 --- a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/__tests__/transform-full-name-field.util.spec.ts +++ b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/__tests__/transform-full-name-field.util.spec.ts @@ -2,7 +2,7 @@ import { transformFullNameField } from 'src/engine/api/common/common-args-proces describe('transformFullNameField', () => { it('should return null when value is null', () => { - const result = transformFullNameField(null, true); + const result = transformFullNameField(null); expect(result).toBeNull(); }); @@ -12,7 +12,7 @@ describe('transformFullNameField', () => { firstName: 'John', lastName: 'Doe', }; - const result = transformFullNameField(value, true); + const result = transformFullNameField(value); expect(result).toEqual({ firstName: 'John', @@ -24,7 +24,7 @@ describe('transformFullNameField', () => { const value = { lastName: '', }; - const result = transformFullNameField(value, true); + const result = transformFullNameField(value); expect(result).toEqual({ lastName: null, diff --git a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/__tests__/transform-raw-json-field.util.spec.ts b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/__tests__/transform-raw-json-field.util.spec.ts index 600c2a63aa..09c47f4214 100644 --- a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/__tests__/transform-raw-json-field.util.spec.ts +++ b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/__tests__/transform-raw-json-field.util.spec.ts @@ -2,19 +2,19 @@ import { transformRawJsonField } from 'src/engine/api/common/common-args-process describe('transformRawJsonField', () => { it('should return null when value is null', () => { - const result = transformRawJsonField(null, true); + const result = transformRawJsonField(null); expect(result).toBeNull(); }); it('should return null when value is empty object', () => { - const result = transformRawJsonField({}, true); + const result = transformRawJsonField({}); expect(result).toBeNull(); }); it('should return the string when value is empty array', () => { - const result = transformRawJsonField([], true); + const result = transformRawJsonField([]); expect(result).toBeNull(); }); diff --git a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/__tests__/transform-text-field.util.spec.ts b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/__tests__/transform-text-field.util.spec.ts index cfdffb2783..3454e034d6 100644 --- a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/__tests__/transform-text-field.util.spec.ts +++ b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/__tests__/transform-text-field.util.spec.ts @@ -2,19 +2,19 @@ import { transformTextField } from 'src/engine/api/common/common-args-processors describe('transformTextField', () => { it('should return null when value is null', () => { - const result = transformTextField(null, true); + const result = transformTextField(null); expect(result).toBeNull(); }); it('should return null when value is empty string', () => { - const result = transformTextField('', true); + const result = transformTextField(''); expect(result).toBeNull(); }); it('should return the string when value is a non-empty string', () => { - const result = transformTextField('hello world', true); + const result = transformTextField('hello world'); expect(result).toBe('hello world'); }); diff --git a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-actor-field.util.ts b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-actor-field.util.ts index f6d8f4715b..c0a46a7439 100644 --- a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-actor-field.util.ts +++ b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-actor-field.util.ts @@ -11,7 +11,6 @@ export const transformActorField = ( name?: string | null; workspaceMemberId?: string | null; } | null, - isNullEquivalenceEnabled: boolean = false, ): { source?: FieldActorSource | null; context?: object | string | null; @@ -24,10 +23,8 @@ export const transformActorField = ( source: value.source, context: isUndefined(value.context) ? undefined - : transformRawJsonField(value.context, isNullEquivalenceEnabled), - name: isUndefined(value.name) - ? undefined - : transformTextField(value.name, isNullEquivalenceEnabled), + : transformRawJsonField(value.context), + name: isUndefined(value.name) ? undefined : transformTextField(value.name), workspaceMemberId: isUndefined(value.workspaceMemberId) ? undefined : value.workspaceMemberId, diff --git a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-address-field.util.ts b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-address-field.util.ts index 537f6d148b..123edae9d3 100644 --- a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-address-field.util.ts +++ b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-address-field.util.ts @@ -14,7 +14,6 @@ export const transformAddressField = ( addressLat?: number | null; addressLng?: number | null; } | null, - isNullEquivalenceEnabled: boolean = false, ): { addressStreet1?: string | null; addressStreet2?: string | null; @@ -30,22 +29,22 @@ export const transformAddressField = ( return { addressStreet1: isUndefined(value.addressStreet1) ? undefined - : transformTextField(value.addressStreet1, isNullEquivalenceEnabled), + : transformTextField(value.addressStreet1), addressStreet2: isUndefined(value.addressStreet2) ? undefined - : transformTextField(value.addressStreet2, isNullEquivalenceEnabled), + : transformTextField(value.addressStreet2), addressCity: isUndefined(value.addressCity) ? undefined - : transformTextField(value.addressCity, isNullEquivalenceEnabled), + : transformTextField(value.addressCity), addressState: isUndefined(value.addressState) ? undefined - : transformTextField(value.addressState, isNullEquivalenceEnabled), + : transformTextField(value.addressState), addressPostcode: isUndefined(value.addressPostcode) ? undefined - : transformTextField(value.addressPostcode, isNullEquivalenceEnabled), + : transformTextField(value.addressPostcode), addressCountry: isUndefined(value.addressCountry) ? undefined - : transformTextField(value.addressCountry, isNullEquivalenceEnabled), + : transformTextField(value.addressCountry), addressLat: isUndefined(value.addressLat) ? undefined : transformNumericField(value.addressLat), diff --git a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-array-field.util.ts b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-array-field.util.ts index 5cc7cb4263..6ada51b487 100644 --- a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-array-field.util.ts +++ b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-array-field.util.ts @@ -2,11 +2,8 @@ import { isNullEquivalentArrayFieldValue } from 'src/engine/api/common/common-ar export const transformArrayField = ( value: string | string[] | null, - isNullEquivalenceEnabled: boolean = false, ): string[] | null => { if (typeof value === 'string') return [value]; - return isNullEquivalenceEnabled && isNullEquivalentArrayFieldValue(value) - ? null - : value; + return isNullEquivalentArrayFieldValue(value) ? null : value; }; diff --git a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-currency-field.util.ts b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-currency-field.util.ts index 7481f4b49d..3f9441853a 100644 --- a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-currency-field.util.ts +++ b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-currency-field.util.ts @@ -8,7 +8,6 @@ export const transformCurrencyField = ( amountMicros?: number | string | null; currencyCode?: string | null; } | null, - isNullEquivalenceEnabled: boolean = false, ): { amountMicros?: number | null; currencyCode?: string | null; @@ -21,6 +20,6 @@ export const transformCurrencyField = ( : transformNumericField(value.amountMicros), currencyCode: isUndefined(value.currencyCode) ? undefined - : transformTextField(value.currencyCode, isNullEquivalenceEnabled), + : transformTextField(value.currencyCode), }; }; diff --git a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-full-name-field.util.ts b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-full-name-field.util.ts index 90dec4d07e..7a41982be4 100644 --- a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-full-name-field.util.ts +++ b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-full-name-field.util.ts @@ -7,7 +7,6 @@ export const transformFullNameField = ( firstName?: string | null; lastName?: string | null; } | null, - isNullEquivalenceEnabled: boolean = false, ): { firstName?: string | null; lastName?: string | null; @@ -17,9 +16,9 @@ export const transformFullNameField = ( return { firstName: isUndefined(value.firstName) ? undefined - : transformTextField(value.firstName, isNullEquivalenceEnabled), + : transformTextField(value.firstName), lastName: isUndefined(value.lastName) ? undefined - : transformTextField(value.lastName, isNullEquivalenceEnabled), + : transformTextField(value.lastName), }; }; diff --git a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-raw-json-field.util.ts b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-raw-json-field.util.ts index 56726c6948..66ab1126c1 100644 --- a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-raw-json-field.util.ts +++ b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-raw-json-field.util.ts @@ -3,9 +3,6 @@ import { isNullEquivalentRawJsonFieldValue } from 'src/engine/api/common/common- export const transformRawJsonField = ( value: object | string | null, - isNullEquivalenceEnabled: boolean = false, ): object | string | null => { - return isNullEquivalenceEnabled && isNullEquivalentRawJsonFieldValue(value) - ? null - : value; + return isNullEquivalentRawJsonFieldValue(value) ? null : value; }; diff --git a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-text-field.util.ts b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-text-field.util.ts index 08ebfa4c4d..acb2986ab5 100644 --- a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-text-field.util.ts +++ b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-text-field.util.ts @@ -1,10 +1,5 @@ import { isNullEquivalentTextFieldValue } from 'src/engine/api/common/common-args-processors/data-arg-processor/utils/is-null-equivalent-text-field-value.util'; -export const transformTextField = ( - value: string | null, - isNullEquivalenceEnabled: boolean = false, -): string | null => { - return isNullEquivalenceEnabled && isNullEquivalentTextFieldValue(value) - ? null - : value; +export const transformTextField = (value: string | null): string | null => { + return isNullEquivalentTextFieldValue(value) ? null : value; }; diff --git a/packages/twenty-server/src/engine/core-modules/feature-flag/enums/feature-flag-key.enum.ts b/packages/twenty-server/src/engine/core-modules/feature-flag/enums/feature-flag-key.enum.ts index 6e3ad3c8df..e174371735 100644 --- a/packages/twenty-server/src/engine/core-modules/feature-flag/enums/feature-flag-key.enum.ts +++ b/packages/twenty-server/src/engine/core-modules/feature-flag/enums/feature-flag-key.enum.ts @@ -15,5 +15,4 @@ export enum FeatureFlagKey { IS_WORKFLOW_RUN_STOPPAGE_ENABLED = 'IS_WORKFLOW_RUN_STOPPAGE_ENABLED', IS_DASHBOARD_V2_ENABLED = 'IS_DASHBOARD_V2_ENABLED', IS_GLOBAL_WORKSPACE_DATASOURCE_ENABLED = 'IS_GLOBAL_WORKSPACE_DATASOURCE_ENABLED', - IS_NULL_EQUIVALENCE_ENABLED = 'IS_NULL_EQUIVALENCE_ENABLED', } diff --git a/packages/twenty-server/src/engine/core-modules/record-crud/services/upsert-record.service.ts b/packages/twenty-server/src/engine/core-modules/record-crud/services/upsert-record.service.ts index 972f37830d..f7705b9d9c 100644 --- a/packages/twenty-server/src/engine/core-modules/record-crud/services/upsert-record.service.ts +++ b/packages/twenty-server/src/engine/core-modules/record-crud/services/upsert-record.service.ts @@ -16,7 +16,6 @@ import { getCompositeTypeOrThrow } from 'src/engine/metadata-modules/field-metad import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import { buildFieldMapsFromFlatObjectMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/build-field-maps-from-flat-object-metadata.util'; -import { computeUniqueIndexWhereClause } from 'src/engine/metadata-modules/index-metadata/utils/compute-unique-index-where-clause.util'; import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; @Injectable() @@ -148,17 +147,6 @@ export class UpsertRecordService { ? conflictPathsUniqueFieldsToUpdate : ['id']; - //TODO : To delete once IS_NULL_EQUIVALENCE_ENABLED feature flag removed - const indexPredicate = uniqueFieldsToUpdate - .map((field) => - computeUniqueIndexWhereClause({ - type: field.type, - name: field.name, - defaultValue: field.defaultValue, - }), - ) - .filter(isDefined); - const restrictedFields = repository.objectRecordsPermissions?.[flatObjectMetadata.id] ?.restrictedFields; @@ -173,10 +161,6 @@ export class UpsertRecordService { transformedObjectRecord, { conflictPaths: conflictPaths, - indexPredicate: - indexPredicate.length > 0 - ? `${indexPredicate.join(' AND ')}` - : undefined, }, undefined, selectedColumns, diff --git a/packages/twenty-server/src/engine/core-modules/record-transformer/utils/transform-emails-value.util.ts b/packages/twenty-server/src/engine/core-modules/record-transformer/utils/transform-emails-value.util.ts index 3112574473..b600694c4a 100644 --- a/packages/twenty-server/src/engine/core-modules/record-transformer/utils/transform-emails-value.util.ts +++ b/packages/twenty-server/src/engine/core-modules/record-transformer/utils/transform-emails-value.util.ts @@ -1,9 +1,8 @@ -import { isNonEmptyString } from '@sniptt/guards'; +import { isNonEmptyArray, isNonEmptyString } from '@sniptt/guards'; export const transformEmailsValue = ( // eslint-disable-next-line @typescript-eslint/no-explicit-any value: any, - isNullEquivalenceEnabled: boolean = false, // eslint-disable-next-line @typescript-eslint/no-explicit-any ): any => { if (!value) { @@ -13,9 +12,7 @@ export const transformEmailsValue = ( let additionalEmails: string | null = value?.additionalEmails; const primaryEmail = value?.primaryEmail ? value.primaryEmail.toLowerCase() - : isNullEquivalenceEnabled - ? null - : ''; + : null; if (additionalEmails) { try { @@ -25,16 +22,9 @@ export const transformEmailsValue = ( : additionalEmails ) as string[]; - additionalEmails = JSON.stringify( - emailArray.map((email) => email.toLowerCase()), - ); - - if (isNullEquivalenceEnabled) { - additionalEmails = - Array.isArray(emailArray) && emailArray.length === 0 - ? null - : additionalEmails; - } + additionalEmails = isNonEmptyArray(emailArray) + ? JSON.stringify(emailArray.map((email) => email.toLowerCase())) + : null; } catch { /* empty */ } diff --git a/packages/twenty-server/src/engine/metadata-modules/index-metadata/utils/compute-unique-index-where-clause.util.ts b/packages/twenty-server/src/engine/metadata-modules/index-metadata/utils/compute-unique-index-where-clause.util.ts deleted file mode 100644 index 16a111e5f8..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/index-metadata/utils/compute-unique-index-where-clause.util.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { isNonEmptyString } from '@sniptt/guards'; -import { - FieldMetadataType, - compositeTypeDefinitions, -} from 'twenty-shared/types'; -import { isDefined } from 'twenty-shared/utils'; - -import { type FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; -import { - FieldMetadataException, - FieldMetadataExceptionCode, -} from 'src/engine/metadata-modules/field-metadata/field-metadata.exception'; -import { computeCompositeColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util'; -import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; -import { - IndexMetadataException, - IndexMetadataExceptionCode, -} from 'src/engine/metadata-modules/index-metadata/index-field-metadata.exception'; - -//TODO : To delete once IS_NULL_EQUIVALENCE_ENABLED feature flag removed -export const computeUniqueIndexWhereClause = ( - fieldMetadata: Pick, -) => { - const defaultValue = fieldMetadata.defaultValue; - - if (!isDefined(defaultValue)) return; - - if ( - fieldMetadata.type === FieldMetadataType.RELATION || - fieldMetadata.type === FieldMetadataType.MORPH_RELATION - ) { - throw new IndexMetadataException( - `Unique index cannot be created for relation or morph relation field ${fieldMetadata.name}`, - IndexMetadataExceptionCode.INDEX_NOT_SUPPORTED_FOR_MORH_RELATION_FIELD_AND_RELATION_FIELD, - ); - } - - if (!isCompositeFieldMetadataType(fieldMetadata.type)) { - return `"${fieldMetadata.name}" != ${defaultValue}`; - } - - const compositeType = compositeTypeDefinitions.get(fieldMetadata.type); - - if (!isDefined(compositeType)) { - throw new FieldMetadataException( - `Composite type not found for field metadata type: ${fieldMetadata.type}`, - FieldMetadataExceptionCode.INTERNAL_SERVER_ERROR, - ); - } - - const defaultDefaultValueProperties = Object.keys(defaultValue); - - const columnNamesWithDefaultValues = compositeType.properties - .filter( - (property) => - property.isIncludedInUniqueConstraint && - defaultDefaultValueProperties.includes(property.name), - ) - .map((property) => { - const defaultValueProperty = - defaultValue[property.name as keyof typeof defaultValue]; - - if (isNonEmptyString(defaultValueProperty)) { - return [ - computeCompositeColumnName(fieldMetadata, property), - defaultValueProperty, - ]; - } - }) - .filter(isDefined); - - return columnNamesWithDefaultValues.length > 0 - ? columnNamesWithDefaultValues - .map( - ([columnName, defaultValue]) => `"${columnName}" != ${defaultValue}`, - ) - .join(' OR ') - : undefined; -}; diff --git a/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.spec.ts b/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.spec.ts index 5e7d4b256d..aca2c2b418 100644 --- a/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.spec.ts +++ b/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.spec.ts @@ -207,7 +207,6 @@ describe('WorkspaceEntityManager', () => { IS_WORKFLOW_RUN_STOPPAGE_ENABLED: false, IS_DASHBOARD_V2_ENABLED: false, IS_GLOBAL_WORKSPACE_DATASOURCE_ENABLED: false, - IS_NULL_EQUIVALENCE_ENABLED: false, }, eventEmitterService: { emitMutationEvent: jest.fn(), @@ -234,7 +233,6 @@ describe('WorkspaceEntityManager', () => { IS_WORKFLOW_RUN_STOPPAGE_ENABLED: false, IS_DASHBOARD_V2_ENABLED: false, IS_GLOBAL_WORKSPACE_DATASOURCE_ENABLED: false, - IS_NULL_EQUIVALENCE_ENABLED: false, }, permissionsPerRoleId: {}, } as WorkspaceDataSource; diff --git a/packages/twenty-server/src/engine/workspace-manager/dev-seeder/core/utils/seed-feature-flags.util.ts b/packages/twenty-server/src/engine/workspace-manager/dev-seeder/core/utils/seed-feature-flags.util.ts index ee34a837aa..33e19438d0 100644 --- a/packages/twenty-server/src/engine/workspace-manager/dev-seeder/core/utils/seed-feature-flags.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/dev-seeder/core/utils/seed-feature-flags.util.ts @@ -92,11 +92,6 @@ export const seedFeatureFlags = async ({ workspaceId: workspaceId, value: true, }, - { - key: FeatureFlagKey.IS_NULL_EQUIVALENCE_ENABLED, - workspaceId: workspaceId, - value: true, - }, ]) .execute(); }; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/default-feature-flags.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/default-feature-flags.ts index 31efe0cd65..b3b022fe39 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/default-feature-flags.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/default-feature-flags.ts @@ -2,5 +2,4 @@ import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/featu export const DEFAULT_FEATURE_FLAGS = [ FeatureFlagKey.IS_WORKSPACE_MIGRATION_V2_ENABLED, - FeatureFlagKey.IS_NULL_EQUIVALENCE_ENABLED, ] as const satisfies FeatureFlagKey[];