Resolve involved application ids from API metadata (#18221)
# Introduction Resolving each create|updated|deleted entities related entities application through their universal foreingKey ( silently failing if not found leaving the validator handling that ) In order to compute all the required application in the dependency flat entity maps ## Tested Creating a field on a custom local twenty-apps installed on the workspace + view field ## Out of scope - updated snapshot - update graphql generated front
This commit is contained in:
+125
-23
@@ -6,8 +6,10 @@ import {
|
||||
} from 'twenty-shared/metadata';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { FlatApplicationCacheMaps } from 'src/engine/core-modules/application/types/flat-application-cache-maps.type';
|
||||
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
|
||||
import { MetadataEventEmitter } from 'src/engine/metadata-event-emitter/metadata-event-emitter';
|
||||
import { ALL_MANY_TO_ONE_METADATA_RELATIONS } from 'src/engine/metadata-modules/flat-entity/constant/all-many-to-one-metadata-relations.constant';
|
||||
import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
|
||||
import {
|
||||
FlatEntityMapsException,
|
||||
@@ -68,6 +70,122 @@ export class WorkspaceMigrationValidateBuildAndRunService {
|
||||
this.isDebugEnabled = logLevels.includes('debug');
|
||||
}
|
||||
|
||||
private computeAllInvolvedApplicationIds({
|
||||
allFlatEntityOperationByMetadataName,
|
||||
flatApplicationMaps,
|
||||
applicationUniversalIdentifier,
|
||||
allRelatedFlatEntityMaps,
|
||||
}: Pick<
|
||||
ValidateBuildAndRunWorkspaceMigrationFromMatriceArgs,
|
||||
'allFlatEntityOperationByMetadataName' | 'applicationUniversalIdentifier'
|
||||
> & {
|
||||
flatApplicationMaps: FlatApplicationCacheMaps;
|
||||
allRelatedFlatEntityMaps: Partial<AllFlatEntityMaps>;
|
||||
}): string[] {
|
||||
const applicationIds = new Set<string>();
|
||||
|
||||
const applicationId =
|
||||
flatApplicationMaps.idByUniversalIdentifier[
|
||||
applicationUniversalIdentifier
|
||||
];
|
||||
|
||||
const twentyStandardApplicationId =
|
||||
flatApplicationMaps.idByUniversalIdentifier[
|
||||
TWENTY_STANDARD_APPLICATION.universalIdentifier
|
||||
];
|
||||
|
||||
if (!isDefined(twentyStandardApplicationId) || !isDefined(applicationId)) {
|
||||
throw new FlatEntityMapsException(
|
||||
'Application to build and its dependent application not found',
|
||||
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
applicationIds.add(applicationId);
|
||||
|
||||
const isBuildingTwentyStandardApplication =
|
||||
applicationUniversalIdentifier ===
|
||||
TWENTY_STANDARD_APPLICATION.universalIdentifier;
|
||||
|
||||
if (!isBuildingTwentyStandardApplication) {
|
||||
applicationIds.add(twentyStandardApplicationId);
|
||||
}
|
||||
|
||||
for (const metadataName of Object.keys(
|
||||
allFlatEntityOperationByMetadataName,
|
||||
) as AllMetadataName[]) {
|
||||
const flatEntityOperations =
|
||||
allFlatEntityOperationByMetadataName[metadataName];
|
||||
|
||||
if (!isDefined(flatEntityOperations)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const { flatEntityToCreate, flatEntityToUpdate, flatEntityToDelete } =
|
||||
flatEntityOperations;
|
||||
|
||||
const relations = ALL_MANY_TO_ONE_METADATA_RELATIONS[metadataName];
|
||||
|
||||
for (const flatEntity of [
|
||||
...flatEntityToCreate,
|
||||
...flatEntityToUpdate,
|
||||
...flatEntityToDelete,
|
||||
]) {
|
||||
const entityApplicationId =
|
||||
flatApplicationMaps.idByUniversalIdentifier[
|
||||
flatEntity.applicationUniversalIdentifier
|
||||
];
|
||||
|
||||
if (isDefined(entityApplicationId)) {
|
||||
applicationIds.add(entityApplicationId);
|
||||
}
|
||||
|
||||
for (const relation of Object.values(relations) as ({
|
||||
foreignKey: string;
|
||||
metadataName: AllMetadataName;
|
||||
isNullable: boolean;
|
||||
universalForeignKey: string;
|
||||
} | null)[]) {
|
||||
if (!isDefined(relation)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const { universalForeignKey, metadataName: targetMetadataName } =
|
||||
relation;
|
||||
|
||||
const referencedUniversalIdentifier =
|
||||
flatEntity[universalForeignKey as keyof typeof flatEntity];
|
||||
|
||||
if (!isDefined(referencedUniversalIdentifier)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const targetFlatEntityMaps =
|
||||
allRelatedFlatEntityMaps[
|
||||
getMetadataFlatEntityMapsKey(
|
||||
targetMetadataName as AllMetadataName,
|
||||
)
|
||||
];
|
||||
|
||||
if (!isDefined(targetFlatEntityMaps)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const referencedEntity =
|
||||
targetFlatEntityMaps.byUniversalIdentifier[
|
||||
referencedUniversalIdentifier
|
||||
];
|
||||
|
||||
if (isDefined(referencedEntity)) {
|
||||
applicationIds.add(referencedEntity.applicationId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [...applicationIds];
|
||||
}
|
||||
|
||||
private async computeAllRelatedFlatEntityMaps({
|
||||
allFlatEntityOperationByMetadataName,
|
||||
workspaceId,
|
||||
@@ -105,26 +223,12 @@ export class WorkspaceMigrationValidateBuildAndRunService {
|
||||
{},
|
||||
);
|
||||
|
||||
const twentyStandardApplicationId =
|
||||
flatApplicationMaps.idByUniversalIdentifier[
|
||||
TWENTY_STANDARD_APPLICATION.universalIdentifier
|
||||
];
|
||||
|
||||
const applicationId =
|
||||
flatApplicationMaps.idByUniversalIdentifier[
|
||||
applicationUniversalIdentifier
|
||||
];
|
||||
|
||||
if (!isDefined(twentyStandardApplicationId) || !isDefined(applicationId)) {
|
||||
throw new FlatEntityMapsException(
|
||||
'Application to build and its dependent application not found',
|
||||
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
const isBuildingTwentyStandardApplication =
|
||||
applicationUniversalIdentifier ===
|
||||
TWENTY_STANDARD_APPLICATION.universalIdentifier;
|
||||
const applicationIds = this.computeAllInvolvedApplicationIds({
|
||||
allFlatEntityOperationByMetadataName,
|
||||
flatApplicationMaps,
|
||||
applicationUniversalIdentifier,
|
||||
allRelatedFlatEntityMaps,
|
||||
});
|
||||
|
||||
const dependencyAllFlatEntityMaps = allMetadataNameCacheToCompute.reduce(
|
||||
(allFlatEntityMaps, metadataName) => {
|
||||
@@ -137,9 +241,7 @@ export class WorkspaceMigrationValidateBuildAndRunService {
|
||||
getSubFlatEntityMapsByApplicationIdsOrThrow<
|
||||
MetadataFlatEntity<typeof metadataName>
|
||||
>({
|
||||
applicationIds: isBuildingTwentyStandardApplication
|
||||
? [applicationId]
|
||||
: [applicationId, twentyStandardApplicationId],
|
||||
applicationIds,
|
||||
flatEntityMaps:
|
||||
allRelatedFlatEntityMaps[metadataFlatEntityMapsKey],
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user