Builder runs delete update and then create (#18272)

# Introduction
We need to build and validate the flat entity operation in the following
order delete update and create
For example if not, if a created field has the same name than a deleted
one than it will fail whereas it should not
This commit is contained in:
Paul Rastoin
2026-03-03 11:26:06 +01:00
committed by GitHub
parent 0b766464e4
commit 58e37a118c
3 changed files with 489 additions and 74 deletions
@@ -103,79 +103,7 @@ export abstract class WorkspaceEntityMigrationBuilderService<
);
const allValidationResult: FailedFlatEntityValidateAndBuild<T>['errors'] =
[];
const remainingFlatEntityMapsToCreate = structuredClone(
createdFlatEntityMaps,
);
this.logger.time(
`EntityBuilder ${this.metadataName}`,
'creation validation',
);
for (const flatEntityToCreateUniversalIdentifier in createdFlatEntityMaps.byUniversalIdentifier) {
const rawUniversalflatEntityToCreate =
findFlatEntityByUniversalIdentifierOrThrow({
universalIdentifier: flatEntityToCreateUniversalIdentifier,
flatEntityMaps: createdFlatEntityMaps,
});
const universalFlatEntityToCreate =
resetUniversalFlatEntityForeignKeyAggregators({
metadataName: this.metadataName,
universalFlatEntity: rawUniversalflatEntityToCreate,
});
const universalIdentifierToDelete =
universalFlatEntityToCreate.universalIdentifier;
deleteUniversalFlatEntityFromUniversalFlatEntityMapsThroughMutationOrThrow(
{
universalIdentifierToDelete,
universalFlatEntityMapsToMutate: remainingFlatEntityMapsToCreate,
},
);
const validationResult = await this.innerValidateFlatEntityCreation({
additionalCacheDataMaps,
flatEntityToValidate: universalFlatEntityToCreate,
workspaceId,
optimisticFlatEntityMapsAndRelatedFlatEntityMaps,
remainingFlatEntityMapsToValidate: remainingFlatEntityMapsToCreate,
buildOptions,
});
if (validationResult.status === 'fail') {
allValidationResult.push(validationResult);
continue;
}
addUniversalFlatEntityToUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrow(
{
universalFlatEntity: universalFlatEntityToCreate,
universalFlatEntityAndRelatedMapsToMutate:
optimisticFlatEntityMapsAndRelatedFlatEntityMaps,
metadataName: this.metadataName,
},
);
const formattedNewCreateAction: AllUniversalWorkspaceMigrationAction<
'create',
typeof this.metadataName
> = {
...validationResult.action,
flatEntity: deleteUniversalFlatEntityForeignKeyAggregators({
metadataName: this.metadataName,
universalFlatEntity: validationResult.action
.flatEntity as MetadataFlatEntity<T>,
}),
};
actionsResult.create.push(formattedNewCreateAction);
}
this.logger.timeEnd(
`EntityBuilder ${this.metadataName}`,
'creation validation',
);
this.logger.time(
`EntityBuilder ${this.metadataName}`,
'deletion validation',
@@ -310,6 +238,80 @@ export abstract class WorkspaceEntityMigrationBuilderService<
`EntityBuilder ${this.metadataName}`,
'update validation',
);
const remainingFlatEntityMapsToCreate = structuredClone(
createdFlatEntityMaps,
);
this.logger.time(
`EntityBuilder ${this.metadataName}`,
'creation validation',
);
for (const flatEntityToCreateUniversalIdentifier in createdFlatEntityMaps.byUniversalIdentifier) {
const rawUniversalflatEntityToCreate =
findFlatEntityByUniversalIdentifierOrThrow({
universalIdentifier: flatEntityToCreateUniversalIdentifier,
flatEntityMaps: createdFlatEntityMaps,
});
const universalFlatEntityToCreate =
resetUniversalFlatEntityForeignKeyAggregators({
metadataName: this.metadataName,
universalFlatEntity: rawUniversalflatEntityToCreate,
});
const universalIdentifierToDelete =
universalFlatEntityToCreate.universalIdentifier;
deleteUniversalFlatEntityFromUniversalFlatEntityMapsThroughMutationOrThrow(
{
universalIdentifierToDelete,
universalFlatEntityMapsToMutate: remainingFlatEntityMapsToCreate,
},
);
const validationResult = await this.innerValidateFlatEntityCreation({
additionalCacheDataMaps,
flatEntityToValidate: universalFlatEntityToCreate,
workspaceId,
optimisticFlatEntityMapsAndRelatedFlatEntityMaps,
remainingFlatEntityMapsToValidate: remainingFlatEntityMapsToCreate,
buildOptions,
});
if (validationResult.status === 'fail') {
allValidationResult.push(validationResult);
continue;
}
addUniversalFlatEntityToUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrow(
{
universalFlatEntity: universalFlatEntityToCreate,
universalFlatEntityAndRelatedMapsToMutate:
optimisticFlatEntityMapsAndRelatedFlatEntityMaps,
metadataName: this.metadataName,
},
);
const formattedNewCreateAction: AllUniversalWorkspaceMigrationAction<
'create',
typeof this.metadataName
> = {
...validationResult.action,
flatEntity: deleteUniversalFlatEntityForeignKeyAggregators({
metadataName: this.metadataName,
universalFlatEntity: validationResult.action
.flatEntity as MetadataFlatEntity<T>,
}),
};
actionsResult.create.push(formattedNewCreateAction);
}
this.logger.timeEnd(
`EntityBuilder ${this.metadataName}`,
'creation validation',
);
this.logger.timeEnd(
`EntityBuilder ${this.metadataName}`,
'entity processing',