diff --git a/packages/twenty-server/src/engine/api/common/common-query-runners/common-base-query-runner.service.ts b/packages/twenty-server/src/engine/api/common/common-query-runners/common-base-query-runner.service.ts index 8358c1299a..92d039d704 100644 --- a/packages/twenty-server/src/engine/api/common/common-query-runners/common-base-query-runner.service.ts +++ b/packages/twenty-server/src/engine/api/common/common-query-runners/common-base-query-runner.service.ts @@ -134,7 +134,7 @@ export abstract class CommonBaseQueryRunnerService< if (isGlobalDatasourceEnabled) { return this.globalWorkspaceOrmManager.executeInWorkspaceContext( - authContext.workspace.id, + authContext, async () => this.executeQueryAndEnrichResults( processedArgs, diff --git a/packages/twenty-server/src/engine/twenty-orm/global-workspace-datasource/global-workspace-datasource.ts b/packages/twenty-server/src/engine/twenty-orm/global-workspace-datasource/global-workspace-datasource.ts index 58182579c4..d77707a7d6 100644 --- a/packages/twenty-server/src/engine/twenty-orm/global-workspace-datasource/global-workspace-datasource.ts +++ b/packages/twenty-server/src/engine/twenty-orm/global-workspace-datasource/global-workspace-datasource.ts @@ -16,10 +16,9 @@ import { EntitySchemaTransformer } from 'typeorm/entity-schema/EntitySchemaTrans import { EntityMetadataNotFoundError } from 'typeorm/error/EntityMetadataNotFoundError'; import { EntityMetadataBuilder } from 'typeorm/metadata-builder/EntityMetadataBuilder'; +import { type WorkspaceAuthContext } from 'src/engine/api/common/interfaces/workspace-auth-context.interface'; import { type FeatureFlagMap } from 'src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface'; -import { type WorkspaceInternalContext } from 'src/engine/twenty-orm/interfaces/workspace-internal-context.interface'; -import { type AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type'; import { PermissionsException, PermissionsExceptionCode, @@ -67,6 +66,12 @@ export class GlobalWorkspaceDataSource extends DataSource { }); } + get authContext(): WorkspaceAuthContext { + const context = getWorkspaceContext(); + + return context.authContext; + } + get featureFlagMap(): FeatureFlagMap { const context = getWorkspaceContext(); @@ -82,18 +87,18 @@ export class GlobalWorkspaceDataSource extends DataSource { override getRepository( target: EntityTarget, permissionOptions?: RolePermissionConfig, - authContext?: AuthContext, ): WorkspaceRepository { const manager = this.createEntityManager(); - return manager.getRepository(target, permissionOptions, authContext); + return manager.getRepository(target, permissionOptions, this.authContext); } override findMetadata( target: EntityTarget, ): EntityMetadata | undefined { const context = getWorkspaceContext(); - const { workspaceId, metadataVersion } = context; + const { authContext, metadataVersion } = context; + const workspaceId = authContext.workspace.id; const cacheKey = `${workspaceId}-${metadataVersion}`; const cachedEntityMetadata = this.getCachedEntityMetadata(cacheKey); @@ -123,12 +128,17 @@ export class GlobalWorkspaceDataSource extends DataSource { } const context = getWorkspaceContext(); - const fullContext: WorkspaceInternalContext = { - ...context, - eventEmitterService: this.eventEmitterService, - }; - return new WorkspaceEntityManager(fullContext, this, queryRunner); + return new WorkspaceEntityManager( + { + workspaceId: context.authContext.workspace.id, + objectMetadataMaps: context.objectMetadataMaps, + featureFlagsMap: context.featureFlagsMap, + eventEmitterService: this.eventEmitterService, + }, + this, + queryRunner, + ); } override createQueryRunner( diff --git a/packages/twenty-server/src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager.ts b/packages/twenty-server/src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager.ts index 9517d4534b..f8c6f179c9 100644 --- a/packages/twenty-server/src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager.ts +++ b/packages/twenty-server/src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager.ts @@ -2,13 +2,15 @@ import { Injectable, type Type } from '@nestjs/common'; import { type ObjectLiteral } from 'typeorm'; +import { WorkspaceAuthContext } from 'src/engine/api/common/interfaces/workspace-auth-context.interface'; + import { WorkspaceFeatureFlagsMapCacheService } from 'src/engine/metadata-modules/workspace-feature-flags-map-cache/workspace-feature-flags-map-cache.service'; import { WorkspaceMetadataCacheService } from 'src/engine/metadata-modules/workspace-metadata-cache/services/workspace-metadata-cache.service'; import { WorkspacePermissionsCacheService } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.service'; import { GlobalWorkspaceDataSourceService } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-datasource.service'; import { type WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository'; import { - type WorkspaceContextForStorage, + type WorkspaceContext, withWorkspaceContext, } from 'src/engine/twenty-orm/storage/workspace-context.storage'; import { type RolePermissionConfig } from 'src/engine/twenty-orm/types/role-permission-config'; @@ -64,21 +66,21 @@ export class GlobalWorkspaceOrmManager { } async executeInWorkspaceContext( - workspaceId: string, + authContext: WorkspaceAuthContext, fn: () => T | Promise, ): Promise { - const context = await this.loadWorkspaceContext(workspaceId); + const context = await this.loadWorkspaceContext(authContext); const globalDataSource = this.globalWorkspaceDataSourceService.getGlobalWorkspaceDataSource(); if ( !globalDataSource.hasWorkspaceEntityMetadataCacheForVersion( - workspaceId, + authContext.workspace.id, context.metadataVersion, ) ) { await globalDataSource.buildWorkspaceMetadata( - workspaceId, + authContext.workspace.id, context.metadataVersion, context.objectMetadataMaps, ); @@ -88,8 +90,9 @@ export class GlobalWorkspaceOrmManager { } private async loadWorkspaceContext( - workspaceId: string, - ): Promise { + authContext: WorkspaceAuthContext, + ): Promise { + const workspaceId = authContext.workspace.id; const { objectMetadataMaps, metadataVersion } = await this.workspaceMetadataCacheService.getExistingOrRecomputeMetadataMaps( { @@ -108,7 +111,7 @@ export class GlobalWorkspaceOrmManager { }); return { - workspaceId, + authContext, objectMetadataMaps, metadataVersion, featureFlagsMap, diff --git a/packages/twenty-server/src/engine/twenty-orm/storage/workspace-context.storage.ts b/packages/twenty-server/src/engine/twenty-orm/storage/workspace-context.storage.ts index fbb924a7cf..fc77c58407 100644 --- a/packages/twenty-server/src/engine/twenty-orm/storage/workspace-context.storage.ts +++ b/packages/twenty-server/src/engine/twenty-orm/storage/workspace-context.storage.ts @@ -2,11 +2,13 @@ import { AsyncLocalStorage } from 'async_hooks'; import { type ObjectsPermissionsByRoleId } from 'twenty-shared/types'; +import { type WorkspaceAuthContext } from 'src/engine/api/common/interfaces/workspace-auth-context.interface'; + import { type FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; import { type ObjectMetadataMaps } from 'src/engine/metadata-modules/types/object-metadata-maps'; -export type WorkspaceContextForStorage = { - workspaceId: string; +export type WorkspaceContext = { + authContext: WorkspaceAuthContext; objectMetadataMaps: ObjectMetadataMaps; metadataVersion: number; featureFlagsMap: Record; @@ -14,9 +16,9 @@ export type WorkspaceContextForStorage = { }; export const workspaceContextStorage = - new AsyncLocalStorage(); + new AsyncLocalStorage(); -export const getWorkspaceContext = (): WorkspaceContextForStorage => { +export const getWorkspaceContext = (): WorkspaceContext => { const context = workspaceContextStorage.getStore(); if (!context) { @@ -29,14 +31,12 @@ export const getWorkspaceContext = (): WorkspaceContextForStorage => { }; export const withWorkspaceContext = ( - context: WorkspaceContextForStorage, + context: WorkspaceContext, fn: () => T | Promise, ): T | Promise => { return workspaceContextStorage.run(context, fn); }; -export const setWorkspaceContext = ( - context: WorkspaceContextForStorage, -): void => { +export const setWorkspaceContext = (context: WorkspaceContext): void => { workspaceContextStorage.enterWith(context); };