Migrate Views-xxx Index Field Object Skill to be fully universal ( all actions and metadata runner and builder ) + all metadata update actions runner (#17687)

# What this PR does
Overall naming `universal` versus `flat` is not always the most updated
and so on
Will make a big cleaning tour after I've finished the whole migration
Migrating all `view` and ( filter fields etc ) `field` `object` `index`
to the universal pattern on all `services`, `builder` and `runner`
levels

## Universal and flat optimistic tooling

`addUniversalFlatEntityToUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrow`
and its delete counterpart maintain the consistency of
`UniversalFlatEntityMaps` when an entity is created or removed. Beyond
inserting/removing the entity from its own maps, they walk through
`ALL_UNIVERSAL_METADATA_RELATIONS` to update the **aggregator arrays**
on related parent entities — the add appends the new entity's
`universalIdentifier` to the parent's aggregator (e.g. a new viewField's
identifier gets appended to its parent view's
`viewFieldUniversalIdentifiers`), and the delete filters it out. This
keeps the maps in sync so that diff computations and relation lookups
remain accurate throughout the migration building process.

## ALL_UNIVERSAL_METADATA_RELATIONS
`ALL_UNIVERSAL_METADATA_RELATIONS` is the universal counterpart of
`ALL_METADATA_RELATIONS`. It maps each metadata entity to its
many-to-one and one-to-many relations using universal foreign keys
(`*UniversalIdentifier`) instead of database IDs (`*Id`). This allows
migration actions to reference related entities in a workspace-agnostic
way. Relations that are workspace-specific (e.g. `workspace`,
`dataSource`, `userWorkspace`) are set to `null` and skipped during
resolution.

## `workspaceMigrationCreateIdEnrichment`
Reserved to API metadata ( will be able to validate at app installation
lvl )
- Workspace migration `create` actions now carry an optional `id` (and
`fieldIdByUniversalIdentifier` for object/field actions) so that
caller-provided IDs flow through the entire build-validate-run pipeline.
- New `enrichCreateWorkspaceMigrationActionsWithIds` utility resolves
`universalIdentifier → id` mappings after the builder runs and injects
them into the migration actions before the runner persists entities.
- Runner action handlers use the provided IDs instead of generating new
UUIDs, enabling deterministic entity creation for synchronization
workflows.


## `resolveUniversalUpdateRelationIdentifiersToIds`
`resolveUniversalUpdateRelationIdentifiersToIds` converts universal
identifiers (workspace-agnostic, stable keys) in a migration update
payload into concrete database UUIDs, so the update can be applied to a
specific workspace.

It iterates over the many-to-one relations defined in
`ALL_UNIVERSAL_METADATA_RELATIONS` for the given entity type, replaces
each `*UniversalIdentifier` property with its corresponding `*Id` by
looking up the target entity in `allFlatEntityMaps`, and throws if a
non-null identifier can't be resolved.

Used by all `update` action handlers in
`transpileUniversalActionToFlatAction`, avoiding duplicated resolution
logic across handlers.

