Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,22 @@ import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/worksp
import { ApplicationService } from 'src/engine/core-modules/application/services/application.service';
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
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 { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util';
import { findFlatEntityByUniversalIdentifierOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier-or-throw.util';
import { findFlatEntityByUniversalIdentifier } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util';
import { getSubFlatEntityMapsByApplicationIdsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-by-application-ids-or-throw.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 { findManyFlatEntityByUniversalIdentifierInUniversalFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-universal-identifier-in-universal-flat-entity-maps-or-throw.util';
import { isMorphOrRelationUniversalFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-morph-or-relation-flat-field-metadata.util';
import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager';
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
import { computeTwentyStandardApplicationAllFlatEntityMaps } from 'src/engine/workspace-manager/twenty-standard-application/utils/twenty-standard-application-all-flat-entity-maps.constant';
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service';

const OBJECT_UNIVERSAL_IDENTIFIER_TO_CREATE =
STANDARD_OBJECTS.messageChannelMessageAssociationMessageFolder
.universalIdentifier;
const FIELD_UNIVERSAL_IDENTIFIERS_TO_CREATE = Object.values(
STANDARD_OBJECTS.messageChannelMessageAssociationMessageFolder.fields,
).map((el) => el.universalIdentifier);

@Command({
name: 'upgrade:1-19:backfill-message-channel-message-association-message-folder',
description:
Expand All @@ -40,34 +44,6 @@ export class BackfillMessageChannelMessageAssociationMessageFolderCommand extend
super(workspaceRepository, twentyORMGlobalManager, dataSourceService);
}

private addNewEntitiesToFlatEntityMaps<T extends SyncableFlatEntity>({
fromMaps,
standardBuilderMaps,
}: {
fromMaps: FlatEntityMaps<T>;
standardBuilderMaps: FlatEntityMaps<T>;
}): FlatEntityMaps<T> {
let toMaps = fromMaps;

for (const [universalIdentifier, entity] of Object.entries(
standardBuilderMaps.byUniversalIdentifier,
)) {
if (
!isDefined(entity) ||
isDefined(fromMaps.byUniversalIdentifier[universalIdentifier])
) {
continue;
}

toMaps = addFlatEntityToFlatEntityMapsOrThrow({
flatEntity: entity,
flatEntityMaps: toMaps,
});
}

return toMaps;
}

override async runOnWorkspace({
workspaceId,
options,
Expand All @@ -78,18 +54,14 @@ export class BackfillMessageChannelMessageAssociationMessageFolderCommand extend
`${isDryRun ? '[DRY RUN] ' : ''}Starting backfill of messageChannelMessageAssociationMessageFolder for workspace ${workspaceId}`,
);

const { flatObjectMetadataMaps, flatFieldMetadataMaps, featureFlagsMap } =
const { flatObjectMetadataMaps } =
await this.workspaceCacheService.getOrRecompute(workspaceId, [
'flatObjectMetadataMaps',
'flatFieldMetadataMaps',
'featureFlagsMap',
]);

const existingObject = findFlatEntityByUniversalIdentifier({
flatEntityMaps: flatObjectMetadataMaps,
universalIdentifier:
STANDARD_OBJECTS.messageChannelMessageAssociationMessageFolder
.universalIdentifier,
universalIdentifier: OBJECT_UNIVERSAL_IDENTIFIER_TO_CREATE,
});

if (existingObject) {
Expand All @@ -113,67 +85,63 @@ export class BackfillMessageChannelMessageAssociationMessageFolderCommand extend
{ workspaceId },
);

const fromFlatObjectMetadataMaps =
getSubFlatEntityMapsByApplicationIdsOrThrow<FlatObjectMetadata>({
applicationIds: [twentyStandardFlatApplication.id],
flatEntityMaps: flatObjectMetadataMaps,
const { allFlatEntityMaps: standardAllFlatEntityMaps } =
computeTwentyStandardApplicationAllFlatEntityMaps({
now: new Date().toISOString(),
workspaceId,
twentyStandardApplicationId: twentyStandardFlatApplication.id,
});

const fromFlatFieldMetadataMaps =
getSubFlatEntityMapsByApplicationIdsOrThrow<FlatFieldMetadata>({
applicationIds: [twentyStandardFlatApplication.id],
flatEntityMaps: flatFieldMetadataMaps,
const flatObjectMetadataToCreate =
findFlatEntityByUniversalIdentifierOrThrow({
flatEntityMaps: standardAllFlatEntityMaps.flatObjectMetadataMaps,
universalIdentifier: OBJECT_UNIVERSAL_IDENTIFIER_TO_CREATE,
});

const {
allFlatEntityMaps: standardAllFlatEntityMaps,
idByUniversalIdentifierByMetadataName,
} = computeTwentyStandardApplicationAllFlatEntityMaps({
now: new Date().toISOString(),
workspaceId,
twentyStandardApplicationId: twentyStandardFlatApplication.id,
});

const toFlatObjectMetadataMaps =
this.addNewEntitiesToFlatEntityMaps<FlatObjectMetadata>({
fromMaps: fromFlatObjectMetadataMaps,
standardBuilderMaps: standardAllFlatEntityMaps.flatObjectMetadataMaps,
});

const toFlatFieldMetadataMaps =
this.addNewEntitiesToFlatEntityMaps<FlatFieldMetadata>({
fromMaps: fromFlatFieldMetadataMaps,
standardBuilderMaps: standardAllFlatEntityMaps.flatFieldMetadataMaps,
const flatFieldMetadataToCreateOnObject =
findManyFlatEntityByUniversalIdentifierInUniversalFlatEntityMapsOrThrow({
flatEntityMaps: standardAllFlatEntityMaps.flatFieldMetadataMaps,
universalIdentifiers: FIELD_UNIVERSAL_IDENTIFIERS_TO_CREATE,
});
const relatedFlatFieldMetadataToCreate = flatFieldMetadataToCreateOnObject
.map((flatFieldMetadata) => {
if (!isMorphOrRelationUniversalFlatFieldMetadata(flatFieldMetadata)) {
return undefined;
}

return findFlatEntityByUniversalIdentifierOrThrow({
flatEntityMaps: standardAllFlatEntityMaps.flatFieldMetadataMaps,
universalIdentifier:
flatFieldMetadata.relationTargetFieldMetadataUniversalIdentifier,
});
})
.filter(isDefined);

const validateAndBuildResult =
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigrationFromTo(
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
{
buildOptions: {
isSystemBuild: true,
applicationUniversalIdentifier:
twentyStandardFlatApplication.universalIdentifier,
},
fromToAllFlatEntityMaps: {
flatObjectMetadataMaps: {
from: fromFlatObjectMetadataMaps,
to: toFlatObjectMetadataMaps,
allFlatEntityOperationByMetadataName: {
objectMetadata: {
flatEntityToCreate: [flatObjectMetadataToCreate],
flatEntityToDelete: [],
flatEntityToUpdate: [],
},
flatFieldMetadataMaps: {
from: fromFlatFieldMetadataMaps,
to: toFlatFieldMetadataMaps,
fieldMetadata: {
flatEntityToCreate: [
...flatFieldMetadataToCreateOnObject,
...relatedFlatFieldMetadataToCreate,
],
flatEntityToDelete: [],
flatEntityToUpdate: [],
},
},
workspaceId,
additionalCacheDataMaps: {
featureFlagsMap,
},

idByUniversalIdentifierByMetadataName,
applicationUniversalIdentifier:
twentyStandardFlatApplication.universalIdentifier,
},
);

if (isDefined(validateAndBuildResult)) {
if (validateAndBuildResult.status === 'fail') {
this.logger.error(
`Failed to create messageChannelMessageAssociationMessageFolder:\n${JSON.stringify(validateAndBuildResult, null, 2)}`,
);
Expand Down