Deprecate object metadata maps in favor of flat entities (#16080)
## Context Deprecating the old objectMetadataMap type in favour of split flat entities to match with our new caching. In the long run, trying to achieve: - Better performance through caching - Consistent data access patterns across the codebase - Reduced database queries Now that everything is based on flat entities, which are cached, we can finish the refactoring of workspace context cache which should already improve performances. Then the last step will be to consume that new cache in the new global datasource to get rid of the many workspace datasources stored in the server
This commit is contained in:
+33
-2
@@ -1,7 +1,11 @@
|
||||
import { isString } from '@sniptt/guards';
|
||||
import { type DataSource, type QueryRunner } from 'typeorm';
|
||||
|
||||
import { getFlatFieldsFromFlatObjectMetadata } from 'src/engine/api/graphql/workspace-schema-builder/utils/get-flat-fields-for-flat-object-metadata.util';
|
||||
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
|
||||
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
|
||||
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 { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { ViewFieldEntity } from 'src/engine/metadata-modules/view-field/entities/view-field.entity';
|
||||
import { ViewFilterEntity } from 'src/engine/metadata-modules/view-filter/entities/view-filter.entity';
|
||||
@@ -37,19 +41,46 @@ import { workspaceMembersAllView } from 'src/engine/workspace-manager/standard-o
|
||||
type PrefillCoreViewsArgs = {
|
||||
coreDataSource: DataSource;
|
||||
workspaceId: string;
|
||||
objectMetadataItems: ObjectMetadataEntity[];
|
||||
flatObjectMetadataMaps: FlatEntityMaps<FlatObjectMetadata>;
|
||||
flatFieldMetadataMaps: FlatEntityMaps<FlatFieldMetadata>;
|
||||
featureFlags?: Record<string, boolean>;
|
||||
workspaceSchemaName: string;
|
||||
twentyStandardFlatApplication: FlatApplication;
|
||||
};
|
||||
|
||||
// This is a temporary function to build the object metadata items from the flat maps.
|
||||
// We should use the maps in the seeders instead.
|
||||
const buildObjectMetadataItemsFromFlatMaps = (
|
||||
flatObjectMetadataMaps: FlatEntityMaps<FlatObjectMetadata>,
|
||||
flatFieldMetadataMaps: FlatEntityMaps<FlatFieldMetadata>,
|
||||
): ObjectMetadataEntity[] => {
|
||||
return Object.values(flatObjectMetadataMaps.byId)
|
||||
.filter((flatObjectMetadata) => flatObjectMetadata !== undefined)
|
||||
.map((flatObjectMetadata) => {
|
||||
const fields = getFlatFieldsFromFlatObjectMetadata(
|
||||
flatObjectMetadata,
|
||||
flatFieldMetadataMaps,
|
||||
);
|
||||
|
||||
return {
|
||||
...flatObjectMetadata,
|
||||
fields,
|
||||
} as unknown as ObjectMetadataEntity;
|
||||
});
|
||||
};
|
||||
|
||||
export const prefillCoreViews = async ({
|
||||
coreDataSource,
|
||||
workspaceId,
|
||||
objectMetadataItems,
|
||||
flatObjectMetadataMaps,
|
||||
flatFieldMetadataMaps,
|
||||
workspaceSchemaName,
|
||||
twentyStandardFlatApplication,
|
||||
}: PrefillCoreViewsArgs): Promise<ViewEntity[]> => {
|
||||
const objectMetadataItems = buildObjectMetadataItemsFromFlatMaps(
|
||||
flatObjectMetadataMaps,
|
||||
flatFieldMetadataMaps,
|
||||
);
|
||||
const views = [
|
||||
companiesAllView,
|
||||
peopleAllView,
|
||||
|
||||
+21
-14
@@ -1,9 +1,11 @@
|
||||
import { FieldActorSource } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { type EntityManager } from 'typeorm';
|
||||
import { FieldActorSource } from 'twenty-shared/types';
|
||||
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { generateObjectMetadataMaps } from 'src/engine/metadata-modules/utils/generate-object-metadata-maps.util';
|
||||
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
|
||||
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 { buildObjectIdByNameMaps } from 'src/engine/metadata-modules/flat-object-metadata/utils/build-object-id-by-name-maps.util';
|
||||
import { generateObjectRecordFields } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-object-record-fields';
|
||||
|
||||
const QUICK_LEAD_WORKFLOW_ID = '8b213cac-a68b-4ffe-817a-3ec994e9932d';
|
||||
@@ -12,13 +14,15 @@ const QUICK_LEAD_WORKFLOW_VERSION_ID = 'ac67974f-c524-4288-9d88-af8515400b68';
|
||||
export const prefillWorkflows = async (
|
||||
entityManager: EntityManager,
|
||||
schemaName: string,
|
||||
objectMetadataItems: ObjectMetadataEntity[],
|
||||
flatObjectMetadataMaps: FlatEntityMaps<FlatObjectMetadata>,
|
||||
flatFieldMetadataMaps: FlatEntityMaps<FlatFieldMetadata>,
|
||||
) => {
|
||||
const objectMetadataMaps = generateObjectMetadataMaps(objectMetadataItems);
|
||||
const companyObjectMetadataId =
|
||||
objectMetadataMaps.idByNameSingular['company'];
|
||||
const { idByNameSingular: objectIdByNameSingular } = buildObjectIdByNameMaps(
|
||||
flatObjectMetadataMaps,
|
||||
);
|
||||
|
||||
const personObjectMetadataId = objectMetadataMaps.idByNameSingular['person'];
|
||||
const companyObjectMetadataId = objectIdByNameSingular['company'];
|
||||
const personObjectMetadataId = objectIdByNameSingular['person'];
|
||||
|
||||
if (
|
||||
!isDefined(companyObjectMetadataId) ||
|
||||
@@ -28,9 +32,10 @@ export const prefillWorkflows = async (
|
||||
}
|
||||
|
||||
const companyObjectMetadata =
|
||||
objectMetadataMaps.byId[companyObjectMetadataId];
|
||||
flatObjectMetadataMaps.byId[companyObjectMetadataId];
|
||||
|
||||
const personObjectMetadata = objectMetadataMaps.byId[personObjectMetadataId];
|
||||
const personObjectMetadata =
|
||||
flatObjectMetadataMaps.byId[personObjectMetadataId];
|
||||
|
||||
if (!isDefined(companyObjectMetadata) || !isDefined(personObjectMetadata)) {
|
||||
throw new Error('Company or person object metadata not found');
|
||||
@@ -220,8 +225,9 @@ export const prefillWorkflows = async (
|
||||
_outputSchemaType: 'RECORD',
|
||||
fields: generateObjectRecordFields({
|
||||
objectMetadataInfo: {
|
||||
objectMetadataItemWithFieldsMaps: companyObjectMetadata,
|
||||
objectMetadataMaps,
|
||||
flatObjectMetadata: companyObjectMetadata,
|
||||
flatObjectMetadataMaps,
|
||||
flatFieldMetadataMaps,
|
||||
},
|
||||
depth: 0,
|
||||
}),
|
||||
@@ -262,8 +268,9 @@ export const prefillWorkflows = async (
|
||||
outputSchema: {
|
||||
fields: generateObjectRecordFields({
|
||||
objectMetadataInfo: {
|
||||
objectMetadataItemWithFieldsMaps: personObjectMetadata,
|
||||
objectMetadataMaps,
|
||||
flatObjectMetadata: personObjectMetadata,
|
||||
flatObjectMetadataMaps,
|
||||
flatFieldMetadataMaps,
|
||||
},
|
||||
depth: 0,
|
||||
}),
|
||||
|
||||
+11
-3
@@ -1,6 +1,8 @@
|
||||
import { type DataSource, type EntityManager } from 'typeorm';
|
||||
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
|
||||
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 { prefillCompanies } from 'src/engine/workspace-manager/standard-objects-prefill-data/prefill-companies';
|
||||
import { prefillPeople } from 'src/engine/workspace-manager/standard-objects-prefill-data/prefill-people';
|
||||
import { prefillWorkflows } from 'src/engine/workspace-manager/standard-objects-prefill-data/prefill-workflows';
|
||||
@@ -8,13 +10,19 @@ import { prefillWorkflows } from 'src/engine/workspace-manager/standard-objects-
|
||||
export const standardObjectsPrefillData = async (
|
||||
dataSource: DataSource,
|
||||
schemaName: string,
|
||||
objectMetadataItems: ObjectMetadataEntity[],
|
||||
flatObjectMetadataMaps: FlatEntityMaps<FlatObjectMetadata>,
|
||||
flatFieldMetadataMaps: FlatEntityMaps<FlatFieldMetadata>,
|
||||
) => {
|
||||
dataSource.transaction(async (entityManager: EntityManager) => {
|
||||
await prefillCompanies(entityManager, schemaName);
|
||||
|
||||
await prefillPeople(entityManager, schemaName);
|
||||
|
||||
await prefillWorkflows(entityManager, schemaName, objectMetadataItems);
|
||||
await prefillWorkflows(
|
||||
entityManager,
|
||||
schemaName,
|
||||
flatObjectMetadataMaps,
|
||||
flatFieldMetadataMaps,
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user