## What this PR does not
- Migrating twenty-standard declaration to universal
- Migrating all the inputs transpilers to universal
- Migrating all metadata to be fully universal ( we still need to
de-scope the type of all of them and refactor their validator very close
)

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Paul Rastoin
2026-02-09 19:02:38 +01:00
committed by GitHub
parent 2a76e1791e
commit 8c951d3623
366 changed files with 10036 additions and 6606 deletions
@@ -0,0 +1,140 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { assertUnreachable, isDefined } from 'twenty-shared/utils';
import { type UniversalCreateFieldAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/types/workspace-migration-field-action';
import { type UniversalCreateObjectAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/object/types/workspace-migration-object-action';
import { type WorkspaceMigration } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/workspace-migration';
export type IdByUniversalIdentifierByMetadataName = {
[P in AllMetadataName]?: Record<string, string>;
};
const buildFieldIdByUniversalIdentifier = ({
action,
fieldMetadataIdByUniversalIdentifier,
}: {
action: UniversalCreateObjectAction | UniversalCreateFieldAction;
fieldMetadataIdByUniversalIdentifier: Record<string, string>;
}): Record<string, string> | undefined => {
const fieldIdByUniversalIdentifier = {
...action.fieldIdByUniversalIdentifier,
};
for (const universalFlatFieldMetadata of action.universalFlatFieldMetadatas) {
const providedFieldId =
fieldMetadataIdByUniversalIdentifier[
universalFlatFieldMetadata.universalIdentifier
];
if (isDefined(providedFieldId)) {
fieldIdByUniversalIdentifier[
universalFlatFieldMetadata.universalIdentifier
] = providedFieldId;
}
}
if (Object.keys(fieldIdByUniversalIdentifier).length === 0) {
return undefined;
}
return fieldIdByUniversalIdentifier;
};
export const enrichCreateWorkspaceMigrationActionsWithIds = ({
workspaceMigration,
idByUniversalIdentifierByMetadataName,
}: {
workspaceMigration: WorkspaceMigration;
idByUniversalIdentifierByMetadataName: IdByUniversalIdentifierByMetadataName;
}): WorkspaceMigration => {
const fieldMetadataIdByUniversalIdentifier =
idByUniversalIdentifierByMetadataName.fieldMetadata;
const enrichedActions = workspaceMigration.actions.map((action) => {
if (action.type !== 'create') {
return action;
}
const idByUniversalIdentifier =
idByUniversalIdentifierByMetadataName[action.metadataName];
if (
!isDefined(idByUniversalIdentifier) &&
!isDefined(fieldMetadataIdByUniversalIdentifier)
) {
return action;
}
switch (action.metadataName) {
case 'objectMetadata': {
const id = isDefined(idByUniversalIdentifier)
? idByUniversalIdentifier[action.flatEntity.universalIdentifier]
: undefined;
const fieldIdByUniversalIdentifier = isDefined(
fieldMetadataIdByUniversalIdentifier,
)
? buildFieldIdByUniversalIdentifier({
action,
fieldMetadataIdByUniversalIdentifier,
})
: undefined;
return {
...action,
id,
fieldIdByUniversalIdentifier,
};
}
case 'fieldMetadata': {
if (!isDefined(fieldMetadataIdByUniversalIdentifier)) {
return action;
}
return {
...action,
fieldIdByUniversalIdentifier: buildFieldIdByUniversalIdentifier({
action,
fieldMetadataIdByUniversalIdentifier,
}),
};
}
case 'view':
case 'viewField':
case 'viewGroup':
case 'rowLevelPermissionPredicate':
case 'rowLevelPermissionPredicateGroup':
case 'viewFilterGroup':
case 'index':
case 'logicFunction':
case 'viewFilter':
case 'role':
case 'roleTarget':
case 'agent':
case 'skill':
case 'pageLayout':
case 'pageLayoutWidget':
case 'pageLayoutTab':
case 'commandMenuItem':
case 'navigationMenuItem':
case 'frontComponent':
case 'webhook': {
if (!isDefined(idByUniversalIdentifier)) {
return action;
}
return {
...action,
id: idByUniversalIdentifier[action.flatEntity.universalIdentifier],
};
}
default: {
assertUnreachable(action);
}
}
});
return {
...workspaceMigration,
actions: enrichedActions,
};
};
@@ -4,8 +4,7 @@ import { type AllMetadataName } from 'twenty-shared/metadata';
import { isDefined } from 'twenty-shared/utils';
import { createEmptyAllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-all-flat-entity-maps.constant';
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
import { type MetadataFlatEntityAndRelatedFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-related-types.type';
import { type MetadataUniversalFlatEntityAndRelatedUniversalFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-related-types.type';
import { createEmptyOrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration/constant/empty-orchestrator-actions-report.constant';
import { EMPTY_ORCHESTRATOR_FAILURE_REPORT } from 'src/engine/workspace-manager/workspace-migration/constant/empty-orchestrator-failure-report.constant';
import {
@@ -13,6 +12,7 @@ import {
type WorkspaceMigrationOrchestratorFailedResult,
type WorkspaceMigrationOrchestratorSuccessfulResult,
} from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-orchestrator.type';
import { AllUniversalFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/all-universal-flat-entity-maps.type';
import { aggregateOrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration/utils/aggregate-orchestrator-actions-report.util';
import { WorkspaceMigrationAgentActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/agent/workspace-migration-agent-actions-builder.service';
import { WorkspaceMigrationCommandMenuItemActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/command-menu-item/workspace-migration-command-menu-item-actions-builder.service';
@@ -70,12 +70,12 @@ export class WorkspaceMigrationBuildOrchestratorService {
}: Pick<
WorkspaceMigrationOrchestratorBuildArgs,
'fromToAllFlatEntityMaps' | 'dependencyAllFlatEntityMaps'
>): AllFlatEntityMaps {
>): AllUniversalFlatEntityMaps {
const allFromToFlatEntityMapsKeys = Object.keys(
fromToAllFlatEntityMaps,
) as (keyof AllFlatEntityMaps)[];
) as (keyof AllUniversalFlatEntityMaps)[];
return allFromToFlatEntityMapsKeys.reduce<AllFlatEntityMaps>(
return allFromToFlatEntityMapsKeys.reduce<AllUniversalFlatEntityMaps>(
(allFlatEntityMaps, currFlatMaps) => {
const fromToOccurence = fromToAllFlatEntityMaps[currFlatMaps];
@@ -104,12 +104,12 @@ export class WorkspaceMigrationBuildOrchestratorService {
allFlatEntityMaps,
flatEntityMapsAndRelatedFlatEntityMaps,
}: {
flatEntityMapsAndRelatedFlatEntityMaps: MetadataFlatEntityAndRelatedFlatEntityMaps<T>;
allFlatEntityMaps: AllFlatEntityMaps;
flatEntityMapsAndRelatedFlatEntityMaps: MetadataUniversalFlatEntityAndRelatedUniversalFlatEntityMaps<T>;
allFlatEntityMaps: AllUniversalFlatEntityMaps;
}) {
const flatEntityMapsKeys = Object.keys(
flatEntityMapsAndRelatedFlatEntityMaps,
) as (keyof MetadataFlatEntityAndRelatedFlatEntityMaps<T>)[];
) as (keyof MetadataUniversalFlatEntityAndRelatedUniversalFlatEntityMaps<T>)[];
for (const flatEntityMapsKey of flatEntityMapsKeys) {
// @ts-expect-error TODO improve
@@ -183,20 +183,6 @@ export class WorkspaceMigrationBuildOrchestratorService {
...flatFieldMetadataMaps?.from.byUniversalIdentifier,
...flatFieldMetadataMaps?.to.byUniversalIdentifier,
},
universalIdentifierById: {
...dependencyAllFlatEntityMaps?.flatFieldMetadataMaps
?.universalIdentifierById,
...flatFieldMetadataMaps?.from.universalIdentifierById,
...flatFieldMetadataMaps?.to.universalIdentifierById,
},
universalIdentifiersByApplicationId: {
...dependencyAllFlatEntityMaps?.flatFieldMetadataMaps
?.universalIdentifiersByApplicationId,
...flatFieldMetadataMaps?.from
.universalIdentifiersByApplicationId,
...flatFieldMetadataMaps?.to
.universalIdentifiersByApplicationId,
},
},
},
///
@@ -11,11 +11,15 @@ import { ALL_METADATA_REQUIRED_METADATA_FOR_VALIDATION } from 'src/engine/metada
import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
import { AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
import { FlatEntityToCreateDeleteUpdate } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-to-create-delete-update.type';
import { computeFlatEntityMapsFromTo } from 'src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util';
import { MetadataUniversalFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-universal-flat-entity.type';
import { getMetadataFlatEntityMapsKey } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-flat-entity-maps-key.util';
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
import { WorkspaceMigrationV2Exception } from 'src/engine/workspace-manager/workspace-migration.exception';
import { WORKSPACE_MIGRATION_ADDITIONAL_CACHE_DATA_MAPS_KEY } from 'src/engine/workspace-manager/workspace-migration/constant/workspace-migration-additional-cache-data-maps-key.constant';
import {
enrichCreateWorkspaceMigrationActionsWithIds,
IdByUniversalIdentifierByMetadataName,
} from 'src/engine/workspace-manager/workspace-migration/services/utils/enrich-create-workspace-migration-action-with-ids.util';
import { WorkspaceMigrationBuildOrchestratorService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-build-orchestrator.service';
import { WorkspaceMigrationBuilderAdditionalCacheDataMaps } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-builder-additional-cache-data-maps.type';
import {
@@ -23,6 +27,7 @@ import {
WorkspaceMigrationOrchestratorBuildArgs,
WorkspaceMigrationOrchestratorFailedResult,
} from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-orchestrator.type';
import { computeUniversalFlatEntityMapsFromTo } from 'src/engine/workspace-manager/workspace-migration/utils/compute-universal-flat-entity-maps-from-to.util';
import { InferDeletionFromMissingEntities } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/infer-deletion-from-missing-entities.type';
import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/services/workspace-migration-runner.service';
@@ -132,6 +137,7 @@ export class WorkspaceMigrationValidateBuildAndRunService {
inferDeletionFromMissingEntities: InferDeletionFromMissingEntities;
dependencyAllFlatEntityMaps: Partial<AllFlatEntityMaps>;
additionalCacheDataMaps: WorkspaceMigrationBuilderAdditionalCacheDataMaps;
idByUniversalIdentifierByMetadataName: IdByUniversalIdentifierByMetadataName;
}> {
const {
allRelatedFlatEntityMaps,
@@ -146,6 +152,8 @@ export class WorkspaceMigrationValidateBuildAndRunService {
const fromToAllFlatEntityMaps: FromToAllFlatEntityMaps = {};
const inferDeletionFromMissingEntities: InferDeletionFromMissingEntities =
{};
const idByUniversalIdentifierByMetadataName: IdByUniversalIdentifierByMetadataName =
{};
const allMetadataNameToCompare = Object.keys(
allFlatEntityOperationByMetadataName,
) as AllMetadataName[];
@@ -159,16 +167,35 @@ export class WorkspaceMigrationValidateBuildAndRunService {
}
const { flatEntityToCreate, flatEntityToDelete, flatEntityToUpdate } =
flatEntityOperations;
const idByUniversalIdentifier = Object.fromEntries(
flatEntityToCreate
.filter(
(
flatEntity,
): flatEntity is MetadataUniversalFlatEntity<
typeof metadataName
> & { id: string } => isDefined(flatEntity.id),
)
.map((flatEntity) => [flatEntity.universalIdentifier, flatEntity.id]),
);
if (Object.keys(idByUniversalIdentifier).length > 0) {
idByUniversalIdentifierByMetadataName[metadataName] =
idByUniversalIdentifier;
}
const flatEntityMapsKey = getMetadataFlatEntityMapsKey(metadataName);
const flatEntityMaps = allRelatedFlatEntityMaps[flatEntityMapsKey];
// @ts-expect-error Metadata flat entity maps cache key and metadataName colliding
fromToAllFlatEntityMaps[flatEntityMapsKey] = computeFlatEntityMapsFromTo({
flatEntityMaps,
flatEntityToCreate,
flatEntityToDelete,
flatEntityToUpdate,
});
fromToAllFlatEntityMaps[flatEntityMapsKey] =
computeUniversalFlatEntityMapsFromTo({
flatEntityMaps,
flatEntityToCreate,
flatEntityToDelete,
flatEntityToUpdate,
});
if (flatEntityToDelete.length > 0) {
inferDeletionFromMissingEntities[metadataName] = true;
@@ -180,15 +207,20 @@ export class WorkspaceMigrationValidateBuildAndRunService {
inferDeletionFromMissingEntities,
dependencyAllFlatEntityMaps,
additionalCacheDataMaps,
idByUniversalIdentifierByMetadataName,
};
}
public async validateBuildAndRunWorkspaceMigrationFromTo(
args: WorkspaceMigrationOrchestratorBuildArgs,
args: WorkspaceMigrationOrchestratorBuildArgs & {
idByUniversalIdentifierByMetadataName?: IdByUniversalIdentifierByMetadataName;
},
) {
const { idByUniversalIdentifierByMetadataName, ...buildArgs } = args;
const validateAndBuildResult =
await this.workspaceMigrationBuildOrchestratorService
.buildWorkspaceMigration(args)
.buildWorkspaceMigration(buildArgs)
.catch((error) => {
this.logger.error(error);
throw new WorkspaceMigrationV2Exception(
@@ -205,16 +237,18 @@ export class WorkspaceMigrationValidateBuildAndRunService {
return validateAndBuildResult;
}
// Note: This should be removed once we've refactored the runner optimistic rendering
// As with the current implementation passing an empty workspace migration might result
// in dependency flat entity maps invalidation
if (validateAndBuildResult.workspaceMigration.actions.length === 0) {
return;
return undefined;
}
await this.workspaceMigrationRunnerService.run(
validateAndBuildResult.workspaceMigration,
);
const workspaceMigration = isDefined(idByUniversalIdentifierByMetadataName)
? enrichCreateWorkspaceMigrationActionsWithIds({
idByUniversalIdentifierByMetadataName,
workspaceMigration: validateAndBuildResult.workspaceMigration,
})
: validateAndBuildResult.workspaceMigration;
await this.workspaceMigrationRunnerService.run(workspaceMigration);
}
public async validateBuildAndRunWorkspaceMigration({
@@ -230,6 +264,7 @@ export class WorkspaceMigrationValidateBuildAndRunService {
inferDeletionFromMissingEntities,
dependencyAllFlatEntityMaps,
additionalCacheDataMaps,
idByUniversalIdentifierByMetadataName,
} = await this.computeFromToAllFlatEntityMapsAndBuildOptions({
allFlatEntityOperationByMetadataName: allFlatEntities,
workspaceId,
@@ -246,6 +281,7 @@ export class WorkspaceMigrationValidateBuildAndRunService {
workspaceId,
dependencyAllFlatEntityMaps,
additionalCacheDataMaps,
idByUniversalIdentifierByMetadataName,
});
}
}
@@ -1,7 +1,7 @@
import { type MetadataFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity-maps.type';
import { type OrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-orchestrator.type';
import { type MetadataUniversalFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/metadata-universal-flat-entity-maps.type';
export type AggregateOrchestratorActionsReportArgs = {
orchestratorActionsReport: OrchestratorActionsReport;
flatFieldMetadataMaps?: MetadataFlatEntityMaps<'fieldMetadata'>;
flatFieldMetadataMaps?: MetadataUniversalFlatEntityMaps<'fieldMetadata'>;
};
@@ -1,25 +1,27 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type FromTo } from 'twenty-shared/types';
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
import {
type MetadataUniversalWorkspaceMigrationActionsRecord,
type WorkspaceMigrationActionType,
} from 'src/engine/metadata-modules/flat-entity/types/metadata-workspace-migration-action.type';
import { type WorkspaceMigrationBuilderAdditionalCacheDataMaps } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-builder-additional-cache-data-maps.type';
import { type AllUniversalFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/all-universal-flat-entity-maps.type';
import { type FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/types/failed-flat-entity-validation.type';
import { type WorkspaceMigration } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/workspace-migration';
import { type WorkspaceMigrationBuilderOptions } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/workspace-migration-builder-options.type';
export type FromToAllFlatEntityMaps = {
[P in keyof AllFlatEntityMaps]?: FromTo<AllFlatEntityMaps[P]>;
[P in keyof AllUniversalFlatEntityMaps]?: FromTo<
AllUniversalFlatEntityMaps[P]
>;
};
export type WorkspaceMigrationOrchestratorBuildArgs = {
workspaceId: string;
buildOptions: WorkspaceMigrationBuilderOptions;
fromToAllFlatEntityMaps: FromToAllFlatEntityMaps;
dependencyAllFlatEntityMaps?: Partial<AllFlatEntityMaps>;
dependencyAllFlatEntityMaps?: Partial<AllUniversalFlatEntityMaps>;
additionalCacheDataMaps: WorkspaceMigrationBuilderAdditionalCacheDataMaps;
applicationUniversalIdentifier: string;
};
@@ -3,6 +3,10 @@ import { type AllMetadataName } from 'twenty-shared/metadata';
import { type MetadataEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-entity.type';
import { type ExtractJsonbProperties } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/extract-jsonb-properties.type';
/**
* Important notice: This file is not strictly typed and needs manual referencement
* of jsonb properties that may contain a serialized relation
*/
export const ALL_JSONB_PROPERTIES_WITH_SERIALIZED_RELATION_BY_METADATA_NAME = {
fieldMetadata: {
settings: 'settings',
@@ -32,6 +36,7 @@ export const ALL_JSONB_PROPERTIES_WITH_SERIALIZED_RELATION_BY_METADATA_NAME = {
frontComponent: {},
} as const satisfies {
[P in AllMetadataName]: Partial<{
// TODO prastoin: improve strict typing to recursively serach for nested SerializedRelation
[K in ExtractJsonbProperties<MetadataEntity<P>>]: K;
}>;
};
@@ -0,0 +1,517 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type ALL_METADATA_RELATIONS } from 'src/engine/metadata-modules/flat-entity/constant/all-metadata-relations.constant';
export type ToUniversalForeignKey<T extends string> =
T extends `${infer Prefix}Id` ? `${Prefix}UniversalIdentifier` : never;
type ToUniversalAggregator<T extends string> = T extends `${infer Prefix}Ids`
? `${Prefix}UniversalIdentifiers`
: never;
export type ToUniversalMetadataManyToOneRelationConfiguration<T> = T extends {
metadataName: infer M extends AllMetadataName;
foreignKey: infer FK extends string;
flatEntityForeignKeyAggregator: infer Agg;
isNullable: infer N extends boolean;
}
? {
metadataName: M;
foreignKey: FK;
universalForeignKey: ToUniversalForeignKey<FK>;
universalFlatEntityForeignKeyAggregator: Agg extends string
? ToUniversalAggregator<Agg>
: null;
isNullable: N;
}
: null;
type ToUniversalManyToOneRelations<T> = {
[K in keyof T]: ToUniversalMetadataManyToOneRelationConfiguration<T[K]>;
};
type ToUniversalOneToManyRelations<T> = T;
export type UniversalMetadataRelationsProperties = {
[M in AllMetadataName]: {
manyToOne: ToUniversalManyToOneRelations<
(typeof ALL_METADATA_RELATIONS)[M]['manyToOne']
>;
oneToMany: ToUniversalOneToManyRelations<
(typeof ALL_METADATA_RELATIONS)[M]['oneToMany']
>;
};
};
export const ALL_UNIVERSAL_METADATA_RELATIONS = {
agent: {
manyToOne: {
workspace: null,
application: null,
},
oneToMany: {},
},
skill: {
manyToOne: {
workspace: null,
application: null,
},
oneToMany: {},
},
commandMenuItem: {
manyToOne: {
workspace: null,
application: null,
availabilityObjectMetadata: {
metadataName: 'objectMetadata',
foreignKey: 'availabilityObjectMetadataId',
universalFlatEntityForeignKeyAggregator: null,
universalForeignKey: 'availabilityObjectMetadataUniversalIdentifier',
isNullable: true,
},
frontComponent: {
metadataName: 'frontComponent',
foreignKey: 'frontComponentId',
universalFlatEntityForeignKeyAggregator: null,
universalForeignKey: 'frontComponentUniversalIdentifier',
isNullable: true,
},
},
oneToMany: {},
},
navigationMenuItem: {
manyToOne: {
workspace: null,
userWorkspace: null,
application: null,
targetObjectMetadata: {
metadataName: 'objectMetadata',
foreignKey: 'targetObjectMetadataId',
universalFlatEntityForeignKeyAggregator: null,
universalForeignKey: 'targetObjectMetadataUniversalIdentifier',
isNullable: true,
},
folder: {
metadataName: 'navigationMenuItem',
foreignKey: 'folderId',
universalFlatEntityForeignKeyAggregator: null,
universalForeignKey: 'folderUniversalIdentifier',
isNullable: true,
},
view: {
metadataName: 'view',
foreignKey: 'viewId',
universalFlatEntityForeignKeyAggregator: null,
universalForeignKey: 'viewUniversalIdentifier',
isNullable: true,
},
},
oneToMany: {},
},
fieldMetadata: {
manyToOne: {
object: {
metadataName: 'objectMetadata',
foreignKey: 'objectMetadataId',
universalFlatEntityForeignKeyAggregator: 'fieldUniversalIdentifiers',
universalForeignKey: 'objectMetadataUniversalIdentifier',
isNullable: false,
},
workspace: null,
application: null,
relationTargetFieldMetadata: {
metadataName: 'fieldMetadata',
foreignKey: 'relationTargetFieldMetadataId',
universalFlatEntityForeignKeyAggregator: null,
universalForeignKey: 'relationTargetFieldMetadataUniversalIdentifier',
isNullable: true,
},
relationTargetObjectMetadata: {
metadataName: 'objectMetadata',
foreignKey: 'relationTargetObjectMetadataId',
universalFlatEntityForeignKeyAggregator: null,
universalForeignKey: 'relationTargetObjectMetadataUniversalIdentifier',
isNullable: true,
},
},
oneToMany: {
fieldPermissions: null,
indexFieldMetadatas: null,
viewFields: { metadataName: 'viewField' },
viewFilters: { metadataName: 'viewFilter' },
kanbanAggregateOperationViews: { metadataName: 'view' },
calendarViews: { metadataName: 'view' },
mainGroupByFieldMetadataViews: { metadataName: 'view' },
},
},
objectMetadata: {
manyToOne: {
dataSource: null,
workspace: null,
application: null,
},
oneToMany: {
fields: { metadataName: 'fieldMetadata' },
indexMetadatas: { metadataName: 'index' },
targetRelationFields: { metadataName: 'fieldMetadata' },
objectPermissions: null,
fieldPermissions: null,
views: { metadataName: 'view' },
},
},
view: {
manyToOne: {
objectMetadata: {
metadataName: 'objectMetadata',
foreignKey: 'objectMetadataId',
universalFlatEntityForeignKeyAggregator: 'viewUniversalIdentifiers',
universalForeignKey: 'objectMetadataUniversalIdentifier',
isNullable: false,
},
workspace: null,
createdBy: null,
application: null,
calendarFieldMetadata: {
metadataName: 'fieldMetadata',
foreignKey: 'calendarFieldMetadataId',
universalFlatEntityForeignKeyAggregator:
'calendarViewUniversalIdentifiers',
universalForeignKey: 'calendarFieldMetadataUniversalIdentifier',
isNullable: true,
},
kanbanAggregateOperationFieldMetadata: {
metadataName: 'fieldMetadata',
foreignKey: 'kanbanAggregateOperationFieldMetadataId',
universalFlatEntityForeignKeyAggregator:
'kanbanAggregateOperationViewUniversalIdentifiers',
universalForeignKey:
'kanbanAggregateOperationFieldMetadataUniversalIdentifier',
isNullable: true,
},
mainGroupByFieldMetadata: {
metadataName: 'fieldMetadata',
foreignKey: 'mainGroupByFieldMetadataId',
universalFlatEntityForeignKeyAggregator:
'mainGroupByFieldMetadataViewUniversalIdentifiers',
universalForeignKey: 'mainGroupByFieldMetadataUniversalIdentifier',
isNullable: true,
},
},
oneToMany: {
viewFields: { metadataName: 'viewField' },
viewFilters: { metadataName: 'viewFilter' },
viewFilterGroups: { metadataName: 'viewFilterGroup' },
viewGroups: { metadataName: 'viewGroup' },
// TODO migrate viewSort to v2
viewSorts: null,
},
},
viewField: {
manyToOne: {
fieldMetadata: {
metadataName: 'fieldMetadata',
foreignKey: 'fieldMetadataId',
universalFlatEntityForeignKeyAggregator:
'viewFieldUniversalIdentifiers',
universalForeignKey: 'fieldMetadataUniversalIdentifier',
isNullable: false,
},
view: {
metadataName: 'view',
foreignKey: 'viewId',
universalFlatEntityForeignKeyAggregator:
'viewFieldUniversalIdentifiers',
universalForeignKey: 'viewUniversalIdentifier',
isNullable: false,
},
workspace: null,
application: null,
},
oneToMany: {},
},
viewFilter: {
manyToOne: {
fieldMetadata: {
metadataName: 'fieldMetadata',
foreignKey: 'fieldMetadataId',
universalFlatEntityForeignKeyAggregator:
'viewFilterUniversalIdentifiers',
universalForeignKey: 'fieldMetadataUniversalIdentifier',
isNullable: false,
},
view: {
metadataName: 'view',
foreignKey: 'viewId',
universalFlatEntityForeignKeyAggregator:
'viewFilterUniversalIdentifiers',
universalForeignKey: 'viewUniversalIdentifier',
isNullable: false,
},
viewFilterGroup: {
metadataName: 'viewFilterGroup',
foreignKey: 'viewFilterGroupId',
universalFlatEntityForeignKeyAggregator:
'viewFilterUniversalIdentifiers',
universalForeignKey: 'viewFilterGroupUniversalIdentifier',
isNullable: true,
},
workspace: null,
application: null,
},
oneToMany: {},
},
viewGroup: {
manyToOne: {
view: {
metadataName: 'view',
foreignKey: 'viewId',
universalFlatEntityForeignKeyAggregator:
'viewGroupUniversalIdentifiers',
universalForeignKey: 'viewUniversalIdentifier',
isNullable: false,
},
workspace: null,
application: null,
},
oneToMany: {},
},
index: {
manyToOne: {
objectMetadata: {
metadataName: 'objectMetadata',
foreignKey: 'objectMetadataId',
universalFlatEntityForeignKeyAggregator:
'indexMetadataUniversalIdentifiers',
universalForeignKey: 'objectMetadataUniversalIdentifier',
isNullable: false,
},
workspace: null,
application: null,
},
oneToMany: {
indexFieldMetadatas: null,
},
},
logicFunction: {
manyToOne: {
workspace: null,
application: null,
},
oneToMany: {},
},
role: {
manyToOne: {
workspace: null,
application: null,
},
oneToMany: {
roleTargets: { metadataName: 'roleTarget' },
objectPermissions: null,
permissionFlags: null,
fieldPermissions: null,
rowLevelPermissionPredicates: {
metadataName: 'rowLevelPermissionPredicate',
},
rowLevelPermissionPredicateGroups: {
metadataName: 'rowLevelPermissionPredicateGroup',
},
},
},
roleTarget: {
manyToOne: {
role: {
metadataName: 'role',
foreignKey: 'roleId',
universalFlatEntityForeignKeyAggregator:
'roleTargetUniversalIdentifiers',
universalForeignKey: 'roleUniversalIdentifier',
isNullable: false,
},
apiKey: null,
workspace: null,
application: null,
},
oneToMany: {},
},
pageLayout: {
manyToOne: {
workspace: null,
objectMetadata: {
metadataName: 'objectMetadata',
foreignKey: 'objectMetadataId',
universalFlatEntityForeignKeyAggregator: null,
universalForeignKey: 'objectMetadataUniversalIdentifier',
isNullable: true,
},
application: null,
defaultTabToFocusOnMobileAndSidePanel: {
metadataName: 'pageLayoutTab',
foreignKey: 'defaultTabToFocusOnMobileAndSidePanelId',
universalFlatEntityForeignKeyAggregator: null,
universalForeignKey:
'defaultTabToFocusOnMobileAndSidePanelUniversalIdentifier',
isNullable: true,
},
},
oneToMany: {
tabs: { metadataName: 'pageLayoutTab' },
},
},
pageLayoutTab: {
manyToOne: {
workspace: null,
pageLayout: {
metadataName: 'pageLayout',
foreignKey: 'pageLayoutId',
universalFlatEntityForeignKeyAggregator: 'tabUniversalIdentifiers',
universalForeignKey: 'pageLayoutUniversalIdentifier',
isNullable: false,
},
application: null,
},
oneToMany: {
widgets: { metadataName: 'pageLayoutWidget' },
},
},
pageLayoutWidget: {
manyToOne: {
workspace: null,
pageLayoutTab: {
metadataName: 'pageLayoutTab',
foreignKey: 'pageLayoutTabId',
universalFlatEntityForeignKeyAggregator: 'widgetUniversalIdentifiers',
universalForeignKey: 'pageLayoutTabUniversalIdentifier',
isNullable: false,
},
objectMetadata: {
metadataName: 'objectMetadata',
foreignKey: 'objectMetadataId',
universalFlatEntityForeignKeyAggregator: null,
universalForeignKey: 'objectMetadataUniversalIdentifier',
isNullable: true,
},
application: null,
},
oneToMany: {},
},
rowLevelPermissionPredicate: {
manyToOne: {
workspace: null,
role: {
metadataName: 'role',
foreignKey: 'roleId',
universalFlatEntityForeignKeyAggregator: null,
universalForeignKey: 'roleUniversalIdentifier',
isNullable: false,
},
fieldMetadata: {
metadataName: 'fieldMetadata',
foreignKey: 'fieldMetadataId',
universalFlatEntityForeignKeyAggregator: null,
universalForeignKey: 'fieldMetadataUniversalIdentifier',
isNullable: false,
},
workspaceMemberFieldMetadata: {
metadataName: 'fieldMetadata',
foreignKey: 'workspaceMemberFieldMetadataId',
universalFlatEntityForeignKeyAggregator: null,
universalForeignKey: 'workspaceMemberFieldMetadataUniversalIdentifier',
isNullable: true,
},
objectMetadata: {
metadataName: 'objectMetadata',
foreignKey: 'objectMetadataId',
universalFlatEntityForeignKeyAggregator: null,
universalForeignKey: 'objectMetadataUniversalIdentifier',
isNullable: false,
},
rowLevelPermissionPredicateGroup: {
metadataName: 'rowLevelPermissionPredicateGroup',
foreignKey: 'rowLevelPermissionPredicateGroupId',
universalFlatEntityForeignKeyAggregator: null,
universalForeignKey:
'rowLevelPermissionPredicateGroupUniversalIdentifier',
isNullable: true,
},
application: null,
},
oneToMany: {},
},
rowLevelPermissionPredicateGroup: {
manyToOne: {
objectMetadata: {
metadataName: 'objectMetadata',
foreignKey: 'objectMetadataId',
universalFlatEntityForeignKeyAggregator: null,
universalForeignKey: 'objectMetadataUniversalIdentifier',
isNullable: false,
},
role: {
metadataName: 'role',
foreignKey: 'roleId',
universalFlatEntityForeignKeyAggregator: null,
universalForeignKey: 'roleUniversalIdentifier',
isNullable: false,
},
parentRowLevelPermissionPredicateGroup: {
metadataName: 'rowLevelPermissionPredicateGroup',
foreignKey: 'parentRowLevelPermissionPredicateGroupId',
universalFlatEntityForeignKeyAggregator:
'childRowLevelPermissionPredicateGroupUniversalIdentifiers',
universalForeignKey:
'parentRowLevelPermissionPredicateGroupUniversalIdentifier',
isNullable: true,
},
workspace: null,
application: null,
},
oneToMany: {
childRowLevelPermissionPredicateGroups: {
metadataName: 'rowLevelPermissionPredicateGroup',
},
rowLevelPermissionPredicates: {
metadataName: 'rowLevelPermissionPredicate',
},
},
},
viewFilterGroup: {
manyToOne: {
application: null,
parentViewFilterGroup: {
metadataName: 'viewFilterGroup',
foreignKey: 'parentViewFilterGroupId',
universalFlatEntityForeignKeyAggregator:
'childViewFilterGroupUniversalIdentifiers',
universalForeignKey: 'parentViewFilterGroupUniversalIdentifier',
isNullable: true,
},
view: {
metadataName: 'view',
foreignKey: 'viewId',
universalFlatEntityForeignKeyAggregator:
'viewFilterGroupUniversalIdentifiers',
universalForeignKey: 'viewUniversalIdentifier',
isNullable: false,
},
workspace: null,
},
oneToMany: {
childViewFilterGroups: { metadataName: 'viewFilterGroup' },
viewFilters: { metadataName: 'viewFilter' },
},
},
frontComponent: {
manyToOne: {
workspace: null,
application: null,
},
oneToMany: {},
},
webhook: {
manyToOne: {
workspace: null,
application: null,
},
oneToMany: {},
},
} as const satisfies UniversalMetadataRelationsProperties;
@@ -0,0 +1,21 @@
import { type Equal, type Expect } from 'twenty-shared/testing';
import { type MetadataUniversalFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/metadata-universal-flat-entity-maps.type';
import { type UniversalFlatFieldMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-field-metadata.type';
import { type UniversalFlatViewField } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-view-field.type';
// eslint-disable-next-line unused-imports/no-unused-vars
type Assertions = [
Expect<
Equal<
MetadataUniversalFlatEntityMaps<'fieldMetadata'>['byUniversalIdentifier'][string],
UniversalFlatFieldMetadata | undefined
>
>,
Expect<
Equal<
MetadataUniversalFlatEntityMaps<'viewField'>['byUniversalIdentifier'][string],
UniversalFlatViewField | undefined
>
>,
];
@@ -0,0 +1,39 @@
import { type Equal, type Expect } from 'twenty-shared/testing';
import { type UniversalFlatEntityUpdate } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-update.type';
// eslint-disable-next-line unused-imports/no-unused-vars
type Assertions = [
Expect<
Equal<
keyof UniversalFlatEntityUpdate<'fieldMetadata'>,
| 'name'
| 'label'
| 'icon'
| 'description'
| 'isActive'
| 'defaultValue'
| 'standardOverrides'
| 'options'
| 'isUnique'
| 'isLabelSyncedWithName'
| 'universalSettings'
>
>,
Expect<
Equal<
keyof UniversalFlatEntityUpdate<'objectMetadata'>,
| 'icon'
| 'description'
| 'isActive'
| 'standardOverrides'
| 'isLabelSyncedWithName'
| 'nameSingular'
| 'namePlural'
| 'labelSingular'
| 'labelPlural'
| 'labelIdentifierFieldMetadataUniversalIdentifier'
>
>,
];
@@ -0,0 +1,8 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type MetadataToFlatEntityMapsKey } from 'src/engine/metadata-modules/flat-entity/types/metadata-to-flat-entity-maps-key';
import { type MetadataUniversalFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/metadata-universal-flat-entity-maps.type';
export type AllUniversalFlatEntityMaps = {
[P in AllMetadataName as MetadataToFlatEntityMapsKey<P>]: MetadataUniversalFlatEntityMaps<P>;
};
@@ -0,0 +1,9 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type AllFlatEntityTypesByMetadataName } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-types-by-metadata-name';
import { type UniversalFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-maps.type';
export type MetadataUniversalFlatEntityMaps<T extends AllMetadataName> =
UniversalFlatEntityMaps<
AllFlatEntityTypesByMetadataName[T]['universalFlatEntity']
>;
@@ -0,0 +1,63 @@
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 MetadataUniversalFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-universal-flat-entity.type';
type ExtractPropertyToCompare<
MetadataConfig,
P extends keyof MetadataConfig,
> = MetadataConfig[P] extends { universalProperty: string }
? MetadataConfig[P]['universalProperty']
: P;
export type MetadataUniversalFlatEntityPropertiesToCompare<
T extends AllMetadataName,
MetadataConfig = (typeof ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME)[T],
> = {
[P in keyof MetadataConfig]: ExtractPropertyToCompare<MetadataConfig, P>;
}[keyof MetadataConfig] &
keyof MetadataUniversalFlatEntity<T>;
// eslint-disable-next-line unused-imports/no-unused-vars
type Assertions = [
Expect<
Equal<
MetadataUniversalFlatEntityPropertiesToCompare<'fieldMetadata'>,
| 'name'
| 'label'
| 'icon'
| 'description'
| 'isActive'
| 'defaultValue'
| 'standardOverrides'
| 'options'
| 'isUnique'
| 'isLabelSyncedWithName'
| 'universalSettings'
>
>,
Expect<
Equal<
MetadataUniversalFlatEntityPropertiesToCompare<'view'>,
| 'name'
| 'icon'
| 'deletedAt'
| 'type'
| 'position'
| 'key'
| 'isCompact'
| 'openRecordIn'
| 'kanbanAggregateOperation'
| 'kanbanAggregateOperationFieldMetadataUniversalIdentifier'
| 'calendarLayout'
| 'calendarFieldMetadataUniversalIdentifier'
| 'mainGroupByFieldMetadataUniversalIdentifier'
| 'shouldHideEmptyGroups'
| 'anyFieldFilterValue'
| 'visibility'
| 'createdByUserWorkspaceId'
>
>,
];
@@ -0,0 +1,13 @@
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;
}[keyof T];
export type MetadataUniversalFlatEntityPropertiesToStringify<
T extends AllMetadataName,
> = ExtractKeysWithToStringify<
(typeof ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME)[T]
>;
@@ -1,9 +1,9 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type ALL_METADATA_RELATIONS } from 'src/engine/metadata-modules/flat-entity/constant/all-metadata-relations.constant';
import { type AddSuffixToEntityManyToOneProperties } from 'src/engine/metadata-modules/flat-entity/types/add-suffix-to-entity-many-to-one-properties.type';
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 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';
@@ -46,7 +46,8 @@ export type UniversalFlatEntityFrom<
| 'applicationId'
| 'workspaceId'
| 'id'
| ExtractEntityRelatedEntityProperties<TEntity>
| keyof (typeof ALL_METADATA_RELATIONS)[TMetadataName]['manyToOne']
| keyof (typeof ALL_METADATA_RELATIONS)[TMetadataName]['oneToMany']
| Extract<MetadataManyToOneJoinColumn<TMetadataName>, keyof TEntity>
| keyof CastRecordTypeOrmDatePropertiesToString<TEntity>
| AllJsonbPropertiesWithSerializedPropertiesForMetadataName<TMetadataName>
@@ -0,0 +1,8 @@
import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type';
import { type UniversalSyncableFlatEntity } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type';
export type UniversalFlatEntityMaps<
T extends SyncableFlatEntity | UniversalSyncableFlatEntity,
> = {
byUniversalIdentifier: Partial<Record<string, T>>;
};
@@ -0,0 +1,11 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type MetadataUniversalFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-universal-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';
export type UniversalFlatEntityUpdate<T extends AllMetadataName> = Partial<
Pick<
MetadataUniversalFlatEntity<T>,
MetadataUniversalFlatEntityPropertiesToCompare<T>
>
>;
@@ -0,0 +1,23 @@
import { type CastRecordTypeOrmDatePropertiesToString } from 'src/engine/metadata-modules/flat-entity/types/cast-record-typeorm-date-properties-to-string.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';
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
export type UniversalFlatIndexFieldMetadata = Omit<
IndexFieldMetadataEntity,
| 'indexMetadataId'
| 'indexMetadata'
| 'fieldMetadataId'
| 'fieldMetadata'
| 'id'
| keyof CastRecordTypeOrmDatePropertiesToString<IndexFieldMetadataEntity>
> & {
indexMetadataUniversalIdentifier: string;
fieldMetadataUniversalIdentifier: string;
} & CastRecordTypeOrmDatePropertiesToString<IndexFieldMetadataEntity>;
export type UniversalFlatIndexMetadata =
UniversalFlatEntityFrom<IndexMetadataEntity> & {
universalFlatIndexFieldMetadatas: UniversalFlatIndexFieldMetadata[];
};
@@ -2,7 +2,13 @@ import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-me
import { type UniversalFlatEntityFrom } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type';
export type UniversalFlatObjectMetadata = UniversalFlatEntityFrom<
Omit<ObjectMetadataEntity, 'targetRelationFields' | 'dataSourceId'>,
Omit<
ObjectMetadataEntity,
| 'targetRelationFields'
| 'dataSourceId'
| 'labelIdentifierFieldMetadataId'
| 'imageIdentifierFieldMetadataId'
>,
'objectMetadata'
> & {
// NOTE: below fields are not reflected on the final UniversalFlatEntity either they should we should define a common source
@@ -0,0 +1,4 @@
import { type SkillEntity } from 'src/engine/metadata-modules/skill/entities/skill.entity';
import { type UniversalFlatEntityFrom } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type';
export type UniversalFlatSkill = UniversalFlatEntityFrom<SkillEntity, 'skill'>;
@@ -0,0 +1,7 @@
import { type ViewFieldEntity } from 'src/engine/metadata-modules/view-field/entities/view-field.entity';
import { type UniversalFlatEntityFrom } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type';
export type UniversalFlatViewField = UniversalFlatEntityFrom<
ViewFieldEntity,
'viewField'
>;
@@ -0,0 +1,7 @@
import { type ViewFilterGroupEntity } from 'src/engine/metadata-modules/view-filter-group/entities/view-filter-group.entity';
import { type UniversalFlatEntityFrom } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type';
export type UniversalFlatViewFilterGroup = UniversalFlatEntityFrom<
ViewFilterGroupEntity,
'viewFilterGroup'
>;
@@ -0,0 +1,7 @@
import { type ViewFilterEntity } from 'src/engine/metadata-modules/view-filter/entities/view-filter.entity';
import { type UniversalFlatEntityFrom } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type';
export type UniversalFlatViewFilter = UniversalFlatEntityFrom<
ViewFilterEntity,
'viewFilter'
>;
@@ -0,0 +1,7 @@
import { type ViewGroupEntity } from 'src/engine/metadata-modules/view-group/entities/view-group.entity';
import { type UniversalFlatEntityFrom } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type';
export type UniversalFlatViewGroup = UniversalFlatEntityFrom<
ViewGroupEntity,
'viewGroup'
>;
@@ -0,0 +1,8 @@
import { type ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
import { type UniversalFlatEntityFrom } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type';
// TODO remove once viewSorts has been migrated to v2
export type UniversalFlatView = UniversalFlatEntityFrom<
Omit<ViewEntity, 'viewSorts'>,
'view'
>;
@@ -0,0 +1,13 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`compareTwoFlatEntity It should detect flat field metadata isActive diff from true to false 1`] = `
{
"isActive": false,
}
`;
exports[`compareTwoFlatEntity It should detect flat field metadata isActive diff from true to false 2`] = `
{
"isActive": true,
}
`;
@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect a created entity 1`] = `
{
@@ -48,19 +48,9 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect a crea
"workspaceId": "workspace-id-1",
},
},
"universalIdentifierById": {
"field-id-1": "universal-identifier-1",
},
"universalIdentifiersByApplicationId": {
"application-id-1": [
"universal-identifier-1",
],
},
},
"deletedFlatEntityMaps": {
"byUniversalIdentifier": {},
"universalIdentifierById": {},
"universalIdentifiersByApplicationId": {},
},
"updatedFlatEntityMaps": {
"byUniversalIdentifier": {},
@@ -72,8 +62,6 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect a dele
{
"createdFlatEntityMaps": {
"byUniversalIdentifier": {},
"universalIdentifierById": {},
"universalIdentifiersByApplicationId": {},
},
"deletedFlatEntityMaps": {
"byUniversalIdentifier": {
@@ -121,14 +109,6 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect a dele
"workspaceId": "workspace-id-1",
},
},
"universalIdentifierById": {
"field-id-1": "universal-identifier-1",
},
"universalIdentifiersByApplicationId": {
"application-id-1": [
"universal-identifier-1",
],
},
},
"updatedFlatEntityMaps": {
"byUniversalIdentifier": {},
@@ -140,18 +120,13 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect an upd
{
"createdFlatEntityMaps": {
"byUniversalIdentifier": {},
"universalIdentifierById": {},
"universalIdentifiersByApplicationId": {},
},
"deletedFlatEntityMaps": {
"byUniversalIdentifier": {},
"universalIdentifierById": {},
"universalIdentifiersByApplicationId": {},
},
"updatedFlatEntityMaps": {
"byUniversalIdentifier": {
"universal-identifier-1": {
"id": "field-id-1",
"update": {
"isActive": true,
},
@@ -209,14 +184,6 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect create
"workspaceId": "workspace-id-1",
},
},
"universalIdentifierById": {
"field-id-3": "universal-identifier-3",
},
"universalIdentifiersByApplicationId": {
"application-id-1": [
"universal-identifier-3",
],
},
},
"deletedFlatEntityMaps": {
"byUniversalIdentifier": {
@@ -264,19 +231,10 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect create
"workspaceId": "workspace-id-1",
},
},
"universalIdentifierById": {
"field-id-2": "universal-identifier-2",
},
"universalIdentifiersByApplicationId": {
"application-id-1": [
"universal-identifier-2",
],
},
},
"updatedFlatEntityMaps": {
"byUniversalIdentifier": {
"universal-identifier-1": {
"id": "field-id-1",
"update": {
"isActive": false,
},
@@ -290,13 +248,9 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should not detect de
{
"createdFlatEntityMaps": {
"byUniversalIdentifier": {},
"universalIdentifierById": {},
"universalIdentifiersByApplicationId": {},
},
"deletedFlatEntityMaps": {
"byUniversalIdentifier": {},
"universalIdentifierById": {},
"universalIdentifiersByApplicationId": {},
},
"updatedFlatEntityMaps": {
"byUniversalIdentifier": {},
@@ -0,0 +1,239 @@
import { FieldMetadataType } from 'twenty-shared/types';
import {
FlatEntityMapsException,
FlatEntityMapsExceptionCode,
} from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception';
import { type MetadataUniversalFlatEntityAndRelatedFlatEntityMapsForValidation } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity-and-related-flat-entity-maps-for-validation.type';
import { type MetadataUniversalFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-universal-flat-entity.type';
import { findFlatEntityByUniversalIdentifier } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import { type FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
import { type UniversalFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-maps.type';
import { addUniversalFlatEntityToUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/add-universal-flat-entity-to-universal-flat-entity-and-related-entity-maps-through-mutation-or-throw.util';
import { addUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/add-universal-flat-entity-to-universal-flat-entity-maps-through-mutation-or-throw.util';
const createEmptyUniversalFlatEntityMaps = <T>(): UniversalFlatEntityMaps<
T & { universalIdentifier: string; applicationUniversalIdentifier: string }
> => ({
byUniversalIdentifier: {},
});
describe('addUniversalFlatEntityToUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrow', () => {
it('should add a view and update related objectMetadata with viewUniversalIdentifier', () => {
const objectMetadataUniversalIdentifier = 'object-universal-1';
const fieldMetadataUniversalIdentifier = 'field-universal-1';
const viewUniversalIdentifier = 'view-universal-1';
const applicationUniversalIdentifier =
'20202020-f3ad-452e-b5b6-2d49d3ea88b1';
const mockUniversalObjectMetadata = {
universalIdentifier: objectMetadataUniversalIdentifier,
viewUniversalIdentifiers: [],
fieldUniversalIdentifiers: [],
indexMetadataUniversalIdentifiers: [],
description: 'default flat object metadata description',
icon: 'icon',
isActive: true,
isAuditLogged: true,
isCustom: true,
isLabelSyncedWithName: false,
isRemote: false,
isSearchable: true,
isSystem: false,
isUIReadOnly: false,
labelPlural: 'default flat object metadata label plural',
labelSingular: 'default flat object metadata label singular',
namePlural: 'defaultflatObjectMetadataNamePlural',
nameSingular: 'defaultflatObjectMetadataNameSingular',
shortcut: 'shortcut',
standardOverrides: null,
targetTableName: '',
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z',
duplicateCriteria: null,
applicationUniversalIdentifier,
labelIdentifierFieldMetadataUniversalIdentifier:
'20202020-1a62-405c-87fa-4d4fd215851b',
imageIdentifierFieldMetadataUniversalIdentifier:
'20202020-9d65-415f-b0e1-216a2e257ea4',
};
const mockUniversalFieldMetadata = {
universalIdentifier: fieldMetadataUniversalIdentifier,
objectMetadataUniversalIdentifier,
type: FieldMetadataType.DATE,
applicationUniversalIdentifier,
viewFieldUniversalIdentifiers: [],
viewFilterUniversalIdentifiers: [],
calendarViewUniversalIdentifiers: [],
mainGroupByFieldMetadataViewUniversalIdentifiers: [],
kanbanAggregateOperationViewUniversalIdentifiers: [],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z',
defaultValue: null,
options: null,
morphId: null,
settings: null,
universalSettings: null,
description: 'default flat field metadata description',
icon: 'icon',
isActive: true,
isCustom: true,
name: 'flatFieldMetadataName',
label: 'flat field metadata label',
isNullable: true,
isUnique: false,
isUIReadOnly: false,
isLabelSyncedWithName: false,
isSystem: false,
standardOverrides: null,
relationTargetObjectMetadataUniversalIdentifier: null,
relationTargetFieldMetadataUniversalIdentifier: null,
};
const mockUniversalView = {
universalIdentifier: viewUniversalIdentifier,
objectMetadataUniversalIdentifier,
viewFieldUniversalIdentifiers: [],
viewFilterUniversalIdentifiers: [],
viewGroupUniversalIdentifiers: [],
applicationUniversalIdentifier,
calendarFieldMetadataUniversalIdentifier:
fieldMetadataUniversalIdentifier,
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z',
name: 'Test View',
type: 'table',
icon: 'IconList',
isCompact: false,
position: 0,
key: null,
kanbanFieldMetadataUniversalIdentifier: null,
kanbanAggregateOperationFieldMetadataUniversalIdentifier: null,
kanbanAggregateOperation: null,
mainGroupByFieldMetadataUniversalIdentifier: null,
viewFilterGroupUniversalIdentifiers: [],
rowLevelPermissionPredicateGroupUniversalIdentifiers: [],
};
const flatObjectMetadataMaps =
createEmptyUniversalFlatEntityMaps<typeof mockUniversalObjectMetadata>();
addUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrow({
universalFlatEntity: mockUniversalObjectMetadata,
universalFlatEntityMapsToMutate: flatObjectMetadataMaps,
});
const flatFieldMetadataMaps =
createEmptyUniversalFlatEntityMaps<typeof mockUniversalFieldMetadata>();
addUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrow({
universalFlatEntity: mockUniversalFieldMetadata,
universalFlatEntityMapsToMutate: flatFieldMetadataMaps,
});
const universalFlatEntityAndRelatedMapsToMutate = {
flatFieldMetadataMaps,
flatObjectMetadataMaps,
flatViewMaps:
createEmptyUniversalFlatEntityMaps<typeof mockUniversalView>(),
} as unknown as MetadataUniversalFlatEntityAndRelatedFlatEntityMapsForValidation<'view'>;
addUniversalFlatEntityToUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrow(
{
metadataName: 'view',
universalFlatEntity:
mockUniversalView as unknown as MetadataUniversalFlatEntity<'view'>,
universalFlatEntityAndRelatedMapsToMutate,
},
);
expect(
findFlatEntityByUniversalIdentifier({
universalIdentifier: viewUniversalIdentifier,
flatEntityMaps:
universalFlatEntityAndRelatedMapsToMutate.flatViewMaps as UniversalFlatEntityMaps<FlatView>,
}),
).toMatchObject({
universalIdentifier: viewUniversalIdentifier,
});
const updatedObjectMetadata = findFlatEntityByUniversalIdentifier({
universalIdentifier: objectMetadataUniversalIdentifier,
flatEntityMaps:
universalFlatEntityAndRelatedMapsToMutate.flatObjectMetadataMaps as UniversalFlatEntityMaps<FlatObjectMetadata>,
});
expect(updatedObjectMetadata).toMatchObject({
viewUniversalIdentifiers: [viewUniversalIdentifier],
});
const updatedFieldMetadata = findFlatEntityByUniversalIdentifier({
universalIdentifier: fieldMetadataUniversalIdentifier,
flatEntityMaps:
universalFlatEntityAndRelatedMapsToMutate.flatFieldMetadataMaps as UniversalFlatEntityMaps<FlatFieldMetadata>,
});
expect(updatedFieldMetadata).toMatchObject({
calendarViewUniversalIdentifiers: [viewUniversalIdentifier],
});
});
it('should throw when related entity is not found', () => {
const viewUniversalIdentifier = 'view-universal-1';
const nonExistentObjectMetadataUniversalIdentifier =
'non-existent-object-universal';
const applicationUniversalIdentifier =
'20202020-f3ad-452e-b5b6-2d49d3ea88b1';
const mockUniversalView = {
universalIdentifier: viewUniversalIdentifier,
objectMetadataUniversalIdentifier:
nonExistentObjectMetadataUniversalIdentifier,
viewFieldUniversalIdentifiers: [],
viewFilterUniversalIdentifiers: [],
viewGroupUniversalIdentifiers: [],
applicationUniversalIdentifier,
calendarFieldMetadataUniversalIdentifier: null,
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z',
name: 'Test View',
type: 'table',
icon: 'IconList',
isCompact: false,
position: 0,
key: null,
kanbanFieldMetadataUniversalIdentifier: null,
kanbanAggregateOperationFieldMetadataUniversalIdentifier: null,
kanbanAggregateOperation: null,
mainGroupByFieldMetadataUniversalIdentifier: null,
viewFilterGroupUniversalIdentifiers: [],
rowLevelPermissionPredicateGroupUniversalIdentifiers: [],
};
const universalFlatEntityAndRelatedMapsToMutate = {
flatFieldMetadataMaps: createEmptyUniversalFlatEntityMaps(),
flatObjectMetadataMaps: createEmptyUniversalFlatEntityMaps(),
flatViewMaps:
createEmptyUniversalFlatEntityMaps<typeof mockUniversalView>(),
} as unknown as MetadataUniversalFlatEntityAndRelatedFlatEntityMapsForValidation<'view'>;
expect(() =>
addUniversalFlatEntityToUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrow(
{
metadataName: 'view',
universalFlatEntity:
mockUniversalView as unknown as MetadataUniversalFlatEntity<'view'>,
universalFlatEntityAndRelatedMapsToMutate,
},
),
).toThrow(
new FlatEntityMapsException(
`Could not find flat entity with universal identifier ${nonExistentObjectMetadataUniversalIdentifier}`,
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
),
);
});
});
@@ -0,0 +1,76 @@
import { extractRecordIdsAndDatesAsExpectAny } from 'test/utils/extract-record-ids-and-dates-as-expect-any';
import { type AllMetadataName } from 'twenty-shared/metadata';
import {
eachTestingContextFilter,
type EachTestingContext,
} from 'twenty-shared/testing';
import { FieldMetadataType, type FromTo } from 'twenty-shared/types';
import { type MetadataUniversalFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-universal-flat-entity.type';
import { getFlatFieldMetadataMock } from 'src/engine/metadata-modules/flat-field-metadata/__mocks__/get-flat-field-metadata.mock';
import { compareTwoFlatEntity } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/compare-two-universal-flat-entity.util';
type TestContext<T extends AllMetadataName = AllMetadataName> = FromTo<
MetadataUniversalFlatEntity<T>,
'universalFlatEntity'
> & { metadataName: T };
describe('compareTwoFlatEntity', () => {
const testCases = [
{
title:
'It should detect flat field metadata isActive diff from true to false',
context: {
fromUniversalFlatEntity: getFlatFieldMetadataMock({
objectMetadataId: 'object-metadata-id',
type: FieldMetadataType.TEXT,
universalIdentifier: 'universal-identifier',
isActive: true,
}),
metadataName: 'fieldMetadata',
toUniversalFlatEntity: getFlatFieldMetadataMock({
objectMetadataId: 'object-metadata-id',
type: FieldMetadataType.TEXT,
universalIdentifier: 'universal-identifier',
isActive: false,
}),
},
},
{
title:
'It should detect flat field metadata isActive diff from true to false',
context: {
fromUniversalFlatEntity: getFlatFieldMetadataMock({
objectMetadataId: 'object-metadata-id',
type: FieldMetadataType.TEXT,
universalIdentifier: 'universal-identifier',
isActive: false,
}),
metadataName: 'fieldMetadata',
toUniversalFlatEntity: getFlatFieldMetadataMock({
objectMetadataId: 'object-metadata-id',
type: FieldMetadataType.TEXT,
universalIdentifier: 'universal-identifier',
isActive: true,
}),
},
},
] as const satisfies EachTestingContext<TestContext>[];
test.each(eachTestingContextFilter(testCases))(
'$title',
({
context: { metadataName, fromUniversalFlatEntity, toUniversalFlatEntity },
}) => {
const result = compareTwoFlatEntity({
fromUniversalFlatEntity,
toUniversalFlatEntity,
metadataName,
});
expect(result).toMatchSnapshot(
extractRecordIdsAndDatesAsExpectAny({ ...result }),
);
},
);
});
@@ -0,0 +1,192 @@
import { FieldMetadataType } from 'twenty-shared/types';
import { type MetadataUniversalFlatEntityAndRelatedFlatEntityMapsForValidation } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity-and-related-flat-entity-maps-for-validation.type';
import { type MetadataUniversalFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-universal-flat-entity.type';
import { findFlatEntityByUniversalIdentifier } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import { type FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
import { type UniversalFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-maps.type';
import { addUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/add-universal-flat-entity-to-universal-flat-entity-maps-through-mutation-or-throw.util';
import { deleteUniversalFlatEntityFromUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/delete-universal-flat-entity-from-universal-flat-entity-and-related-entity-maps-through-mutation-or-throw.util';
const createEmptyUniversalFlatEntityMaps = <T>(): UniversalFlatEntityMaps<
T & { universalIdentifier: string; applicationUniversalIdentifier: string }
> => ({
byUniversalIdentifier: {},
});
describe('deleteUniversalFlatEntityFromUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrow', () => {
it('should delete a view and update related objectMetadata by removing viewUniversalIdentifier', () => {
const objectMetadataUniversalIdentifier = 'object-universal-1';
const fieldMetadataUniversalIdentifier = 'field-universal-1';
const viewUniversalIdentifier = 'view-universal-1';
const applicationUniversalIdentifier =
'20202020-f3ad-452e-b5b6-2d49d3ea88b1';
const mockUniversalObjectMetadata = {
universalIdentifier: objectMetadataUniversalIdentifier,
viewUniversalIdentifiers: [viewUniversalIdentifier],
fieldUniversalIdentifiers: [],
indexMetadataUniversalIdentifiers: [],
description: 'default flat object metadata description',
icon: 'icon',
isActive: true,
isAuditLogged: true,
isCustom: true,
isLabelSyncedWithName: false,
isRemote: false,
isSearchable: true,
isSystem: false,
isUIReadOnly: false,
labelPlural: 'default flat object metadata label plural',
labelSingular: 'default flat object metadata label singular',
namePlural: 'defaultflatObjectMetadataNamePlural',
nameSingular: 'defaultflatObjectMetadataNameSingular',
shortcut: 'shortcut',
standardOverrides: null,
targetTableName: '',
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z',
duplicateCriteria: null,
applicationUniversalIdentifier,
labelIdentifierFieldMetadataUniversalIdentifier:
'20202020-1a62-405c-87fa-4d4fd215851b',
imageIdentifierFieldMetadataUniversalIdentifier:
'20202020-9d65-415f-b0e1-216a2e257ea4',
};
const mockUniversalFieldMetadata = {
universalIdentifier: fieldMetadataUniversalIdentifier,
objectMetadataUniversalIdentifier,
type: FieldMetadataType.DATE,
applicationUniversalIdentifier,
viewFieldUniversalIdentifiers: [],
viewFilterUniversalIdentifiers: [],
calendarViewUniversalIdentifiers: [viewUniversalIdentifier],
mainGroupByFieldMetadataViewUniversalIdentifiers: [],
kanbanAggregateOperationViewUniversalIdentifiers: [],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z',
defaultValue: null,
options: null,
morphId: null,
settings: null,
universalSettings: null,
description: 'default flat field metadata description',
icon: 'icon',
isActive: true,
isCustom: true,
name: 'flatFieldMetadataName',
label: 'flat field metadata label',
isNullable: true,
isUnique: false,
isUIReadOnly: false,
isLabelSyncedWithName: false,
isSystem: false,
standardOverrides: null,
relationTargetObjectMetadataUniversalIdentifier: null,
relationTargetFieldMetadataUniversalIdentifier: null,
};
const mockUniversalView = {
universalIdentifier: viewUniversalIdentifier,
objectMetadataUniversalIdentifier,
viewFieldUniversalIdentifiers: [],
viewFilterUniversalIdentifiers: [],
viewGroupUniversalIdentifiers: [],
applicationUniversalIdentifier,
calendarFieldMetadataUniversalIdentifier:
fieldMetadataUniversalIdentifier,
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z',
name: 'Test View',
type: 'table',
icon: 'IconList',
isCompact: false,
position: 0,
key: null,
kanbanFieldMetadataUniversalIdentifier: null,
kanbanAggregateOperationFieldMetadataUniversalIdentifier: null,
kanbanAggregateOperation: null,
mainGroupByFieldMetadataUniversalIdentifier: null,
viewFilterGroupUniversalIdentifiers: [],
rowLevelPermissionPredicateGroupUniversalIdentifiers: [],
};
const flatObjectMetadataMaps =
createEmptyUniversalFlatEntityMaps<typeof mockUniversalObjectMetadata>();
addUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrow({
universalFlatEntity: mockUniversalObjectMetadata,
universalFlatEntityMapsToMutate: flatObjectMetadataMaps,
});
const flatFieldMetadataMaps =
createEmptyUniversalFlatEntityMaps<typeof mockUniversalFieldMetadata>();
addUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrow({
universalFlatEntity: mockUniversalFieldMetadata,
universalFlatEntityMapsToMutate: flatFieldMetadataMaps,
});
const flatViewMaps =
createEmptyUniversalFlatEntityMaps<typeof mockUniversalView>();
addUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrow({
universalFlatEntity: mockUniversalView,
universalFlatEntityMapsToMutate: flatViewMaps,
});
const universalFlatEntityAndRelatedMapsToMutate = {
flatFieldMetadataMaps,
flatObjectMetadataMaps,
flatViewMaps,
} as unknown as MetadataUniversalFlatEntityAndRelatedFlatEntityMapsForValidation<'view'>;
expect(
findFlatEntityByUniversalIdentifier({
universalIdentifier: viewUniversalIdentifier,
flatEntityMaps:
universalFlatEntityAndRelatedMapsToMutate.flatViewMaps as UniversalFlatEntityMaps<FlatView>,
}),
).toBeDefined();
deleteUniversalFlatEntityFromUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrow(
{
metadataName: 'view',
universalFlatEntity:
mockUniversalView as unknown as MetadataUniversalFlatEntity<'view'>,
universalFlatEntityAndRelatedMapsToMutate,
},
);
expect(
findFlatEntityByUniversalIdentifier({
universalIdentifier: viewUniversalIdentifier,
flatEntityMaps:
universalFlatEntityAndRelatedMapsToMutate.flatViewMaps as UniversalFlatEntityMaps<FlatView>,
}),
).toBeUndefined();
const updatedObjectMetadata = findFlatEntityByUniversalIdentifier({
universalIdentifier: objectMetadataUniversalIdentifier,
flatEntityMaps:
universalFlatEntityAndRelatedMapsToMutate.flatObjectMetadataMaps as UniversalFlatEntityMaps<FlatObjectMetadata>,
});
expect(updatedObjectMetadata).toMatchObject({
viewUniversalIdentifiers: [],
});
const updatedFieldMetadata = findFlatEntityByUniversalIdentifier({
universalIdentifier: fieldMetadataUniversalIdentifier,
flatEntityMaps:
universalFlatEntityAndRelatedMapsToMutate.flatFieldMetadataMaps as UniversalFlatEntityMaps<FlatFieldMetadata>,
});
expect(updatedFieldMetadata).toMatchObject({
calendarViewUniversalIdentifiers: [],
});
});
});
@@ -1,10 +1,10 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { sanitizeFlatEntityUpdate } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/sanitize-flat-entity-update.util';
import { sanitizeUniversalFlatEntityUpdate } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/sanitize-universal-flat-entity-update.util';
describe('sanitizeFlatEntityUpdate', () => {
it('should return only valid properties for fieldMetadata when update contains valid and invalid properties', () => {
const result = sanitizeFlatEntityUpdate({
const result = sanitizeUniversalFlatEntityUpdate({
flatEntityUpdate: {
isActive: true,
label: 'New Label',
@@ -17,7 +17,7 @@ describe('sanitizeFlatEntityUpdate', () => {
});
it('should return empty object when all properties are undefined for fieldMetadata', () => {
const result = sanitizeFlatEntityUpdate({
const result = sanitizeUniversalFlatEntityUpdate({
flatEntityUpdate: {
isActive: undefined,
label: undefined,
@@ -29,7 +29,7 @@ describe('sanitizeFlatEntityUpdate', () => {
});
it('should return empty object when update is empty for fieldMetadata', () => {
const result = sanitizeFlatEntityUpdate({
const result = sanitizeUniversalFlatEntityUpdate({
flatEntityUpdate: {} as any,
metadataName: 'fieldMetadata' as AllMetadataName,
});
@@ -38,7 +38,7 @@ describe('sanitizeFlatEntityUpdate', () => {
});
it('should preserve null values as they are valid updates for fieldMetadata', () => {
const result = sanitizeFlatEntityUpdate({
const result = sanitizeUniversalFlatEntityUpdate({
flatEntityUpdate: {
isActive: false,
label: null,
@@ -51,7 +51,7 @@ describe('sanitizeFlatEntityUpdate', () => {
});
it('should return only valid properties for view metadata', () => {
const result = sanitizeFlatEntityUpdate({
const result = sanitizeUniversalFlatEntityUpdate({
flatEntityUpdate: {
name: 'My View',
icon: 'IconUser',
@@ -64,7 +64,7 @@ describe('sanitizeFlatEntityUpdate', () => {
});
it('should return only valid properties for objectMetadata', () => {
const result = sanitizeFlatEntityUpdate({
const result = sanitizeUniversalFlatEntityUpdate({
flatEntityUpdate: {
isActive: true,
labelSingular: 'Person',
@@ -78,7 +78,7 @@ describe('sanitizeFlatEntityUpdate', () => {
});
it('should handle viewField metadata updates', () => {
const result = sanitizeFlatEntityUpdate({
const result = sanitizeUniversalFlatEntityUpdate({
flatEntityUpdate: {
position: 1,
size: 100,
@@ -92,7 +92,7 @@ describe('sanitizeFlatEntityUpdate', () => {
});
it('should handle role metadata updates', () => {
const result = sanitizeFlatEntityUpdate({
const result = sanitizeUniversalFlatEntityUpdate({
flatEntityUpdate: {
label: 'Admin Role',
description: 'Administrator role',
@@ -105,7 +105,7 @@ describe('sanitizeFlatEntityUpdate', () => {
});
it('should handle agent metadata updates', () => {
const result = sanitizeFlatEntityUpdate({
const result = sanitizeUniversalFlatEntityUpdate({
flatEntityUpdate: {
name: 'My Agent',
description: 'Agent description',
@@ -118,7 +118,7 @@ describe('sanitizeFlatEntityUpdate', () => {
});
it('should handle webhook metadata updates', () => {
const result = sanitizeFlatEntityUpdate({
const result = sanitizeUniversalFlatEntityUpdate({
flatEntityUpdate: {
targetUrl: 'https://example.com/webhook',
description: 'My webhook',
@@ -6,7 +6,7 @@ import { FieldMetadataType, type FromTo } from 'twenty-shared/types';
import { type MetadataFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity.type';
import { getFlatFieldMetadataMock } from 'src/engine/metadata-modules/flat-field-metadata/__mocks__/get-flat-field-metadata.mock';
import { flatEntityDeletedCreatedUpdatedMatrixDispatcher } from 'src/engine/workspace-manager/workspace-migration/utils/flat-entity-deleted-created-updated-matrix-dispatcher.util';
import { flatEntityDeletedCreatedUpdatedMatrixDispatcher } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/universal-flat-entity-deleted-created-updated-matrix-dispatcher.util';
import { type WorkspaceMigrationBuilderOptions } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/workspace-migration-builder-options.type';
type TestContext = FromTo<MetadataFlatEntity<'fieldMetadata'>[]> & {
@@ -0,0 +1,116 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { isDefined } from 'twenty-shared/utils';
import {
FlatEntityMapsException,
FlatEntityMapsExceptionCode,
} from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception';
import { type MetadataUniversalFlatEntityAndRelatedUniversalFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-related-types.type';
import { type MetadataRelatedFlatEntityMapsKeys } from 'src/engine/metadata-modules/flat-entity/types/metadata-related-flat-entity-maps-keys.type';
import { type MetadataUniversalFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-universal-flat-entity.type';
import { findFlatEntityByUniversalIdentifierOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier-or-throw.util';
import { getMetadataFlatEntityMapsKey } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-flat-entity-maps-key.util';
import { ALL_UNIVERSAL_METADATA_RELATIONS } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/constants/all-universal-metadata-relations.constant';
import { type UniversalFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-maps.type';
import { addUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/add-universal-flat-entity-to-universal-flat-entity-maps-through-mutation-or-throw.util';
import { replaceUniversalFlatEntityInUniversalFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/replace-universal-flat-entity-in-universal-flat-entity-maps-through-mutation-or-throw.util';
type AddUniversalFlatEntityToUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrowArgs<
T extends AllMetadataName,
> = {
metadataName: T;
universalFlatEntity: MetadataUniversalFlatEntity<T>;
universalFlatEntityAndRelatedMapsToMutate: MetadataUniversalFlatEntityAndRelatedUniversalFlatEntityMaps<T>;
};
export const addUniversalFlatEntityToUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrow =
<T extends AllMetadataName>({
metadataName,
universalFlatEntity,
universalFlatEntityAndRelatedMapsToMutate,
}: AddUniversalFlatEntityToUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrowArgs<T>) => {
const flatEntityMapsKey = getMetadataFlatEntityMapsKey(metadataName);
addUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrow({
universalFlatEntity,
universalFlatEntityMapsToMutate:
universalFlatEntityAndRelatedMapsToMutate[flatEntityMapsKey],
});
const universalManyToOneRelations = Object.values(
ALL_UNIVERSAL_METADATA_RELATIONS[metadataName].manyToOne,
) as Array<{
metadataName: AllMetadataName;
universalFlatEntityForeignKeyAggregator: string | null;
universalForeignKey: string;
} | null>;
for (const universalRelation of universalManyToOneRelations) {
if (!isDefined(universalRelation)) {
continue;
}
const {
metadataName: relatedMetadataName,
universalFlatEntityForeignKeyAggregator,
universalForeignKey,
} = universalRelation;
if (!isDefined(universalFlatEntityForeignKeyAggregator)) {
continue;
}
const relatedFlatEntityMapsKey =
getMetadataFlatEntityMapsKey(relatedMetadataName);
const relatedUniversalFlatEntityMaps =
universalFlatEntityAndRelatedMapsToMutate[
relatedFlatEntityMapsKey as MetadataRelatedFlatEntityMapsKeys<T>
] as UniversalFlatEntityMaps<
MetadataUniversalFlatEntity<typeof relatedMetadataName>
>;
const universalForeignKeyValue = (
universalFlatEntity as unknown as Record<string, string | undefined>
)[universalForeignKey];
if (!isDefined(universalForeignKeyValue)) {
continue;
}
const relatedUniversalFlatEntity =
findFlatEntityByUniversalIdentifierOrThrow({
universalIdentifier: universalForeignKeyValue,
flatEntityMaps: relatedUniversalFlatEntityMaps,
});
if (
!Object.prototype.hasOwnProperty.call(
relatedUniversalFlatEntity,
universalFlatEntityForeignKeyAggregator,
)
) {
throw new FlatEntityMapsException(
`Should never occur, invalid flat entity typing. flat ${relatedMetadataName} should contain ${universalFlatEntityForeignKeyAggregator}`,
FlatEntityMapsExceptionCode.ENTITY_MALFORMED,
);
}
const updatedRelatedEntity = {
...relatedUniversalFlatEntity,
[universalFlatEntityForeignKeyAggregator]: [
...((
relatedUniversalFlatEntity as unknown as Record<string, string[]>
)[universalFlatEntityForeignKeyAggregator] ?? []),
universalFlatEntity.universalIdentifier,
],
};
replaceUniversalFlatEntityInUniversalFlatEntityMapsThroughMutationOrThrow(
{
universalFlatEntity: updatedRelatedEntity,
universalFlatEntityMapsToMutate: relatedUniversalFlatEntityMaps,
},
);
}
};
@@ -0,0 +1,43 @@
import { isDefined } from 'twenty-shared/utils';
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 UniversalSyncableFlatEntity } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type';
import { type UniversalFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-maps.type';
type AddUniversalFlatEntityToUniversalFlatEntityMapsOrThrowArgs<
T extends SyncableFlatEntity | UniversalSyncableFlatEntity,
> = {
universalFlatEntity: T;
universalFlatEntityMaps: UniversalFlatEntityMaps<T>;
};
export const addUniversalFlatEntityToUniversalFlatEntityMapsOrThrow = <
T extends SyncableFlatEntity | UniversalSyncableFlatEntity,
>({
universalFlatEntity,
universalFlatEntityMaps,
}: AddUniversalFlatEntityToUniversalFlatEntityMapsOrThrowArgs<T>): UniversalFlatEntityMaps<T> => {
if (
isDefined(
universalFlatEntityMaps.byUniversalIdentifier[
universalFlatEntity.universalIdentifier
],
)
) {
throw new FlatEntityMapsException(
'addUniversalFlatEntityToUniversalFlatEntityMapsOrThrow: flat entity to add already exists',
FlatEntityMapsExceptionCode.ENTITY_ALREADY_EXISTS,
);
}
return {
byUniversalIdentifier: {
...universalFlatEntityMaps.byUniversalIdentifier,
[universalFlatEntity.universalIdentifier]: universalFlatEntity,
},
};
};
@@ -0,0 +1,39 @@
import { isDefined } from 'twenty-shared/utils';
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 UniversalSyncableFlatEntity } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type';
import { type UniversalFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-maps.type';
type AddUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrowArgs<
T extends SyncableFlatEntity | UniversalSyncableFlatEntity,
> = {
universalFlatEntity: T;
universalFlatEntityMapsToMutate: UniversalFlatEntityMaps<T>;
};
export const addUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrow =
<T extends SyncableFlatEntity | UniversalSyncableFlatEntity>({
universalFlatEntity,
universalFlatEntityMapsToMutate,
}: AddUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrowArgs<T>): void => {
if (
isDefined(
universalFlatEntityMapsToMutate.byUniversalIdentifier[
universalFlatEntity.universalIdentifier
],
)
) {
throw new FlatEntityMapsException(
'addUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrow: flat entity to add already exists',
FlatEntityMapsExceptionCode.ENTITY_ALREADY_EXISTS,
);
}
universalFlatEntityMapsToMutate.byUniversalIdentifier[
universalFlatEntity.universalIdentifier
] = universalFlatEntity;
};
@@ -0,0 +1,77 @@
import diff from 'microdiff';
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type FromTo } from 'twenty-shared/types';
import { parseJson } from 'twenty-shared/utils';
import { ALL_UNIVERSAL_FLAT_ENTITY_PROPERTIES_TO_COMPARE_AND_STRINGIFY } from 'src/engine/metadata-modules/flat-entity/constant/all-universal-flat-entity-properties-to-compare-and-stringify.constant';
import { type MetadataUniversalFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-universal-flat-entity.type';
import { type MetadataUniversalFlatEntityPropertiesToStringify } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/metadata-universal-flat-entity-properties-to-stringify.type';
import { type UniversalFlatEntityUpdate } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-update.type';
import { transformUniversalFlatEntityForComparison } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/transform-universal-flat-entity-for-comparison.util';
type CompareTwoUniversalFlatEntityArgs<T extends AllMetadataName> = FromTo<
MetadataUniversalFlatEntity<T>,
'universalFlatEntity'
> & { metadataName: T };
export const compareTwoFlatEntity = <T extends AllMetadataName>({
fromUniversalFlatEntity,
toUniversalFlatEntity,
metadataName,
}: CompareTwoUniversalFlatEntityArgs<T>):
| UniversalFlatEntityUpdate<T>
| undefined => {
const { propertiesToStringify, propertiesToCompare } =
ALL_UNIVERSAL_FLAT_ENTITY_PROPERTIES_TO_COMPARE_AND_STRINGIFY[metadataName];
const [transformedFromUniversalFlatEntity, transformedToUniversalFlatEntity] =
[fromUniversalFlatEntity, toUniversalFlatEntity].map(
(universalFlatEntity) =>
transformUniversalFlatEntityForComparison({
universalFlatEntity,
propertiesToCompare,
propertiesToStringify,
}),
);
const flatEntityDifferences = diff(
transformedFromUniversalFlatEntity,
transformedToUniversalFlatEntity,
);
if (flatEntityDifferences.length === 0) {
return undefined;
}
const initialAccumulator: UniversalFlatEntityUpdate<T> = {};
return flatEntityDifferences.reduce((accumulator, difference) => {
switch (difference.type) {
case 'CHANGE': {
const { path, value } = difference;
const property = path[0];
const isJsonb = propertiesToStringify.includes(
property as MetadataUniversalFlatEntityPropertiesToStringify<T>,
);
if (isJsonb) {
return {
...accumulator,
[property]: parseJson(value),
};
}
return {
...accumulator,
[property]: value,
};
}
case 'CREATE':
case 'REMOVE':
default: {
// Should never occur, we should only provide null never undefined and so on
return accumulator;
}
}
}, initialAccumulator);
};
@@ -0,0 +1,125 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { isDefined } from 'twenty-shared/utils';
import {
FlatEntityMapsException,
FlatEntityMapsExceptionCode,
} from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception';
import { type MetadataRelatedFlatEntityMapsKeys } from 'src/engine/metadata-modules/flat-entity/types/metadata-related-flat-entity-maps-keys.type';
import { type MetadataUniversalFlatEntityAndRelatedUniversalFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-related-types.type';
import { type MetadataUniversalFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-universal-flat-entity.type';
import { findFlatEntityByUniversalIdentifier } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util';
import { getMetadataFlatEntityMapsKey } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-flat-entity-maps-key.util';
import { ALL_UNIVERSAL_METADATA_RELATIONS } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/constants/all-universal-metadata-relations.constant';
import { type UniversalFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-maps.type';
import { deleteUniversalFlatEntityFromUniversalFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/delete-universal-flat-entity-from-universal-flat-entity-maps-through-mutation-or-throw.util';
import { replaceUniversalFlatEntityInUniversalFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/replace-universal-flat-entity-in-universal-flat-entity-maps-through-mutation-or-throw.util';
type DeleteUniversalFlatEntityFromUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrowArgs<
T extends AllMetadataName,
> = {
metadataName: T;
universalFlatEntity: MetadataUniversalFlatEntity<T>;
universalFlatEntityAndRelatedMapsToMutate: MetadataUniversalFlatEntityAndRelatedUniversalFlatEntityMaps<T>;
};
export const deleteUniversalFlatEntityFromUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrow =
<T extends AllMetadataName>({
metadataName,
universalFlatEntity,
universalFlatEntityAndRelatedMapsToMutate,
}: DeleteUniversalFlatEntityFromUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrowArgs<T>) => {
const flatEntityMapsKey = getMetadataFlatEntityMapsKey(metadataName);
deleteUniversalFlatEntityFromUniversalFlatEntityMapsThroughMutationOrThrow({
universalIdentifierToDelete: universalFlatEntity.universalIdentifier,
universalFlatEntityMapsToMutate:
universalFlatEntityAndRelatedMapsToMutate[
flatEntityMapsKey
] as UniversalFlatEntityMaps<
MetadataUniversalFlatEntity<typeof metadataName>
>,
});
const universalManyToOneRelations = Object.values(
ALL_UNIVERSAL_METADATA_RELATIONS[metadataName].manyToOne,
) as Array<{
metadataName: AllMetadataName;
universalFlatEntityForeignKeyAggregator: string | null;
universalForeignKey: string;
} | null>;
for (const universalRelation of universalManyToOneRelations) {
if (!isDefined(universalRelation)) {
continue;
}
const {
metadataName: relatedMetadataName,
universalFlatEntityForeignKeyAggregator,
universalForeignKey,
} = universalRelation;
if (!isDefined(universalFlatEntityForeignKeyAggregator)) {
continue;
}
const relatedFlatEntityMapsKey =
getMetadataFlatEntityMapsKey(relatedMetadataName);
const relatedUniversalFlatEntityMaps =
universalFlatEntityAndRelatedMapsToMutate[
relatedFlatEntityMapsKey as MetadataRelatedFlatEntityMapsKeys<T>
] as UniversalFlatEntityMaps<
MetadataUniversalFlatEntity<typeof relatedMetadataName>
>;
const universalForeignKeyValue = (
universalFlatEntity as unknown as Record<string, string | undefined>
)[universalForeignKey];
if (!isDefined(universalForeignKeyValue)) {
continue;
}
const relatedUniversalFlatEntity = findFlatEntityByUniversalIdentifier({
universalIdentifier: universalForeignKeyValue,
flatEntityMaps: relatedUniversalFlatEntityMaps,
});
if (!isDefined(relatedUniversalFlatEntity)) {
continue;
}
if (
!Object.prototype.hasOwnProperty.call(
relatedUniversalFlatEntity,
universalFlatEntityForeignKeyAggregator,
)
) {
throw new FlatEntityMapsException(
`Should never occur, invalid flat entity typing. flat ${relatedMetadataName} should contain ${universalFlatEntityForeignKeyAggregator}`,
FlatEntityMapsExceptionCode.ENTITY_MALFORMED,
);
}
const updatedRelatedEntity = {
...relatedUniversalFlatEntity,
[universalFlatEntityForeignKeyAggregator]: (
(relatedUniversalFlatEntity as unknown as Record<string, string[]>)[
universalFlatEntityForeignKeyAggregator
] ?? []
).filter(
(universalIdentifier) =>
universalIdentifier !== universalFlatEntity.universalIdentifier,
),
};
replaceUniversalFlatEntityInUniversalFlatEntityMapsThroughMutationOrThrow(
{
universalFlatEntity: updatedRelatedEntity,
universalFlatEntityMapsToMutate: relatedUniversalFlatEntityMaps,
},
);
}
};
@@ -0,0 +1,38 @@
import { isDefined } from 'twenty-shared/utils';
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 UniversalSyncableFlatEntity } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type';
import { type UniversalFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-maps.type';
export type DeleteUniversalFlatEntityFromUniversalFlatEntityMapsThroughMutationOrThrowArgs<
T extends SyncableFlatEntity | UniversalSyncableFlatEntity,
> = {
universalIdentifierToDelete: string;
universalFlatEntityMapsToMutate: UniversalFlatEntityMaps<T>;
};
export const deleteUniversalFlatEntityFromUniversalFlatEntityMapsThroughMutationOrThrow =
<T extends SyncableFlatEntity | UniversalSyncableFlatEntity>({
universalFlatEntityMapsToMutate,
universalIdentifierToDelete,
}: DeleteUniversalFlatEntityFromUniversalFlatEntityMapsThroughMutationOrThrowArgs<T>): void => {
const entityToDelete =
universalFlatEntityMapsToMutate.byUniversalIdentifier[
universalIdentifierToDelete
];
if (!isDefined(entityToDelete)) {
throw new FlatEntityMapsException(
'deleteUniversalFlatEntityFromUniversalFlatEntityMapsThroughMutationOrThrow: entity to delete not found',
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
);
}
delete universalFlatEntityMapsToMutate.byUniversalIdentifier[
universalIdentifierToDelete
];
};
@@ -0,0 +1,28 @@
import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type';
import { type UniversalSyncableFlatEntity } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type';
import { type UniversalFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-maps.type';
import { addUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/add-universal-flat-entity-to-universal-flat-entity-maps-through-mutation-or-throw.util';
import { deleteUniversalFlatEntityFromUniversalFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/delete-universal-flat-entity-from-universal-flat-entity-maps-through-mutation-or-throw.util';
export type ReplaceUniversalFlatEntityInUniversalFlatEntityMapsThroughMutationOrThrowArgs<
T extends SyncableFlatEntity | UniversalSyncableFlatEntity,
> = {
universalFlatEntity: T;
universalFlatEntityMapsToMutate: UniversalFlatEntityMaps<T>;
};
export const replaceUniversalFlatEntityInUniversalFlatEntityMapsThroughMutationOrThrow =
<T extends SyncableFlatEntity | UniversalSyncableFlatEntity>({
universalFlatEntity,
universalFlatEntityMapsToMutate,
}: ReplaceUniversalFlatEntityInUniversalFlatEntityMapsThroughMutationOrThrowArgs<T>): void => {
deleteUniversalFlatEntityFromUniversalFlatEntityMapsThroughMutationOrThrow({
universalFlatEntityMapsToMutate,
universalIdentifierToDelete: universalFlatEntity.universalIdentifier,
});
addUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrow({
universalFlatEntity,
universalFlatEntityMapsToMutate,
});
};
@@ -0,0 +1,156 @@
import { t } from '@lingui/core/macro';
import { type AllMetadataName } from 'twenty-shared/metadata';
import { isDefined } from 'twenty-shared/utils';
import { type MetadataManyToOneRelationConfiguration } from 'src/engine/metadata-modules/flat-entity/constant/all-metadata-relations.constant';
import {
FlatEntityMapsException,
FlatEntityMapsExceptionCode,
} from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception';
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
import { type ExtractEntityManyToOneEntityRelationProperties } from 'src/engine/metadata-modules/flat-entity/types/extract-entity-many-to-one-entity-relation-properties.type';
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 MetadataToFlatEntityMapsKey } from 'src/engine/metadata-modules/flat-entity/types/metadata-to-flat-entity-maps-key';
import { findFlatEntityByUniversalIdentifier } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util';
import { getMetadataFlatEntityMapsKey } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-flat-entity-maps-key.util';
import {
ALL_UNIVERSAL_METADATA_RELATIONS,
type ToUniversalMetadataManyToOneRelationConfiguration,
} from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/constants/all-universal-metadata-relations.constant';
type UniversalManyToOneConfig<T extends AllMetadataName> =
(typeof ALL_UNIVERSAL_METADATA_RELATIONS)[T]['manyToOne'];
type ExtractUniversalForeignKeys<T> = {
[K in keyof T]: T[K] extends { universalForeignKey: infer UFK } ? UFK : never;
}[keyof T];
type MetadataUniversalManyToOneJoinColumn<T extends AllMetadataName> =
ExtractUniversalForeignKeys<UniversalManyToOneConfig<T>>;
type TargetMetadataNamesForUniversalForeignKeys<
T extends AllMetadataName,
TProvidedKeys extends string,
> = {
[K in keyof UniversalManyToOneConfig<T>]: UniversalManyToOneConfig<T>[K] extends {
universalForeignKey: infer _UFK extends TProvidedKeys;
metadataName: infer MN extends AllMetadataName;
}
? MN
: never;
}[keyof UniversalManyToOneConfig<T>];
type RequiredFlatEntityMapsForUniversalForeignKeys<
T extends AllMetadataName,
TProvidedKeys extends string,
> = Pick<
AllFlatEntityMaps,
MetadataToFlatEntityMapsKey<
TargetMetadataNamesForUniversalForeignKeys<T, TProvidedKeys>
>
>;
type ResolvedForeignKeyIds<
T extends AllMetadataName,
TProvidedKeys extends Extract<
MetadataUniversalManyToOneJoinColumn<T>,
string
>,
> = {
[K in keyof UniversalManyToOneConfig<T> as UniversalManyToOneConfig<T>[K] extends {
universalForeignKey: infer UFK extends string;
foreignKey: infer FK extends string;
}
? UFK extends TProvidedKeys
? FK
: never
: never]: UniversalManyToOneConfig<T>[K] extends { isNullable: true }
? string | null
: string;
};
export const resolveUniversalRelationIdentifiersToIds = <
T extends AllMetadataName,
TProvidedKeys extends Extract<
MetadataUniversalManyToOneJoinColumn<T>,
string
> = Extract<MetadataUniversalManyToOneJoinColumn<T>, string>,
>({
metadataName,
universalForeignKeyValues,
flatEntityMaps,
}: {
metadataName: T;
universalForeignKeyValues: Record<TProvidedKeys, string | null | undefined>;
flatEntityMaps: RequiredFlatEntityMapsForUniversalForeignKeys<
T,
TProvidedKeys
>;
}): ResolvedForeignKeyIds<T, TProvidedKeys> => {
const relations = ALL_UNIVERSAL_METADATA_RELATIONS[metadataName].manyToOne;
const result: Record<string, string | null> = {};
for (const relation of Object.values(
relations,
) as ToUniversalMetadataManyToOneRelationConfiguration<
MetadataManyToOneRelationConfiguration<
T,
ExtractEntityManyToOneEntityRelationProperties<MetadataEntity<T>>
>
>[]) {
if (!isDefined(relation)) {
continue;
}
const {
foreignKey,
universalForeignKey,
metadataName: targetMetadataName,
isNullable,
} = relation;
if (
!Object.prototype.hasOwnProperty.call(
universalForeignKeyValues,
universalForeignKey,
)
) {
continue;
}
const universalIdentifierValue =
universalForeignKeyValues[
universalForeignKey as keyof typeof universalForeignKeyValues
];
const mapsKey = getMetadataFlatEntityMapsKey(
targetMetadataName,
) as keyof RequiredFlatEntityMapsForUniversalForeignKeys<T, TProvidedKeys>;
const targetFlatEntityMaps = flatEntityMaps[mapsKey];
if (isNullable && !isDefined(universalIdentifierValue)) {
result[foreignKey] = null;
continue;
}
const targetEntity = findFlatEntityByUniversalIdentifier<
MetadataFlatEntity<typeof targetMetadataName>
>({
flatEntityMaps: targetFlatEntityMaps,
universalIdentifier: universalIdentifierValue as string,
});
if (!isDefined(targetEntity)) {
throw new FlatEntityMapsException(
t`Could not find ${targetMetadataName} for given ${universalForeignKey}`,
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
);
}
result[foreignKey] = targetEntity.id;
}
return result as ResolvedForeignKeyIds<T, TProvidedKeys>;
};
@@ -0,0 +1,95 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { isDefined } from 'twenty-shared/utils';
import { type MetadataManyToOneRelationConfiguration } from 'src/engine/metadata-modules/flat-entity/constant/all-metadata-relations.constant';
import {
FlatEntityMapsException,
FlatEntityMapsExceptionCode,
} from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception';
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
import { type ExtractEntityManyToOneEntityRelationProperties } from 'src/engine/metadata-modules/flat-entity/types/extract-entity-many-to-one-entity-relation-properties.type';
import { type FlatEntityUpdate } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-update.type';
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 { findFlatEntityByUniversalIdentifier } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util';
import { getMetadataFlatEntityMapsKey } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-flat-entity-maps-key.util';
import {
ALL_UNIVERSAL_METADATA_RELATIONS,
type ToUniversalMetadataManyToOneRelationConfiguration,
} from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/constants/all-universal-metadata-relations.constant';
import { type UniversalFlatEntityUpdate } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-update.type';
export const resolveUniversalUpdateRelationIdentifiersToIds = <
T extends AllMetadataName,
>({
metadataName,
universalUpdate,
allFlatEntityMaps,
}: {
metadataName: T;
universalUpdate: UniversalFlatEntityUpdate<T>;
allFlatEntityMaps: AllFlatEntityMaps;
}): FlatEntityUpdate<T> => {
const relations = ALL_UNIVERSAL_METADATA_RELATIONS[metadataName].manyToOne;
const result: Record<string, unknown> = { ...universalUpdate };
for (const relation of Object.values(
relations,
) as ToUniversalMetadataManyToOneRelationConfiguration<
MetadataManyToOneRelationConfiguration<
T,
ExtractEntityManyToOneEntityRelationProperties<MetadataEntity<T>>
>
>[]) {
if (!isDefined(relation)) {
continue;
}
const {
foreignKey,
universalForeignKey,
metadataName: targetMetadataName,
} = relation;
if (!Object.prototype.hasOwnProperty.call(result, universalForeignKey)) {
continue;
}
const universalIdentifierValue = result[universalForeignKey] as
| string
| null
| undefined;
delete result[universalForeignKey];
if (!isDefined(universalIdentifierValue)) {
if (universalIdentifierValue === null) {
result[foreignKey] = null;
}
continue;
}
const mapsKey = getMetadataFlatEntityMapsKey(targetMetadataName);
const targetFlatEntityMaps = allFlatEntityMaps[mapsKey];
const targetEntity = findFlatEntityByUniversalIdentifier<
MetadataFlatEntity<typeof targetMetadataName>
>({
flatEntityMaps: targetFlatEntityMaps,
universalIdentifier: universalIdentifierValue,
});
if (!isDefined(targetEntity)) {
throw new FlatEntityMapsException(
`Could not resolve ${universalForeignKey} to ${foreignKey}: no ${targetMetadataName} found for universal identifier ${universalIdentifierValue}`,
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
);
}
result[foreignKey] = targetEntity.id;
}
return result as FlatEntityUpdate<T>;
};
@@ -0,0 +1,30 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { ALL_UNIVERSAL_FLAT_ENTITY_PROPERTIES_TO_COMPARE_AND_STRINGIFY } from 'src/engine/metadata-modules/flat-entity/constant/all-universal-flat-entity-properties-to-compare-and-stringify.constant';
import { type UniversalFlatEntityUpdate } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-update.type';
export const sanitizeUniversalFlatEntityUpdate = <T extends AllMetadataName>({
flatEntityUpdate,
metadataName,
}: {
flatEntityUpdate: UniversalFlatEntityUpdate<T>;
metadataName: T;
}): UniversalFlatEntityUpdate<T> => {
const { propertiesToCompare } =
ALL_UNIVERSAL_FLAT_ENTITY_PROPERTIES_TO_COMPARE_AND_STRINGIFY[metadataName];
const initialAccumulator: UniversalFlatEntityUpdate<T> = {};
return propertiesToCompare.reduce((accumulator, property) => {
const updatedValue = flatEntityUpdate[property];
if (updatedValue === undefined) {
return accumulator;
}
return {
...accumulator,
[property]: updatedValue,
};
}, initialAccumulator);
};
@@ -0,0 +1,43 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type MetadataUniversalFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-universal-flat-entity.type';
import { orderObjectProperties } from 'src/engine/metadata-modules/flat-entity/utils/order-object-properties.util';
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';
export function transformUniversalFlatEntityForComparison<
T extends AllMetadataName,
>({
universalFlatEntity,
propertiesToCompare,
propertiesToStringify,
}: {
universalFlatEntity: MetadataUniversalFlatEntity<T>;
propertiesToCompare: MetadataUniversalFlatEntityPropertiesToCompare<T>[];
propertiesToStringify: MetadataUniversalFlatEntityPropertiesToStringify<T>[];
}) {
return propertiesToCompare.reduce(
(flatEntityAccumulator, propertyToCompare) => {
const currentValue = universalFlatEntity[propertyToCompare];
if (
propertiesToStringify.includes(
propertyToCompare as MetadataUniversalFlatEntityPropertiesToStringify<T>,
)
) {
const orderedValue = orderObjectProperties(currentValue);
return {
...flatEntityAccumulator,
[propertyToCompare]: JSON.stringify(orderedValue),
};
}
return {
...flatEntityAccumulator,
[propertyToCompare]: currentValue,
};
},
{},
);
}
@@ -0,0 +1,102 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type FromTo } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { type MetadataUniversalFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-universal-flat-entity.type';
import { type MetadataUniversalFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/metadata-universal-flat-entity-maps.type';
import { type UniversalFlatEntityUpdate } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-update.type';
import { compareTwoFlatEntity } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/compare-two-universal-flat-entity.util';
import { addUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/add-universal-flat-entity-to-universal-flat-entity-maps-through-mutation-or-throw.util';
import { shouldInferDeletionFromMissingEntities } from 'src/engine/workspace-manager/workspace-migration/utils/should-infer-deletion-from-missing-entities.util';
import { type WorkspaceMigrationBuilderOptions } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/workspace-migration-builder-options.type';
export type DeletedCreatedUpdatedMatrix<T extends AllMetadataName> = {
createdFlatEntityMaps: MetadataUniversalFlatEntityMaps<T>;
deletedFlatEntityMaps: MetadataUniversalFlatEntityMaps<T>;
updatedFlatEntityMaps: {
byUniversalIdentifier: Record<
string,
{
update: UniversalFlatEntityUpdate<T>;
}
>;
};
};
export type UniversalIdentifierItem = {
universalIdentifier: string;
};
type FlatEntityDeletedCreatedUpdatedMatrixDispatcherArgs<
T extends AllMetadataName,
> = FromTo<MetadataUniversalFlatEntity<T>[]> & {
metadataName: T;
buildOptions: WorkspaceMigrationBuilderOptions;
};
export const flatEntityDeletedCreatedUpdatedMatrixDispatcher = <
T extends AllMetadataName,
>({
from,
to,
metadataName,
buildOptions,
}: FlatEntityDeletedCreatedUpdatedMatrixDispatcherArgs<T>): DeletedCreatedUpdatedMatrix<T> => {
const initialDispatcher: DeletedCreatedUpdatedMatrix<T> = {
createdFlatEntityMaps: { byUniversalIdentifier: {} },
deletedFlatEntityMaps: { byUniversalIdentifier: {} },
updatedFlatEntityMaps: { byUniversalIdentifier: {} },
};
const fromMap = new Map(from.map((obj) => [obj.universalIdentifier, obj]));
const toMap = new Map(to.map((obj) => [obj.universalIdentifier, obj]));
if (shouldInferDeletionFromMissingEntities({ buildOptions, metadataName })) {
for (const [universalIdentifier, fromEntity] of fromMap) {
if (toMap.has(universalIdentifier)) {
continue;
}
addUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrow({
universalFlatEntity: fromEntity,
universalFlatEntityMapsToMutate:
initialDispatcher.deletedFlatEntityMaps,
});
}
}
for (const [universalIdentifier, toFlatEntity] of toMap) {
if (fromMap.has(universalIdentifier)) {
continue;
}
addUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrow({
universalFlatEntity: toFlatEntity,
universalFlatEntityMapsToMutate: initialDispatcher.createdFlatEntityMaps,
});
}
for (const [universalIdentifier, fromUniversalFlatEntity] of fromMap) {
const toUniversalFlatEntity = toMap.get(universalIdentifier);
if (!isDefined(toUniversalFlatEntity)) {
continue;
}
const update = compareTwoFlatEntity({
fromUniversalFlatEntity,
toUniversalFlatEntity,
metadataName,
});
if (!isDefined(update)) {
continue;
}
initialDispatcher.updatedFlatEntityMaps.byUniversalIdentifier[
fromUniversalFlatEntity.universalIdentifier
] = {
update,
};
}
return initialDispatcher;
};
@@ -1,42 +1,36 @@
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 UniversalSyncableFlatEntity } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type';
import { type UniversalFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-maps.type';
import {
type CircularDependencyValidationResult,
validateFlatEntityCircularDependency,
} from 'src/engine/workspace-manager/workspace-migration/utils/validate-flat-entity-circular-dependency.util';
type TestFlatEntity = SyncableFlatEntity & {
parentId: string | null;
type TestFlatEntity = UniversalSyncableFlatEntity & {
parentUniversalIdentifier: string | null;
};
const createFlatEntityMaps = (
const createUniversalFlatEntityMaps = (
entities: TestFlatEntity[],
): FlatEntityMaps<TestFlatEntity> => ({
): UniversalFlatEntityMaps<TestFlatEntity> => ({
byUniversalIdentifier: Object.fromEntries(
entities.map((entity) => [entity.universalIdentifier, entity]),
),
universalIdentifierById: Object.fromEntries(
entities.map((entity) => [entity.id, entity.universalIdentifier]),
),
universalIdentifiersByApplicationId: {},
});
const createTestEntity = (
id: string,
parentId: string | null = null,
universalIdentifier: string,
parentUniversalIdentifier: string | null = null,
): TestFlatEntity => ({
id,
parentId,
universalIdentifier: id,
applicationId: 'test-app',
workspaceId: 'test-workspace',
parentUniversalIdentifier,
universalIdentifier,
applicationUniversalIdentifier: 'test-app',
});
type TestContext = {
flatEntityId: string;
flatEntityParentId: string;
flatEntityUniversalIdentifier: string;
flatEntityParentUniversalIdentifier: string;
maxDepth?: number;
entities: TestFlatEntity[];
expected: CircularDependencyValidationResult;
@@ -48,8 +42,8 @@ const testCases: ValidateCircularDependencyTestCase[] = [
{
title: 'should fail with self_reference when entity is its own parent',
context: {
flatEntityId: 'entity-1',
flatEntityParentId: 'entity-1',
flatEntityUniversalIdentifier: 'entity-1',
flatEntityParentUniversalIdentifier: 'entity-1',
entities: [],
expected: {
status: 'fail',
@@ -60,8 +54,8 @@ const testCases: ValidateCircularDependencyTestCase[] = [
{
title: 'should succeed with depth 2 when parent has no parent',
context: {
flatEntityId: 'entity-child',
flatEntityParentId: 'entity-parent',
flatEntityUniversalIdentifier: 'entity-child',
flatEntityParentUniversalIdentifier: 'entity-parent',
entities: [createTestEntity('entity-parent', null)],
expected: {
status: 'success',
@@ -72,8 +66,8 @@ const testCases: ValidateCircularDependencyTestCase[] = [
{
title: 'should succeed with depth 3 when parent has a grandparent',
context: {
flatEntityId: 'entity-child',
flatEntityParentId: 'entity-parent',
flatEntityUniversalIdentifier: 'entity-child',
flatEntityParentUniversalIdentifier: 'entity-parent',
entities: [
createTestEntity('entity-grandparent', null),
createTestEntity('entity-parent', 'entity-grandparent'),
@@ -88,8 +82,8 @@ const testCases: ValidateCircularDependencyTestCase[] = [
title:
'should fail with circular_dependency when parent points back to entity',
context: {
flatEntityId: 'entity-a',
flatEntityParentId: 'entity-b',
flatEntityUniversalIdentifier: 'entity-a',
flatEntityParentUniversalIdentifier: 'entity-b',
entities: [createTestEntity('entity-b', 'entity-a')],
expected: {
status: 'fail',
@@ -102,8 +96,8 @@ const testCases: ValidateCircularDependencyTestCase[] = [
title:
'should fail with circular_dependency when chain creates a cycle (A -> B -> C -> A)',
context: {
flatEntityId: 'entity-a',
flatEntityParentId: 'entity-b',
flatEntityUniversalIdentifier: 'entity-a',
flatEntityParentUniversalIdentifier: 'entity-b',
entities: [
createTestEntity('entity-b', 'entity-c'),
createTestEntity('entity-c', 'entity-a'),
@@ -119,8 +113,8 @@ const testCases: ValidateCircularDependencyTestCase[] = [
title:
'should fail with circular_dependency when ancestors form a cycle among themselves',
context: {
flatEntityId: 'entity-new',
flatEntityParentId: 'entity-a',
flatEntityUniversalIdentifier: 'entity-new',
flatEntityParentUniversalIdentifier: 'entity-a',
entities: [
createTestEntity('entity-a', 'entity-b'),
createTestEntity('entity-b', 'entity-a'),
@@ -135,8 +129,8 @@ const testCases: ValidateCircularDependencyTestCase[] = [
{
title: 'should succeed when parent does not exist in maps',
context: {
flatEntityId: 'entity-child',
flatEntityParentId: 'non-existent-parent',
flatEntityUniversalIdentifier: 'entity-child',
flatEntityParentUniversalIdentifier: 'non-existent-parent',
entities: [],
expected: {
status: 'success',
@@ -147,8 +141,8 @@ const testCases: ValidateCircularDependencyTestCase[] = [
{
title: 'should fail with max_depth_exceeded when depth exceeds maxDepth',
context: {
flatEntityId: 'entity-child',
flatEntityParentId: 'entity-parent',
flatEntityUniversalIdentifier: 'entity-child',
flatEntityParentUniversalIdentifier: 'entity-parent',
maxDepth: 2,
entities: [
createTestEntity('entity-grandparent', null),
@@ -164,8 +158,8 @@ const testCases: ValidateCircularDependencyTestCase[] = [
{
title: 'should succeed when depth equals maxDepth',
context: {
flatEntityId: 'entity-child',
flatEntityParentId: 'entity-parent',
flatEntityUniversalIdentifier: 'entity-child',
flatEntityParentUniversalIdentifier: 'entity-parent',
maxDepth: 3,
entities: [
createTestEntity('entity-grandparent', null),
@@ -180,8 +174,8 @@ const testCases: ValidateCircularDependencyTestCase[] = [
{
title: 'should succeed with depth 2 when maxDepth is 2 and parent is root',
context: {
flatEntityId: 'entity-child',
flatEntityParentId: 'entity-parent',
flatEntityUniversalIdentifier: 'entity-child',
flatEntityParentUniversalIdentifier: 'entity-parent',
maxDepth: 2,
entities: [createTestEntity('entity-parent', null)],
expected: {
@@ -194,8 +188,8 @@ const testCases: ValidateCircularDependencyTestCase[] = [
title:
'should check max depth before circular dependency to prevent infinite loop',
context: {
flatEntityId: 'entity-new',
flatEntityParentId: 'entity-a',
flatEntityUniversalIdentifier: 'entity-new',
flatEntityParentUniversalIdentifier: 'entity-a',
maxDepth: 2,
entities: [
createTestEntity('entity-a', 'entity-b'),
@@ -213,8 +207,8 @@ const testCases: ValidateCircularDependencyTestCase[] = [
{
title: 'should handle deep valid hierarchy without maxDepth',
context: {
flatEntityId: 'entity-new',
flatEntityParentId: 'entity-1',
flatEntityUniversalIdentifier: 'entity-new',
flatEntityParentUniversalIdentifier: 'entity-1',
entities: [
createTestEntity('entity-5', null),
createTestEntity('entity-4', 'entity-5'),
@@ -232,13 +226,14 @@ const testCases: ValidateCircularDependencyTestCase[] = [
describe('validateFlatEntityCircularDependency', () => {
test.each(testCases)('$title', ({ context }) => {
const flatEntityMaps = createFlatEntityMaps(context.entities);
const flatEntityMaps = createUniversalFlatEntityMaps(context.entities);
const result = validateFlatEntityCircularDependency({
flatEntityId: context.flatEntityId,
flatEntityParentId: context.flatEntityParentId,
flatEntityUniversalIdentifier: context.flatEntityUniversalIdentifier,
flatEntityParentUniversalIdentifier:
context.flatEntityParentUniversalIdentifier,
maxDepth: context.maxDepth,
parentIdKey: 'parentId',
parentUniversalIdentifierKey: 'parentUniversalIdentifier',
flatEntityMaps,
});
@@ -0,0 +1,39 @@
import { isDefined } from 'twenty-shared/utils';
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 UniversalSyncableFlatEntity } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type';
import { type UniversalFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-maps.type';
type AddUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrowArgs<
T extends SyncableFlatEntity | UniversalSyncableFlatEntity,
> = {
universalFlatEntity: T;
universalFlatEntityMapsToMutate: UniversalFlatEntityMaps<T>;
};
export const addUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrow =
<T extends SyncableFlatEntity | UniversalSyncableFlatEntity>({
universalFlatEntity: flatEntity,
universalFlatEntityMapsToMutate,
}: AddUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrowArgs<T>): void => {
if (
isDefined(
universalFlatEntityMapsToMutate.byUniversalIdentifier[
flatEntity.universalIdentifier
],
)
) {
throw new FlatEntityMapsException(
'addUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrow: flat entity to add already exists',
FlatEntityMapsExceptionCode.ENTITY_ALREADY_EXISTS,
);
}
universalFlatEntityMapsToMutate.byUniversalIdentifier[
flatEntity.universalIdentifier
] = flatEntity;
};
@@ -0,0 +1,66 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type FlatEntityToCreateDeleteUpdate } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-to-create-delete-update.type';
import { getSubUniversalFlatEntityByUniversalIdentifiersMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/get-sub-universal-flat-entity-by-universal-identifiers-maps-or-throw.util';
import { type MetadataUniversalFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/metadata-universal-flat-entity-maps.type';
import { addUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/add-universal-flat-entity-to-universal-flat-entity-maps-through-mutation-or-throw.util';
import { deleteUniversalFlatEntityFromUniversalFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/delete-universal-flat-entity-from-universal-flat-entity-maps-through-mutation-or-throw.util';
import { replaceUniversalFlatEntityInUniversalFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/replace-universal-flat-entity-in-universal-flat-entity-maps-through-mutation-or-throw.util';
export type ComputeUniversalFlatEntityMapsFromToArgs<
T extends AllMetadataName,
> = {
flatEntityMaps: MetadataUniversalFlatEntityMaps<T>;
} & FlatEntityToCreateDeleteUpdate<T>;
export const computeUniversalFlatEntityMapsFromTo = <
T extends AllMetadataName,
>({
flatEntityMaps,
flatEntityToCreate,
flatEntityToDelete,
flatEntityToUpdate,
}: ComputeUniversalFlatEntityMapsFromToArgs<T>): {
from: MetadataUniversalFlatEntityMaps<T>;
to: MetadataUniversalFlatEntityMaps<T>;
} => {
const fromFlatEntityMaps =
flatEntityToDelete.length > 0
? getSubUniversalFlatEntityByUniversalIdentifiersMapsOrThrow({
universalIdentifiers: [
...flatEntityToDelete,
...flatEntityToUpdate,
].map(({ universalIdentifier }) => universalIdentifier),
universalFlatEntityMaps: flatEntityMaps,
})
: flatEntityMaps;
const toFlatEntityMaps: MetadataUniversalFlatEntityMaps<T> =
structuredClone(fromFlatEntityMaps);
for (const flatEntity of flatEntityToDelete) {
deleteUniversalFlatEntityFromUniversalFlatEntityMapsThroughMutationOrThrow({
universalIdentifierToDelete: flatEntity.universalIdentifier,
universalFlatEntityMapsToMutate: toFlatEntityMaps,
});
}
for (const flatEntity of flatEntityToUpdate) {
replaceUniversalFlatEntityInUniversalFlatEntityMapsThroughMutationOrThrow({
universalFlatEntity: flatEntity,
universalFlatEntityMapsToMutate: toFlatEntityMaps,
});
}
for (const flatEntity of flatEntityToCreate) {
addUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrow({
universalFlatEntity: flatEntity,
universalFlatEntityMapsToMutate: toFlatEntityMaps,
});
}
return {
from: fromFlatEntityMaps,
to: toFlatEntityMaps,
};
};
@@ -1,117 +0,0 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type FromTo } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { ALL_FLAT_ENTITY_PROPERTIES_TO_COMPARE_AND_STRINGIFY } from 'src/engine/metadata-modules/flat-entity/constant/all-flat-entity-properties-to-compare-and-stringify.constant';
import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
import { type FlatEntityPropertiesToCompare } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-to-compare.type';
import { type FlatEntityPropertiesToStringify } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-to-stringify.type';
import { type FlatEntityUpdate } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
import { type MetadataFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity-maps.type';
import { type MetadataFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity.type';
import { compareTwoFlatEntity } from 'src/engine/metadata-modules/flat-entity/utils/compare-two-flat-entity.util';
import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
import { shouldInferDeletionFromMissingEntities } from 'src/engine/workspace-manager/workspace-migration/utils/should-infer-deletion-from-missing-entities.util';
import { type WorkspaceMigrationBuilderOptions } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/workspace-migration-builder-options.type';
export type DeletedCreatedUpdatedMatrix<T extends AllMetadataName> = {
createdFlatEntityMaps: MetadataFlatEntityMaps<T>;
deletedFlatEntityMaps: MetadataFlatEntityMaps<T>;
updatedFlatEntityMaps: {
byUniversalIdentifier: Record<
string,
{
update: FlatEntityUpdate<T>;
// TMP remove when maps is universal based
id: string;
}
>;
};
};
export type UniversalIdentifierItem = {
universalIdentifier: string;
};
type FlatEntityDeletedCreatedUpdatedMatrixDispatcherArgs<
T extends AllMetadataName,
> = FromTo<MetadataFlatEntity<T>[]> & {
metadataName: T;
buildOptions: WorkspaceMigrationBuilderOptions;
};
export const flatEntityDeletedCreatedUpdatedMatrixDispatcher = <
T extends AllMetadataName,
>({
from,
to,
metadataName,
buildOptions,
}: FlatEntityDeletedCreatedUpdatedMatrixDispatcherArgs<T>): DeletedCreatedUpdatedMatrix<T> => {
const initialDispatcher: DeletedCreatedUpdatedMatrix<T> = {
createdFlatEntityMaps: createEmptyFlatEntityMaps(),
deletedFlatEntityMaps: createEmptyFlatEntityMaps(),
updatedFlatEntityMaps: { byUniversalIdentifier: {} },
};
const fromMap = new Map(from.map((obj) => [obj.universalIdentifier, obj]));
const toMap = new Map(to.map((obj) => [obj.universalIdentifier, obj]));
if (shouldInferDeletionFromMissingEntities({ buildOptions, metadataName })) {
for (const [universalIdentifier, fromEntity] of fromMap) {
if (toMap.has(universalIdentifier)) {
continue;
}
addFlatEntityToFlatEntityMapsThroughMutationOrThrow({
flatEntity: fromEntity,
flatEntityMapsToMutate: initialDispatcher.deletedFlatEntityMaps,
});
}
}
for (const [universalIdentifier, toFlatEntity] of toMap) {
if (fromMap.has(universalIdentifier)) {
continue;
}
addFlatEntityToFlatEntityMapsThroughMutationOrThrow({
flatEntity: toFlatEntity,
flatEntityMapsToMutate: initialDispatcher.createdFlatEntityMaps,
});
}
const { propertiesToCompare, propertiesToStringify } =
ALL_FLAT_ENTITY_PROPERTIES_TO_COMPARE_AND_STRINGIFY[metadataName];
for (const [universalIdentifier, fromFlatEntity] of fromMap) {
const toFlatEntity = toMap.get(universalIdentifier);
if (!isDefined(toFlatEntity)) {
continue;
}
const update = compareTwoFlatEntity({
fromFlatEntity,
toFlatEntity,
propertiesToCompare: propertiesToCompare as unknown as Extract<
FlatEntityPropertiesToCompare<T>,
keyof MetadataFlatEntity<T>
>[],
propertiesToStringify: propertiesToStringify as unknown as Extract<
FlatEntityPropertiesToStringify<T>,
keyof MetadataFlatEntity<T>
>[],
});
if (!isDefined(update)) {
continue;
}
initialDispatcher.updatedFlatEntityMaps.byUniversalIdentifier[
fromFlatEntity.universalIdentifier
] = {
id: toFlatEntity.id,
update,
};
}
return initialDispatcher;
};
@@ -1,8 +1,9 @@
import { isDefined } from 'twenty-shared/utils';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
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 { findFlatEntityByUniversalIdentifier } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util';
import { type UniversalSyncableFlatEntity } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type';
import { type UniversalFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-maps.type';
export type CircularDependencyValidationSuccess = {
status: 'success';
@@ -20,23 +21,23 @@ export type CircularDependencyValidationResult =
| CircularDependencyValidationFailure;
export const validateFlatEntityCircularDependency = <
T extends SyncableFlatEntity,
T extends SyncableFlatEntity | UniversalSyncableFlatEntity,
K extends keyof T,
>({
flatEntityId,
flatEntityParentId,
flatEntityUniversalIdentifier,
flatEntityParentUniversalIdentifier,
maxDepth,
parentIdKey,
parentUniversalIdentifierKey,
flatEntityMaps,
}: {
flatEntityId: string;
flatEntityParentId: string;
flatEntityUniversalIdentifier: string;
flatEntityParentUniversalIdentifier: string;
maxDepth?: number;
parentIdKey: K;
flatEntityMaps: FlatEntityMaps<T>;
parentUniversalIdentifierKey: K;
flatEntityMaps: UniversalFlatEntityMaps<T>;
}): CircularDependencyValidationResult => {
// Direct self-reference check
if (flatEntityId === flatEntityParentId) {
if (flatEntityUniversalIdentifier === flatEntityParentUniversalIdentifier) {
return {
status: 'fail',
reason: 'self_reference',
@@ -45,10 +46,11 @@ export const validateFlatEntityCircularDependency = <
// Traverse ancestor chain to detect cycles and measure depth
const visited = new Set<string>();
let currentParentId: string | null | undefined = flatEntityParentId;
let currentParentUniversalIdentifier: string | null | undefined =
flatEntityParentUniversalIdentifier;
let depth = 1;
while (isDefined(currentParentId)) {
while (isDefined(currentParentUniversalIdentifier)) {
if (isDefined(maxDepth) && depth > maxDepth) {
return {
status: 'fail',
@@ -58,7 +60,7 @@ export const validateFlatEntityCircularDependency = <
}
// Check for circular dependency
if (currentParentId === flatEntityId) {
if (currentParentUniversalIdentifier === flatEntityUniversalIdentifier) {
return {
status: 'fail',
reason: 'circular_dependency',
@@ -67,7 +69,7 @@ export const validateFlatEntityCircularDependency = <
}
// Check for cycle in ancestors (already visited node)
if (visited.has(currentParentId)) {
if (visited.has(currentParentUniversalIdentifier)) {
return {
status: 'fail',
reason: 'circular_dependency',
@@ -75,10 +77,10 @@ export const validateFlatEntityCircularDependency = <
};
}
visited.add(currentParentId);
visited.add(currentParentUniversalIdentifier);
const parentEntity: T | undefined = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: currentParentId,
const parentEntity: T | undefined = findFlatEntityByUniversalIdentifier({
universalIdentifier: currentParentUniversalIdentifier,
flatEntityMaps,
});
@@ -86,11 +88,13 @@ export const validateFlatEntityCircularDependency = <
break;
}
const nextParentId: T[K] = parentEntity[parentIdKey];
const nextParentUniversalIdentifier: T[K] =
parentEntity[parentUniversalIdentifierKey];
currentParentId =
isDefined(nextParentId) && typeof nextParentId === 'string'
? nextParentId
currentParentUniversalIdentifier =
isDefined(nextParentUniversalIdentifier) &&
typeof nextParentUniversalIdentifier === 'string'
? nextParentUniversalIdentifier
: undefined;
depth++;
}
@@ -2,6 +2,7 @@ import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspac
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
import { type BaseUniversalUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-update-workspace-migration-action.type';
export type FlatCreateAgentAction =
BaseFlatCreateWorkspaceMigrationAction<'agent'>;
@@ -9,6 +10,9 @@ export type FlatCreateAgentAction =
export type FlatUpdateAgentAction =
BaseFlatUpdateWorkspaceMigrationAction<'agent'>;
export type UniversalUpdateAgentAction =
BaseUniversalUpdateWorkspaceMigrationAction<'agent'>;
export type UniversalDeleteAgentAction =
BaseUniversalDeleteWorkspaceMigrationAction<'agent'>;
@@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { FlatUpdateAgentAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/agent/types/workspace-migration-agent-action-builder.service';
import { UniversalUpdateAgentAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/agent/types/workspace-migration-agent-action-builder.service';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-update-validation-args.type';
import { UniversalFlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-args.type';
import { UniversalFlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-result.type';
import { FlatAgentValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-agent-validator.service';
@Injectable()
@@ -20,8 +20,11 @@ export class WorkspaceMigrationAgentActionsBuilderService extends WorkspaceEntit
}
protected validateFlatEntityCreation(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.agent>,
): FlatEntityValidationReturnType<typeof ALL_METADATA_NAME.agent, 'create'> {
args: UniversalFlatEntityValidationArgs<typeof ALL_METADATA_NAME.agent>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.agent,
'create'
> {
const validationResult =
this.flatAgentValidatorService.validateFlatAgentCreation(args);
@@ -45,8 +48,11 @@ export class WorkspaceMigrationAgentActionsBuilderService extends WorkspaceEntit
}
protected validateFlatEntityDeletion(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.agent>,
): FlatEntityValidationReturnType<typeof ALL_METADATA_NAME.agent, 'delete'> {
args: UniversalFlatEntityValidationArgs<typeof ALL_METADATA_NAME.agent>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.agent,
'delete'
> {
const validationResult =
this.flatAgentValidatorService.validateFlatAgentDeletion(args);
@@ -71,7 +77,10 @@ export class WorkspaceMigrationAgentActionsBuilderService extends WorkspaceEntit
protected validateFlatEntityUpdate(
args: FlatEntityUpdateValidationArgs<typeof ALL_METADATA_NAME.agent>,
): FlatEntityValidationReturnType<typeof ALL_METADATA_NAME.agent, 'update'> {
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.agent,
'update'
> {
const validationResult =
this.flatAgentValidatorService.validateFlatAgentUpdate(args);
@@ -82,12 +91,12 @@ export class WorkspaceMigrationAgentActionsBuilderService extends WorkspaceEntit
};
}
const { flatEntityId, flatEntityUpdate } = args;
const { universalIdentifier, flatEntityUpdate } = args;
const updateAgentAction: FlatUpdateAgentAction = {
const updateAgentAction: UniversalUpdateAgentAction = {
type: 'update',
metadataName: 'agent',
entityId: flatEntityId,
universalIdentifier,
update: flatEntityUpdate,
};
@@ -2,6 +2,7 @@ import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspac
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
import { type BaseUniversalUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-update-workspace-migration-action.type';
export type FlatCreateCommandMenuItemAction =
BaseFlatCreateWorkspaceMigrationAction<'commandMenuItem'>;
@@ -9,6 +10,9 @@ export type FlatCreateCommandMenuItemAction =
export type FlatUpdateCommandMenuItemAction =
BaseFlatUpdateWorkspaceMigrationAction<'commandMenuItem'>;
export type UniversalUpdateCommandMenuItemAction =
BaseUniversalUpdateWorkspaceMigrationAction<'commandMenuItem'>;
export type UniversalDeleteCommandMenuItemAction =
BaseUniversalDeleteWorkspaceMigrationAction<'commandMenuItem'>;
@@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { FlatUpdateCommandMenuItemAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/command-menu-item/types/workspace-migration-command-menu-item-action.type';
import { UniversalUpdateCommandMenuItemAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/command-menu-item/types/workspace-migration-command-menu-item-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-update-validation-args.type';
import { UniversalFlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-args.type';
import { UniversalFlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-result.type';
import { FlatCommandMenuItemValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-command-menu-item-validator.service';
@Injectable()
@@ -20,8 +20,10 @@ export class WorkspaceMigrationCommandMenuItemActionsBuilderService extends Work
}
protected validateFlatEntityCreation(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.commandMenuItem>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.commandMenuItem
>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.commandMenuItem,
'create'
> {
@@ -50,8 +52,10 @@ export class WorkspaceMigrationCommandMenuItemActionsBuilderService extends Work
}
protected validateFlatEntityDeletion(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.commandMenuItem>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.commandMenuItem
>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.commandMenuItem,
'delete'
> {
@@ -83,7 +87,7 @@ export class WorkspaceMigrationCommandMenuItemActionsBuilderService extends Work
args: FlatEntityUpdateValidationArgs<
typeof ALL_METADATA_NAME.commandMenuItem
>,
): FlatEntityValidationReturnType<
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.commandMenuItem,
'update'
> {
@@ -99,12 +103,12 @@ export class WorkspaceMigrationCommandMenuItemActionsBuilderService extends Work
};
}
const { flatEntityId, flatEntityUpdate } = args;
const { universalIdentifier, flatEntityUpdate } = args;
const updateCommandMenuItemAction: FlatUpdateCommandMenuItemAction = {
const updateCommandMenuItemAction: UniversalUpdateCommandMenuItemAction = {
type: 'update',
metadataName: 'commandMenuItem',
entityId: flatEntityId,
universalIdentifier,
update: flatEntityUpdate,
};
@@ -4,9 +4,9 @@ import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { UniversalUpdateFieldAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/types/workspace-migration-field-action';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-update-validation-args.type';
import { UniversalFlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-args.type';
import { UniversalFlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-result.type';
import { FlatFieldMetadataValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-field-metadata-validator.service';
@Injectable()
@@ -20,8 +20,10 @@ export class WorkspaceMigrationFieldActionsBuilderService extends WorkspaceEntit
}
protected validateFlatEntityCreation(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.fieldMetadata>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.fieldMetadata
>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.fieldMetadata,
'create'
> {
@@ -37,27 +39,21 @@ export class WorkspaceMigrationFieldActionsBuilderService extends WorkspaceEntit
const { flatEntityToValidate: flatFieldMetadataToValidate } = args;
const fieldIdByUniversalIdentifier = flatFieldMetadataToValidate.id
? {
[flatFieldMetadataToValidate.universalIdentifier]:
flatFieldMetadataToValidate.id,
}
: undefined;
return {
status: 'success',
action: {
type: 'create',
metadataName: 'fieldMetadata',
universalFlatFieldMetadatas: [flatFieldMetadataToValidate],
fieldIdByUniversalIdentifier,
},
};
}
protected validateFlatEntityDeletion(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.fieldMetadata>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.fieldMetadata
>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.fieldMetadata,
'delete'
> {
@@ -87,7 +83,7 @@ export class WorkspaceMigrationFieldActionsBuilderService extends WorkspaceEntit
args: FlatEntityUpdateValidationArgs<
typeof ALL_METADATA_NAME.fieldMetadata
>,
): FlatEntityValidationReturnType<
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.fieldMetadata,
'update'
> {
@@ -2,6 +2,7 @@ import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspac
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
import { type BaseUniversalUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-update-workspace-migration-action.type';
export type FlatCreateFrontComponentAction =
BaseFlatCreateWorkspaceMigrationAction<'frontComponent'>;
@@ -9,6 +10,9 @@ export type FlatCreateFrontComponentAction =
export type FlatUpdateFrontComponentAction =
BaseFlatUpdateWorkspaceMigrationAction<'frontComponent'>;
export type UniversalUpdateFrontComponentAction =
BaseUniversalUpdateWorkspaceMigrationAction<'frontComponent'>;
export type UniversalDeleteFrontComponentAction =
BaseUniversalDeleteWorkspaceMigrationAction<'frontComponent'>;
@@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { FlatUpdateFrontComponentAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/front-component/types/workspace-migration-front-component-action.type';
import { UniversalUpdateFrontComponentAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/front-component/types/workspace-migration-front-component-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-update-validation-args.type';
import { UniversalFlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-args.type';
import { UniversalFlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-result.type';
import { FlatFrontComponentValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-front-component-validator.service';
@Injectable()
@@ -20,8 +20,10 @@ export class WorkspaceMigrationFrontComponentActionsBuilderService extends Works
}
protected validateFlatEntityCreation(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.frontComponent>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.frontComponent
>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.frontComponent,
'create'
> {
@@ -50,8 +52,10 @@ export class WorkspaceMigrationFrontComponentActionsBuilderService extends Works
}
protected validateFlatEntityDeletion(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.frontComponent>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.frontComponent
>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.frontComponent,
'delete'
> {
@@ -83,7 +87,7 @@ export class WorkspaceMigrationFrontComponentActionsBuilderService extends Works
args: FlatEntityUpdateValidationArgs<
typeof ALL_METADATA_NAME.frontComponent
>,
): FlatEntityValidationReturnType<
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.frontComponent,
'update'
> {
@@ -99,12 +103,12 @@ export class WorkspaceMigrationFrontComponentActionsBuilderService extends Works
};
}
const { flatEntityId, flatEntityUpdate } = args;
const { universalIdentifier, flatEntityUpdate } = args;
const updateFrontComponentAction: FlatUpdateFrontComponentAction = {
const updateFrontComponentAction: UniversalUpdateFrontComponentAction = {
type: 'update',
metadataName: 'frontComponent',
entityId: flatEntityId,
universalIdentifier,
update: flatEntityUpdate,
};
@@ -1,20 +1,31 @@
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
import { type UniversalFlatIndexMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-index-metadata.type';
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-create-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
import { type BaseUniversalUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-update-workspace-migration-action.type';
export type FlatCreateIndexAction =
BaseFlatCreateWorkspaceMigrationAction<'index'>;
export type UniversalCreateIndexAction =
BaseUniversalCreateWorkspaceMigrationAction<'index'>;
export type UniversalUpdateIndexAction =
BaseUniversalUpdateWorkspaceMigrationAction<'index'> & {
updatedUniversalFlatIndex: UniversalFlatIndexMetadata;
};
export type UniversalDeleteIndexAction =
BaseUniversalDeleteWorkspaceMigrationAction<'index'>;
export type FlatCreateIndexAction =
BaseFlatCreateWorkspaceMigrationAction<'index'>;
export type FlatDeleteIndexAction =
BaseFlatDeleteWorkspaceMigrationAction<'index'>;
export type FlatUpdateIndexAction =
BaseFlatUpdateWorkspaceMigrationAction<'index'> & {
// TODO document
updatedFlatEntity: FlatIndexMetadata;
// Note: Literally drop and create under the hood
updatedFlatIndex: FlatIndexMetadata;
};
@@ -6,13 +6,13 @@ import { isDefined } from 'twenty-shared/utils';
import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
import { FlatEntityMapsExceptionCode } from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
import { deleteFlatEntityFromFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/delete-flat-entity-from-flat-entity-maps-through-mutation-or-throw.util';
import { findFlatEntityByUniversalIdentifier } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util';
import { UniversalFlatIndexMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-index-metadata.type';
import { deleteUniversalFlatEntityFromUniversalFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/delete-universal-flat-entity-from-universal-flat-entity-maps-through-mutation-or-throw.util';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-update-validation-args.type';
import { UniversalFlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-args.type';
import { UniversalFlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-result.type';
import { FlatIndexValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-index-metadata-validator.service';
@Injectable()
@@ -26,8 +26,11 @@ export class WorkspaceMigrationIndexActionsBuilderService extends WorkspaceEntit
}
protected validateFlatEntityCreation(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.index>,
): FlatEntityValidationReturnType<typeof ALL_METADATA_NAME.index, 'create'> {
args: UniversalFlatEntityValidationArgs<typeof ALL_METADATA_NAME.index>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.index,
'create'
> {
const validationResult =
this.flatIndexValidatorService.validateFlatIndexCreation(args);
@@ -51,8 +54,11 @@ export class WorkspaceMigrationIndexActionsBuilderService extends WorkspaceEntit
}
protected validateFlatEntityDeletion(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.index>,
): FlatEntityValidationReturnType<typeof ALL_METADATA_NAME.index, 'delete'> {
args: UniversalFlatEntityValidationArgs<typeof ALL_METADATA_NAME.index>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.index,
'delete'
> {
const validationResult =
this.flatIndexValidatorService.validateFlatIndexDeletion(args);
@@ -77,16 +83,19 @@ export class WorkspaceMigrationIndexActionsBuilderService extends WorkspaceEntit
protected validateFlatEntityUpdate({
optimisticFlatEntityMapsAndRelatedFlatEntityMaps,
flatEntityId,
universalIdentifier,
flatEntityUpdate,
buildOptions,
workspaceId,
additionalCacheDataMaps,
}: FlatEntityUpdateValidationArgs<
typeof ALL_METADATA_NAME.index
>): FlatEntityValidationReturnType<typeof ALL_METADATA_NAME.index, 'update'> {
const flatEntity = findFlatEntityByIdInFlatEntityMaps({
flatEntityId,
>): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.index,
'update'
> {
const flatEntity = findFlatEntityByUniversalIdentifier({
universalIdentifier,
flatEntityMaps:
optimisticFlatEntityMapsAndRelatedFlatEntityMaps.flatIndexMaps,
});
@@ -97,7 +106,7 @@ export class WorkspaceMigrationIndexActionsBuilderService extends WorkspaceEntit
metadataName: 'index',
type: 'update',
flatEntityMinimalInformation: {
id: flatEntityId,
universalIdentifier,
},
errors: [
{
@@ -128,7 +137,7 @@ export class WorkspaceMigrationIndexActionsBuilderService extends WorkspaceEntit
};
}
const updatedFlatIndex: FlatIndexMetadata = {
const updatedFlatIndex: UniversalFlatIndexMetadata = {
...flatEntity,
...flatEntityUpdate,
};
@@ -137,9 +146,9 @@ export class WorkspaceMigrationIndexActionsBuilderService extends WorkspaceEntit
optimisticFlatEntityMapsAndRelatedFlatEntityMaps.flatIndexMaps,
);
deleteFlatEntityFromFlatEntityMapsThroughMutationOrThrow({
entityToDeleteId: flatEntity.id,
flatEntityMapsToMutate: tempOptimisticFlatIndexMaps,
deleteUniversalFlatEntityFromUniversalFlatEntityMapsThroughMutationOrThrow({
universalIdentifierToDelete: flatEntity.universalIdentifier,
universalFlatEntityMapsToMutate: tempOptimisticFlatIndexMaps,
});
const creationValidationResult =
@@ -171,10 +180,8 @@ export class WorkspaceMigrationIndexActionsBuilderService extends WorkspaceEntit
action: {
type: 'update',
metadataName: 'index',
entityId: flatEntity.id,
// Note: Index update action ignores the native update field
// As under the hood it result as a drop and create
updatedFlatEntity: updatedFlatIndex,
universalIdentifier,
updatedUniversalFlatIndex: updatedFlatIndex,
update: {},
},
};
@@ -4,6 +4,7 @@ import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspac
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
import { type BaseUniversalUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-update-workspace-migration-action.type';
export type FlatCreateLogicFunctionAction =
BaseFlatCreateWorkspaceMigrationAction<'logicFunction'>;
@@ -13,6 +14,9 @@ export type FlatUpdateLogicFunctionAction =
code?: Sources;
};
export type UniversalUpdateLogicFunctionAction =
BaseUniversalUpdateWorkspaceMigrationAction<'logicFunction'>;
export type UniversalDeleteLogicFunctionAction =
BaseUniversalDeleteWorkspaceMigrationAction<'logicFunction'>;
@@ -2,16 +2,16 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { FlatUpdateLogicFunctionAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/logic-function/types/workspace-migration-logic-function-action.type';
import { findFlatEntityByUniversalIdentifier } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util';
import { UniversalUpdateLogicFunctionAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/logic-function/types/workspace-migration-logic-function-action.type';
import {
ValidateAndBuildArgs,
ValidateAndBuildReturnType,
WorkspaceEntityMigrationBuilderService,
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-update-validation-args.type';
import { UniversalFlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-args.type';
import { UniversalFlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-result.type';
import { FlatLogicFunctionValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-logic-function-validator.service';
@Injectable()
@@ -39,8 +39,8 @@ export class WorkspaceMigrationLogicFunctionActionsBuilderService extends Worksp
return action;
}
const toLogicFunction = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: action.entityId,
const toLogicFunction = findFlatEntityByUniversalIdentifier({
universalIdentifier: action.universalIdentifier,
flatEntityMaps: toFlatEntityMaps,
});
@@ -60,8 +60,10 @@ export class WorkspaceMigrationLogicFunctionActionsBuilderService extends Worksp
}
protected validateFlatEntityCreation(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.logicFunction>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.logicFunction
>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.logicFunction,
'create'
> {
@@ -90,8 +92,10 @@ export class WorkspaceMigrationLogicFunctionActionsBuilderService extends Worksp
}
protected validateFlatEntityDeletion(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.logicFunction>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.logicFunction
>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.logicFunction,
'delete'
> {
@@ -123,7 +127,7 @@ export class WorkspaceMigrationLogicFunctionActionsBuilderService extends Worksp
args: FlatEntityUpdateValidationArgs<
typeof ALL_METADATA_NAME.logicFunction
>,
): FlatEntityValidationReturnType<
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.logicFunction,
'update'
> {
@@ -139,12 +143,12 @@ export class WorkspaceMigrationLogicFunctionActionsBuilderService extends Worksp
};
}
const { flatEntityId, flatEntityUpdate } = args;
const { universalIdentifier, flatEntityUpdate } = args;
const updateLogicFunctionAction: FlatUpdateLogicFunctionAction = {
const updateLogicFunctionAction: UniversalUpdateLogicFunctionAction = {
type: 'update',
metadataName: 'logicFunction',
entityId: flatEntityId,
universalIdentifier,
update: flatEntityUpdate,
};
@@ -2,6 +2,7 @@ import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspac
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
import { type BaseUniversalUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-update-workspace-migration-action.type';
export type FlatCreateNavigationMenuItemAction =
BaseFlatCreateWorkspaceMigrationAction<'navigationMenuItem'>;
@@ -9,6 +10,9 @@ export type FlatCreateNavigationMenuItemAction =
export type FlatUpdateNavigationMenuItemAction =
BaseFlatUpdateWorkspaceMigrationAction<'navigationMenuItem'>;
export type UniversalUpdateNavigationMenuItemAction =
BaseUniversalUpdateWorkspaceMigrationAction<'navigationMenuItem'>;
export type UniversalDeleteNavigationMenuItemAction =
BaseUniversalDeleteWorkspaceMigrationAction<'navigationMenuItem'>;
@@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { FlatUpdateNavigationMenuItemAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/navigation-menu-item/types/workspace-migration-navigation-menu-item-action.type';
import { UniversalUpdateNavigationMenuItemAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/navigation-menu-item/types/workspace-migration-navigation-menu-item-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-update-validation-args.type';
import { UniversalFlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-args.type';
import { UniversalFlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-result.type';
import { FlatNavigationMenuItemValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-navigation-menu-item-validator.service';
@Injectable()
@@ -20,8 +20,10 @@ export class WorkspaceMigrationNavigationMenuItemActionsBuilderService extends W
}
protected validateFlatEntityCreation(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.navigationMenuItem>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.navigationMenuItem
>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.navigationMenuItem,
'create'
> {
@@ -50,8 +52,10 @@ export class WorkspaceMigrationNavigationMenuItemActionsBuilderService extends W
}
protected validateFlatEntityDeletion(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.navigationMenuItem>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.navigationMenuItem
>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.navigationMenuItem,
'delete'
> {
@@ -84,7 +88,7 @@ export class WorkspaceMigrationNavigationMenuItemActionsBuilderService extends W
args: FlatEntityUpdateValidationArgs<
typeof ALL_METADATA_NAME.navigationMenuItem
>,
): FlatEntityValidationReturnType<
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.navigationMenuItem,
'update'
> {
@@ -100,14 +104,15 @@ export class WorkspaceMigrationNavigationMenuItemActionsBuilderService extends W
};
}
const { flatEntityId, flatEntityUpdate } = args;
const { universalIdentifier, flatEntityUpdate } = args;
const updateNavigationMenuItemAction: FlatUpdateNavigationMenuItemAction = {
type: 'update',
metadataName: 'navigationMenuItem',
entityId: flatEntityId,
update: flatEntityUpdate,
};
const updateNavigationMenuItemAction: UniversalUpdateNavigationMenuItemAction =
{
type: 'update',
metadataName: 'navigationMenuItem',
universalIdentifier,
update: flatEntityUpdate,
};
return {
status: 'success',
@@ -4,9 +4,9 @@ import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { UniversalUpdateObjectAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/object/types/workspace-migration-object-action';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-update-validation-args.type';
import { UniversalFlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-args.type';
import { UniversalFlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-result.type';
import { FlatObjectMetadataValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-object-metadata-validator.service';
@Injectable()
@@ -20,8 +20,10 @@ export class WorkspaceMigrationObjectActionsBuilderService extends WorkspaceEnti
}
protected validateFlatEntityCreation(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.objectMetadata>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.objectMetadata
>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.objectMetadata,
'create'
> {
@@ -44,14 +46,15 @@ export class WorkspaceMigrationObjectActionsBuilderService extends WorkspaceEnti
metadataName: 'objectMetadata',
universalFlatFieldMetadatas: [],
flatEntity: flatObjectMetadataToValidate,
id: flatObjectMetadataToValidate.id,
},
};
}
protected validateFlatEntityDeletion(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.objectMetadata>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.objectMetadata
>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.objectMetadata,
'delete'
> {
@@ -81,7 +84,7 @@ export class WorkspaceMigrationObjectActionsBuilderService extends WorkspaceEnti
args: FlatEntityUpdateValidationArgs<
typeof ALL_METADATA_NAME.objectMetadata
>,
): FlatEntityValidationReturnType<
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.objectMetadata,
'update'
> {
@@ -2,6 +2,7 @@ import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspac
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
import { type BaseUniversalUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-update-workspace-migration-action.type';
export type FlatCreatePageLayoutTabAction =
BaseFlatCreateWorkspaceMigrationAction<'pageLayoutTab'>;
@@ -9,6 +10,9 @@ export type FlatCreatePageLayoutTabAction =
export type FlatUpdatePageLayoutTabAction =
BaseFlatUpdateWorkspaceMigrationAction<'pageLayoutTab'>;
export type UniversalUpdatePageLayoutTabAction =
BaseUniversalUpdateWorkspaceMigrationAction<'pageLayoutTab'>;
export type UniversalDeletePageLayoutTabAction =
BaseUniversalDeleteWorkspaceMigrationAction<'pageLayoutTab'>;
@@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { FlatUpdatePageLayoutTabAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/page-layout-tab/types/workspace-migration-page-layout-tab-action.type';
import { UniversalUpdatePageLayoutTabAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/page-layout-tab/types/workspace-migration-page-layout-tab-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-update-validation-args.type';
import { UniversalFlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-args.type';
import { UniversalFlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-result.type';
import { FlatPageLayoutTabValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-page-layout-tab-validator.service';
@Injectable()
@@ -20,8 +20,10 @@ export class WorkspaceMigrationPageLayoutTabActionsBuilderService extends Worksp
}
protected validateFlatEntityCreation(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.pageLayoutTab>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.pageLayoutTab
>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.pageLayoutTab,
'create'
> {
@@ -50,8 +52,10 @@ export class WorkspaceMigrationPageLayoutTabActionsBuilderService extends Worksp
}
protected validateFlatEntityDeletion(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.pageLayoutTab>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.pageLayoutTab
>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.pageLayoutTab,
'delete'
> {
@@ -83,7 +87,7 @@ export class WorkspaceMigrationPageLayoutTabActionsBuilderService extends Worksp
args: FlatEntityUpdateValidationArgs<
typeof ALL_METADATA_NAME.pageLayoutTab
>,
): FlatEntityValidationReturnType<
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.pageLayoutTab,
'update'
> {
@@ -99,12 +103,12 @@ export class WorkspaceMigrationPageLayoutTabActionsBuilderService extends Worksp
};
}
const { flatEntityId, flatEntityUpdate } = args;
const { universalIdentifier, flatEntityUpdate } = args;
const updatePageLayoutTabAction: FlatUpdatePageLayoutTabAction = {
const updatePageLayoutTabAction: UniversalUpdatePageLayoutTabAction = {
type: 'update',
metadataName: 'pageLayoutTab',
entityId: flatEntityId,
universalIdentifier,
update: flatEntityUpdate,
};
@@ -2,6 +2,7 @@ import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspac
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
import { type BaseUniversalUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-update-workspace-migration-action.type';
export type FlatCreatePageLayoutWidgetAction =
BaseFlatCreateWorkspaceMigrationAction<'pageLayoutWidget'>;
@@ -9,6 +10,9 @@ export type FlatCreatePageLayoutWidgetAction =
export type FlatUpdatePageLayoutWidgetAction =
BaseFlatUpdateWorkspaceMigrationAction<'pageLayoutWidget'>;
export type UniversalUpdatePageLayoutWidgetAction =
BaseUniversalUpdateWorkspaceMigrationAction<'pageLayoutWidget'>;
export type UniversalDeletePageLayoutWidgetAction =
BaseUniversalDeleteWorkspaceMigrationAction<'pageLayoutWidget'>;
@@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { FlatUpdatePageLayoutWidgetAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/page-layout-widget/types/workspace-migration-page-layout-widget-action.type';
import { UniversalUpdatePageLayoutWidgetAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/page-layout-widget/types/workspace-migration-page-layout-widget-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-update-validation-args.type';
import { UniversalFlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-args.type';
import { UniversalFlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-result.type';
import { FlatPageLayoutWidgetValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-page-layout-widget-validator.service';
@Injectable()
@@ -20,9 +20,11 @@ export class WorkspaceMigrationPageLayoutWidgetActionsBuilderService extends Wor
}
protected async validateFlatEntityCreation(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.pageLayoutWidget>,
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.pageLayoutWidget
>,
): Promise<
FlatEntityValidationReturnType<
UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.pageLayoutWidget,
'create'
>
@@ -50,8 +52,10 @@ export class WorkspaceMigrationPageLayoutWidgetActionsBuilderService extends Wor
}
protected validateFlatEntityDeletion(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.pageLayoutWidget>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.pageLayoutWidget
>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.pageLayoutWidget,
'delete'
> {
@@ -84,7 +88,7 @@ export class WorkspaceMigrationPageLayoutWidgetActionsBuilderService extends Wor
typeof ALL_METADATA_NAME.pageLayoutWidget
>,
): Promise<
FlatEntityValidationReturnType<
UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.pageLayoutWidget,
'update'
>
@@ -101,14 +105,15 @@ export class WorkspaceMigrationPageLayoutWidgetActionsBuilderService extends Wor
};
}
const { flatEntityId, flatEntityUpdate } = args;
const { universalIdentifier, flatEntityUpdate } = args;
const updatePageLayoutWidgetAction: FlatUpdatePageLayoutWidgetAction = {
type: 'update',
metadataName: 'pageLayoutWidget',
entityId: flatEntityId,
update: flatEntityUpdate,
};
const updatePageLayoutWidgetAction: UniversalUpdatePageLayoutWidgetAction =
{
type: 'update',
metadataName: 'pageLayoutWidget',
universalIdentifier,
update: flatEntityUpdate,
};
return {
status: 'success',
@@ -2,6 +2,7 @@ import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspac
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
import { type BaseUniversalUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-update-workspace-migration-action.type';
export type FlatCreatePageLayoutAction =
BaseFlatCreateWorkspaceMigrationAction<'pageLayout'>;
@@ -9,6 +10,9 @@ export type FlatCreatePageLayoutAction =
export type FlatUpdatePageLayoutAction =
BaseFlatUpdateWorkspaceMigrationAction<'pageLayout'>;
export type UniversalUpdatePageLayoutAction =
BaseUniversalUpdateWorkspaceMigrationAction<'pageLayout'>;
export type UniversalDeletePageLayoutAction =
BaseUniversalDeleteWorkspaceMigrationAction<'pageLayout'>;
@@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { FlatUpdatePageLayoutAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/page-layout/types/workspace-migration-page-layout-action.type';
import { UniversalUpdatePageLayoutAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/page-layout/types/workspace-migration-page-layout-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-update-validation-args.type';
import { UniversalFlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-args.type';
import { UniversalFlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-result.type';
import { FlatPageLayoutValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-page-layout-validator.service';
@Injectable()
@@ -20,9 +20,11 @@ export class WorkspaceMigrationPageLayoutActionsBuilderService extends Workspace
}
protected async validateFlatEntityCreation(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.pageLayout>,
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.pageLayout
>,
): Promise<
FlatEntityValidationReturnType<
UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.pageLayout,
'create'
>
@@ -50,8 +52,10 @@ export class WorkspaceMigrationPageLayoutActionsBuilderService extends Workspace
}
protected validateFlatEntityDeletion(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.pageLayout>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.pageLayout
>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.pageLayout,
'delete'
> {
@@ -80,7 +84,7 @@ export class WorkspaceMigrationPageLayoutActionsBuilderService extends Workspace
protected async validateFlatEntityUpdate(
args: FlatEntityUpdateValidationArgs<typeof ALL_METADATA_NAME.pageLayout>,
): Promise<
FlatEntityValidationReturnType<
UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.pageLayout,
'update'
>
@@ -95,12 +99,12 @@ export class WorkspaceMigrationPageLayoutActionsBuilderService extends Workspace
};
}
const { flatEntityId, flatEntityUpdate } = args;
const { universalIdentifier, flatEntityUpdate } = args;
const updatePageLayoutAction: FlatUpdatePageLayoutAction = {
const updatePageLayoutAction: UniversalUpdatePageLayoutAction = {
type: 'update',
metadataName: 'pageLayout',
entityId: flatEntityId,
universalIdentifier,
update: flatEntityUpdate,
};
@@ -2,6 +2,7 @@ import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspac
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
import { type BaseUniversalUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-update-workspace-migration-action.type';
export type FlatCreateRoleTargetAction =
BaseFlatCreateWorkspaceMigrationAction<'roleTarget'>;
@@ -9,6 +10,9 @@ export type FlatCreateRoleTargetAction =
export type FlatUpdateRoleTargetAction =
BaseFlatUpdateWorkspaceMigrationAction<'roleTarget'>;
export type UniversalUpdateRoleTargetAction =
BaseUniversalUpdateWorkspaceMigrationAction<'roleTarget'>;
export type UniversalDeleteRoleTargetAction =
BaseUniversalDeleteWorkspaceMigrationAction<'roleTarget'>;
@@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { FlatUpdateRoleTargetAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/role-target/types/workspace-migration-role-target-action.type';
import { UniversalUpdateRoleTargetAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/role-target/types/workspace-migration-role-target-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-update-validation-args.type';
import { UniversalFlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-args.type';
import { UniversalFlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-result.type';
import { FlatRoleTargetValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-role-target-validator.service';
@Injectable()
@@ -20,8 +20,10 @@ export class WorkspaceMigrationRoleTargetActionsBuilderService extends Workspace
}
protected validateFlatEntityCreation(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.roleTarget>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.roleTarget
>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.roleTarget,
'create'
> {
@@ -48,8 +50,10 @@ export class WorkspaceMigrationRoleTargetActionsBuilderService extends Workspace
}
protected validateFlatEntityDeletion(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.roleTarget>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.roleTarget
>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.roleTarget,
'delete'
> {
@@ -77,7 +81,7 @@ export class WorkspaceMigrationRoleTargetActionsBuilderService extends Workspace
protected validateFlatEntityUpdate(
args: FlatEntityUpdateValidationArgs<typeof ALL_METADATA_NAME.roleTarget>,
): FlatEntityValidationReturnType<
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.roleTarget,
'update'
> {
@@ -91,12 +95,12 @@ export class WorkspaceMigrationRoleTargetActionsBuilderService extends Workspace
};
}
const { flatEntityId, flatEntityUpdate } = args;
const { universalIdentifier, flatEntityUpdate } = args;
const updateRoleTargetAction: FlatUpdateRoleTargetAction = {
const updateRoleTargetAction: UniversalUpdateRoleTargetAction = {
type: 'update',
metadataName: 'roleTarget',
entityId: flatEntityId,
universalIdentifier,
update: flatEntityUpdate,
};
@@ -2,6 +2,7 @@ import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspac
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
import { type BaseUniversalUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-update-workspace-migration-action.type';
export type FlatCreateRoleAction =
BaseFlatCreateWorkspaceMigrationAction<'role'>;
@@ -9,6 +10,9 @@ export type FlatCreateRoleAction =
export type FlatUpdateRoleAction =
BaseFlatUpdateWorkspaceMigrationAction<'role'>;
export type UniversalUpdateRoleAction =
BaseUniversalUpdateWorkspaceMigrationAction<'role'>;
export type UniversalDeleteRoleAction =
BaseUniversalDeleteWorkspaceMigrationAction<'role'>;
@@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { FlatUpdateRoleAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/role/types/workspace-migration-role-action.type';
import { UniversalUpdateRoleAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/role/types/workspace-migration-role-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-update-validation-args.type';
import { UniversalFlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-args.type';
import { UniversalFlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-result.type';
import { FlatRoleValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-role-validator.service';
@Injectable()
@@ -20,8 +20,11 @@ export class WorkspaceMigrationRoleActionsBuilderService extends WorkspaceEntity
}
protected validateFlatEntityCreation(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.role>,
): FlatEntityValidationReturnType<typeof ALL_METADATA_NAME.role, 'create'> {
args: UniversalFlatEntityValidationArgs<typeof ALL_METADATA_NAME.role>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.role,
'create'
> {
const validationResult =
this.flatRoleValidatorService.validateFlatRoleCreation(args);
@@ -45,8 +48,11 @@ export class WorkspaceMigrationRoleActionsBuilderService extends WorkspaceEntity
}
protected validateFlatEntityDeletion(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.role>,
): FlatEntityValidationReturnType<typeof ALL_METADATA_NAME.role, 'delete'> {
args: UniversalFlatEntityValidationArgs<typeof ALL_METADATA_NAME.role>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.role,
'delete'
> {
const validationResult =
this.flatRoleValidatorService.validateFlatRoleDeletion(args);
@@ -71,7 +77,10 @@ export class WorkspaceMigrationRoleActionsBuilderService extends WorkspaceEntity
protected validateFlatEntityUpdate(
args: FlatEntityUpdateValidationArgs<typeof ALL_METADATA_NAME.role>,
): FlatEntityValidationReturnType<typeof ALL_METADATA_NAME.role, 'update'> {
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.role,
'update'
> {
const validationResult =
this.flatRoleValidatorService.validateFlatRoleUpdate(args);
@@ -82,12 +91,12 @@ export class WorkspaceMigrationRoleActionsBuilderService extends WorkspaceEntity
};
}
const { flatEntityId, flatEntityUpdate } = args;
const { universalIdentifier, flatEntityUpdate } = args;
const updateRoleAction: FlatUpdateRoleAction = {
const updateRoleAction: UniversalUpdateRoleAction = {
type: 'update',
metadataName: 'role',
entityId: flatEntityId,
universalIdentifier,
update: flatEntityUpdate,
};
@@ -4,6 +4,7 @@ import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspac
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
import { type BaseUniversalUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-update-workspace-migration-action.type';
export type FlatCreateRowLevelPermissionPredicateGroupAction =
BaseFlatCreateWorkspaceMigrationAction<'rowLevelPermissionPredicateGroup'>;
@@ -11,6 +12,9 @@ export type FlatCreateRowLevelPermissionPredicateGroupAction =
export type FlatUpdateRowLevelPermissionPredicateGroupAction =
BaseFlatUpdateWorkspaceMigrationAction<'rowLevelPermissionPredicateGroup'>;
export type UniversalUpdateRowLevelPermissionPredicateGroupAction =
BaseUniversalUpdateWorkspaceMigrationAction<'rowLevelPermissionPredicateGroup'>;
export type UniversalDeleteRowLevelPermissionPredicateGroupAction =
BaseUniversalDeleteWorkspaceMigrationAction<'rowLevelPermissionPredicateGroup'>;
@@ -4,11 +4,11 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { FlatUpdateRowLevelPermissionPredicateGroupAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/row-level-permission-predicate-group/types/workspace-migration-row-level-permission-predicate-group-action.type';
import { UniversalUpdateRowLevelPermissionPredicateGroupAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/row-level-permission-predicate-group/types/workspace-migration-row-level-permission-predicate-group-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-update-validation-args.type';
import { UniversalFlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-args.type';
import { UniversalFlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-result.type';
import { FlatRowLevelPermissionPredicateGroupValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-row-level-permission-predicate-group-validator.service';
@Injectable()
@@ -22,10 +22,10 @@ export class WorkspaceMigrationRowLevelPermissionPredicateGroupActionsBuilderSer
}
protected validateFlatEntityCreation(
args: FlatEntityValidationArgs<
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.rowLevelPermissionPredicateGroup
>,
): FlatEntityValidationReturnType<
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.rowLevelPermissionPredicateGroup,
'create'
> {
@@ -54,10 +54,10 @@ export class WorkspaceMigrationRowLevelPermissionPredicateGroupActionsBuilderSer
}
protected validateFlatEntityDeletion(
args: FlatEntityValidationArgs<
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.rowLevelPermissionPredicateGroup
>,
): FlatEntityValidationReturnType<
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.rowLevelPermissionPredicateGroup,
'delete'
> {
@@ -93,7 +93,7 @@ export class WorkspaceMigrationRowLevelPermissionPredicateGroupActionsBuilderSer
args: FlatEntityUpdateValidationArgs<
typeof ALL_METADATA_NAME.rowLevelPermissionPredicateGroup
>,
): FlatEntityValidationReturnType<
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.rowLevelPermissionPredicateGroup,
'update'
> {
@@ -109,14 +109,15 @@ export class WorkspaceMigrationRowLevelPermissionPredicateGroupActionsBuilderSer
};
}
const { flatEntityId, flatEntityUpdate } = args;
const { universalIdentifier, flatEntityUpdate } = args;
const updateAction: FlatUpdateRowLevelPermissionPredicateGroupAction = {
type: 'update',
metadataName: 'rowLevelPermissionPredicateGroup',
entityId: flatEntityId,
update: flatEntityUpdate,
};
const updateAction: UniversalUpdateRowLevelPermissionPredicateGroupAction =
{
type: 'update',
metadataName: 'rowLevelPermissionPredicateGroup',
universalIdentifier,
update: flatEntityUpdate,
};
return {
status: 'success',
@@ -4,6 +4,7 @@ import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspac
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
import { type BaseUniversalUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-update-workspace-migration-action.type';
export type FlatCreateRowLevelPermissionPredicateAction =
BaseFlatCreateWorkspaceMigrationAction<'rowLevelPermissionPredicate'>;
@@ -11,6 +12,9 @@ export type FlatCreateRowLevelPermissionPredicateAction =
export type FlatUpdateRowLevelPermissionPredicateAction =
BaseFlatUpdateWorkspaceMigrationAction<'rowLevelPermissionPredicate'>;
export type UniversalUpdateRowLevelPermissionPredicateAction =
BaseUniversalUpdateWorkspaceMigrationAction<'rowLevelPermissionPredicate'>;
export type UniversalDeleteRowLevelPermissionPredicateAction =
BaseUniversalDeleteWorkspaceMigrationAction<'rowLevelPermissionPredicate'>;
@@ -4,11 +4,11 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { FlatUpdateRowLevelPermissionPredicateAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/row-level-permission-predicate/types/workspace-migration-row-level-permission-predicate-action.type';
import { UniversalUpdateRowLevelPermissionPredicateAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/row-level-permission-predicate/types/workspace-migration-row-level-permission-predicate-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-update-validation-args.type';
import { UniversalFlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-args.type';
import { UniversalFlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-result.type';
import { FlatRowLevelPermissionPredicateValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-row-level-permission-predicate-validator.service';
@Injectable()
@@ -22,10 +22,10 @@ export class WorkspaceMigrationRowLevelPermissionPredicateActionsBuilderService
}
protected validateFlatEntityCreation(
args: FlatEntityValidationArgs<
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.rowLevelPermissionPredicate
>,
): FlatEntityValidationReturnType<
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.rowLevelPermissionPredicate,
'create'
> {
@@ -54,10 +54,10 @@ export class WorkspaceMigrationRowLevelPermissionPredicateActionsBuilderService
}
protected validateFlatEntityDeletion(
args: FlatEntityValidationArgs<
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.rowLevelPermissionPredicate
>,
): FlatEntityValidationReturnType<
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.rowLevelPermissionPredicate,
'delete'
> {
@@ -93,7 +93,7 @@ export class WorkspaceMigrationRowLevelPermissionPredicateActionsBuilderService
args: FlatEntityUpdateValidationArgs<
typeof ALL_METADATA_NAME.rowLevelPermissionPredicate
>,
): FlatEntityValidationReturnType<
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.rowLevelPermissionPredicate,
'update'
> {
@@ -109,12 +109,12 @@ export class WorkspaceMigrationRowLevelPermissionPredicateActionsBuilderService
};
}
const { flatEntityId, flatEntityUpdate } = args;
const { universalIdentifier, flatEntityUpdate } = args;
const updateAction: FlatUpdateRowLevelPermissionPredicateAction = {
const updateAction: UniversalUpdateRowLevelPermissionPredicateAction = {
type: 'update',
metadataName: 'rowLevelPermissionPredicate',
entityId: flatEntityId,
universalIdentifier,
update: flatEntityUpdate,
};
@@ -1,7 +1,9 @@
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-create-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
import { type BaseUniversalUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-update-workspace-migration-action.type';
export type FlatCreateSkillAction =
BaseFlatCreateWorkspaceMigrationAction<'skill'>;
@@ -9,8 +11,14 @@ export type FlatCreateSkillAction =
export type FlatUpdateSkillAction =
BaseFlatUpdateWorkspaceMigrationAction<'skill'>;
export type FlatDeleteSkillAction =
BaseFlatDeleteWorkspaceMigrationAction<'skill'>;
export type UniversalUpdateSkillAction =
BaseUniversalUpdateWorkspaceMigrationAction<'skill'>;
export type UniversalDeleteSkillAction =
BaseUniversalDeleteWorkspaceMigrationAction<'skill'>;
export type FlatDeleteSkillAction =
BaseFlatDeleteWorkspaceMigrationAction<'skill'>;
export type UniversalCreateSkillAction =
BaseUniversalCreateWorkspaceMigrationAction<'skill'>;
@@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { FlatUpdateSkillAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/skill/types/workspace-migration-skill-action.type';
import { UniversalUpdateSkillAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/skill/types/workspace-migration-skill-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-update-validation-args.type';
import { UniversalFlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-args.type';
import { UniversalFlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-result.type';
import { FlatSkillValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-skill-validator.service';
@Injectable()
@@ -20,8 +20,11 @@ export class WorkspaceMigrationSkillActionsBuilderService extends WorkspaceEntit
}
protected validateFlatEntityCreation(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.skill>,
): FlatEntityValidationReturnType<typeof ALL_METADATA_NAME.skill, 'create'> {
args: UniversalFlatEntityValidationArgs<typeof ALL_METADATA_NAME.skill>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.skill,
'create'
> {
const validationResult =
this.flatSkillValidatorService.validateFlatSkillCreation(args);
@@ -45,8 +48,11 @@ export class WorkspaceMigrationSkillActionsBuilderService extends WorkspaceEntit
}
protected validateFlatEntityDeletion(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.skill>,
): FlatEntityValidationReturnType<typeof ALL_METADATA_NAME.skill, 'delete'> {
args: UniversalFlatEntityValidationArgs<typeof ALL_METADATA_NAME.skill>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.skill,
'delete'
> {
const validationResult =
this.flatSkillValidatorService.validateFlatSkillDeletion(args);
@@ -71,7 +77,10 @@ export class WorkspaceMigrationSkillActionsBuilderService extends WorkspaceEntit
protected validateFlatEntityUpdate(
args: FlatEntityUpdateValidationArgs<typeof ALL_METADATA_NAME.skill>,
): FlatEntityValidationReturnType<typeof ALL_METADATA_NAME.skill, 'update'> {
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.skill,
'update'
> {
const validationResult =
this.flatSkillValidatorService.validateFlatSkillUpdate(args);
@@ -82,12 +91,12 @@ export class WorkspaceMigrationSkillActionsBuilderService extends WorkspaceEntit
};
}
const { flatEntityId, flatEntityUpdate } = args;
const { universalIdentifier, flatEntityUpdate } = args;
const updateSkillAction: FlatUpdateSkillAction = {
const updateSkillAction: UniversalUpdateSkillAction = {
type: 'update',
metadataName: 'skill',
entityId: flatEntityId,
universalIdentifier,
update: flatEntityUpdate,
};
@@ -18,6 +18,5 @@ export type FailedFlatEntityValidation<
type: TAcionType;
metadataName: TMetadataName;
errors: FlatEntityValidationError[];
flatEntityMinimalInformation: Pick<MetadataFlatEntity<TMetadataName>, 'id'> &
Partial<Omit<MetadataFlatEntity<TMetadataName>, 'id'>>;
flatEntityMinimalInformation: Partial<MetadataFlatEntity<TMetadataName>>;
};
@@ -1,7 +1,12 @@
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-create-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
import { type BaseUniversalUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-update-workspace-migration-action.type';
export type UniversalCreateViewFieldAction =
BaseUniversalCreateWorkspaceMigrationAction<'viewField'>;
export type FlatCreateViewFieldAction =
BaseFlatCreateWorkspaceMigrationAction<'viewField'>;
@@ -9,6 +14,9 @@ export type FlatCreateViewFieldAction =
export type FlatUpdateViewFieldAction =
BaseFlatUpdateWorkspaceMigrationAction<'viewField'>;
export type UniversalUpdateViewFieldAction =
BaseUniversalUpdateWorkspaceMigrationAction<'viewField'>;
export type UniversalDeleteViewFieldAction =
BaseUniversalDeleteWorkspaceMigrationAction<'viewField'>;
@@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { FlatUpdateViewFieldAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-field/types/workspace-migration-view-field-action.type';
import { UniversalUpdateViewFieldAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-field/types/workspace-migration-view-field-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-update-validation-args.type';
import { UniversalFlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-args.type';
import { UniversalFlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-result.type';
import { FlatViewFieldValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-field-validator.service';
@Injectable()
@@ -20,8 +20,8 @@ export class WorkspaceMigrationViewFieldActionsBuilderService extends WorkspaceE
}
protected validateFlatEntityCreation(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.viewField>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<typeof ALL_METADATA_NAME.viewField>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.viewField,
'create'
> {
@@ -46,8 +46,8 @@ export class WorkspaceMigrationViewFieldActionsBuilderService extends WorkspaceE
}
protected validateFlatEntityDeletion(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.viewField>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<typeof ALL_METADATA_NAME.viewField>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.viewField,
'delete'
> {
@@ -75,7 +75,7 @@ export class WorkspaceMigrationViewFieldActionsBuilderService extends WorkspaceE
protected validateFlatEntityUpdate(
args: FlatEntityUpdateValidationArgs<typeof ALL_METADATA_NAME.viewField>,
): FlatEntityValidationReturnType<
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.viewField,
'update'
> {
@@ -89,12 +89,12 @@ export class WorkspaceMigrationViewFieldActionsBuilderService extends WorkspaceE
};
}
const { flatEntityId, flatEntityUpdate } = args;
const { universalIdentifier, flatEntityUpdate } = args;
const updateViewFieldAction: FlatUpdateViewFieldAction = {
const updateViewFieldAction: UniversalUpdateViewFieldAction = {
type: 'update',
metadataName: 'viewField',
entityId: flatEntityId,
universalIdentifier,
update: flatEntityUpdate,
};
@@ -1,7 +1,12 @@
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-create-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
import { type BaseUniversalUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-update-workspace-migration-action.type';
export type UniversalCreateViewFilterGroupAction =
BaseUniversalCreateWorkspaceMigrationAction<'viewFilterGroup'>;
export type FlatCreateViewFilterGroupAction =
BaseFlatCreateWorkspaceMigrationAction<'viewFilterGroup'>;
@@ -9,6 +14,9 @@ export type FlatCreateViewFilterGroupAction =
export type FlatUpdateViewFilterGroupAction =
BaseFlatUpdateWorkspaceMigrationAction<'viewFilterGroup'>;
export type UniversalUpdateViewFilterGroupAction =
BaseUniversalUpdateWorkspaceMigrationAction<'viewFilterGroup'>;
export type UniversalDeleteViewFilterGroupAction =
BaseUniversalDeleteWorkspaceMigrationAction<'viewFilterGroup'>;
@@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { type FlatUpdateViewFilterGroupAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-filter-group/types/workspace-migration-view-filter-group-action.type';
import { type UniversalUpdateViewFilterGroupAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-filter-group/types/workspace-migration-view-filter-group-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { type FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { type FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
import { type FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type';
import { type FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-update-validation-args.type';
import { type UniversalFlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-args.type';
import { type UniversalFlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-result.type';
import { FlatViewFilterGroupValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-filter-group-validator.service';
@Injectable()
@@ -20,8 +20,10 @@ export class WorkspaceMigrationViewFilterGroupActionsBuilderService extends Work
}
protected validateFlatEntityCreation(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.viewFilterGroup>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.viewFilterGroup
>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.viewFilterGroup,
'create'
> {
@@ -50,8 +52,10 @@ export class WorkspaceMigrationViewFilterGroupActionsBuilderService extends Work
}
protected validateFlatEntityDeletion(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.viewFilterGroup>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.viewFilterGroup
>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.viewFilterGroup,
'delete'
> {
@@ -83,7 +87,7 @@ export class WorkspaceMigrationViewFilterGroupActionsBuilderService extends Work
args: FlatEntityUpdateValidationArgs<
typeof ALL_METADATA_NAME.viewFilterGroup
>,
): FlatEntityValidationReturnType<
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.viewFilterGroup,
'update'
> {
@@ -99,12 +103,12 @@ export class WorkspaceMigrationViewFilterGroupActionsBuilderService extends Work
};
}
const { flatEntityId, flatEntityUpdate } = args;
const { universalIdentifier, flatEntityUpdate } = args;
const updateViewFilterGroupAction: FlatUpdateViewFilterGroupAction = {
const updateViewFilterGroupAction: UniversalUpdateViewFilterGroupAction = {
type: 'update',
metadataName: 'viewFilterGroup',
entityId: flatEntityId,
universalIdentifier,
update: flatEntityUpdate,
};
@@ -1,7 +1,12 @@
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-create-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
import { type BaseUniversalUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-update-workspace-migration-action.type';
export type UniversalCreateViewFilterAction =
BaseUniversalCreateWorkspaceMigrationAction<'viewFilter'>;
export type FlatCreateViewFilterAction =
BaseFlatCreateWorkspaceMigrationAction<'viewFilter'>;
@@ -9,6 +14,9 @@ export type FlatCreateViewFilterAction =
export type FlatUpdateViewFilterAction =
BaseFlatUpdateWorkspaceMigrationAction<'viewFilter'>;
export type UniversalUpdateViewFilterAction =
BaseUniversalUpdateWorkspaceMigrationAction<'viewFilter'>;
export type UniversalDeleteViewFilterAction =
BaseUniversalDeleteWorkspaceMigrationAction<'viewFilter'>;
@@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { FlatUpdateViewFilterAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-filter/types/workspace-migration-view-filter-action.type';
import { UniversalUpdateViewFilterAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-filter/types/workspace-migration-view-filter-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-update-validation-args.type';
import { UniversalFlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-args.type';
import { UniversalFlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-result.type';
import { FlatViewFilterValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-filter-validator.service';
@Injectable()
@@ -20,8 +20,10 @@ export class WorkspaceMigrationViewFilterActionsBuilderService extends Workspace
}
protected validateFlatEntityCreation(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.viewFilter>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.viewFilter
>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.viewFilter,
'create'
> {
@@ -48,8 +50,10 @@ export class WorkspaceMigrationViewFilterActionsBuilderService extends Workspace
}
protected validateFlatEntityDeletion(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.viewFilter>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.viewFilter
>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.viewFilter,
'delete'
> {
@@ -77,7 +81,7 @@ export class WorkspaceMigrationViewFilterActionsBuilderService extends Workspace
protected validateFlatEntityUpdate(
args: FlatEntityUpdateValidationArgs<typeof ALL_METADATA_NAME.viewFilter>,
): FlatEntityValidationReturnType<
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.viewFilter,
'update'
> {
@@ -91,12 +95,12 @@ export class WorkspaceMigrationViewFilterActionsBuilderService extends Workspace
};
}
const { flatEntityId, flatEntityUpdate } = args;
const { universalIdentifier, flatEntityUpdate } = args;
const updateViewFilterAction: FlatUpdateViewFilterAction = {
const updateViewFilterAction: UniversalUpdateViewFilterAction = {
type: 'update',
metadataName: 'viewFilter',
entityId: flatEntityId,
universalIdentifier,
update: flatEntityUpdate,
};
@@ -1,7 +1,12 @@
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-create-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
import { type BaseUniversalUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-update-workspace-migration-action.type';
export type UniversalCreateViewGroupAction =
BaseUniversalCreateWorkspaceMigrationAction<'viewGroup'>;
export type FlatCreateViewGroupAction =
BaseFlatCreateWorkspaceMigrationAction<'viewGroup'>;
@@ -9,6 +14,9 @@ export type FlatCreateViewGroupAction =
export type FlatUpdateViewGroupAction =
BaseFlatUpdateWorkspaceMigrationAction<'viewGroup'>;
export type UniversalUpdateViewGroupAction =
BaseUniversalUpdateWorkspaceMigrationAction<'viewGroup'>;
export type UniversalDeleteViewGroupAction =
BaseUniversalDeleteWorkspaceMigrationAction<'viewGroup'>;
@@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { FlatUpdateViewGroupAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-group/types/workspace-migration-view-group-action.type';
import { UniversalUpdateViewGroupAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-group/types/workspace-migration-view-group-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-update-validation-args.type';
import { UniversalFlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-args.type';
import { UniversalFlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-result.type';
import { FlatViewGroupValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-group-validator.service';
@Injectable()
@@ -20,8 +20,8 @@ export class WorkspaceMigrationViewGroupActionsBuilderService extends WorkspaceE
}
protected validateFlatEntityCreation(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.viewGroup>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<typeof ALL_METADATA_NAME.viewGroup>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.viewGroup,
'create'
> {
@@ -48,8 +48,8 @@ export class WorkspaceMigrationViewGroupActionsBuilderService extends WorkspaceE
}
protected validateFlatEntityDeletion(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.viewGroup>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<typeof ALL_METADATA_NAME.viewGroup>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.viewGroup,
'delete'
> {
@@ -77,7 +77,7 @@ export class WorkspaceMigrationViewGroupActionsBuilderService extends WorkspaceE
protected validateFlatEntityUpdate(
args: FlatEntityUpdateValidationArgs<typeof ALL_METADATA_NAME.viewGroup>,
): FlatEntityValidationReturnType<
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.viewGroup,
'update'
> {
@@ -91,12 +91,12 @@ export class WorkspaceMigrationViewGroupActionsBuilderService extends WorkspaceE
};
}
const { flatEntityId, flatEntityUpdate } = args;
const { universalIdentifier, flatEntityUpdate } = args;
const updateViewGroupAction: FlatUpdateViewGroupAction = {
const updateViewGroupAction: UniversalUpdateViewGroupAction = {
type: 'update',
metadataName: 'viewGroup',
entityId: flatEntityId,
universalIdentifier,
update: flatEntityUpdate,
};
@@ -1,7 +1,12 @@
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-create-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
import { type BaseUniversalUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-update-workspace-migration-action.type';
export type UniversalCreateViewAction =
BaseUniversalCreateWorkspaceMigrationAction<'view'>;
export type FlatCreateViewAction =
BaseFlatCreateWorkspaceMigrationAction<'view'>;
@@ -9,6 +14,9 @@ export type FlatCreateViewAction =
export type FlatUpdateViewAction =
BaseFlatUpdateWorkspaceMigrationAction<'view'>;
export type UniversalUpdateViewAction =
BaseUniversalUpdateWorkspaceMigrationAction<'view'>;
export type UniversalDeleteViewAction =
BaseUniversalDeleteWorkspaceMigrationAction<'view'>;
@@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { FlatUpdateViewAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view/types/workspace-migration-view-action.type';
import { UniversalUpdateViewAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view/types/workspace-migration-view-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-update-validation-args.type';
import { UniversalFlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-args.type';
import { UniversalFlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-result.type';
import { FlatViewValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-validator.service';
@Injectable()
@@ -20,8 +20,11 @@ export class WorkspaceMigrationViewActionsBuilderService extends WorkspaceEntity
}
protected validateFlatEntityCreation(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.view>,
): FlatEntityValidationReturnType<typeof ALL_METADATA_NAME.view, 'create'> {
args: UniversalFlatEntityValidationArgs<typeof ALL_METADATA_NAME.view>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.view,
'create'
> {
const validationResult =
this.flatViewValidatorService.validateFlatViewCreation(args);
@@ -45,8 +48,11 @@ export class WorkspaceMigrationViewActionsBuilderService extends WorkspaceEntity
}
protected validateFlatEntityDeletion(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.view>,
): FlatEntityValidationReturnType<typeof ALL_METADATA_NAME.view, 'delete'> {
args: UniversalFlatEntityValidationArgs<typeof ALL_METADATA_NAME.view>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.view,
'delete'
> {
const validationResult =
this.flatViewValidatorService.validateFlatViewDeletion(args);
@@ -71,7 +77,10 @@ export class WorkspaceMigrationViewActionsBuilderService extends WorkspaceEntity
protected validateFlatEntityUpdate(
args: FlatEntityUpdateValidationArgs<typeof ALL_METADATA_NAME.view>,
): FlatEntityValidationReturnType<typeof ALL_METADATA_NAME.view, 'update'> {
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.view,
'update'
> {
const validationResult =
this.flatViewValidatorService.validateFlatViewUpdate(args);
@@ -82,12 +91,12 @@ export class WorkspaceMigrationViewActionsBuilderService extends WorkspaceEntity
};
}
const { flatEntityId, flatEntityUpdate } = args;
const { universalIdentifier, flatEntityUpdate } = args;
const updateViewAction: FlatUpdateViewAction = {
const updateViewAction: UniversalUpdateViewAction = {
type: 'update',
metadataName: 'view',
entityId: flatEntityId,
universalIdentifier,
update: flatEntityUpdate,
};
@@ -2,6 +2,7 @@ import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspac
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
import { type BaseUniversalUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-update-workspace-migration-action.type';
export type FlatCreateWebhookAction =
BaseFlatCreateWorkspaceMigrationAction<'webhook'>;
@@ -9,6 +10,9 @@ export type FlatCreateWebhookAction =
export type FlatUpdateWebhookAction =
BaseFlatUpdateWorkspaceMigrationAction<'webhook'>;
export type UniversalUpdateWebhookAction =
BaseUniversalUpdateWorkspaceMigrationAction<'webhook'>;
export type UniversalDeleteWebhookAction =
BaseUniversalDeleteWorkspaceMigrationAction<'webhook'>;
@@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { FlatUpdateWebhookAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/webhook/types/workspace-migration-webhook-action.type';
import { UniversalUpdateWebhookAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/webhook/types/workspace-migration-webhook-action.type';
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-update-validation-args.type';
import { UniversalFlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-args.type';
import { UniversalFlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-result.type';
import { FlatWebhookValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-webhook-validator.service';
@Injectable()
@@ -20,8 +20,8 @@ export class WorkspaceMigrationWebhookActionsBuilderService extends WorkspaceEnt
}
protected validateFlatEntityCreation(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.webhook>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<typeof ALL_METADATA_NAME.webhook>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.webhook,
'create'
> {
@@ -48,8 +48,8 @@ export class WorkspaceMigrationWebhookActionsBuilderService extends WorkspaceEnt
}
protected validateFlatEntityDeletion(
args: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.webhook>,
): FlatEntityValidationReturnType<
args: UniversalFlatEntityValidationArgs<typeof ALL_METADATA_NAME.webhook>,
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.webhook,
'delete'
> {
@@ -77,7 +77,7 @@ export class WorkspaceMigrationWebhookActionsBuilderService extends WorkspaceEnt
protected validateFlatEntityUpdate(
args: FlatEntityUpdateValidationArgs<typeof ALL_METADATA_NAME.webhook>,
): FlatEntityValidationReturnType<
): UniversalFlatEntityValidationReturnType<
typeof ALL_METADATA_NAME.webhook,
'update'
> {
@@ -91,12 +91,12 @@ export class WorkspaceMigrationWebhookActionsBuilderService extends WorkspaceEnt
};
}
const { flatEntityId, flatEntityUpdate } = args;
const { universalIdentifier, flatEntityUpdate } = args;
const updateWebhookAction: FlatUpdateWebhookAction = {
const updateWebhookAction: UniversalUpdateWebhookAction = {
type: 'update',
metadataName: 'webhook',
entityId: flatEntityId,
universalIdentifier,
update: flatEntityUpdate,
};
@@ -9,34 +9,34 @@ import {
FlatEntityMapsException,
FlatEntityMapsExceptionCode,
} from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception';
import { MetadataFlatEntityAndRelatedFlatEntityMapsForValidation } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity-and-related-flat-entity-maps-for-validation.type';
import { MetadataFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity-maps.type';
import { MetadataFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity.type';
import { MetadataValidationRelatedFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-related-types.type';
import { addFlatEntityToFlatEntityAndRelatedEntityMapsThroughMutationOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-and-related-entity-maps-through-mutation-or-throw.util';
import { deleteFlatEntityFromFlatEntityAndRelatedEntityMapsThroughMutationOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/delete-flat-entity-from-flat-entity-and-related-entity-maps-through-mutation-or-throw.util';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { MetadataUniversalFlatEntityAndRelatedFlatEntityMapsForValidation } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity-and-related-flat-entity-maps-for-validation.type';
import { MetadataValidationRelatedUniversalFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-related-types.type';
import { MetadataUniversalFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-universal-flat-entity.type';
import { findFlatEntityByUniversalIdentifierOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier-or-throw.util';
import { findFlatEntityByUniversalIdentifier } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util';
import { getMetadataFlatEntityMapsKey } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-flat-entity-maps-key.util';
import { WorkspaceMigrationBuilderAdditionalCacheDataMaps } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-builder-additional-cache-data-maps.type';
import { deleteFlatEntityFromFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/delete-flat-entity-from-flat-entity-maps-through-mutation-or-throw.util';
import { flatEntityDeletedCreatedUpdatedMatrixDispatcher } from 'src/engine/workspace-manager/workspace-migration/utils/flat-entity-deleted-created-updated-matrix-dispatcher.util';
import { MetadataUniversalFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/metadata-universal-flat-entity-maps.type';
import { addUniversalFlatEntityToUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/add-universal-flat-entity-to-universal-flat-entity-and-related-entity-maps-through-mutation-or-throw.util';
import { deleteUniversalFlatEntityFromUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/delete-universal-flat-entity-from-universal-flat-entity-and-related-entity-maps-through-mutation-or-throw.util';
import { deleteUniversalFlatEntityFromUniversalFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/delete-universal-flat-entity-from-universal-flat-entity-maps-through-mutation-or-throw.util';
import { replaceUniversalFlatEntityInUniversalFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/replace-universal-flat-entity-in-universal-flat-entity-maps-through-mutation-or-throw.util';
import { flatEntityDeletedCreatedUpdatedMatrixDispatcher } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/universal-flat-entity-deleted-created-updated-matrix-dispatcher.util';
import { getMetadataEmptyWorkspaceMigrationActionRecord } from 'src/engine/workspace-manager/workspace-migration/utils/get-metadata-empty-workspace-migration-action-record.util';
import { replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/replace-flat-entity-in-flat-entity-maps-through-mutation-or-throw.util';
import { shouldInferDeletionFromMissingEntities } from 'src/engine/workspace-manager/workspace-migration/utils/should-infer-deletion-from-missing-entities.util';
import { FailedFlatEntityValidateAndBuild } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/failed-flat-entity-validate-and-build.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type';
import { SuccessfulFlatEntityValidateAndBuild } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/successful-flat-entity-validate-and-build.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-update-validation-args.type';
import { UniversalFlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-args.type';
import { UniversalFlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-result.type';
import { type WorkspaceMigrationBuilderOptions } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/workspace-migration-builder-options.type';
export type ValidateAndBuildArgs<T extends AllMetadataName> = {
buildOptions: WorkspaceMigrationBuilderOptions;
dependencyOptimisticFlatEntityMaps: MetadataValidationRelatedFlatEntityMaps<T>;
dependencyOptimisticFlatEntityMaps: MetadataValidationRelatedUniversalFlatEntityMaps<T>;
workspaceId: string;
additionalCacheDataMaps: WorkspaceMigrationBuilderAdditionalCacheDataMaps;
} & FromTo<MetadataFlatEntityMaps<T>>;
} & FromTo<MetadataUniversalFlatEntityMaps<T>>;
export type ValidateAndBuildReturnType<T extends AllMetadataName> = Promise<
SuccessfulFlatEntityValidateAndBuild<T> | FailedFlatEntityValidateAndBuild<T>
@@ -95,7 +95,7 @@ export abstract class WorkspaceEntityMigrationBuilderService<
const optimisticFlatEntityMapsAndRelatedFlatEntityMaps = {
[flatEntityMapsKey]: structuredClone(fromFlatEntityMaps),
...structuredClone(inputDependencyOptimisticFlatEntityMaps),
} as MetadataFlatEntityAndRelatedFlatEntityMapsForValidation<T>;
} as MetadataUniversalFlatEntityAndRelatedFlatEntityMapsForValidation<T>;
const actionsResult = getMetadataEmptyWorkspaceMigrationActionRecord(
this.metadataName,
@@ -116,12 +116,14 @@ export abstract class WorkspaceEntityMigrationBuilderService<
flatEntityMaps: createdFlatEntityMaps,
});
const flatEntityToCreateId = flatEntityToCreate.id;
const flatEntityToCreateId = flatEntityToCreate.universalIdentifier;
deleteFlatEntityFromFlatEntityMapsThroughMutationOrThrow({
entityToDeleteId: flatEntityToCreateId,
flatEntityMapsToMutate: remainingFlatEntityMapsToCreate,
});
deleteUniversalFlatEntityFromUniversalFlatEntityMapsThroughMutationOrThrow(
{
universalIdentifierToDelete: flatEntityToCreateId,
universalFlatEntityMapsToMutate: remainingFlatEntityMapsToCreate,
},
);
const validationResult = await this.validateFlatEntityCreation({
additionalCacheDataMaps,
@@ -137,12 +139,14 @@ export abstract class WorkspaceEntityMigrationBuilderService<
continue;
}
addFlatEntityToFlatEntityAndRelatedEntityMapsThroughMutationOrThrow({
flatEntity: flatEntityToCreate,
flatEntityAndRelatedMapsToMutate:
optimisticFlatEntityMapsAndRelatedFlatEntityMaps,
metadataName: this.metadataName,
});
addUniversalFlatEntityToUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrow(
{
universalFlatEntity: flatEntityToCreate,
universalFlatEntityAndRelatedMapsToMutate:
optimisticFlatEntityMapsAndRelatedFlatEntityMaps,
metadataName: this.metadataName,
},
);
actionsResult.create.push(
...(Array.isArray(validationResult.action)
@@ -164,33 +168,31 @@ export abstract class WorkspaceEntityMigrationBuilderService<
deletedFlatEntityMaps,
);
const flatEntityToDeleteIds = shouldInferDeletionFromMissingEntities({
buildOptions,
metadataName: this.metadataName,
})
? Object.keys(deletedFlatEntityMaps.universalIdentifierById)
const universalIdentifiersToDelete = shouldInferDeletionFromMissingEntities(
{
buildOptions,
metadataName: this.metadataName,
},
)
? Object.keys(deletedFlatEntityMaps.byUniversalIdentifier)
: [];
for (const flatEntityToDeleteId of flatEntityToDeleteIds) {
const flatEntityToDelete = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: flatEntityToDeleteId,
flatEntityMaps: deletedFlatEntityMaps,
});
for (const universalIdentifierToDelete of universalIdentifiersToDelete) {
deleteUniversalFlatEntityFromUniversalFlatEntityMapsThroughMutationOrThrow(
{
universalIdentifierToDelete,
universalFlatEntityMapsToMutate: remainingFlatEntityMapsToDelete,
},
);
if (!isDefined(flatEntityToDelete)) {
throw new FlatEntityMapsException(
'Could not find flat entity to delete in maps should never occur',
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
);
}
deleteFlatEntityFromFlatEntityMapsThroughMutationOrThrow({
entityToDeleteId: flatEntityToDeleteId,
flatEntityMapsToMutate: remainingFlatEntityMapsToDelete,
});
const universalFlatEntityToDelete =
findFlatEntityByUniversalIdentifierOrThrow({
universalIdentifier: universalIdentifierToDelete,
flatEntityMaps: deletedFlatEntityMaps,
});
const validationResult = await this.validateFlatEntityDeletion({
flatEntityToValidate: flatEntityToDelete,
flatEntityToValidate: universalFlatEntityToDelete,
workspaceId,
remainingFlatEntityMapsToValidate: remainingFlatEntityMapsToDelete,
buildOptions,
@@ -203,12 +205,14 @@ export abstract class WorkspaceEntityMigrationBuilderService<
continue;
}
deleteFlatEntityFromFlatEntityAndRelatedEntityMapsThroughMutationOrThrow({
flatEntity: flatEntityToDelete,
flatEntityAndRelatedMapsToMutate:
optimisticFlatEntityMapsAndRelatedFlatEntityMaps,
metadataName: this.metadataName,
});
deleteUniversalFlatEntityFromUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrow(
{
universalFlatEntity: universalFlatEntityToDelete,
universalFlatEntityAndRelatedMapsToMutate:
optimisticFlatEntityMapsAndRelatedFlatEntityMaps,
metadataName: this.metadataName,
},
);
actionsResult.delete.push(
...(Array.isArray(validationResult.action)
@@ -224,12 +228,12 @@ export abstract class WorkspaceEntityMigrationBuilderService<
this.logger.time(`EntityBuilder ${this.metadataName}`, 'update validation');
for (const flatEntityToUpdateUniversalIdentifier in updatedFlatEntityMaps.byUniversalIdentifier) {
const flatEntityToUpdate =
const flatEntityUpdate =
updatedFlatEntityMaps.byUniversalIdentifier[
flatEntityToUpdateUniversalIdentifier
];
if (!isDefined(flatEntityToUpdate)) {
if (!isDefined(flatEntityUpdate)) {
throw new FlatEntityMapsException(
'Could not find flat entity updates in maps dispatcher should never occur',
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
@@ -237,8 +241,7 @@ export abstract class WorkspaceEntityMigrationBuilderService<
}
const validationResult = await this.validateFlatEntityUpdate({
flatEntityUpdate: flatEntityToUpdate.update,
flatEntityId: flatEntityToUpdate.id,
flatEntityUpdate: flatEntityUpdate.update,
optimisticFlatEntityMapsAndRelatedFlatEntityMaps,
workspaceId,
buildOptions,
@@ -251,11 +254,12 @@ export abstract class WorkspaceEntityMigrationBuilderService<
continue;
}
const existingFlatEntity = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: flatEntityToUpdate.id,
flatEntityMaps: optimisticFlatEntityMapsAndRelatedFlatEntityMaps[
flatEntityMapsKey
] as MetadataFlatEntityMaps<T>,
const existingFlatEntity = findFlatEntityByUniversalIdentifier<
MetadataUniversalFlatEntity<T>
>({
universalIdentifier: flatEntityToUpdateUniversalIdentifier,
flatEntityMaps:
optimisticFlatEntityMapsAndRelatedFlatEntityMaps[flatEntityMapsKey],
});
if (!isDefined(existingFlatEntity)) {
@@ -265,16 +269,18 @@ export abstract class WorkspaceEntityMigrationBuilderService<
);
}
const updatedFlatEntity: MetadataFlatEntity<T> = {
const updatedFlatEntity: MetadataUniversalFlatEntity<T> = {
...existingFlatEntity,
...flatEntityToUpdate.update,
...flatEntityUpdate.update,
};
replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow({
flatEntity: updatedFlatEntity,
flatEntityMapsToMutate:
optimisticFlatEntityMapsAndRelatedFlatEntityMaps[flatEntityMapsKey],
});
replaceUniversalFlatEntityInUniversalFlatEntityMapsThroughMutationOrThrow(
{
universalFlatEntity: updatedFlatEntity,
universalFlatEntityMapsToMutate:
optimisticFlatEntityMapsAndRelatedFlatEntityMaps[flatEntityMapsKey],
},
);
actionsResult.update.push(
...(Array.isArray(validationResult.action)
@@ -313,20 +319,20 @@ export abstract class WorkspaceEntityMigrationBuilderService<
}
protected abstract validateFlatEntityCreation(
args: FlatEntityValidationArgs<T>,
args: UniversalFlatEntityValidationArgs<T>,
):
| FlatEntityValidationReturnType<T, 'create'>
| Promise<FlatEntityValidationReturnType<T, 'create'>>;
| UniversalFlatEntityValidationReturnType<T, 'create'>
| Promise<UniversalFlatEntityValidationReturnType<T, 'create'>>;
protected abstract validateFlatEntityDeletion(
args: FlatEntityValidationArgs<T>,
args: UniversalFlatEntityValidationArgs<T>,
):
| FlatEntityValidationReturnType<T, 'delete'>
| Promise<FlatEntityValidationReturnType<T, 'delete'>>;
| UniversalFlatEntityValidationReturnType<T, 'delete'>
| Promise<UniversalFlatEntityValidationReturnType<T, 'delete'>>;
protected abstract validateFlatEntityUpdate(
args: FlatEntityUpdateValidationArgs<T>,
):
| FlatEntityValidationReturnType<T, 'update'>
| Promise<FlatEntityValidationReturnType<T, 'update'>>;
| UniversalFlatEntityValidationReturnType<T, 'update'>
| Promise<UniversalFlatEntityValidationReturnType<T, 'update'>>;
}
@@ -1,6 +1,6 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type FlatEntityUpdate } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
import { type FlatEntityUpdate } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-update.type';
import { type WORKSPACE_MIGRATION_ACTION_TYPE } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/constants/workspace-migration-action-type.constant';
export type BaseFlatUpdateWorkspaceMigrationAction<T extends AllMetadataName> =
@@ -6,7 +6,6 @@ import { type WORKSPACE_MIGRATION_ACTION_TYPE } from 'src/engine/workspace-manag
export type BaseUniversalCreateWorkspaceMigrationAction<
T extends AllMetadataName,
> = {
// TODO prastoin rename to universalFlatEntity ?
flatEntity: MetadataUniversalFlatEntity<T>;
type: typeof WORKSPACE_MIGRATION_ACTION_TYPE.create;
metadataName: T;
@@ -1,6 +1,6 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type FlatEntityUpdate } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
import { type UniversalFlatEntityUpdate } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-update.type';
import { type WORKSPACE_MIGRATION_ACTION_TYPE } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/constants/workspace-migration-action-type.constant';
export type BaseUniversalUpdateWorkspaceMigrationAction<
@@ -9,5 +9,5 @@ export type BaseUniversalUpdateWorkspaceMigrationAction<
type: typeof WORKSPACE_MIGRATION_ACTION_TYPE.update;
metadataName: T;
universalIdentifier: string;
update: FlatEntityUpdate<T>;
update: UniversalFlatEntityUpdate<T>;
};
@@ -1,11 +1,11 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type MetadataFlatEntityAndRelatedFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-related-types.type';
import { type MetadataUniversalFlatEntityAndRelatedUniversalFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-related-types.type';
import { type WorkspaceMigrationActionType } from 'src/engine/metadata-modules/flat-entity/types/metadata-workspace-migration-action.type';
import { type FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/types/failed-flat-entity-validation.type';
export type FailedFlatEntityValidateAndBuild<T extends AllMetadataName> = {
status: 'fail';
errors: FailedFlatEntityValidation<T, WorkspaceMigrationActionType>[];
optimisticFlatEntityMapsAndRelatedFlatEntityMaps: MetadataFlatEntityAndRelatedFlatEntityMaps<T>;
optimisticFlatEntityMapsAndRelatedFlatEntityMaps: MetadataUniversalFlatEntityAndRelatedUniversalFlatEntityMaps<T>;
};
@@ -1,13 +0,0 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type FlatEntityUpdate } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
import { type FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
export type FlatEntityUpdateValidationArgs<T extends AllMetadataName> = Omit<
FlatEntityValidationArgs<T>,
'flatEntityToValidate' | 'remainingFlatEntityMapsToValidate'
> & {
flatEntityId: string;
flatEntityUpdate: FlatEntityUpdate<T>;
universalIdentifier: string;
};
@@ -1,16 +0,0 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type MetadataFlatEntityAndRelatedFlatEntityMapsForValidation } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity-and-related-flat-entity-maps-for-validation.type';
import { type MetadataFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity-maps.type';
import { type MetadataFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity.type';
import { type WorkspaceMigrationBuilderAdditionalCacheDataMaps } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-builder-additional-cache-data-maps.type';
import { type WorkspaceMigrationBuilderOptions } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/workspace-migration-builder-options.type';
export type FlatEntityValidationArgs<T extends AllMetadataName> = {
additionalCacheDataMaps: WorkspaceMigrationBuilderAdditionalCacheDataMaps;
flatEntityToValidate: MetadataFlatEntity<T>;
optimisticFlatEntityMapsAndRelatedFlatEntityMaps: MetadataFlatEntityAndRelatedFlatEntityMapsForValidation<T>;
workspaceId: string;
remainingFlatEntityMapsToValidate: MetadataFlatEntityMaps<T>;
buildOptions: WorkspaceMigrationBuilderOptions;
};
@@ -1,10 +1,10 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type MetadataFlatEntityAndRelatedFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-related-types.type';
import { type MetadataUniversalFlatEntityAndRelatedUniversalFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-related-types.type';
import { type MetadataUniversalWorkspaceMigrationActionsRecord } from 'src/engine/metadata-modules/flat-entity/types/metadata-workspace-migration-action.type';
export type SuccessfulFlatEntityValidateAndBuild<T extends AllMetadataName> = {
status: 'success';
actions: MetadataUniversalWorkspaceMigrationActionsRecord<T>;
optimisticFlatEntityMapsAndRelatedFlatEntityMaps: MetadataFlatEntityAndRelatedFlatEntityMaps<T>;
optimisticFlatEntityMapsAndRelatedFlatEntityMaps: MetadataUniversalFlatEntityAndRelatedUniversalFlatEntityMaps<T>;
};

Some files were not shown because too many files have changed in this diff Show More