Extract field metadata build out of object metadata build (#14763)
# Introduction Extracting the legacy fields build and dispatch out of the object one to follow the generic flat entity build, also update caches entries for object ## Main tasks - flat field map cache - flat field builder - refactored the dispatch matrix to return flat entity maps instead of flat entity arrays - orchestrator aggregator - removing legacy code - making universal identifier aka standardId of standard field for custom object deterministically dynamic - perfs debug logs for v2 ## TODO - [x] Refactor the generic entity builder to be dependency flat maps in order to main foreign keys list in flat parent - [x] Refactor the flat object metadata to contain the array of related fields and avoid costy find object fields - [ ] Improve the create field handler to handle multiple field at once - [ ] Refactor the dispatch to embbed the comparison - [ ] Improve perf by extracting from elements out of existing - [ ] Fix the labelIdentifierId validators on object before field creation ( integ tests are in failing mode ) ## Debug logs snippet ```ts [EntityBuilder fieldMetadata] matrix computation: 0.027ms [EntityBuilder fieldMetadata] creation validation: 0.001ms [EntityBuilder fieldMetadata] deletion validation: 0.293ms [EntityBuilder fieldMetadata] update validation: 0.006ms [EntityBuilder fieldMetadata] entity processing: 0.363ms [EntityBuilder fieldMetadata] validateAndBuild: 0.455ms [EntityBuilder index] matrix computation: 0.005ms [EntityBuilder index] creation validation: 0.001ms [EntityBuilder index] deletion validation: 0.146ms [EntityBuilder index] update validation: 0.004ms [EntityBuilder index] entity processing: 0.199ms [EntityBuilder index] validateAndBuild: 0.228ms [Runner] Initial cache retrieval: 0.549ms [BaseWorkspaceMigrationRunnerActionHandlerService] delete_index executeForWorkspaceSchema: 11.665ms [BaseWorkspaceMigrationRunnerActionHandlerService] delete_index executeForMetadata: 12.864ms [BaseWorkspaceMigrationRunnerActionHandlerService] delete_field executeForWorkspaceSchema: 1.476ms [BaseWorkspaceMigrationRunnerActionHandlerService] delete_field executeForMetadata: 6.816ms [BaseWorkspaceMigrationRunnerActionHandlerService] delete_field executeForWorkspaceSchema: 0.062ms [BaseWorkspaceMigrationRunnerActionHandlerService] delete_field executeForMetadata: 0.889ms [Runner] Transaction execution: 23.434ms [Runner] Cache invalidation: 316.662ms [Runner] Total execution: 340.767ms ``` As you can see cache invalidation is way to long, we could replace the cache by the optimistic in the end
This commit is contained in:
+9
-2
@@ -1,5 +1,6 @@
|
||||
import { FieldMetadataType, RelationType } from 'twenty-shared/types';
|
||||
|
||||
import { ROCKET_CUSTOM_OBJECT_SEED } from 'src/engine/workspace-manager/dev-seeder/metadata/custom-objects/constants/rocket-custom-object-seed.constant';
|
||||
import { type FieldMetadataSeed } from 'src/engine/workspace-manager/dev-seeder/metadata/types/field-metadata-seed.type';
|
||||
|
||||
export const PET_CUSTOM_RELATION_FIELD_SEEDS: (FieldMetadataSeed & {
|
||||
@@ -18,7 +19,10 @@ export const PET_CUSTOM_RELATION_FIELD_SEEDS: (FieldMetadataSeed & {
|
||||
targetFieldIcon: 'IconRelationOneToMany',
|
||||
},
|
||||
],
|
||||
targetObjectMetadataNames: ['surveyResult', 'rocket'],
|
||||
targetObjectMetadataNames: [
|
||||
'surveyResult',
|
||||
ROCKET_CUSTOM_OBJECT_SEED.nameSingular,
|
||||
],
|
||||
},
|
||||
{
|
||||
type: FieldMetadataType.MORPH_RELATION,
|
||||
@@ -33,6 +37,9 @@ export const PET_CUSTOM_RELATION_FIELD_SEEDS: (FieldMetadataSeed & {
|
||||
targetFieldIcon: 'IconRelationOneToMany',
|
||||
},
|
||||
],
|
||||
targetObjectMetadataNames: ['surveyResult', 'rocket'],
|
||||
targetObjectMetadataNames: [
|
||||
'surveyResult',
|
||||
ROCKET_CUSTOM_OBJECT_SEED.nameSingular,
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
+28
-21
@@ -6,7 +6,8 @@ import { DataSource } from 'typeorm';
|
||||
|
||||
import { type DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity';
|
||||
import { CreateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/create-field.input';
|
||||
import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata/services/field-metadata.service';
|
||||
import { FieldMetadataServiceV2 } from 'src/engine/metadata-modules/field-metadata/services/field-metadata.service-v2';
|
||||
import { ObjectMetadataServiceV2 } from 'src/engine/metadata-modules/object-metadata/object-metadata-v2.service';
|
||||
import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service';
|
||||
import { ObjectMetadataMaps } from 'src/engine/metadata-modules/types/object-metadata-maps';
|
||||
import { WorkspaceMetadataCacheService } from 'src/engine/metadata-modules/workspace-metadata-cache/services/workspace-metadata-cache.service';
|
||||
@@ -30,7 +31,8 @@ import { prefillCoreViews } from 'src/engine/workspace-manager/standard-objects-
|
||||
export class DevSeederMetadataService {
|
||||
constructor(
|
||||
private readonly objectMetadataService: ObjectMetadataService,
|
||||
private readonly fieldMetadataService: FieldMetadataService,
|
||||
private readonly objectMetadataServiceV2: ObjectMetadataServiceV2,
|
||||
private readonly fieldMetadataServiceV2: FieldMetadataServiceV2,
|
||||
private readonly workspaceMetadataCacheService: WorkspaceMetadataCacheService,
|
||||
@InjectDataSource()
|
||||
private readonly coreDataSource: DataSource,
|
||||
@@ -61,7 +63,10 @@ export class DevSeederMetadataService {
|
||||
{ objectName: 'person', seeds: PERSON_CUSTOM_FIELD_SEEDS },
|
||||
],
|
||||
relations: [
|
||||
{ objectName: 'pet', seeds: PET_CUSTOM_RELATION_FIELD_SEEDS },
|
||||
{
|
||||
objectName: PET_CUSTOM_OBJECT_SEED.nameSingular,
|
||||
seeds: PET_CUSTOM_RELATION_FIELD_SEEDS,
|
||||
},
|
||||
],
|
||||
},
|
||||
[SEED_YCOMBINATOR_WORKSPACE_ID]: {
|
||||
@@ -131,9 +136,11 @@ export class DevSeederMetadataService {
|
||||
workspaceId: string;
|
||||
objectMetadataSeed: ObjectMetadataSeed;
|
||||
}): Promise<void> {
|
||||
await this.objectMetadataService.createOne({
|
||||
...objectMetadataSeed,
|
||||
dataSourceId,
|
||||
await this.objectMetadataServiceV2.createOne({
|
||||
createObjectInput: {
|
||||
...objectMetadataSeed,
|
||||
dataSourceId,
|
||||
},
|
||||
workspaceId,
|
||||
});
|
||||
}
|
||||
@@ -152,19 +159,20 @@ export class DevSeederMetadataService {
|
||||
where: { nameSingular: objectMetadataNameSingular },
|
||||
});
|
||||
|
||||
if (!objectMetadata) {
|
||||
if (!isDefined(objectMetadata)) {
|
||||
throw new Error(
|
||||
`Object metadata not found for: ${objectMetadataNameSingular}`,
|
||||
);
|
||||
}
|
||||
const createFieldInputs = fieldMetadataSeeds.map((fieldMetadataSeed) => ({
|
||||
...fieldMetadataSeed,
|
||||
objectMetadataId: objectMetadata.id,
|
||||
}));
|
||||
|
||||
await this.fieldMetadataService.createMany(
|
||||
fieldMetadataSeeds.map((fieldMetadataSeed) => ({
|
||||
...fieldMetadataSeed,
|
||||
objectMetadataId: objectMetadata.id,
|
||||
workspaceId,
|
||||
})),
|
||||
);
|
||||
await this.fieldMetadataServiceV2.createMany({
|
||||
createFieldInputs,
|
||||
workspaceId,
|
||||
});
|
||||
}
|
||||
|
||||
private async seedCoreViews({
|
||||
@@ -226,27 +234,27 @@ export class DevSeederMetadataService {
|
||||
},
|
||||
);
|
||||
|
||||
const relationFieldInputs = this.createFieldInputs({
|
||||
const createFieldInputs = this.createFieldInputs({
|
||||
relation,
|
||||
objectMetadataMaps,
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
await this.fieldMetadataService.createMany(relationFieldInputs);
|
||||
await this.fieldMetadataServiceV2.createMany({
|
||||
createFieldInputs,
|
||||
workspaceId,
|
||||
});
|
||||
}
|
||||
|
||||
private createFieldInputs({
|
||||
relation,
|
||||
objectMetadataMaps,
|
||||
workspaceId,
|
||||
}: {
|
||||
relation: {
|
||||
objectName: string;
|
||||
seeds: (FieldMetadataSeed & { targetObjectMetadataNames: string[] })[];
|
||||
};
|
||||
objectMetadataMaps: ObjectMetadataMaps;
|
||||
workspaceId: string;
|
||||
}): CreateFieldInput[] {
|
||||
}): Omit<CreateFieldInput, 'workspaceId'>[] {
|
||||
const objectMetadataId =
|
||||
objectMetadataMaps.idByNameSingular[relation.objectName];
|
||||
|
||||
@@ -261,7 +269,6 @@ export class DevSeederMetadataService {
|
||||
label: seed.label,
|
||||
name: seed.name,
|
||||
objectMetadataId,
|
||||
workspaceId,
|
||||
morphRelationsCreationPayload: seed.targetObjectMetadataNames.map(
|
||||
(targetObjectMetadataName) => {
|
||||
const targetObjectMetadataId =
|
||||
|
||||
Reference in New Issue
Block a user