Factorize from entity to flat entity utils (#21972)
## What Factorizes the two responsibilities that were copy‑pasted across every `from-<entity>-entity-to-flat-<entity>` util into two reusable tools. ### `fromEntityToScalarEntity` Projects a TypeORM entity into its scalar flat shape using an **allow‑list** driven by `ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME` (plus the base columns `id`/`workspaceId`/`applicationId`/`universalIdentifier`). Only registered scalar columns are forwarded, `Date`s are serialized to ISO strings, and absent values are normalized to `null`. Replaces the previous deny‑list (`removePropertiesFromRecord`) approach, so unregistered/deprecated columns can no longer silently leak into the flat entity. ### `resolveManyToOneRelationIdsToUniversalIdentifiers` Resolves an entity's many‑to‑one foreign keys to their universal identifiers, driven by `ALL_MANY_TO_ONE_METADATA_RELATIONS`. Handles the always‑present `application`, nullable relations, and throws a `FlatEntityMapsException` when a referenced id is missing from its identifier map. Mirrors `resolveUniversalRelationIdentifiersToIds` in the opposite direction. Each `from-<entity>` util now reduces to: scalar spread + relation spread (+ explicit one‑to‑many id/universalIdentifier arrays where applicable). ### Note The allow‑list drops `isUIReadOnly` (a `WasRemovedInUpgrade` column not in the config) from `fieldMetadata`, which is the only integration‑snapshot change. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21972?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. -->
This commit is contained in:
-11
@@ -1,11 +0,0 @@
|
||||
/* @license Enterprise */
|
||||
|
||||
export const ROW_LEVEL_PERMISSION_PREDICATE_ENTITY_RELATION_PROPERTIES = [
|
||||
'workspace',
|
||||
'role',
|
||||
'fieldMetadata',
|
||||
'workspaceMemberFieldMetadata',
|
||||
'objectMetadata',
|
||||
'rowLevelPermissionPredicateGroup',
|
||||
'application',
|
||||
] as const;
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
/* @license Enterprise */
|
||||
|
||||
export const ROW_LEVEL_PERMISSION_PREDICATE_GROUP_ENTITY_RELATION_PROPERTIES = [
|
||||
'workspace',
|
||||
'role',
|
||||
'parentRowLevelPermissionPredicateGroup',
|
||||
'childRowLevelPermissionPredicateGroups',
|
||||
'rowLevelPermissionPredicates',
|
||||
'application',
|
||||
] as const;
|
||||
+17
-118
@@ -1,130 +1,29 @@
|
||||
/* @license Enterprise */
|
||||
|
||||
import { isDefined, removePropertiesFromRecord } from 'twenty-shared/utils';
|
||||
|
||||
import {
|
||||
FlatEntityMapsException,
|
||||
FlatEntityMapsExceptionCode,
|
||||
} from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception';
|
||||
import { ROW_LEVEL_PERMISSION_PREDICATE_ENTITY_RELATION_PROPERTIES } from 'src/engine/metadata-modules/flat-row-level-permission-predicate/constants/row-level-permission-predicate-entity-relation-properties.constant';
|
||||
import { fromEntityToScalarEntity } from 'src/engine/metadata-modules/flat-entity/utils/from-entity-to-scalar-entity.util';
|
||||
import { type FlatRowLevelPermissionPredicate } from 'src/engine/metadata-modules/row-level-permission-predicate/types/flat-row-level-permission-predicate.type';
|
||||
import { type FromEntityToFlatEntityArgs } from 'src/engine/workspace-cache/types/from-entity-to-flat-entity-args.type';
|
||||
import { resolveManyToOneRelationIdsToUniversalIdentifiers } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/resolve-many-to-one-relation-ids-to-universal-identifiers.util';
|
||||
|
||||
export const fromRowLevelPermissionPredicateEntityToFlatRowLevelPermissionPredicate =
|
||||
({
|
||||
entity: rowLevelPermissionPredicateEntity,
|
||||
applicationIdToUniversalIdentifierMap,
|
||||
fieldMetadataIdToUniversalIdentifierMap,
|
||||
objectMetadataIdToUniversalIdentifierMap,
|
||||
roleIdToUniversalIdentifierMap,
|
||||
rowLevelPermissionPredicateGroupIdToUniversalIdentifierMap,
|
||||
}: FromEntityToFlatEntityArgs<'rowLevelPermissionPredicate'>): FlatRowLevelPermissionPredicate => {
|
||||
const rowLevelPermissionPredicateEntityWithoutRelations =
|
||||
removePropertiesFromRecord(rowLevelPermissionPredicateEntity, [
|
||||
...ROW_LEVEL_PERMISSION_PREDICATE_ENTITY_RELATION_PROPERTIES,
|
||||
] as (typeof ROW_LEVEL_PERMISSION_PREDICATE_ENTITY_RELATION_PROPERTIES)[number][]);
|
||||
(
|
||||
args: FromEntityToFlatEntityArgs<'rowLevelPermissionPredicate'>,
|
||||
): FlatRowLevelPermissionPredicate => {
|
||||
const { entity: rowLevelPermissionPredicateEntity } = args;
|
||||
|
||||
const applicationUniversalIdentifier =
|
||||
applicationIdToUniversalIdentifierMap.get(
|
||||
rowLevelPermissionPredicateEntity.applicationId,
|
||||
);
|
||||
const rowLevelPermissionPredicateScalarEntity = fromEntityToScalarEntity({
|
||||
metadataName: 'rowLevelPermissionPredicate',
|
||||
entity: rowLevelPermissionPredicateEntity,
|
||||
});
|
||||
|
||||
if (!isDefined(applicationUniversalIdentifier)) {
|
||||
throw new FlatEntityMapsException(
|
||||
`Application with id ${rowLevelPermissionPredicateEntity.applicationId} not found for rowLevelPermissionPredicate ${rowLevelPermissionPredicateEntity.id}`,
|
||||
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
const fieldMetadataUniversalIdentifier =
|
||||
fieldMetadataIdToUniversalIdentifierMap.get(
|
||||
rowLevelPermissionPredicateEntity.fieldMetadataId,
|
||||
);
|
||||
|
||||
if (!isDefined(fieldMetadataUniversalIdentifier)) {
|
||||
throw new FlatEntityMapsException(
|
||||
`FieldMetadata with id ${rowLevelPermissionPredicateEntity.fieldMetadataId} not found for rowLevelPermissionPredicate ${rowLevelPermissionPredicateEntity.id}`,
|
||||
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
const objectMetadataUniversalIdentifier =
|
||||
objectMetadataIdToUniversalIdentifierMap.get(
|
||||
rowLevelPermissionPredicateEntity.objectMetadataId,
|
||||
);
|
||||
|
||||
if (!isDefined(objectMetadataUniversalIdentifier)) {
|
||||
throw new FlatEntityMapsException(
|
||||
`ObjectMetadata with id ${rowLevelPermissionPredicateEntity.objectMetadataId} not found for rowLevelPermissionPredicate ${rowLevelPermissionPredicateEntity.id}`,
|
||||
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
const roleUniversalIdentifier = roleIdToUniversalIdentifierMap.get(
|
||||
rowLevelPermissionPredicateEntity.roleId,
|
||||
);
|
||||
|
||||
if (!isDefined(roleUniversalIdentifier)) {
|
||||
throw new FlatEntityMapsException(
|
||||
`Role with id ${rowLevelPermissionPredicateEntity.roleId} not found for rowLevelPermissionPredicate ${rowLevelPermissionPredicateEntity.id}`,
|
||||
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
let workspaceMemberFieldMetadataUniversalIdentifier: string | null = null;
|
||||
|
||||
if (
|
||||
isDefined(
|
||||
rowLevelPermissionPredicateEntity.workspaceMemberFieldMetadataId,
|
||||
)
|
||||
) {
|
||||
workspaceMemberFieldMetadataUniversalIdentifier =
|
||||
fieldMetadataIdToUniversalIdentifierMap.get(
|
||||
rowLevelPermissionPredicateEntity.workspaceMemberFieldMetadataId,
|
||||
) ?? null;
|
||||
|
||||
if (!isDefined(workspaceMemberFieldMetadataUniversalIdentifier)) {
|
||||
throw new FlatEntityMapsException(
|
||||
`FieldMetadata with id ${rowLevelPermissionPredicateEntity.workspaceMemberFieldMetadataId} not found for rowLevelPermissionPredicate ${rowLevelPermissionPredicateEntity.id}`,
|
||||
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let rowLevelPermissionPredicateGroupUniversalIdentifier: string | null =
|
||||
null;
|
||||
|
||||
if (
|
||||
isDefined(
|
||||
rowLevelPermissionPredicateEntity.rowLevelPermissionPredicateGroupId,
|
||||
)
|
||||
) {
|
||||
rowLevelPermissionPredicateGroupUniversalIdentifier =
|
||||
rowLevelPermissionPredicateGroupIdToUniversalIdentifierMap.get(
|
||||
rowLevelPermissionPredicateEntity.rowLevelPermissionPredicateGroupId,
|
||||
) ?? null;
|
||||
|
||||
if (!isDefined(rowLevelPermissionPredicateGroupUniversalIdentifier)) {
|
||||
throw new FlatEntityMapsException(
|
||||
`RowLevelPermissionPredicateGroup with id ${rowLevelPermissionPredicateEntity.rowLevelPermissionPredicateGroupId} not found for rowLevelPermissionPredicate ${rowLevelPermissionPredicateEntity.id}`,
|
||||
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
}
|
||||
const relationUniversalIdentifiers =
|
||||
resolveManyToOneRelationIdsToUniversalIdentifiers({
|
||||
metadataName: 'rowLevelPermissionPredicate',
|
||||
...args,
|
||||
});
|
||||
|
||||
return {
|
||||
...rowLevelPermissionPredicateEntityWithoutRelations,
|
||||
createdAt: rowLevelPermissionPredicateEntity.createdAt.toISOString(),
|
||||
updatedAt: rowLevelPermissionPredicateEntity.updatedAt.toISOString(),
|
||||
deletedAt:
|
||||
rowLevelPermissionPredicateEntity.deletedAt?.toISOString() ?? null,
|
||||
universalIdentifier:
|
||||
rowLevelPermissionPredicateEntityWithoutRelations.universalIdentifier,
|
||||
applicationUniversalIdentifier,
|
||||
fieldMetadataUniversalIdentifier,
|
||||
objectMetadataUniversalIdentifier,
|
||||
roleUniversalIdentifier,
|
||||
workspaceMemberFieldMetadataUniversalIdentifier,
|
||||
rowLevelPermissionPredicateGroupUniversalIdentifier,
|
||||
...rowLevelPermissionPredicateScalarEntity,
|
||||
...relationUniversalIdentifiers,
|
||||
};
|
||||
};
|
||||
|
||||
+18
-94
@@ -1,103 +1,31 @@
|
||||
/* @license Enterprise */
|
||||
|
||||
import { isDefined, removePropertiesFromRecord } from 'twenty-shared/utils';
|
||||
|
||||
import {
|
||||
FlatEntityMapsException,
|
||||
FlatEntityMapsExceptionCode,
|
||||
} from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception';
|
||||
import { ROW_LEVEL_PERMISSION_PREDICATE_GROUP_ENTITY_RELATION_PROPERTIES } from 'src/engine/metadata-modules/flat-row-level-permission-predicate/constants/row-level-permission-predicate-group-entity-relation-properties.constant';
|
||||
import { fromEntityToScalarEntity } from 'src/engine/metadata-modules/flat-entity/utils/from-entity-to-scalar-entity.util';
|
||||
import { type FlatRowLevelPermissionPredicateGroup } from 'src/engine/metadata-modules/row-level-permission-predicate/types/flat-row-level-permission-predicate-group.type';
|
||||
import { type FromEntityToFlatEntityArgs } from 'src/engine/workspace-cache/types/from-entity-to-flat-entity-args.type';
|
||||
|
||||
type FromRowLevelPermissionPredicateGroupEntityToFlatRowLevelPermissionPredicateGroupArgs =
|
||||
FromEntityToFlatEntityArgs<'rowLevelPermissionPredicateGroup'> & {
|
||||
rowLevelPermissionPredicateGroupIdToUniversalIdentifierMap: Map<
|
||||
string,
|
||||
string
|
||||
>;
|
||||
};
|
||||
import { resolveManyToOneRelationIdsToUniversalIdentifiers } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/resolve-many-to-one-relation-ids-to-universal-identifiers.util';
|
||||
|
||||
export const fromRowLevelPermissionPredicateGroupEntityToFlatRowLevelPermissionPredicateGroup =
|
||||
({
|
||||
entity: rowLevelPermissionPredicateGroupEntity,
|
||||
applicationIdToUniversalIdentifierMap,
|
||||
objectMetadataIdToUniversalIdentifierMap,
|
||||
roleIdToUniversalIdentifierMap,
|
||||
rowLevelPermissionPredicateGroupIdToUniversalIdentifierMap,
|
||||
}: FromRowLevelPermissionPredicateGroupEntityToFlatRowLevelPermissionPredicateGroupArgs): FlatRowLevelPermissionPredicateGroup => {
|
||||
const rowLevelPermissionPredicateGroupEntityWithoutRelations =
|
||||
removePropertiesFromRecord(rowLevelPermissionPredicateGroupEntity, [
|
||||
...ROW_LEVEL_PERMISSION_PREDICATE_GROUP_ENTITY_RELATION_PROPERTIES,
|
||||
] as (typeof ROW_LEVEL_PERMISSION_PREDICATE_GROUP_ENTITY_RELATION_PROPERTIES)[number][]);
|
||||
(
|
||||
args: FromEntityToFlatEntityArgs<'rowLevelPermissionPredicateGroup'>,
|
||||
): FlatRowLevelPermissionPredicateGroup => {
|
||||
const { entity: rowLevelPermissionPredicateGroupEntity } = args;
|
||||
|
||||
const applicationUniversalIdentifier =
|
||||
applicationIdToUniversalIdentifierMap.get(
|
||||
rowLevelPermissionPredicateGroupEntity.applicationId,
|
||||
);
|
||||
const rowLevelPermissionPredicateGroupScalarEntity =
|
||||
fromEntityToScalarEntity({
|
||||
metadataName: 'rowLevelPermissionPredicateGroup',
|
||||
entity: rowLevelPermissionPredicateGroupEntity,
|
||||
});
|
||||
|
||||
if (!isDefined(applicationUniversalIdentifier)) {
|
||||
throw new FlatEntityMapsException(
|
||||
`Application with id ${rowLevelPermissionPredicateGroupEntity.applicationId} not found for rowLevelPermissionPredicateGroup ${rowLevelPermissionPredicateGroupEntity.id}`,
|
||||
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
const objectMetadataUniversalIdentifier =
|
||||
objectMetadataIdToUniversalIdentifierMap.get(
|
||||
rowLevelPermissionPredicateGroupEntity.objectMetadataId,
|
||||
);
|
||||
|
||||
if (!isDefined(objectMetadataUniversalIdentifier)) {
|
||||
throw new FlatEntityMapsException(
|
||||
`ObjectMetadata with id ${rowLevelPermissionPredicateGroupEntity.objectMetadataId} not found for rowLevelPermissionPredicateGroup ${rowLevelPermissionPredicateGroupEntity.id}`,
|
||||
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
const roleUniversalIdentifier = roleIdToUniversalIdentifierMap.get(
|
||||
rowLevelPermissionPredicateGroupEntity.roleId,
|
||||
);
|
||||
|
||||
if (!isDefined(roleUniversalIdentifier)) {
|
||||
throw new FlatEntityMapsException(
|
||||
`Role with id ${rowLevelPermissionPredicateGroupEntity.roleId} not found for rowLevelPermissionPredicateGroup ${rowLevelPermissionPredicateGroupEntity.id}`,
|
||||
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
let parentRowLevelPermissionPredicateGroupUniversalIdentifier:
|
||||
| string
|
||||
| null = null;
|
||||
|
||||
if (
|
||||
isDefined(
|
||||
rowLevelPermissionPredicateGroupEntity.parentRowLevelPermissionPredicateGroupId,
|
||||
)
|
||||
) {
|
||||
parentRowLevelPermissionPredicateGroupUniversalIdentifier =
|
||||
rowLevelPermissionPredicateGroupIdToUniversalIdentifierMap.get(
|
||||
rowLevelPermissionPredicateGroupEntity.parentRowLevelPermissionPredicateGroupId,
|
||||
) ?? null;
|
||||
|
||||
if (
|
||||
!isDefined(parentRowLevelPermissionPredicateGroupUniversalIdentifier)
|
||||
) {
|
||||
throw new FlatEntityMapsException(
|
||||
`RowLevelPermissionPredicateGroup with id ${rowLevelPermissionPredicateGroupEntity.parentRowLevelPermissionPredicateGroupId} not found for rowLevelPermissionPredicateGroup ${rowLevelPermissionPredicateGroupEntity.id}`,
|
||||
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
}
|
||||
const relationUniversalIdentifiers =
|
||||
resolveManyToOneRelationIdsToUniversalIdentifiers({
|
||||
metadataName: 'rowLevelPermissionPredicateGroup',
|
||||
...args,
|
||||
});
|
||||
|
||||
return {
|
||||
...rowLevelPermissionPredicateGroupEntityWithoutRelations,
|
||||
createdAt: rowLevelPermissionPredicateGroupEntity.createdAt.toISOString(),
|
||||
updatedAt: rowLevelPermissionPredicateGroupEntity.updatedAt.toISOString(),
|
||||
deletedAt:
|
||||
rowLevelPermissionPredicateGroupEntity.deletedAt?.toISOString() ?? null,
|
||||
universalIdentifier:
|
||||
rowLevelPermissionPredicateGroupEntityWithoutRelations.universalIdentifier,
|
||||
...rowLevelPermissionPredicateGroupScalarEntity,
|
||||
...relationUniversalIdentifiers,
|
||||
childRowLevelPermissionPredicateGroupIds: (
|
||||
rowLevelPermissionPredicateGroupEntity.childRowLevelPermissionPredicateGroups ??
|
||||
[]
|
||||
@@ -106,10 +34,6 @@ export const fromRowLevelPermissionPredicateGroupEntityToFlatRowLevelPermissionP
|
||||
rowLevelPermissionPredicateGroupEntity.rowLevelPermissionPredicates ??
|
||||
[]
|
||||
).map(({ id }) => id),
|
||||
applicationUniversalIdentifier,
|
||||
objectMetadataUniversalIdentifier,
|
||||
roleUniversalIdentifier,
|
||||
parentRowLevelPermissionPredicateGroupUniversalIdentifier,
|
||||
childRowLevelPermissionPredicateGroupUniversalIdentifiers: (
|
||||
rowLevelPermissionPredicateGroupEntity.childRowLevelPermissionPredicateGroups ??
|
||||
[]
|
||||
|
||||
Reference in New Issue
Block a user