Refactor flat entity maps to be universal oriented (#17665)

# Introduction
In preparation of the workspace agnostic builder, we're migrating
`FlatEntityMaps` to be universal identifier oriented and based
As in the builder context there're won't be any ids at all
Please also note that the FlatEntity is a UniversalFlatEntity superset

From
```ts
import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type';

export type FlatEntityMaps<T extends SyncableFlatEntity> = {
  byId: Partial<Record<string, T>>;
  idByUniversalIdentifier: Partial<Record<string, string>>;
  universalIdentifiersByApplicationId: Partial<Record<string, string[]>>;
};
```

To
```ts
export type FlatEntityMaps<
  T extends SyncableFlatEntity | UniversalSyncableFlatEntity,
> = {
  byUniversalIdentifier: Partial<Record<string, T>>;
  universalIdentifierById: Partial<Record<string, string>>;
  universalIdentifiersByApplicationId: Partial<Record<string, string[]>>; // this might make more sense to be migrated to universalIdentifiersByApplicationUniversalIdentifier but it's the main topic of this PR
};
```

## Low level maps tools
Had to refactor find | create | delete | replace | find-many | get-sub
tools ( through mutations and or throw equivalent )
This commit is contained in:
Paul Rastoin
2026-02-03 17:16:02 +01:00
committed by GitHub
parent 43042d55b2
commit 476bdf764c
202 changed files with 1853 additions and 909 deletions
@@ -2,6 +2,7 @@ import { Injectable, Logger } from '@nestjs/common';
import { isDefined } from 'twenty-shared/utils';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
import { PageLayoutType } from 'src/engine/metadata-modules/page-layout/enums/page-layout-type.enum';
import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager';
@@ -31,7 +32,10 @@ export class DashboardSyncService {
},
);
const pageLayout = flatPageLayoutMaps.byId[pageLayoutId];
const pageLayout = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: pageLayoutId,
flatEntityMaps: flatPageLayoutMaps,
});
return (
isDefined(pageLayout) && pageLayout.type === PageLayoutType.DASHBOARD
@@ -96,13 +100,19 @@ export class DashboardSyncService {
},
);
const tab = flatPageLayoutTabMaps.byId[tabId];
const tab = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: tabId,
flatEntityMaps: flatPageLayoutTabMaps,
});
if (!isDefined(tab)) {
return;
}
const pageLayout = flatPageLayoutMaps.byId[tab.pageLayoutId];
const pageLayout = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: tab.pageLayoutId,
flatEntityMaps: flatPageLayoutMaps,
});
if (
!isDefined(pageLayout) ||
@@ -143,19 +153,28 @@ export class DashboardSyncService {
},
);
const widget = flatPageLayoutWidgetMaps.byId[widgetId];
const widget = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: widgetId,
flatEntityMaps: flatPageLayoutWidgetMaps,
});
if (!isDefined(widget)) {
return;
}
const tab = flatPageLayoutTabMaps.byId[widget.pageLayoutTabId];
const tab = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: widget.pageLayoutTabId,
flatEntityMaps: flatPageLayoutTabMaps,
});
if (!isDefined(tab)) {
return;
}
const pageLayout = flatPageLayoutMaps.byId[tab.pageLayoutId];
const pageLayout = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: tab.pageLayoutId,
flatEntityMaps: flatPageLayoutMaps,
});
if (
!isDefined(pageLayout) ||
@@ -58,14 +58,38 @@ describe('BarChartDataService', () => {
mockExecuteGroupByQuery = jest.fn();
mockGetOrRecomputeManyOrAllFlatEntityMaps = jest.fn().mockResolvedValue({
flatObjectMetadataMaps: {
byId: { [objectMetadataId]: mockObjectMetadata },
byUniversalIdentifier: {
'test-object-universal-id': {
...mockObjectMetadata,
universalIdentifier: 'test-object-universal-id',
},
},
universalIdentifierById: {
[objectMetadataId]: 'test-object-universal-id',
},
universalIdentifiersByApplicationId: {},
},
flatFieldMetadataMaps: {
byId: {
[mockGroupByField.id]: mockGroupByField,
[mockAggregateField.id]: mockAggregateField,
[mockSelectField.id]: mockSelectField,
byUniversalIdentifier: {
'group-by-field-universal-id': {
...mockGroupByField,
universalIdentifier: 'group-by-field-universal-id',
},
'aggregate-field-universal-id': {
...mockAggregateField,
universalIdentifier: 'aggregate-field-universal-id',
},
'select-field-universal-id': {
...mockSelectField,
universalIdentifier: 'select-field-universal-id',
},
},
universalIdentifierById: {
[mockGroupByField.id]: 'group-by-field-universal-id',
[mockAggregateField.id]: 'aggregate-field-universal-id',
[mockSelectField.id]: 'select-field-universal-id',
},
universalIdentifiersByApplicationId: {},
},
});
@@ -294,14 +318,38 @@ describe('BarChartDataService', () => {
beforeEach(() => {
mockGetOrRecomputeManyOrAllFlatEntityMaps.mockResolvedValue({
flatObjectMetadataMaps: {
byId: { [objectMetadataId]: mockObjectMetadata },
byUniversalIdentifier: {
'test-object-universal-id': {
...mockObjectMetadata,
universalIdentifier: 'test-object-universal-id',
},
},
universalIdentifierById: {
[objectMetadataId]: 'test-object-universal-id',
},
universalIdentifiersByApplicationId: {},
},
flatFieldMetadataMaps: {
byId: {
[mockGroupByField.id]: mockGroupByField,
[mockAggregateField.id]: mockAggregateField,
[mockSelectField.id]: mockSelectField,
byUniversalIdentifier: {
'group-by-field-universal-id': {
...mockGroupByField,
universalIdentifier: 'group-by-field-universal-id',
},
'aggregate-field-universal-id': {
...mockAggregateField,
universalIdentifier: 'aggregate-field-universal-id',
},
'select-field-universal-id': {
...mockSelectField,
universalIdentifier: 'select-field-universal-id',
},
},
universalIdentifierById: {
[mockGroupByField.id]: 'group-by-field-universal-id',
[mockAggregateField.id]: 'aggregate-field-universal-id',
[mockSelectField.id]: 'select-field-universal-id',
},
universalIdentifiersByApplicationId: {},
},
});
});
@@ -65,15 +65,44 @@ describe('LineChartDataService', () => {
useValue: {
getOrRecomputeManyOrAllFlatEntityMaps: jest.fn().mockResolvedValue({
flatObjectMetadataMaps: {
byId: { [objectMetadataId]: mockObjectMetadata },
byUniversalIdentifier: {
'test-object-universal-id': {
...mockObjectMetadata,
universalIdentifier: 'test-object-universal-id',
},
},
universalIdentifierById: {
[objectMetadataId]: 'test-object-universal-id',
},
universalIdentifiersByApplicationId: {},
},
flatFieldMetadataMaps: {
byId: {
[mockGroupByFieldX.id]: mockGroupByFieldX,
[mockGroupByFieldXText.id]: mockGroupByFieldXText,
[mockGroupByFieldY.id]: mockGroupByFieldY,
[mockAggregateField.id]: mockAggregateField,
byUniversalIdentifier: {
'group-by-field-x-universal-id': {
...mockGroupByFieldX,
universalIdentifier: 'group-by-field-x-universal-id',
},
'group-by-field-x-text-universal-id': {
...mockGroupByFieldXText,
universalIdentifier: 'group-by-field-x-text-universal-id',
},
'group-by-field-y-universal-id': {
...mockGroupByFieldY,
universalIdentifier: 'group-by-field-y-universal-id',
},
'aggregate-field-universal-id': {
...mockAggregateField,
universalIdentifier: 'aggregate-field-universal-id',
},
},
universalIdentifierById: {
[mockGroupByFieldX.id]: 'group-by-field-x-universal-id',
[mockGroupByFieldXText.id]:
'group-by-field-x-text-universal-id',
[mockGroupByFieldY.id]: 'group-by-field-y-universal-id',
[mockAggregateField.id]: 'aggregate-field-universal-id',
},
universalIdentifiersByApplicationId: {},
},
}),
},
@@ -56,14 +56,38 @@ describe('PieChartDataService', () => {
mockExecuteGroupByQuery = jest.fn();
mockGetOrRecomputeManyOrAllFlatEntityMaps = jest.fn().mockResolvedValue({
flatObjectMetadataMaps: {
byId: { [objectMetadataId]: mockObjectMetadata },
byUniversalIdentifier: {
'test-object-universal-id': {
...mockObjectMetadata,
universalIdentifier: 'test-object-universal-id',
},
},
universalIdentifierById: {
[objectMetadataId]: 'test-object-universal-id',
},
universalIdentifiersByApplicationId: {},
},
flatFieldMetadataMaps: {
byId: {
[mockGroupByField.id]: mockGroupByField,
[mockSelectField.id]: mockSelectField,
[mockAggregateField.id]: mockAggregateField,
byUniversalIdentifier: {
'group-by-field-universal-id': {
...mockGroupByField,
universalIdentifier: 'group-by-field-universal-id',
},
'select-field-universal-id': {
...mockSelectField,
universalIdentifier: 'select-field-universal-id',
},
'aggregate-field-universal-id': {
...mockAggregateField,
universalIdentifier: 'aggregate-field-universal-id',
},
},
universalIdentifierById: {
[mockGroupByField.id]: 'group-by-field-universal-id',
[mockSelectField.id]: 'select-field-universal-id',
[mockAggregateField.id]: 'aggregate-field-universal-id',
},
universalIdentifiersByApplicationId: {},
},
});
@@ -244,13 +268,33 @@ describe('PieChartDataService', () => {
it('should format select field values using option labels', async () => {
mockGetOrRecomputeManyOrAllFlatEntityMaps.mockResolvedValue({
flatObjectMetadataMaps: {
byId: { [objectMetadataId]: mockObjectMetadata },
byUniversalIdentifier: {
'test-object-universal-id': {
...mockObjectMetadata,
universalIdentifier: 'test-object-universal-id',
},
},
universalIdentifierById: {
[objectMetadataId]: 'test-object-universal-id',
},
universalIdentifiersByApplicationId: {},
},
flatFieldMetadataMaps: {
byId: {
[mockSelectField.id]: mockSelectField,
[mockAggregateField.id]: mockAggregateField,
byUniversalIdentifier: {
'select-field-universal-id': {
...mockSelectField,
universalIdentifier: 'select-field-universal-id',
},
'aggregate-field-universal-id': {
...mockAggregateField,
universalIdentifier: 'aggregate-field-universal-id',
},
},
universalIdentifierById: {
[mockSelectField.id]: 'select-field-universal-id',
[mockAggregateField.id]: 'aggregate-field-universal-id',
},
universalIdentifiersByApplicationId: {},
},
});
@@ -293,8 +337,16 @@ describe('PieChartDataService', () => {
it('should throw when object metadata is not found', async () => {
mockGetOrRecomputeManyOrAllFlatEntityMaps.mockResolvedValue({
flatObjectMetadataMaps: { byId: {} },
flatFieldMetadataMaps: { byId: {} },
flatObjectMetadataMaps: {
byUniversalIdentifier: {},
universalIdentifierById: {},
universalIdentifiersByApplicationId: {},
},
flatFieldMetadataMaps: {
byUniversalIdentifier: {},
universalIdentifierById: {},
universalIdentifiersByApplicationId: {},
},
});
await expect(
@@ -315,9 +367,22 @@ describe('PieChartDataService', () => {
it('should throw when field metadata is not found', async () => {
mockGetOrRecomputeManyOrAllFlatEntityMaps.mockResolvedValue({
flatObjectMetadataMaps: {
byId: { [objectMetadataId]: mockObjectMetadata },
byUniversalIdentifier: {
'test-object-universal-id': {
...mockObjectMetadata,
universalIdentifier: 'test-object-universal-id',
},
},
universalIdentifierById: {
[objectMetadataId]: 'test-object-universal-id',
},
universalIdentifiersByApplicationId: {},
},
flatFieldMetadataMaps: {
byUniversalIdentifier: {},
universalIdentifierById: {},
universalIdentifiersByApplicationId: {},
},
flatFieldMetadataMaps: { byId: {} },
});
await expect(
@@ -347,13 +412,33 @@ describe('PieChartDataService', () => {
beforeEach(() => {
mockGetOrRecomputeManyOrAllFlatEntityMaps.mockResolvedValue({
flatObjectMetadataMaps: {
byId: { [objectMetadataId]: mockObjectMetadata },
byUniversalIdentifier: {
'test-object-universal-id': {
...mockObjectMetadata,
universalIdentifier: 'test-object-universal-id',
},
},
universalIdentifierById: {
[objectMetadataId]: 'test-object-universal-id',
},
universalIdentifiersByApplicationId: {},
},
flatFieldMetadataMaps: {
byId: {
[booleanField.id]: booleanField,
[mockAggregateField.id]: mockAggregateField,
byUniversalIdentifier: {
'boolean-field-universal-id': {
...booleanField,
universalIdentifier: 'boolean-field-universal-id',
},
'aggregate-field-universal-id': {
...mockAggregateField,
universalIdentifier: 'aggregate-field-universal-id',
},
},
universalIdentifierById: {
[booleanField.id]: 'boolean-field-universal-id',
[mockAggregateField.id]: 'aggregate-field-universal-id',
},
universalIdentifiersByApplicationId: {},
},
});
});
@@ -9,6 +9,7 @@ import {
} from 'twenty-shared/utils';
import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { BarChartConfigurationDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/bar-chart-configuration.dto';
@@ -78,7 +79,10 @@ export class BarChartDataService {
);
}
const flatObjectMetadata = flatObjectMetadataMaps.byId[objectMetadataId];
const flatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: objectMetadataId,
flatEntityMaps: flatObjectMetadataMaps,
});
if (!isDefined(flatObjectMetadata)) {
throw new ChartDataException(
@@ -92,12 +96,12 @@ export class BarChartDataService {
const primaryAxisGroupByField = getFieldMetadata(
configuration.primaryAxisGroupByFieldMetadataId,
flatFieldMetadataMaps.byId,
flatFieldMetadataMaps,
);
const aggregateField = getFieldMetadata(
configuration.aggregateFieldMetadataId,
flatFieldMetadataMaps.byId,
flatFieldMetadataMaps,
);
const isTwoDimensional = isDefined(
@@ -109,7 +113,7 @@ export class BarChartDataService {
if (isTwoDimensional) {
secondaryAxisGroupByField = getFieldMetadata(
configuration.secondaryAxisGroupByFieldMetadataId!,
flatFieldMetadataMaps.byId,
flatFieldMetadataMaps,
);
}
@@ -131,11 +135,11 @@ export class BarChartDataService {
const objectIdByNameSingular: Record<string, string> = {};
for (const objectId in flatObjectMetadataMaps.byId) {
const objMetadata = flatObjectMetadataMaps.byId[objectId];
for (const objMetadata of Object.values(
flatObjectMetadataMaps.byUniversalIdentifier,
)) {
if (isDefined(objMetadata)) {
objectIdByNameSingular[objMetadata.nameSingular] = objectId;
objectIdByNameSingular[objMetadata.nameSingular] = objMetadata.id;
}
}
@@ -89,12 +89,12 @@ export class ChartDataQueryService {
const primaryGroupByField = getFieldMetadata(
groupByFieldMetadataId,
flatFieldMetadataMaps.byId,
flatFieldMetadataMaps,
);
const aggregateField = getFieldMetadata(
aggregateFieldMetadataId,
flatFieldMetadataMaps.byId,
flatFieldMetadataMaps,
);
const isPrimaryFieldDate = isFieldMetadataDateKind(
@@ -146,7 +146,7 @@ export class ChartDataQueryService {
if (isDefined(secondaryGroupByFieldMetadataId)) {
const secondaryGroupByField = getFieldMetadata(
secondaryGroupByFieldMetadataId,
flatFieldMetadataMaps.byId,
flatFieldMetadataMaps,
);
const isSecondaryFieldDate = isFieldMetadataDateKind(
@@ -8,6 +8,7 @@ import {
} from 'twenty-shared/utils';
import { type AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { LineChartConfigurationDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/line-chart-configuration.dto';
@@ -77,7 +78,10 @@ export class LineChartDataService {
);
}
const flatObjectMetadata = flatObjectMetadataMaps.byId[objectMetadataId];
const flatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: objectMetadataId,
flatEntityMaps: flatObjectMetadataMaps,
});
if (!isDefined(flatObjectMetadata)) {
throw new ChartDataException(
@@ -91,12 +95,12 @@ export class LineChartDataService {
const primaryAxisGroupByField = getFieldMetadata(
configuration.primaryAxisGroupByFieldMetadataId,
flatFieldMetadataMaps.byId,
flatFieldMetadataMaps,
);
const aggregateField = getFieldMetadata(
configuration.aggregateFieldMetadataId,
flatFieldMetadataMaps.byId,
flatFieldMetadataMaps,
);
const isTwoDimensional = isDefined(
@@ -108,7 +112,7 @@ export class LineChartDataService {
if (isTwoDimensional) {
secondaryAxisGroupByField = getFieldMetadata(
configuration.secondaryAxisGroupByFieldMetadataId!,
flatFieldMetadataMaps.byId,
flatFieldMetadataMaps,
);
}
@@ -132,11 +136,11 @@ export class LineChartDataService {
const objectIdByNameSingular: Record<string, string> = {};
for (const objectId in flatObjectMetadataMaps.byId) {
const objMetadata = flatObjectMetadataMaps.byId[objectId];
for (const objMetadata of Object.values(
flatObjectMetadataMaps.byUniversalIdentifier,
)) {
if (isDefined(objMetadata)) {
objectIdByNameSingular[objMetadata.nameSingular] = objectId;
objectIdByNameSingular[objMetadata.nameSingular] = objMetadata.id;
}
}
@@ -8,6 +8,7 @@ import {
} from 'twenty-shared/utils';
import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { PieChartConfigurationDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/pie-chart-configuration.dto';
@@ -77,7 +78,10 @@ export class PieChartDataService {
);
}
const flatObjectMetadata = flatObjectMetadataMaps.byId[objectMetadataId];
const flatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: objectMetadataId,
flatEntityMaps: flatObjectMetadataMaps,
});
if (!isDefined(flatObjectMetadata)) {
throw new ChartDataException(
@@ -91,7 +95,7 @@ export class PieChartDataService {
const groupByField = getFieldMetadata(
configuration.groupByFieldMetadataId,
flatFieldMetadataMaps.byId,
flatFieldMetadataMaps,
);
const limit =
@@ -100,11 +104,11 @@ export class PieChartDataService {
const objectIdByNameSingular: Record<string, string> = {};
for (const objectId in flatObjectMetadataMaps.byId) {
const objMetadata = flatObjectMetadataMaps.byId[objectId];
for (const objMetadata of Object.values(
flatObjectMetadataMaps.byUniversalIdentifier,
)) {
if (isDefined(objMetadata)) {
objectIdByNameSingular[objMetadata.nameSingular] = objectId;
objectIdByNameSingular[objMetadata.nameSingular] = objMetadata.id;
}
}
@@ -63,19 +63,24 @@ describe('isRelationNestedFieldDateKind', () => {
});
const flatObjectMetadataMaps: FlatEntityMaps<FlatObjectMetadata> = {
byId: {
[companyObjectId]: companyObject,
byUniversalIdentifier: {
[companyObject.universalIdentifier as string]: companyObject,
},
universalIdentifierById: {
[companyObjectId]: companyObject.universalIdentifier as string,
},
idByUniversalIdentifier: {},
universalIdentifiersByApplicationId: {},
};
const flatFieldMetadataMaps: FlatEntityMaps<FlatFieldMetadata> = {
byId: {
[createdAtFieldId]: createdAtField,
[nameFieldId]: nameField,
byUniversalIdentifier: {
[createdAtField.universalIdentifier as string]: createdAtField,
[nameField.universalIdentifier as string]: nameField,
},
universalIdentifierById: {
[createdAtFieldId]: createdAtField.universalIdentifier as string,
[nameFieldId]: nameField.universalIdentifier as string,
},
idByUniversalIdentifier: {},
universalIdentifiersByApplicationId: {},
};
@@ -193,13 +198,23 @@ describe('isRelationNestedFieldDateKind', () => {
relationFieldMetadata: personRelationField,
relationNestedFieldName: 'birthDate',
flatObjectMetadataMaps: {
byId: { 'object-with-date-id': objectWithDateField },
idByUniversalIdentifier: {},
byUniversalIdentifier: {
[objectWithDateField.universalIdentifier as string]:
objectWithDateField,
},
universalIdentifierById: {
'object-with-date-id':
objectWithDateField.universalIdentifier as string,
},
universalIdentifiersByApplicationId: {},
},
flatFieldMetadataMaps: {
byId: { [dateFieldId]: dateField },
idByUniversalIdentifier: {},
byUniversalIdentifier: {
[dateField.universalIdentifier as string]: dateField,
},
universalIdentifierById: {
[dateFieldId]: dateField.universalIdentifier as string,
},
universalIdentifiersByApplicationId: {},
},
});
@@ -14,6 +14,7 @@ import {
import { type ObjectRecordFilter } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-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';
@@ -46,7 +47,10 @@ export const convertChartFilterToGqlOperationFilter = ({
const fieldIds = flatObjectMetadata.fieldIds ?? [];
const fields: PartialFieldMetadataItem[] = fieldIds
.map((fieldId: string) => {
const field = flatFieldMetadataMaps.byId[fieldId];
const field = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: fieldId,
flatEntityMaps: flatFieldMetadataMaps,
});
if (!isDefined(field)) {
return null;
@@ -70,7 +74,10 @@ export const convertChartFilterToGqlOperationFilter = ({
const convertedRecordFilters: RecordFilter[] = recordFilters.map(
(recordFilter) => {
const field = flatFieldMetadataMaps.byId[recordFilter.fieldMetadataId];
const field = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: recordFilter.fieldMetadataId,
flatEntityMaps: flatFieldMetadataMaps,
});
return {
id: recordFilter.id,
@@ -1,5 +1,7 @@
import { isDefined } from 'twenty-shared/utils';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-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 {
ChartDataException,
@@ -9,9 +11,12 @@ import {
export const getFieldMetadata = (
fieldMetadataId: string,
fieldMetadataById: Partial<Record<string, FlatFieldMetadata>>,
flatFieldMetadataMaps: FlatEntityMaps<FlatFieldMetadata>,
): FlatFieldMetadata => {
const fieldMetadata = fieldMetadataById[fieldMetadataId];
const fieldMetadata = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: fieldMetadataId,
flatEntityMaps: flatFieldMetadataMaps,
});
if (!isDefined(fieldMetadata)) {
throw new ChartDataException(
@@ -1,5 +1,6 @@
import { isDefined, isFieldMetadataDateKind } from 'twenty-shared/utils';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-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 { isMorphOrRelationFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-morph-or-relation-flat-field-metadata.util';
@@ -30,7 +31,10 @@ export const isRelationNestedFieldDateKind = ({
return false;
}
const targetObjectMetadata = flatObjectMetadataMaps.byId[targetObjectId];
const targetObjectMetadata = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: targetObjectId,
flatEntityMaps: flatObjectMetadataMaps,
});
if (!isDefined(targetObjectMetadata)) {
return false;
@@ -41,7 +45,12 @@ export const isRelationNestedFieldDateKind = ({
const targetFieldIds = targetObjectMetadata.fieldIds;
const nestedFieldMetadata = targetFieldIds
.map((fieldId: string) => flatFieldMetadataMaps.byId[fieldId])
.map((fieldId: string) =>
findFlatEntityByIdInFlatEntityMaps({
flatEntityId: fieldId,
flatEntityMaps: flatFieldMetadataMaps,
}),
)
.find(
(fieldMetadata: FlatFieldMetadata | undefined) =>
isDefined(fieldMetadata) && fieldMetadata.name === nestedFieldName,
@@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common';
import { isDefined } from 'twenty-shared/utils';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
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';
@@ -138,7 +139,10 @@ export class WorkflowCommonWorkspaceService {
);
}
const flatObjectMetadata = flatObjectMetadataMaps.byId[objectId];
const flatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: objectId,
flatEntityMaps: flatObjectMetadataMaps,
});
if (!isDefined(flatObjectMetadata)) {
throw new WorkflowCommonException(
@@ -1,5 +1,6 @@
import { isDefined } from 'twenty-shared/utils';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-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';
@@ -39,7 +40,10 @@ export const generateFakeFormResponse = ({
);
}
const flatObjectMetadata = flatObjectMetadataMaps.byId[objectId];
const flatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: objectId,
flatEntityMaps: flatObjectMetadataMaps,
});
if (!isDefined(flatObjectMetadata)) {
throw new Error(
@@ -2,6 +2,7 @@ import { isString } from 'class-validator';
import { FieldMetadataType } from 'twenty-shared/types';
import { isDefined, resolveRichTextVariables } from 'twenty-shared/utils';
import { findManyFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps.util';
import { type ObjectMetadataInfo } from 'src/modules/workflow/common/workspace-services/workflow-common.workspace-service';
export const resolveRichTextFieldsInRecord = (
@@ -11,8 +12,10 @@ export const resolveRichTextFieldsInRecord = (
): Record<string, unknown> => {
const { flatObjectMetadata, flatFieldMetadataMaps } = objectMetadataInfo;
const richTextFieldNames = flatObjectMetadata.fieldIds
.map((fieldId) => flatFieldMetadataMaps.byId[fieldId])
const richTextFieldNames = findManyFlatEntityByIdInFlatEntityMaps({
flatEntityIds: flatObjectMetadata.fieldIds,
flatEntityMaps: flatFieldMetadataMaps,
})
.filter((field) => field?.type === FieldMetadataType.RICH_TEXT_V2)
.map((field) => field?.name)
.filter(isDefined);
@@ -5,6 +5,7 @@ import { resolveInput } from 'twenty-shared/utils';
import { type WorkflowAction } from 'src/modules/workflow/workflow-executor/interfaces/workflow-action.interface';
import { LogicFunctionExecutorService } from 'src/engine/core-modules/logic-function/logic-function-executor/services/logic-function-executor.service';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
import {
WorkflowStepExecutorException,
@@ -57,8 +58,10 @@ export class LogicFunctionWorkflowAction implements WorkflowAction {
},
);
const logicFunction =
flatLogicFunctionMaps.byId[workflowActionInput.logicFunctionId];
const logicFunction = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: workflowActionInput.logicFunctionId,
flatEntityMaps: flatLogicFunctionMaps,
});
if (!logicFunction) {
throw new WorkflowStepExecutorException(
@@ -17,6 +17,7 @@ import {
RecordCrudExceptionCode,
} from 'src/engine/core-modules/record-crud/exceptions/record-crud.exception';
import { FindRecordsService } from 'src/engine/core-modules/record-crud/services/find-records.service';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { WorkflowCommonWorkspaceService } from 'src/modules/workflow/common/workspace-services/workflow-common.workspace-service';
import {
WorkflowStepExecutorException,
@@ -73,7 +74,10 @@ export class FindRecordsWorkflowAction implements WorkflowAction {
const fields = flatObjectMetadata.fieldIds
.map((fieldId) => {
const field = flatFieldMetadataMaps.byId[fieldId];
const field = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: fieldId,
flatEntityMaps: flatFieldMetadataMaps,
});
if (!field) {
return null;
@@ -18,6 +18,7 @@ import { InjectMessageQueue } from 'src/engine/core-modules/message-queue/decora
import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants';
import { MessageQueueService } from 'src/engine/core-modules/message-queue/services/message-queue.service';
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { buildFieldMapsFromFlatObjectMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/build-field-maps-from-flat-object-metadata.util';
@@ -277,7 +278,10 @@ export class WorkflowDatabaseEventTriggerListener {
}
const relatedObjectMetadataNameSingular =
flatObjectMetadataMaps.byId[relatedObjectMetadataId]?.nameSingular;
findFlatEntityByIdInFlatEntityMaps({
flatEntityId: relatedObjectMetadataId,
flatEntityMaps: flatObjectMetadataMaps,
})?.nameSingular;
if (!isDefined(relatedObjectMetadataNameSingular)) {
continue;