Migrate agent v2 (#16214)

# Introduction
Closes https://github.com/twentyhq/core-team-issues/issues/1980

In this PR we migrate the agent from v1 to v2.

## New FlatRoleTargetByAgentIdMaps
Derivated the `flatRoleTargetMaps` to be building a
`flatRoleTargetByAgentIdMaps` to ease retrieving a roleId to associate
to an agent

## Coverage
Added strong coverage on both failing and successful CRU agents
operations

---------

Co-authored-by: Weiko <corentin@twenty.com>
This commit is contained in:
Paul Rastoin
2025-12-03 11:51:19 +01:00
committed by GitHub
parent a7c5969ede
commit 59672e3e34
110 changed files with 4864 additions and 849 deletions
@@ -2,6 +2,7 @@ import { type ObjectsPermissionsByRoleId } from 'twenty-shared/types';
import { type FlatApplicationCacheMaps } from 'src/engine/core-modules/application/types/flat-application-cache-maps.type';
import { type FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { type FlatRoleTargetByAgentIdMaps } from 'src/engine/metadata-modules/flat-agent/types/flat-role-target-by-agent-id-maps.type';
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
import { type UserWorkspaceRoleMap } from 'src/engine/metadata-modules/role-target/services/workspace-user-workspace-role-map-cache.service';
@@ -24,6 +25,8 @@ export const WORKSPACE_CACHE_KEYS_V2 = {
flatApplicationMaps: 'flat-maps:flatApplicationMaps',
flatRoleMaps: 'flat-maps:role',
flatRoleTargetMaps: 'flat-maps:role-target',
flatAgentMaps: 'flat-maps:agent',
flatRoleTargetByAgentIdMaps: 'flat-maps:flatRoleTargetByAgentId',
} as const satisfies Record<WorkspaceCacheKeyName, string>;
type AdditionalCacheDataMap = {
@@ -32,6 +35,7 @@ type AdditionalCacheDataMap = {
userWorkspaceRoleMap: UserWorkspaceRoleMap;
apiKeyRoleMap: Record<string, string>;
flatApplicationMaps: FlatApplicationCacheMaps;
flatRoleTargetByAgentIdMaps: FlatRoleTargetByAgentIdMaps;
};
export type WorkspaceCacheDataMap = AllFlatEntityMaps & AdditionalCacheDataMap;
@@ -0,0 +1,39 @@
import { isDefined } from 'class-validator';
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type MetadataEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-entity.type';
import { type MetadataManyToOneJoinColumn } from 'src/engine/metadata-modules/flat-entity/types/metadata-many-to-one-join-column.type';
export type RegroupEntitiesByRelatedEntityIdArgs<T extends AllMetadataName> =
MetadataManyToOneJoinColumn<T> extends never
? never
: {
entities: MetadataEntity<T>[];
foreignKey: MetadataManyToOneJoinColumn<T>;
};
export const regroupEntitiesByRelatedEntityId = <T extends AllMetadataName>({
entities,
foreignKey,
}: RegroupEntitiesByRelatedEntityIdArgs<T>) => {
const entitiesByRelatedEntityId = new Map<string, { id: string }[]>();
for (const entity of entities) {
const currentRelatedEntityId = entity[
foreignKey as keyof MetadataEntity<T>
] as string;
if (!isDefined(currentRelatedEntityId)) {
continue;
}
if (!entitiesByRelatedEntityId.has(currentRelatedEntityId)) {
entitiesByRelatedEntityId.set(currentRelatedEntityId, []);
}
entitiesByRelatedEntityId
.get(currentRelatedEntityId)!
.push({ id: entity.id });
}
return entitiesByRelatedEntityId;
};