Compare commits

...

8 Commits

Author SHA1 Message Date
prastoin 1a09822bc5 lint 2026-02-12 17:54:05 +01:00
prastoin c86a905b91 fix 2026-02-12 17:50:03 +01:00
prastoin 61d7054487 fix(server): remove unused transpilers 2026-02-12 17:40:30 +01:00
prastoin a47ddef0ec fix 2026-02-12 16:49:22 +01:00
prastoin f91d4a0c82 fix 2026-02-12 16:40:30 +01:00
prastoin 895c2d3c7a lint 2026-02-12 16:37:28 +01:00
prastoin 5bce5fe472 fix(server): index comparison keys 2026-02-12 16:37:26 +01:00
prastoin 9a655d5ab8 wip 2026-02-12 16:37:10 +01:00
37 changed files with 1400 additions and 428 deletions
@@ -66,9 +66,9 @@ exports[`ALL_UNIVERSAL_FLAT_ENTITY_PROPERTIES_TO_COMPARE_AND_STRINGIFY should ma
"propertiesToCompare": [
"indexType",
"indexWhereClause",
"universalFlatIndexFieldMetadatas",
"isUnique",
"name",
"universalFlatIndexFieldMetadatas",
],
"propertiesToStringify": [
"universalFlatIndexFieldMetadatas",
@@ -4,9 +4,31 @@ import {
} from 'twenty-shared/metadata';
import { ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME } from 'src/engine/metadata-modules/flat-entity/constant/all-entity-properties-configuration-by-metadata-name.constant';
import { type MetadataFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity.type';
import { type MetadataUniversalFlatEntityPropertiesToCompare } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/metadata-universal-flat-entity-properties-to-compare.type';
import { type MetadataUniversalFlatEntityPropertiesToStringify } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/metadata-universal-flat-entity-properties-to-stringify.type';
type PropertyConfiguration = {
universalProperty: string | undefined;
toStringify: boolean;
toCompare: boolean;
};
// TODO remove once https://github.com/twentyhq/core-team-issues/issues/2227 has been resolved
const EXTRA_PROPERTIES_TO_COMPARE = {
index: {
flatIndexFieldMetadatas: {
toStringify: true,
universalProperty: 'universalFlatIndexFieldMetadatas',
toCompare: true,
},
},
} as const satisfies {
[P in AllMetadataName]?: Partial<
Record<keyof MetadataFlatEntity<P>, PropertyConfiguration>
>;
};
type UniversalFlatEntityPropertiesToCompareAndStringify<
T extends AllMetadataName,
> = {
@@ -18,18 +40,23 @@ const computeUniversalFlatEntityPropertiesToCompareAndStringify = <
>(
metadataName: T,
): UniversalFlatEntityPropertiesToCompareAndStringify<T> => {
const entries = Object.entries(
ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME[metadataName],
) as [
string,
{ universalProperty: string | undefined; toStringify: boolean },
][];
const entries = Object.entries({
...ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME[metadataName],
...EXTRA_PROPERTIES_TO_COMPARE[
metadataName as keyof typeof EXTRA_PROPERTIES_TO_COMPARE
],
}) as [string, PropertyConfiguration][];
const accumulator: UniversalFlatEntityPropertiesToCompareAndStringify<T> = {
propertiesToCompare: [],
propertiesToStringify: [],
};
for (const [property, configuration] of entries) {
if (!configuration.toCompare) {
continue;
}
const comparedProperty = configuration.universalProperty ?? property;
accumulator.propertiesToCompare.push(
@@ -1,9 +1,8 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type AddSuffixToEntityOneToManyProperties } from 'src/engine/metadata-modules/flat-entity/types/add-suffix-to-entity-one-to-many-properties.type';
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';
import { type FromMetadataEntityToMetadataName } from 'src/engine/metadata-modules/flat-entity/types/from-metadata-entity-to-metadata-name.type';
import { type ScalarFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/scalar-flat-entity.type';
import { type SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface';
import { type UniversalFlatEntityExtraProperties } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type';
@@ -14,18 +13,11 @@ export type SyncableFlatEntity = Omit<
id: string;
};
type AtomicFlatEntity<TEntity> = Omit<
TEntity,
| ExtractEntityRelatedEntityProperties<TEntity>
| keyof CastRecordTypeOrmDatePropertiesToString<TEntity>
>;
export type FlatEntityFrom<
TEntity,
// Required to be passed for narrowed type
TMetadataName extends AllMetadataName | undefined = undefined,
> = AtomicFlatEntity<TEntity> &
CastRecordTypeOrmDatePropertiesToString<TEntity> &
> = ScalarFlatEntity<TEntity> &
AddSuffixToEntityOneToManyProperties<TEntity, 'ids'> &
(TEntity extends SyncableEntity
? UniversalFlatEntityExtraProperties<
@@ -1,6 +1,9 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME } from 'src/engine/metadata-modules/flat-entity/constant/all-entity-properties-configuration-by-metadata-name.constant';
import {
type ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME,
type MetadataEntityComparablePropertyName,
} from 'src/engine/metadata-modules/flat-entity/constant/all-entity-properties-configuration-by-metadata-name.constant';
import { type MetadataFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity.type';
type IsUniversalMappedProperty<
@@ -13,15 +16,19 @@ type IsUniversalMappedProperty<
export type FlatEntityUpdate<
T extends AllMetadataName,
MetadataPropertyConfig = (typeof ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME)[T],
TComparedKeys extends
keyof MetadataPropertyConfig = MetadataEntityComparablePropertyName<T> &
keyof MetadataPropertyConfig,
> = Partial<
Pick<
MetadataFlatEntity<T>,
Extract<keyof MetadataFlatEntity<T>, keyof MetadataPropertyConfig>
Extract<keyof MetadataFlatEntity<T>, TComparedKeys>
>
> & {
[K in keyof MetadataPropertyConfig as [
never,
] extends IsUniversalMappedProperty<MetadataPropertyConfig, K>
[K in TComparedKeys as [never] extends IsUniversalMappedProperty<
MetadataPropertyConfig,
K
>
? never
: IsUniversalMappedProperty<MetadataPropertyConfig, K>]?: never;
};
@@ -0,0 +1,9 @@
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<TEntity> = Omit<
TEntity,
| ExtractEntityRelatedEntityProperties<TEntity>
| keyof CastRecordTypeOrmDatePropertiesToString<TEntity>
> &
CastRecordTypeOrmDatePropertiesToString<TEntity>;
@@ -1,7 +1,10 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type Equal, type Expect } from 'twenty-shared/testing';
import { type ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME } from 'src/engine/metadata-modules/flat-entity/constant/all-entity-properties-configuration-by-metadata-name.constant';
import {
type ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME,
type MetadataEntityComparablePropertyName,
} from 'src/engine/metadata-modules/flat-entity/constant/all-entity-properties-configuration-by-metadata-name.constant';
import { type MetadataUniversalFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-universal-flat-entity.type';
type ExtractPropertyToCompare<
@@ -14,9 +17,12 @@ type ExtractPropertyToCompare<
export type MetadataUniversalFlatEntityPropertiesToCompare<
T extends AllMetadataName,
MetadataConfig = (typeof ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME)[T],
TComparedKeys extends
keyof MetadataConfig = MetadataEntityComparablePropertyName<T> &
keyof MetadataConfig,
> = {
[P in keyof MetadataConfig]: ExtractPropertyToCompare<MetadataConfig, P>;
}[keyof MetadataConfig] &
[P in TComparedKeys]: ExtractPropertyToCompare<MetadataConfig, P>;
}[TComparedKeys] &
keyof MetadataUniversalFlatEntity<T>;
// eslint-disable-next-line unused-imports/no-unused-vars
@@ -2,12 +2,14 @@ import { type AllMetadataName } from 'twenty-shared/metadata';
import { type ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME } from 'src/engine/metadata-modules/flat-entity/constant/all-entity-properties-configuration-by-metadata-name.constant';
type ExtractKeysWithToStringify<T> = {
[K in keyof T]: T[K] extends { toStringify: true } ? K : never;
type ExtractComparableKeysWithToStringify<T> = {
[K in keyof T]: T[K] extends { toCompare: true; toStringify: true }
? K
: never;
}[keyof T];
export type MetadataUniversalFlatEntityPropertiesToStringify<
T extends AllMetadataName,
> = ExtractKeysWithToStringify<
> = ExtractComparableKeysWithToStringify<
(typeof ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME)[T]
>;
@@ -3,7 +3,7 @@ import { type IndexFieldMetadataEntity } from 'src/engine/metadata-modules/index
import { type IndexMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity';
import { type UniversalFlatEntityFrom } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type';
// Note: IndexFieldMetadataEntity is just in between a SyncableEntity and a jsonb we should decide one of both
// Note: IndexFieldMetadataEntity is just in between a SyncableEntity and a jsonb we should decide one of both https://github.com/twentyhq/core-team-issues/issues/2227
export type UniversalFlatIndexFieldMetadata = Omit<
IndexFieldMetadataEntity,
| 'indexMetadataId'
@@ -22,7 +22,7 @@ export function transformUniversalFlatEntityForComparison<
if (
propertiesToStringify.includes(
propertyToCompare as MetadataUniversalFlatEntityPropertiesToStringify<T>,
propertyToCompare as string as MetadataUniversalFlatEntityPropertiesToStringify<T>,
)
) {
const orderedValue = orderObjectProperties(currentValue);
@@ -4,7 +4,6 @@ import { v4 } from 'uuid';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity';
import {
FlatCreateAgentAction,
UniversalCreateAgentAction,
@@ -42,15 +41,12 @@ export class CreateAgentActionHandlerService extends WorkspaceMigrationRunnerAct
async executeForMetadata(
context: WorkspaceMigrationActionRunnerContext<FlatCreateAgentAction>,
): Promise<void> {
const { flatAction, queryRunner, workspaceId } = context;
const { flatAction, queryRunner } = context;
const { flatEntity } = flatAction;
const agentRepository =
queryRunner.manager.getRepository<AgentEntity>(AgentEntity);
await agentRepository.save({
...flatEntity,
workspaceId,
await this.insertFlatEntitiesInRepository({
queryRunner,
flatEntities: [flatEntity],
});
}
@@ -4,7 +4,6 @@ import { v4 } from 'uuid';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { CommandMenuItemEntity } from 'src/engine/metadata-modules/command-menu-item/entities/command-menu-item.entity';
import { resolveUniversalRelationIdentifiersToIds } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/resolve-universal-relation-identifiers-to-ids.util';
import {
FlatCreateCommandMenuItemAction,
@@ -53,17 +52,12 @@ export class CreateCommandMenuItemActionHandlerService extends WorkspaceMigratio
async executeForMetadata(
context: WorkspaceMigrationActionRunnerContext<FlatCreateCommandMenuItemAction>,
): Promise<void> {
const { flatAction, queryRunner, workspaceId } = context;
const { flatAction, queryRunner } = context;
const { flatEntity } = flatAction;
const commandMenuItemRepository =
queryRunner.manager.getRepository<CommandMenuItemEntity>(
CommandMenuItemEntity,
);
await commandMenuItemRepository.insert({
...flatEntity,
workspaceId,
await this.insertFlatEntitiesInRepository({
queryRunner,
flatEntities: [flatEntity],
});
}
@@ -7,7 +7,6 @@ import { v4 } from 'uuid';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { type MetadataFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity-maps.type';
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
@@ -91,12 +90,10 @@ export class CreateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
const { queryRunner, flatAction } = context;
const { flatFieldMetadatas } = flatAction;
const fieldMetadataRepository =
queryRunner.manager.getRepository<FieldMetadataEntity>(
FieldMetadataEntity,
);
await fieldMetadataRepository.insert(flatFieldMetadatas);
await this.insertFlatEntitiesInRepository({
queryRunner,
flatEntities: flatFieldMetadatas,
});
}
async executeForWorkspaceSchema(
@@ -7,7 +7,6 @@ import { v4 } from 'uuid';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { FileStorageService } from 'src/engine/core-modules/file-storage/file-storage.service';
import { FrontComponentEntity } from 'src/engine/metadata-modules/front-component/entities/front-component.entity';
import {
FrontComponentException,
FrontComponentExceptionCode,
@@ -62,14 +61,9 @@ export class CreateFrontComponentActionHandlerService extends WorkspaceMigration
});
}
const frontComponentRepository =
queryRunner.manager.getRepository<FrontComponentEntity>(
FrontComponentEntity,
);
await frontComponentRepository.insert({
...frontComponent,
workspaceId,
await this.insertFlatEntitiesInRepository({
queryRunner,
flatEntities: [frontComponent],
});
}
@@ -5,16 +5,14 @@ import { v4 } from 'uuid';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
import { IndexFieldMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-field-metadata.entity';
import { WorkspaceSchemaManagerService } from 'src/engine/twenty-orm/workspace-schema-manager/workspace-schema-manager.service';
import {
type FlatCreateIndexAction,
type UniversalCreateIndexAction,
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/index/types/workspace-migration-index-action';
import { fromUniversalFlatIndexToFlatIndex } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/index/utils/from-universal-flat-index-to-flat-index.util';
import {
createIndexInWorkspaceSchema,
insertIndexMetadata,
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/index/utils/index-action-handler.utils';
import { createIndexInWorkspaceSchema } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/index/utils/index-action-handler.utils';
import {
type WorkspaceMigrationActionRunnerArgs,
type WorkspaceMigrationActionRunnerContext,
@@ -55,11 +53,20 @@ export class CreateIndexActionHandlerService extends WorkspaceMigrationRunnerAct
context: WorkspaceMigrationActionRunnerContext<FlatCreateIndexAction>,
): Promise<void> {
const { flatAction, queryRunner } = context;
const { flatEntity: flatIndexMetadata } = flatAction;
await insertIndexMetadata({
flatIndexMetadata: flatAction.flatEntity,
await this.insertFlatEntitiesInRepository({
queryRunner,
flatEntities: [flatIndexMetadata],
});
const indexFieldMetadataRepository = queryRunner.manager.getRepository(
IndexFieldMetadataEntity,
);
await indexFieldMetadataRepository.insert(
flatIndexMetadata.flatIndexFieldMetadatas,
);
}
async executeForWorkspaceSchema(
@@ -6,6 +6,7 @@ import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-mana
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
import { findFlatEntityByUniversalIdentifierOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier-or-throw.util';
import { IndexFieldMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-field-metadata.entity';
import { WorkspaceSchemaManagerService } from 'src/engine/twenty-orm/workspace-schema-manager/workspace-schema-manager.service';
import { getWorkspaceSchemaName } from 'src/engine/workspace-datasource/utils/get-workspace-schema-name.util';
import {
@@ -17,7 +18,6 @@ import {
createIndexInWorkspaceSchema,
deleteIndexMetadata,
dropIndexFromWorkspaceSchema,
insertIndexMetadata,
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/index/utils/index-action-handler.utils';
import {
type WorkspaceMigrationActionRunnerArgs,
@@ -66,19 +66,32 @@ export class UpdateIndexActionHandlerService extends WorkspaceMigrationRunnerAct
context: WorkspaceMigrationActionRunnerContext<FlatUpdateIndexAction>,
): Promise<void> {
const { flatAction, queryRunner, workspaceId } = context;
const { updatedFlatIndex } = flatAction;
// Delete old index metadata
await deleteIndexMetadata({
entityId: flatAction.entityId,
queryRunner,
workspaceId,
});
// Create new index metadata
await insertIndexMetadata({
flatIndexMetadata: flatAction.updatedFlatIndex,
await this.insertFlatEntitiesInRepository({
queryRunner,
flatEntities: [updatedFlatIndex],
});
const indexFieldMetadataRepository = queryRunner.manager.getRepository(
IndexFieldMetadataEntity,
);
const indexFieldMetadataToInsert =
updatedFlatIndex.flatIndexFieldMetadatas.map(
(flatIndexFieldMetadata) => ({
...flatIndexFieldMetadata,
indexMetadataId: updatedFlatIndex.id,
}),
);
await indexFieldMetadataRepository.insert(indexFieldMetadataToInsert);
}
async executeForWorkspaceSchema(
@@ -15,14 +15,9 @@ import {
type FlatIndexFieldMetadata,
type FlatIndexMetadata,
} from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
import { IndexFieldMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-field-metadata.entity';
import { IndexMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import { IndexMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity';
import { type WorkspaceSchemaManagerService } from 'src/engine/twenty-orm/workspace-schema-manager/workspace-schema-manager.service';
import {
WorkspaceMigrationActionExecutionException,
WorkspaceMigrationActionExecutionExceptionCode,
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/exceptions/workspace-migration-action-execution.exception';
import { getWorkspaceSchemaContextForMigration } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/get-workspace-schema-context-for-migration.util';
export const computeFlatIndexFieldColumnNames = ({
@@ -81,45 +76,6 @@ export const computeFlatIndexFieldColumnNames = ({
});
};
export const insertIndexMetadata = async ({
flatIndexMetadata,
queryRunner,
}: {
flatIndexMetadata: FlatIndexMetadata;
queryRunner: QueryRunner;
}): Promise<void> => {
const indexMetadataRepository =
queryRunner.manager.getRepository<IndexMetadataEntity>(IndexMetadataEntity);
const indexFieldMetadataRepository =
queryRunner.manager.getRepository<IndexFieldMetadataEntity>(
IndexFieldMetadataEntity,
);
const { flatIndexFieldMetadatas, ...indexMetadataToInsert } =
flatIndexMetadata;
const indexInsertResult = await indexMetadataRepository.insert(
indexMetadataToInsert,
);
if (indexInsertResult.identifiers.length !== 1) {
throw new WorkspaceMigrationActionExecutionException({
message: 'Failed to create index metadata',
code: WorkspaceMigrationActionExecutionExceptionCode.INTERNAL_SERVER_ERROR,
});
}
const indexMetadataId = indexInsertResult.identifiers[0].id;
const indexFieldMetadataToInsert = flatIndexFieldMetadatas.map(
(flatIndexFieldMetadata) => ({
...flatIndexFieldMetadata,
indexMetadataId,
}),
);
await indexFieldMetadataRepository.insert(indexFieldMetadataToInsert);
};
export const deleteIndexMetadata = async ({
entityId,
queryRunner,
@@ -4,7 +4,6 @@ import { v4 } from 'uuid';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { LogicFunctionEntity } from 'src/engine/metadata-modules/logic-function/logic-function.entity';
import {
FlatCreateLogicFunctionAction,
UniversalCreateLogicFunctionAction,
@@ -38,17 +37,12 @@ export class CreateLogicFunctionActionHandlerService extends WorkspaceMigrationR
async executeForMetadata(
context: WorkspaceMigrationActionRunnerContext<FlatCreateLogicFunctionAction>,
): Promise<void> {
const { flatAction, queryRunner, workspaceId } = context;
const { flatAction, queryRunner } = context;
const { flatEntity: logicFunction } = flatAction;
const logicFunctionRepository =
queryRunner.manager.getRepository<LogicFunctionEntity>(
LogicFunctionEntity,
);
await logicFunctionRepository.insert({
...logicFunction,
workspaceId,
await this.insertFlatEntitiesInRepository({
queryRunner,
flatEntities: [logicFunction],
});
}
@@ -4,7 +4,6 @@ import { v4 } from 'uuid';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { NavigationMenuItemEntity } from 'src/engine/metadata-modules/navigation-menu-item/entities/navigation-menu-item.entity';
import { resolveUniversalRelationIdentifiersToIds } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/resolve-universal-relation-identifiers-to-ids.util';
import {
FlatCreateNavigationMenuItemAction,
@@ -54,17 +53,12 @@ export class CreateNavigationMenuItemActionHandlerService extends WorkspaceMigra
async executeForMetadata(
context: WorkspaceMigrationActionRunnerContext<FlatCreateNavigationMenuItemAction>,
): Promise<void> {
const { flatAction, queryRunner, workspaceId } = context;
const { flatAction, queryRunner } = context;
const { flatEntity } = flatAction;
const navigationMenuItemRepository =
queryRunner.manager.getRepository<NavigationMenuItemEntity>(
NavigationMenuItemEntity,
);
await navigationMenuItemRepository.insert({
...flatEntity,
workspaceId,
await this.insertFlatEntitiesInRepository({
queryRunner,
flatEntities: [flatEntity],
});
}
@@ -5,10 +5,9 @@ import { v4 } from 'uuid';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity';
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { ALL_METADATA_ENTITY_BY_METADATA_NAME } from 'src/engine/metadata-modules/flat-entity/constant/all-metadata-entity-by-metadata-name.constant';
import { isCompositeFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-composite-flat-field-metadata.util';
import { isEnumFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-enum-flat-field-metadata.util';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { WorkspaceSchemaManagerService } from 'src/engine/twenty-orm/workspace-schema-manager/workspace-schema-manager.service';
import {
FlatCreateObjectAction,
@@ -20,6 +19,7 @@ import {
WorkspaceMigrationActionRunnerContext,
type WorkspaceMigrationActionRunnerArgs,
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
import { flatEntityToScalarFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/flat-entity-to-scalar-flat-entity.util';
import { generateColumnDefinitions } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/generate-column-definitions.util';
import { getWorkspaceSchemaContextForMigration } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/get-workspace-schema-context-for-migration.util';
import {
@@ -107,19 +107,23 @@ export class CreateObjectActionHandlerService extends WorkspaceMigrationRunnerAc
const { queryRunner, flatAction } = context;
const { flatEntity: flatObjectMetadata, flatFieldMetadatas } = flatAction;
const objectMetadataRepository =
queryRunner.manager.getRepository<ObjectMetadataEntity>(
ObjectMetadataEntity,
);
await this.insertFlatEntitiesInRepository({
queryRunner,
flatEntities: [flatObjectMetadata],
});
await objectMetadataRepository.insert(flatObjectMetadata);
const scalarFieldMetadatas = flatFieldMetadatas.map((flatFieldMetadata) =>
flatEntityToScalarFlatEntity({
metadataName: 'fieldMetadata',
flatEntity: flatFieldMetadata,
}),
);
const fieldMetadataRepository =
queryRunner.manager.getRepository<FieldMetadataEntity>(
FieldMetadataEntity,
);
const fieldMetadataRepository = queryRunner.manager.getRepository(
ALL_METADATA_ENTITY_BY_METADATA_NAME['fieldMetadata'],
);
await fieldMetadataRepository.insert(flatFieldMetadatas);
await fieldMetadataRepository.insert(scalarFieldMetadatas);
}
async executeForWorkspaceSchema(
@@ -4,7 +4,6 @@ import { v4 } from 'uuid';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { PageLayoutTabEntity } from 'src/engine/metadata-modules/page-layout-tab/entities/page-layout-tab.entity';
import { resolveUniversalRelationIdentifiersToIds } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/resolve-universal-relation-identifiers-to-ids.util';
import {
FlatCreatePageLayoutTabAction,
@@ -52,17 +51,12 @@ export class CreatePageLayoutTabActionHandlerService extends WorkspaceMigrationR
async executeForMetadata(
context: WorkspaceMigrationActionRunnerContext<FlatCreatePageLayoutTabAction>,
): Promise<void> {
const { flatAction, queryRunner, workspaceId } = context;
const { flatAction, queryRunner } = context;
const { flatEntity } = flatAction;
const pageLayoutTabRepository =
queryRunner.manager.getRepository<PageLayoutTabEntity>(
PageLayoutTabEntity,
);
await pageLayoutTabRepository.insert({
...flatEntity,
workspaceId,
await this.insertFlatEntitiesInRepository({
queryRunner,
flatEntities: [flatEntity],
});
}
@@ -4,7 +4,6 @@ import { v4 } from 'uuid';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { PageLayoutWidgetEntity } from 'src/engine/metadata-modules/page-layout-widget/entities/page-layout-widget.entity';
import { resolveUniversalRelationIdentifiersToIds } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/resolve-universal-relation-identifiers-to-ids.util';
import {
FlatCreatePageLayoutWidgetAction,
@@ -61,17 +60,12 @@ export class CreatePageLayoutWidgetActionHandlerService extends WorkspaceMigrati
async executeForMetadata(
context: WorkspaceMigrationActionRunnerContext<FlatCreatePageLayoutWidgetAction>,
): Promise<void> {
const { flatAction, queryRunner, workspaceId } = context;
const { flatAction, queryRunner } = context;
const { flatEntity } = flatAction;
const pageLayoutWidgetRepository =
queryRunner.manager.getRepository<PageLayoutWidgetEntity>(
PageLayoutWidgetEntity,
);
await pageLayoutWidgetRepository.insert({
...flatEntity,
workspaceId,
await this.insertFlatEntitiesInRepository({
queryRunner,
flatEntities: [flatEntity],
});
}
@@ -9,7 +9,6 @@ import {
FlatEntityMapsException,
FlatEntityMapsExceptionCode,
} from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception';
import { PageLayoutEntity } from 'src/engine/metadata-modules/page-layout/entities/page-layout.entity';
import { resolveUniversalRelationIdentifiersToIds } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/resolve-universal-relation-identifiers-to-ids.util';
import {
FlatCreatePageLayoutAction,
@@ -88,15 +87,12 @@ export class CreatePageLayoutActionHandlerService extends WorkspaceMigrationRunn
async executeForMetadata(
context: WorkspaceMigrationActionRunnerContext<FlatCreatePageLayoutAction>,
): Promise<void> {
const { flatAction, queryRunner, workspaceId } = context;
const { flatAction, queryRunner } = context;
const { flatEntity } = flatAction;
const pageLayoutRepository =
queryRunner.manager.getRepository<PageLayoutEntity>(PageLayoutEntity);
await pageLayoutRepository.insert({
...flatEntity,
workspaceId,
await this.insertFlatEntitiesInRepository({
queryRunner,
flatEntities: [flatEntity],
});
}
@@ -4,7 +4,6 @@ import { v4 } from 'uuid';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { resolveUniversalRelationIdentifiersToIds } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/resolve-universal-relation-identifiers-to-ids.util';
import {
FlatCreateRoleTargetAction,
@@ -47,15 +46,12 @@ export class CreateRoleTargetActionHandlerService extends WorkspaceMigrationRunn
async executeForMetadata(
context: WorkspaceMigrationActionRunnerContext<FlatCreateRoleTargetAction>,
): Promise<void> {
const { flatAction, queryRunner, workspaceId } = context;
const { flatEntity: roleTarget } = flatAction;
const { flatAction, queryRunner } = context;
const { flatEntity } = flatAction;
const roleTargetRepository =
queryRunner.manager.getRepository<RoleTargetEntity>(RoleTargetEntity);
await roleTargetRepository.insert({
...roleTarget,
workspaceId,
await this.insertFlatEntitiesInRepository({
queryRunner,
flatEntities: [flatEntity],
});
}
@@ -4,7 +4,6 @@ import { v4 } from 'uuid';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import {
FlatCreateRoleAction,
UniversalCreateRoleAction,
@@ -48,15 +47,12 @@ export class CreateRoleActionHandlerService extends WorkspaceMigrationRunnerActi
async executeForMetadata(
context: WorkspaceMigrationActionRunnerContext<FlatCreateRoleAction>,
): Promise<void> {
const { flatAction, queryRunner, workspaceId } = context;
const { flatEntity: role } = flatAction;
const { flatAction, queryRunner } = context;
const { flatEntity } = flatAction;
const roleRepository =
queryRunner.manager.getRepository<RoleEntity>(RoleEntity);
await roleRepository.insert({
...role,
workspaceId,
await this.insertFlatEntitiesInRepository({
queryRunner,
flatEntities: [flatEntity],
});
}
@@ -6,7 +6,6 @@ import { v4 } from 'uuid';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { RowLevelPermissionPredicateGroupEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate-group.entity';
import { resolveUniversalRelationIdentifiersToIds } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/resolve-universal-relation-identifiers-to-ids.util';
import {
FlatCreateRowLevelPermissionPredicateGroupAction,
@@ -57,17 +56,12 @@ export class CreateRowLevelPermissionPredicateGroupActionHandlerService extends
async executeForMetadata(
context: WorkspaceMigrationActionRunnerContext<FlatCreateRowLevelPermissionPredicateGroupAction>,
): Promise<void> {
const { flatAction, queryRunner, workspaceId } = context;
const { flatAction, queryRunner } = context;
const { flatEntity } = flatAction;
const repository =
queryRunner.manager.getRepository<RowLevelPermissionPredicateGroupEntity>(
RowLevelPermissionPredicateGroupEntity,
);
await repository.insert({
...flatEntity,
workspaceId,
await this.insertFlatEntitiesInRepository({
queryRunner,
flatEntities: [flatEntity],
});
}
@@ -6,7 +6,6 @@ import { v4 } from 'uuid';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { RowLevelPermissionPredicateEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate.entity';
import { resolveUniversalRelationIdentifiersToIds } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/resolve-universal-relation-identifiers-to-ids.util';
import {
FlatCreateRowLevelPermissionPredicateAction,
@@ -59,17 +58,12 @@ export class CreateRowLevelPermissionPredicateActionHandlerService extends Works
async executeForMetadata(
context: WorkspaceMigrationActionRunnerContext<FlatCreateRowLevelPermissionPredicateAction>,
): Promise<void> {
const { flatAction, queryRunner, workspaceId } = context;
const { flatAction, queryRunner } = context;
const { flatEntity } = flatAction;
const repository =
queryRunner.manager.getRepository<RowLevelPermissionPredicateEntity>(
RowLevelPermissionPredicateEntity,
);
await repository.insert({
...flatEntity,
workspaceId,
await this.insertFlatEntitiesInRepository({
queryRunner,
flatEntities: [flatEntity],
});
}
@@ -4,7 +4,6 @@ import { v4 } from 'uuid';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { SkillEntity } from 'src/engine/metadata-modules/skill/entities/skill.entity';
import {
FlatCreateSkillAction,
UniversalCreateSkillAction,
@@ -42,15 +41,12 @@ export class CreateSkillActionHandlerService extends WorkspaceMigrationRunnerAct
async executeForMetadata(
context: WorkspaceMigrationActionRunnerContext<FlatCreateSkillAction>,
): Promise<void> {
const { flatAction, queryRunner, workspaceId } = context;
const { flatAction, queryRunner } = context;
const { flatEntity } = flatAction;
const skillRepository =
queryRunner.manager.getRepository<SkillEntity>(SkillEntity);
await skillRepository.save({
...flatEntity,
workspaceId,
await this.insertFlatEntitiesInRepository({
queryRunner,
flatEntities: [flatEntity],
});
}
@@ -4,7 +4,6 @@ import { v4 } from 'uuid';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { ViewFieldEntity } from 'src/engine/metadata-modules/view-field/entities/view-field.entity';
import { resolveUniversalRelationIdentifiersToIds } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/resolve-universal-relation-identifiers-to-ids.util';
import {
FlatCreateViewFieldAction,
@@ -54,15 +53,12 @@ export class CreateViewFieldActionHandlerService extends WorkspaceMigrationRunne
async executeForMetadata(
context: WorkspaceMigrationActionRunnerContext<FlatCreateViewFieldAction>,
): Promise<void> {
const { flatAction, queryRunner, workspaceId } = context;
const { flatAction, queryRunner } = context;
const { flatEntity } = flatAction;
const viewFieldRepository =
queryRunner.manager.getRepository<ViewFieldEntity>(ViewFieldEntity);
await viewFieldRepository.insert({
...flatEntity,
workspaceId,
await this.insertFlatEntitiesInRepository({
queryRunner,
flatEntities: [flatEntity],
});
}
@@ -4,7 +4,6 @@ import { v4 } from 'uuid';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { ViewFilterGroupEntity } from 'src/engine/metadata-modules/view-filter-group/entities/view-filter-group.entity';
import { resolveUniversalRelationIdentifiersToIds } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/resolve-universal-relation-identifiers-to-ids.util';
import {
type FlatCreateViewFilterGroupAction,
@@ -51,17 +50,12 @@ export class CreateViewFilterGroupActionHandlerService extends WorkspaceMigratio
async executeForMetadata(
context: WorkspaceMigrationActionRunnerContext<FlatCreateViewFilterGroupAction>,
): Promise<void> {
const { flatAction, queryRunner, workspaceId } = context;
const { flatAction, queryRunner } = context;
const { flatEntity } = flatAction;
const viewFilterGroupRepository =
queryRunner.manager.getRepository<ViewFilterGroupEntity>(
ViewFilterGroupEntity,
);
await viewFilterGroupRepository.insert({
...flatEntity,
workspaceId,
await this.insertFlatEntitiesInRepository({
queryRunner,
flatEntities: [flatEntity],
});
}
@@ -4,7 +4,6 @@ import { v4 } from 'uuid';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { ViewFilterEntity } from 'src/engine/metadata-modules/view-filter/entities/view-filter.entity';
import { resolveUniversalRelationIdentifiersToIds } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/resolve-universal-relation-identifiers-to-ids.util';
import {
FlatCreateViewFilterAction,
@@ -50,15 +49,12 @@ export class CreateViewFilterActionHandlerService extends WorkspaceMigrationRunn
async executeForMetadata(
context: WorkspaceMigrationActionRunnerContext<FlatCreateViewFilterAction>,
): Promise<void> {
const { flatAction, queryRunner, workspaceId } = context;
const { flatAction, queryRunner } = context;
const { flatEntity } = flatAction;
const viewFilterRepository =
queryRunner.manager.getRepository<ViewFilterEntity>(ViewFilterEntity);
await viewFilterRepository.insert({
...flatEntity,
workspaceId,
await this.insertFlatEntitiesInRepository({
queryRunner,
flatEntities: [flatEntity],
});
}
@@ -4,7 +4,6 @@ import { v4 } from 'uuid';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { ViewGroupEntity } from 'src/engine/metadata-modules/view-group/entities/view-group.entity';
import { resolveUniversalRelationIdentifiersToIds } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/resolve-universal-relation-identifiers-to-ids.util';
import {
FlatCreateViewGroupAction,
@@ -47,15 +46,12 @@ export class CreateViewGroupActionHandlerService extends WorkspaceMigrationRunne
async executeForMetadata(
context: WorkspaceMigrationActionRunnerContext<FlatCreateViewGroupAction>,
): Promise<void> {
const { flatAction, queryRunner, workspaceId } = context;
const { flatAction, queryRunner } = context;
const { flatEntity } = flatAction;
const viewGroupRepository =
queryRunner.manager.getRepository<ViewGroupEntity>(ViewGroupEntity);
await viewGroupRepository.insert({
...flatEntity,
workspaceId,
await this.insertFlatEntitiesInRepository({
queryRunner,
flatEntities: [flatEntity],
});
}
@@ -4,7 +4,6 @@ import { v4 } from 'uuid';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
import { resolveUniversalRelationIdentifiersToIds } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/resolve-universal-relation-identifiers-to-ids.util';
import {
FlatCreateViewAction,
@@ -64,15 +63,12 @@ export class CreateViewActionHandlerService extends WorkspaceMigrationRunnerActi
async executeForMetadata(
context: WorkspaceMigrationActionRunnerContext<FlatCreateViewAction>,
): Promise<void> {
const { flatAction, queryRunner, workspaceId } = context;
const { flatAction, queryRunner } = context;
const { flatEntity } = flatAction;
const viewRepository =
queryRunner.manager.getRepository<ViewEntity>(ViewEntity);
await viewRepository.insert({
...flatEntity,
workspaceId,
await this.insertFlatEntitiesInRepository({
queryRunner,
flatEntities: [flatEntity],
});
}
@@ -4,7 +4,6 @@ import { v4 } from 'uuid';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
import { WebhookEntity } from 'src/engine/metadata-modules/webhook/entities/webhook.entity';
import {
FlatCreateWebhookAction,
UniversalCreateWebhookAction,
@@ -42,15 +41,12 @@ export class CreateWebhookActionHandlerService extends WorkspaceMigrationRunnerA
async executeForMetadata(
context: WorkspaceMigrationActionRunnerContext<FlatCreateWebhookAction>,
): Promise<void> {
const { flatAction, queryRunner, workspaceId } = context;
const { flatAction, queryRunner } = context;
const { flatEntity } = flatAction;
const webhookRepository =
queryRunner.manager.getRepository<WebhookEntity>(WebhookEntity);
await webhookRepository.insert({
...flatEntity,
workspaceId,
await this.insertFlatEntitiesInRepository({
queryRunner,
flatEntities: [flatEntity],
});
}
@@ -1,8 +1,10 @@
import { Inject, SetMetadata } from '@nestjs/common';
import { AllMetadataName } from 'twenty-shared/metadata';
import { QueryRunner } from 'typeorm';
import { LoggerService } from 'src/engine/core-modules/logger/logger.service';
import { ALL_METADATA_ENTITY_BY_METADATA_NAME } from 'src/engine/metadata-modules/flat-entity/constant/all-metadata-entity-by-metadata-name.constant';
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
import { AllFlatEntityTypesByMetadataName } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-types-by-metadata-name';
import { FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
@@ -33,6 +35,7 @@ import {
import { deriveMetadataEventsFromCreateAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/derive-metadata-events-from-create-action.util';
import { deriveMetadataEventsFromDeleteAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/derive-metadata-events-from-delete-action.util';
import { deriveMetadataEventsFromUpdateAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/derive-metadata-events-from-update-action.util';
import { flatEntityToScalarFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/flat-entity-to-scalar-flat-entity.util';
import { optimisticallyApplyCreateActionOnAllFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/optimistically-apply-create-action-on-all-flat-entity-maps.util';
import { optimisticallyApplyDeleteActionOnAllFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/optimistically-apply-delete-action-on-all-flat-entity-maps.util';
import { optimisticallyApplyUpdateActionOnAllFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/optimistically-apply-update-action-on-all-flat-entity-maps.util';
@@ -72,6 +75,26 @@ export abstract class BaseWorkspaceMigrationRunnerActionHandlerService<
context: WorkspaceMigrationActionRunnerArgs<TUniversalAction>,
): Promise<TFlatAction>;
protected async insertFlatEntitiesInRepository({
flatEntities,
queryRunner,
}: {
queryRunner: QueryRunner;
flatEntities: MetadataFlatEntity<TMetadataName>[];
}) {
const metadataEntity =
ALL_METADATA_ENTITY_BY_METADATA_NAME[this.metadataName];
const repository = queryRunner.manager.getRepository(metadataEntity);
const scalarFlatEntities = flatEntities.map((flatEntity) =>
flatEntityToScalarFlatEntity({
flatEntity,
metadataName: this.metadataName,
}),
);
await repository.insert(scalarFlatEntities);
}
protected transpileUniversalDeleteActionToFlatDeleteAction(
context: 'delete' extends TActionType
? WorkspaceMigrationActionRunnerArgs<
@@ -0,0 +1,80 @@
import { FieldMetadataType } from 'twenty-shared/types';
import { getFlatFieldMetadataMock } from 'src/engine/metadata-modules/flat-field-metadata/__mocks__/get-flat-field-metadata.mock';
import { flatEntityToScalarFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/flat-entity-to-scalar-flat-entity.util';
describe('flatEntityToScalarFlatEntity', () => {
it('should return only scalar and structural properties, excluding universal extras', () => {
const flatEntity = getFlatFieldMetadataMock({
id: 'field-metadata-id',
workspaceId: 'workspace-id',
applicationId: 'application-id',
universalIdentifier: 'universal-identifier',
applicationUniversalIdentifier: 'app-universal-id',
objectMetadataId: 'object-metadata-id',
objectMetadataUniversalIdentifier: 'object-universal-id',
type: FieldMetadataType.TEXT,
defaultValue: "'default-value'",
description: 'test description',
icon: 'IconTest',
isActive: true,
isLabelSyncedWithName: false,
isUnique: false,
label: 'Test Label',
name: 'testField',
options: null,
standardOverrides: null,
settings: null,
universalSettings: null,
isCustom: true,
isSystem: false,
isUIReadOnly: false,
isNullable: true,
relationTargetFieldMetadataId: 'relation-target-field-id',
relationTargetFieldMetadataUniversalIdentifier:
'relation-target-field-universal-id',
relationTargetObjectMetadataId: 'relation-target-object-id',
relationTargetObjectMetadataUniversalIdentifier:
'relation-target-object-universal-id',
morphId: null,
createdAt: '2025-01-01T00:00:00.000Z',
updatedAt: '2025-01-01T00:00:00.000Z',
});
const result = flatEntityToScalarFlatEntity({
metadataName: 'fieldMetadata',
flatEntity,
});
expect(result).toMatchInlineSnapshot(`
{
"applicationId": "application-id",
"createdAt": "2025-01-01T00:00:00.000Z",
"defaultValue": "'default-value'",
"description": "test description",
"icon": "IconTest",
"id": "field-metadata-id",
"isActive": true,
"isCustom": true,
"isLabelSyncedWithName": false,
"isNullable": true,
"isSystem": false,
"isUIReadOnly": false,
"isUnique": false,
"label": "Test Label",
"morphId": null,
"name": "testField",
"objectMetadataId": "object-metadata-id",
"options": null,
"relationTargetFieldMetadataId": "relation-target-field-id",
"relationTargetObjectMetadataId": "relation-target-object-id",
"settings": null,
"standardOverrides": null,
"type": "TEXT",
"universalIdentifier": "universal-identifier",
"updatedAt": "2025-01-01T00:00:00.000Z",
"workspaceId": "workspace-id",
}
`);
});
});
@@ -0,0 +1,30 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME } from 'src/engine/metadata-modules/flat-entity/constant/all-entity-properties-configuration-by-metadata-name.constant';
import { type MetadataEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-entity.type';
import { type MetadataFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity.type';
import { type ScalarFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/scalar-flat-entity.type';
export const flatEntityToScalarFlatEntity = <T extends AllMetadataName>({
metadataName,
flatEntity,
}: {
metadataName: T;
flatEntity: MetadataFlatEntity<T>;
}): ScalarFlatEntity<MetadataEntity<T>> => {
const config =
ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME[metadataName];
const result: Record<string, unknown> = {};
const flatEntityRecord = flatEntity as Record<string, unknown>;
for (const key of Object.keys(config)) {
result[key] = flatEntityRecord[key];
}
result.id = flatEntityRecord.id;
result.workspaceId = flatEntityRecord.workspaceId;
result.applicationId = flatEntityRecord.applicationId;
result.universalIdentifier = flatEntityRecord.universalIdentifier;
return result as ScalarFlatEntity<MetadataEntity<T>>;
};