From 9c66975520ee967a229b3a0a5c37bb40db44d402 Mon Sep 17 00:00:00 2001 From: Weiko Date: Tue, 9 Jun 2026 15:57:19 +0200 Subject: [PATCH] isCustom deprecation for Objects and Fields (#21228) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Context `isCustom` was a legacy denormalized boolean on `ObjectMetadataEntity` and `FieldMetadataEntity`. Now that every metadata row carries `applicationId` (via `SyncableEntity`), "is this custom" is fully derivable, and the stored boolean was a redundant second source of truth that could drift. The real meaning of `isCustom` is **"the owning application is not the twenty-standard application"** — i.e. `!belongsToTwentyStandardApp`. Note this is *not* "belongs to the workspace custom app" as I initially thought: third-party-application objects/fields are custom too. The standard application has a globally stable `universalIdentifier`, so the value derives with no per-workspace lookup. ## Changed ## `isCustom` checks — before → after `isCustom` is no longer a stored column. The table below lists every site that branched on it and how it resolves now. The unifying rule: `isCustom ≡ !isTwentyStandardApplicationUniversalIdentifier(applicationUniversalIdentifier)`. ### Server — behavioural checks | Location | Purpose | Before | Now | |---|---|---|---| | `utils/compute-object-target-table.util.ts` | Physical table name `_` prefix | `computeTableName(nameSingular, objectMetadata.isCustom)` | derives from `applicationUniversalIdentifier` (single source for all table-name callers) | | `twenty-orm/factories/entity-schema.factory.ts` + `…/entity-schema-metadata.type.ts` | ORM table name (hot path) | `object.isCustom` | `object.applicationId !== standardApplicationId` (computed in `buildEntitySchemaMetadataMaps`) | | `twenty-orm/repository/workspace-{delete,soft-delete,update}-query-builder.ts` | Table name for mutations | `computeTableName(nameSingular, objectMetadata.isCustom)` | `computeObjectTargetTable(objectMetadata)` | | `index-metadata/utils/generate-deterministic-index-name-v2.ts` | Index name hash (must stay bit-identical) | `flatObjectMetadata.isCustom` | derives from `applicationUniversalIdentifier` | | `object-metadata/object-record-count.service.ts` | Table name for record count | `computeTableName(nameSingular, isCustom)` | `computeObjectTargetTable(flatObjectMetadata)` | | `workspace-manager/dev-seeder/data/services/dev-seeder-data.service.ts` | Match seed config by table name | `computeTableName(item.nameSingular, item.isCustom)` | `computeObjectTargetTable(item)` | | `commands/workspace-export/workspace-export.service.ts` + `…/utils/generate-workspace-schema-ddl.util.ts` | Export table name (raw entity) | `objectMetadata.isCustom` | `!isTwentyStandard…(objectMetadata.application?.universalIdentifier)` | | `flat-field-metadata/services/flat-field-metadata-type-validator.service.ts` | Block users creating reserved field types | `args.flatEntityToValidate.isCustom` | `!args.flatEntityToValidate.isSystem` | | `api/common/.../common-create-many-query-runner.service.ts` | Don't let client overwrite system `createdBy` | `createdByFieldMetadata.isCustom === false` | `createdByFieldMetadata.isSystem === true` | | `field-metadata/utils/resolve-field-metadata-standard-override.util.ts` | Skip i18n/overrides for custom fields | `if (fieldMetadata.isCustom) return raw` | **removed** — falls through on `isDefined(standardOverrides)` | | `object-metadata/utils/resolve-object-metadata-standard-override.util.ts` | Skip i18n/overrides for custom objects | `if (objectMetadata.isCustom) return raw` | **removed** — same fall-through | | `command-menu-item/utils/build-navigation-interpolation-context.util.ts` | Override context for nav labels | passed `isCustom` into resolver | dropped (resolver no longer needs it) | | `api/common/.../data-arg-processor.service.ts` | `isCustom` for record-position table name | `flatObjectMetadata.isCustom` | derives from `applicationUniversalIdentifier` | | `metadata-modules/minimal-metadata/minimal-metadata.service.ts` | Minimal DTO + override context | `flatObjectMetadata.isCustom` | derives from `applicationUniversalIdentifier` | | `commands/upgrade-version-command/1-23/…backfill-record-page-layouts.command.ts` | Filter to custom objects | `objectMetadata.isCustom` | `!isTwentyStandard…(applicationUniversalIdentifier)` | ### Server — DTO / API population | Location | Before | Now | |---|---|---| | `flat-object-metadata/utils/from-flat-object-metadata-to-object-metadata-dto.util.ts` | passthrough `isCustom` | derives from `applicationUniversalIdentifier` | | `flat-field-metadata/utils/from-flat-field-metadata-to-field-metadata-dto.util.ts` | passthrough `isCustom` | derives from `applicationUniversalIdentifier` | | `object-metadata/utils/from-object-metadata-entity-to-object-metadata-dto.util.ts` (REST) | `entity.isCustom` | `entity.applicationId !== standardApplicationId` | | `field-metadata/utils/from-field-metadata-entity-to-field-metadata-dto.util.ts` (REST) | `entity.isCustom` | `entity.applicationId !== standardApplicationId` | | `dataloaders/dataloader.service.ts` | passed `flatFieldMetadata.isCustom` into override resolver | dropped (resolver no longer needs it) | > REST controllers (`object-metadata.controller.ts`, `field-metadata.controller.ts`) resolve `standardApplicationId` once per request from the cached `flatApplicationMaps`. ### Frontend | Location | Purpose | Before | Now | |---|---|---|---| | `settings/.../SettingsObjectFieldDisabledActionDropdown.tsx` | Whether an inactive field is deletable | `isDeletable = isCustomField` | `isDeletable = isCustomField && !isSystemField` | ### Unchanged (out of scope) `isCustom` on `IndexMetadata` / `View` / `Skill` / `Agent` and their guards still read the persisted column. Breaking change is on the isCustom filter on field and object APIs, this is never used in the FE and unlikely used by external consumers --- .../src/__tests__/schema.integration-test.ts | 14 +-- .../src/metadata/generated/schema.graphql | 6 +- .../src/metadata/generated/schema.ts | 8 +- .../src/metadata/generated/types.ts | 6 -- .../src/generated-metadata/graphql.ts | 4 +- ...tingsObjectFieldDisabledActionDropdown.tsx | 4 +- .../SettingsObjectFieldItemTableRow.tsx | 1 + ...s-custom-from-object-and-field-metadata.ts | 44 ++++++++++ .../instance-commands.constant.ts | 2 + .../generate-workspace-schema-ddl.util.ts | 4 +- .../workspace-export.service.ts | 5 +- .../__mocks__/object-metadata-item.mock.ts | 1 - .../data-arg-processor.service.spec.ts | 3 - .../data-arg-processor.service.ts | 3 +- .../filter-arg-processor.service.spec.ts | 3 - ...common-create-many-query-runner.service.ts | 2 +- .../get-conflicting-fields.util.spec.ts | 1 - .../get-all-selectable-fields.util.spec.ts | 1 - .../__mocks__/mockPersonObjectMetadata.ts | 1 - .../__tests__/build-columns-to-select.spec.ts | 2 - .../utils/__tests__/cursors.util.spec.ts | 1 - .../__tests__/selected-fields-handler.spec.ts | 1 - .../compute-cursor-arg-filter.utils.spec.ts | 1 - .../__mocks__/mockFlatObjectMetadatas.ts | 10 --- .../mockObjectMetadataItemsWithFieldMaps.ts | 9 -- ...ifest-to-universal-flat-index.util.spec.ts | 1 - ...t-to-universal-flat-field-metadata.util.ts | 1 - ...-to-universal-flat-object-metadata.util.ts | 1 - .../application-rest-api-exception.filter.ts | 67 ++++++++++++++ .../object-record-changed-values.spec.ts | 1 - .../was-removed-in-upgrade.decorator.ts | 18 ++++ .../dataloaders/dataloader.interface.ts | 3 + .../engine/dataloaders/dataloader.service.ts | 32 ++++++- ...ation-command-menu-item-field.util.spec.ts | 3 - ...d-navigation-interpolation-context.util.ts | 2 - .../controllers/field-metadata.controller.ts | 39 +++++++-- .../field-metadata/dtos/field-metadata.dto.ts | 6 +- .../field-metadata/field-metadata.entity.ts | 9 +- .../field-metadata/field-metadata.module.ts | 1 + .../field-metadata/field-metadata.resolver.ts | 16 ++++ ...ld-metadata-standard-override.util.spec.ts | 17 ---- ...adata-entity-to-field-metadata-dto.util.ts | 3 +- ...e-field-metadata-standard-override.util.ts | 6 +- ...configuration-by-metadata-name.constant.ts | 10 --- .../types/scalar-flat-entity.type.ts | 3 +- .../__mocks__/attachment-flat-fields.mock.ts | 16 ---- .../__mocks__/company-flat-fields.mock.ts | 23 ----- .../__mocks__/get-flat-field-metadata.mock.ts | 2 - ...elation-target-flat-field-metadata-mock.ts | 1 - .../__mocks__/note-flat-fields.mock.ts | 12 --- .../__mocks__/notetarget-flat-fields.mock.ts | 11 --- .../__mocks__/opportunity-flat-fields.mock.ts | 17 ---- .../__mocks__/person-flat-fields.mock.ts | 25 ------ .../__mocks__/pet-flat-fields.mock.ts | 28 ------ .../__mocks__/rocket-flat-fields.mock.ts | 12 --- .../__mocks__/task-flat-fields.mock.ts | 15 ---- .../__mocks__/tasktarget-flat-fields.mock.ts | 11 --- .../timelineactivity-flat-fields.mock.ts | 22 ----- ...lat-field-metadatas-to-create.spec.ts.snap | 6 +- ...t-field-metadata-type-validator.service.ts | 5 +- ...-relation-flat-field-metadata-pair.spec.ts | 7 -- ...eld-metadata-to-field-metadata-dto.util.ts | 4 +- ...d-metadata-from-create-field-input.util.ts | 1 - .../__mocks__/attachment-flat-object.mock.ts | 5 +- .../__mocks__/company-flat-object.mock.ts | 5 +- .../get-flat-object-metadata.mock.ts | 5 +- .../__mocks__/note-flat-object.mock.ts | 5 +- .../__mocks__/note-target-flat-object.mock.ts | 5 +- .../__mocks__/opportunity-flat-object.mock.ts | 5 +- .../__mocks__/person-flat-object.mock.ts | 5 +- .../__mocks__/pet-flat-object.mock.ts | 1 - .../__mocks__/rocket-flat-object.mock.ts | 1 - .../__mocks__/task-flat-object.mock.ts | 5 +- .../__mocks__/task-target-flat-object.mock.ts | 5 +- .../timeline-activity-flat-object.mock.ts | 5 +- ...and-flat-field-metadatas-to-create.util.ts | 1 - ...ct-metadata-to-object-metadata-dto.util.ts | 4 +- .../generate-flat-index.util.spec.ts | 6 +- .../generate-deterministic-index-name-v2.ts | 8 +- .../minimal-metadata.service.ts | 4 +- ...al-system-flat-field-metadatas.constant.ts | 8 -- .../controllers/object-metadata.controller.ts | 87 +++++++++++++------ .../dtos/object-metadata.dto.ts | 5 +- .../object-metadata/object-metadata.entity.ts | 9 +- .../object-metadata/object-metadata.module.ts | 1 + .../object-metadata.resolver.ts | 15 ++++ .../object-record-count.service.ts | 9 +- ...te-flat-view-fields-to-create.util.spec.ts | 1 - ...ct-metadata-standard-override.util.spec.ts | 25 ------ ...-field-metadatas-for-custom-object.util.ts | 1 - ...data-entity-to-object-metadata-dto.util.ts | 3 +- ...-object-metadata-standard-override.util.ts | 5 -- ...y-standard-application-id-or-throw.util.ts | 26 ++++++ .../view/controllers/view.controller.ts | 1 - .../view/resolvers/view.resolver.ts | 1 - ...form-event-batch-to-webhook-events.spec.ts | 1 - ...vent-with-resolved-navigation.util.spec.ts | 1 - .../workspace-entity-manager.spec.ts | 2 - .../global-workspace-datasource.module.ts | 2 + .../types/entity-schema-metadata.type.ts | 6 +- ...pace-orm-entity-metadatas-cache.service.ts | 38 +++++--- .../__tests__/workspace.repository.spec.ts | 1 - .../workspace-delete-query-builder.ts | 7 +- .../workspace-soft-delete-query-builder.ts | 7 +- .../workspace-update-query-builder.ts | 7 +- ...elation-connect-query-configs.util.spec.ts | 1 - ...event-to-database-batch-event.util.spec.ts | 1 - ...umn-name-to-field-metadata-id.util.spec.ts | 1 - ...tadata-id-to-column-names-map.util.spec.ts | 1 - ...ow-level-permission-predicate.util.spec.ts | 1 - .../utils/compute-object-target-table.util.ts | 9 +- .../data/services/dev-seeder-data.service.ts | 5 +- ...reate-standard-field-flat-metadata.util.ts | 5 +- ...ndard-relation-field-flat-metadata.util.ts | 5 +- ...eate-standard-object-flat-metadata.util.ts | 5 +- .../types/universal-flat-entity-from.type.ts | 4 +- ...pdated-matrix-dispatcher.util.spec.ts.snap | 6 +- ...aps-through-mutation-or-throw.util.spec.ts | 2 - ...aps-through-mutation-or-throw.util.spec.ts | 2 - ...-entity-to-scalar-flat-entity.util.spec.ts | 2 - ...space-schema-context-for-migration.util.ts | 2 +- .../__tests__/create-company.service.spec.ts | 1 - ...ow-database-event-trigger.listener.spec.ts | 1 - .../get-field-metadata-entity.mock.ts | 2 +- ...rkspace-migration.integration-spec.ts.snap | 23 ----- .../dry-run-manifest-sync.integration-spec.ts | 13 ++- ...manifest-update-object.integration-spec.ts | 4 +- ...on-workspace-migration.integration-spec.ts | 2 +- .../rename-custom-object.integration-spec.ts | 4 +- 129 files changed, 502 insertions(+), 538 deletions(-) create mode 100644 packages/twenty-server/src/database/commands/upgrade-version-command/2-12/2-12-instance-command-fast-1780579070012-drop-is-custom-from-object-and-field-metadata.ts create mode 100644 packages/twenty-server/src/engine/core-modules/application/application-rest-api-exception.filter.ts create mode 100644 packages/twenty-server/src/engine/metadata-modules/utils/get-twenty-standard-application-id-or-throw.util.ts diff --git a/packages/twenty-apps/examples/postcard/src/__tests__/schema.integration-test.ts b/packages/twenty-apps/examples/postcard/src/__tests__/schema.integration-test.ts index 0e8bbb9ec8..2bc6e07aed 100644 --- a/packages/twenty-apps/examples/postcard/src/__tests__/schema.integration-test.ts +++ b/packages/twenty-apps/examples/postcard/src/__tests__/schema.integration-test.ts @@ -1,5 +1,5 @@ -import { MetadataApiClient } from 'twenty-client-sdk/metadata'; import { APPLICATION_UNIVERSAL_IDENTIFIER } from 'src/application.config'; +import { MetadataApiClient } from 'twenty-client-sdk/metadata'; import { describe, expect, it } from 'vitest'; describe('App installation', () => { @@ -7,11 +7,7 @@ describe('App installation', () => { const client = new MetadataApiClient(); const result = await client.query({ - findManyApplications: { - id: true, - name: true, - universalIdentifier: true, - }, + findManyApplications: { id: true, name: true, universalIdentifier: true }, }); const app = result.findManyApplications.find( @@ -29,10 +25,7 @@ describe('PostCard object', () => { const { objects } = await client.query({ objects: { - __args: { - filter: { isCustom: { is: true } }, - paging: { first: 50 }, - }, + __args: { paging: { first: 50 } }, edges: { node: { nameSingular: true, @@ -59,5 +52,4 @@ describe('PostCard object', () => { expect(names).toContain('deliveredAt'); expect(names).toContain('recipient'); }); - }); diff --git a/packages/twenty-client-sdk/src/metadata/generated/schema.graphql b/packages/twenty-client-sdk/src/metadata/generated/schema.graphql index 7f0e4cc6ba..6975fb1617 100644 --- a/packages/twenty-client-sdk/src/metadata/generated/schema.graphql +++ b/packages/twenty-client-sdk/src/metadata/generated/schema.graphql @@ -476,7 +476,7 @@ type Field { description: String icon: String standardOverrides: StandardOverrides - isCustom: Boolean + isCustom: Boolean @deprecated(reason: "isCustom is derived from the owning application and will be removed; a field is custom when it does not belong to the twenty-standard application.") isActive: Boolean isSystem: Boolean isUIReadOnly: Boolean @@ -587,7 +587,6 @@ input ObjectFilter { and: [ObjectFilter!] or: [ObjectFilter!] id: UUIDFilterComparison - isCustom: BooleanFieldComparison isRemote: BooleanFieldComparison isActive: BooleanFieldComparison isSystem: BooleanFieldComparison @@ -645,7 +644,7 @@ type Object { standardOverrides: ObjectStandardOverrides shortcut: String color: String - isCustom: Boolean! + isCustom: Boolean! @deprecated(reason: "isCustom is derived from the owning application and will be removed; an object is custom when it does not belong to the twenty-standard application.") isRemote: Boolean! isActive: Boolean! isSystem: Boolean! @@ -680,7 +679,6 @@ input FieldFilter { and: [FieldFilter!] or: [FieldFilter!] id: UUIDFilterComparison - isCustom: BooleanFieldComparison isActive: BooleanFieldComparison isSystem: BooleanFieldComparison isUIReadOnly: BooleanFieldComparison diff --git a/packages/twenty-client-sdk/src/metadata/generated/schema.ts b/packages/twenty-client-sdk/src/metadata/generated/schema.ts index a12c26be5f..b7af6b5b9d 100644 --- a/packages/twenty-client-sdk/src/metadata/generated/schema.ts +++ b/packages/twenty-client-sdk/src/metadata/generated/schema.ts @@ -360,6 +360,7 @@ export interface Field { description?: Scalars['String'] icon?: Scalars['String'] standardOverrides?: StandardOverrides + /** @deprecated isCustom is derived from the owning application and will be removed; a field is custom when it does not belong to the twenty-standard application. */ isCustom?: Scalars['Boolean'] isActive?: Scalars['Boolean'] isSystem?: Scalars['Boolean'] @@ -436,6 +437,7 @@ export interface Object { standardOverrides?: ObjectStandardOverrides shortcut?: Scalars['String'] color?: Scalars['String'] + /** @deprecated isCustom is derived from the owning application and will be removed; an object is custom when it does not belong to the twenty-standard application. */ isCustom: Scalars['Boolean'] isRemote: Scalars['Boolean'] isActive: Scalars['Boolean'] @@ -3261,6 +3263,7 @@ export interface FieldGenqlSelection{ description?: boolean | number icon?: boolean | number standardOverrides?: StandardOverridesGenqlSelection + /** @deprecated isCustom is derived from the owning application and will be removed; a field is custom when it does not belong to the twenty-standard application. */ isCustom?: boolean | number isActive?: boolean | number isSystem?: boolean | number @@ -3328,7 +3331,7 @@ first?: (Scalars['Int'] | null), /** Paginate last */ last?: (Scalars['Int'] | null)} -export interface ObjectFilter {and?: (ObjectFilter[] | null),or?: (ObjectFilter[] | null),id?: (UUIDFilterComparison | null),isCustom?: (BooleanFieldComparison | null),isRemote?: (BooleanFieldComparison | null),isActive?: (BooleanFieldComparison | null),isSystem?: (BooleanFieldComparison | null),isUIReadOnly?: (BooleanFieldComparison | null),isSearchable?: (BooleanFieldComparison | null)} +export interface ObjectFilter {and?: (ObjectFilter[] | null),or?: (ObjectFilter[] | null),id?: (UUIDFilterComparison | null),isRemote?: (BooleanFieldComparison | null),isActive?: (BooleanFieldComparison | null),isSystem?: (BooleanFieldComparison | null),isUIReadOnly?: (BooleanFieldComparison | null),isSearchable?: (BooleanFieldComparison | null)} export interface UUIDFilterComparison {is?: (Scalars['Boolean'] | null),isNot?: (Scalars['Boolean'] | null),eq?: (Scalars['UUID'] | null),neq?: (Scalars['UUID'] | null),gt?: (Scalars['UUID'] | null),gte?: (Scalars['UUID'] | null),lt?: (Scalars['UUID'] | null),lte?: (Scalars['UUID'] | null),like?: (Scalars['UUID'] | null),notLike?: (Scalars['UUID'] | null),iLike?: (Scalars['UUID'] | null),notILike?: (Scalars['UUID'] | null),in?: (Scalars['UUID'][] | null),notIn?: (Scalars['UUID'][] | null)} @@ -3359,6 +3362,7 @@ export interface ObjectGenqlSelection{ standardOverrides?: ObjectStandardOverridesGenqlSelection shortcut?: boolean | number color?: boolean | number + /** @deprecated isCustom is derived from the owning application and will be removed; an object is custom when it does not belong to the twenty-standard application. */ isCustom?: boolean | number isRemote?: boolean | number isActive?: boolean | number @@ -3388,7 +3392,7 @@ export interface ObjectGenqlSelection{ __scalar?: boolean | number } -export interface FieldFilter {and?: (FieldFilter[] | null),or?: (FieldFilter[] | null),id?: (UUIDFilterComparison | null),isCustom?: (BooleanFieldComparison | null),isActive?: (BooleanFieldComparison | null),isSystem?: (BooleanFieldComparison | null),isUIReadOnly?: (BooleanFieldComparison | null),objectMetadataId?: (UUIDFilterComparison | null)} +export interface FieldFilter {and?: (FieldFilter[] | null),or?: (FieldFilter[] | null),id?: (UUIDFilterComparison | null),isActive?: (BooleanFieldComparison | null),isSystem?: (BooleanFieldComparison | null),isUIReadOnly?: (BooleanFieldComparison | null),objectMetadataId?: (UUIDFilterComparison | null)} export interface IndexFilter {and?: (IndexFilter[] | null),or?: (IndexFilter[] | null),id?: (UUIDFilterComparison | null),isCustom?: (BooleanFieldComparison | null)} diff --git a/packages/twenty-client-sdk/src/metadata/generated/types.ts b/packages/twenty-client-sdk/src/metadata/generated/types.ts index 08a7d86973..2756922a7e 100644 --- a/packages/twenty-client-sdk/src/metadata/generated/types.ts +++ b/packages/twenty-client-sdk/src/metadata/generated/types.ts @@ -1076,9 +1076,6 @@ export default { "id": [ 52 ], - "isCustom": [ - 53 - ], "isRemote": [ 53 ], @@ -1315,9 +1312,6 @@ export default { "id": [ 52 ], - "isCustom": [ - 53 - ], "isActive": [ 53 ], diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts index b47da6349f..5be83fbd1c 100644 --- a/packages/twenty-front/src/generated-metadata/graphql.ts +++ b/packages/twenty-front/src/generated-metadata/graphql.ts @@ -1664,6 +1664,7 @@ export type Field = { icon?: Maybe; id: Scalars['UUID']; isActive?: Maybe; + /** @deprecated isCustom is derived from the owning application and will be removed; a field is custom when it does not belong to the twenty-standard application. */ isCustom?: Maybe; isLabelSyncedWithName?: Maybe; isNullable?: Maybe; @@ -1722,7 +1723,6 @@ export type FieldFilter = { and?: InputMaybe>; id?: InputMaybe; isActive?: InputMaybe; - isCustom?: InputMaybe; isSystem?: InputMaybe; isUIReadOnly?: InputMaybe; objectMetadataId?: InputMaybe; @@ -3711,6 +3711,7 @@ export type Object = { indexMetadataList: Array; indexMetadatas: ObjectIndexMetadatasConnection; isActive: Scalars['Boolean']; + /** @deprecated isCustom is derived from the owning application and will be removed; an object is custom when it does not belong to the twenty-standard application. */ isCustom: Scalars['Boolean']; isLabelSyncedWithName: Scalars['Boolean']; isRemote: Scalars['Boolean']; @@ -3768,7 +3769,6 @@ export type ObjectFilter = { and?: InputMaybe>; id?: InputMaybe; isActive?: InputMaybe; - isCustom?: InputMaybe; isRemote?: InputMaybe; isSearchable?: InputMaybe; isSystem?: InputMaybe; diff --git a/packages/twenty-front/src/modules/settings/data-model/object-details/components/SettingsObjectFieldDisabledActionDropdown.tsx b/packages/twenty-front/src/modules/settings/data-model/object-details/components/SettingsObjectFieldDisabledActionDropdown.tsx index 1011352f06..76d8adf5ae 100644 --- a/packages/twenty-front/src/modules/settings/data-model/object-details/components/SettingsObjectFieldDisabledActionDropdown.tsx +++ b/packages/twenty-front/src/modules/settings/data-model/object-details/components/SettingsObjectFieldDisabledActionDropdown.tsx @@ -17,6 +17,7 @@ import { type FieldMetadataType } from '~/generated-metadata/graphql'; type SettingsObjectFieldInactiveActionDropdownProps = { isCustomField?: boolean; + isSystemField?: boolean; fieldType?: FieldMetadataType; onActivate: () => void; onEdit: () => void; @@ -32,6 +33,7 @@ export const SettingsObjectFieldInactiveActionDropdown = ({ onDelete, onEdit, isCustomField, + isSystemField, }: SettingsObjectFieldInactiveActionDropdownProps) => { const dropdownId = `${fieldMetadataItemId}-settings-field-disabled-action-dropdown`; @@ -52,7 +54,7 @@ export const SettingsObjectFieldInactiveActionDropdown = ({ closeDropdown(dropdownId); }; - const isDeletable = isCustomField; + const isDeletable = isCustomField && !isSystemField; return ( { + await queryRunner.query( + 'ALTER TABLE "core"."fieldMetadata" DROP COLUMN IF EXISTS "isCustom"', + ); + await queryRunner.query( + 'ALTER TABLE "core"."objectMetadata" DROP COLUMN IF EXISTS "isCustom"', + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + 'ALTER TABLE "core"."objectMetadata" ADD COLUMN IF NOT EXISTS "isCustom" boolean NOT NULL DEFAULT false', + ); + await queryRunner.query( + 'ALTER TABLE "core"."fieldMetadata" ADD COLUMN IF NOT EXISTS "isCustom" boolean NOT NULL DEFAULT false', + ); + await queryRunner.query( + `UPDATE "core"."objectMetadata" "objectMetadata" + SET "isCustom" = ("objectMetadata"."applicationId" <> "standardApplication"."id") + FROM "core"."application" "standardApplication" + WHERE "standardApplication"."workspaceId" = "objectMetadata"."workspaceId" + AND "standardApplication"."universalIdentifier" = '${TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER}'`, + ); + await queryRunner.query( + `UPDATE "core"."fieldMetadata" "fieldMetadata" + SET "isCustom" = ("fieldMetadata"."applicationId" <> "standardApplication"."id") + FROM "core"."application" "standardApplication" + WHERE "standardApplication"."workspaceId" = "fieldMetadata"."workspaceId" + AND "standardApplication"."universalIdentifier" = '${TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER}'`, + ); + } +} diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/instance-commands.constant.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/instance-commands.constant.ts index 04739ac636..ed564b56f8 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/instance-commands.constant.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/instance-commands.constant.ts @@ -59,6 +59,7 @@ import { EmailingDomainTenantStatusAndGlobalUniquenessFastInstanceCommand } from import { AddLogicFunctionExecutionModeFastInstanceCommand } from 'src/database/commands/upgrade-version-command/2-9/2-9-instance-command-fast-1799000030000-add-logic-function-execution-mode'; import { EncryptNonSecretApplicationVariableSlowInstanceCommand } from 'src/database/commands/upgrade-version-command/2-9/2-9-instance-command-slow-1798400000000-encrypt-non-secret-application-variable'; import { MigrateAiModelPreferencesSlowInstanceCommand } from 'src/database/commands/upgrade-version-command/2-9/2-9-instance-command-slow-1799000010000-migrate-ai-model-preferences'; +import { DropIsCustomFromObjectAndFieldMetadataFastInstanceCommand } from 'src/database/commands/upgrade-version-command/2-12/2-12-instance-command-fast-1780579070012-drop-is-custom-from-object-and-field-metadata'; import { DropEmailingDomainDriverColumnFastInstanceCommand } from 'src/database/commands/upgrade-version-command/2-11/2-11-instance-command-fast-1780926908000-drop-emailing-domain-driver-column'; export const INSTANCE_COMMANDS = [ @@ -121,5 +122,6 @@ export const INSTANCE_COMMANDS = [ AddLogicFunctionExecutionModeFastInstanceCommand, MigrateAiModelPreferencesSlowInstanceCommand, EncryptNonSecretApplicationVariableSlowInstanceCommand, + DropIsCustomFromObjectAndFieldMetadataFastInstanceCommand, DropEmailingDomainDriverColumnFastInstanceCommand, ]; diff --git a/packages/twenty-server/src/database/commands/workspace-export/utils/generate-workspace-schema-ddl.util.ts b/packages/twenty-server/src/database/commands/workspace-export/utils/generate-workspace-schema-ddl.util.ts index e989af8a2a..96f804c38c 100644 --- a/packages/twenty-server/src/database/commands/workspace-export/utils/generate-workspace-schema-ddl.util.ts +++ b/packages/twenty-server/src/database/commands/workspace-export/utils/generate-workspace-schema-ddl.util.ts @@ -9,6 +9,7 @@ import { escapeLiteral, } from 'src/engine/workspace-manager/workspace-migration/utils/remove-sql-injection.util'; import { generateColumnDefinitions } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/generate-column-definitions.util'; +import { TWENTY_STANDARD_APPLICATION } from 'src/engine/workspace-manager/twenty-standard-application/constants/twenty-standard-applications'; import { type CreateEnumOperationSpec, EnumOperation, @@ -28,7 +29,8 @@ export const generateWorkspaceSchemaDdl = ( const tableName = computeTableName( objectMetadata.nameSingular, - objectMetadata.isCustom, + objectMetadata.application?.universalIdentifier !== + TWENTY_STANDARD_APPLICATION.universalIdentifier, ); const fieldMetadatas = fieldsByObjectId.get(objectMetadata.id) ?? []; diff --git a/packages/twenty-server/src/database/commands/workspace-export/workspace-export.service.ts b/packages/twenty-server/src/database/commands/workspace-export/workspace-export.service.ts index bbaa92b41f..85078c842b 100644 --- a/packages/twenty-server/src/database/commands/workspace-export/workspace-export.service.ts +++ b/packages/twenty-server/src/database/commands/workspace-export/workspace-export.service.ts @@ -14,6 +14,7 @@ import { import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; +import { TWENTY_STANDARD_APPLICATION } from 'src/engine/workspace-manager/twenty-standard-application/constants/twenty-standard-applications'; import { getWorkspaceSchemaName } from 'src/engine/workspace-datasource/utils/get-workspace-schema-name.util'; import { computeTableName } from 'src/engine/utils/compute-table-name.util'; import { escapeIdentifier } from 'src/engine/workspace-manager/workspace-migration/utils/remove-sql-injection.util'; @@ -77,6 +78,7 @@ export class WorkspaceExportService { const objectMetadatas = await this.objectMetadataRepository.find({ where: { workspaceId }, + relations: { application: true }, }); const fieldMetadatas = await this.fieldMetadataRepository.find({ @@ -359,7 +361,8 @@ export class WorkspaceExportService { const tableName = computeTableName( objectMetadata.nameSingular, - objectMetadata.isCustom, + objectMetadata.application?.universalIdentifier !== + TWENTY_STANDARD_APPLICATION.universalIdentifier, ); if (tableFilter && !tableFilter.includes(objectMetadata.nameSingular)) { diff --git a/packages/twenty-server/src/engine/api/__mocks__/object-metadata-item.mock.ts b/packages/twenty-server/src/engine/api/__mocks__/object-metadata-item.mock.ts index 386b22f43e..21eab2b8c7 100644 --- a/packages/twenty-server/src/engine/api/__mocks__/object-metadata-item.mock.ts +++ b/packages/twenty-server/src/engine/api/__mocks__/object-metadata-item.mock.ts @@ -436,7 +436,6 @@ export const objectMetadataItemMock: ObjectMetadataEntity = { description: 'Object description', icon: 'Icon123', targetTableName: 'DEPRECATED', - isCustom: false, isRemote: false, isActive: true, isSystem: false, diff --git a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/__tests__/data-arg-processor.service.spec.ts b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/__tests__/data-arg-processor.service.spec.ts index 6056102fce..922713c9cb 100644 --- a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/__tests__/data-arg-processor.service.spec.ts +++ b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/__tests__/data-arg-processor.service.spec.ts @@ -76,7 +76,6 @@ describe('DataArgProcessorService', () => { id: 'object-id', nameSingular: 'testObject', namePlural: 'testObjects', - isCustom: false, fieldIds: fieldNames.map((name) => `${name}-id`), universalIdentifier: 'test-object-universal-id', labelIdentifierFieldMetadataUniversalIdentifier: null, @@ -161,7 +160,6 @@ describe('DataArgProcessorService', () => { id: 'object-id', nameSingular: 'testObject', namePlural: 'testObjects', - isCustom: false, fieldIds: ['company-id'], universalIdentifier: 'test-object-universal-id', labelIdentifierFieldMetadataUniversalIdentifier: null, @@ -174,7 +172,6 @@ describe('DataArgProcessorService', () => { id: 'target-company-object-id', nameSingular: 'company', namePlural: 'companies', - isCustom: false, fieldIds: ['emails-id', 'domainName-id'], universalIdentifier: 'target-company-universal-id', labelIdentifierFieldMetadataUniversalIdentifier: null, diff --git a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/data-arg-processor.service.ts b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/data-arg-processor.service.ts index 5c1e415dac..67586e1fd6 100644 --- a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/data-arg-processor.service.ts +++ b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/data-arg-processor.service.ts @@ -15,6 +15,7 @@ import { } from 'twenty-shared/utils'; import { computeMorphOrRelationFieldJoinColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-morph-or-relation-field-join-column-name.util'; +import { belongsToTwentyStandardApp } from 'src/engine/metadata-modules/utils/belongs-to-twenty-standard-app.util'; import { transformActorField } from 'src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-actor-field.util'; import { transformAddressField } from 'src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-address-field.util'; import { transformArrayField } from 'src/engine/api/common/common-args-processors/data-arg-processor/transformer-utils/transform-array-field.util'; @@ -101,7 +102,7 @@ export class DataArgProcessorService { partialRecordInputs: partialRecordInputs, workspaceId: workspace.id, objectMetadata: { - isCustom: flatObjectMetadata.isCustom, + isCustom: !belongsToTwentyStandardApp(flatObjectMetadata), nameSingular: flatObjectMetadata.nameSingular, fieldIdByName, }, diff --git a/packages/twenty-server/src/engine/api/common/common-args-processors/filter-arg-processor/__tests__/filter-arg-processor.service.spec.ts b/packages/twenty-server/src/engine/api/common/common-args-processors/filter-arg-processor/__tests__/filter-arg-processor.service.spec.ts index 7d1f358842..841a031594 100644 --- a/packages/twenty-server/src/engine/api/common/common-args-processors/filter-arg-processor/__tests__/filter-arg-processor.service.spec.ts +++ b/packages/twenty-server/src/engine/api/common/common-args-processors/filter-arg-processor/__tests__/filter-arg-processor.service.spec.ts @@ -57,7 +57,6 @@ describe('FilterArgProcessorService', () => { id: 'object-id', nameSingular: 'testObject', namePlural: 'testObjects', - isCustom: false, fieldIds: fieldNames.map((name) => `${name}-id`), universalIdentifier: 'test-object-universal-id', labelIdentifierFieldMetadataUniversalIdentifier: null, @@ -338,7 +337,6 @@ describe('FilterArgProcessorService', () => { id: sourceObjectId, nameSingular: 'sourceObject', namePlural: 'sourceObjects', - isCustom: false, fieldIds: [relationFieldId], universalIdentifier: sourceUniversalId, labelIdentifierFieldMetadataUniversalIdentifier: null, @@ -349,7 +347,6 @@ describe('FilterArgProcessorService', () => { id: targetObjectId, nameSingular: 'targetObject', namePlural: 'targetObjects', - isCustom: false, fieldIds: [targetTextFieldId, targetCurrencyFieldId], universalIdentifier: targetUniversalId, labelIdentifierFieldMetadataUniversalIdentifier: null, diff --git a/packages/twenty-server/src/engine/api/common/common-query-runners/common-create-many-query-runner/common-create-many-query-runner.service.ts b/packages/twenty-server/src/engine/api/common/common-query-runners/common-create-many-query-runner/common-create-many-query-runner.service.ts index baa70b864f..a86c184dcb 100644 --- a/packages/twenty-server/src/engine/api/common/common-query-runners/common-create-many-query-runner/common-create-many-query-runner.service.ts +++ b/packages/twenty-server/src/engine/api/common/common-query-runners/common-create-many-query-runner/common-create-many-query-runner.service.ts @@ -490,7 +490,7 @@ export class CommonCreateManyQueryRunnerService extends CommonBaseQueryRunnerSer ); } - if ('createdBy' in record && createdByFieldMetadata.isCustom === false) { + if ('createdBy' in record && createdByFieldMetadata.isSystem === true) { const { createdBy: _createdBy, ...recordWithoutCreatedBy } = record; recordWithoutCreatedByUpdate = recordWithoutCreatedBy; diff --git a/packages/twenty-server/src/engine/api/common/common-query-runners/common-create-many-query-runner/utils/__tests__/get-conflicting-fields.util.spec.ts b/packages/twenty-server/src/engine/api/common/common-query-runners/common-create-many-query-runner/utils/__tests__/get-conflicting-fields.util.spec.ts index c4b9adb7a9..90bcea4f10 100644 --- a/packages/twenty-server/src/engine/api/common/common-query-runners/common-create-many-query-runner/utils/__tests__/get-conflicting-fields.util.spec.ts +++ b/packages/twenty-server/src/engine/api/common/common-query-runners/common-create-many-query-runner/utils/__tests__/get-conflicting-fields.util.spec.ts @@ -85,7 +85,6 @@ describe('getConflictingFields', () => { namePlural: 'testObjects', labelSingular: 'Test Object', labelPlural: 'Test Objects', - isCustom: false, isRemote: false, isActive: true, isSystem: false, diff --git a/packages/twenty-server/src/engine/api/common/common-select-fields/utils/__tests__/get-all-selectable-fields.util.spec.ts b/packages/twenty-server/src/engine/api/common/common-select-fields/utils/__tests__/get-all-selectable-fields.util.spec.ts index 963bfc4416..beb41b908d 100644 --- a/packages/twenty-server/src/engine/api/common/common-select-fields/utils/__tests__/get-all-selectable-fields.util.spec.ts +++ b/packages/twenty-server/src/engine/api/common/common-select-fields/utils/__tests__/get-all-selectable-fields.util.spec.ts @@ -60,7 +60,6 @@ describe('getAllSelectableFields', () => { namePlural: 'testObjects', labelSingular: 'Test Object', labelPlural: 'Test Objects', - isCustom: false, isRemote: false, isActive: true, isSystem: false, diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/__mocks__/mockPersonObjectMetadata.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/__mocks__/mockPersonObjectMetadata.ts index c4b42936e7..d9057a6a98 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/__mocks__/mockPersonObjectMetadata.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/__mocks__/mockPersonObjectMetadata.ts @@ -141,7 +141,6 @@ export const mockPersonFlatObjectMetadata = ( labelSingular: 'Person', labelPlural: 'People', targetTableName: 'person', - isCustom: false, isRemote: false, isActive: true, isSystem: false, diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/__tests__/build-columns-to-select.spec.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/__tests__/build-columns-to-select.spec.ts index 3441a9a55e..d789ed6e77 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/__tests__/build-columns-to-select.spec.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/__tests__/build-columns-to-select.spec.ts @@ -36,7 +36,6 @@ describe('buildColumnsToSelect', () => { calendarViewIds: [], applicationId: null, label: overrides.name, - isCustom: false, isActive: true, isSystem: false, isUnique: false, @@ -87,7 +86,6 @@ describe('buildColumnsToSelect', () => { description: 'A person', icon: 'IconUser', targetTableName: 'DEPRECATED', - isCustom: false, isRemote: false, isActive: true, isSystem: false, diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/__tests__/cursors.util.spec.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/__tests__/cursors.util.spec.ts index 0f608e8d01..28f18e7264 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/__tests__/cursors.util.spec.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/__tests__/cursors.util.spec.ts @@ -59,7 +59,6 @@ const flatObjectMetadata: FlatObjectMetadata = { labelSingular: 'Person', labelPlural: 'People', targetTableName: 'person', - isCustom: false, isRemote: false, isActive: true, isSystem: false, diff --git a/packages/twenty-server/src/engine/api/rest/core/rest-to-common-args-handlers/__tests__/selected-fields-handler.spec.ts b/packages/twenty-server/src/engine/api/rest/core/rest-to-common-args-handlers/__tests__/selected-fields-handler.spec.ts index da8d52fc18..4c0af85bca 100644 --- a/packages/twenty-server/src/engine/api/rest/core/rest-to-common-args-handlers/__tests__/selected-fields-handler.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/core/rest-to-common-args-handlers/__tests__/selected-fields-handler.spec.ts @@ -56,7 +56,6 @@ describe('RestToCommonSelectedFieldsHandler', () => { namePlural: `${overrides.nameSingular}s`, labelSingular: overrides.nameSingular, labelPlural: `${overrides.nameSingular}s`, - isCustom: false, isRemote: false, isActive: true, isSystem: false, diff --git a/packages/twenty-server/src/engine/api/utils/__tests__/compute-cursor-arg-filter.utils.spec.ts b/packages/twenty-server/src/engine/api/utils/__tests__/compute-cursor-arg-filter.utils.spec.ts index 4f756e966b..27f4888153 100644 --- a/packages/twenty-server/src/engine/api/utils/__tests__/compute-cursor-arg-filter.utils.spec.ts +++ b/packages/twenty-server/src/engine/api/utils/__tests__/compute-cursor-arg-filter.utils.spec.ts @@ -91,7 +91,6 @@ describe('computeCursorArgFilter', () => { labelSingular: 'Person', labelPlural: 'People', targetTableName: 'person', - isCustom: false, isRemote: false, isActive: true, isSystem: false, diff --git a/packages/twenty-server/src/engine/core-modules/__mocks__/mockFlatObjectMetadatas.ts b/packages/twenty-server/src/engine/core-modules/__mocks__/mockFlatObjectMetadatas.ts index 9cf7cfaaf9..1f83b3ccb0 100644 --- a/packages/twenty-server/src/engine/core-modules/__mocks__/mockFlatObjectMetadatas.ts +++ b/packages/twenty-server/src/engine/core-modules/__mocks__/mockFlatObjectMetadatas.ts @@ -23,7 +23,6 @@ export const mockFlatObjectMetadatas: FlatObjectMetadata[] = [ labelPlural: 'People', description: 'A person', icon: 'test-person-icon', - isCustom: false, isSearchable: true, labelIdentifierFieldMetadataId: personNameFieldId, imageIdentifierFieldMetadataId: null, @@ -40,7 +39,6 @@ export const mockFlatObjectMetadatas: FlatObjectMetadata[] = [ labelPlural: 'Companies', description: 'A company', icon: 'test-company-icon', - isCustom: false, isSearchable: true, labelIdentifierFieldMetadataId: companyNameFieldId, imageIdentifierFieldMetadataId: null, @@ -57,7 +55,6 @@ export const mockFlatObjectMetadatas: FlatObjectMetadata[] = [ labelPlural: 'Regular Custom Objects', description: 'A regular custom object', icon: 'test-regular-custom-object-icon', - isCustom: true, isSearchable: true, labelIdentifierFieldMetadataId: customObjectNameFieldId, imageIdentifierFieldMetadataId: customObjectImageFieldId, @@ -74,7 +71,6 @@ export const mockFlatObjectMetadatas: FlatObjectMetadata[] = [ labelPlural: '', description: '', icon: 'test-non-searchable-object-icon', - isCustom: false, isSystem: true, isSearchable: false, labelIdentifierFieldMetadataId: null, @@ -92,7 +88,6 @@ export const mockFlatObjectMetadatas: FlatObjectMetadata[] = [ labelPlural: 'Messages', description: 'Message', icon: 'IconMessage', - isCustom: false, isSystem: true, isSearchable: false, labelIdentifierFieldMetadataId: null, @@ -113,7 +108,6 @@ export const mockFlatFieldMetadataMaps: FlatEntityMaps = { name: 'name', label: 'Name', description: "Contact's name", - isCustom: false, defaultValue: { lastName: "''", firstName: "''" }, objectMetadataId: '20202020-8dec-43d5-b2ff-6eef05095bec', workspaceId, @@ -127,7 +121,6 @@ export const mockFlatFieldMetadataMaps: FlatEntityMaps = { name: 'name', label: 'Name', description: null, - isCustom: false, defaultValue: '', objectMetadataId: '20202020-c03c-45d6-a4b0-04afe1357c5c', workspaceId, @@ -141,7 +134,6 @@ export const mockFlatFieldMetadataMaps: FlatEntityMaps = { name: 'domainName', label: 'Domain Name', description: null, - isCustom: false, defaultValue: { primaryLinkLabel: '', primaryLinkUrl: '', @@ -159,7 +151,6 @@ export const mockFlatFieldMetadataMaps: FlatEntityMaps = { name: 'name', label: 'Name', description: null, - isCustom: false, defaultValue: '', objectMetadataId: '20202020-3d75-4aab-bacd-ee176c5f63ca', workspaceId, @@ -173,7 +164,6 @@ export const mockFlatFieldMetadataMaps: FlatEntityMaps = { name: 'imageIdentifierFieldName', label: 'Image Identifier Field Name', description: null, - isCustom: false, defaultValue: '', objectMetadataId: '20202020-3d75-4aab-bacd-ee176c5f63ca', workspaceId, diff --git a/packages/twenty-server/src/engine/core-modules/__mocks__/mockObjectMetadataItemsWithFieldMaps.ts b/packages/twenty-server/src/engine/core-modules/__mocks__/mockObjectMetadataItemsWithFieldMaps.ts index 8e46077384..6119389d60 100644 --- a/packages/twenty-server/src/engine/core-modules/__mocks__/mockObjectMetadataItemsWithFieldMaps.ts +++ b/packages/twenty-server/src/engine/core-modules/__mocks__/mockObjectMetadataItemsWithFieldMaps.ts @@ -26,7 +26,6 @@ const personFlatObject = getFlatObjectMetadataMock({ description: 'A person', icon: 'test-person-icon', targetTableName: 'DEPRECATED', - isCustom: false, isRemote: false, isActive: true, isSystem: false, @@ -50,7 +49,6 @@ const companyFlatObject = getFlatObjectMetadataMock({ description: 'A company', icon: 'test-company-icon', targetTableName: 'DEPRECATED', - isCustom: false, isRemote: false, isActive: true, isSystem: false, @@ -74,7 +72,6 @@ const customObjectFlatObject = getFlatObjectMetadataMock({ description: 'A regular custom object', icon: 'test-regular-custom-object-icon', targetTableName: 'DEPRECATED', - isCustom: true, isRemote: false, isActive: true, isSystem: false, @@ -98,7 +95,6 @@ const nonSearchableFlatObject = getFlatObjectMetadataMock({ description: '', icon: 'test-non-searchable-object-icon', targetTableName: 'DEPRECATED', - isCustom: false, isRemote: false, isActive: true, isSystem: true, @@ -125,7 +121,6 @@ const personNameField = getFlatFieldMetadataMock({ firstName: "''", }, description: "Contact's name", - isCustom: false, isNullable: true, isUnique: false, isLabelSyncedWithName: true, @@ -141,7 +136,6 @@ const companyNameField = getFlatFieldMetadataMock({ name: 'name', label: 'Name', defaultValue: '', - isCustom: false, isNullable: true, isUnique: false, isLabelSyncedWithName: true, @@ -161,7 +155,6 @@ const companyDomainNameField = getFlatFieldMetadataMock({ primaryLinkUrl: '', secondaryLinks: [], }, - isCustom: false, isNullable: true, isUnique: false, isLabelSyncedWithName: true, @@ -177,7 +170,6 @@ const customObjectNameField = getFlatFieldMetadataMock({ name: 'name', label: 'Name', defaultValue: '', - isCustom: false, isNullable: true, isUnique: false, isLabelSyncedWithName: true, @@ -193,7 +185,6 @@ const customObjectImageField = getFlatFieldMetadataMock({ name: 'imageIdentifierFieldName', label: 'Image Identifier Field Name', defaultValue: '', - isCustom: false, isNullable: true, isUnique: false, isLabelSyncedWithName: true, diff --git a/packages/twenty-server/src/engine/core-modules/application/application-manifest/converters/__tests__/from-index-manifest-to-universal-flat-index.util.spec.ts b/packages/twenty-server/src/engine/core-modules/application/application-manifest/converters/__tests__/from-index-manifest-to-universal-flat-index.util.spec.ts index 562c8ebc49..a8c4c8495d 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-manifest/converters/__tests__/from-index-manifest-to-universal-flat-index.util.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-manifest/converters/__tests__/from-index-manifest-to-universal-flat-index.util.spec.ts @@ -12,7 +12,6 @@ describe('fromIndexManifestToUniversalFlatIndex', () => { const flatObjectMetadata = { universalIdentifier: 'obj-uuid-1', nameSingular: 'company', - isCustom: false, } as UniversalFlatObjectMetadata; const scalarField = { diff --git a/packages/twenty-server/src/engine/core-modules/application/application-manifest/converters/from-field-manifest-to-universal-flat-field-metadata.util.ts b/packages/twenty-server/src/engine/core-modules/application/application-manifest/converters/from-field-manifest-to-universal-flat-field-metadata.util.ts index c957d94a5e..02a844ff8a 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-manifest/converters/from-field-manifest-to-universal-flat-field-metadata.util.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-manifest/converters/from-field-manifest-to-universal-flat-field-metadata.util.ts @@ -92,7 +92,6 @@ export const fromFieldManifestToUniversalFlatFieldMetadata = ({ options: fieldManifest.options ?? null, defaultValue, universalSettings: fieldManifest.universalSettings ?? null, - isCustom: true, isActive: true, isSystem: fieldManifest.name in PARTIAL_SYSTEM_FLAT_FIELD_METADATAS, isUIReadOnly: false, diff --git a/packages/twenty-server/src/engine/core-modules/application/application-manifest/converters/from-object-manifest-to-universal-flat-object-metadata.util.ts b/packages/twenty-server/src/engine/core-modules/application/application-manifest/converters/from-object-manifest-to-universal-flat-object-metadata.util.ts index 815ac8c813..ecaaf2a428 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-manifest/converters/from-object-manifest-to-universal-flat-object-metadata.util.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-manifest/converters/from-object-manifest-to-universal-flat-object-metadata.util.ts @@ -23,7 +23,6 @@ export const fromObjectManifestToUniversalFlatObjectMetadata = ({ icon: objectManifest.icon ?? null, standardOverrides: null, targetTableName: 'DEPRECATED', - isCustom: true, isRemote: false, isActive: true, isSystem: false, diff --git a/packages/twenty-server/src/engine/core-modules/application/application-rest-api-exception.filter.ts b/packages/twenty-server/src/engine/core-modules/application/application-rest-api-exception.filter.ts new file mode 100644 index 0000000000..98dc1ff2da --- /dev/null +++ b/packages/twenty-server/src/engine/core-modules/application/application-rest-api-exception.filter.ts @@ -0,0 +1,67 @@ +import { + type ArgumentsHost, + Catch, + type ExceptionFilter, + Injectable, +} from '@nestjs/common'; + +import { type Response } from 'express'; +import { assertUnreachable } from 'twenty-shared/utils'; + +import { + ApplicationException, + ApplicationExceptionCode, +} from 'src/engine/core-modules/application/application.exception'; +import { HttpExceptionHandlerService } from 'src/engine/core-modules/exception-handler/http-exception-handler.service'; +import { type CustomException } from 'src/utils/custom-exception'; + +const applicationExceptionCodeToHttpStatus = ( + code: ApplicationExceptionCode, +): number => { + switch (code) { + case ApplicationExceptionCode.OBJECT_NOT_FOUND: + case ApplicationExceptionCode.FIELD_NOT_FOUND: + case ApplicationExceptionCode.ENTITY_NOT_FOUND: + case ApplicationExceptionCode.APPLICATION_NOT_FOUND: + case ApplicationExceptionCode.APP_NOT_INSTALLED: + case ApplicationExceptionCode.LOGIC_FUNCTION_NOT_FOUND: + case ApplicationExceptionCode.FRONT_COMPONENT_NOT_FOUND: + return 404; + case ApplicationExceptionCode.FORBIDDEN: + return 403; + case ApplicationExceptionCode.INVALID_INPUT: + case ApplicationExceptionCode.SOURCE_CHANNEL_MISMATCH: + case ApplicationExceptionCode.APP_ALREADY_INSTALLED: + case ApplicationExceptionCode.CANNOT_DOWNGRADE_APPLICATION: + case ApplicationExceptionCode.SERVER_VERSION_INCOMPATIBLE: + case ApplicationExceptionCode.INVALID_APP_ENGINE_REQUIREMENT: + return 400; + case ApplicationExceptionCode.PACKAGE_RESOLUTION_FAILED: + case ApplicationExceptionCode.POST_INSTALL_ERROR: + case ApplicationExceptionCode.PRE_INSTALL_ERROR: + case ApplicationExceptionCode.TARBALL_EXTRACTION_FAILED: + case ApplicationExceptionCode.UPGRADE_FAILED: + case ApplicationExceptionCode.INVALID_SERVER_VERSION: + return 500; + default: + return assertUnreachable(code); + } +}; + +@Injectable() +@Catch(ApplicationException) +export class ApplicationRestApiExceptionFilter implements ExceptionFilter { + constructor( + private readonly httpExceptionHandlerService: HttpExceptionHandlerService, + ) {} + + catch(exception: ApplicationException, host: ArgumentsHost) { + const response = host.switchToHttp().getResponse(); + + return this.httpExceptionHandlerService.handleError( + exception as CustomException, + response, + applicationExceptionCodeToHttpStatus(exception.code), + ); + } +} diff --git a/packages/twenty-server/src/engine/core-modules/event-emitter/utils/__tests__/object-record-changed-values.spec.ts b/packages/twenty-server/src/engine/core-modules/event-emitter/utils/__tests__/object-record-changed-values.spec.ts index 15223a122a..e3045e4c2e 100644 --- a/packages/twenty-server/src/engine/core-modules/event-emitter/utils/__tests__/object-record-changed-values.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/event-emitter/utils/__tests__/object-record-changed-values.spec.ts @@ -17,7 +17,6 @@ const mockObjectMetadata: FlatObjectMetadata = { workspaceId: '1', universalIdentifier: '1', isSystem: false, - isCustom: false, isActive: true, isRemote: false, isAuditLogged: true, diff --git a/packages/twenty-server/src/engine/core-modules/upgrade/decorators/was-removed-in-upgrade.decorator.ts b/packages/twenty-server/src/engine/core-modules/upgrade/decorators/was-removed-in-upgrade.decorator.ts index 4cf8efa63e..0fe3889d65 100644 --- a/packages/twenty-server/src/engine/core-modules/upgrade/decorators/was-removed-in-upgrade.decorator.ts +++ b/packages/twenty-server/src/engine/core-modules/upgrade/decorators/was-removed-in-upgrade.decorator.ts @@ -6,6 +6,24 @@ export type WasRemovedInUpgradeOptions = { upgradeCommandName: string; }; +declare const wasRemovedInUpgradeBrand: unique symbol; + +export type WasRemovedInUpgrade = T & { + readonly [wasRemovedInUpgradeBrand]?: true; +}; + +type WasRemovedInUpgradeKeys = { + [K in keyof TEntity]: typeof wasRemovedInUpgradeBrand extends keyof TEntity[K] + ? K + : never; +}[keyof TEntity]; + +export type MakeWasRemovedInUpgradePropertiesOptional = Omit< + TEntity, + WasRemovedInUpgradeKeys +> & + Partial>>; + export const WAS_REMOVED_IN_UPGRADE_CLASS_METADATA_KEY = 'WAS_REMOVED_IN_UPGRADE_CLASS'; diff --git a/packages/twenty-server/src/engine/dataloaders/dataloader.interface.ts b/packages/twenty-server/src/engine/dataloaders/dataloader.interface.ts index 053e6553ce..c9f99a7685 100644 --- a/packages/twenty-server/src/engine/dataloaders/dataloader.interface.ts +++ b/packages/twenty-server/src/engine/dataloaders/dataloader.interface.ts @@ -5,6 +5,7 @@ import { type IndexFieldMetadataLoaderPayload, type IndexMetadataLoaderPayload, type IsConfiguredLoaderPayload, + type IsCustomLoaderPayload, type MorphRelationLoaderPayload, type ObjectMetadataLoaderPayload, type RelationLoaderPayload, @@ -92,4 +93,6 @@ export interface IDataloaders { >; isConfiguredLoader: DataLoader; + + isCustomLoader: DataLoader; } diff --git a/packages/twenty-server/src/engine/dataloaders/dataloader.service.ts b/packages/twenty-server/src/engine/dataloaders/dataloader.service.ts index e709c365e5..9fd65254ef 100644 --- a/packages/twenty-server/src/engine/dataloaders/dataloader.service.ts +++ b/packages/twenty-server/src/engine/dataloaders/dataloader.service.ts @@ -37,6 +37,7 @@ import { type IndexFieldMetadataDTO } from 'src/engine/metadata-modules/index-me import { type IndexMetadataDTO } from 'src/engine/metadata-modules/index-metadata/dtos/index-metadata.dto'; import { ObjectMetadataDTO } from 'src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto'; import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { getTwentyStandardApplicationIdOrThrow } from 'src/engine/metadata-modules/utils/get-twenty-standard-application-id-or-throw.util'; export type RelationMetadataLoaderPayload = { workspaceId: string; @@ -116,6 +117,11 @@ export type IsConfiguredLoaderPayload = { applicationRegistrationId: string; }; +export type IsCustomLoaderPayload = { + workspaceId: string; + applicationId: string; +}; + @Injectable() export class DataloaderService { constructor( @@ -142,6 +148,7 @@ export class DataloaderService { const viewFilterGroupsByViewIdLoader = this.createViewFilterGroupsByViewIdLoader(); const isConfiguredLoader = this.createIsConfiguredLoader(); + const isCustomLoader = this.createIsCustomLoader(); return { relationLoader, @@ -158,6 +165,7 @@ export class DataloaderService { viewGroupsByViewIdLoader, viewFilterGroupsByViewIdLoader, isConfiguredLoader, + isCustomLoader, }; } @@ -328,7 +336,6 @@ export class DataloaderService { label: flatFieldMetadata.label, description: flatFieldMetadata.description ?? undefined, icon: flatFieldMetadata.icon ?? undefined, - isCustom: flatFieldMetadata.isCustom, standardOverrides: flatFieldMetadata.standardOverrides ?? undefined, }, @@ -759,4 +766,27 @@ export class DataloaderService { }, ); } + + private createIsCustomLoader() { + return new DataLoader( + async (dataLoaderParams: IsCustomLoaderPayload[]) => { + const workspaceId = dataLoaderParams[0].workspaceId; + + const { flatApplicationMaps } = + await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( + { + workspaceId, + flatMapsKeys: ['flatApplicationMaps'], + }, + ); + + const twentyStandardApplicationId = + getTwentyStandardApplicationIdOrThrow(flatApplicationMaps); + + return dataLoaderParams.map( + ({ applicationId }) => applicationId !== twentyStandardApplicationId, + ); + }, + ); + } } diff --git a/packages/twenty-server/src/engine/metadata-modules/command-menu-item/utils/__tests__/interpolate-navigation-command-menu-item-field.util.spec.ts b/packages/twenty-server/src/engine/metadata-modules/command-menu-item/utils/__tests__/interpolate-navigation-command-menu-item-field.util.spec.ts index 461708a1ab..88e608d6de 100644 --- a/packages/twenty-server/src/engine/metadata-modules/command-menu-item/utils/__tests__/interpolate-navigation-command-menu-item-field.util.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/command-menu-item/utils/__tests__/interpolate-navigation-command-menu-item-field.util.spec.ts @@ -20,7 +20,6 @@ const mockObjectMetadata = { labelSingular: 'Person', description: 'A person', icon: 'IconUser', - isCustom: false, standardOverrides: undefined, } as unknown as ObjectMetadataDTO; @@ -127,7 +126,6 @@ describe('interpolateNavigationCommandMenuItemField', () => { it('should resolve label for custom object metadata', () => { const customObjectMetadata = { ...mockObjectMetadata, - isCustom: true, labelPlural: 'Custom Objects', icon: 'IconCustom', } as unknown as ObjectMetadataDTO; @@ -146,7 +144,6 @@ describe('interpolateNavigationCommandMenuItemField', () => { it('should resolve icon for custom object metadata', () => { const customObjectMetadata = { ...mockObjectMetadata, - isCustom: true, icon: 'IconCustom', } as unknown as ObjectMetadataDTO; diff --git a/packages/twenty-server/src/engine/metadata-modules/command-menu-item/utils/build-navigation-interpolation-context.util.ts b/packages/twenty-server/src/engine/metadata-modules/command-menu-item/utils/build-navigation-interpolation-context.util.ts index 0aa7e08ac2..76da3818f9 100644 --- a/packages/twenty-server/src/engine/metadata-modules/command-menu-item/utils/build-navigation-interpolation-context.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/command-menu-item/utils/build-navigation-interpolation-context.util.ts @@ -9,7 +9,6 @@ export type NavigationInterpolationObjectMetadata = { labelSingular: string; description?: string | null; icon?: string | null; - isCustom: boolean; standardOverrides?: ObjectStandardOverridesDTO | null; }; @@ -27,7 +26,6 @@ export const buildNavigationInterpolationContext = ({ labelSingular: objectMetadata.labelSingular, description: objectMetadata.description ?? undefined, icon: objectMetadata.icon ?? undefined, - isCustom: objectMetadata.isCustom, standardOverrides: objectMetadata.standardOverrides ?? undefined, }; diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/controllers/field-metadata.controller.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/controllers/field-metadata.controller.ts index 99f5b0cbdb..ef8832bb78 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/controllers/field-metadata.controller.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/controllers/field-metadata.controller.ts @@ -16,9 +16,9 @@ import { } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; -import { Repository } from 'typeorm'; import { PermissionFlagType } from 'twenty-shared/constants'; import { FeatureFlagKey } from 'twenty-shared/types'; +import { Repository } from 'typeorm'; import { parseEndingBeforeRestRequest } from 'src/engine/api/rest/input-request-parsers/ending-before-parser-utils/parse-ending-before-rest-request.util'; import { parseLimitRestRequest } from 'src/engine/api/rest/input-request-parsers/limit-parser-utils/parse-limit-rest-request.util'; @@ -28,6 +28,7 @@ import { type RestCursorPageInfo, } from 'src/engine/api/rest/metadata/utils/paginate-by-id-cursor.util'; import { type AuthenticatedRequest } from 'src/engine/api/rest/types/authenticated-request'; +import { ApplicationRestApiExceptionFilter } from 'src/engine/core-modules/application/application-rest-api-exception.filter'; import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; @@ -45,8 +46,6 @@ import { import { FieldMetadataRestApiExceptionFilter } from 'src/engine/metadata-modules/field-metadata/filters/field-metadata-rest-api-exception.filter'; import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata/services/field-metadata.service'; import { fromFieldMetadataEntityToFieldMetadataDto } from 'src/engine/metadata-modules/field-metadata/utils/from-field-metadata-entity-to-field-metadata-dto.util'; -import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; -import { computeUniqueFieldMetadataIdsFromFlatIndexMaps } from 'src/engine/metadata-modules/index-metadata/utils/compute-unique-field-metadata-ids-from-flat-index-maps.util'; import { toLegacyFieldMetadataCreateResponse, toLegacyFieldMetadataDeleteResponse, @@ -54,8 +53,11 @@ import { toLegacyFieldMetadataListResponse, toLegacyFieldMetadataUpdateResponse, } from 'src/engine/metadata-modules/field-metadata/utils/to-legacy-field-metadata-response.util'; +import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; import { fromFlatFieldMetadataToFieldMetadataDto } from 'src/engine/metadata-modules/flat-field-metadata/utils/from-flat-field-metadata-to-field-metadata-dto.util'; +import { computeUniqueFieldMetadataIdsFromFlatIndexMaps } from 'src/engine/metadata-modules/index-metadata/utils/compute-unique-field-metadata-ids-from-flat-index-maps.util'; import { PermissionsRestApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-rest-api-exception.filter'; +import { getTwentyStandardApplicationIdOrThrow } from 'src/engine/metadata-modules/utils/get-twenty-standard-application-id-or-throw.util'; @Controller('rest/metadata/fields') @UseGuards( @@ -66,6 +68,7 @@ import { PermissionsRestApiExceptionFilter } from 'src/engine/metadata-modules/p @UseFilters( PermissionsRestApiExceptionFilter, FieldMetadataRestApiExceptionFilter, + ApplicationRestApiExceptionFilter, ) @UsePipes(new ValidationPipe()) export class FieldMetadataController { @@ -88,6 +91,17 @@ export class FieldMetadataController { return computeUniqueFieldMetadataIdsFromFlatIndexMaps(flatIndexMaps); } + private async loadStandardApplicationId( + workspaceId: string, + ): Promise { + const { flatApplicationMaps } = + await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( + { workspaceId, flatMapsKeys: ['flatApplicationMaps'] }, + ); + + return getTwentyStandardApplicationIdOrThrow(flatApplicationMaps); + } + @Get() async findMany( @Req() request: AuthenticatedRequest, @@ -101,8 +115,10 @@ export class FieldMetadataController { endingBefore: parseEndingBeforeRestRequest(request), }); - const uniqueFieldMetadataIds = - await this.loadUniqueFieldMetadataIds(workspaceId); + const [uniqueFieldMetadataIds, standardApplicationId] = await Promise.all([ + this.loadUniqueFieldMetadataIds(workspaceId), + this.loadStandardApplicationId(workspaceId), + ]); const result: { data: FieldMetadataDTO[]; @@ -110,7 +126,11 @@ export class FieldMetadataController { totalCount: number; } = { data: items.map((item) => - fromFieldMetadataEntityToFieldMetadataDto(item, uniqueFieldMetadataIds), + fromFieldMetadataEntityToFieldMetadataDto( + item, + standardApplicationId, + uniqueFieldMetadataIds, + ), ), pageInfo, totalCount, @@ -137,10 +157,13 @@ export class FieldMetadataController { ); } - const uniqueFieldMetadataIds = - await this.loadUniqueFieldMetadataIds(workspaceId); + const [uniqueFieldMetadataIds, standardApplicationId] = await Promise.all([ + this.loadUniqueFieldMetadataIds(workspaceId), + this.loadStandardApplicationId(workspaceId), + ]); const result = fromFieldMetadataEntityToFieldMetadataDto( field, + standardApplicationId, uniqueFieldMetadataIds, ); diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto.ts index 880ae3ac99..092208e3ea 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto.ts @@ -100,7 +100,11 @@ export class FieldMetadataDTO { @IsBoolean() @IsOptional() - @FilterableField({ nullable: true }) + @Field({ + nullable: true, + deprecationReason: + 'isCustom is derived from the owning application and will be removed; a field is custom when it does not belong to the twenty-standard application.', + }) isCustom?: boolean; @IsBoolean() diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.entity.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.entity.ts index 69989427ea..e277e0f490 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.entity.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.entity.ts @@ -20,6 +20,7 @@ import { UpdateDateColumn, } from 'typeorm'; +import { WasRemovedInUpgrade } from 'src/engine/core-modules/upgrade/decorators/was-removed-in-upgrade.decorator'; import { type FieldStandardOverridesDTO } from 'src/engine/metadata-modules/field-metadata/dtos/field-standard-overrides.dto'; import { AssignIfIsGivenFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/types/assign-if-is-given-field-metadata-type.type'; import { AssignTypeIfIsMorphOrRelationFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/types/assign-type-if-is-morph-or-relation-field-metadata-type.type'; @@ -106,8 +107,12 @@ export class FieldMetadataEntity< @Column('jsonb', { nullable: true }) settings: JsonbProperty>; - @Column({ default: false }) - isCustom: boolean; + @WasRemovedInUpgrade({ + upgradeCommandName: + '2.12.0_DropIsCustomFromObjectAndFieldMetadataFastInstanceCommand_1780579070012', + }) + @Column({ type: 'boolean', default: false }) + isCustom: WasRemovedInUpgrade; @Column({ default: false }) isActive: boolean; diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.module.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.module.ts index 3d92e094a9..e2fb308500 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.module.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.module.ts @@ -41,6 +41,7 @@ import { UpdateFieldInput } from './dtos/update-field.input'; @Module({ imports: [ + ApplicationModule, TokenModule, WorkspaceCacheStorageModule, FeatureFlagModule, diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.resolver.ts index 373eadfec0..414cc482c9 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.resolver.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.resolver.ts @@ -45,6 +45,22 @@ export class FieldMetadataResolver { private readonly i18nService: I18nService, ) {} + @ResolveField(() => Boolean, { + nullable: true, + deprecationReason: + 'isCustom is derived from the owning application and will be removed; a field is custom when it does not belong to the twenty-standard application.', + }) + async isCustom( + @Parent() fieldMetadata: Pick, + @AuthWorkspace() { id: workspaceId }: WorkspaceEntity, + @Context() context: { loaders: IDataloaders }, + ): Promise { + return context.loaders.isCustomLoader.load({ + workspaceId, + applicationId: fieldMetadata.applicationId, + }); + } + @ResolveField(() => String, { nullable: true }) async label( @Parent() fieldMetadata: FieldMetadataStandardOverrideParent, diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/__tests__/resolve-field-metadata-standard-override.util.spec.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/__tests__/resolve-field-metadata-standard-override.util.spec.ts index 3b5e608226..3e605bdfa6 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/__tests__/resolve-field-metadata-standard-override.util.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/__tests__/resolve-field-metadata-standard-override.util.spec.ts @@ -26,7 +26,6 @@ describe('resolveFieldMetadataStandardOverride', () => { label: 'Custom Label', description: 'Custom Description', icon: 'custom-icon', - isCustom: true, standardOverrides: undefined, }; @@ -45,7 +44,6 @@ describe('resolveFieldMetadataStandardOverride', () => { label: 'Custom Label', description: 'Custom Description', icon: 'custom-icon', - isCustom: true, standardOverrides: undefined, }; @@ -64,7 +62,6 @@ describe('resolveFieldMetadataStandardOverride', () => { label: 'Custom Label', description: 'Custom Description', icon: 'custom-icon', - isCustom: true, standardOverrides: undefined, }; @@ -85,7 +82,6 @@ describe('resolveFieldMetadataStandardOverride', () => { label: 'Standard Label', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: { icon: 'override-icon', }, @@ -108,7 +104,6 @@ describe('resolveFieldMetadataStandardOverride', () => { label: 'Standard Label', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: { translations: { 'fr-FR': { @@ -142,7 +137,6 @@ describe('resolveFieldMetadataStandardOverride', () => { label: 'Standard Label', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: { translations: { 'es-ES': { @@ -170,7 +164,6 @@ describe('resolveFieldMetadataStandardOverride', () => { label: 'Standard Label', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: { translations: { 'fr-FR': { @@ -198,7 +191,6 @@ describe('resolveFieldMetadataStandardOverride', () => { label: 'Standard Label', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: { translations: { 'fr-FR': { @@ -228,7 +220,6 @@ describe('resolveFieldMetadataStandardOverride', () => { label: 'Standard Label', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: { label: 'Overridden Label', description: 'Overridden Description', @@ -267,7 +258,6 @@ describe('resolveFieldMetadataStandardOverride', () => { label: 'Standard Label', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: { label: 'Overridden Label', }, @@ -293,7 +283,6 @@ describe('resolveFieldMetadataStandardOverride', () => { label: 'Standard Label', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: { label: '', }, @@ -317,7 +306,6 @@ describe('resolveFieldMetadataStandardOverride', () => { label: 'Standard Label', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: { label: undefined, }, @@ -343,7 +331,6 @@ describe('resolveFieldMetadataStandardOverride', () => { label: 'Standard Label', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: undefined, }; @@ -367,7 +354,6 @@ describe('resolveFieldMetadataStandardOverride', () => { label: 'Standard Label', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: undefined, }; @@ -393,7 +379,6 @@ describe('resolveFieldMetadataStandardOverride', () => { label: 'Standard Label', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: { label: 'Source Override', translations: { @@ -421,7 +406,6 @@ describe('resolveFieldMetadataStandardOverride', () => { label: 'Standard Label', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: { label: 'Source Override', }, @@ -444,7 +428,6 @@ describe('resolveFieldMetadataStandardOverride', () => { label: 'Standard Label', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: {}, }; diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/from-field-metadata-entity-to-field-metadata-dto.util.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/from-field-metadata-entity-to-field-metadata-dto.util.ts index 6ec3a580cb..9384eca88f 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/from-field-metadata-entity-to-field-metadata-dto.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/from-field-metadata-entity-to-field-metadata-dto.util.ts @@ -7,6 +7,7 @@ import { type FieldMetadataEntity } from 'src/engine/metadata-modules/field-meta // contexts that don't care about uniqueness can omit it. export const fromFieldMetadataEntityToFieldMetadataDto = ( entity: FieldMetadataEntity, + standardApplicationId: string, uniqueFieldMetadataIds?: ReadonlySet, ): FieldMetadataDTO => ({ id: entity.id, @@ -18,7 +19,7 @@ export const fromFieldMetadataEntityToFieldMetadataDto = ( description: entity.description ?? undefined, icon: entity.icon ?? undefined, standardOverrides: entity.standardOverrides ?? undefined, - isCustom: entity.isCustom, + isCustom: entity.applicationId !== standardApplicationId, isActive: entity.isActive, isSystem: entity.isSystem, isUIReadOnly: entity.isUIReadOnly, diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/resolve-field-metadata-standard-override.util.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/resolve-field-metadata-standard-override.util.ts index b854796c31..f5a51fb355 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/resolve-field-metadata-standard-override.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/resolve-field-metadata-standard-override.util.ts @@ -10,7 +10,7 @@ import { type FieldMetadataDTO } from 'src/engine/metadata-modules/field-metadat export const resolveFieldMetadataStandardOverride = ( fieldMetadata: Pick< FieldMetadataDTO, - 'label' | 'description' | 'icon' | 'isCustom' | 'standardOverrides' + 'label' | 'description' | 'icon' | 'standardOverrides' >, labelKey: 'label' | 'description' | 'icon', locale: keyof typeof APP_LOCALES | undefined, @@ -18,10 +18,6 @@ export const resolveFieldMetadataStandardOverride = ( ): string => { const safeLocale = locale ?? SOURCE_LOCALE; - if (fieldMetadata.isCustom) { - return fieldMetadata[labelKey] ?? ''; - } - if (labelKey === 'icon' && isDefined(fieldMetadata.standardOverrides?.icon)) { return fieldMetadata.standardOverrides.icon; } diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/all-entity-properties-configuration-by-metadata-name.constant.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/all-entity-properties-configuration-by-metadata-name.constant.ts index 2b2d707bfb..181182edf6 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/all-entity-properties-configuration-by-metadata-name.constant.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/all-entity-properties-configuration-by-metadata-name.constant.ts @@ -103,11 +103,6 @@ export const ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME = { toStringify: false, universalProperty: undefined, }, - isCustom: { - toCompare: false, - toStringify: false, - universalProperty: undefined, - }, isSystem: { toCompare: false, toStringify: false, @@ -207,11 +202,6 @@ export const ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME = { toStringify: true, universalProperty: undefined, }, - isCustom: { - toCompare: false, - toStringify: false, - universalProperty: undefined, - }, isRemote: { toCompare: false, toStringify: false, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/scalar-flat-entity.type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/scalar-flat-entity.type.ts index 834f8b2569..e1aa8a0480 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/scalar-flat-entity.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/scalar-flat-entity.type.ts @@ -1,8 +1,9 @@ +import { type MakeWasRemovedInUpgradePropertiesOptional } from 'src/engine/core-modules/upgrade/decorators/was-removed-in-upgrade.decorator'; import { type CastRecordTypeOrmDatePropertiesToString } from 'src/engine/metadata-modules/flat-entity/types/cast-record-typeorm-date-properties-to-string.type'; import { type ExtractEntityRelatedEntityProperties } from 'src/engine/metadata-modules/flat-entity/types/extract-entity-related-entity-properties.type'; export type ScalarFlatEntity = Omit< - TEntity, + MakeWasRemovedInUpgradePropertiesOptional, | ExtractEntityRelatedEntityProperties | keyof CastRecordTypeOrmDatePropertiesToString > & diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/attachment-flat-fields.mock.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/attachment-flat-fields.mock.ts index 3d9138b7df..8c14a453e1 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/attachment-flat-fields.mock.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/attachment-flat-fields.mock.ts @@ -22,7 +22,6 @@ export const ATTACHMENT_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -45,7 +44,6 @@ export const ATTACHMENT_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -68,7 +66,6 @@ export const ATTACHMENT_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -91,7 +88,6 @@ export const ATTACHMENT_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: true, isNullable: false, @@ -114,7 +110,6 @@ export const ATTACHMENT_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -137,7 +132,6 @@ export const ATTACHMENT_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -160,7 +154,6 @@ export const ATTACHMENT_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -187,7 +180,6 @@ export const ATTACHMENT_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'authorId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -214,7 +206,6 @@ export const ATTACHMENT_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'taskId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -241,7 +232,6 @@ export const ATTACHMENT_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'noteId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -268,7 +258,6 @@ export const ATTACHMENT_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'personId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -295,7 +284,6 @@ export const ATTACHMENT_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'companyId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -322,7 +310,6 @@ export const ATTACHMENT_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'opportunityId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -349,7 +336,6 @@ export const ATTACHMENT_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'rocketId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -376,7 +362,6 @@ export const ATTACHMENT_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'petId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -403,7 +388,6 @@ export const ATTACHMENT_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'surveyResultId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/company-flat-fields.mock.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/company-flat-fields.mock.ts index d806d8f9b4..3e963921e1 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/company-flat-fields.mock.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/company-flat-fields.mock.ts @@ -22,7 +22,6 @@ export const COMPANY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -50,7 +49,6 @@ export const COMPANY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -77,7 +75,6 @@ export const COMPANY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -100,7 +97,6 @@ export const COMPANY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -132,7 +128,6 @@ export const COMPANY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -155,7 +150,6 @@ export const COMPANY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: true, isNullable: false, @@ -182,7 +176,6 @@ export const COMPANY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -205,7 +198,6 @@ export const COMPANY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -228,7 +220,6 @@ export const COMPANY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: true, isNullable: false, @@ -251,7 +242,6 @@ export const COMPANY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -274,7 +264,6 @@ export const COMPANY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -297,7 +286,6 @@ export const COMPANY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -320,7 +308,6 @@ export const COMPANY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -348,7 +335,6 @@ export const COMPANY_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'accountOwnerId', }, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -371,7 +357,6 @@ export const COMPANY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -394,7 +379,6 @@ export const COMPANY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -417,7 +401,6 @@ export const COMPANY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -440,7 +423,6 @@ export const COMPANY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -463,7 +445,6 @@ export const COMPANY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -486,7 +467,6 @@ export const COMPANY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: true, isActive: true, isSystem: false, isNullable: false, @@ -513,7 +493,6 @@ export const COMPANY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: true, isActive: true, isSystem: false, isNullable: true, @@ -558,7 +537,6 @@ export const COMPANY_FLAT_FIELDS_MOCK = { }, ], settings: null, - isCustom: true, isActive: true, isSystem: false, isNullable: true, @@ -581,7 +559,6 @@ export const COMPANY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: true, isActive: true, isSystem: false, isNullable: true, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/get-flat-field-metadata.mock.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/get-flat-field-metadata.mock.ts index 06b29f2d63..2a087c15d0 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/get-flat-field-metadata.mock.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/get-flat-field-metadata.mock.ts @@ -32,7 +32,6 @@ export const getFlatFieldMetadataMock = ( icon: 'icon', id: faker.string.uuid(), isActive: true, - isCustom: true, name: 'flatFieldMetadataName', label: 'flat field metadata label', isNullable: true, @@ -67,7 +66,6 @@ export const getStandardFlatFieldMetadataMock = ( ) => { return getFlatFieldMetadataMock({ standardOverrides: {}, - isCustom: false, isSystem: true, ...overrides, }); diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/get-morph-or-relation-target-flat-field-metadata-mock.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/get-morph-or-relation-target-flat-field-metadata-mock.ts index 323b23961f..f440a8cb39 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/get-morph-or-relation-target-flat-field-metadata-mock.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/get-morph-or-relation-target-flat-field-metadata-mock.ts @@ -45,7 +45,6 @@ export const getRelationTargetFlatFieldMetadataMock = ({ icon: 'icon', id: faker.string.uuid(), isActive: true, - isCustom: true, name: 'flatFieldMetadataName', label: 'flat field metadata label', isNullable: true, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/note-flat-fields.mock.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/note-flat-fields.mock.ts index 6c5ed92b78..9e8e0e95c5 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/note-flat-fields.mock.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/note-flat-fields.mock.ts @@ -18,7 +18,6 @@ export const NOTE_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: true, isNullable: false, @@ -41,7 +40,6 @@ export const NOTE_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -64,7 +62,6 @@ export const NOTE_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -91,7 +88,6 @@ export const NOTE_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -114,7 +110,6 @@ export const NOTE_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -137,7 +132,6 @@ export const NOTE_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: true, isNullable: false, @@ -160,7 +154,6 @@ export const NOTE_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -183,7 +176,6 @@ export const NOTE_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -206,7 +198,6 @@ export const NOTE_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -229,7 +220,6 @@ export const NOTE_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -252,7 +242,6 @@ export const NOTE_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -275,7 +264,6 @@ export const NOTE_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/notetarget-flat-fields.mock.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/notetarget-flat-fields.mock.ts index 6140f04e45..e25d74208e 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/notetarget-flat-fields.mock.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/notetarget-flat-fields.mock.ts @@ -22,7 +22,6 @@ export const NOTETARGET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: true, isNullable: false, @@ -45,7 +44,6 @@ export const NOTETARGET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -68,7 +66,6 @@ export const NOTETARGET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -91,7 +88,6 @@ export const NOTETARGET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -118,7 +114,6 @@ export const NOTETARGET_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'noteId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -145,7 +140,6 @@ export const NOTETARGET_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'personId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -172,7 +166,6 @@ export const NOTETARGET_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'companyId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -199,7 +192,6 @@ export const NOTETARGET_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'opportunityId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -226,7 +218,6 @@ export const NOTETARGET_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'rocketId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -253,7 +244,6 @@ export const NOTETARGET_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'petId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -280,7 +270,6 @@ export const NOTETARGET_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'surveyResultId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/opportunity-flat-fields.mock.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/opportunity-flat-fields.mock.ts index fcf6000e0e..a830c08057 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/opportunity-flat-fields.mock.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/opportunity-flat-fields.mock.ts @@ -22,7 +22,6 @@ export const OPPORTUNITY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -45,7 +44,6 @@ export const OPPORTUNITY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -68,7 +66,6 @@ export const OPPORTUNITY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -127,7 +124,6 @@ export const OPPORTUNITY_FLAT_FIELDS_MOCK = { }, ], settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -150,7 +146,6 @@ export const OPPORTUNITY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: true, isNullable: false, @@ -177,7 +172,6 @@ export const OPPORTUNITY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -200,7 +194,6 @@ export const OPPORTUNITY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -223,7 +216,6 @@ export const OPPORTUNITY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: true, isNullable: false, @@ -246,7 +238,6 @@ export const OPPORTUNITY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -269,7 +260,6 @@ export const OPPORTUNITY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -292,7 +282,6 @@ export const OPPORTUNITY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -319,7 +308,6 @@ export const OPPORTUNITY_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'pointOfContactId', }, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -346,7 +334,6 @@ export const OPPORTUNITY_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'companyId', }, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -369,7 +356,6 @@ export const OPPORTUNITY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -392,7 +378,6 @@ export const OPPORTUNITY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -415,7 +400,6 @@ export const OPPORTUNITY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -438,7 +422,6 @@ export const OPPORTUNITY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/person-flat-fields.mock.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/person-flat-fields.mock.ts index eed0a0e85d..2fab6d5b86 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/person-flat-fields.mock.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/person-flat-fields.mock.ts @@ -22,7 +22,6 @@ export const PERSON_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -45,7 +44,6 @@ export const PERSON_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -72,7 +70,6 @@ export const PERSON_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -95,7 +92,6 @@ export const PERSON_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -123,7 +119,6 @@ export const PERSON_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -146,7 +141,6 @@ export const PERSON_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: true, isNullable: false, @@ -169,7 +163,6 @@ export const PERSON_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: true, isNullable: false, @@ -196,7 +189,6 @@ export const PERSON_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -219,7 +211,6 @@ export const PERSON_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -242,7 +233,6 @@ export const PERSON_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: true, isNullable: false, @@ -265,7 +255,6 @@ export const PERSON_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -288,7 +277,6 @@ export const PERSON_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -311,7 +299,6 @@ export const PERSON_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -338,7 +325,6 @@ export const PERSON_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'companyId', }, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -362,7 +348,6 @@ export const PERSON_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -385,7 +370,6 @@ export const PERSON_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -408,7 +392,6 @@ export const PERSON_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -431,7 +414,6 @@ export const PERSON_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -454,7 +436,6 @@ export const PERSON_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -477,7 +458,6 @@ export const PERSON_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -500,7 +480,6 @@ export const PERSON_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -523,7 +502,6 @@ export const PERSON_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: true, isActive: true, isSystem: false, isNullable: false, @@ -551,7 +529,6 @@ export const PERSON_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: true, isActive: true, isSystem: false, isNullable: false, @@ -596,7 +573,6 @@ export const PERSON_FLAT_FIELDS_MOCK = { }, ], settings: null, - isCustom: true, isActive: true, isSystem: false, isNullable: true, @@ -650,7 +626,6 @@ export const PERSON_FLAT_FIELDS_MOCK = { }, ], settings: null, - isCustom: true, isActive: true, isSystem: false, isNullable: true, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/pet-flat-fields.mock.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/pet-flat-fields.mock.ts index 723202973f..73572d7500 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/pet-flat-fields.mock.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/pet-flat-fields.mock.ts @@ -18,7 +18,6 @@ export const PET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -41,7 +40,6 @@ export const PET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: true, isNullable: false, @@ -64,7 +62,6 @@ export const PET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -87,7 +84,6 @@ export const PET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -110,7 +106,6 @@ export const PET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -133,7 +128,6 @@ export const PET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -156,7 +150,6 @@ export const PET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -179,7 +172,6 @@ export const PET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: true, isNullable: false, @@ -202,7 +194,6 @@ export const PET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -225,7 +216,6 @@ export const PET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -248,7 +238,6 @@ export const PET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -271,7 +260,6 @@ export const PET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: false, isSystem: true, isNullable: true, @@ -337,7 +325,6 @@ export const PET_FLAT_FIELDS_MOCK = { }, ], settings: null, - isCustom: true, isActive: true, isSystem: false, isNullable: true, @@ -403,7 +390,6 @@ export const PET_FLAT_FIELDS_MOCK = { }, ], settings: null, - isCustom: true, isActive: true, isSystem: false, isNullable: true, @@ -426,7 +412,6 @@ export const PET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: true, isActive: true, isSystem: false, isNullable: false, @@ -449,7 +434,6 @@ export const PET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: true, isActive: true, isSystem: false, isNullable: true, @@ -481,7 +465,6 @@ export const PET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: true, isActive: true, isSystem: false, isNullable: true, @@ -509,7 +492,6 @@ export const PET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: true, isActive: true, isSystem: false, isNullable: true, @@ -532,7 +514,6 @@ export const PET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: true, isActive: true, isSystem: false, isNullable: true, @@ -555,7 +536,6 @@ export const PET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: true, isActive: true, isSystem: false, isNullable: true, @@ -578,7 +558,6 @@ export const PET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: true, isActive: true, isSystem: false, isNullable: true, @@ -605,7 +584,6 @@ export const PET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: true, isActive: true, isSystem: false, isNullable: true, @@ -628,7 +606,6 @@ export const PET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: true, isActive: true, isSystem: false, isNullable: true, @@ -651,7 +628,6 @@ export const PET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: true, isActive: true, isSystem: false, isNullable: true, @@ -705,7 +681,6 @@ export const PET_FLAT_FIELDS_MOCK = { }, ], settings: null, - isCustom: true, isActive: true, isSystem: false, isNullable: true, @@ -728,7 +703,6 @@ export const PET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: true, isActive: true, isSystem: false, isNullable: true, @@ -751,7 +725,6 @@ export const PET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: true, isActive: true, isSystem: false, isNullable: true, @@ -774,7 +747,6 @@ export const PET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: true, isActive: true, isSystem: false, isNullable: true, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/rocket-flat-fields.mock.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/rocket-flat-fields.mock.ts index 8a0aab5dde..6cd58a97fe 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/rocket-flat-fields.mock.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/rocket-flat-fields.mock.ts @@ -18,7 +18,6 @@ export const ROCKET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: true, isNullable: false, @@ -41,7 +40,6 @@ export const ROCKET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -64,7 +62,6 @@ export const ROCKET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -87,7 +84,6 @@ export const ROCKET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -110,7 +106,6 @@ export const ROCKET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -133,7 +128,6 @@ export const ROCKET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -156,7 +150,6 @@ export const ROCKET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: true, isNullable: false, @@ -179,7 +172,6 @@ export const ROCKET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -202,7 +194,6 @@ export const ROCKET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -225,7 +216,6 @@ export const ROCKET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -248,7 +238,6 @@ export const ROCKET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -271,7 +260,6 @@ export const ROCKET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: false, isSystem: true, isNullable: true, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/task-flat-fields.mock.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/task-flat-fields.mock.ts index 3a494757eb..035e0bbe7d 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/task-flat-fields.mock.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/task-flat-fields.mock.ts @@ -22,7 +22,6 @@ export const TASK_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: true, isNullable: false, @@ -45,7 +44,6 @@ export const TASK_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -68,7 +66,6 @@ export const TASK_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -91,7 +88,6 @@ export const TASK_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -136,7 +132,6 @@ export const TASK_FLAT_FIELDS_MOCK = { }, ], settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -163,7 +158,6 @@ export const TASK_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -186,7 +180,6 @@ export const TASK_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -209,7 +202,6 @@ export const TASK_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: true, isNullable: false, @@ -232,7 +224,6 @@ export const TASK_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -255,7 +246,6 @@ export const TASK_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -278,7 +268,6 @@ export const TASK_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -301,7 +290,6 @@ export const TASK_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -324,7 +312,6 @@ export const TASK_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -351,7 +338,6 @@ export const TASK_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'assigneeId', }, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -374,7 +360,6 @@ export const TASK_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { relationType: RelationType.ONE_TO_MANY }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/tasktarget-flat-fields.mock.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/tasktarget-flat-fields.mock.ts index b43b68123e..0e3d5a095e 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/tasktarget-flat-fields.mock.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/tasktarget-flat-fields.mock.ts @@ -22,7 +22,6 @@ export const TASKTARGET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: true, isNullable: false, @@ -45,7 +44,6 @@ export const TASKTARGET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -68,7 +66,6 @@ export const TASKTARGET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -91,7 +88,6 @@ export const TASKTARGET_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -118,7 +114,6 @@ export const TASKTARGET_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'taskId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -145,7 +140,6 @@ export const TASKTARGET_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'personId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -172,7 +166,6 @@ export const TASKTARGET_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'companyId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -199,7 +192,6 @@ export const TASKTARGET_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'opportunityId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -226,7 +218,6 @@ export const TASKTARGET_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'rocketId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -253,7 +244,6 @@ export const TASKTARGET_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'petId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -280,7 +270,6 @@ export const TASKTARGET_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'surveyResultId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/timelineactivity-flat-fields.mock.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/timelineactivity-flat-fields.mock.ts index 1301c716bf..1be3cdecc4 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/timelineactivity-flat-fields.mock.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__mocks__/timelineactivity-flat-fields.mock.ts @@ -22,7 +22,6 @@ export const TIMELINEACTIVITY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -45,7 +44,6 @@ export const TIMELINEACTIVITY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -68,7 +66,6 @@ export const TIMELINEACTIVITY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -91,7 +88,6 @@ export const TIMELINEACTIVITY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -114,7 +110,6 @@ export const TIMELINEACTIVITY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -137,7 +132,6 @@ export const TIMELINEACTIVITY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -160,7 +154,6 @@ export const TIMELINEACTIVITY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: null, - isCustom: false, isActive: true, isSystem: true, isNullable: false, @@ -183,7 +176,6 @@ export const TIMELINEACTIVITY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -206,7 +198,6 @@ export const TIMELINEACTIVITY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: false, @@ -229,7 +220,6 @@ export const TIMELINEACTIVITY_FLAT_FIELDS_MOCK = { standardOverrides: null, options: null, settings: { displayFormat: DateDisplayFormat.RELATIVE }, - isCustom: false, isActive: true, isSystem: false, isNullable: true, @@ -256,7 +246,6 @@ export const TIMELINEACTIVITY_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'workspaceMemberId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -283,7 +272,6 @@ export const TIMELINEACTIVITY_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'personId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -310,7 +298,6 @@ export const TIMELINEACTIVITY_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'companyId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -337,7 +324,6 @@ export const TIMELINEACTIVITY_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'opportunityId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -364,7 +350,6 @@ export const TIMELINEACTIVITY_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'noteId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -391,7 +376,6 @@ export const TIMELINEACTIVITY_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'taskId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -418,7 +402,6 @@ export const TIMELINEACTIVITY_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'workflowId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -445,7 +428,6 @@ export const TIMELINEACTIVITY_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'workflowVersionId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -472,7 +454,6 @@ export const TIMELINEACTIVITY_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'workflowRunId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -499,7 +480,6 @@ export const TIMELINEACTIVITY_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'rocketId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -526,7 +506,6 @@ export const TIMELINEACTIVITY_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'petId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, @@ -553,7 +532,6 @@ export const TIMELINEACTIVITY_FLAT_FIELDS_MOCK = { relationType: RelationType.MANY_TO_ONE, joinColumnName: 'surveyResultId', }, - isCustom: false, isActive: true, isSystem: true, isNullable: true, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__tests__/__snapshots__/morph-relation-from-create-field-input-to-flat-field-metadatas-to-create.spec.ts.snap b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__tests__/__snapshots__/morph-relation-from-create-field-input-to-flat-field-metadatas-to-create.spec.ts.snap index 92d15b30ce..7263d5b00f 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__tests__/__snapshots__/morph-relation-from-create-field-input-to-flat-field-metadatas-to-create.spec.ts.snap +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__tests__/__snapshots__/morph-relation-from-create-field-input-to-flat-field-metadatas-to-create.spec.ts.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing +// Jest Snapshot v1, https://goo.gl/fbAQLP exports[`fromCreateFieldInputToFlatFieldMetadatasToCreate MORPH_RELATION test suite Failure cases should fail when morphRelationsCreationPayload has different relation types 1`] = ` { @@ -124,7 +124,6 @@ exports[`fromCreateFieldInputToFlatFieldMetadatasToCreate MORPH_RELATION test su "fieldPermissionUniversalIdentifiers": [], "icon": "IconRelationOneToMany", "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": false, @@ -159,7 +158,6 @@ exports[`fromCreateFieldInputToFlatFieldMetadatasToCreate MORPH_RELATION test su "fieldPermissionUniversalIdentifiers": [], "icon": "IconPet", "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": false, @@ -196,7 +194,6 @@ exports[`fromCreateFieldInputToFlatFieldMetadatasToCreate MORPH_RELATION test su "fieldPermissionUniversalIdentifiers": [], "icon": "IconRelationOneToMany", "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": false, @@ -231,7 +228,6 @@ exports[`fromCreateFieldInputToFlatFieldMetadatasToCreate MORPH_RELATION test su "fieldPermissionUniversalIdentifiers": [], "icon": "IconBuilding", "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": false, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/services/flat-field-metadata-type-validator.service.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/services/flat-field-metadata-type-validator.service.ts index 8b5bf34512..0aa6f5cde6 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/services/flat-field-metadata-type-validator.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/services/flat-field-metadata-type-validator.service.ts @@ -16,6 +16,7 @@ import { validateMorphOrRelationFlatFieldMetadata } from 'src/engine/metadata-mo import { validateMorphRelationFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-morph-relation-flat-field-metadata.util'; import { validatePositionFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-position-flat-field-metadata.util'; import { validateTsVectorFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-ts-vector-flat-field-metadata.util'; +import { belongsToTwentyStandardApp } from 'src/engine/metadata-modules/utils/belongs-to-twenty-standard-app.util'; const DEFAULT_NO_VALIDATION = (): FlatFieldMetadataValidationError[] => []; @@ -28,7 +29,9 @@ const rejectUserCreation = ( args: FlatFieldMetadataTypeValidationArgs, ): FlatFieldMetadataValidationError[] => { const isCreation = !isDefined(args.update); - const isCustomField = args.flatEntityToValidate.isCustom; + const isCustomField = !belongsToTwentyStandardApp( + args.flatEntityToValidate, + ); if (isCreation && isCustomField) { return [ diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/__tests__/generate-morph-or-relation-flat-field-metadata-pair.spec.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/__tests__/generate-morph-or-relation-flat-field-metadata-pair.spec.ts index 43989a9d4d..0b1d37845e 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/__tests__/generate-morph-or-relation-flat-field-metadata-pair.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/__tests__/generate-morph-or-relation-flat-field-metadata-pair.spec.ts @@ -74,7 +74,6 @@ describe('generate Morph Or Relation Flat Field Metadata Pair test suite', () => description: 'Company pets', icon: 'IconCat', type: FieldMetadataType.RELATION, - isCustom: true, isSystem: false, isUnique: false, relationCreationPayload: { @@ -109,7 +108,6 @@ describe('generate Morph Or Relation Flat Field Metadata Pair test suite', () => description: 'Company pets', icon: 'IconCat', type: FieldMetadataType.RELATION, - isCustom: true, isSystem: false, isUnique: false, relationCreationPayload: { @@ -144,7 +142,6 @@ describe('generate Morph Or Relation Flat Field Metadata Pair test suite', () => description: 'Company pets', icon: 'IconCat', type: FieldMetadataType.RELATION, - isCustom: false, isSystem: true, isUnique: true, relationCreationPayload: { @@ -180,7 +177,6 @@ describe('generate Morph Or Relation Flat Field Metadata Pair test suite', () => description: 'Morph relation to pet', icon: 'IconCat', type: FieldMetadataType.MORPH_RELATION, - isCustom: false, isSystem: true, isUnique: false, relationCreationPayload: { @@ -216,7 +212,6 @@ describe('generate Morph Or Relation Flat Field Metadata Pair test suite', () => description: 'Morph relation to pet', icon: 'IconCat', type: FieldMetadataType.MORPH_RELATION, - isCustom: false, isSystem: true, isUnique: false, relationCreationPayload: { @@ -252,7 +247,6 @@ describe('generate Morph Or Relation Flat Field Metadata Pair test suite', () => description: 'Morph relation to pet', icon: 'IconCat', type: FieldMetadataType.RELATION, - isCustom: false, isSystem: true, isUnique: false, relationCreationPayload: { @@ -363,7 +357,6 @@ describe('generate Morph Or Relation Flat Field Metadata Pair test suite', () => description: 'Company pets', icon: 'IconCat', type: FieldMetadataType.RELATION, - isCustom: true, isSystem: false, isUnique: false, universalIdentifier: sourceUniversalIdentifier, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/from-flat-field-metadata-to-field-metadata-dto.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/from-flat-field-metadata-to-field-metadata-dto.util.ts index 93a47a1219..7c226fb6e8 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/from-flat-field-metadata-to-field-metadata-dto.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/from-flat-field-metadata-to-field-metadata-dto.util.ts @@ -1,5 +1,6 @@ import { type FieldMetadataDTO } from 'src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; +import { belongsToTwentyStandardApp } from 'src/engine/metadata-modules/utils/belongs-to-twenty-standard-app.util'; export const fromFlatFieldMetadataToFieldMetadataDto = ( flatFieldMetadata: FlatFieldMetadata, @@ -22,7 +23,6 @@ export const fromFlatFieldMetadataToFieldMetadataDto = ( workspaceId, defaultValue, isActive, - isCustom, isLabelSyncedWithName, isSystem, isUIReadOnly, @@ -41,7 +41,7 @@ export const fromFlatFieldMetadataToFieldMetadataDto = ( workspaceId, defaultValue, isActive, - isCustom, + isCustom: !belongsToTwentyStandardApp(flatFieldMetadata), isLabelSyncedWithName, isSystem, isUIReadOnly, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/get-default-flat-field-metadata-from-create-field-input.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/get-default-flat-field-metadata-from-create-field-input.util.ts index 5c65c58e5a..493b6471f6 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/get-default-flat-field-metadata-from-create-field-input.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/get-default-flat-field-metadata-from-create-field-input.util.ts @@ -32,7 +32,6 @@ export const getDefaultFlatFieldMetadata = ({ description: createFieldInput.description ?? null, icon: createFieldInput.icon ?? null, isActive: true, - isCustom: true, isLabelSyncedWithName: createFieldInput.isLabelSyncedWithName ?? false, isNullable: generateNullable( createFieldInput.isNullable, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/attachment-flat-object.mock.ts b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/attachment-flat-object.mock.ts index c4b4cffd2e..8e473fbde9 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/attachment-flat-object.mock.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/attachment-flat-object.mock.ts @@ -1,8 +1,12 @@ +import { TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER } from 'twenty-shared/application'; + import { getFlatObjectMetadataMock } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/get-flat-object-metadata.mock'; export const ATTACHMENT_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({ id: '819ed5ff-312f-4423-8e95-02a691cf5c27', nameSingular: 'attachment', + applicationUniversalIdentifier: + TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER, namePlural: 'attachments', labelSingular: 'Attachment', labelPlural: 'Attachments', @@ -10,7 +14,6 @@ export const ATTACHMENT_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({ icon: 'IconFileImport', standardOverrides: null, targetTableName: 'DEPRECATED', - isCustom: false, isRemote: false, isActive: true, isSystem: true, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/company-flat-object.mock.ts b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/company-flat-object.mock.ts index 3dccfc9cab..fbeb1055a9 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/company-flat-object.mock.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/company-flat-object.mock.ts @@ -1,8 +1,12 @@ +import { TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER } from 'twenty-shared/application'; + import { getFlatObjectMetadataMock } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/get-flat-object-metadata.mock'; export const COMPANY_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({ id: '7f5c2c7a-bb23-46fb-b59d-9b7a52a8d1cc', nameSingular: 'company', + applicationUniversalIdentifier: + TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER, namePlural: 'companies', labelSingular: 'Company', labelPlural: 'Companies', @@ -10,7 +14,6 @@ export const COMPANY_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({ icon: 'IconBuildingSkyscraper', standardOverrides: null, targetTableName: 'DEPRECATED', - isCustom: false, isRemote: false, isActive: true, isSystem: false, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/get-flat-object-metadata.mock.ts b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/get-flat-object-metadata.mock.ts index c6cf6d301e..15b7e9d825 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/get-flat-object-metadata.mock.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/get-flat-object-metadata.mock.ts @@ -1,4 +1,5 @@ import { faker } from '@faker-js/faker'; +import { TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER } from 'twenty-shared/application'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; @@ -29,7 +30,6 @@ export const getFlatObjectMetadataMock = ( imageIdentifierFieldMetadataId, isActive: true, isAuditLogged: true, - isCustom: true, isLabelSyncedWithName: false, isRemote: false, isSearchable: true, @@ -67,8 +67,9 @@ export const getStandardFlatObjectMetadataMock = ( ) => { return getFlatObjectMetadataMock({ standardOverrides: {}, - isCustom: false, isSystem: true, + applicationUniversalIdentifier: + TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER, ...overrides, }); }; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/note-flat-object.mock.ts b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/note-flat-object.mock.ts index 785e366f24..67d93a76dc 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/note-flat-object.mock.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/note-flat-object.mock.ts @@ -1,8 +1,12 @@ +import { TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER } from 'twenty-shared/application'; + import { getFlatObjectMetadataMock } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/get-flat-object-metadata.mock'; export const NOTE_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({ id: '1253e3e5-5b00-4a34-93b8-02f3dc6e2b7c', nameSingular: 'note', + applicationUniversalIdentifier: + TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER, namePlural: 'notes', labelSingular: 'Note', labelPlural: 'Notes', @@ -10,7 +14,6 @@ export const NOTE_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({ icon: 'IconNotes', standardOverrides: null, targetTableName: 'DEPRECATED', - isCustom: false, isRemote: false, isActive: true, isSystem: false, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/note-target-flat-object.mock.ts b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/note-target-flat-object.mock.ts index b4ddbbcf66..8c3cb0f51c 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/note-target-flat-object.mock.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/note-target-flat-object.mock.ts @@ -1,8 +1,12 @@ +import { TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER } from 'twenty-shared/application'; + import { getFlatObjectMetadataMock } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/get-flat-object-metadata.mock'; export const NOTE_TARGET_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({ id: '12e3cb51-c3de-4192-b0d5-965d48d001c0', nameSingular: 'noteTarget', + applicationUniversalIdentifier: + TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER, namePlural: 'noteTargets', labelSingular: 'Note Target', labelPlural: 'Note Targets', @@ -10,7 +14,6 @@ export const NOTE_TARGET_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({ icon: 'IconCheckbox', standardOverrides: null, targetTableName: 'DEPRECATED', - isCustom: false, isRemote: false, isActive: true, isSystem: true, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/opportunity-flat-object.mock.ts b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/opportunity-flat-object.mock.ts index 128313d820..536710f342 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/opportunity-flat-object.mock.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/opportunity-flat-object.mock.ts @@ -1,8 +1,12 @@ +import { TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER } from 'twenty-shared/application'; + import { getFlatObjectMetadataMock } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/get-flat-object-metadata.mock'; export const OPPORTUNITY_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({ id: 'e6996bbf-dd41-423a-9324-8546f5b22fa7', nameSingular: 'opportunity', + applicationUniversalIdentifier: + TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER, namePlural: 'opportunities', labelSingular: 'Opportunity', labelPlural: 'Opportunities', @@ -10,7 +14,6 @@ export const OPPORTUNITY_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({ icon: 'IconTargetArrow', standardOverrides: null, targetTableName: 'DEPRECATED', - isCustom: false, isRemote: false, isActive: true, isSystem: false, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/person-flat-object.mock.ts b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/person-flat-object.mock.ts index 169cd19fb5..c2b81be0bf 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/person-flat-object.mock.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/person-flat-object.mock.ts @@ -1,8 +1,12 @@ +import { TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER } from 'twenty-shared/application'; + import { getFlatObjectMetadataMock } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/get-flat-object-metadata.mock'; export const PERSON_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({ id: '843e0b67-9619-4628-91c4-2fa62256a611', nameSingular: 'person', + applicationUniversalIdentifier: + TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER, namePlural: 'people', labelSingular: 'Person', labelPlural: 'People', @@ -10,7 +14,6 @@ export const PERSON_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({ icon: 'IconUser', standardOverrides: null, targetTableName: 'DEPRECATED', - isCustom: false, isRemote: false, isActive: true, isSystem: false, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/pet-flat-object.mock.ts b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/pet-flat-object.mock.ts index 78f56b91de..52031dc739 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/pet-flat-object.mock.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/pet-flat-object.mock.ts @@ -10,7 +10,6 @@ export const PET_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({ icon: 'IconCat', standardOverrides: null, targetTableName: 'DEPRECATED', - isCustom: true, isRemote: false, isActive: true, isSystem: false, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/rocket-flat-object.mock.ts b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/rocket-flat-object.mock.ts index f611ce6968..1ded249661 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/rocket-flat-object.mock.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/rocket-flat-object.mock.ts @@ -10,7 +10,6 @@ export const ROCKET_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({ icon: 'IconRocket', standardOverrides: null, targetTableName: 'DEPRECATED', - isCustom: true, isRemote: false, isActive: true, isSystem: false, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/task-flat-object.mock.ts b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/task-flat-object.mock.ts index 0b4f24cd81..b75974fa1c 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/task-flat-object.mock.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/task-flat-object.mock.ts @@ -1,8 +1,12 @@ +import { TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER } from 'twenty-shared/application'; + import { getFlatObjectMetadataMock } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/get-flat-object-metadata.mock'; export const TASK_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({ id: '3186920d-2a15-4b5f-96c7-2bf6567024b0', nameSingular: 'task', + applicationUniversalIdentifier: + TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER, namePlural: 'tasks', labelSingular: 'Task', labelPlural: 'Tasks', @@ -10,7 +14,6 @@ export const TASK_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({ icon: 'IconCheckbox', standardOverrides: null, targetTableName: 'DEPRECATED', - isCustom: false, isRemote: false, isActive: true, isSystem: false, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/task-target-flat-object.mock.ts b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/task-target-flat-object.mock.ts index df21072636..5b8b4ffd71 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/task-target-flat-object.mock.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/task-target-flat-object.mock.ts @@ -1,8 +1,12 @@ +import { TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER } from 'twenty-shared/application'; + import { getFlatObjectMetadataMock } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/get-flat-object-metadata.mock'; export const TASK_TARGET_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({ id: 'bb2b29b8-7f46-4106-a8ae-3a32df9c9166', nameSingular: 'taskTarget', + applicationUniversalIdentifier: + TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER, namePlural: 'taskTargets', labelSingular: 'Task Target', labelPlural: 'Task Targets', @@ -10,7 +14,6 @@ export const TASK_TARGET_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({ icon: 'IconCheckbox', standardOverrides: null, targetTableName: 'DEPRECATED', - isCustom: false, isRemote: false, isActive: true, isSystem: true, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/timeline-activity-flat-object.mock.ts b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/timeline-activity-flat-object.mock.ts index 3cc376703b..6b369aa2bd 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/timeline-activity-flat-object.mock.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/timeline-activity-flat-object.mock.ts @@ -1,8 +1,12 @@ +import { TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER } from 'twenty-shared/application'; + import { getFlatObjectMetadataMock } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/get-flat-object-metadata.mock'; export const TIMELINE_ACTIVITY_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({ id: '3090f830-c4b1-41a1-8e18-815760830bec', nameSingular: 'timelineActivity', + applicationUniversalIdentifier: + TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER, namePlural: 'timelineActivities', labelSingular: 'Timeline Activity', labelPlural: 'Timeline Activities', @@ -10,7 +14,6 @@ export const TIMELINE_ACTIVITY_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({ icon: 'IconTimelineEvent', standardOverrides: null, targetTableName: 'DEPRECATED', - isCustom: false, isRemote: false, isActive: true, isSystem: true, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/from-create-object-input-to-flat-object-metadata-and-flat-field-metadatas-to-create.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/from-create-object-input-to-flat-object-metadata-and-flat-field-metadatas-to-create.util.ts index bb11907d93..05e87fc87b 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/from-create-object-input-to-flat-object-metadata-and-flat-field-metadatas-to-create.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/from-create-object-input-to-flat-object-metadata-and-flat-field-metadatas-to-create.util.ts @@ -75,7 +75,6 @@ export const fromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCre icon: createObjectInput.icon ?? null, isActive: true, isAuditLogged: true, - isCustom: true, isLabelSyncedWithName: createObjectInput.isLabelSyncedWithName ?? false, isRemote: createObjectInput.isRemote ?? false, isSearchable: true, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/from-flat-object-metadata-to-object-metadata-dto.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/from-flat-object-metadata-to-object-metadata-dto.util.ts index 1f7b99db0d..d3811a703f 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/from-flat-object-metadata-to-object-metadata-dto.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/from-flat-object-metadata-to-object-metadata-dto.util.ts @@ -1,5 +1,6 @@ import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; import { type ObjectMetadataDTO } from 'src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto'; +import { belongsToTwentyStandardApp } from 'src/engine/metadata-modules/utils/belongs-to-twenty-standard-app.util'; export const fromFlatObjectMetadataToObjectMetadataDto = ( flatObjectMetadata: FlatObjectMetadata, @@ -16,7 +17,6 @@ export const fromFlatObjectMetadataToObjectMetadataDto = ( id, universalIdentifier, isActive, - isCustom, isLabelSyncedWithName, isRemote, isSearchable, @@ -36,7 +36,7 @@ export const fromFlatObjectMetadataToObjectMetadataDto = ( id, universalIdentifier, isActive, - isCustom, + isCustom: !belongsToTwentyStandardApp(flatObjectMetadata), isLabelSyncedWithName, isRemote, isSearchable, diff --git a/packages/twenty-server/src/engine/metadata-modules/index-metadata/utils/__tests__/generate-flat-index.util.spec.ts b/packages/twenty-server/src/engine/metadata-modules/index-metadata/utils/__tests__/generate-flat-index.util.spec.ts index 487cac2256..ff0cc19cb2 100644 --- a/packages/twenty-server/src/engine/metadata-modules/index-metadata/utils/__tests__/generate-flat-index.util.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/index-metadata/utils/__tests__/generate-flat-index.util.spec.ts @@ -1,3 +1,4 @@ +import { TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER } from 'twenty-shared/application'; import { FieldMetadataType, RelationType } from 'twenty-shared/types'; import { IndexType } from 'src/engine/metadata-modules/index-metadata/types/indexType.types'; @@ -15,7 +16,8 @@ describe('generateFlatIndexMetadataWithNameOrThrow', () => { const companyObject = { universalIdentifier: 'obj-company', nameSingular: 'company', - isCustom: false, + applicationUniversalIdentifier: + TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER, } as UniversalFlatObjectMetadata; const scalarUniqueField = { @@ -61,8 +63,8 @@ describe('generateFlatIndexMetadataWithNameOrThrow', () => { objectMetadataUniversalIdentifier: companyObject.universalIdentifier, indexType: overrides.indexType, indexWhereClause: overrides.indexWhereClause ?? null, - isCustom: false, isUnique: overrides.isUnique, + isCustom: false, universalFlatIndexFieldMetadatas: overrides.fieldIds.map((id, order) => ({ createdAt: now, updatedAt: now, diff --git a/packages/twenty-server/src/engine/metadata-modules/index-metadata/utils/generate-deterministic-index-name-v2.ts b/packages/twenty-server/src/engine/metadata-modules/index-metadata/utils/generate-deterministic-index-name-v2.ts index 8b8671869f..20a7b78e38 100644 --- a/packages/twenty-server/src/engine/metadata-modules/index-metadata/utils/generate-deterministic-index-name-v2.ts +++ b/packages/twenty-server/src/engine/metadata-modules/index-metadata/utils/generate-deterministic-index-name-v2.ts @@ -1,13 +1,11 @@ import { createHash } from 'crypto'; +import { belongsToTwentyStandardApp } from 'src/engine/metadata-modules/utils/belongs-to-twenty-standard-app.util'; import { type UniversalFlatObjectMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-object-metadata.type'; import { computeTableName } from 'src/engine/utils/compute-table-name.util'; type GenerateDeterministicIndexNameArgs = { - flatObjectMetadata: Pick< - UniversalFlatObjectMetadata, - 'nameSingular' | 'isCustom' - >; + flatObjectMetadata: UniversalFlatObjectMetadata; isUnique?: boolean; orderedIndexColumnNames: string[]; // Include the WHERE clause in the hash so a partial index on the same @@ -25,7 +23,7 @@ export const generateDeterministicIndexNameV2 = ({ const tableName = computeTableName( flatObjectMetadata.nameSingular, - flatObjectMetadata.isCustom, + !belongsToTwentyStandardApp(flatObjectMetadata), ); [tableName, ...orderedIndexColumnNames].forEach((column) => { diff --git a/packages/twenty-server/src/engine/metadata-modules/minimal-metadata/minimal-metadata.service.ts b/packages/twenty-server/src/engine/metadata-modules/minimal-metadata/minimal-metadata.service.ts index f1079ad693..4dfeb9ea9e 100644 --- a/packages/twenty-server/src/engine/metadata-modules/minimal-metadata/minimal-metadata.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/minimal-metadata/minimal-metadata.service.ts @@ -16,6 +16,7 @@ import { MinimalMetadataDTO } from 'src/engine/metadata-modules/minimal-metadata import { MinimalObjectMetadataDTO } from 'src/engine/metadata-modules/minimal-metadata/dtos/minimal-object-metadata.dto'; import { MinimalViewDTO } from 'src/engine/metadata-modules/minimal-metadata/dtos/minimal-view.dto'; import { resolveObjectMetadataStandardOverride } from 'src/engine/metadata-modules/object-metadata/utils/resolve-object-metadata-standard-override.util'; +import { belongsToTwentyStandardApp } from 'src/engine/metadata-modules/utils/belongs-to-twenty-standard-app.util'; import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service'; import { type WorkspaceCacheKeyName } from 'src/engine/workspace-cache/types/workspace-cache-key.type'; @@ -83,7 +84,6 @@ export class MinimalMetadataService { description: flatObjectMetadata.description ?? undefined, icon: flatObjectMetadata.icon ?? undefined, color: flatObjectMetadata.color ?? undefined, - isCustom: flatObjectMetadata.isCustom, standardOverrides: flatObjectMetadata.standardOverrides ?? undefined, }; @@ -104,7 +104,7 @@ export class MinimalMetadataService { i18nInstance, ), icon: flatObjectMetadata.icon ?? undefined, - isCustom: flatObjectMetadata.isCustom, + isCustom: !belongsToTwentyStandardApp(flatObjectMetadata), isActive: flatObjectMetadata.isActive, isSystem: flatObjectMetadata.isSystem, isRemote: flatObjectMetadata.isRemote, diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/constants/partial-system-flat-field-metadatas.constant.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/constants/partial-system-flat-field-metadatas.constant.ts index 8103e7b5de..9be66768f4 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/constants/partial-system-flat-field-metadatas.constant.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/constants/partial-system-flat-field-metadatas.constant.ts @@ -22,7 +22,6 @@ const PARTIAL_ID_FIELD = { isNullable: false, isUnique: true, isActive: true, - isCustom: false, isSystem: true, isUIReadOnly: true, isLabelSyncedWithName: false, @@ -51,7 +50,6 @@ const PARTIAL_CREATED_AT_FIELD = { isNullable: false, isUnique: false, isActive: true, - isCustom: false, isSystem: true, isUIReadOnly: true, isLabelSyncedWithName: false, @@ -80,7 +78,6 @@ const PARTIAL_UPDATED_AT_FIELD = { isNullable: false, isUnique: false, isActive: true, - isCustom: false, isSystem: true, isUIReadOnly: true, isLabelSyncedWithName: false, @@ -109,7 +106,6 @@ const PARTIAL_DELETED_AT_FIELD = { isNullable: true, isUnique: false, isActive: true, - isCustom: false, isSystem: true, isUIReadOnly: true, isLabelSyncedWithName: false, @@ -138,7 +134,6 @@ const PARTIAL_CREATED_BY_FIELD = { isNullable: false, isUnique: false, isActive: true, - isCustom: false, isSystem: true, isUIReadOnly: true, isLabelSyncedWithName: false, @@ -167,7 +162,6 @@ const PARTIAL_UPDATED_BY_FIELD = { isNullable: false, isUnique: false, isActive: true, - isCustom: false, isSystem: true, isUIReadOnly: true, isLabelSyncedWithName: false, @@ -196,7 +190,6 @@ const PARTIAL_POSITION_FIELD = { isNullable: false, isUnique: false, isActive: true, - isCustom: false, isSystem: true, isUIReadOnly: true, isLabelSyncedWithName: false, @@ -225,7 +218,6 @@ const PARTIAL_SEARCH_VECTOR_FIELD = { isNullable: true, isUnique: false, isActive: true, - isCustom: false, isSystem: true, isUIReadOnly: true, isLabelSyncedWithName: false, diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/controllers/object-metadata.controller.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/controllers/object-metadata.controller.ts index 72d67f9da5..99762f3f74 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/controllers/object-metadata.controller.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/controllers/object-metadata.controller.ts @@ -16,9 +16,9 @@ import { } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; -import { In, Repository } from 'typeorm'; import { PermissionFlagType } from 'twenty-shared/constants'; import { FeatureFlagKey } from 'twenty-shared/types'; +import { In, Repository } from 'typeorm'; import { parseEndingBeforeRestRequest } from 'src/engine/api/rest/input-request-parsers/ending-before-parser-utils/parse-ending-before-rest-request.util'; import { parseLimitRestRequest } from 'src/engine/api/rest/input-request-parsers/limit-parser-utils/parse-limit-rest-request.util'; @@ -28,6 +28,7 @@ import { type RestCursorPageInfo, } from 'src/engine/api/rest/metadata/utils/paginate-by-id-cursor.util'; import { type AuthenticatedRequest } from 'src/engine/api/rest/types/authenticated-request'; +import { ApplicationRestApiExceptionFilter } from 'src/engine/core-modules/application/application-rest-api-exception.filter'; import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; @@ -37,8 +38,8 @@ import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { fromFieldMetadataEntityToFieldMetadataDto } from 'src/engine/metadata-modules/field-metadata/utils/from-field-metadata-entity-to-field-metadata-dto.util'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; -import { computeUniqueFieldMetadataIdsFromFlatIndexMaps } from 'src/engine/metadata-modules/index-metadata/utils/compute-unique-field-metadata-ids-from-flat-index-maps.util'; import { fromFlatObjectMetadataToObjectMetadataDto } from 'src/engine/metadata-modules/flat-object-metadata/utils/from-flat-object-metadata-to-object-metadata-dto.util'; +import { computeUniqueFieldMetadataIdsFromFlatIndexMaps } from 'src/engine/metadata-modules/index-metadata/utils/compute-unique-field-metadata-ids-from-flat-index-maps.util'; import { CreateObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/create-object.input'; import { type ObjectMetadataWithFieldsDTO } from 'src/engine/metadata-modules/object-metadata/dtos/object-metadata-with-fields.dto'; import { UpdateObjectPayload } from 'src/engine/metadata-modules/object-metadata/dtos/update-object.input'; @@ -58,6 +59,7 @@ import { toLegacyObjectMetadataUpdateResponse, } from 'src/engine/metadata-modules/object-metadata/utils/to-legacy-object-metadata-response.util'; import { PermissionsRestApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-rest-api-exception.filter'; +import { getTwentyStandardApplicationIdOrThrow } from 'src/engine/metadata-modules/utils/get-twenty-standard-application-id-or-throw.util'; @Controller('rest/metadata/objects') @UseGuards( @@ -68,6 +70,7 @@ import { PermissionsRestApiExceptionFilter } from 'src/engine/metadata-modules/p @UseFilters( PermissionsRestApiExceptionFilter, ObjectMetadataRestApiExceptionFilter, + ApplicationRestApiExceptionFilter, ) @UsePipes(new ValidationPipe()) export class ObjectMetadataController { @@ -92,6 +95,17 @@ export class ObjectMetadataController { return computeUniqueFieldMetadataIdsFromFlatIndexMaps(flatIndexMaps); } + private async loadStandardApplicationId( + workspaceId: string, + ): Promise { + const { flatApplicationMaps } = + await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( + { workspaceId, flatMapsKeys: ['flatApplicationMaps'] }, + ); + + return getTwentyStandardApplicationIdOrThrow(flatApplicationMaps); + } + @Get() async findMany( @Req() request: AuthenticatedRequest, @@ -105,19 +119,22 @@ export class ObjectMetadataController { endingBefore: parseEndingBeforeRestRequest(request), }); - const [fields, uniqueFieldMetadataIds] = await Promise.all([ - this.findFieldsForObjectIds( - workspaceId, - items.map((object) => object.id), - ), - this.loadUniqueFieldMetadataIds(workspaceId), - ]); + const [fields, uniqueFieldMetadataIds, standardApplicationId] = + await Promise.all([ + this.findFieldsForObjectIds( + workspaceId, + items.map((object) => object.id), + ), + this.loadUniqueFieldMetadataIds(workspaceId), + this.loadStandardApplicationId(workspaceId), + ]); const data = items.map((object) => this.toObjectWithFieldsDto( object, fields.get(object.id) ?? [], uniqueFieldMetadataIds, + standardApplicationId, ), ); @@ -148,17 +165,20 @@ export class ObjectMetadataController { ); } - const [fields, uniqueFieldMetadataIds] = await Promise.all([ - this.fieldMetadataRepository.find({ - where: { objectMetadataId: object.id, workspaceId }, - }), - this.loadUniqueFieldMetadataIds(workspaceId), - ]); + const [fields, uniqueFieldMetadataIds, standardApplicationId] = + await Promise.all([ + this.fieldMetadataRepository.find({ + where: { objectMetadataId: object.id, workspaceId }, + }), + this.loadUniqueFieldMetadataIds(workspaceId), + this.loadStandardApplicationId(workspaceId), + ]); const result = this.toObjectWithFieldsDto( object, fields, uniqueFieldMetadataIds, + standardApplicationId, ); return (await this.isNewMetadataFormat(workspaceId)) @@ -176,18 +196,21 @@ export class ObjectMetadataController { workspaceId, }); - const [fields, uniqueFieldMetadataIds] = await Promise.all([ - this.fieldMetadataRepository.find({ - where: { objectMetadataId: flatObject.id, workspaceId }, - }), - this.loadUniqueFieldMetadataIds(workspaceId), - ]); + const [fields, uniqueFieldMetadataIds, standardApplicationId] = + await Promise.all([ + this.fieldMetadataRepository.find({ + where: { objectMetadataId: flatObject.id, workspaceId }, + }), + this.loadUniqueFieldMetadataIds(workspaceId), + this.loadStandardApplicationId(workspaceId), + ]); const result: ObjectMetadataWithFieldsDTO = { ...fromFlatObjectMetadataToObjectMetadataDto(flatObject), fields: fields.map((field) => fromFieldMetadataEntityToFieldMetadataDto( field, + standardApplicationId, uniqueFieldMetadataIds, ), ), @@ -247,18 +270,21 @@ export class ObjectMetadataController { workspaceId, }); - const [fields, uniqueFieldMetadataIds] = await Promise.all([ - this.fieldMetadataRepository.find({ - where: { objectMetadataId: flatObject.id, workspaceId }, - }), - this.loadUniqueFieldMetadataIds(workspaceId), - ]); + const [fields, uniqueFieldMetadataIds, standardApplicationId] = + await Promise.all([ + this.fieldMetadataRepository.find({ + where: { objectMetadataId: flatObject.id, workspaceId }, + }), + this.loadUniqueFieldMetadataIds(workspaceId), + this.loadStandardApplicationId(workspaceId), + ]); const result: ObjectMetadataWithFieldsDTO = { ...fromFlatObjectMetadataToObjectMetadataDto(flatObject), fields: fields.map((field) => fromFieldMetadataEntityToFieldMetadataDto( field, + standardApplicationId, uniqueFieldMetadataIds, ), ), @@ -307,12 +333,17 @@ export class ObjectMetadataController { object: ObjectMetadataEntity, fields: FieldMetadataEntity[], uniqueFieldMetadataIds: ReadonlySet, + standardApplicationId: string, ): ObjectMetadataWithFieldsDTO { return { - ...fromObjectMetadataEntityToObjectMetadataDto(object), + ...fromObjectMetadataEntityToObjectMetadataDto( + object, + standardApplicationId, + ), fields: fields.map((field) => fromFieldMetadataEntityToFieldMetadataDto( field, + standardApplicationId, uniqueFieldMetadataIds, ), ), diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto.ts index c535a6cb35..98b000f03c 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto.ts @@ -62,7 +62,10 @@ export class ObjectMetadataDTO { @Field({ nullable: true }) color?: string; - @FilterableField() + @Field({ + deprecationReason: + 'isCustom is derived from the owning application and will be removed; an object is custom when it does not belong to the twenty-standard application.', + }) isCustom: boolean; @FilterableField() diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.entity.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.entity.ts index 86ca3f3b1f..a00ec6d7c8 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.entity.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.entity.ts @@ -16,6 +16,7 @@ import { type ObjectStandardOverridesDTO } from 'src/engine/metadata-modules/obj import { FieldPermissionEntity } from 'src/engine/metadata-modules/object-permission/field-permission/field-permission.entity'; import { ObjectPermissionEntity } from 'src/engine/metadata-modules/object-permission/object-permission.entity'; import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity'; +import { WasRemovedInUpgrade } from 'src/engine/core-modules/upgrade/decorators/was-removed-in-upgrade.decorator'; import { SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface'; import { type JsonbProperty } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/jsonb-property.type'; @@ -69,8 +70,12 @@ export class ObjectMetadataEntity @Column({ nullable: false }) targetTableName: string; - @Column({ default: false }) - isCustom: boolean; + @WasRemovedInUpgrade({ + upgradeCommandName: + '2.12.0_DropIsCustomFromObjectAndFieldMetadataFastInstanceCommand_1780579070012', + }) + @Column({ type: 'boolean', default: false }) + isCustom: WasRemovedInUpgrade; @Column({ default: false }) isRemote: boolean; diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.module.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.module.ts index 5bed45928a..581ea9bb59 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.module.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.module.ts @@ -45,6 +45,7 @@ import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace TokenModule, WorkspaceCacheStorageModule, FeatureFlagModule, + ApplicationModule, NestjsQueryGraphQLModule.forFeature({ imports: [ TypeORMModule, diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.resolver.ts index cc2a1d115a..f5e9be16eb 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.resolver.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.resolver.ts @@ -48,6 +48,21 @@ export class ObjectMetadataResolver { private readonly i18nService: I18nService, ) {} + @ResolveField(() => Boolean, { + deprecationReason: + 'isCustom is derived from the owning application and will be removed; an object is custom when it does not belong to the twenty-standard application.', + }) + async isCustom( + @Parent() objectMetadata: ObjectMetadataDTO, + @AuthWorkspace() { id: workspaceId }: WorkspaceEntity, + @Context() context: { loaders: IDataloaders }, + ): Promise { + return context.loaders.isCustomLoader.load({ + workspaceId, + applicationId: objectMetadata.applicationId, + }); + } + @UseGuards(SettingsPermissionGuard(PermissionFlagType.DATA_MODEL)) @Query(() => [ObjectRecordCountDTO]) async objectRecordCounts( diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-record-count.service.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-record-count.service.ts index 68e05e3a71..2dad95f33f 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-record-count.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-record-count.service.ts @@ -5,7 +5,7 @@ import { isDefined } from 'twenty-shared/utils'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; import { type ObjectRecordCountDTO } from 'src/engine/metadata-modules/object-metadata/dtos/object-record-count.dto'; import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; -import { computeTableName } from 'src/engine/utils/compute-table-name.util'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; import { getWorkspaceSchemaName } from 'src/engine/workspace-datasource/utils/get-workspace-schema-name.util'; @Injectable() @@ -57,12 +57,7 @@ export class ObjectRecordCountService { return flatObjectMetadatas.map((flatObjectMetadata) => ({ objectNamePlural: flatObjectMetadata.namePlural, totalCount: - countByTableName.get( - computeTableName( - flatObjectMetadata.nameSingular, - flatObjectMetadata.isCustom, - ), - ) ?? 0, + countByTableName.get(computeObjectTargetTable(flatObjectMetadata)) ?? 0, })); } } diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/__tests__/compute-flat-view-fields-to-create.util.spec.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/__tests__/compute-flat-view-fields-to-create.util.spec.ts index 269cc190b1..c86d84be51 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/__tests__/compute-flat-view-fields-to-create.util.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/__tests__/compute-flat-view-fields-to-create.util.spec.ts @@ -20,7 +20,6 @@ const makeFieldMetadata = ( name: overrides.name, label: overrides.label ?? overrides.name, type: overrides.type, - isCustom: overrides.isCustom ?? false, isActive: true, isSystem: false, isUIReadOnly: false, diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/__tests__/resolve-object-metadata-standard-override.util.spec.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/__tests__/resolve-object-metadata-standard-override.util.spec.ts index 745d13a262..16e237fc09 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/__tests__/resolve-object-metadata-standard-override.util.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/__tests__/resolve-object-metadata-standard-override.util.spec.ts @@ -29,7 +29,6 @@ describe('resolveObjectMetadataStandardOverride', () => { description: 'Custom Description', icon: 'custom-icon', color: 'blue', - isCustom: true, standardOverrides: undefined, } satisfies Pick< ObjectMetadataDTO, @@ -38,7 +37,6 @@ describe('resolveObjectMetadataStandardOverride', () => { | 'labelSingular' | 'description' | 'icon' - | 'isCustom' | 'standardOverrides' >; @@ -59,7 +57,6 @@ describe('resolveObjectMetadataStandardOverride', () => { description: 'Custom Description', icon: 'custom-icon', color: 'blue', - isCustom: true, standardOverrides: undefined, } satisfies Pick< ObjectMetadataDTO, @@ -68,7 +65,6 @@ describe('resolveObjectMetadataStandardOverride', () => { | 'labelSingular' | 'description' | 'icon' - | 'isCustom' | 'standardOverrides' >; @@ -89,7 +85,6 @@ describe('resolveObjectMetadataStandardOverride', () => { description: 'Custom Description', icon: 'custom-icon', color: 'blue', - isCustom: true, standardOverrides: undefined, } satisfies Pick< ObjectMetadataDTO, @@ -98,7 +93,6 @@ describe('resolveObjectMetadataStandardOverride', () => { | 'labelSingular' | 'description' | 'icon' - | 'isCustom' | 'standardOverrides' >; @@ -119,7 +113,6 @@ describe('resolveObjectMetadataStandardOverride', () => { description: 'Custom Description', icon: 'custom-icon', color: 'green', - isCustom: true, standardOverrides: undefined, } satisfies Pick< ObjectMetadataDTO, @@ -128,7 +121,6 @@ describe('resolveObjectMetadataStandardOverride', () => { | 'labelSingular' | 'description' | 'icon' - | 'isCustom' | 'standardOverrides' >; @@ -150,7 +142,6 @@ describe('resolveObjectMetadataStandardOverride', () => { labelPlural: 'My Customs', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: { icon: 'override-icon', }, @@ -175,7 +166,6 @@ describe('resolveObjectMetadataStandardOverride', () => { description: 'Standard Description', icon: 'default-icon', color: 'blue', - isCustom: false, standardOverrides: { color: 'red', }, @@ -198,7 +188,6 @@ describe('resolveObjectMetadataStandardOverride', () => { description: 'Standard Description', icon: 'default-icon', color: 'blue', - isCustom: false, standardOverrides: undefined, }; @@ -223,7 +212,6 @@ describe('resolveObjectMetadataStandardOverride', () => { labelPlural: 'Standard Labels', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: { translations: { 'fr-FR': { @@ -267,7 +255,6 @@ describe('resolveObjectMetadataStandardOverride', () => { labelPlural: 'Standard Labels', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: { translations: { 'es-ES': { @@ -298,7 +285,6 @@ describe('resolveObjectMetadataStandardOverride', () => { labelPlural: 'Standard Labels', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: { translations: { 'fr-FR': { @@ -328,7 +314,6 @@ describe('resolveObjectMetadataStandardOverride', () => { labelPlural: 'Standard Labels', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: { translations: { 'fr-FR': { @@ -361,7 +346,6 @@ describe('resolveObjectMetadataStandardOverride', () => { labelPlural: 'Standard Labels', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: { labelSingular: 'Overridden Label', labelPlural: 'Overridden Labels', @@ -410,7 +394,6 @@ describe('resolveObjectMetadataStandardOverride', () => { labelPlural: 'Standard Labels', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: { labelSingular: 'Overridden Label', labelPlural: 'Overridden Labels', @@ -433,7 +416,6 @@ describe('resolveObjectMetadataStandardOverride', () => { labelPlural: 'Standard Labels', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: { labelSingular: undefined, }, @@ -460,7 +442,6 @@ describe('resolveObjectMetadataStandardOverride', () => { labelPlural: 'Standard Labels', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: undefined, }; @@ -485,7 +466,6 @@ describe('resolveObjectMetadataStandardOverride', () => { labelPlural: 'Standard Labels', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: undefined, }; @@ -512,7 +492,6 @@ describe('resolveObjectMetadataStandardOverride', () => { labelPlural: 'Standard Labels', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: { labelSingular: 'Source Override', labelPlural: 'Source Overrides', @@ -543,7 +522,6 @@ describe('resolveObjectMetadataStandardOverride', () => { labelPlural: 'Standard Labels', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: { labelSingular: 'Source Override', labelPlural: 'Source Overrides', @@ -568,7 +546,6 @@ describe('resolveObjectMetadataStandardOverride', () => { labelPlural: 'Standard Labels', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: {}, }; @@ -595,7 +572,6 @@ describe('resolveObjectMetadataStandardOverride', () => { labelPlural: 'Standard Labels', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: { labelSingular: 'Source Override', }, @@ -622,7 +598,6 @@ describe('resolveObjectMetadataStandardOverride', () => { labelPlural: 'Standard Labels', description: 'Standard Description', icon: 'default-icon', - isCustom: false, standardOverrides: undefined, }; diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/build-default-flat-field-metadatas-for-custom-object.util.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/build-default-flat-field-metadatas-for-custom-object.util.ts index 84bbc6c3d3..ca37de5314 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/build-default-flat-field-metadatas-for-custom-object.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/build-default-flat-field-metadatas-for-custom-object.util.ts @@ -133,7 +133,6 @@ export const buildDefaultFlatFieldMetadatasForCustomObject = ({ description: 'Name', isNullable: true, isActive: true, - isCustom: false, isSystem: false, isUIReadOnly: false, defaultValue: null, diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/from-object-metadata-entity-to-object-metadata-dto.util.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/from-object-metadata-entity-to-object-metadata-dto.util.ts index 6ef0228bb2..eeacf3f3ec 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/from-object-metadata-entity-to-object-metadata-dto.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/from-object-metadata-entity-to-object-metadata-dto.util.ts @@ -3,6 +3,7 @@ import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-me export const fromObjectMetadataEntityToObjectMetadataDto = ( entity: ObjectMetadataEntity, + standardApplicationId: string, ): ObjectMetadataDTO => ({ id: entity.id, universalIdentifier: entity.universalIdentifier, @@ -16,7 +17,7 @@ export const fromObjectMetadataEntityToObjectMetadataDto = ( color: entity.color ?? undefined, shortcut: entity.shortcut ?? undefined, standardOverrides: entity.standardOverrides ?? undefined, - isCustom: entity.isCustom, + isCustom: entity.applicationId !== standardApplicationId, isRemote: entity.isRemote, isActive: entity.isActive, isSystem: entity.isSystem, diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/resolve-object-metadata-standard-override.util.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/resolve-object-metadata-standard-override.util.ts index 22440b5c68..4d0633acb3 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/resolve-object-metadata-standard-override.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/resolve-object-metadata-standard-override.util.ts @@ -14,7 +14,6 @@ export const resolveObjectMetadataStandardOverride = ( | 'labelSingular' | 'description' | 'icon' - | 'isCustom' | 'standardOverrides' >, labelKey: 'color' | 'labelPlural' | 'labelSingular' | 'description' | 'icon', @@ -23,10 +22,6 @@ export const resolveObjectMetadataStandardOverride = ( ): string => { const safeLocale = locale ?? SOURCE_LOCALE; - if (objectMetadata.isCustom) { - return objectMetadata[labelKey] ?? ''; - } - if ( (labelKey === 'icon' || labelKey === 'color') && isDefined(objectMetadata.standardOverrides?.[labelKey]) diff --git a/packages/twenty-server/src/engine/metadata-modules/utils/get-twenty-standard-application-id-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/utils/get-twenty-standard-application-id-or-throw.util.ts new file mode 100644 index 0000000000..ec5f5557a8 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/utils/get-twenty-standard-application-id-or-throw.util.ts @@ -0,0 +1,26 @@ +import { TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER } from 'twenty-shared/application'; +import { isDefined } from 'twenty-shared/utils'; + +import { + ApplicationException, + ApplicationExceptionCode, +} from 'src/engine/core-modules/application/application.exception'; +import { type FlatApplicationCacheMaps } from 'src/engine/core-modules/application/types/flat-application-cache-maps.type'; + +export const getTwentyStandardApplicationIdOrThrow = ( + flatApplicationMaps: FlatApplicationCacheMaps, +): string => { + const twentyStandardApplicationId = + flatApplicationMaps.idByUniversalIdentifier[ + TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER + ]; + + if (!isDefined(twentyStandardApplicationId)) { + throw new ApplicationException( + 'Could not find the twenty-standard application in the workspace cache', + ApplicationExceptionCode.APPLICATION_NOT_FOUND, + ); + } + + return twentyStandardApplicationId; +}; diff --git a/packages/twenty-server/src/engine/metadata-modules/view/controllers/view.controller.ts b/packages/twenty-server/src/engine/metadata-modules/view/controllers/view.controller.ts index eb71df7b81..82090117d8 100644 --- a/packages/twenty-server/src/engine/metadata-modules/view/controllers/view.controller.ts +++ b/packages/twenty-server/src/engine/metadata-modules/view/controllers/view.controller.ts @@ -216,7 +216,6 @@ export class ViewController { labelSingular: objectMetadata.labelSingular, description: objectMetadata.description ?? undefined, icon: objectMetadata.icon ?? undefined, - isCustom: objectMetadata.isCustom, standardOverrides: objectMetadata.standardOverrides ?? undefined, }, 'labelPlural', diff --git a/packages/twenty-server/src/engine/metadata-modules/view/resolvers/view.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/view/resolvers/view.resolver.ts index 7b14881248..6a77cd3ffc 100644 --- a/packages/twenty-server/src/engine/metadata-modules/view/resolvers/view.resolver.ts +++ b/packages/twenty-server/src/engine/metadata-modules/view/resolvers/view.resolver.ts @@ -74,7 +74,6 @@ export class ViewResolver { labelSingular: objectMetadata.labelSingular, description: objectMetadata.description ?? undefined, icon: objectMetadata.icon ?? undefined, - isCustom: objectMetadata.isCustom, standardOverrides: objectMetadata.standardOverrides ?? undefined, }, 'labelPlural', diff --git a/packages/twenty-server/src/engine/metadata-modules/webhook/utils/__tests__/transform-event-batch-to-webhook-events.spec.ts b/packages/twenty-server/src/engine/metadata-modules/webhook/utils/__tests__/transform-event-batch-to-webhook-events.spec.ts index c6d30b44ed..c59b694e43 100644 --- a/packages/twenty-server/src/engine/metadata-modules/webhook/utils/__tests__/transform-event-batch-to-webhook-events.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/webhook/utils/__tests__/transform-event-batch-to-webhook-events.spec.ts @@ -12,7 +12,6 @@ const mockObjectMetadata: FlatObjectMetadata = { workspaceId: 'workspaceId', labelSingular: 'Label Singular', labelPlural: 'Label Plural', - isCustom: false, isRemote: false, isActive: true, isSystem: false, diff --git a/packages/twenty-server/src/engine/subscriptions/metadata-event/utils/__tests__/enrich-command-menu-item-event-with-resolved-navigation.util.spec.ts b/packages/twenty-server/src/engine/subscriptions/metadata-event/utils/__tests__/enrich-command-menu-item-event-with-resolved-navigation.util.spec.ts index a056180785..b6817cade5 100644 --- a/packages/twenty-server/src/engine/subscriptions/metadata-event/utils/__tests__/enrich-command-menu-item-event-with-resolved-navigation.util.spec.ts +++ b/packages/twenty-server/src/engine/subscriptions/metadata-event/utils/__tests__/enrich-command-menu-item-event-with-resolved-navigation.util.spec.ts @@ -29,7 +29,6 @@ const makeFlatObjectMetadata = ( labelPlural: 'People', labelSingular: 'Person', icon: 'IconUser', - isCustom: false, standardOverrides: null, ...overrides, }) as unknown as FlatObjectMetadata; 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 545bdddefc..a0f6bf1710 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 @@ -101,7 +101,6 @@ describe('WorkspaceEntityManager', () => { workspaceId: 'test-workspace-id', icon: 'test-icon', color: null, - isCustom: false, isRemote: false, isAuditLogged: false, isSearchable: false, @@ -154,7 +153,6 @@ describe('WorkspaceEntityManager', () => { description: null, icon: null, isActive: true, - isCustom: false, isSystem: false, isUIReadOnly: false, isUnique: false, diff --git a/packages/twenty-server/src/engine/twenty-orm/global-workspace-datasource/global-workspace-datasource.module.ts b/packages/twenty-server/src/engine/twenty-orm/global-workspace-datasource/global-workspace-datasource.module.ts index 3b64e3050c..6d941fcc76 100644 --- a/packages/twenty-server/src/engine/twenty-orm/global-workspace-datasource/global-workspace-datasource.module.ts +++ b/packages/twenty-server/src/engine/twenty-orm/global-workspace-datasource/global-workspace-datasource.module.ts @@ -1,6 +1,7 @@ import { Global, Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; +import { ApplicationEntity } from 'src/engine/core-modules/application/application.entity'; import { TwentyConfigModule } from 'src/engine/core-modules/twenty-config/twenty-config.module'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; @@ -25,6 +26,7 @@ import { WorkspaceEventEmitterModule } from 'src/engine/workspace-event-emitter/ WorkspaceEntity, ObjectMetadataEntity, FieldMetadataEntity, + ApplicationEntity, ]), WorkspaceCacheStorageModule, WorkspaceManyOrAllFlatEntityMapsCacheModule, diff --git a/packages/twenty-server/src/engine/twenty-orm/global-workspace-datasource/types/entity-schema-metadata.type.ts b/packages/twenty-server/src/engine/twenty-orm/global-workspace-datasource/types/entity-schema-metadata.type.ts index 7d724fe791..5e99064142 100644 --- a/packages/twenty-server/src/engine/twenty-orm/global-workspace-datasource/types/entity-schema-metadata.type.ts +++ b/packages/twenty-server/src/engine/twenty-orm/global-workspace-datasource/types/entity-schema-metadata.type.ts @@ -5,8 +5,9 @@ import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-me export type EntitySchemaObjectMetadata = Pick< ObjectMetadataEntity, - 'id' | 'nameSingular' | 'isCustom' + 'id' | 'nameSingular' > & { + isCustom: boolean; fieldIds: string[]; }; @@ -38,6 +39,7 @@ export type EntitySchemaFieldMetadataMaps = { export const buildEntitySchemaMetadataMaps = ( objectMetadatas: ObjectMetadataEntity[], fieldMetadatas: FieldMetadataEntity[], + standardApplicationId: string | undefined, ): { objectMetadataMaps: EntitySchemaObjectMetadataMaps; fieldMetadataMaps: EntitySchemaFieldMetadataMaps; @@ -60,7 +62,7 @@ export const buildEntitySchemaMetadataMaps = ( objectMetadataMaps.byId[object.id] = { id: object.id, nameSingular: object.nameSingular, - isCustom: object.isCustom, + isCustom: object.applicationId !== standardApplicationId, fieldIds: fieldIdsByObjectId.get(object.id) ?? [], }; } diff --git a/packages/twenty-server/src/engine/twenty-orm/global-workspace-datasource/workspace-orm-entity-metadatas-cache.service.ts b/packages/twenty-server/src/engine/twenty-orm/global-workspace-datasource/workspace-orm-entity-metadatas-cache.service.ts index 39024fb3a8..b900895801 100644 --- a/packages/twenty-server/src/engine/twenty-orm/global-workspace-datasource/workspace-orm-entity-metadatas-cache.service.ts +++ b/packages/twenty-server/src/engine/twenty-orm/global-workspace-datasource/workspace-orm-entity-metadatas-cache.service.ts @@ -1,6 +1,7 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; +import { TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER } from 'twenty-shared/application'; import { isDefined } from 'twenty-shared/utils'; import { type EntityMetadata, EntitySchema, Repository } from 'typeorm'; import { EntitySchemaTransformer } from 'typeorm/entity-schema/EntitySchemaTransformer'; @@ -8,6 +9,7 @@ import { EntityMetadataBuilder } from 'typeorm/metadata-builder/EntityMetadataBu import { WorkspaceCacheProvider } from 'src/engine/workspace-cache/interfaces/workspace-cache-provider.service'; +import { ApplicationEntity } from 'src/engine/core-modules/application/application.entity'; import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { EntitySchemaFactory } from 'src/engine/twenty-orm/factories/entity-schema.factory'; @@ -25,6 +27,8 @@ export class WorkspaceORMEntityMetadatasCacheService extends WorkspaceCacheProvi private readonly objectMetadataRepository: Repository, @InjectRepository(FieldMetadataEntity) private readonly fieldMetadataRepository: Repository, + @InjectRepository(ApplicationEntity) + private readonly applicationRepository: Repository, private readonly entitySchemaFactory: EntitySchemaFactory, private readonly globalWorkspaceOrmManager: GlobalWorkspaceOrmManager, ) { @@ -32,19 +36,31 @@ export class WorkspaceORMEntityMetadatasCacheService extends WorkspaceCacheProvi } async computeForCache(workspaceId: string): Promise { - const [objectMetadatas, fieldMetadatas] = await Promise.all([ - this.objectMetadataRepository.find({ - where: { workspaceId }, - withDeleted: true, - }), - this.fieldMetadataRepository.find({ - where: { workspaceId }, - withDeleted: true, - }), - ]); + const [objectMetadatas, fieldMetadatas, twentyStandardApplication] = + await Promise.all([ + this.objectMetadataRepository.find({ + where: { workspaceId }, + withDeleted: true, + }), + this.fieldMetadataRepository.find({ + where: { workspaceId }, + withDeleted: true, + }), + this.applicationRepository.findOne({ + where: { + workspaceId, + universalIdentifier: + TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER, + }, + }), + ]); const { objectMetadataMaps, fieldMetadataMaps } = - buildEntitySchemaMetadataMaps(objectMetadatas, fieldMetadatas); + buildEntitySchemaMetadataMaps( + objectMetadatas, + fieldMetadatas, + twentyStandardApplication?.id, + ); const entitySchemas = Object.values(objectMetadataMaps.byId) .filter(isDefined) diff --git a/packages/twenty-server/src/engine/twenty-orm/repository/__tests__/workspace.repository.spec.ts b/packages/twenty-server/src/engine/twenty-orm/repository/__tests__/workspace.repository.spec.ts index d95b532f99..f6e92f29bf 100644 --- a/packages/twenty-server/src/engine/twenty-orm/repository/__tests__/workspace.repository.spec.ts +++ b/packages/twenty-server/src/engine/twenty-orm/repository/__tests__/workspace.repository.spec.ts @@ -73,7 +73,6 @@ describe('WorkspaceRepository', () => { isNullable: false, isUnique: true, isSystem: true, - isCustom: false, isUIReadOnly: false, isLabelSyncedWithName: false, label: 'ID', diff --git a/packages/twenty-server/src/engine/twenty-orm/repository/workspace-delete-query-builder.ts b/packages/twenty-server/src/engine/twenty-orm/repository/workspace-delete-query-builder.ts index a3030580d6..0bf625f0b1 100644 --- a/packages/twenty-server/src/engine/twenty-orm/repository/workspace-delete-query-builder.ts +++ b/packages/twenty-server/src/engine/twenty-orm/repository/workspace-delete-query-builder.ts @@ -30,7 +30,7 @@ import { computeEventSelectQueryBuilder } from 'src/engine/twenty-orm/utils/comp import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; import { formatTwentyOrmEventToDatabaseBatchEvent } from 'src/engine/twenty-orm/utils/format-twenty-orm-event-to-database-batch-event.util'; import { getObjectMetadataFromEntityTarget } from 'src/engine/twenty-orm/utils/get-object-metadata-from-entity-target.util'; -import { computeTableName } from 'src/engine/utils/compute-table-name.util'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; export class WorkspaceDeleteQueryBuilder< T extends ObjectLiteral, @@ -99,10 +99,7 @@ export class WorkspaceDeleteQueryBuilder< objectRecordsPermissions: this.objectRecordsPermissions, }); - const tableName = computeTableName( - objectMetadata.nameSingular, - objectMetadata.isCustom, - ); + const tableName = computeObjectTargetTable(objectMetadata); const before = await eventSelectQueryBuilder.getOne({ noFormatting: true, diff --git a/packages/twenty-server/src/engine/twenty-orm/repository/workspace-soft-delete-query-builder.ts b/packages/twenty-server/src/engine/twenty-orm/repository/workspace-soft-delete-query-builder.ts index 5e7acd15a7..30e4c95e4e 100644 --- a/packages/twenty-server/src/engine/twenty-orm/repository/workspace-soft-delete-query-builder.ts +++ b/packages/twenty-server/src/engine/twenty-orm/repository/workspace-soft-delete-query-builder.ts @@ -28,7 +28,7 @@ import { computeEventSelectQueryBuilder } from 'src/engine/twenty-orm/utils/comp import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; import { formatTwentyOrmEventToDatabaseBatchEvent } from 'src/engine/twenty-orm/utils/format-twenty-orm-event-to-database-batch-event.util'; import { getObjectMetadataFromEntityTarget } from 'src/engine/twenty-orm/utils/get-object-metadata-from-entity-target.util'; -import { computeTableName } from 'src/engine/utils/compute-table-name.util'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; export class WorkspaceSoftDeleteQueryBuilder< T extends ObjectLiteral, @@ -98,10 +98,7 @@ export class WorkspaceSoftDeleteQueryBuilder< objectRecordsPermissions: this.objectRecordsPermissions, }); - const tableName = computeTableName( - objectMetadata.nameSingular, - objectMetadata.isCustom, - ); + const tableName = computeObjectTargetTable(objectMetadata); const before = await beforeEventSelectQueryBuilder.getMany({ noFormatting: true, diff --git a/packages/twenty-server/src/engine/twenty-orm/repository/workspace-update-query-builder.ts b/packages/twenty-server/src/engine/twenty-orm/repository/workspace-update-query-builder.ts index e205353275..5013f81b44 100644 --- a/packages/twenty-server/src/engine/twenty-orm/repository/workspace-update-query-builder.ts +++ b/packages/twenty-server/src/engine/twenty-orm/repository/workspace-update-query-builder.ts @@ -39,7 +39,7 @@ import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; import { formatTwentyOrmEventToDatabaseBatchEvent } from 'src/engine/twenty-orm/utils/format-twenty-orm-event-to-database-batch-event.util'; import { getObjectMetadataFromEntityTarget } from 'src/engine/twenty-orm/utils/get-object-metadata-from-entity-target.util'; import { validateRLSPredicatesForRecords } from 'src/engine/twenty-orm/utils/validate-rls-predicates-for-records.util'; -import { computeTableName } from 'src/engine/utils/compute-table-name.util'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; export class WorkspaceUpdateQueryBuilder< T extends ObjectLiteral, @@ -131,10 +131,7 @@ export class WorkspaceUpdateQueryBuilder< objectRecordsPermissions: this.objectRecordsPermissions, }); - const tableName = computeTableName( - objectMetadata.nameSingular, - objectMetadata.isCustom, - ); + const tableName = computeObjectTargetTable(objectMetadata); const before = await eventSelectQueryBuilder.getMany({ noFormatting: true, diff --git a/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/compute-relation-connect-query-configs.util.spec.ts b/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/compute-relation-connect-query-configs.util.spec.ts index 50a2158448..54c98656a4 100644 --- a/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/compute-relation-connect-query-configs.util.spec.ts +++ b/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/compute-relation-connect-query-configs.util.spec.ts @@ -217,7 +217,6 @@ describe('computeRelationConnectQueryConfigs', () => { icon: 'Icon', targetTableName: partial.nameSingular, workspaceId: 'workspace-id', - isCustom: false, isRemote: false, isActive: true, isSystem: false, diff --git a/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/format-twenty-orm-event-to-database-batch-event.util.spec.ts b/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/format-twenty-orm-event-to-database-batch-event.util.spec.ts index 245cdf7569..99bd7ade01 100644 --- a/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/format-twenty-orm-event-to-database-batch-event.util.spec.ts +++ b/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/format-twenty-orm-event-to-database-batch-event.util.spec.ts @@ -64,7 +64,6 @@ describe('formatTwentyOrmEventToDatabaseBatchEvent', () => { namePlural: 'people', labelSingular: 'Person', labelPlural: 'People', - isCustom: false, isRemote: false, isActive: true, isSystem: false, diff --git a/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/get-column-name-to-field-metadata-id.util.spec.ts b/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/get-column-name-to-field-metadata-id.util.spec.ts index fdf7359432..a85e8368f8 100644 --- a/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/get-column-name-to-field-metadata-id.util.spec.ts +++ b/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/get-column-name-to-field-metadata-id.util.spec.ts @@ -17,7 +17,6 @@ describe('getColumnNameToFieldMetadataIdMap', () => { icon: 'IconTest', color: null, targetTableName: 'test', - isCustom: false, isRemote: false, isActive: true, isSystem: false, diff --git a/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/get-field-metadata-id-to-column-names-map.util.spec.ts b/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/get-field-metadata-id-to-column-names-map.util.spec.ts index 7ca0813ab3..b2a34b2ba0 100644 --- a/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/get-field-metadata-id-to-column-names-map.util.spec.ts +++ b/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/get-field-metadata-id-to-column-names-map.util.spec.ts @@ -17,7 +17,6 @@ describe('getFieldMetadataIdToColumnNamesMap', () => { icon: 'IconTest', color: null, targetTableName: 'test', - isCustom: false, isRemote: false, isActive: true, isSystem: false, diff --git a/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/is-record-matching-rls-row-level-permission-predicate.util.spec.ts b/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/is-record-matching-rls-row-level-permission-predicate.util.spec.ts index d8acbd8138..cbeff80d97 100644 --- a/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/is-record-matching-rls-row-level-permission-predicate.util.spec.ts +++ b/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/is-record-matching-rls-row-level-permission-predicate.util.spec.ts @@ -17,7 +17,6 @@ describe('isRecordMatchingRLSRowLevelPermissionPredicate', () => { icon: 'IconTest', color: null, targetTableName: 'test', - isCustom: false, isRemote: false, isActive: true, isSystem: false, diff --git a/packages/twenty-server/src/engine/utils/compute-object-target-table.util.ts b/packages/twenty-server/src/engine/utils/compute-object-target-table.util.ts index 03bb1c7f82..8dd786cce1 100644 --- a/packages/twenty-server/src/engine/utils/compute-object-target-table.util.ts +++ b/packages/twenty-server/src/engine/utils/compute-object-target-table.util.ts @@ -1,3 +1,4 @@ +import { TWENTY_STANDARD_APPLICATION } from 'src/engine/workspace-manager/twenty-standard-application/constants/twenty-standard-applications'; import { type UniversalFlatObjectMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-object-metadata.type'; import { computeTableName } from './compute-table-name.util'; @@ -5,8 +6,12 @@ import { computeTableName } from './compute-table-name.util'; export const computeObjectTargetTable = ( objectMetadata: Pick< UniversalFlatObjectMetadata, - 'nameSingular' | 'isCustom' + 'nameSingular' | 'applicationUniversalIdentifier' >, ) => { - return computeTableName(objectMetadata.nameSingular, objectMetadata.isCustom); + return computeTableName( + objectMetadata.nameSingular, + objectMetadata.applicationUniversalIdentifier !== + TWENTY_STANDARD_APPLICATION.universalIdentifier, + ); }; diff --git a/packages/twenty-server/src/engine/workspace-manager/dev-seeder/data/services/dev-seeder-data.service.ts b/packages/twenty-server/src/engine/workspace-manager/dev-seeder/data/services/dev-seeder-data.service.ts index 72c4ec298e..5f0ab904f1 100644 --- a/packages/twenty-server/src/engine/workspace-manager/dev-seeder/data/services/dev-seeder-data.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/dev-seeder/data/services/dev-seeder-data.service.ts @@ -14,7 +14,7 @@ import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadat import { FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; import { type WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager'; -import { computeTableName } from 'src/engine/utils/compute-table-name.util'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; import { ATTACHMENT_DATA_SEED_COLUMNS, ATTACHMENT_SAMPLE_FILES, @@ -387,8 +387,7 @@ export class DevSeederDataService { const objectMetadata = objectMetadataItems.find( (item) => - computeTableName(item.nameSingular, item.isCustom) === - recordSeedsConfig.tableName, + computeObjectTargetTable(item) === recordSeedsConfig.tableName, ); if (!objectMetadata) { diff --git a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-field-flat-metadata.util.ts b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-field-flat-metadata.util.ts index c75391e586..131cf33ddc 100644 --- a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-field-flat-metadata.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-field-flat-metadata.util.ts @@ -6,6 +6,7 @@ import { type FieldMetadataType, } from 'twenty-shared/types'; import { STANDARD_OBJECTS } from 'twenty-shared/metadata'; +import { TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER } from 'twenty-shared/application'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { type AllStandardObjectFieldName } from 'src/engine/workspace-manager/twenty-standard-application/types/all-standard-object-field-name.type'; @@ -79,7 +80,6 @@ export const createStandardFieldFlatMetadata = < label, description, icon, - isCustom: false, isActive: true, isSystem, isNullable, @@ -101,7 +101,8 @@ export const createStandardFieldFlatMetadata = < mainGroupByFieldMetadataViewIds: [], createdAt: now, updatedAt: now, - applicationUniversalIdentifier: twentyStandardApplicationId, + applicationUniversalIdentifier: + TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER, objectMetadataUniversalIdentifier: STANDARD_OBJECTS[objectName].universalIdentifier, relationTargetObjectMetadataUniversalIdentifier: null, diff --git a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-relation-field-flat-metadata.util.ts b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-relation-field-flat-metadata.util.ts index 8df6c90cb5..df54405822 100644 --- a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-relation-field-flat-metadata.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-relation-field-flat-metadata.util.ts @@ -6,6 +6,7 @@ import { type FieldMetadataType, } from 'twenty-shared/types'; import { STANDARD_OBJECTS } from 'twenty-shared/metadata'; +import { TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER } from 'twenty-shared/application'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { type AllStandardObjectFieldName } from 'src/engine/workspace-manager/twenty-standard-application/types/all-standard-object-field-name.type'; @@ -96,7 +97,6 @@ export const createStandardRelationFieldFlatMetadata = < label, description, icon, - isCustom: false, isActive: true, isSystem: false, isNullable, @@ -119,7 +119,8 @@ export const createStandardRelationFieldFlatMetadata = < mainGroupByFieldMetadataViewIds: [], createdAt: now, updatedAt: now, - applicationUniversalIdentifier: twentyStandardApplicationId, + applicationUniversalIdentifier: + TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER, objectMetadataUniversalIdentifier: STANDARD_OBJECTS[objectName].universalIdentifier, relationTargetObjectMetadataUniversalIdentifier: diff --git a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/object-metadata/create-standard-object-flat-metadata.util.ts b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/object-metadata/create-standard-object-flat-metadata.util.ts index 95e02c1011..44b67d37f8 100644 --- a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/object-metadata/create-standard-object-flat-metadata.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/object-metadata/create-standard-object-flat-metadata.util.ts @@ -1,4 +1,5 @@ import { STANDARD_OBJECTS } from 'twenty-shared/metadata'; +import { TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER } from 'twenty-shared/application'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; import { type AllStandardObjectFieldName } from 'src/engine/workspace-manager/twenty-standard-application/types/all-standard-object-field-name.type'; @@ -80,7 +81,6 @@ export const createStandardObjectFlatMetadata = < color: null, description, icon, - isCustom: false, isRemote: false, isActive: true, isSystem, @@ -109,7 +109,8 @@ export const createStandardObjectFlatMetadata = < createdAt: now, updatedAt: now, id: standardObjectMetadataRelatedEntityIds[nameSingular].id, - applicationUniversalIdentifier: twentyStandardApplicationId, + applicationUniversalIdentifier: + TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER, fieldUniversalIdentifiers: [], objectPermissionUniversalIdentifiers: [], fieldPermissionUniversalIdentifiers: [], diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type.ts index f08726ea89..160d491a51 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type.ts @@ -1,6 +1,8 @@ import { type AllMetadataName } from 'twenty-shared/metadata'; import { type FormatRecordSerializedRelationProperties } from 'twenty-shared/types'; +import { type MakeWasRemovedInUpgradePropertiesOptional } from 'src/engine/core-modules/upgrade/decorators/was-removed-in-upgrade.decorator'; + import { type ALL_MANY_TO_ONE_METADATA_RELATIONS } from 'src/engine/metadata-modules/flat-entity/constant/all-many-to-one-metadata-relations.constant'; import { type ALL_ONE_TO_MANY_METADATA_RELATIONS } from 'src/engine/metadata-modules/flat-entity/constant/all-one-to-many-metadata-relations.constant'; import { type AddSuffixToEntityManyToOneProperties } from 'src/engine/metadata-modules/flat-entity/types/add-suffix-to-entity-many-to-one-properties.type'; @@ -43,7 +45,7 @@ export type UniversalFlatEntityFrom< TMetadataName extends AllMetadataName = FromMetadataEntityToMetadataName, > = Omit< - TEntity, + MakeWasRemovedInUpgradePropertiesOptional, | 'applicationId' | 'workspaceId' | 'id' diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/__tests__/__snapshots__/universal-flat-entity-deleted-created-updated-matrix-dispatcher.util.spec.ts.snap b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/__tests__/__snapshots__/universal-flat-entity-deleted-created-updated-matrix-dispatcher.util.spec.ts.snap index a0414b61c7..6c73627b71 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/__tests__/__snapshots__/universal-flat-entity-deleted-created-updated-matrix-dispatcher.util.spec.ts.snap +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/__tests__/__snapshots__/universal-flat-entity-deleted-created-updated-matrix-dispatcher.util.spec.ts.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing +// Jest Snapshot v1, https://goo.gl/fbAQLP exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect a created entity 1`] = ` { @@ -17,7 +17,6 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect a crea "icon": "icon", "id": "field-id-1", "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": false, @@ -82,7 +81,6 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect a dele "icon": "icon", "id": "field-id-1", "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": false, @@ -161,7 +159,6 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect create "icon": "icon", "id": "field-id-3", "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": false, @@ -212,7 +209,6 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect create "icon": "icon", "id": "field-id-2", "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": false, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/__tests__/add-universal-flat-entity-to-universal-flat-entity-and-related-entity-maps-through-mutation-or-throw.util.spec.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/__tests__/add-universal-flat-entity-to-universal-flat-entity-and-related-entity-maps-through-mutation-or-throw.util.spec.ts index 1eb5b43035..ca995f4dc5 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/__tests__/add-universal-flat-entity-to-universal-flat-entity-and-related-entity-maps-through-mutation-or-throw.util.spec.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/__tests__/add-universal-flat-entity-to-universal-flat-entity-and-related-entity-maps-through-mutation-or-throw.util.spec.ts @@ -37,7 +37,6 @@ describe('addUniversalFlatEntityToUniversalFlatEntityAndRelatedEntityMapsThrough icon: 'icon', isActive: true, isAuditLogged: true, - isCustom: true, isLabelSyncedWithName: false, isRemote: false, isSearchable: true, @@ -80,7 +79,6 @@ describe('addUniversalFlatEntityToUniversalFlatEntityAndRelatedEntityMapsThrough description: 'default flat field metadata description', icon: 'icon', isActive: true, - isCustom: true, name: 'flatFieldMetadataName', label: 'flat field metadata label', isNullable: true, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/__tests__/delete-universal-flat-entity-from-universal-flat-entity-and-related-entity-maps-through-mutation-or-throw.util.spec.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/__tests__/delete-universal-flat-entity-from-universal-flat-entity-and-related-entity-maps-through-mutation-or-throw.util.spec.ts index 0ce6e1e44b..941811d58c 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/__tests__/delete-universal-flat-entity-from-universal-flat-entity-and-related-entity-maps-through-mutation-or-throw.util.spec.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/__tests__/delete-universal-flat-entity-from-universal-flat-entity-and-related-entity-maps-through-mutation-or-throw.util.spec.ts @@ -33,7 +33,6 @@ describe('deleteUniversalFlatEntityFromUniversalFlatEntityAndRelatedEntityMapsTh icon: 'icon', isActive: true, isAuditLogged: true, - isCustom: true, isLabelSyncedWithName: false, isRemote: false, isSearchable: true, @@ -76,7 +75,6 @@ describe('deleteUniversalFlatEntityFromUniversalFlatEntityAndRelatedEntityMapsTh description: 'default flat field metadata description', icon: 'icon', isActive: true, - isCustom: true, name: 'flatFieldMetadataName', label: 'flat field metadata label', isNullable: true, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/__tests__/flat-entity-to-scalar-flat-entity.util.spec.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/__tests__/flat-entity-to-scalar-flat-entity.util.spec.ts index 8b161db699..56f73309b8 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/__tests__/flat-entity-to-scalar-flat-entity.util.spec.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/__tests__/flat-entity-to-scalar-flat-entity.util.spec.ts @@ -27,7 +27,6 @@ describe('flatEntityToScalarFlatEntity', () => { standardOverrides: null, settings: null, universalSettings: null, - isCustom: true, isSystem: false, isUIReadOnly: false, isNullable: true, @@ -56,7 +55,6 @@ describe('flatEntityToScalarFlatEntity', () => { "icon": "IconTest", "id": "field-metadata-id", "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": false, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/get-workspace-schema-context-for-migration.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/get-workspace-schema-context-for-migration.util.ts index ba6c37b497..d003d8fb12 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/get-workspace-schema-context-for-migration.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/get-workspace-schema-context-for-migration.util.ts @@ -15,7 +15,7 @@ export const getWorkspaceSchemaContextForMigration = ({ workspaceId: string; objectMetadata: Pick< FlatObjectMetadata | UniversalFlatObjectMetadata, - 'nameSingular' | 'isCustom' + 'nameSingular' | 'applicationUniversalIdentifier' >; }): WorkspaceSchemaContextForMigration => { return { diff --git a/packages/twenty-server/src/modules/contact-creation-manager/services/__tests__/create-company.service.spec.ts b/packages/twenty-server/src/modules/contact-creation-manager/services/__tests__/create-company.service.spec.ts index ea887bd5b9..2c43442108 100644 --- a/packages/twenty-server/src/modules/contact-creation-manager/services/__tests__/create-company.service.spec.ts +++ b/packages/twenty-server/src/modules/contact-creation-manager/services/__tests__/create-company.service.spec.ts @@ -137,7 +137,6 @@ describe('CreateCompanyService', () => { labelSingular: 'Company', labelPlural: 'Companies', targetTableName: 'company', - isCustom: false, isRemote: false, isActive: true, isSystem: false, diff --git a/packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/listeners/__tests__/workflow-database-event-trigger.listener.spec.ts b/packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/listeners/__tests__/workflow-database-event-trigger.listener.spec.ts index 66b5e70b67..38fe4f713b 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/listeners/__tests__/workflow-database-event-trigger.listener.spec.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/listeners/__tests__/workflow-database-event-trigger.listener.spec.ts @@ -31,7 +31,6 @@ describe('WorkflowDatabaseEventTriggerListener', () => { description: 'Test object for testing', targetTableName: 'test_objects', isSystem: false, - isCustom: false, isActive: true, isRemote: false, isAuditLogged: true, diff --git a/packages/twenty-server/src/utils/__test__/get-field-metadata-entity.mock.ts b/packages/twenty-server/src/utils/__test__/get-field-metadata-entity.mock.ts index d4e60153a6..c8e92a077b 100644 --- a/packages/twenty-server/src/utils/__test__/get-field-metadata-entity.mock.ts +++ b/packages/twenty-server/src/utils/__test__/get-field-metadata-entity.mock.ts @@ -31,7 +31,6 @@ export const getMockFieldMetadataEntity = < fieldPermissions: [], icon: null, indexFieldMetadatas: [], - isCustom: true, isLabelSyncedWithName: false, isNullable: null, isUIReadOnly: false, @@ -53,6 +52,7 @@ export const getMockFieldMetadataEntity = < createdAt: new Date(), updatedAt: new Date(), isActive: true, + isCustom: false, application: {} as ApplicationEntity, applicationId: faker.string.uuid(), universalIdentifier: faker.string.uuid(), diff --git a/packages/twenty-server/test/integration/metadata/suites/application/__snapshots__/successful-sync-application-workspace-migration.integration-spec.ts.snap b/packages/twenty-server/test/integration/metadata/suites/application/__snapshots__/successful-sync-application-workspace-migration.integration-spec.ts.snap index f225b1b81a..7f30561410 100644 --- a/packages/twenty-server/test/integration/metadata/suites/application/__snapshots__/successful-sync-application-workspace-migration.integration-spec.ts.snap +++ b/packages/twenty-server/test/integration/metadata/suites/application/__snapshots__/successful-sync-application-workspace-migration.integration-spec.ts.snap @@ -12,7 +12,6 @@ exports[`syncApplication should create a TEXT field on the standard Company obje "description": "The industry of the company", "icon": "IconBuildingFactory2", "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": false, @@ -79,7 +78,6 @@ exports[`syncApplication should delete old field and create equivalent one when "imageIdentifierFieldMetadataUniversalIdentifier": null, "isActive": true, "isAuditLogged": true, - "isCustom": true, "isLabelSyncedWithName": false, "isRemote": false, "isSearchable": true, @@ -106,7 +104,6 @@ exports[`syncApplication should delete old field and create equivalent one when "description": null, "icon": null, "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": true, @@ -132,7 +129,6 @@ exports[`syncApplication should delete old field and create equivalent one when "description": null, "icon": null, "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": true, @@ -158,7 +154,6 @@ exports[`syncApplication should delete old field and create equivalent one when "description": null, "icon": null, "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": true, @@ -184,7 +179,6 @@ exports[`syncApplication should delete old field and create equivalent one when "description": null, "icon": null, "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": true, @@ -215,7 +209,6 @@ exports[`syncApplication should delete old field and create equivalent one when "description": null, "icon": null, "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": true, @@ -246,7 +239,6 @@ exports[`syncApplication should delete old field and create equivalent one when "description": null, "icon": null, "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": true, @@ -272,7 +264,6 @@ exports[`syncApplication should delete old field and create equivalent one when "description": null, "icon": null, "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": true, @@ -298,7 +289,6 @@ exports[`syncApplication should delete old field and create equivalent one when "description": null, "icon": null, "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": true, @@ -327,7 +317,6 @@ exports[`syncApplication should delete old field and create equivalent one when "description": "Ticket description", "icon": "IconFileDescription", "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": false, @@ -395,7 +384,6 @@ exports[`syncApplication should delete old field and create equivalent one when "icon": "IconFileDescription", "id": Any, "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": false, @@ -441,7 +429,6 @@ exports[`syncApplication should delete old field and create equivalent one when "description": "Ticket description", "icon": "IconFileDescription", "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": false, @@ -485,7 +472,6 @@ exports[`syncApplication should return workspace migration actions on initial sy "imageIdentifierFieldMetadataUniversalIdentifier": null, "isActive": true, "isAuditLogged": true, - "isCustom": true, "isLabelSyncedWithName": false, "isRemote": false, "isSearchable": true, @@ -512,7 +498,6 @@ exports[`syncApplication should return workspace migration actions on initial sy "description": null, "icon": null, "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": true, @@ -538,7 +523,6 @@ exports[`syncApplication should return workspace migration actions on initial sy "description": null, "icon": null, "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": true, @@ -564,7 +548,6 @@ exports[`syncApplication should return workspace migration actions on initial sy "description": null, "icon": null, "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": true, @@ -590,7 +573,6 @@ exports[`syncApplication should return workspace migration actions on initial sy "description": null, "icon": null, "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": true, @@ -621,7 +603,6 @@ exports[`syncApplication should return workspace migration actions on initial sy "description": null, "icon": null, "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": true, @@ -652,7 +633,6 @@ exports[`syncApplication should return workspace migration actions on initial sy "description": null, "icon": null, "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": true, @@ -678,7 +658,6 @@ exports[`syncApplication should return workspace migration actions on initial sy "description": null, "icon": null, "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": true, @@ -704,7 +683,6 @@ exports[`syncApplication should return workspace migration actions on initial sy "description": null, "icon": null, "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": true, @@ -733,7 +711,6 @@ exports[`syncApplication should return workspace migration actions on initial sy "description": "Ticket description", "icon": "IconFileDescription", "isActive": true, - "isCustom": true, "isLabelSyncedWithName": false, "isNullable": true, "isSystem": false, diff --git a/packages/twenty-server/test/integration/metadata/suites/application/dry-run-manifest-sync.integration-spec.ts b/packages/twenty-server/test/integration/metadata/suites/application/dry-run-manifest-sync.integration-spec.ts index e63a61eb5d..7ff0ec4b66 100644 --- a/packages/twenty-server/test/integration/metadata/suites/application/dry-run-manifest-sync.integration-spec.ts +++ b/packages/twenty-server/test/integration/metadata/suites/application/dry-run-manifest-sync.integration-spec.ts @@ -14,12 +14,9 @@ const buildManifest = ( overrides?: Partial>, ) => buildBaseManifest({ appId: TEST_APP_ID, roleId: TEST_ROLE_ID, overrides }); -const findCustomObjectNames = async (): Promise => { +const findObjectNames = async (): Promise => { const { objects } = await findManyObjectMetadata({ - input: { - filter: { isCustom: { is: true } }, - paging: { first: 100 }, - }, + input: { filter: {}, paging: { first: 100 } }, gqlFields: 'id nameSingular', expectToFail: false, }); @@ -76,9 +73,9 @@ describe('Manifest sync - dry run', () => { 0, ); - const customObjectNames = await findCustomObjectNames(); + const objectNames = await findObjectNames(); - expect(customObjectNames).toContain('dryRunTicket'); - expect(customObjectNames).not.toContain('dryRunInvoice'); + expect(objectNames).toContain('dryRunTicket'); + expect(objectNames).not.toContain('dryRunInvoice'); }, 60000); }); diff --git a/packages/twenty-server/test/integration/metadata/suites/application/successful-manifest-update-object.integration-spec.ts b/packages/twenty-server/test/integration/metadata/suites/application/successful-manifest-update-object.integration-spec.ts index 894fe8073f..f261dd5f4e 100644 --- a/packages/twenty-server/test/integration/metadata/suites/application/successful-manifest-update-object.integration-spec.ts +++ b/packages/twenty-server/test/integration/metadata/suites/application/successful-manifest-update-object.integration-spec.ts @@ -20,14 +20,14 @@ const OBJECT_GQL_FIELDS = const findCustomObjects = async () => { const { objects } = await findManyObjectMetadata({ input: { - filter: { isCustom: { is: true } }, + filter: {}, paging: { first: 100 }, }, gqlFields: OBJECT_GQL_FIELDS, expectToFail: false, }); - return objects; + return objects.filter((object) => object.isCustom); }; describe('Manifest update - objects', () => { diff --git a/packages/twenty-server/test/integration/metadata/suites/application/successful-sync-application-workspace-migration.integration-spec.ts b/packages/twenty-server/test/integration/metadata/suites/application/successful-sync-application-workspace-migration.integration-spec.ts index f71bf9e86e..0114669e4b 100644 --- a/packages/twenty-server/test/integration/metadata/suites/application/successful-sync-application-workspace-migration.integration-spec.ts +++ b/packages/twenty-server/test/integration/metadata/suites/application/successful-sync-application-workspace-migration.integration-spec.ts @@ -89,7 +89,7 @@ describe('syncApplication', () => { // Verify database state after first sync const { objects: objectsAfterSync } = await findManyObjectMetadata({ input: { - filter: { isCustom: { is: true } }, + filter: {}, paging: { first: 100 }, }, gqlFields: diff --git a/packages/twenty-server/test/integration/metadata/suites/object-metadata/rename-custom-object.integration-spec.ts b/packages/twenty-server/test/integration/metadata/suites/object-metadata/rename-custom-object.integration-spec.ts index 080ca64b57..9b865acbf2 100644 --- a/packages/twenty-server/test/integration/metadata/suites/object-metadata/rename-custom-object.integration-spec.ts +++ b/packages/twenty-server/test/integration/metadata/suites/object-metadata/rename-custom-object.integration-spec.ts @@ -36,9 +36,7 @@ describe('Custom object renaming', () => { nameSingular `, input: { - filter: { - isCustom: { isNot: true }, - }, + filter: {}, paging: { first: 1000 }, }, });