diff --git a/packages/twenty-server/src/engine/core-modules/applicationVariable/types/flat-application-variable.type.ts b/packages/twenty-server/src/engine/core-modules/applicationVariable/types/flat-application-variable.type.ts index e01f18d6db1..619273f7f07 100644 --- a/packages/twenty-server/src/engine/core-modules/applicationVariable/types/flat-application-variable.type.ts +++ b/packages/twenty-server/src/engine/core-modules/applicationVariable/types/flat-application-variable.type.ts @@ -1,4 +1,4 @@ import { type ApplicationVariableEntity } from 'src/engine/core-modules/applicationVariable/application-variable.entity'; -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; export type FlatApplicationVariable = FlatEntityFrom; diff --git a/packages/twenty-server/src/engine/core-modules/user/types/flat-workspace-member.type.ts b/packages/twenty-server/src/engine/core-modules/user/types/flat-workspace-member.type.ts index 27992affd0b..ef96477347b 100644 --- a/packages/twenty-server/src/engine/core-modules/user/types/flat-workspace-member.type.ts +++ b/packages/twenty-server/src/engine/core-modules/user/types/flat-workspace-member.type.ts @@ -1,4 +1,4 @@ -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity'; export type FlatWorkspaceMember = diff --git a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger.type.ts b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger.type.ts index 76a29c6c6fe..a0f5bf94a08 100644 --- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger.type.ts @@ -1,4 +1,4 @@ import { type CronTriggerEntity } from 'src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity'; -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; export type FlatCronTrigger = FlatEntityFrom; diff --git a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/types/flat-database-event-trigger.type.ts b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/types/flat-database-event-trigger.type.ts index f6df53f8237..9ff8d04d5a6 100644 --- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/types/flat-database-event-trigger.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/types/flat-database-event-trigger.type.ts @@ -1,5 +1,5 @@ import { type DatabaseEventTriggerEntity } from 'src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity'; -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; export type FlatDatabaseEventTrigger = FlatEntityFrom; 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 f39808e62ce..c539afac643 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 @@ -32,6 +32,8 @@ import { ViewFilterEntity } from 'src/engine/metadata-modules/view-filter/entiti import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity'; import { SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface'; +// This entity is used as a reference test case for type utilities in: +// Modifying relations or properties may require updating type test expectations for Typecheck to pass. @Entity('fieldMetadata') @Check( 'CHK_FIELD_METADATA_MORPH_RELATION_REQUIRES_MORPH_ID', diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/types/field-metadata-entity-test.type.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/types/__tests__/field-metadata-entity.test-type.ts similarity index 100% rename from packages/twenty-server/src/engine/metadata-modules/field-metadata/types/field-metadata-entity-test.type.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/types/__tests__/field-metadata-entity.test-type.ts diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-agent/types/flat-agent.type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-agent/types/flat-agent.type.ts index 4152c1ad12a..92bab589251 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-agent/types/flat-agent.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-agent/types/flat-agent.type.ts @@ -1,5 +1,5 @@ import { type AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity'; -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; export type FlatAgent = FlatEntityFrom; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-command-menu-item/types/flat-command-menu-item.type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-command-menu-item/types/flat-command-menu-item.type.ts index 8a09761bc84..ac719161bd8 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-command-menu-item/types/flat-command-menu-item.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-command-menu-item/types/flat-command-menu-item.type.ts @@ -1,4 +1,4 @@ import { type CommandMenuItemEntity } from 'src/engine/metadata-modules/command-menu-item/entities/command-menu-item.entity'; -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; export type FlatCommandMenuItem = FlatEntityFrom; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant.ts index 4bbb141f796..ec66537c50c 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant.ts @@ -1,5 +1,5 @@ +import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; -import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; export const createEmptyFlatEntityMaps = () => ({ diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/all-flat-entity-by-metadata-engine-name-test.type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/__tests__/all-flat-entity-by-metadata-engine-name.test-type.ts similarity index 96% rename from packages/twenty-server/src/engine/metadata-modules/flat-entity/types/all-flat-entity-by-metadata-engine-name-test.type.ts rename to packages/twenty-server/src/engine/metadata-modules/flat-entity/types/__tests__/all-flat-entity-by-metadata-engine-name.test-type.ts index c4d9bdcace1..6ad315ecf23 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/all-flat-entity-by-metadata-engine-name-test.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/__tests__/all-flat-entity-by-metadata-engine-name.test-type.ts @@ -2,7 +2,7 @@ import { type AllMetadataName } from 'twenty-shared/metadata'; import { type Expect } from 'twenty-shared/testing'; import { type AllFlatEntityTypesByMetadataName } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-types-by-metadata-name'; -import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type WorkspaceMigrationActionType } from 'src/engine/metadata-modules/flat-entity/types/metadata-workspace-migration-action.type'; import { type WorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/workspace-migration-action-common'; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/__tests__/cast-record-typeorm-date-properties-to-string.type-test.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/__tests__/cast-record-typeorm-date-properties-to-string.type-test.ts new file mode 100644 index 00000000000..571588ad563 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/__tests__/cast-record-typeorm-date-properties-to-string.type-test.ts @@ -0,0 +1,21 @@ +import { type Expect, type Equal } from 'twenty-shared/testing'; + +import { type FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { type CastRecordTypeOrmDatePropertiesToString } from 'src/engine/metadata-modules/flat-entity/types/cast-record-typeorm-date-properties-to-string.type'; + +type FieldMetadataDateProperties = + CastRecordTypeOrmDatePropertiesToString; + +// eslint-disable-next-line unused-imports/no-unused-vars +type Assertions = [ + // FieldMetadataEntity has createdAt and updatedAt Date properties + Expect< + Equal< + FieldMetadataDateProperties, + { + createdAt: string; + updatedAt: string; + } + > + >, +]; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/__tests__/extract-entity-many-to-one-entity-relation-properties.type-test.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/__tests__/extract-entity-many-to-one-entity-relation-properties.type-test.ts new file mode 100644 index 00000000000..26e00825632 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/__tests__/extract-entity-many-to-one-entity-relation-properties.type-test.ts @@ -0,0 +1,27 @@ +import { type Expect, type Equal } from 'twenty-shared/testing'; + +import { type FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { type ExtractEntityManyToOneEntityRelationProperties } from 'src/engine/metadata-modules/flat-entity/types/extract-entity-many-to-one-entity-relation-properties.type'; + +type FieldMetadataManyToOneRelations = + ExtractEntityManyToOneEntityRelationProperties; + +// eslint-disable-next-line unused-imports/no-unused-vars +type Assertions = [ + // FieldMetadataEntity ManyToOne relations: + // - object (ObjectMetadataEntity) + // - workspace (WorkspaceEntity) + // - application (ApplicationEntity) + // - relationTargetFieldMetadata (FieldMetadataEntity) + // - relationTargetObjectMetadata (ObjectMetadataEntity) + Expect< + Equal< + FieldMetadataManyToOneRelations, + | 'object' + | 'workspace' + | 'application' + | 'relationTargetFieldMetadata' + | 'relationTargetObjectMetadata' + > + >, +]; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/__tests__/extract-entity-one-to-many-entity-relation-properties.type-test.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/__tests__/extract-entity-one-to-many-entity-relation-properties.type-test.ts new file mode 100644 index 00000000000..5f65a7b75a2 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/__tests__/extract-entity-one-to-many-entity-relation-properties.type-test.ts @@ -0,0 +1,45 @@ +import { type Equal, type Expect } from 'twenty-shared/testing'; + +import { type FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { type ExtractEntityOneToManyEntityRelationProperties } from 'src/engine/metadata-modules/flat-entity/types/extract-entity-one-to-many-entity-relation-properties.type'; +import { type SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface'; + +type FieldMetadataOneToManyRelations = + ExtractEntityOneToManyEntityRelationProperties; + +type FieldMetadataOneToManySyncableRelations = + ExtractEntityOneToManyEntityRelationProperties< + FieldMetadataEntity, + SyncableEntity + >; + +// eslint-disable-next-line unused-imports/no-unused-vars +type Assertions = [ + // FieldMetadataEntity OneToMany relations (all targets): + // - indexFieldMetadatas, fieldPermissions, viewFields, viewFilters, + // - kanbanAggregateOperationViews, calendarViews, mainGroupByFieldMetadataViews + Expect< + Equal< + FieldMetadataOneToManyRelations, + | 'indexFieldMetadatas' + | 'fieldPermissions' + | 'viewFields' + | 'viewFilters' + | 'kanbanAggregateOperationViews' + | 'calendarViews' + | 'mainGroupByFieldMetadataViews' + > + >, + + // When filtered by SyncableEntity target, only syncable relations are included + Expect< + Equal< + FieldMetadataOneToManySyncableRelations, + | 'viewFields' + | 'viewFilters' + | 'kanbanAggregateOperationViews' + | 'calendarViews' + | 'mainGroupByFieldMetadataViews' + > + >, +]; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/__tests__/extract-entity-related-entity-properties.type-test.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/__tests__/extract-entity-related-entity-properties.type-test.ts new file mode 100644 index 00000000000..3f93c3e9ead --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/__tests__/extract-entity-related-entity-properties.type-test.ts @@ -0,0 +1,31 @@ +import { type Expect, type Equal } from 'twenty-shared/testing'; + +import { type FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { type ExtractEntityRelatedEntityProperties } from 'src/engine/metadata-modules/flat-entity/types/extract-entity-related-entity-properties.type'; + +type FieldMetadataRelatedProperties = + ExtractEntityRelatedEntityProperties; + +// eslint-disable-next-line unused-imports/no-unused-vars +type Assertions = [ + // FieldMetadataEntity has both ManyToOne and OneToMany relations + // ManyToOne: object, workspace, application, relationTargetFieldMetadata, relationTargetObjectMetadata + // OneToMany: indexFieldMetadatas, fieldPermissions, viewFields, viewFilters, kanbanAggregateOperationViews, calendarViews, mainGroupByFieldMetadataViews + Expect< + Equal< + FieldMetadataRelatedProperties, + | 'object' + | 'workspace' + | 'application' + | 'relationTargetFieldMetadata' + | 'relationTargetObjectMetadata' + | 'indexFieldMetadatas' + | 'fieldPermissions' + | 'viewFields' + | 'viewFilters' + | 'kanbanAggregateOperationViews' + | 'calendarViews' + | 'mainGroupByFieldMetadataViews' + > + >, +]; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/__tests__/metadata-many-to-one-join-column.type-test.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/__tests__/metadata-many-to-one-join-column.type-test.ts new file mode 100644 index 00000000000..214955e24c7 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/__tests__/metadata-many-to-one-join-column.type-test.ts @@ -0,0 +1,18 @@ +import { type Equal, type Expect } from 'twenty-shared/testing'; + +import { type MetadataManyToOneJoinColumn } from 'src/engine/metadata-modules/flat-entity/types/metadata-many-to-one-join-column.type'; + +type FieldMetadataJoinColumns = MetadataManyToOneJoinColumn<'fieldMetadata'>; + +// eslint-disable-next-line unused-imports/no-unused-vars +type Assertions = [ + // fieldMetadata foreign keys from ALL_METADATA_RELATIONS + Expect< + Equal< + FieldMetadataJoinColumns, + | 'objectMetadataId' + | 'relationTargetFieldMetadataId' + | 'relationTargetObjectMetadataId' + > + >, +]; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/flat-entity.type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/flat-entity-from.type.ts similarity index 97% rename from packages/twenty-server/src/engine/metadata-modules/flat-entity/types/flat-entity.type.ts rename to packages/twenty-server/src/engine/metadata-modules/flat-entity/types/flat-entity-from.type.ts index a0e7570fd9c..d5590074fcd 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/flat-entity.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/flat-entity-from.type.ts @@ -15,8 +15,6 @@ export type SyncableFlatEntity = NonNullableProperties< export type FlatEntityFrom = Omit< TEntity, | ExtractEntityRelatedEntityProperties - | 'application' - | 'workspace' | keyof CastRecordTypeOrmDatePropertiesToString > & CastRecordTypeOrmDatePropertiesToString & { diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type.ts index f15cc45cc1e..d5f0f26e67b 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type.ts @@ -1,4 +1,4 @@ -import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; export type FlatEntityMaps = { byId: Partial>; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/from-metadata-entity-to-metadata-name.type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/from-metadata-entity-to-metadata-name.type.ts index c5fe3f8ac6d..2d18e5c48fb 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/from-metadata-entity-to-metadata-name.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/from-metadata-entity-to-metadata-name.type.ts @@ -1,5 +1,8 @@ import { type AllMetadataName } from 'twenty-shared/metadata'; +import { type Expect } from 'twenty-shared/testing'; +import { type FieldMetadataType } from 'twenty-shared/types'; +import { type FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { type AllFlatEntityTypesByMetadataName } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-types-by-metadata-name'; import { type SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface'; @@ -10,3 +13,17 @@ export type FromMetadataEntityToMetadataName = { ? P : never; }[AllMetadataName]; + +// metadata name lookups works with the base entity type, not with narrowed variants. +// eslint-disable-next-line unused-imports/no-unused-vars +type Assertions = [ + Expect< + [never] extends [ + FromMetadataEntityToMetadataName< + FieldMetadataEntity + >, + ] + ? true + : false + >, +]; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util.ts index a4dac00b90b..1633f15f3eb 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util.ts @@ -4,8 +4,8 @@ import { FlatEntityMapsException, FlatEntityMapsExceptionCode, } from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception'; +import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; -import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; type AddFlatEntityToFlatEntityMapsOrThrowArgs = { flatEntity: T; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/delete-flat-entity-from-flat-entity-maps-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/delete-flat-entity-from-flat-entity-maps-or-throw.util.ts index dcb3afa76f2..cf6cddb85ac 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/delete-flat-entity-from-flat-entity-maps-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/delete-flat-entity-from-flat-entity-maps-or-throw.util.ts @@ -5,8 +5,8 @@ import { FlatEntityMapsException, FlatEntityMapsExceptionCode, } from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception'; +import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; -import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; export type DeleteFlatEntityFromFlatEntityMapsOrThrowArgs< T extends SyncableFlatEntity, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entities-by-application-id.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entities-by-application-id.util.ts index 939d37c5fce..a213bcfa9ba 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entities-by-application-id.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entities-by-application-id.util.ts @@ -1,7 +1,7 @@ import { isDefined } from 'twenty-shared/utils'; +import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; -import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; export const findFlatEntitiesByApplicationId = ({ applicationId, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util.ts index 18d950a35d4..d7ea89ca185 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util.ts @@ -5,8 +5,8 @@ import { FlatEntityMapsException, FlatEntityMapsExceptionCode, } from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception'; +import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; -import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; export type FindFlatEntityByIdInFlatEntityMapsOrThrowArgs< T extends SyncableFlatEntity, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util.ts index 9f9b2d7d2a4..80842b0be27 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util.ts @@ -1,4 +1,4 @@ -import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { findFlatEntityByIdInFlatEntityMapsOrThrow, type FindFlatEntityByIdInFlatEntityMapsOrThrowArgs, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier-or-throw.util.ts index e9679ce6b96..62d5dde2cf7 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier-or-throw.util.ts @@ -4,8 +4,8 @@ import { FlatEntityMapsException, FlatEntityMapsExceptionCode, } from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception'; +import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; -import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; import { findFlatEntityByUniversalIdentifier } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util'; export type FindFlatEntityByUniversalIdentifierOrThrowArgs< diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util.ts index 68b1b429afe..5e149d8ecef 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util.ts @@ -1,7 +1,7 @@ import { isDefined } from 'twenty-shared/utils'; +import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; -import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; export const findFlatEntityByUniversalIdentifier = < T extends SyncableFlatEntity, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps-or-throw.util.ts index 71f56313755..29b8f04c5d4 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps-or-throw.util.ts @@ -1,7 +1,7 @@ import { isDefined } from 'twenty-shared/utils'; +import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; -import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; import { getSubFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-or-throw.util'; export type FindManyFlatEntityByIdInFlatEntityMapsOrThrowArgs< diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-by-application-id-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-by-application-id-or-throw.util.ts index f58b0ba469a..581c959615f 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-by-application-id-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-by-application-id-or-throw.util.ts @@ -1,5 +1,5 @@ +import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; -import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; import { findFlatEntitiesByApplicationId } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entities-by-application-id.util'; import { getSubFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-or-throw.util'; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-or-throw.util.ts index 2ff0f670534..333a2b11429 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-or-throw.util.ts @@ -1,6 +1,6 @@ import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant'; +import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; -import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util'; import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/replace-flat-entity-in-flat-entity-maps-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/replace-flat-entity-in-flat-entity-maps-or-throw.util.ts index 6d5f241d8b3..c8df4cb914a 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/replace-flat-entity-in-flat-entity-maps-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/replace-flat-entity-in-flat-entity-maps-or-throw.util.ts @@ -1,5 +1,5 @@ +import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; -import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util'; import { deleteFlatEntityFromFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/delete-flat-entity-from-flat-entity-maps-or-throw.util'; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/transform-flat-entity-for-comparison.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/transform-flat-entity-for-comparison.util.ts index f99840e5e29..83472390611 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/transform-flat-entity-for-comparison.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/transform-flat-entity-for-comparison.util.ts @@ -1,4 +1,4 @@ -import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { orderObjectProperties } from 'src/engine/metadata-modules/flat-entity/utils/order-object-properties.util'; export function transformFlatEntityForComparison< diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/types/__tests__/flat-field-metadata.test-type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/types/__tests__/flat-field-metadata.test-type.ts new file mode 100644 index 00000000000..e074b47c547 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/types/__tests__/flat-field-metadata.test-type.ts @@ -0,0 +1,73 @@ +import { type Expect, type HasAllProperties } from 'twenty-shared/testing'; +import { + type FieldMetadataType, + type NullablePartial, +} from 'twenty-shared/types'; + +import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; + +// Relation field types have defined relation IDs +type DefinedRelationIdRecord = { + relationTargetFieldMetadataId: string; + relationTargetObjectMetadataId: string; +}; + +// Non-relation field types have never | null relation IDs +type NotDefinedRelationIdRecord = { + relationTargetFieldMetadataId: never | null; + relationTargetObjectMetadataId: never | null; +}; + +// Date properties are cast to strings +type DatePropertiesCastToString = { + createdAt: string; + updatedAt: string; +}; + +// OneToMany relations become ...Ids arrays +type OneToManyRelationIdArrays = { + viewFieldIds: string[]; + viewFilterIds: string[]; + kanbanAggregateOperationViewIds: string[]; + calendarViewIds: string[]; + mainGroupByFieldMetadataViewIds: string[]; +}; + +// eslint-disable-next-line unused-imports/no-unused-vars +type RelationIdAssertions = [ + // Non-relation types have undefined relation IDs + Expect< + HasAllProperties< + FlatFieldMetadata, + NotDefinedRelationIdRecord + > + >, + + // Relation types have defined relation IDs + Expect< + HasAllProperties< + FlatFieldMetadata, + DefinedRelationIdRecord + > + >, + Expect< + HasAllProperties< + FlatFieldMetadata, + DefinedRelationIdRecord + > + >, + + // Abstract type has nullable partial relation IDs + Expect< + HasAllProperties< + FlatFieldMetadata, + NullablePartial + > + >, +]; + +// eslint-disable-next-line unused-imports/no-unused-vars +type FlatTransformationAssertions = [ + Expect>, + Expect>, +]; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type.ts index acdfd921561..c52d078682f 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type.ts @@ -1,7 +1,7 @@ import { type FieldMetadataType } from 'twenty-shared/types'; import { type FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; export type FlatFieldMetadata = FlatEntityFrom< @@ -9,6 +9,4 @@ export type FlatFieldMetadata = FieldMetadataEntity, 'relationTargetFieldMetadata' | 'relationTargetObjectMetadata' > - > & { - universalIdentifier: string; // TODO remove once universalIdentifier is required on entity directly - }; + >; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-front-component/types/flat-front-component.type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-front-component/types/flat-front-component.type.ts index a8907b346d5..ad47b4e4de1 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-front-component/types/flat-front-component.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-front-component/types/flat-front-component.type.ts @@ -1,4 +1,4 @@ -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type FrontComponentEntity } from 'src/engine/metadata-modules/front-component/entities/front-component.entity'; export type FlatFrontComponent = FlatEntityFrom; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type.ts index 9e58bc88543..b4ad77111ad 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type.ts @@ -1,4 +1,4 @@ -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type IndexFieldMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-field-metadata.entity'; import { type IndexMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity'; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-navigation-menu-item/types/flat-navigation-menu-item.type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-navigation-menu-item/types/flat-navigation-menu-item.type.ts index 3da677ed497..78d4eb05c94 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-navigation-menu-item/types/flat-navigation-menu-item.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-navigation-menu-item/types/flat-navigation-menu-item.type.ts @@ -1,4 +1,4 @@ -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type NavigationMenuItemEntity } from 'src/engine/metadata-modules/navigation-menu-item/entities/navigation-menu-item.entity'; export type FlatNavigationMenuItem = FlatEntityFrom; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type.ts index e63c71aebf4..2ca44fc8208 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type.ts @@ -1,4 +1,4 @@ -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; export type FlatObjectMetadata = FlatEntityFrom< diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-tab/types/flat-page-layout-tab.type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-tab/types/flat-page-layout-tab.type.ts index dacb31460bd..d96c4d073bc 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-tab/types/flat-page-layout-tab.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-tab/types/flat-page-layout-tab.type.ts @@ -1,4 +1,4 @@ -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type PageLayoutTabEntity } from 'src/engine/metadata-modules/page-layout-tab/entities/page-layout-tab.entity'; export type FlatPageLayoutTab = FlatEntityFrom; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget.type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget.type.ts index b985bef7f82..853fde7d413 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget.type.ts @@ -1,4 +1,4 @@ -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type PageLayoutWidgetEntity } from 'src/engine/metadata-modules/page-layout-widget/entities/page-layout-widget.entity'; import { type WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type'; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-page-layout/types/flat-page-layout.type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-page-layout/types/flat-page-layout.type.ts index 19407d28d7b..ec113dc694c 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-page-layout/types/flat-page-layout.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-page-layout/types/flat-page-layout.type.ts @@ -1,4 +1,4 @@ -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type PageLayoutEntity } from 'src/engine/metadata-modules/page-layout/entities/page-layout.entity'; export type FlatPageLayout = FlatEntityFrom; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-role-target/types/flat-role-target.type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-role-target/types/flat-role-target.type.ts index d824fd108ec..39a4c374641 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-role-target/types/flat-role-target.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-role-target/types/flat-role-target.type.ts @@ -1,4 +1,4 @@ -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity'; export type FlatRoleTarget = FlatEntityFrom; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-role/types/flat-role.type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-role/types/flat-role.type.ts index 712d4fda3b3..4e04c099ec0 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-role/types/flat-role.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-role/types/flat-role.type.ts @@ -1,4 +1,4 @@ -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type RoleEntity } from 'src/engine/metadata-modules/role/role.entity'; export type FlatRole = FlatEntityFrom & { diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-skill/types/flat-skill.type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-skill/types/flat-skill.type.ts index 627d6a19451..ba09e9139ed 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-skill/types/flat-skill.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-skill/types/flat-skill.type.ts @@ -1,4 +1,4 @@ +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type SkillEntity } from 'src/engine/metadata-modules/skill/entities/skill.entity'; -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; export type FlatSkill = FlatEntityFrom; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-view-field/types/flat-view-field.type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-view-field/types/flat-view-field.type.ts index 8355d65bd34..e989ac2fc12 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-view-field/types/flat-view-field.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-view-field/types/flat-view-field.type.ts @@ -1,4 +1,4 @@ -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type ViewFieldEntity } from 'src/engine/metadata-modules/view-field/entities/view-field.entity'; export type FlatViewField = FlatEntityFrom; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-view-filter-group/types/flat-view-filter-group.type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-view-filter-group/types/flat-view-filter-group.type.ts index e7b40359708..28c98f38457 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-view-filter-group/types/flat-view-filter-group.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-view-filter-group/types/flat-view-filter-group.type.ts @@ -1,4 +1,4 @@ -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type ViewFilterGroupEntity } from 'src/engine/metadata-modules/view-filter-group/entities/view-filter-group.entity'; export type FlatViewFilterGroup = FlatEntityFrom; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-view-filter/types/flat-view-filter.type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-view-filter/types/flat-view-filter.type.ts index 32798529bc3..658a9bb1b5b 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-view-filter/types/flat-view-filter.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-view-filter/types/flat-view-filter.type.ts @@ -1,4 +1,4 @@ -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type ViewFilterEntity } from 'src/engine/metadata-modules/view-filter/entities/view-filter.entity'; export type FlatViewFilter = FlatEntityFrom; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-view-group/types/flat-view-group.type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-view-group/types/flat-view-group.type.ts index ac55795448e..9667a47d4b6 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-view-group/types/flat-view-group.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-view-group/types/flat-view-group.type.ts @@ -1,4 +1,4 @@ -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type ViewGroupEntity } from 'src/engine/metadata-modules/view-group/entities/view-group.entity'; export type FlatViewGroup = FlatEntityFrom; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-view/types/flat-view.type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-view/types/flat-view.type.ts index 532d13f29e7..e7d3449e2cf 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-view/types/flat-view.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-view/types/flat-view.type.ts @@ -1,4 +1,4 @@ -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity'; export type FlatView = FlatEntityFrom< diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type.ts index a3a18c01edc..d88b18b2102 100644 --- a/packages/twenty-server/src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type.ts @@ -1,4 +1,4 @@ -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type RouteTriggerEntity } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; export type FlatRouteTrigger = FlatEntityFrom; diff --git a/packages/twenty-server/src/engine/metadata-modules/row-level-permission-predicate/types/flat-row-level-permission-predicate-group.type.ts b/packages/twenty-server/src/engine/metadata-modules/row-level-permission-predicate/types/flat-row-level-permission-predicate-group.type.ts index f8e0237f8b1..ec8c1b475c9 100644 --- a/packages/twenty-server/src/engine/metadata-modules/row-level-permission-predicate/types/flat-row-level-permission-predicate-group.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/row-level-permission-predicate/types/flat-row-level-permission-predicate-group.type.ts @@ -1,6 +1,6 @@ /* @license Enterprise */ -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type RowLevelPermissionPredicateGroupEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate-group.entity'; export type FlatRowLevelPermissionPredicateGroup = diff --git a/packages/twenty-server/src/engine/metadata-modules/row-level-permission-predicate/types/flat-row-level-permission-predicate.type.ts b/packages/twenty-server/src/engine/metadata-modules/row-level-permission-predicate/types/flat-row-level-permission-predicate.type.ts index 09f5deace61..e9d496fa03e 100644 --- a/packages/twenty-server/src/engine/metadata-modules/row-level-permission-predicate/types/flat-row-level-permission-predicate.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/row-level-permission-predicate/types/flat-row-level-permission-predicate.type.ts @@ -1,6 +1,6 @@ /* @license Enterprise */ -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type RowLevelPermissionPredicateEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate.entity'; export type FlatRowLevelPermissionPredicate = diff --git a/packages/twenty-server/src/engine/metadata-modules/serverless-function-layer/types/flat-serverless-function-layer.type.ts b/packages/twenty-server/src/engine/metadata-modules/serverless-function-layer/types/flat-serverless-function-layer.type.ts index 2cb2b0003c2..95a9510cd0f 100644 --- a/packages/twenty-server/src/engine/metadata-modules/serverless-function-layer/types/flat-serverless-function-layer.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/serverless-function-layer/types/flat-serverless-function-layer.type.ts @@ -1,4 +1,4 @@ -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type ServerlessFunctionLayerEntity } from 'src/engine/metadata-modules/serverless-function-layer/serverless-function-layer.entity'; export type FlatServerlessFunctionLayer = diff --git a/packages/twenty-server/src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type.ts b/packages/twenty-server/src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type.ts index a2952556d6c..a7a9a0fe9d3 100644 --- a/packages/twenty-server/src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type.ts @@ -1,6 +1,6 @@ import { type Sources } from 'twenty-shared/types'; -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; +import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity'; export type FlatServerlessFunction = diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/__tests__/universal-flat-field-metadata.test-type.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/__tests__/universal-flat-field-metadata.test-type.ts new file mode 100644 index 00000000000..c53a94bf397 --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/__tests__/universal-flat-field-metadata.test-type.ts @@ -0,0 +1,81 @@ +import { type Expect, type HasAllProperties } from 'twenty-shared/testing'; +import { + type FieldMetadataType, + type NullablePartial, +} from 'twenty-shared/types'; + +import { type UniversalFlatFieldMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-field-metadata.type'; + +// Relation field types have defined relation universal identifiers +type DefinedRelationUniversalIdentifierRecord = { + relationTargetFieldMetadataUniversalIdentifier: string; + relationTargetObjectMetadataUniversalIdentifier: string; +}; + +// Non-relation field types have never | null relation universal identifiers +type NotDefinedRelationUniversalIdentifierRecord = { + relationTargetFieldMetadataUniversalIdentifier: never | null; + relationTargetObjectMetadataUniversalIdentifier: never | null; +}; + +// Date properties are cast to strings +type DatePropertiesCastToString = { + createdAt: string; + updatedAt: string; +}; + +// OneToMany relations become ...UniversalIdentifiers arrays +type OneToManyUniversalIdentifierArrays = { + viewFieldUniversalIdentifiers: string[]; + viewFilterUniversalIdentifiers: string[]; + kanbanAggregateOperationViewUniversalIdentifiers: string[]; + calendarViewUniversalIdentifiers: string[]; + mainGroupByFieldMetadataViewUniversalIdentifiers: string[]; +}; + +// Narrowed relation universal identifier assertions - verifies conditional typing is preserved +// eslint-disable-next-line unused-imports/no-unused-vars +type RelationUniversalIdentifierAssertions = [ + // Non-relation types have undefined relation universal identifiers + Expect< + HasAllProperties< + UniversalFlatFieldMetadata, + NotDefinedRelationUniversalIdentifierRecord + > + >, + + // Relation types have defined relation universal identifiers + Expect< + HasAllProperties< + UniversalFlatFieldMetadata, + DefinedRelationUniversalIdentifierRecord + > + >, + Expect< + HasAllProperties< + UniversalFlatFieldMetadata, + DefinedRelationUniversalIdentifierRecord + > + >, + + // Abstract type has nullable partial relation universal identifiers + Expect< + HasAllProperties< + UniversalFlatFieldMetadata, + NullablePartial + > + >, +]; + +// eslint-disable-next-line unused-imports/no-unused-vars +type UniversalFlatTransformationAssertions = [ + Expect< + HasAllProperties + >, + Expect< + HasAllProperties< + UniversalFlatFieldMetadata, + OneToManyUniversalIdentifierArrays + > + >, +]; 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 new file mode 100644 index 00000000000..cc5d538f791 --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type.ts @@ -0,0 +1,37 @@ +import { type AllMetadataName } from 'twenty-shared/metadata'; + +import { type CastRecordTypeOrmDatePropertiesToString } from 'src/engine/metadata-modules/flat-entity/types/cast-record-typeorm-date-properties-to-string.type'; +import { type ExtractEntityOneToManyEntityRelationProperties } from 'src/engine/metadata-modules/flat-entity/types/extract-entity-one-to-many-entity-relation-properties.type'; +import { type ExtractEntityRelatedEntityProperties } from 'src/engine/metadata-modules/flat-entity/types/extract-entity-related-entity-properties.type'; +import { type FromMetadataEntityToMetadataName } from 'src/engine/metadata-modules/flat-entity/types/from-metadata-entity-to-metadata-name.type'; +import { type MetadataManyToOneJoinColumn } from 'src/engine/metadata-modules/flat-entity/types/metadata-many-to-one-join-column.type'; +import { type SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface'; +import { type RemoveSuffix } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/remove-suffix.type'; + +// TODO Handle universal settings +export type UniversalFlatEntityFrom< + TEntity extends SyncableEntity, + TMetadataName extends + AllMetadataName = FromMetadataEntityToMetadataName, +> = Omit< + TEntity, + | 'applicationId' + | 'workspaceId' + | 'standardId' + | 'id' + | ExtractEntityRelatedEntityProperties + | Extract, keyof TEntity> + | keyof CastRecordTypeOrmDatePropertiesToString +> & + CastRecordTypeOrmDatePropertiesToString & { + [P in ExtractEntityOneToManyEntityRelationProperties< + TEntity, + SyncableEntity + > & + string as `${RemoveSuffix}UniversalIdentifiers`]: string[]; + } & { + [P in Extract, keyof TEntity> & + string as `${RemoveSuffix}UniversalIdentifier`]: TEntity[P]; + } & { + applicationUniversalIdentifier: string; + }; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-field-metadata.type.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-field-metadata.type.ts new file mode 100644 index 00000000000..173c629508c --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-field-metadata.type.ts @@ -0,0 +1,8 @@ +import { type FieldMetadataType } from 'twenty-shared/types'; + +import { type FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { type UniversalFlatEntityFrom } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type'; + +export type UniversalFlatFieldMetadata< + T extends FieldMetadataType = FieldMetadataType, +> = UniversalFlatEntityFrom, 'fieldMetadata'>; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/__tests__/validate-flat-entity-circular-dependency.util.spec.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/__tests__/validate-flat-entity-circular-dependency.util.spec.ts index 5c3f22829bf..b73f86edfc0 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/__tests__/validate-flat-entity-circular-dependency.util.spec.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/__tests__/validate-flat-entity-circular-dependency.util.spec.ts @@ -1,7 +1,7 @@ import { type EachTestingContext } from 'twenty-shared/testing'; +import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; -import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; import { type CircularDependencyValidationResult, validateFlatEntityCircularDependency, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util.ts index cfd5d86de8d..a00fcefd0af 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util.ts @@ -4,8 +4,8 @@ import { FlatEntityMapsException, FlatEntityMapsExceptionCode, } from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception'; +import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; -import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; type AddFlatEntityToFlatEntityMapsThroughMutationOrThrowArgs< T extends SyncableFlatEntity, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/delete-flat-entity-from-flat-entity-maps-through-mutation-or-throw.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/delete-flat-entity-from-flat-entity-maps-through-mutation-or-throw.util.ts index 88d9b27ae11..82e59a34aa6 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/delete-flat-entity-from-flat-entity-maps-through-mutation-or-throw.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/delete-flat-entity-from-flat-entity-maps-through-mutation-or-throw.util.ts @@ -4,8 +4,8 @@ import { FlatEntityMapsException, FlatEntityMapsExceptionCode, } from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception'; +import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; -import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; export type DeleteFlatEntityFromFlatEntityMapsThroughMutationOrThrowArgs< T extends SyncableFlatEntity, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/replace-flat-entity-in-flat-entity-maps-through-mutation-or-throw.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/replace-flat-entity-in-flat-entity-maps-through-mutation-or-throw.util.ts index 2e06da0a9c4..412618ec8f7 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/replace-flat-entity-in-flat-entity-maps-through-mutation-or-throw.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/replace-flat-entity-in-flat-entity-maps-through-mutation-or-throw.util.ts @@ -1,5 +1,5 @@ +import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; -import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util'; import { deleteFlatEntityFromFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/delete-flat-entity-from-flat-entity-maps-through-mutation-or-throw.util'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/validate-flat-entity-circular-dependency.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/validate-flat-entity-circular-dependency.util.ts index 4aa82ce60b8..200f8152d2a 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/validate-flat-entity-circular-dependency.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/validate-flat-entity-circular-dependency.util.ts @@ -1,7 +1,7 @@ import { isDefined } from 'twenty-shared/utils'; +import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; -import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; export type CircularDependencyValidationSuccess = { status: 'success';