Remove sync-metadata and IS_WORKSPACE_CREATION_V2_ENABLED feature flag (#16997)
# Introduction Followup of https://github.com/twentyhq/twenty/pull/17001#pullrequestreview-3638508738 close https://github.com/twentyhq/core-team-issues/issues/1910 We've completely decom the `sync-metadata` in production. We're now then removing its implementation in favor of the v2. ## TODO: - [x] Remove sync-metadata implem and commands - [x] Remove workspace decorators - [x] Type each deprecated field to deprecated on their workspaceEntity - [x] Remove the `workspace-sync-metadata` folder entirely - [x] remove workspace migration - [x] workspace migration removal migration - [x] remove the `v2` references from workspace manager file names - [x] remove the `v2` references from workspace manager modules - [ ] Double check impact on translation file path updates ## Note - Removed the gate logic - Remains some service v2 naming, serverless needs to be migrated on v2 fully - Removed workspaceMigration service app health consumption, making it always returning up ( no more down ) cc @FelixMalfait ( quite obsolete health check now, will require complete refactor once we introduce inter app dependency etc )
This commit is contained in:
+1075
File diff suppressed because it is too large
Load Diff
+238
@@ -0,0 +1,238 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
|
||||
import {
|
||||
AllMetadataName,
|
||||
WorkspaceMigrationV2ExceptionCode,
|
||||
} from 'twenty-shared/metadata';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { ALL_METADATA_REQUIRED_METADATA_FOR_VALIDATION } from 'src/engine/metadata-modules/flat-entity/constant/all-metadata-required-metadata-for-validation.constant';
|
||||
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 { 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 { 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 {
|
||||
FromToAllFlatEntityMaps,
|
||||
WorkspaceMigrationOrchestratorBuildArgs,
|
||||
WorkspaceMigrationOrchestratorFailedResult,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-orchestrator.type';
|
||||
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';
|
||||
|
||||
type ValidateBuildAndRunWorkspaceMigrationFromMatriceArgs = {
|
||||
workspaceId: string;
|
||||
allFlatEntityOperationByMetadataName: {
|
||||
[P in AllMetadataName]?: FlatEntityToCreateDeleteUpdate<P>;
|
||||
};
|
||||
isSystemBuild?: boolean;
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceMigrationValidateBuildAndRunService {
|
||||
private readonly logger = new Logger(
|
||||
WorkspaceMigrationValidateBuildAndRunService.name,
|
||||
);
|
||||
|
||||
constructor(
|
||||
private readonly workspaceMigrationRunnerService: WorkspaceMigrationRunnerService,
|
||||
private readonly workspaceMigrationBuildOrchestratorService: WorkspaceMigrationBuildOrchestratorService,
|
||||
private readonly workspaceCacheService: WorkspaceCacheService,
|
||||
) {}
|
||||
|
||||
private async computeAllRelatedFlatEntityMaps({
|
||||
allFlatEntityOperationByMetadataName,
|
||||
workspaceId,
|
||||
}: ValidateBuildAndRunWorkspaceMigrationFromMatriceArgs) {
|
||||
const allMetadataNameToCompare = Object.keys(
|
||||
allFlatEntityOperationByMetadataName,
|
||||
) as AllMetadataName[];
|
||||
const allDependencyMetadataName = allMetadataNameToCompare.flatMap(
|
||||
(metadataName) =>
|
||||
Object.keys(
|
||||
ALL_METADATA_REQUIRED_METADATA_FOR_VALIDATION[metadataName],
|
||||
) as AllMetadataName[],
|
||||
);
|
||||
const allMetadataNameCacheToCompute = [
|
||||
...new Set([...allMetadataNameToCompare, ...allDependencyMetadataName]),
|
||||
];
|
||||
const allFlatEntityMapsCacheKeysToCompute =
|
||||
allMetadataNameCacheToCompute.map(getMetadataFlatEntityMapsKey);
|
||||
|
||||
const allRelatedFlatEntityMaps =
|
||||
await this.workspaceCacheService.getOrRecompute(workspaceId, [
|
||||
...allFlatEntityMapsCacheKeysToCompute,
|
||||
...WORKSPACE_MIGRATION_ADDITIONAL_CACHE_DATA_MAPS_KEY,
|
||||
]);
|
||||
|
||||
const initialAccumulator = allDependencyMetadataName.reduce<
|
||||
Partial<AllFlatEntityMaps>
|
||||
>(
|
||||
(allFlatEntityMaps, metadataName) => ({
|
||||
...allFlatEntityMaps,
|
||||
[getMetadataFlatEntityMapsKey(metadataName)]:
|
||||
createEmptyFlatEntityMaps(),
|
||||
}),
|
||||
{},
|
||||
);
|
||||
const dependencyAllFlatEntityMaps = allDependencyMetadataName.reduce(
|
||||
(allFlatEntityMaps, metadataName) => {
|
||||
const metadataFlatEntityMapsKey =
|
||||
getMetadataFlatEntityMapsKey(metadataName);
|
||||
|
||||
return {
|
||||
...allFlatEntityMaps,
|
||||
[metadataFlatEntityMapsKey]:
|
||||
allRelatedFlatEntityMaps[metadataFlatEntityMapsKey],
|
||||
};
|
||||
},
|
||||
initialAccumulator,
|
||||
);
|
||||
|
||||
const additionalCacheDataMaps =
|
||||
WORKSPACE_MIGRATION_ADDITIONAL_CACHE_DATA_MAPS_KEY.reduce<WorkspaceMigrationBuilderAdditionalCacheDataMaps>(
|
||||
(acc, additionalCacheDataMapsKey) => {
|
||||
return {
|
||||
...acc,
|
||||
[additionalCacheDataMapsKey]:
|
||||
allRelatedFlatEntityMaps[additionalCacheDataMapsKey],
|
||||
};
|
||||
},
|
||||
{} as WorkspaceMigrationBuilderAdditionalCacheDataMaps,
|
||||
);
|
||||
|
||||
return {
|
||||
allRelatedFlatEntityMaps,
|
||||
dependencyAllFlatEntityMaps,
|
||||
additionalCacheDataMaps,
|
||||
};
|
||||
}
|
||||
|
||||
private async computeFromToAllFlatEntityMapsAndBuildOptions({
|
||||
allFlatEntityOperationByMetadataName,
|
||||
workspaceId,
|
||||
}: ValidateBuildAndRunWorkspaceMigrationFromMatriceArgs): Promise<{
|
||||
fromToAllFlatEntityMaps: FromToAllFlatEntityMaps;
|
||||
inferDeletionFromMissingEntities: InferDeletionFromMissingEntities;
|
||||
dependencyAllFlatEntityMaps: Partial<AllFlatEntityMaps>;
|
||||
additionalCacheDataMaps: WorkspaceMigrationBuilderAdditionalCacheDataMaps;
|
||||
}> {
|
||||
const {
|
||||
allRelatedFlatEntityMaps,
|
||||
dependencyAllFlatEntityMaps,
|
||||
additionalCacheDataMaps,
|
||||
} = await this.computeAllRelatedFlatEntityMaps({
|
||||
allFlatEntityOperationByMetadataName,
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
const fromToAllFlatEntityMaps: FromToAllFlatEntityMaps = {};
|
||||
const inferDeletionFromMissingEntities: InferDeletionFromMissingEntities =
|
||||
{};
|
||||
const allMetadataNameToCompare = Object.keys(
|
||||
allFlatEntityOperationByMetadataName,
|
||||
) as AllMetadataName[];
|
||||
|
||||
for (const metadataName of allMetadataNameToCompare) {
|
||||
const flatEntityOperations =
|
||||
allFlatEntityOperationByMetadataName[metadataName];
|
||||
|
||||
if (!isDefined(flatEntityOperations)) {
|
||||
throw new Error('Should never occurs');
|
||||
}
|
||||
const { flatEntityToCreate, flatEntityToDelete, flatEntityToUpdate } =
|
||||
flatEntityOperations;
|
||||
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,
|
||||
});
|
||||
|
||||
if (flatEntityToDelete.length > 0) {
|
||||
inferDeletionFromMissingEntities[metadataName] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
fromToAllFlatEntityMaps,
|
||||
inferDeletionFromMissingEntities,
|
||||
dependencyAllFlatEntityMaps,
|
||||
additionalCacheDataMaps,
|
||||
};
|
||||
}
|
||||
|
||||
public async validateBuildAndRunWorkspaceMigrationFromTo(
|
||||
args: WorkspaceMigrationOrchestratorBuildArgs,
|
||||
) {
|
||||
const validateAndBuildResult =
|
||||
await this.workspaceMigrationBuildOrchestratorService
|
||||
.buildWorkspaceMigration(args)
|
||||
.catch((error) => {
|
||||
this.logger.error(error);
|
||||
throw new WorkspaceMigrationV2Exception(
|
||||
WorkspaceMigrationV2ExceptionCode.BUILDER_INTERNAL_SERVER_ERROR,
|
||||
error.message,
|
||||
);
|
||||
});
|
||||
|
||||
if (validateAndBuildResult.status === 'fail') {
|
||||
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;
|
||||
}
|
||||
|
||||
await this.workspaceMigrationRunnerService
|
||||
.run(validateAndBuildResult.workspaceMigration)
|
||||
.catch((error) => {
|
||||
this.logger.error(error);
|
||||
throw new WorkspaceMigrationV2Exception(
|
||||
WorkspaceMigrationV2ExceptionCode.RUNNER_INTERNAL_SERVER_ERROR,
|
||||
error.message,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public async validateBuildAndRunWorkspaceMigration({
|
||||
allFlatEntityOperationByMetadataName: allFlatEntities,
|
||||
workspaceId,
|
||||
isSystemBuild = false,
|
||||
}: ValidateBuildAndRunWorkspaceMigrationFromMatriceArgs): Promise<
|
||||
WorkspaceMigrationOrchestratorFailedResult | undefined
|
||||
> {
|
||||
const {
|
||||
fromToAllFlatEntityMaps,
|
||||
inferDeletionFromMissingEntities,
|
||||
dependencyAllFlatEntityMaps,
|
||||
additionalCacheDataMaps,
|
||||
} = await this.computeFromToAllFlatEntityMapsAndBuildOptions({
|
||||
allFlatEntityOperationByMetadataName: allFlatEntities,
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
return await this.validateBuildAndRunWorkspaceMigrationFromTo({
|
||||
buildOptions: {
|
||||
isSystemBuild,
|
||||
inferDeletionFromMissingEntities,
|
||||
},
|
||||
fromToAllFlatEntityMaps,
|
||||
workspaceId,
|
||||
dependencyAllFlatEntityMaps,
|
||||
additionalCacheDataMaps,
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user