Rename roleTargets -> roleTarget (#16247)

This commit is contained in:
Weiko
2025-12-02 14:39:54 +01:00
committed by GitHub
parent 9cfcc114de
commit 13e283fc3a
82 changed files with 390 additions and 334 deletions
@@ -8,7 +8,7 @@ import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/worksp
import { UserWorkspaceEntity } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
@Command({
@@ -19,8 +19,8 @@ import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.
export class CleanOrphanedRoleTargetsCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner {
private hasRunOnce = false;
constructor(
@InjectRepository(RoleTargetsEntity)
private readonly roleTargetsRepository: Repository<RoleTargetsEntity>,
@InjectRepository(RoleTargetEntity)
private readonly roleTargetRepository: Repository<RoleTargetEntity>,
@InjectRepository(WorkspaceEntity)
protected readonly workspaceRepository: Repository<WorkspaceEntity>,
protected readonly twentyORMGlobalManager: TwentyORMGlobalManager,
@@ -43,7 +43,7 @@ export class CleanOrphanedRoleTargetsCommand extends ActiveOrSuspendedWorkspaces
this.logger.log('Dry run mode: No changes will be applied');
}
const orphanedRoleTargets = await this.roleTargetsRepository
const orphanedRoleTargets = await this.roleTargetRepository
.createQueryBuilder('roleTarget')
.leftJoin(
UserWorkspaceEntity,
@@ -82,7 +82,7 @@ export class CleanOrphanedRoleTargetsCommand extends ActiveOrSuspendedWorkspaces
const orphanedIds = orphanedRoleTargets.map((roleTarget) => roleTarget.id);
await this.roleTargetsRepository.delete({ id: In(orphanedIds) });
await this.roleTargetRepository.delete({ id: In(orphanedIds) });
this.logger.log(
`Deleted ${orphanedRoleTargets.length} orphaned roleTarget(s)`,
@@ -12,7 +12,7 @@ import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-s
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { IndexMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
import { WorkspaceSchemaManagerModule } from 'src/engine/twenty-orm/workspace-schema-manager/workspace-schema-manager.module';
@@ -25,7 +25,7 @@ import { WorkspaceSchemaManagerModule } from 'src/engine/twenty-orm/workspace-sc
IndexMetadataEntity,
ViewEntity,
UserWorkspaceEntity,
RoleTargetsEntity,
RoleTargetEntity,
ApplicationEntity,
]),
DataSourceModule,
@@ -0,0 +1,125 @@
import { type MigrationInterface, type QueryRunner } from 'typeorm';
export class RenameRoleTargets1764671363647 implements MigrationInterface {
name = 'RenameRoleTargets1764671363647';
public async up(queryRunner: QueryRunner): Promise<void> {
// Rename table from roleTargets to roleTarget
await queryRunner.query(
`ALTER TABLE "core"."roleTargets" RENAME TO "roleTarget"`,
);
// Rename unique constraints
await queryRunner.query(
`ALTER TABLE "core"."roleTarget" RENAME CONSTRAINT "IDX_ROLE_TARGETS_UNIQUE_USER_WORKSPACE" TO "IDX_ROLE_TARGET_UNIQUE_USER_WORKSPACE"`,
);
await queryRunner.query(
`ALTER TABLE "core"."roleTarget" RENAME CONSTRAINT "IDX_ROLE_TARGETS_UNIQUE_AGENT" TO "IDX_ROLE_TARGET_UNIQUE_AGENT"`,
);
await queryRunner.query(
`ALTER TABLE "core"."roleTarget" RENAME CONSTRAINT "IDX_ROLE_TARGETS_UNIQUE_API_KEY" TO "IDX_ROLE_TARGET_UNIQUE_API_KEY"`,
);
// Rename check constraint
await queryRunner.query(
`ALTER TABLE "core"."roleTarget" RENAME CONSTRAINT "CHK_role_targets_single_entity" TO "CHK_role_target_single_entity"`,
);
// Rename indexes
await queryRunner.query(
`ALTER INDEX "core"."IDX_ROLE_TARGETS_WORKSPACE_ID" RENAME TO "IDX_ROLE_TARGET_WORKSPACE_ID"`,
);
await queryRunner.query(
`ALTER INDEX "core"."IDX_ROLE_TARGETS_AGENT_ID" RENAME TO "IDX_ROLE_TARGET_AGENT_ID"`,
);
await queryRunner.query(
`ALTER INDEX "core"."IDX_ROLE_TARGETS_API_KEY_ID" RENAME TO "IDX_ROLE_TARGET_API_KEY_ID"`,
);
// FK
await queryRunner.query(
`ALTER TABLE "core"."roleTarget" DROP CONSTRAINT "FK_d5838ba43033ee6266d8928d7d7"`,
);
await queryRunner.query(
`ALTER TABLE "core"."roleTarget" DROP CONSTRAINT "FK_915c8bcb0f861a56f793a4b8331"`,
);
await queryRunner.query(
`ALTER TABLE "core"."roleTarget" DROP CONSTRAINT "FK_d4fcfdc3cd562a3e81fa9f0dae5"`,
);
await queryRunner.query(
`DROP INDEX "core"."IDX_3e571e80f99488686015f3d00c"`,
);
await queryRunner.query(
`CREATE UNIQUE INDEX "IDX_0082568653b80c15903c5a2ba9" ON "core"."roleTarget" ("workspaceId", "universalIdentifier") `,
);
await queryRunner.query(
`ALTER TABLE "core"."roleTarget" ADD CONSTRAINT "FK_b1db027b64f44029389ace305ac" FOREIGN KEY ("applicationId") REFERENCES "core"."application"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
);
await queryRunner.query(
`ALTER TABLE "core"."roleTarget" ADD CONSTRAINT "FK_83ea4a0433da5007a198db7667e" FOREIGN KEY ("roleId") REFERENCES "core"."role"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
);
await queryRunner.query(
`ALTER TABLE "core"."roleTarget" ADD CONSTRAINT "FK_4b3865868c7da0747ee8e480851" FOREIGN KEY ("apiKeyId") REFERENCES "core"."apiKey"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
// FK
await queryRunner.query(
`ALTER TABLE "core"."roleTarget" DROP CONSTRAINT "FK_4b3865868c7da0747ee8e480851"`,
);
await queryRunner.query(
`ALTER TABLE "core"."roleTarget" DROP CONSTRAINT "FK_83ea4a0433da5007a198db7667e"`,
);
await queryRunner.query(
`ALTER TABLE "core"."roleTarget" DROP CONSTRAINT "FK_b1db027b64f44029389ace305ac"`,
);
await queryRunner.query(
`DROP INDEX "core"."IDX_0082568653b80c15903c5a2ba9"`,
);
await queryRunner.query(
`CREATE UNIQUE INDEX "IDX_3e571e80f99488686015f3d00c" ON "core"."roleTarget" ("workspaceId", "universalIdentifier") `,
);
await queryRunner.query(
`ALTER TABLE "core"."roleTarget" ADD CONSTRAINT "FK_d4fcfdc3cd562a3e81fa9f0dae5" FOREIGN KEY ("applicationId") REFERENCES "core"."application"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
);
await queryRunner.query(
`ALTER TABLE "core"."roleTarget" ADD CONSTRAINT "FK_915c8bcb0f861a56f793a4b8331" FOREIGN KEY ("apiKeyId") REFERENCES "core"."apiKey"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
);
await queryRunner.query(
`ALTER TABLE "core"."roleTarget" ADD CONSTRAINT "FK_d5838ba43033ee6266d8928d7d7" FOREIGN KEY ("roleId") REFERENCES "core"."role"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
);
// Rename indexes back
await queryRunner.query(
`ALTER INDEX "core"."IDX_ROLE_TARGET_API_KEY_ID" RENAME TO "IDX_ROLE_TARGETS_API_KEY_ID"`,
);
await queryRunner.query(
`ALTER INDEX "core"."IDX_ROLE_TARGET_AGENT_ID" RENAME TO "IDX_ROLE_TARGETS_AGENT_ID"`,
);
await queryRunner.query(
`ALTER INDEX "core"."IDX_ROLE_TARGET_WORKSPACE_ID" RENAME TO "IDX_ROLE_TARGETS_WORKSPACE_ID"`,
);
// Rename check constraint back
await queryRunner.query(
`ALTER TABLE "core"."roleTarget" RENAME CONSTRAINT "CHK_role_target_single_entity" TO "CHK_role_targets_single_entity"`,
);
// Rename unique constraints back
await queryRunner.query(
`ALTER TABLE "core"."roleTarget" RENAME CONSTRAINT "IDX_ROLE_TARGET_UNIQUE_API_KEY" TO "IDX_ROLE_TARGETS_UNIQUE_API_KEY"`,
);
await queryRunner.query(
`ALTER TABLE "core"."roleTarget" RENAME CONSTRAINT "IDX_ROLE_TARGET_UNIQUE_AGENT" TO "IDX_ROLE_TARGETS_UNIQUE_AGENT"`,
);
await queryRunner.query(
`ALTER TABLE "core"."roleTarget" RENAME CONSTRAINT "IDX_ROLE_TARGET_UNIQUE_USER_WORKSPACE" TO "IDX_ROLE_TARGETS_UNIQUE_USER_WORKSPACE"`,
);
// Rename table back
await queryRunner.query(
`ALTER TABLE "core"."roleTarget" RENAME TO "roleTargets"`,
);
}
}
@@ -28,7 +28,7 @@ import { GraphqlQueryParser } from 'src/engine/api/graphql/graphql-query-runner/
import { ProcessNestedRelationsHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/process-nested-relations.helper';
import { WorkspacePreQueryHookPayload } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/types/workspace-query-hook.type';
import { WorkspaceQueryHookService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/workspace-query-hook.service';
import { ApiKeyRoleService } from 'src/engine/core-modules/api-key/api-key-role.service';
import { ApiKeyRoleService } from 'src/engine/core-modules/api-key/services/api-key-role.service';
import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
@@ -48,9 +48,9 @@ import {
import { PermissionsService } from 'src/engine/metadata-modules/permissions/permissions.service';
import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role.service';
import { WorkspaceDataSource } from 'src/engine/twenty-orm/datasource/workspace.datasource';
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
@Injectable()
export abstract class CommonBaseQueryRunnerService<
@@ -18,12 +18,11 @@ import { RecordPositionModule } from 'src/engine/core-modules/record-position/re
import { RecordTransformerModule } from 'src/engine/core-modules/record-transformer/record-transformer.module';
import { ThrottlerModule } from 'src/engine/core-modules/throttler/throttler.module';
import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { UserRoleModule } from 'src/engine/metadata-modules/user-role/user-role.module';
import { ViewFilterGroupModule } from 'src/engine/metadata-modules/view-filter-group/view-filter-group.module';
import { ViewFilterModule } from 'src/engine/metadata-modules/view-filter/view-filter.module';
import { ViewModule } from 'src/engine/metadata-modules/view/view.module';
import { WorkspacePermissionsCacheModule } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.module';
import { GlobalWorkspaceDataSourceModule } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-datasource.module';
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
@@ -32,10 +31,9 @@ import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache
WorkspaceQueryHookModule,
WorkspaceQueryRunnerModule,
PermissionsModule,
TypeOrmModule.forFeature([RoleTargetsEntity]),
TypeOrmModule.forFeature([RoleTargetEntity]),
UserRoleModule,
ApiKeyModule,
WorkspacePermissionsCacheModule,
FileModule,
ViewModule,
ViewFilterModule,
@@ -8,7 +8,7 @@ import { WorkspaceQueryHookModule } from 'src/engine/api/graphql/workspace-query
import { WorkspaceQueryRunnerModule } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module';
import { ApiKeyModule } from 'src/engine/core-modules/api-key/api-key.module';
import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { UserRoleModule } from 'src/engine/metadata-modules/user-role/user-role.module';
import { ViewFilterGroupModule } from 'src/engine/metadata-modules/view-filter-group/view-filter-group.module';
import { ViewFilterModule } from 'src/engine/metadata-modules/view-filter/view-filter.module';
@@ -19,7 +19,7 @@ import { ViewModule } from 'src/engine/metadata-modules/view/view.module';
WorkspaceQueryHookModule,
WorkspaceQueryRunnerModule,
PermissionsModule,
TypeOrmModule.forFeature([RoleTargetsEntity]),
TypeOrmModule.forFeature([RoleTargetEntity]),
UserRoleModule,
ApiKeyModule,
ViewModule,
@@ -6,7 +6,7 @@ import { GraphqlQueryRunnerException } from 'src/engine/api/graphql/graphql-quer
import { graphqlQueryRunnerExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/graphql-query-runner-exception-handler.util';
import { workspaceExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-exception-handler.util';
import { WorkspaceQueryRunnerException } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.exception';
import { ApiKeyException } from 'src/engine/core-modules/api-key/api-key.exception';
import { ApiKeyException } from 'src/engine/core-modules/api-key/exceptions/api-key.exception';
import { apiKeyGraphqlApiExceptionHandler } from 'src/engine/core-modules/api-key/utils/api-key-graphql-api-exception-handler.util';
import { AuthException } from 'src/engine/core-modules/auth/auth.exception';
import { authGraphqlApiExceptionHandler } from 'src/engine/core-modules/auth/utils/auth-graphql-api-exception-handler.util';
@@ -16,7 +16,7 @@ import { parseCorePath } from 'src/engine/api/rest/input-request-parsers/path-pa
import { Depth } from 'src/engine/api/rest/input-request-parsers/types/depth.type';
import { AuthenticatedRequest } from 'src/engine/api/rest/types/authenticated-request';
import { CreatedByFromAuthContextService } from 'src/engine/core-modules/actor/services/created-by-from-auth-context.service';
import { ApiKeyRoleService } from 'src/engine/core-modules/api-key/api-key-role.service';
import { ApiKeyRoleService } from 'src/engine/core-modules/api-key/services/api-key-role.service';
import { AccessTokenService } from 'src/engine/core-modules/auth/token/services/access-token.service';
import { WorkspaceDomainsService } from 'src/engine/core-modules/domain/workspace-domains/services/workspace-domains.service';
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
@@ -25,8 +25,8 @@ import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadat
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 FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
import { buildObjectIdByNameMaps } from 'src/engine/metadata-modules/flat-object-metadata/utils/build-object-id-by-name-maps.util';
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 {
PermissionsException,
PermissionsExceptionCode,
@@ -34,8 +34,8 @@ import {
} from 'src/engine/metadata-modules/permissions/permissions.exception';
import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role.service';
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage/workspace-cache-storage.service';
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
import { standardObjectMetadataDefinitions } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects';
import { shouldExcludeFromWorkspaceApi } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/should-exclude-from-workspace-api.util';
@@ -29,7 +29,6 @@ import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-
import { RecordTransformerModule } from 'src/engine/core-modules/record-transformer/record-transformer.module';
import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module';
import { UserRoleModule } from 'src/engine/metadata-modules/user-role/user-role.module';
import { WorkspacePermissionsCacheModule } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.module';
import { TwentyORMModule } from 'src/engine/twenty-orm/twenty-orm.module';
import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/workspace-cache-storage.module';
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
@@ -63,7 +62,6 @@ const restApiCoreResolvers = [
HttpModule,
TwentyORMModule,
RecordTransformerModule,
WorkspacePermissionsCacheModule,
WorkspaceManyOrAllFlatEntityMapsCacheModule,
WorkspaceFlatMapCacheModule,
ActorModule,
@@ -1,19 +1,18 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ApiKeyRoleService } from 'src/engine/core-modules/api-key/api-key-role.service';
import { ApiKeyEntity } from 'src/engine/core-modules/api-key/api-key.entity';
import { ApiKeyResolver } from 'src/engine/core-modules/api-key/api-key.resolver';
import { ApiKeyService } from 'src/engine/core-modules/api-key/api-key.service';
import { ApiKeyRoleService } from 'src/engine/core-modules/api-key/services/api-key-role.service';
import { ApiKeyService } from 'src/engine/core-modules/api-key/services/api-key.service';
import { TokenModule } from 'src/engine/core-modules/auth/token/token.module';
import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module';
import { JwtModule } from 'src/engine/core-modules/jwt/jwt.module';
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { RoleTargetModule } from 'src/engine/metadata-modules/role-target/role-target.module';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import { WorkspacePermissionsCacheModule } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.module';
import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/workspace-cache-storage.module';
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
@@ -23,12 +22,11 @@ import { ApiKeyController } from './controllers/api-key.controller';
imports: [
TypeOrmModule.forFeature([
ApiKeyEntity,
RoleTargetsEntity,
RoleTargetEntity,
RoleEntity,
WorkspaceEntity,
]),
JwtModule,
WorkspacePermissionsCacheModule,
WorkspaceCacheModule,
WorkspaceCacheStorageModule,
FeatureFlagModule,
@@ -11,14 +11,15 @@ import {
import { type QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import {
ApiKeyException,
ApiKeyExceptionCode,
} from 'src/engine/core-modules/api-key/api-key.exception';
import { ApiKeyEntity } from 'src/engine/core-modules/api-key/api-key.entity';
import { CreateApiKeyInput } from 'src/engine/core-modules/api-key/dtos/create-api-key.dto';
import { GetApiKeyInput } from 'src/engine/core-modules/api-key/dtos/get-api-key.dto';
import { RevokeApiKeyInput } from 'src/engine/core-modules/api-key/dtos/revoke-api-key.dto';
import { UpdateApiKeyInput } from 'src/engine/core-modules/api-key/dtos/update-api-key.dto';
import {
ApiKeyException,
ApiKeyExceptionCode,
} from 'src/engine/core-modules/api-key/exceptions/api-key.exception';
import { apiKeyGraphqlApiExceptionHandler } from 'src/engine/core-modules/api-key/utils/api-key-graphql-api-exception-handler.util';
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
@@ -27,9 +28,8 @@ import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants';
import { RoleDTO } from 'src/engine/metadata-modules/role/dtos/role.dto';
import { ApiKeyRoleService } from './api-key-role.service';
import { ApiKeyEntity } from './api-key.entity';
import { ApiKeyService } from './api-key.service';
import { ApiKeyRoleService } from './services/api-key-role.service';
import { ApiKeyService } from './services/api-key.service';
@Resolver(() => ApiKeyEntity)
@UseGuards(
@@ -14,9 +14,9 @@ import { type QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialE
import { RestApiExceptionFilter } from 'src/engine/api/rest/rest-api-exception.filter';
import { type ApiKeyEntity } from 'src/engine/core-modules/api-key/api-key.entity';
import { ApiKeyService } from 'src/engine/core-modules/api-key/api-key.service';
import { CreateApiKeyInput } from 'src/engine/core-modules/api-key/dtos/create-api-key.dto';
import { UpdateApiKeyInput } from 'src/engine/core-modules/api-key/dtos/update-api-key.dto';
import { ApiKeyService } from 'src/engine/core-modules/api-key/services/api-key.service';
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
import { JwtAuthGuard } from 'src/engine/guards/jwt-auth.guard';
@@ -3,23 +3,22 @@ import { getDataSourceToken, getRepositoryToken } from '@nestjs/typeorm';
import { IsNull } from 'typeorm';
import { ApiKeyRoleService } from 'src/engine/core-modules/api-key/api-key-role.service';
import { ApiKeyEntity } from 'src/engine/core-modules/api-key/api-key.entity';
import {
ApiKeyException,
ApiKeyExceptionCode,
} from 'src/engine/core-modules/api-key/api-key.exception';
} from 'src/engine/core-modules/api-key/exceptions/api-key.exception';
import { ApiKeyRoleService } from 'src/engine/core-modules/api-key/services/api-key-role.service';
import { ApiKeyService } from 'src/engine/core-modules/api-key/services/api-key.service';
import { JwtTokenTypeEnum } from 'src/engine/core-modules/auth/types/auth-context.type';
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { RoleTargetService } from 'src/engine/metadata-modules/role-target/services/role-target.service';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { ApiKeyEntity } from './api-key.entity';
import { ApiKeyService } from './api-key.service';
describe('ApiKeyService', () => {
let service: ApiKeyService;
let mockApiKeyRepository: any;
let mockRoleTargetsRepository: any;
let mockroleTargetRepository: any;
let mockJwtWrapperService: any;
let mockApiKeyRoleService: any;
let mockRoleTargetService: any;
@@ -60,7 +59,7 @@ describe('ApiKeyService', () => {
update: jest.fn(),
};
mockRoleTargetsRepository = {
mockroleTargetRepository = {
delete: jest.fn(),
save: jest.fn(),
findOne: jest.fn(),
@@ -101,8 +100,8 @@ describe('ApiKeyService', () => {
useValue: mockRoleTargetService,
},
{
provide: getRepositoryToken(RoleTargetsEntity),
useValue: mockRoleTargetsRepository,
provide: getRepositoryToken(RoleTargetEntity),
useValue: mockroleTargetRepository,
},
{
provide: ApiKeyRoleService,
@@ -7,10 +7,10 @@ import { ApiKeyEntity } from 'src/engine/core-modules/api-key/api-key.entity';
import {
ApiKeyException,
ApiKeyExceptionCode,
} from 'src/engine/core-modules/api-key/api-key.exception';
} from 'src/engine/core-modules/api-key/exceptions/api-key.exception';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { RoleTargetService } from 'src/engine/metadata-modules/role-target/services/role-target.service';
import { type RoleDTO } from 'src/engine/metadata-modules/role/dtos/role.dto';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import { fromRoleEntityToRoleDto } from 'src/engine/metadata-modules/role/utils/fromRoleEntityToRoleDto.util';
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
@@ -18,8 +18,8 @@ import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/works
@Injectable()
export class ApiKeyRoleService {
constructor(
@InjectRepository(RoleTargetsEntity)
private readonly roleTargetsRepository: Repository<RoleTargetsEntity>,
@InjectRepository(RoleTargetEntity)
private readonly roleTargetRepository: Repository<RoleTargetEntity>,
@InjectRepository(RoleEntity)
private readonly roleRepository: Repository<RoleEntity>,
@@ -117,7 +117,7 @@ export class ApiKeyRoleService {
);
}
const existingRoleTarget = await this.roleTargetsRepository.findOne({
const existingRoleTarget = await this.roleTargetRepository.findOne({
where: {
apiKeyId,
roleId,
@@ -141,7 +141,7 @@ export class ApiKeyRoleService {
return new Map();
}
const roleTargets = await this.roleTargetsRepository.find({
const roleTargets = await this.roleTargetRepository.find({
where: {
apiKeyId: In(apiKeyIds),
workspaceId,
@@ -167,7 +167,7 @@ export class ApiKeyRoleService {
roleId: string,
workspaceId: string,
): Promise<ApiKeyEntity[]> {
const roleTargets = await this.roleTargetsRepository.find({
const roleTargets = await this.roleTargetRepository.find({
where: {
roleId,
workspaceId,
@@ -9,7 +9,7 @@ import { ApiKeyEntity } from 'src/engine/core-modules/api-key/api-key.entity';
import {
ApiKeyException,
ApiKeyExceptionCode,
} from 'src/engine/core-modules/api-key/api-key.exception';
} from 'src/engine/core-modules/api-key/exceptions/api-key.exception';
import { type ApiKeyToken } from 'src/engine/core-modules/auth/dto/api-key-token.dto';
import { JwtTokenTypeEnum } from 'src/engine/core-modules/auth/types/auth-context.type';
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
@@ -3,7 +3,7 @@ import { assertUnreachable } from 'twenty-shared/utils';
import {
ApiKeyException,
ApiKeyExceptionCode,
} from 'src/engine/core-modules/api-key/api-key.exception';
} from 'src/engine/core-modules/api-key/exceptions/api-key.exception';
import {
ForbiddenError,
NotFoundError,
@@ -2,7 +2,7 @@ import { type CanActivate } from '@nestjs/common';
import { Test, type TestingModule } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm';
import { ApiKeyService } from 'src/engine/core-modules/api-key/api-key.service';
import { ApiKeyService } from 'src/engine/core-modules/api-key/services/api-key.service';
import { AppTokenEntity } from 'src/engine/core-modules/app-token/app-token.entity';
import { AuditService } from 'src/engine/core-modules/audit/services/audit.service';
import { SignInUpService } from 'src/engine/core-modules/auth/services/sign-in-up.service';
@@ -21,7 +21,7 @@ import { ValidatePasswordResetTokenOutput } from 'src/engine/core-modules/auth/d
import { ValidatePasswordResetTokenInput } from 'src/engine/core-modules/auth/dto/validate-password-reset-token.input';
import { AuthGraphqlApiExceptionFilter } from 'src/engine/core-modules/auth/filters/auth-graphql-api-exception.filter';
// import { OAuthService } from 'src/engine/core-modules/auth/services/oauth.service';
import { ApiKeyService } from 'src/engine/core-modules/api-key/api-key.service';
import { ApiKeyService } from 'src/engine/core-modules/api-key/services/api-key.service';
import { AppTokenEntity } from 'src/engine/core-modules/app-token/app-token.entity';
import { AuditService } from 'src/engine/core-modules/audit/services/audit.service';
import { MONITORING_EVENT } from 'src/engine/core-modules/audit/utils/events/workspace-event/monitoring/monitoring';
@@ -34,6 +34,7 @@ import { GetAuthTokenFromEmailVerificationTokenInput } from 'src/engine/core-mod
import { GetAuthorizationUrlForSSOInput } from 'src/engine/core-modules/auth/dto/get-authorization-url-for-sso.input';
import { GetAuthorizationUrlForSSOOutput } from 'src/engine/core-modules/auth/dto/get-authorization-url-for-sso.output';
import { SignUpOutput } from 'src/engine/core-modules/auth/dto/sign-up.output';
import { VerifyEmailAndGetLoginTokenOutput } from 'src/engine/core-modules/auth/dto/verify-email-and-get-login-token.output';
import { ResetPasswordService } from 'src/engine/core-modules/auth/services/reset-password.service';
import { SignInUpService } from 'src/engine/core-modules/auth/services/sign-in-up.service';
import { EmailVerificationTokenService } from 'src/engine/core-modules/auth/token/services/email-verification-token.service';
@@ -76,7 +77,6 @@ import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants';
import { PermissionsService } from 'src/engine/metadata-modules/permissions/permissions.service';
import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter';
import { VerifyEmailAndGetLoginTokenOutput } from 'src/engine/core-modules/auth/dto/verify-email-and-get-login-token.output';
import { ApiKeyToken } from './dto/api-key-token.dto';
import { AuthTokens } from './dto/auth-tokens.dto';
@@ -7,7 +7,6 @@ import { TypeORMModule } from 'src/database/typeorm/typeorm.module';
import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
import { WorkspaceFeatureFlagsMapCacheModule } from 'src/engine/metadata-modules/workspace-feature-flags-map-cache/workspace-feature-flags-map-cache.module';
import { WorkspacePermissionsCacheModule } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.module';
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
@Module({
@@ -19,7 +18,6 @@ import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache
resolvers: [],
}),
WorkspaceFeatureFlagsMapCacheModule,
WorkspacePermissionsCacheModule,
WorkspaceCacheModule,
],
exports: [FeatureFlagService],
@@ -10,7 +10,6 @@ import {
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
import { featureFlagValidator } from 'src/engine/core-modules/feature-flag/validates/feature-flag.validate';
import { publicFeatureFlagValidator } from 'src/engine/core-modules/feature-flag/validates/is-public-feature-flag.validate';
import { WorkspacePermissionsCacheService } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.service';
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
jest.mock(
@@ -36,10 +35,6 @@ describe('FeatureFlagService', () => {
invalidateAndRecompute: jest.fn(),
};
const mockWorkspacePermissionsCacheService = {
recomputeRolesPermissionsCache: jest.fn(),
};
const workspaceId = 'workspace-id';
const featureFlag = FeatureFlagKey.IS_AI_ENABLED;
@@ -62,10 +57,6 @@ describe('FeatureFlagService', () => {
provide: WorkspaceCacheService,
useValue: mockWorkspaceCacheService,
},
{
provide: WorkspacePermissionsCacheService,
useValue: mockWorkspacePermissionsCacheService,
},
],
}).compile();
@@ -19,7 +19,7 @@ import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.ent
import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { UserRoleModule } from 'src/engine/metadata-modules/user-role/user-role.module';
import { TwentyORMModule } from 'src/engine/twenty-orm/twenty-orm.module';
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module';
@@ -32,7 +32,7 @@ import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/works
UserEntity,
UserWorkspaceEntity,
WorkspaceEntity,
RoleTargetsEntity,
RoleTargetEntity,
]),
NestjsQueryTypeOrmModule.forFeature([ObjectMetadataEntity]),
TypeORMModule,
@@ -25,7 +25,7 @@ import { type WorkspaceEntity } from 'src/engine/core-modules/workspace/workspac
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { PermissionsException } from 'src/engine/metadata-modules/permissions/permissions.exception';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role.service';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
@@ -70,7 +70,7 @@ describe('UserWorkspaceService', () => {
},
},
{
provide: getRepositoryToken(RoleTargetsEntity),
provide: getRepositoryToken(RoleTargetEntity),
useValue: {
findOneOrFail: jest.fn(),
},
@@ -31,7 +31,7 @@ import {
PermissionsExceptionCode,
PermissionsExceptionMessage,
} from 'src/engine/metadata-modules/permissions/permissions.exception';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role.service';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
@@ -44,8 +44,8 @@ export class UserWorkspaceService extends TypeOrmQueryService<UserWorkspaceEntit
private readonly userWorkspaceRepository: Repository<UserWorkspaceEntity>,
@InjectRepository(UserEntity)
private readonly userRepository: Repository<UserEntity>,
@InjectRepository(RoleTargetsEntity)
private readonly roleTargetsRepository: Repository<RoleTargetsEntity>,
@InjectRepository(RoleTargetEntity)
private readonly roleTargetRepository: Repository<RoleTargetEntity>,
private readonly workspaceInvitationService: WorkspaceInvitationService,
private readonly workspaceDomainsService: WorkspaceDomainsService,
private readonly loginTokenService: LoginTokenService,
@@ -246,10 +246,10 @@ export class UserWorkspaceService extends TypeOrmQueryService<UserWorkspaceEntit
softDelete?: boolean;
}): Promise<void> {
if (softDelete) {
await this.roleTargetsRepository.softRemove({ userWorkspaceId });
await this.roleTargetRepository.softRemove({ userWorkspaceId });
await this.userWorkspaceRepository.softDelete({ id: userWorkspaceId });
} else {
await this.roleTargetsRepository.delete({ userWorkspaceId }); // TODO remove once userWorkspace foreign key is added on roleTarget
await this.roleTargetRepository.delete({ userWorkspaceId }); // TODO remove once userWorkspace foreign key is added on roleTarget
await this.userWorkspaceRepository.delete({ id: userWorkspaceId });
}
}
@@ -4,7 +4,7 @@ import { TypeOrmModule } from '@nestjs/typeorm';
import { AiBillingModule } from 'src/engine/metadata-modules/ai/ai-billing/ai-billing.module';
import { AiModelsModule } from 'src/engine/metadata-modules/ai/ai-models/ai-models.module';
import { AiToolsModule } from 'src/engine/metadata-modules/ai/ai-tools/ai-tools.module';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { AgentMessagePartEntity } from './entities/agent-message-part.entity';
import { AgentMessageEntity } from './entities/agent-message.entity';
@@ -20,7 +20,7 @@ import { AgentAsyncExecutorService } from './services/agent-async-executor.servi
AgentMessageEntity,
AgentMessagePartEntity,
AgentTurnEntity,
RoleTargetsEntity,
RoleTargetEntity,
]),
],
providers: [AgentAsyncExecutorService],
@@ -23,7 +23,7 @@ import { AI_TELEMETRY_CONFIG } from 'src/engine/metadata-modules/ai/ai-models/co
import { AiModelRegistryService } from 'src/engine/metadata-modules/ai/ai-models/services/ai-model-registry.service';
import { ToolAdapterService } from 'src/engine/metadata-modules/ai/ai-tools/services/tool-adapter.service';
import { ToolService } from 'src/engine/metadata-modules/ai/ai-tools/services/tool.service';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { type RolePermissionConfig } from 'src/engine/twenty-orm/types/role-permission-config';
@Injectable()
@@ -32,8 +32,8 @@ export class AgentAsyncExecutorService {
constructor(
private readonly aiModelRegistryService: AiModelRegistryService,
private readonly toolAdapterService: ToolAdapterService,
@InjectRepository(RoleTargetsEntity)
private readonly roleTargetsRepository: Repository<RoleTargetsEntity>,
@InjectRepository(RoleTargetEntity)
private readonly roleTargetRepository: Repository<RoleTargetEntity>,
private readonly toolService: ToolService,
) {}
@@ -43,7 +43,7 @@ export class AgentAsyncExecutorService {
actorContext?: ActorMetadata,
rolePermissionConfig?: RolePermissionConfig,
): Promise<ToolSet> {
const roleTarget = await this.roleTargetsRepository.findOne({
const roleTarget = await this.roleTargetRepository.findOne({
where: {
agentId: agentId,
workspaceId,
@@ -10,8 +10,8 @@ import {
import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity';
import { type ModelId } from 'src/engine/metadata-modules/ai/ai-models/constants/ai-models.const';
import { type FlatRoleTarget } from 'src/engine/metadata-modules/flat-role-target/types/flat-role-target.type';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { RoleTargetService } from 'src/engine/metadata-modules/role-target/services/role-target.service';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import { AiAgentRoleService } from './ai-agent-role.service';
@@ -20,7 +20,7 @@ describe('AiAgentRoleService', () => {
let service: AiAgentRoleService;
let agentRepository: Repository<AgentEntity>;
let roleRepository: Repository<RoleEntity>;
let roleTargetsRepository: Repository<RoleTargetsEntity>;
let roleTargetRepository: Repository<RoleTargetEntity>;
let roleTargetService: RoleTargetService;
const testWorkspaceId = 'test-workspace-id';
@@ -47,7 +47,7 @@ describe('AiAgentRoleService', () => {
},
},
{
provide: getRepositoryToken(RoleTargetsEntity),
provide: getRepositoryToken(RoleTargetEntity),
useValue: {
findOne: jest.fn(),
save: jest.fn(),
@@ -72,8 +72,8 @@ describe('AiAgentRoleService', () => {
roleRepository = module.get<Repository<RoleEntity>>(
getRepositoryToken(RoleEntity),
);
roleTargetsRepository = module.get<Repository<RoleTargetsEntity>>(
getRepositoryToken(RoleTargetsEntity),
roleTargetRepository = module.get<Repository<RoleTargetEntity>>(
getRepositoryToken(RoleTargetEntity),
);
roleTargetService = module.get<RoleTargetService>(RoleTargetService);
@@ -135,7 +135,7 @@ describe('AiAgentRoleService', () => {
// Arrange
jest.spyOn(agentRepository, 'findOne').mockResolvedValue(testAgent);
jest.spyOn(roleRepository, 'findOne').mockResolvedValue(testRole);
jest.spyOn(roleTargetsRepository, 'findOne').mockResolvedValue(null);
jest.spyOn(roleTargetRepository, 'findOne').mockResolvedValue(null);
jest
.spyOn(roleTargetService, 'create')
.mockResolvedValue({} as FlatRoleTarget);
@@ -154,7 +154,7 @@ describe('AiAgentRoleService', () => {
expect(roleRepository.findOne).toHaveBeenCalledWith({
where: { id: testRole.id, workspaceId: testWorkspaceId },
});
expect(roleTargetsRepository.findOne).toHaveBeenCalledWith({
expect(roleTargetRepository.findOne).toHaveBeenCalledWith({
where: {
agentId: testAgent.id,
roleId: testRole.id,
@@ -175,7 +175,7 @@ describe('AiAgentRoleService', () => {
// Arrange
jest.spyOn(agentRepository, 'findOne').mockResolvedValue(testAgent);
jest.spyOn(roleRepository, 'findOne').mockResolvedValue(testRole2);
jest.spyOn(roleTargetsRepository, 'findOne').mockResolvedValue(null);
jest.spyOn(roleTargetRepository, 'findOne').mockResolvedValue(null);
jest
.spyOn(roleTargetService, 'create')
.mockResolvedValue({} as FlatRoleTarget);
@@ -207,12 +207,12 @@ describe('AiAgentRoleService', () => {
workspaceId: testWorkspaceId,
createdAt: new Date(),
updatedAt: new Date(),
} as RoleTargetsEntity;
} as RoleTargetEntity;
jest.spyOn(agentRepository, 'findOne').mockResolvedValue(testAgent);
jest.spyOn(roleRepository, 'findOne').mockResolvedValue(testRole);
jest
.spyOn(roleTargetsRepository, 'findOne')
.spyOn(roleTargetRepository, 'findOne')
.mockResolvedValue(existingRoleTarget);
// Act
@@ -319,10 +319,10 @@ describe('AiAgentRoleService', () => {
workspaceId: testWorkspaceId,
createdAt: new Date(),
updatedAt: new Date(),
} as RoleTargetsEntity;
} as RoleTargetEntity;
jest
.spyOn(roleTargetsRepository, 'findOne')
.spyOn(roleTargetRepository, 'findOne')
.mockResolvedValue(existingRoleTarget);
jest.spyOn(roleTargetService, 'delete').mockResolvedValue(undefined);
@@ -333,7 +333,7 @@ describe('AiAgentRoleService', () => {
});
// Assert
expect(roleTargetsRepository.findOne).toHaveBeenCalledWith({
expect(roleTargetRepository.findOne).toHaveBeenCalledWith({
where: {
agentId: testAgent.id,
workspaceId: testWorkspaceId,
@@ -347,7 +347,7 @@ describe('AiAgentRoleService', () => {
it('should throw error when removing role from agent that has no role', async () => {
// Arrange
jest.spyOn(roleTargetsRepository, 'findOne').mockResolvedValue(null);
jest.spyOn(roleTargetRepository, 'findOne').mockResolvedValue(null);
// Act & Assert
await expect(
@@ -2,15 +2,15 @@ import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { RoleTargetModule } from 'src/engine/metadata-modules/role-target/role-target.module';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import { AiAgentRoleService } from './ai-agent-role.service';
@Module({
imports: [
TypeOrmModule.forFeature([AgentEntity, RoleEntity, RoleTargetsEntity]),
TypeOrmModule.forFeature([AgentEntity, RoleEntity, RoleTargetEntity]),
RoleTargetModule,
],
providers: [AiAgentRoleService],
@@ -9,8 +9,8 @@ import {
AgentExceptionCode,
} from 'src/engine/metadata-modules/ai/ai-agent/agent.exception';
import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { RoleTargetService } from 'src/engine/metadata-modules/role-target/services/role-target.service';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
@Injectable()
@@ -20,8 +20,8 @@ export class AiAgentRoleService {
private readonly agentRepository: Repository<AgentEntity>,
@InjectRepository(RoleEntity)
private readonly roleRepository: Repository<RoleEntity>,
@InjectRepository(RoleTargetsEntity)
private readonly roleTargetsRepository: Repository<RoleTargetsEntity>,
@InjectRepository(RoleTargetEntity)
private readonly roleTargetRepository: Repository<RoleTargetEntity>,
private readonly roleTargetService: RoleTargetService,
) {}
@@ -88,7 +88,7 @@ export class AiAgentRoleService {
workspaceId: string;
agentId: string;
}): Promise<void> {
const existingRoleTarget = await this.roleTargetsRepository.findOne({
const existingRoleTarget = await this.roleTargetRepository.findOne({
where: {
agentId,
workspaceId,
@@ -112,7 +112,7 @@ export class AiAgentRoleService {
roleId: string,
workspaceId: string,
): Promise<AgentEntity[]> {
const roleTargets = await this.roleTargetsRepository.find({
const roleTargets = await this.roleTargetRepository.find({
where: {
roleId,
workspaceId,
@@ -176,7 +176,7 @@ export class AiAgentRoleService {
);
}
const existingRoleTarget = await this.roleTargetsRepository.findOne({
const existingRoleTarget = await this.roleTargetRepository.findOne({
where: {
agentId,
roleId,
@@ -211,7 +211,7 @@ export class AiAgentRoleService {
return;
}
const remainingAssignments = await this.roleTargetsRepository.count({
const remainingAssignments = await this.roleTargetRepository.count({
where: {
roleId,
workspaceId,
@@ -2,13 +2,13 @@ import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { isNonEmptyString } from '@sniptt/guards';
import { In, Repository } from 'typeorm';
import { computeMetadataNameFromLabel } from 'twenty-shared/metadata';
import { In, Repository } from 'typeorm';
import { AiAgentRoleService } from 'src/engine/metadata-modules/ai/ai-agent-role/ai-agent-role.service';
import { type CreateAgentInput } from 'src/engine/metadata-modules/ai/ai-agent/dtos/create-agent.input';
import { type UpdateAgentInput } from 'src/engine/metadata-modules/ai/ai-agent/dtos/update-agent.input';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { AgentException, AgentExceptionCode } from './agent.exception';
@@ -19,8 +19,8 @@ export class AgentService {
constructor(
@InjectRepository(AgentEntity)
private readonly agentRepository: Repository<AgentEntity>,
@InjectRepository(RoleTargetsEntity)
private readonly roleTargetsRepository: Repository<RoleTargetsEntity>,
@InjectRepository(RoleTargetEntity)
private readonly roleTargetRepository: Repository<RoleTargetEntity>,
private readonly agentRoleService: AiAgentRoleService,
) {}
@@ -46,7 +46,7 @@ export class AgentService {
workspaceId: string,
agents: AgentEntity[],
): Promise<Map<string, string>> {
const roleTargets = await this.roleTargetsRepository.find({
const roleTargets = await this.roleTargetRepository.find({
where: {
workspaceId,
agentId: In(agents.map((agent) => agent.id)),
@@ -137,7 +137,7 @@ export class AgentService {
workspaceId: string,
agentId: string,
): Promise<string | null> {
const roleTarget = await this.roleTargetsRepository.findOne({
const roleTarget = await this.roleTargetRepository.findOne({
where: {
agentId,
workspaceId,
@@ -16,11 +16,11 @@ import { AiModelsModule } from 'src/engine/metadata-modules/ai/ai-models/ai-mode
import { AiToolsModule } from 'src/engine/metadata-modules/ai/ai-tools/ai-tools.module';
import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module';
import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import { UserRoleModule } from 'src/engine/metadata-modules/user-role/user-role.module';
import { WorkspacePermissionsCacheModule } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.module';
import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/workspace-cache-storage.module';
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
import { WorkflowToolsModule } from 'src/modules/workflow/workflow-tools/workflow-tools.module';
import { AgentResolver } from './agent.resolver';
@@ -35,7 +35,7 @@ import { AgentTitleGenerationService } from './services/agent-title-generation.s
import { AgentToolGeneratorService } from './services/agent-tool-generator.service';
@Module({
imports: [
TypeOrmModule.forFeature([AgentEntity, RoleEntity, RoleTargetsEntity]),
TypeOrmModule.forFeature([AgentEntity, RoleEntity, RoleTargetEntity]),
AiModelsModule,
AiToolsModule,
AiBillingModule,
@@ -48,13 +48,13 @@ import { AgentToolGeneratorService } from './services/agent-tool-generator.servi
ObjectMetadataModule,
PermissionsModule,
AiChatRouterModule,
WorkspacePermissionsCacheModule,
WorkspaceCacheStorageModule,
TokenModule,
WorkspaceDomainsModule,
WorkflowToolsModule,
UserWorkspaceModule,
UserRoleModule,
WorkspaceCacheModule,
],
providers: [
AgentResolver,
@@ -34,8 +34,8 @@ import { AIBillingService } from 'src/engine/metadata-modules/ai/ai-billing/serv
import { ToolHints } from 'src/engine/metadata-modules/ai/ai-chat-router/types/tool-hints.interface';
import { AI_TELEMETRY_CONFIG } from 'src/engine/metadata-modules/ai/ai-models/constants/ai-telemetry.const';
import { AiModelRegistryService } from 'src/engine/metadata-modules/ai/ai-models/services/ai-model-registry.service';
import { WorkspacePermissionsCacheService } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.service';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
export interface AgentExecutionResult {
result: object;
@@ -59,13 +59,13 @@ export class AgentExecutionService {
constructor(
private readonly workspaceDomainsService: WorkspaceDomainsService,
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
private readonly workspacePermissionsCacheService: WorkspacePermissionsCacheService,
private readonly aiModelRegistryService: AiModelRegistryService,
private readonly agentToolGeneratorService: AgentToolGeneratorService,
private readonly agentModelConfigService: AgentModelConfigService,
private readonly aiBillingService: AIBillingService,
public readonly agentActorContextService: AgentActorContextService,
public readonly agentService: AgentService,
private readonly workspaceCacheService: WorkspaceCacheService,
) {}
async prepareAIRequestConfig({
@@ -169,11 +169,12 @@ export class AgentExecutionService {
recordIdsByObjectMetadataNameSingular: RecordIdsByObjectMetadataNameSingularType,
userWorkspaceId: string,
) {
const roleId =
await this.workspacePermissionsCacheService.getRoleIdFromUserWorkspaceId({
workspaceId: workspace.id,
userWorkspaceId,
});
const { userWorkspaceRoleMap } =
await this.workspaceCacheService.getOrRecompute(workspace.id, [
'userWorkspaceRoleMap',
]);
const roleId = userWorkspaceRoleMap[userWorkspaceId];
if (!roleId) {
throw new AgentException(
@@ -14,7 +14,6 @@ import { AiAgentModule } from 'src/engine/metadata-modules/ai/ai-agent/ai-agent.
import { AiBillingModule } from 'src/engine/metadata-modules/ai/ai-billing/ai-billing.module';
import { AiChatRouterModule } from 'src/engine/metadata-modules/ai/ai-chat-router/ai-chat-router.module';
import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module';
import { WorkspacePermissionsCacheModule } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.module';
import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/workspace-cache-storage.module';
import { AgentChatController } from './controllers/agent-chat.controller';
@@ -39,7 +38,6 @@ import { AgentChatService } from './services/agent-chat.service';
FileUploadModule,
FileModule,
PermissionsModule,
WorkspacePermissionsCacheModule,
WorkspaceCacheStorageModule,
TokenModule,
UserWorkspaceModule,
@@ -14,7 +14,6 @@ import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata
import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import { UserRoleModule } from 'src/engine/metadata-modules/user-role/user-role.module';
import { WorkspacePermissionsCacheModule } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.module';
import { TwentyORMModule } from 'src/engine/twenty-orm/twenty-orm.module';
import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/workspace-cache-storage.module';
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
@@ -29,7 +28,6 @@ import { MessagingModule } from 'src/modules/messaging/messaging.module';
FeatureFlagModule,
RecordCrudModule,
WorkspaceManyOrAllFlatEntityMapsCacheModule,
WorkspacePermissionsCacheModule,
WorkspaceCacheStorageModule,
UserRoleModule,
TwentyORMModule,
@@ -14,7 +14,7 @@ import { type FlatViewGroup } from 'src/engine/metadata-modules/flat-view-group/
import { type FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
import { type IndexMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity';
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { type RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { type RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { type RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import { type RouteTriggerEntity } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity';
import { type FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type';
@@ -205,6 +205,6 @@ export type AllFlatEntityTypesByMetadataName = {
deleted: DeleteRoleTargetAction;
};
flatEntity: FlatRoleTarget;
entity: RoleTargetsEntity;
entity: RoleTargetEntity;
};
};
@@ -8,7 +8,7 @@ import { WorkspaceCacheProvider } from 'src/engine/workspace-cache/interfaces/wo
import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
import { type FlatRoleTargetMaps } from 'src/engine/metadata-modules/flat-role-target/types/flat-role-target-maps.type';
import { fromRoleTargetsEntityToFlatRoleTarget } from 'src/engine/metadata-modules/flat-role-target/utils/from-role-target-entity-to-flat-role-target.util';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
@@ -16,14 +16,14 @@ import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/
@WorkspaceCache('flatRoleTargetMaps')
export class WorkspaceFlatRoleTargetMapCacheService extends WorkspaceCacheProvider<FlatRoleTargetMaps> {
constructor(
@InjectRepository(RoleTargetsEntity)
private readonly roleTargetsRepository: Repository<RoleTargetsEntity>,
@InjectRepository(RoleTargetEntity)
private readonly roleTargetRepository: Repository<RoleTargetEntity>,
) {
super();
}
async computeForCache(workspaceId: string): Promise<FlatRoleTargetMaps> {
const roleTargets = await this.roleTargetsRepository.find({
const roleTargets = await this.roleTargetRepository.find({
where: {
workspaceId,
},
@@ -1,5 +1,5 @@
import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type';
import { type RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { type RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
export const roleTargetsEntityRelationProperties = ['role', 'apiKey'] as const;
@@ -7,6 +7,6 @@ export type RoleTargetsEntityRelationProperties =
(typeof roleTargetsEntityRelationProperties)[number];
export type FlatRoleTarget = FlatEntityFrom<
RoleTargetsEntity,
RoleTargetEntity,
RoleTargetsEntityRelationProperties
>;
@@ -1,8 +1,8 @@
import { type FlatRoleTarget } from 'src/engine/metadata-modules/flat-role-target/types/flat-role-target.type';
import { type RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { type RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
export const fromRoleTargetsEntityToFlatRoleTarget = (
roleTarget: RoleTargetsEntity,
roleTarget: RoleTargetEntity,
): FlatRoleTarget => {
return {
id: roleTarget.id,
@@ -3,14 +3,14 @@ import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/typ
import { type FieldPermissionEntity } from 'src/engine/metadata-modules/object-permission/field-permission/field-permission.entity';
import { type ObjectPermissionEntity } from 'src/engine/metadata-modules/object-permission/object-permission.entity';
import { type PermissionFlagEntity } from 'src/engine/metadata-modules/permission-flag/permission-flag.entity';
import { type RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { type RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { type RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import { type ExtractRecordTypeOrmRelationProperties } from 'src/engine/workspace-manager/workspace-migration-v2/types/extract-record-typeorm-relation-properties.type';
export type RoleEntityRelationProperties =
ExtractRecordTypeOrmRelationProperties<
RoleEntity,
| RoleTargetsEntity
| RoleTargetEntity
| ObjectPermissionEntity
| PermissionFlagEntity
| FieldPermissionEntity
@@ -33,7 +33,6 @@ import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entit
import { ViewModule } from 'src/engine/metadata-modules/view/view.module';
import { WorkspaceMetadataVersionModule } from 'src/engine/metadata-modules/workspace-metadata-version/workspace-metadata-version.module';
import { WorkspaceMigrationModule } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.module';
import { WorkspacePermissionsCacheModule } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.module';
import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/workspace-cache-storage.module';
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module';
@@ -59,7 +58,6 @@ import { WorkspaceMigrationV2Module } from 'src/engine/workspace-manager/workspa
RemoteTableRelationsModule,
IndexMetadataModule,
PermissionsModule,
WorkspacePermissionsCacheModule,
WorkspaceCacheStorageModule,
WorkspaceDataSourceModule,
FeatureFlagModule,
@@ -9,7 +9,6 @@ import { FieldPermissionService } from 'src/engine/metadata-modules/object-permi
import { ObjectPermissionEntity } from 'src/engine/metadata-modules/object-permission/object-permission.entity';
import { ObjectPermissionService } from 'src/engine/metadata-modules/object-permission/object-permission.service';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import { WorkspacePermissionsCacheModule } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.module';
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
@Module({
@@ -21,7 +20,6 @@ import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache
FieldPermissionEntity,
FieldMetadataEntity,
]),
WorkspacePermissionsCacheModule,
WorkspaceManyOrAllFlatEntityMapsCacheModule,
WorkspaceCacheModule,
],
@@ -4,13 +4,11 @@ import { TypeOrmModule } from '@nestjs/typeorm';
import { PermissionFlagEntity } from 'src/engine/metadata-modules/permission-flag/permission-flag.entity';
import { PermissionFlagService } from 'src/engine/metadata-modules/permission-flag/permission-flag.service';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import { WorkspacePermissionsCacheModule } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.module';
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
@Module({
imports: [
TypeOrmModule.forFeature([PermissionFlagEntity, RoleEntity]),
WorkspacePermissionsCacheModule,
WorkspaceCacheModule,
],
@@ -1,10 +1,10 @@
import { Test, type TestingModule } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm';
import { ApiKeyRoleService } from 'src/engine/core-modules/api-key/services/api-key-role.service';
import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants';
import { PermissionsService } from 'src/engine/metadata-modules/permissions/permissions.service';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import { ApiKeyRoleService } from 'src/engine/core-modules/api-key/api-key-role.service';
import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role.service';
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
@@ -1,31 +1,29 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ApiKeyRoleService } from 'src/engine/core-modules/api-key/api-key-role.service';
import { ApiKeyEntity } from 'src/engine/core-modules/api-key/api-key.entity';
import { ApiKeyRoleService } from 'src/engine/core-modules/api-key/services/api-key-role.service';
import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module';
import { UserWorkspaceEntity } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
import { PermissionsService } from 'src/engine/metadata-modules/permissions/permissions.service';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { RoleTargetModule } from 'src/engine/metadata-modules/role-target/role-target.module';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import { UserRoleModule } from 'src/engine/metadata-modules/user-role/user-role.module';
import { WorkspacePermissionsCacheModule } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.module';
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
@Module({
imports: [
TypeOrmModule.forFeature([
RoleEntity,
RoleTargetsEntity,
RoleTargetEntity,
ApiKeyEntity,
WorkspaceEntity,
]),
FeatureFlagModule,
TypeOrmModule.forFeature([UserWorkspaceEntity]),
UserRoleModule,
WorkspacePermissionsCacheModule,
WorkspaceCacheModule,
RoleTargetModule,
],
@@ -5,7 +5,7 @@ import { msg } from '@lingui/core/macro';
import { isDefined } from 'twenty-shared/utils';
import { In, Repository } from 'typeorm';
import { ApiKeyRoleService } from 'src/engine/core-modules/api-key/api-key-role.service';
import { ApiKeyRoleService } from 'src/engine/core-modules/api-key/services/api-key-role.service';
import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants';
import { TOOL_PERMISSION_FLAGS } from 'src/engine/metadata-modules/permissions/constants/tool-permission-flags';
import {
@@ -17,21 +17,21 @@ import { SyncableEntity } from 'src/engine/workspace-manager/workspace-sync/inte
import { ApiKeyEntity } from 'src/engine/core-modules/api-key/api-key.entity';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
@Entity('roleTargets')
@Unique('IDX_ROLE_TARGETS_UNIQUE_USER_WORKSPACE', [
@Entity('roleTarget')
@Unique('IDX_ROLE_TARGET_UNIQUE_USER_WORKSPACE', [
'workspaceId',
'userWorkspaceId',
])
@Unique('IDX_ROLE_TARGETS_UNIQUE_AGENT', ['workspaceId', 'agentId'])
@Unique('IDX_ROLE_TARGETS_UNIQUE_API_KEY', ['workspaceId', 'apiKeyId'])
@Index('IDX_ROLE_TARGETS_WORKSPACE_ID', ['userWorkspaceId', 'workspaceId'])
@Index('IDX_ROLE_TARGETS_AGENT_ID', ['agentId'])
@Index('IDX_ROLE_TARGETS_API_KEY_ID', ['apiKeyId'])
@Unique('IDX_ROLE_TARGET_UNIQUE_AGENT', ['workspaceId', 'agentId'])
@Unique('IDX_ROLE_TARGET_UNIQUE_API_KEY', ['workspaceId', 'apiKeyId'])
@Index('IDX_ROLE_TARGET_WORKSPACE_ID', ['userWorkspaceId', 'workspaceId'])
@Index('IDX_ROLE_TARGET_AGENT_ID', ['agentId'])
@Index('IDX_ROLE_TARGET_API_KEY_ID', ['apiKeyId'])
@Check(
'CHK_role_targets_single_entity',
'CHK_role_target_single_entity',
'("agentId" IS NOT NULL AND "userWorkspaceId" IS NULL AND "apiKeyId" IS NULL) OR ("agentId" IS NULL AND "userWorkspaceId" IS NOT NULL AND "apiKeyId" IS NULL) OR ("agentId" IS NULL AND "userWorkspaceId" IS NULL AND "apiKeyId" IS NOT NULL)',
)
export class RoleTargetsEntity extends SyncableEntity {
export class RoleTargetEntity extends SyncableEntity {
@PrimaryGeneratedColumn('uuid')
id: string;
@@ -1,7 +1,11 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ApplicationModule } from 'src/engine/core-modules/application/application.module';
import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { WorkspaceApiKeyRoleMapCacheService } from 'src/engine/metadata-modules/role-target/services/workspace-api-key-role-map-cache.service';
import { WorkspaceUserWorkspaceRoleMapCacheService } from 'src/engine/metadata-modules/role-target/services/workspace-user-workspace-role-map-cache.service';
import { WorkspaceMigrationV2Module } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-v2.module';
import { RoleTargetService } from './services/role-target.service';
@@ -11,8 +15,13 @@ import { RoleTargetService } from './services/role-target.service';
WorkspaceManyOrAllFlatEntityMapsCacheModule,
WorkspaceMigrationV2Module,
ApplicationModule,
TypeOrmModule.forFeature([RoleTargetEntity]),
],
providers: [
RoleTargetService,
WorkspaceUserWorkspaceRoleMapCacheService,
WorkspaceApiKeyRoleMapCacheService,
],
providers: [RoleTargetService],
exports: [RoleTargetService],
})
export class RoleTargetModule {}
@@ -5,7 +5,7 @@ import { IsNull, Not, Repository } from 'typeorm';
import { WorkspaceCacheProvider } from 'src/engine/workspace-cache/interfaces/workspace-cache-provider.service';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
@Injectable()
@@ -14,14 +14,14 @@ export class WorkspaceApiKeyRoleMapCacheService extends WorkspaceCacheProvider<
Record<string, string>
> {
constructor(
@InjectRepository(RoleTargetsEntity)
private readonly roleTargetsRepository: Repository<RoleTargetsEntity>,
@InjectRepository(RoleTargetEntity)
private readonly roleTargetRepository: Repository<RoleTargetEntity>,
) {
super();
}
async computeForCache(workspaceId: string): Promise<Record<string, string>> {
const roleTargetsMap = await this.roleTargetsRepository.find({
const roleTargetsMap = await this.roleTargetRepository.find({
where: {
workspaceId,
apiKeyId: Not(IsNull()),
@@ -6,22 +6,23 @@ import { IsNull, Not, Repository } from 'typeorm';
import { WorkspaceCacheProvider } from 'src/engine/workspace-cache/interfaces/workspace-cache-provider.service';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { UserWorkspaceRoleMap } from 'src/engine/metadata-modules/workspace-permissions-cache/types/user-workspace-role-map.type';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
export type UserWorkspaceRoleMap = Record<string, string>;
@Injectable()
@WorkspaceCache('userWorkspaceRoleMap')
export class WorkspaceUserWorkspaceRoleMapCacheService extends WorkspaceCacheProvider<UserWorkspaceRoleMap> {
constructor(
@InjectRepository(RoleTargetsEntity)
private readonly roleTargetsRepository: Repository<RoleTargetsEntity>,
@InjectRepository(RoleTargetEntity)
private readonly roleTargetRepository: Repository<RoleTargetEntity>,
) {
super();
}
async computeForCache(workspaceId: string): Promise<UserWorkspaceRoleMap> {
const roleTargetsMap = await this.roleTargetsRepository.find({
const roleTargetsMap = await this.roleTargetRepository.find({
where: {
workspaceId,
userWorkspaceId: Not(IsNull()),
@@ -8,7 +8,7 @@ import { AgentDTO } from 'src/engine/metadata-modules/ai/ai-agent/dtos/agent.dto
import { FieldPermissionDTO } from 'src/engine/metadata-modules/object-permission/dtos/field-permission.dto';
import { ObjectPermissionDTO } from 'src/engine/metadata-modules/object-permission/dtos/object-permission.dto';
import { PermissionFlagDTO } from 'src/engine/metadata-modules/permission-flag/dtos/permission-flag.dto';
import { type RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { type RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
@ObjectType('ApiKeyForRole')
export class ApiKeyForRoleDTO {
@@ -55,7 +55,7 @@ export class RoleDTO {
canBeAssignedToApiKeys: boolean;
@HideField()
roleTargets?: Relation<RoleTargetsEntity[]>;
roleTargets?: Relation<RoleTargetEntity[]>;
@Field(() => [WorkspaceMemberDTO], { nullable: true })
workspaceMembers?: WorkspaceMemberDTO[];
@@ -14,7 +14,7 @@ import { SyncableEntity } from 'src/engine/workspace-manager/workspace-sync/inte
import { FieldPermissionEntity } from 'src/engine/metadata-modules/object-permission/field-permission/field-permission.entity';
import { ObjectPermissionEntity } from 'src/engine/metadata-modules/object-permission/object-permission.entity';
import { PermissionFlagEntity } from 'src/engine/metadata-modules/permission-flag/permission-flag.entity';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
@Entity('role')
@Unique('IDX_ROLE_LABEL_WORKSPACE_ID_UNIQUE', ['label', 'workspaceId'])
@@ -74,10 +74,10 @@ export class RoleEntity extends SyncableEntity implements Required<RoleEntity> {
canBeAssignedToApiKeys: boolean;
@OneToMany(
() => RoleTargetsEntity,
(roleTargets: RoleTargetsEntity) => roleTargets.role,
() => RoleTargetEntity,
(roleTargets: RoleTargetEntity) => roleTargets.role,
)
roleTargets: Relation<RoleTargetsEntity[]>;
roleTargets: Relation<RoleTargetEntity[]>;
@OneToMany(
() => ObjectPermissionEntity,
@@ -9,19 +9,20 @@ import { UserWorkspaceModule } from 'src/engine/core-modules/user-workspace/user
import { AiAgentRoleModule } from 'src/engine/metadata-modules/ai/ai-agent-role/ai-agent-role.module';
import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module';
import { WorkspaceFlatRoleTargetMapCacheService } from 'src/engine/metadata-modules/flat-role-target/services/workspace-flat-role-target-map-cache.service';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { FieldPermissionEntity } from 'src/engine/metadata-modules/object-permission/field-permission/field-permission.entity';
import { ObjectPermissionEntity } from 'src/engine/metadata-modules/object-permission/object-permission.entity';
import { ObjectPermissionModule } from 'src/engine/metadata-modules/object-permission/object-permission.module';
import { PermissionFlagEntity } from 'src/engine/metadata-modules/permission-flag/permission-flag.entity';
import { PermissionFlagModule } from 'src/engine/metadata-modules/permission-flag/permission-flag.module';
import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import { RoleResolver } from 'src/engine/metadata-modules/role/role.resolver';
import { RoleService } from 'src/engine/metadata-modules/role/role.service';
import { WorkspaceFlatRoleMapCacheService } from 'src/engine/metadata-modules/role/services/workspace-flat-role-map-cache.service';
import { WorkspaceRolesPermissionsCacheService } from 'src/engine/metadata-modules/role/services/workspace-roles-permissions-cache.service';
import { UserRoleModule } from 'src/engine/metadata-modules/user-role/user-role.module';
import { WorkspacePermissionsCacheModule } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.module';
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
import { WorkspaceMigrationBuilderGraphqlApiExceptionInterceptor } from 'src/engine/workspace-manager/workspace-migration-v2/interceptors/workspace-migration-builder-graphql-api-exception.interceptor';
import { WorkspaceMigrationV2Module } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-v2.module';
@@ -30,11 +31,12 @@ import { WorkspaceMigrationV2Module } from 'src/engine/workspace-manager/workspa
imports: [
TypeOrmModule.forFeature([
RoleEntity,
RoleTargetsEntity,
RoleTargetEntity,
ObjectPermissionEntity,
PermissionFlagEntity,
FieldPermissionEntity,
UserWorkspaceEntity,
ObjectMetadataEntity,
]),
UserRoleModule,
AiAgentRoleModule,
@@ -43,7 +45,6 @@ import { WorkspaceMigrationV2Module } from 'src/engine/workspace-manager/workspa
PermissionsModule,
ObjectPermissionModule,
PermissionFlagModule,
WorkspacePermissionsCacheModule,
WorkspaceManyOrAllFlatEntityMapsCacheModule,
WorkspaceMigrationV2Module,
UserWorkspaceModule,
@@ -57,6 +58,7 @@ import { WorkspaceMigrationV2Module } from 'src/engine/workspace-manager/workspa
WorkspaceFlatRoleMapCacheService,
WorkspaceFlatRoleTargetMapCacheService,
WorkspaceMigrationBuilderGraphqlApiExceptionInterceptor,
WorkspaceRolesPermissionsCacheService,
],
exports: [
RoleService,
@@ -16,7 +16,7 @@ import {
import { msg } from '@lingui/core/macro';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { ApiKeyRoleService } from 'src/engine/core-modules/api-key/api-key-role.service';
import { ApiKeyRoleService } from 'src/engine/core-modules/api-key/services/api-key-role.service';
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { PreventNestToAutoLogGraphqlErrorsFilter } from 'src/engine/core-modules/graphql/filters/prevent-nest-to-auto-log-graphql-errors.filter';
@@ -12,7 +12,7 @@ import { fromRoleEntityToFlatRole } from 'src/engine/metadata-modules/flat-role/
import { FieldPermissionEntity } from 'src/engine/metadata-modules/object-permission/field-permission/field-permission.entity';
import { ObjectPermissionEntity } from 'src/engine/metadata-modules/object-permission/object-permission.entity';
import { PermissionFlagEntity } from 'src/engine/metadata-modules/permission-flag/permission-flag.entity';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
import { regroupEntitiesByRelatedEntityId } from 'src/engine/workspace-flat-map-cache/utils/regroup-entities-by-related-entity-id';
@@ -26,8 +26,8 @@ export class WorkspaceFlatRoleMapCacheService extends WorkspaceCacheProvider<
constructor(
@InjectRepository(RoleEntity)
private readonly roleRepository: Repository<RoleEntity>,
@InjectRepository(RoleTargetsEntity)
private readonly roleTargetsRepository: Repository<RoleTargetsEntity>,
@InjectRepository(RoleTargetEntity)
private readonly roleTargetRepository: Repository<RoleTargetEntity>,
@InjectRepository(ObjectPermissionEntity)
private readonly objectPermissionRepository: Repository<ObjectPermissionEntity>,
@InjectRepository(PermissionFlagEntity)
@@ -52,7 +52,7 @@ export class WorkspaceFlatRoleMapCacheService extends WorkspaceCacheProvider<
where: { workspaceId },
withDeleted: true,
}),
this.roleTargetsRepository.find({
this.roleTargetRepository.find({
where: { workspaceId },
select: ['id', 'roleId'],
withDeleted: true,
@@ -2,18 +2,16 @@ import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UserWorkspaceEntity } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { RoleTargetModule } from 'src/engine/metadata-modules/role-target/role-target.module';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role.service';
import { WorkspacePermissionsCacheModule } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.module';
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
@Module({
imports: [
TypeOrmModule.forFeature([RoleEntity, RoleTargetsEntity]),
TypeOrmModule.forFeature([RoleEntity, RoleTargetEntity]),
TypeOrmModule.forFeature([UserWorkspaceEntity]),
WorkspacePermissionsCacheModule,
WorkspaceCacheModule,
RoleTargetModule,
],
@@ -10,10 +10,9 @@ import {
PermissionsExceptionCode,
PermissionsExceptionMessage,
} from 'src/engine/metadata-modules/permissions/permissions.exception';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { RoleTargetService } from 'src/engine/metadata-modules/role-target/services/role-target.service';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import { WorkspacePermissionsCacheService } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.service';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
import { ADMIN_ROLE } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-roles/roles/admin-role';
@@ -21,12 +20,11 @@ import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/sta
export class UserRoleService {
constructor(
@InjectRepository(RoleTargetsEntity)
private readonly roleTargetsRepository: Repository<RoleTargetsEntity>,
@InjectRepository(RoleTargetEntity)
private readonly roleTargetRepository: Repository<RoleTargetEntity>,
@InjectRepository(UserWorkspaceEntity)
private readonly userWorkspaceRepository: Repository<UserWorkspaceEntity>,
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
private readonly workspacePermissionsCacheService: WorkspacePermissionsCacheService,
private readonly roleTargetService: RoleTargetService,
private readonly workspaceCacheService: WorkspaceCacheService,
) {}
@@ -90,7 +88,7 @@ export class UserRoleService {
return new Map();
}
const allRoleTargets = await this.roleTargetsRepository.find({
const allRoleTargets = await this.roleTargetRepository.find({
where: {
userWorkspaceId: In(userWorkspaceIds),
workspaceId,
@@ -1 +0,0 @@
export type UserWorkspaceRoleMap = Record<string, string>;
@@ -1,36 +0,0 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import { WorkspaceApiKeyRoleMapCacheService } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-api-key-role-map-cache.service';
import { WorkspaceRolesPermissionsCacheService } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-roles-permissions-cache.service';
import { WorkspaceUserWorkspaceRoleMapCacheService } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-user-workspace-role-map-cache.service';
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
import { WorkspacePermissionsCacheService } from './workspace-permissions-cache.service';
@Module({
imports: [
TypeOrmModule.forFeature([
ObjectMetadataEntity,
RoleEntity,
RoleTargetsEntity,
]),
WorkspaceCacheModule,
],
providers: [
WorkspacePermissionsCacheService,
WorkspaceRolesPermissionsCacheService,
WorkspaceUserWorkspaceRoleMapCacheService,
WorkspaceApiKeyRoleMapCacheService,
],
exports: [
WorkspacePermissionsCacheService,
WorkspaceRolesPermissionsCacheService,
WorkspaceUserWorkspaceRoleMapCacheService,
WorkspaceApiKeyRoleMapCacheService,
],
})
export class WorkspacePermissionsCacheModule {}
@@ -1,29 +0,0 @@
import { Injectable } from '@nestjs/common';
import { isDefined } from 'twenty-shared/utils';
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
@Injectable()
export class WorkspacePermissionsCacheService {
constructor(private readonly workspaceCacheService: WorkspaceCacheService) {}
async getRoleIdFromUserWorkspaceId({
workspaceId,
userWorkspaceId,
}: {
workspaceId: string;
userWorkspaceId?: string;
}): Promise<string | undefined> {
if (!isDefined(userWorkspaceId)) {
return;
}
const { userWorkspaceRoleMap } =
await this.workspaceCacheService.getOrRecompute(workspaceId, [
'userWorkspaceRoleMap',
]);
return userWorkspaceRoleMap[userWorkspaceId];
}
}
@@ -7,7 +7,6 @@ import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.ent
import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module';
import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module';
import { WorkspaceFeatureFlagsMapCacheModule } from 'src/engine/metadata-modules/workspace-feature-flags-map-cache/workspace-feature-flags-map-cache.module';
import { WorkspacePermissionsCacheModule } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.module';
import { EntitySchemaColumnFactory } from 'src/engine/twenty-orm/factories/entity-schema-column.factory';
import { EntitySchemaRelationFactory } from 'src/engine/twenty-orm/factories/entity-schema-relation.factory';
import { EntitySchemaFactory } from 'src/engine/twenty-orm/factories/entity-schema.factory';
@@ -24,7 +23,6 @@ import { WorkspaceEventEmitterModule } from 'src/engine/workspace-event-emitter/
DataSourceModule,
WorkspaceCacheStorageModule,
WorkspaceManyOrAllFlatEntityMapsCacheModule,
WorkspacePermissionsCacheModule,
WorkspaceFeatureFlagsMapCacheModule,
FeatureFlagModule,
TwentyConfigModule,
@@ -4,7 +4,7 @@ import { InjectRepository } from '@nestjs/typeorm';
import { isDefined } from 'twenty-shared/utils';
import { type ObjectLiteral, Repository } from 'typeorm';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { ScopedWorkspaceContextFactory } from 'src/engine/twenty-orm/factories/scoped-workspace-context.factory';
import { WorkspaceDatasourceFactory } from 'src/engine/twenty-orm/factories/workspace-datasource.factory';
import { type WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
@@ -13,8 +13,8 @@ import { convertClassNameToObjectMetadataName } from 'src/engine/workspace-manag
@Injectable()
export class TwentyORMManager {
constructor(
@InjectRepository(RoleTargetsEntity)
private readonly roleTargetsRepository: Repository<RoleTargetsEntity>,
@InjectRepository(RoleTargetEntity)
private readonly roleTargetRepository: Repository<RoleTargetEntity>,
private readonly workspaceDataSourceFactory: WorkspaceDatasourceFactory,
private readonly scopedWorkspaceContextFactory: ScopedWorkspaceContextFactory,
) {}
@@ -53,7 +53,7 @@ export class TwentyORMManager {
let roleId: string | undefined;
if (isDefined(userWorkspaceId)) {
const roleTarget = await this.roleTargetsRepository.findOne({
const roleTarget = await this.roleTargetRepository.findOne({
where: {
userWorkspaceId,
workspaceId,
@@ -62,7 +62,7 @@ export class TwentyORMManager {
roleId = roleTarget?.roleId;
} else if (isDefined(apiKeyId)) {
const roleTarget = await this.roleTargetsRepository.findOne({
const roleTarget = await this.roleTargetRepository.findOne({
where: {
apiKeyId,
workspaceId,
@@ -8,9 +8,8 @@ import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-s
import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { WorkspaceFeatureFlagsMapCacheModule } from 'src/engine/metadata-modules/workspace-feature-flags-map-cache/workspace-feature-flags-map-cache.module';
import { WorkspacePermissionsCacheModule } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.module';
import { entitySchemaFactories } from 'src/engine/twenty-orm/factories';
import { EntitySchemaFactory } from 'src/engine/twenty-orm/factories/entity-schema.factory';
import { ScopedWorkspaceContextFactory } from 'src/engine/twenty-orm/factories/scoped-workspace-context.factory';
@@ -26,7 +25,7 @@ import { PgPoolSharedModule } from './pg-shared-pool/pg-shared-pool.module';
imports: [
TypeOrmModule.forFeature([
ObjectMetadataEntity,
RoleTargetsEntity,
RoleTargetEntity,
WorkspaceEntity,
]),
DataSourceModule,
@@ -34,7 +33,6 @@ import { PgPoolSharedModule } from './pg-shared-pool/pg-shared-pool.module';
WorkspaceManyOrAllFlatEntityMapsCacheModule,
PermissionsModule,
WorkspaceFeatureFlagsMapCacheModule,
WorkspacePermissionsCacheModule,
FeatureFlagModule,
TwentyConfigModule,
PgPoolSharedModule,
@@ -0,0 +1,13 @@
import {
appendCommonExceptionCode,
CustomException,
} from 'src/utils/custom-exception';
export class WorkspaceCacheException extends CustomException<
keyof typeof WorkspaceCacheExceptionCode
> {}
export const WorkspaceCacheExceptionCode = appendCommonExceptionCode({
MISSING_DECORATOR: 'MISSING_DECORATOR',
INVALID_PARAMETERS: 'INVALID_PARAMETERS',
} as const);
@@ -8,7 +8,7 @@ import { CacheStorageNamespace } from 'src/engine/core-modules/cache-storage/typ
import { WORKSPACE_CACHE_KEY } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
const WORKSPACE_ID = 'test-workspace-id';
const WORKSPACE_ID = '20202020-0000-4000-8000-000000000000';
class MockFeatureFlagsCacheProvider extends WorkspaceCacheProvider<{
testData: string;
@@ -259,8 +259,8 @@ describe('WorkspaceCacheService', () => {
await service.invalidateAndRecompute(WORKSPACE_ID, ['featureFlagsMap']);
expect(cacheStorageService.mdel).toHaveBeenCalledWith([
'feature-flag:feature-flags-map:test-workspace-id:data',
'feature-flag:feature-flags-map:test-workspace-id:hash',
'feature-flag:feature-flags-map:20202020-0000-4000-8000-000000000000:data',
'feature-flag:feature-flags-map:20202020-0000-4000-8000-000000000000:hash',
]);
expect(mockProvider.computeForCache).toHaveBeenCalledWith(WORKSPACE_ID);
expect(cacheStorageService.mset).toHaveBeenCalled();
@@ -306,10 +306,10 @@ describe('WorkspaceCacheService', () => {
expect(cacheStorageService.mdel).toHaveBeenCalledWith(
expect.arrayContaining([
'feature-flag:feature-flags-map:test-workspace-id:data',
'feature-flag:feature-flags-map:test-workspace-id:hash',
'metadata:permissions:roles-permissions:test-workspace-id:data',
'metadata:permissions:roles-permissions:test-workspace-id:hash',
'feature-flag:feature-flags-map:20202020-0000-4000-8000-000000000000:data',
'feature-flag:feature-flags-map:20202020-0000-4000-8000-000000000000:hash',
'metadata:permissions:roles-permissions:20202020-0000-4000-8000-000000000000:data',
'metadata:permissions:roles-permissions:20202020-0000-4000-8000-000000000000:hash',
]),
);
});
@@ -322,8 +322,8 @@ describe('WorkspaceCacheService', () => {
await service.flush(WORKSPACE_ID, ['featureFlagsMap']);
expect(cacheStorageService.mdel).toHaveBeenCalledWith([
'feature-flag:feature-flags-map:test-workspace-id:data',
'feature-flag:feature-flags-map:test-workspace-id:hash',
'feature-flag:feature-flags-map:20202020-0000-4000-8000-000000000000:data',
'feature-flag:feature-flags-map:20202020-0000-4000-8000-000000000000:hash',
]);
});
@@ -3,7 +3,7 @@ import { DiscoveryService, Reflector } from '@nestjs/core';
import crypto from 'crypto';
import { isDefined } from 'twenty-shared/utils';
import { isDefined, isValidUuid } from 'twenty-shared/utils';
import { WorkspaceCacheProvider } from 'src/engine/workspace-cache/interfaces/workspace-cache-provider.service';
@@ -12,10 +12,14 @@ import { CacheStorageService } from 'src/engine/core-modules/cache-storage/servi
import { CacheStorageNamespace } from 'src/engine/core-modules/cache-storage/types/cache-storage-namespace.enum';
import { PromiseMemoizer } from 'src/engine/twenty-orm/storage/promise-memoizer.storage';
import { WORKSPACE_CACHE_KEY } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
import {
WorkspaceCacheException,
WorkspaceCacheExceptionCode,
} from 'src/engine/workspace-cache/exceptions/workspace-cache.exception';
import {
WORKSPACE_CACHE_KEYS_V2,
WorkspaceCacheKeyName,
type WorkspaceCacheDataMap,
type WorkspaceCacheKeyName,
type WorkspaceCacheResult,
} from 'src/engine/workspace-cache/types/workspace-cache-key.type';
import { type WorkspaceLocalCacheEntry } from 'src/engine/workspace-cache/types/workspace-local-cache-entry.type';
@@ -70,10 +74,21 @@ export class WorkspaceCacheService implements OnModuleInit {
}
}
async getOrRecompute<const K extends WorkspaceCacheKeyName[]>(
public async getOrRecompute<const K extends WorkspaceCacheKeyName[]>(
workspaceId: string,
workspaceCacheKeyNames: K,
): Promise<WorkspaceCacheResult<K>> {
if (
!isDefined(workspaceId) ||
workspaceCacheKeyNames.length === 0 ||
!isValidUuid(workspaceId)
) {
throw new WorkspaceCacheException(
'Invalid parameters: workspace ID and cache key names are required',
WorkspaceCacheExceptionCode.INVALID_PARAMETERS,
);
}
const memoKey =
`${workspaceId}-${[...workspaceCacheKeyNames].sort().join(',')}` as const;
@@ -117,7 +132,7 @@ export class WorkspaceCacheService implements OnModuleInit {
return result as WorkspaceCacheResult<K>;
}
async invalidateAndRecompute(
public async invalidateAndRecompute(
workspaceId: string,
workspaceCacheKeys: WorkspaceCacheKeyName[],
): Promise<void> {
@@ -127,7 +142,7 @@ export class WorkspaceCacheService implements OnModuleInit {
await this.recomputeCache(workspaceId, workspaceCacheKeys);
}
async flush(
public async flush(
workspaceId: string,
workspaceCacheKeys: WorkspaceCacheKeyName[],
): Promise<void> {
@@ -3,7 +3,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 AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
import { type UserWorkspaceRoleMap } from 'src/engine/metadata-modules/workspace-permissions-cache/types/user-workspace-role-map.type';
import { type UserWorkspaceRoleMap } from 'src/engine/metadata-modules/role-target/services/workspace-user-workspace-role-map-cache.service';
export const WORKSPACE_CACHE_KEYS_V2 = {
flatObjectMetadataMaps: 'flat-maps:object-metadata',
@@ -17,13 +17,11 @@ import { ViewFieldEntity } from 'src/engine/metadata-modules/view-field/entities
import { ViewFilterEntity } from 'src/engine/metadata-modules/view-filter/entities/view-filter.entity';
import { ViewGroupEntity } from 'src/engine/metadata-modules/view-group/entities/view-group.entity';
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
import { WorkspacePermissionsCacheModule } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.module';
import { WorkspaceFlatMapCacheRegistryService } from 'src/engine/workspace-flat-map-cache/services/workspace-flat-map-cache-registry.service';
@Module({
imports: [
DiscoveryModule,
WorkspacePermissionsCacheModule,
TypeOrmModule.forFeature([
ViewEntity,
ViewFieldEntity,
@@ -15,7 +15,7 @@ import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadat
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service';
import { PermissionsService } from 'src/engine/metadata-modules/permissions/permissions.service';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import { RoleService } from 'src/engine/metadata-modules/role/role.service';
import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role.service';
@@ -31,7 +31,7 @@ describe('WorkspaceManagerService', () => {
let workspaceMigrationRepository: Repository<WorkspaceMigrationEntity>;
let dataSourceRepository: Repository<DataSourceEntity>;
let workspaceDataSourceService: WorkspaceDataSourceService;
let roleTargetsRepository: Repository<RoleTargetsEntity>;
let roleTargetRepository: Repository<RoleTargetEntity>;
let roleRepository: Repository<RoleEntity>;
let mockDataSource: jest.Mocked<DataSource>;
let objectMetadataService: ObjectMetadataService;
@@ -83,7 +83,7 @@ describe('WorkspaceManagerService', () => {
},
},
{
provide: getRepositoryToken(RoleTargetsEntity),
provide: getRepositoryToken(RoleTargetEntity),
useValue: {
delete: jest.fn(),
},
@@ -165,8 +165,8 @@ describe('WorkspaceManagerService', () => {
workspaceDataSourceService = module.get<WorkspaceDataSourceService>(
WorkspaceDataSourceService,
);
roleTargetsRepository = module.get<Repository<RoleTargetsEntity>>(
getRepositoryToken(RoleTargetsEntity),
roleTargetRepository = module.get<Repository<RoleTargetEntity>>(
getRepositoryToken(RoleTargetEntity),
);
roleRepository = module.get<Repository<RoleEntity>>(
getRepositoryToken(RoleEntity),
@@ -192,7 +192,7 @@ describe('WorkspaceManagerService', () => {
expect(dataSourceRepository.delete).toHaveBeenCalledWith({
workspaceId: 'workspace-id',
});
expect(roleTargetsRepository.delete).toHaveBeenCalledWith({
expect(roleTargetRepository.delete).toHaveBeenCalledWith({
workspaceId: 'workspace-id',
});
expect(roleRepository.delete).toHaveBeenCalledWith({
@@ -16,7 +16,6 @@ import { ObjectPermissionModule } from 'src/engine/metadata-modules/object-permi
import { RoleTargetModule } from 'src/engine/metadata-modules/role-target/role-target.module';
import { RoleModule } from 'src/engine/metadata-modules/role/role.module';
import { UserRoleModule } from 'src/engine/metadata-modules/user-role/user-role.module';
import { WorkspacePermissionsCacheModule } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.module';
import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/workspace-cache-storage.module';
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module';
@@ -45,7 +44,6 @@ import { WorkspaceSyncMetadataModule } from 'src/engine/workspace-manager/worksp
WorkspaceSyncMetadataModule,
TypeOrmModule.forFeature([WorkspaceEntity, ObjectMetadataEntity]),
ObjectPermissionModule,
WorkspacePermissionsCacheModule,
WorkspaceManyOrAllFlatEntityMapsCacheModule,
WorkspaceCacheModule,
],
@@ -11,7 +11,7 @@ import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/
import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module';
import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module';
import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import { RoleModule } from 'src/engine/metadata-modules/role/role.module';
import { UserRoleModule } from 'src/engine/metadata-modules/user-role/user-role.module';
@@ -42,7 +42,7 @@ import { WorkspaceManagerService } from './workspace-manager.service';
ApplicationModule,
TypeOrmModule.forFeature([
FieldMetadataEntity,
RoleTargetsEntity,
RoleTargetEntity,
RoleEntity,
]),
],
@@ -12,7 +12,7 @@ import { type DataSourceEntity } from 'src/engine/metadata-modules/data-source/d
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import { RoleService } from 'src/engine/metadata-modules/role/role.service';
import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role.service';
@@ -45,8 +45,8 @@ export class WorkspaceManagerService {
private readonly workspaceRepository: Repository<WorkspaceEntity>,
@InjectRepository(RoleEntity)
private readonly roleRepository: Repository<RoleEntity>,
@InjectRepository(RoleTargetsEntity)
private readonly roleTargetsRepository: Repository<RoleTargetsEntity>,
@InjectRepository(RoleTargetEntity)
private readonly roleTargetRepository: Repository<RoleTargetEntity>,
protected readonly twentyORMGlobalManager: TwentyORMGlobalManager,
private readonly applicationService: ApplicationService,
private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
@@ -164,7 +164,7 @@ export class WorkspaceManagerService {
// TODO investigate why some entities are not on cascade delete
// Are foreign keys correctly applied ?
public async delete(workspaceId: string): Promise<void> {
await this.roleTargetsRepository.delete({
await this.roleTargetRepository.delete({
workspaceId,
});
await this.roleRepository.delete({
@@ -7,7 +7,7 @@ import {
import { AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { CreateRoleTargetAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/role-target/types/workspace-migration-role-target-action-v2.type';
import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/types/workspace-migration-action-runner-args.type';
@@ -39,7 +39,7 @@ export class CreateRoleTargetActionHandlerService extends WorkspaceMigrationRunn
const { roleTarget } = action;
const roleTargetRepository =
queryRunner.manager.getRepository<RoleTargetsEntity>(RoleTargetsEntity);
queryRunner.manager.getRepository<RoleTargetEntity>(RoleTargetEntity);
await roleTargetRepository.insert({
...roleTarget,
@@ -7,7 +7,7 @@ import {
import { AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
import { deleteFlatEntityFromFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/delete-flat-entity-from-flat-entity-maps-or-throw.util';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { DeleteRoleTargetAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/role-target/types/workspace-migration-role-target-action-v2.type';
import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/types/workspace-migration-action-runner-args.type';
@@ -45,7 +45,7 @@ export class DeleteRoleTargetActionHandlerService extends WorkspaceMigrationRunn
const { roleTargetId } = action;
const roleTargetRepository =
queryRunner.manager.getRepository<RoleTargetsEntity>(RoleTargetsEntity);
queryRunner.manager.getRepository<RoleTargetEntity>(RoleTargetEntity);
await roleTargetRepository.delete({
id: roleTargetId,
@@ -8,7 +8,7 @@ import {
import { AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
import { replaceFlatEntityInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/replace-flat-entity-in-flat-entity-maps-or-throw.util';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { UpdateRoleTargetAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/role-target/types/workspace-migration-role-target-action-v2.type';
import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/types/workspace-migration-action-runner-args.type';
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
@@ -55,7 +55,7 @@ export class UpdateRoleTargetActionHandlerService extends WorkspaceMigrationRunn
const { roleTargetId } = action;
const roleTargetRepository =
queryRunner.manager.getRepository<RoleTargetsEntity>(RoleTargetsEntity);
queryRunner.manager.getRepository<RoleTargetEntity>(RoleTargetEntity);
const update = fromFlatEntityPropertiesUpdatesToPartialFlatEntity(action);
@@ -6,7 +6,6 @@ import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-
import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module';
import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module';
import { WorkspaceMetadataVersionModule } from 'src/engine/metadata-modules/workspace-metadata-version/workspace-metadata-version.module';
import { WorkspacePermissionsCacheModule } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.module';
import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/workspace-cache-storage.module';
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
import { WorkspaceSchemaMigrationRunnerActionHandlersModule } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/workspace-schema-migration-runner-action-handlers.module';
@@ -19,7 +18,6 @@ import { WorkspaceMigrationRunnerV2Service } from 'src/engine/workspace-manager/
TypeORMModule,
DataSourceModule,
WorkspaceMetadataVersionModule,
WorkspacePermissionsCacheModule,
WorkspaceSchemaMigrationRunnerActionHandlersModule,
WorkspaceManyOrAllFlatEntityMapsCacheModule,
DiscoveryModule,
@@ -8,7 +8,7 @@ import { type WorkspaceSyncContext } from 'src/engine/workspace-manager/workspac
import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity';
import { transformAgentEntityToFlatAgent } from 'src/engine/metadata-modules/flat-agent/utils/transform-agent-entity-to-flat-agent.util';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import { WorkspaceAgentComparator } from 'src/engine/workspace-manager/workspace-sync-metadata/comparators/workspace-agent.comparator';
import { StandardAgentFactory } from 'src/engine/workspace-manager/workspace-sync-metadata/factories/standard-agent.factory';
@@ -86,10 +86,10 @@ export class WorkspaceSyncAgentService {
);
}
const roleTargetsRepository =
manager.getRepository(RoleTargetsEntity);
const roleTargetRepository =
manager.getRepository(RoleTargetEntity);
await roleTargetsRepository.save({
await roleTargetRepository.save({
roleId: role.id,
agentId: createdAgent.id,
workspaceId: context.workspaceId,
@@ -137,10 +137,10 @@ export class WorkspaceSyncAgentService {
);
}
const roleTargetsRepository =
manager.getRepository(RoleTargetsEntity);
const roleTargetRepository =
manager.getRepository(RoleTargetEntity);
await roleTargetsRepository.save({
await roleTargetRepository.save({
roleId: role.id,
agentId: agentToUpdate.id,
workspaceId: context.workspaceId,
@@ -4,7 +4,7 @@ import { getRepositoryToken } from '@nestjs/typeorm';
import { AiAgentRoleService } from 'src/engine/metadata-modules/ai/ai-agent-role/ai-agent-role.service';
import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import { type ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity';
import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service';
@@ -24,7 +24,7 @@ describe('WorkflowVersionStepOperationsWorkspaceService', () => {
let twentyORMGlobalManager: jest.Mocked<TwentyORMGlobalManager>;
let serverlessFunctionService: jest.Mocked<ServerlessFunctionService>;
let agentRepository: jest.Mocked<any>;
let roleTargetsRepository: jest.Mocked<any>;
let roleTargetRepository: jest.Mocked<any>;
let roleRepository: jest.Mocked<any>;
let objectMetadataRepository: jest.Mocked<any>;
let workflowCommonWorkspaceService: jest.Mocked<WorkflowCommonWorkspaceService>;
@@ -44,7 +44,7 @@ describe('WorkflowVersionStepOperationsWorkspaceService', () => {
delete: jest.fn(),
};
roleTargetsRepository = {
roleTargetRepository = {
findOne: jest.fn(),
count: jest.fn(),
};
@@ -86,8 +86,8 @@ describe('WorkflowVersionStepOperationsWorkspaceService', () => {
useValue: agentRepository,
},
{
provide: getRepositoryToken(RoleTargetsEntity),
useValue: roleTargetsRepository,
provide: getRepositoryToken(RoleTargetEntity),
useValue: roleTargetRepository,
},
{
provide: getRepositoryToken(RoleEntity),
@@ -208,7 +208,7 @@ describe('WorkflowVersionStepOperationsWorkspaceService', () => {
} as unknown as WorkflowAction;
agentRepository.findOne.mockResolvedValue({ id: 'agent-id' });
roleTargetsRepository.findOne.mockResolvedValue({
roleTargetRepository.findOne.mockResolvedValue({
id: 'role-target-id',
roleId: 'role-id',
});
@@ -13,7 +13,7 @@ import { AiAgentRoleService } from 'src/engine/metadata-modules/ai/ai-agent-role
import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity';
import { DEFAULT_SMART_MODEL } from 'src/engine/metadata-modules/ai/ai-models/constants/ai-models.const';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
import {
@@ -55,8 +55,8 @@ export class WorkflowVersionStepOperationsWorkspaceService {
private readonly serverlessFunctionService: ServerlessFunctionService,
@InjectRepository(AgentEntity)
private readonly agentRepository: Repository<AgentEntity>,
@InjectRepository(RoleTargetsEntity)
private readonly roleTargetsRepository: Repository<RoleTargetsEntity>,
@InjectRepository(RoleTargetEntity)
private readonly roleTargetRepository: Repository<RoleTargetEntity>,
@InjectRepository(ObjectMetadataEntity)
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
private readonly workflowCommonWorkspaceService: WorkflowCommonWorkspaceService,
@@ -95,7 +95,7 @@ export class WorkflowVersionStepOperationsWorkspaceService {
});
if (isDefined(agent)) {
const roleTarget = await this.roleTargetsRepository.findOne({
const roleTarget = await this.roleTargetRepository.findOne({
where: {
agentId: agent.id,
workspaceId,
@@ -5,7 +5,7 @@ import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm';
import { AiAgentRoleModule } from 'src/engine/metadata-modules/ai/ai-agent-role/ai-agent-role.module';
import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import { ServerlessFunctionModule } from 'src/engine/metadata-modules/serverless-function/serverless-function.module';
import { WorkflowCommonModule } from 'src/modules/workflow/common/workflow-common.module';
@@ -26,7 +26,7 @@ import { WorkflowVersionStepWorkspaceService } from 'src/modules/workflow/workfl
NestjsQueryTypeOrmModule.forFeature([
ObjectMetadataEntity,
AgentEntity,
RoleTargetsEntity,
RoleTargetEntity,
RoleEntity,
]),
],
@@ -11,7 +11,7 @@ import { AgentService } from 'src/engine/metadata-modules/ai/ai-agent/agent.serv
import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity';
import { AgentChatService } from 'src/engine/metadata-modules/ai/ai-chat/services/agent-chat.service';
import { PermissionsService } from 'src/engine/metadata-modules/permissions/permissions.service';
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
// Mock the guards and decorators
jest.mock('../../../../../src/engine/guards/feature-flag.guard', () => ({
@@ -54,7 +54,7 @@ describe('agentResolver', () => {
},
},
{
provide: getRepositoryToken(RoleTargetsEntity),
provide: getRepositoryToken(RoleTargetEntity),
useValue: {
findOne: jest.fn(),
},
@@ -203,7 +203,7 @@ describe('Successful user and workspace creation', () => {
'searchFieldMetadata',
'workspaceMigration',
'role',
'roleTargets',
'roleTarget',
'objectPermission',
'fieldPermission',
'permissionFlag',