mirror of
https://github.com/twentyhq/twenty.git
synced 2026-06-11 17:37:18 -04:00
refactor(twenty-orm): migrate 23 grandfathered entities to WorkspaceScopedRepository (#20987)
## Summary Follow-up to #20953. Migrates 23 of the 30 entities that were left in `WORKSPACE_SCOPED_EXEMPTIONS` last time, so the lint rule's workspaceId-enforcement default now covers most of the core/metadata schema. ### Migrated (23 entities, 88 files, 22 commits) | Family | Entities | |---|---| | Trivial caches | `NavigationMenuItem`, `Skill`, `DataSource`, `Webhook`, `CommandMenuItem`, `IndexMetadata` | | Views | `View`, `ViewField`, `ViewFieldGroup`, `ViewFilter`, `ViewFilterGroup`, `ViewGroup`, `ViewSort` | | Layouts | `PageLayout`, `PageLayoutTab`, `PageLayoutWidget` | | Roles & permissions | `Role`, `RoleTarget`, `PermissionFlag`, `ObjectPermission`, `FieldPermission`, `RowLevelPermissionPredicate`, `RowLevelPermissionPredicateGroup` | For each entity: swap `@InjectRepository(X)` → `@InjectWorkspaceScopedRepository(X)` (and the field type → `WorkspaceScopedRepository<X>`); rewrite every call site to pass `workspaceId` as the first arg (stripped from `where`/criteria — the wrapper throws if you include it now); register `provideWorkspaceScopedRepository(X)` in every owning NestJS module; update affected spec providers to `getWorkspaceScopedRepositoryToken(X)`. ### Rule update - `ApplicationRegistrationVariableEntity` was misclassified — moved to `STRUCTURAL_EXEMPTIONS` (no `workspaceId` column; it's keyed on `applicationRegistrationId` at the instance level). - 22 of the 23 migrated entities removed from `WORKSPACE_SCOPED_EXEMPTIONS` entirely (zero remaining raw `@InjectRepository` sites). - `RoleTargetEntity` also removed; one call site in `user-workspace.service.ts` keeps a raw injection with an `eslint-disable` + reason because `softRemove(...)` is not on the wrapper API yet (the migration would require threading `workspaceId` through `deleteUserWorkspace`'s three callers). ### Still exempted (7 entities, follow-up PRs) | Entity | Why deferred | |---|---| | `ApplicationEntity` | ~50 sites with several cross-workspace lookups by id (auth, OAuth, file-storage, cleanup) | | `CalendarChannelEntity` / `MessageChannelEntity` | Use `.increment(...)` (not on wrapper) and `repository.manager.transaction(...)` — wrapper needs to grow `.increment` + the transaction sites need `withManager` or dual-inject | | `FieldMetadataEntity` / `ObjectMetadataEntity` | The metadata services `extends TypeOrmQueryService<X>` and `super(rawRepo)` — requires dual-inject or reworking the inheritance | | `KeyValuePairEntity` | Allows `workspaceId: IsNull()` for instance-level config; wrapper rejects null | | `UpgradeMigrationEntity` | Same — instance-level + cross-workspace ledger | ## Test plan - [x] `npx nx typecheck twenty-server` — clean - [x] `npx nx lint twenty-server` — clean (0/0) - [x] All 10 affected unit specs pass (115 tests) — api-key, agent-role, permissions, workspace-roles-permissions-cache, view-filter-group, workflow-version-step-operations, two-factor-authentication (service + resolver), user-workspace, file - [ ] Server integration tests in CI
This commit is contained in:
@@ -2,12 +2,18 @@ import { defineRule } from '@oxlint/plugins';
|
||||
|
||||
export const RULE_NAME = 'prefer-workspace-scoped-repository';
|
||||
|
||||
// Entities that legitimately do not carry a workspaceId column.
|
||||
// Entities that do not fit the scoped wrapper: workspace itself, pivots,
|
||||
// nullable-workspaceId rows (instance-level config / migrations / tokens),
|
||||
// and global tables with no workspaceId column at all.
|
||||
const STRUCTURAL_EXEMPTIONS = new Set<string>([
|
||||
'WorkspaceEntity',
|
||||
'UserWorkspaceEntity',
|
||||
'AppTokenEntity',
|
||||
'ApplicationRegistrationEntity',
|
||||
'ApplicationRegistrationVariableEntity',
|
||||
// nullable workspaceId — both rows support instance-level and per-workspace use
|
||||
'KeyValuePairEntity',
|
||||
'UpgradeMigrationEntity',
|
||||
|
||||
'ApplicationVariableEntity',
|
||||
'BillingMeterEntity',
|
||||
@@ -25,39 +31,25 @@ const STRUCTURAL_EXEMPTIONS = new Set<string>([
|
||||
'WorkspaceSSOIdentityProviderEntity',
|
||||
]);
|
||||
|
||||
// Workspace-scoped entities exempted from the wrapper at the call site.
|
||||
// Workspace-scoped entities the wrapper could technically wrap, but where
|
||||
// the dominant access patterns are cross-workspace (request routing, auth,
|
||||
// metadata sync, file storage, transaction-bound channel updates) and the
|
||||
// payoff doesn't justify dual-injecting every call site or growing the
|
||||
// wrapper API. Treat as a "deliberately not migrated" list, not a backlog.
|
||||
const WORKSPACE_SCOPED_EXEMPTIONS = new Set<string>([
|
||||
// Resolved by id alone at auth/request-routing time and inside file-storage
|
||||
// transactions; very few of the ~50 call sites carry a workspaceId.
|
||||
'ApplicationEntity',
|
||||
'ApplicationRegistrationVariableEntity',
|
||||
// 20+ call sites across calendar/messaging modules; staged for a dedicated PR.
|
||||
'CalendarChannelEntity',
|
||||
'CommandMenuItemEntity',
|
||||
'DataSourceEntity',
|
||||
'FieldMetadataEntity',
|
||||
'FieldPermissionEntity',
|
||||
'IndexMetadataEntity',
|
||||
'KeyValuePairEntity',
|
||||
'MessageChannelEntity',
|
||||
'NavigationMenuItemEntity',
|
||||
// The owning services `extends TypeOrmQueryService<E>` and pass the raw
|
||||
// repo to `super(...)`; the superclass type doesn't accept the wrapper.
|
||||
'FieldMetadataEntity',
|
||||
'ObjectMetadataEntity',
|
||||
'ObjectPermissionEntity',
|
||||
'PageLayoutEntity',
|
||||
'PageLayoutTabEntity',
|
||||
'PageLayoutWidgetEntity',
|
||||
'PermissionFlagEntity',
|
||||
'RoleEntity',
|
||||
'RoleTargetEntity',
|
||||
'RowLevelPermissionPredicateEntity',
|
||||
'RowLevelPermissionPredicateGroupEntity',
|
||||
'SkillEntity',
|
||||
'UpgradeMigrationEntity',
|
||||
'ViewEntity',
|
||||
'ViewFieldEntity',
|
||||
'ViewFieldGroupEntity',
|
||||
'ViewFilterEntity',
|
||||
'ViewFilterGroupEntity',
|
||||
'ViewGroupEntity',
|
||||
'ViewSortEntity',
|
||||
'WebhookEntity',
|
||||
// Only injection lives in a frozen historical upgrade-version-command
|
||||
// directory that CI's mutation-guard refuses to let us edit.
|
||||
'DataSourceEntity',
|
||||
]);
|
||||
|
||||
// Everything else must use @InjectWorkspaceScopedRepository.
|
||||
|
||||
@@ -36,6 +36,8 @@ import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.ent
|
||||
import { WorkspaceModule } from 'src/engine/core-modules/workspace/workspace.module';
|
||||
import { FieldMetadataModule } from 'src/engine/metadata-modules/field-metadata/field-metadata.module';
|
||||
import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module';
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
import { TrashCleanupModule } from 'src/engine/trash-cleanup/trash-cleanup.module';
|
||||
import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/workspace-cache-storage.module';
|
||||
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
|
||||
@@ -52,7 +54,7 @@ import { AutomatedTriggerModule } from 'src/modules/workflow/workflow-trigger/au
|
||||
@Module({
|
||||
imports: [
|
||||
UpgradeVersionCommandModule,
|
||||
TypeOrmModule.forFeature([WorkspaceEntity]),
|
||||
TypeOrmModule.forFeature([WorkspaceEntity, RoleEntity]),
|
||||
WorkspaceExportModule,
|
||||
// Cron command dependencies
|
||||
MessagingImportManagerModule,
|
||||
@@ -102,6 +104,7 @@ import { AutomatedTriggerModule } from 'src/modules/workflow/workflow-trigger/au
|
||||
UpgradeStatusCommand,
|
||||
RebuildApplicationDefaultDepsCommand,
|
||||
InstallPreInstalledAppsCommand,
|
||||
provideWorkspaceScopedRepository(RoleEntity),
|
||||
],
|
||||
})
|
||||
export class DatabaseCommandModule {}
|
||||
|
||||
@@ -44,6 +44,8 @@ import { ApiKeyController } from './controllers/api-key.controller';
|
||||
WorkspaceApiKeyMapCacheService,
|
||||
GenerateApiKeyCommand,
|
||||
provideWorkspaceScopedRepository(ApiKeyEntity),
|
||||
provideWorkspaceScopedRepository(RoleEntity),
|
||||
provideWorkspaceScopedRepository(RoleTargetEntity),
|
||||
],
|
||||
controllers: [ApiKeyController],
|
||||
exports: [
|
||||
|
||||
@@ -13,6 +13,8 @@ import { ApiKeyService } from 'src/engine/core-modules/api-key/services/api-key.
|
||||
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
|
||||
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { STANDARD_ROLE } from 'src/engine/workspace-manager/twenty-standard-application/constants/standard-role.constant';
|
||||
|
||||
type GenerateApiKeyCommandOptions = {
|
||||
@@ -33,8 +35,8 @@ export class GenerateApiKeyCommand extends CommandRunner {
|
||||
constructor(
|
||||
@InjectRepository(WorkspaceEntity)
|
||||
private readonly workspaceRepository: Repository<WorkspaceEntity>,
|
||||
@InjectRepository(RoleEntity)
|
||||
private readonly roleRepository: Repository<RoleEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleEntity)
|
||||
private readonly roleRepository: WorkspaceScopedRepository<RoleEntity>,
|
||||
private readonly apiKeyService: ApiKeyService,
|
||||
private readonly twentyConfigService: TwentyConfigService,
|
||||
) {
|
||||
@@ -104,9 +106,8 @@ export class GenerateApiKeyCommand extends CommandRunner {
|
||||
return;
|
||||
}
|
||||
|
||||
const adminRole = await this.roleRepository.findOne({
|
||||
const adminRole = await this.roleRepository.findOne(workspace.id, {
|
||||
where: {
|
||||
workspaceId: workspace.id,
|
||||
universalIdentifier: STANDARD_ROLE.admin.universalIdentifier,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Test, type TestingModule } from '@nestjs/testing';
|
||||
import { getDataSourceToken, getRepositoryToken } from '@nestjs/typeorm';
|
||||
import { getDataSourceToken } from '@nestjs/typeorm';
|
||||
|
||||
import { IsNull } from 'typeorm';
|
||||
|
||||
@@ -101,7 +101,7 @@ describe('ApiKeyService', () => {
|
||||
useValue: mockRoleTargetService,
|
||||
},
|
||||
{
|
||||
provide: getRepositoryToken(RoleTargetEntity),
|
||||
provide: getWorkspaceScopedRepositoryToken(RoleTargetEntity),
|
||||
useValue: mockroleTargetRepository,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { In, IsNull, Not, Repository } from 'typeorm';
|
||||
import { In, IsNull, Not } from 'typeorm';
|
||||
|
||||
import { ApiKeyEntity } from 'src/engine/core-modules/api-key/api-key.entity';
|
||||
import {
|
||||
@@ -23,10 +22,10 @@ import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/works
|
||||
@Injectable()
|
||||
export class ApiKeyRoleService {
|
||||
constructor(
|
||||
@InjectRepository(RoleTargetEntity)
|
||||
private readonly roleTargetRepository: Repository<RoleTargetEntity>,
|
||||
@InjectRepository(RoleEntity)
|
||||
private readonly roleRepository: Repository<RoleEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleTargetEntity)
|
||||
private readonly roleTargetRepository: WorkspaceScopedRepository<RoleTargetEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleEntity)
|
||||
private readonly roleRepository: WorkspaceScopedRepository<RoleEntity>,
|
||||
|
||||
@InjectWorkspaceScopedRepository(ApiKeyEntity)
|
||||
private readonly apiKeyRepository: WorkspaceScopedRepository<ApiKeyEntity>,
|
||||
@@ -141,8 +140,8 @@ export class ApiKeyRoleService {
|
||||
);
|
||||
}
|
||||
|
||||
const role = await this.roleRepository.findOne({
|
||||
where: { id: roleId, workspaceId },
|
||||
const role = await this.roleRepository.findOne(workspaceId, {
|
||||
where: { id: roleId },
|
||||
});
|
||||
|
||||
if (!role) {
|
||||
@@ -159,13 +158,15 @@ export class ApiKeyRoleService {
|
||||
);
|
||||
}
|
||||
|
||||
const existingRoleTarget = await this.roleTargetRepository.findOne({
|
||||
where: {
|
||||
apiKeyId,
|
||||
roleId,
|
||||
workspaceId,
|
||||
const existingRoleTarget = await this.roleTargetRepository.findOne(
|
||||
workspaceId,
|
||||
{
|
||||
where: {
|
||||
apiKeyId,
|
||||
roleId,
|
||||
},
|
||||
},
|
||||
});
|
||||
);
|
||||
|
||||
return {
|
||||
roleToAssignIsSameAsCurrentRole: Boolean(existingRoleTarget),
|
||||
@@ -183,10 +184,9 @@ export class ApiKeyRoleService {
|
||||
return new Map();
|
||||
}
|
||||
|
||||
const roleTargets = await this.roleTargetRepository.find({
|
||||
const roleTargets = await this.roleTargetRepository.find(workspaceId, {
|
||||
where: {
|
||||
apiKeyId: In(apiKeyIds),
|
||||
workspaceId,
|
||||
},
|
||||
relations: ['role'],
|
||||
});
|
||||
@@ -209,10 +209,9 @@ export class ApiKeyRoleService {
|
||||
roleId: string,
|
||||
workspaceId: string,
|
||||
): Promise<ApiKeyEntity[]> {
|
||||
const roleTargets = await this.roleTargetRepository.find({
|
||||
const roleTargets = await this.roleTargetRepository.find(workspaceId, {
|
||||
where: {
|
||||
roleId,
|
||||
workspaceId,
|
||||
apiKeyId: Not(IsNull()),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -39,6 +39,7 @@ import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache
|
||||
ApplicationService,
|
||||
WorkspaceFlatApplicationMapCacheService,
|
||||
provideWorkspaceScopedRepository(AgentEntity),
|
||||
provideWorkspaceScopedRepository(CommandMenuItemEntity),
|
||||
],
|
||||
})
|
||||
export class ApplicationModule {}
|
||||
|
||||
@@ -43,8 +43,8 @@ export class ApplicationService {
|
||||
private readonly agentRepository: WorkspaceScopedRepository<AgentEntity>,
|
||||
@InjectRepository(FrontComponentEntity)
|
||||
private readonly frontComponentRepository: Repository<FrontComponentEntity>,
|
||||
@InjectRepository(CommandMenuItemEntity)
|
||||
private readonly commandMenuItemRepository: Repository<CommandMenuItemEntity>,
|
||||
@InjectWorkspaceScopedRepository(CommandMenuItemEntity)
|
||||
private readonly commandMenuItemRepository: WorkspaceScopedRepository<CommandMenuItemEntity>,
|
||||
@InjectRepository(ObjectMetadataEntity)
|
||||
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
|
||||
@InjectRepository(ApplicationVariableEntity)
|
||||
@@ -206,8 +206,8 @@ export class ApplicationService {
|
||||
this.frontComponentRepository.find({
|
||||
where: { applicationId: application.id, workspaceId },
|
||||
}),
|
||||
this.commandMenuItemRepository.find({
|
||||
where: { applicationId: application.id, workspaceId },
|
||||
this.commandMenuItemRepository.find(workspaceId, {
|
||||
where: { applicationId: application.id },
|
||||
}),
|
||||
this.objectMetadataRepository.find({
|
||||
where: { applicationId: application.id, workspaceId },
|
||||
|
||||
@@ -51,6 +51,8 @@ export class UserWorkspaceService extends TypeOrmQueryService<UserWorkspaceEntit
|
||||
private readonly userWorkspaceRepository: Repository<UserWorkspaceEntity>,
|
||||
@InjectRepository(UserEntity)
|
||||
private readonly userRepository: Repository<UserEntity>,
|
||||
// softRemove is not supported by WorkspaceScopedRepository.
|
||||
// eslint-disable-next-line twenty/prefer-workspace-scoped-repository
|
||||
@InjectRepository(RoleTargetEntity)
|
||||
private readonly roleTargetRepository: Repository<RoleTargetEntity>,
|
||||
private readonly roleValidationService: RoleValidationService,
|
||||
@@ -311,6 +313,9 @@ export class UserWorkspaceService extends TypeOrmQueryService<UserWorkspaceEntit
|
||||
return await this.userWorkspaceRepository.count({ where: { userId } });
|
||||
}
|
||||
|
||||
// TODO migrate roleTargetRepository to WorkspaceScopedRepository once workspaceId
|
||||
// is threaded through all deleteUserWorkspace callers (user.service.ts does not
|
||||
// currently have it at the call site).
|
||||
async deleteUserWorkspace({
|
||||
userWorkspaceId,
|
||||
softDelete = false,
|
||||
|
||||
@@ -14,6 +14,7 @@ import { AiModelsModule } from 'src/engine/metadata-modules/ai/ai-models/ai-mode
|
||||
import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module';
|
||||
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 { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
|
||||
|
||||
import { AgentMessagePartEntity } from './entities/agent-message-part.entity';
|
||||
@@ -49,6 +50,7 @@ import { AgentAsyncExecutorService } from './services/agent-async-executor.servi
|
||||
AgentAsyncExecutorService,
|
||||
AgentActorContextService,
|
||||
AgentMessagePartResolver,
|
||||
provideWorkspaceScopedRepository(RoleTargetEntity),
|
||||
],
|
||||
exports: [
|
||||
AgentAsyncExecutorService,
|
||||
|
||||
@@ -45,6 +45,8 @@ import {
|
||||
} from 'src/engine/metadata-modules/ai/ai.exception';
|
||||
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
|
||||
import { type RolePermissionConfig } from 'src/engine/twenty-orm/types/role-permission-config';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
|
||||
const EMPTY_USAGE: LanguageModelUsage = {
|
||||
inputTokens: 0,
|
||||
@@ -75,8 +77,8 @@ export class AgentAsyncExecutorService {
|
||||
private readonly nativeToolBinder: NativeToolBinderService,
|
||||
private readonly aiBillingService: AiBillingService,
|
||||
private readonly billingUsageService: BillingUsageService,
|
||||
@InjectRepository(RoleTargetEntity)
|
||||
private readonly roleTargetRepository: Repository<RoleTargetEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleTargetEntity)
|
||||
private readonly roleTargetRepository: WorkspaceScopedRepository<RoleTargetEntity>,
|
||||
@InjectRepository(WorkspaceEntity)
|
||||
private readonly workspaceRepository: Repository<WorkspaceEntity>,
|
||||
) {}
|
||||
@@ -104,10 +106,9 @@ export class AgentAsyncExecutorService {
|
||||
workspaceId: string,
|
||||
rolePermissionConfig?: RolePermissionConfig,
|
||||
): Promise<RolePermissionConfig | undefined> {
|
||||
const roleTarget = await this.roleTargetRepository.findOne({
|
||||
const roleTarget = await this.roleTargetRepository.findOne(workspaceId, {
|
||||
where: {
|
||||
agentId,
|
||||
workspaceId,
|
||||
},
|
||||
select: ['roleId'],
|
||||
});
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import { Test, type TestingModule } from '@nestjs/testing';
|
||||
import { getRepositoryToken } from '@nestjs/typeorm';
|
||||
|
||||
import { type Repository } from 'typeorm';
|
||||
|
||||
import {
|
||||
AiException,
|
||||
@@ -20,8 +17,8 @@ import { AiAgentRoleService } from './ai-agent-role.service';
|
||||
describe('AiAgentRoleService', () => {
|
||||
let service: AiAgentRoleService;
|
||||
let agentRepository: WorkspaceScopedRepository<AgentEntity>;
|
||||
let roleRepository: Repository<RoleEntity>;
|
||||
let roleTargetRepository: Repository<RoleTargetEntity>;
|
||||
let roleRepository: WorkspaceScopedRepository<RoleEntity>;
|
||||
let roleTargetRepository: WorkspaceScopedRepository<RoleTargetEntity>;
|
||||
let roleTargetService: RoleTargetService;
|
||||
|
||||
const testWorkspaceId = 'test-workspace-id';
|
||||
@@ -42,19 +39,20 @@ describe('AiAgentRoleService', () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: getRepositoryToken(RoleEntity),
|
||||
provide: getWorkspaceScopedRepositoryToken(RoleEntity),
|
||||
useValue: {
|
||||
findOne: jest.fn(),
|
||||
save: jest.fn(),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: getRepositoryToken(RoleTargetEntity),
|
||||
provide: getWorkspaceScopedRepositoryToken(RoleTargetEntity),
|
||||
useValue: {
|
||||
findOne: jest.fn(),
|
||||
save: jest.fn(),
|
||||
delete: jest.fn(),
|
||||
find: jest.fn(),
|
||||
count: jest.fn(),
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -71,12 +69,12 @@ describe('AiAgentRoleService', () => {
|
||||
agentRepository = module.get<WorkspaceScopedRepository<AgentEntity>>(
|
||||
getWorkspaceScopedRepositoryToken(AgentEntity),
|
||||
);
|
||||
roleRepository = module.get<Repository<RoleEntity>>(
|
||||
getRepositoryToken(RoleEntity),
|
||||
);
|
||||
roleTargetRepository = module.get<Repository<RoleTargetEntity>>(
|
||||
getRepositoryToken(RoleTargetEntity),
|
||||
roleRepository = module.get<WorkspaceScopedRepository<RoleEntity>>(
|
||||
getWorkspaceScopedRepositoryToken(RoleEntity),
|
||||
);
|
||||
roleTargetRepository = module.get<
|
||||
WorkspaceScopedRepository<RoleTargetEntity>
|
||||
>(getWorkspaceScopedRepositoryToken(RoleTargetEntity));
|
||||
roleTargetService = module.get<RoleTargetService>(RoleTargetService);
|
||||
|
||||
// Setup test data
|
||||
@@ -153,16 +151,18 @@ describe('AiAgentRoleService', () => {
|
||||
expect(agentRepository.findOne).toHaveBeenCalledWith(testWorkspaceId, {
|
||||
where: { id: testAgent.id },
|
||||
});
|
||||
expect(roleRepository.findOne).toHaveBeenCalledWith({
|
||||
where: { id: testRole.id, workspaceId: testWorkspaceId },
|
||||
expect(roleRepository.findOne).toHaveBeenCalledWith(testWorkspaceId, {
|
||||
where: { id: testRole.id },
|
||||
});
|
||||
expect(roleTargetRepository.findOne).toHaveBeenCalledWith({
|
||||
where: {
|
||||
agentId: testAgent.id,
|
||||
roleId: testRole.id,
|
||||
workspaceId: testWorkspaceId,
|
||||
expect(roleTargetRepository.findOne).toHaveBeenCalledWith(
|
||||
testWorkspaceId,
|
||||
{
|
||||
where: {
|
||||
agentId: testAgent.id,
|
||||
roleId: testRole.id,
|
||||
},
|
||||
},
|
||||
});
|
||||
);
|
||||
expect(roleTargetService.create).toHaveBeenCalledWith({
|
||||
createRoleTargetInput: {
|
||||
roleId: testRole.id,
|
||||
@@ -335,12 +335,14 @@ describe('AiAgentRoleService', () => {
|
||||
});
|
||||
|
||||
// Assert
|
||||
expect(roleTargetRepository.findOne).toHaveBeenCalledWith({
|
||||
where: {
|
||||
agentId: testAgent.id,
|
||||
workspaceId: testWorkspaceId,
|
||||
expect(roleTargetRepository.findOne).toHaveBeenCalledWith(
|
||||
testWorkspaceId,
|
||||
{
|
||||
where: {
|
||||
agentId: testAgent.id,
|
||||
},
|
||||
},
|
||||
});
|
||||
);
|
||||
expect(roleTargetService.delete).toHaveBeenCalledWith({
|
||||
id: existingRoleTarget.id,
|
||||
workspaceId: testWorkspaceId,
|
||||
|
||||
@@ -16,6 +16,8 @@ import { AiAgentRoleService } from './ai-agent-role.service';
|
||||
providers: [
|
||||
AiAgentRoleService,
|
||||
provideWorkspaceScopedRepository(AgentEntity),
|
||||
provideWorkspaceScopedRepository(RoleEntity),
|
||||
provideWorkspaceScopedRepository(RoleTargetEntity),
|
||||
],
|
||||
exports: [AiAgentRoleService],
|
||||
})
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { In, IsNull, Not, Repository } from 'typeorm';
|
||||
import { In, IsNull, Not } from 'typeorm';
|
||||
|
||||
import {
|
||||
AiException,
|
||||
@@ -19,10 +18,10 @@ export class AiAgentRoleService {
|
||||
constructor(
|
||||
@InjectWorkspaceScopedRepository(AgentEntity)
|
||||
private readonly agentRepository: WorkspaceScopedRepository<AgentEntity>,
|
||||
@InjectRepository(RoleEntity)
|
||||
private readonly roleRepository: Repository<RoleEntity>,
|
||||
@InjectRepository(RoleTargetEntity)
|
||||
private readonly roleTargetRepository: Repository<RoleTargetEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleEntity)
|
||||
private readonly roleRepository: WorkspaceScopedRepository<RoleEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleTargetEntity)
|
||||
private readonly roleTargetRepository: WorkspaceScopedRepository<RoleTargetEntity>,
|
||||
private readonly roleTargetService: RoleTargetService,
|
||||
) {}
|
||||
|
||||
@@ -62,12 +61,14 @@ export class AiAgentRoleService {
|
||||
workspaceId: string;
|
||||
agentId: string;
|
||||
}): Promise<void> {
|
||||
const existingRoleTarget = await this.roleTargetRepository.findOne({
|
||||
where: {
|
||||
agentId,
|
||||
workspaceId,
|
||||
const existingRoleTarget = await this.roleTargetRepository.findOne(
|
||||
workspaceId,
|
||||
{
|
||||
where: {
|
||||
agentId,
|
||||
},
|
||||
},
|
||||
});
|
||||
);
|
||||
|
||||
if (!isDefined(existingRoleTarget)) {
|
||||
throw new AiException(
|
||||
@@ -86,10 +87,9 @@ export class AiAgentRoleService {
|
||||
roleId: string,
|
||||
workspaceId: string,
|
||||
): Promise<AgentEntity[]> {
|
||||
const roleTargets = await this.roleTargetRepository.find({
|
||||
const roleTargets = await this.roleTargetRepository.find(workspaceId, {
|
||||
where: {
|
||||
roleId,
|
||||
workspaceId,
|
||||
agentId: Not(IsNull()),
|
||||
},
|
||||
});
|
||||
@@ -129,8 +129,8 @@ export class AiAgentRoleService {
|
||||
);
|
||||
}
|
||||
|
||||
const role = await this.roleRepository.findOne({
|
||||
where: { id: roleId, workspaceId },
|
||||
const role = await this.roleRepository.findOne(workspaceId, {
|
||||
where: { id: roleId },
|
||||
});
|
||||
|
||||
if (!role) {
|
||||
@@ -147,13 +147,15 @@ export class AiAgentRoleService {
|
||||
);
|
||||
}
|
||||
|
||||
const existingRoleTarget = await this.roleTargetRepository.findOne({
|
||||
where: {
|
||||
agentId,
|
||||
roleId,
|
||||
workspaceId,
|
||||
const existingRoleTarget = await this.roleTargetRepository.findOne(
|
||||
workspaceId,
|
||||
{
|
||||
where: {
|
||||
agentId,
|
||||
roleId,
|
||||
},
|
||||
},
|
||||
});
|
||||
);
|
||||
|
||||
return {
|
||||
roleToAssignIsSameAsCurrentRole: Boolean(existingRoleTarget),
|
||||
@@ -169,8 +171,8 @@ export class AiAgentRoleService {
|
||||
roleTargetId: string;
|
||||
workspaceId: string;
|
||||
}): Promise<void> {
|
||||
const role = await this.roleRepository.findOne({
|
||||
where: { id: roleId, workspaceId },
|
||||
const role = await this.roleRepository.findOne(workspaceId, {
|
||||
where: { id: roleId },
|
||||
});
|
||||
|
||||
if (
|
||||
@@ -182,16 +184,18 @@ export class AiAgentRoleService {
|
||||
return;
|
||||
}
|
||||
|
||||
const remainingAssignments = await this.roleTargetRepository.count({
|
||||
where: {
|
||||
roleId,
|
||||
workspaceId,
|
||||
id: Not(roleTargetId),
|
||||
const remainingAssignments = await this.roleTargetRepository.count(
|
||||
workspaceId,
|
||||
{
|
||||
where: {
|
||||
roleId,
|
||||
id: Not(roleTargetId),
|
||||
},
|
||||
},
|
||||
});
|
||||
);
|
||||
|
||||
if (remainingAssignments === 0) {
|
||||
await this.roleRepository.delete({ id: roleId, workspaceId });
|
||||
await this.roleRepository.delete(workspaceId, { id: roleId });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspac
|
||||
WorkspaceFlatAgentMapCacheService,
|
||||
WorkspaceFlatRoleTargetByAgentIdService,
|
||||
provideWorkspaceScopedRepository(AgentEntity),
|
||||
provideWorkspaceScopedRepository(RoleEntity),
|
||||
provideWorkspaceScopedRepository(RoleTargetEntity),
|
||||
],
|
||||
exports: [
|
||||
WorkspaceFlatAgentMapCacheService,
|
||||
|
||||
@@ -11,6 +11,8 @@ import { FlatRoleTargetByAgentIdMaps } from 'src/engine/metadata-modules/flat-ag
|
||||
import { fromRoleTargetEntityToFlatRoleTarget } from 'src/engine/metadata-modules/flat-role-target/utils/from-role-target-entity-to-flat-role-target.util';
|
||||
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
||||
|
||||
@@ -18,12 +20,12 @@ import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/uti
|
||||
@WorkspaceCache('flatRoleTargetByAgentIdMaps')
|
||||
export class WorkspaceFlatRoleTargetByAgentIdService extends WorkspaceCacheProvider<FlatRoleTargetByAgentIdMaps> {
|
||||
constructor(
|
||||
@InjectRepository(RoleTargetEntity)
|
||||
private readonly roleTargetRepository: Repository<RoleTargetEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleTargetEntity)
|
||||
private readonly roleTargetRepository: WorkspaceScopedRepository<RoleTargetEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
@InjectRepository(RoleEntity)
|
||||
private readonly roleRepository: Repository<RoleEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleEntity)
|
||||
private readonly roleRepository: WorkspaceScopedRepository<RoleEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -32,9 +34,8 @@ export class WorkspaceFlatRoleTargetByAgentIdService extends WorkspaceCacheProvi
|
||||
workspaceId: string,
|
||||
): Promise<FlatRoleTargetByAgentIdMaps> {
|
||||
const [roleTargetEntities, applications, roles] = await Promise.all([
|
||||
this.roleTargetRepository.find({
|
||||
this.roleTargetRepository.find(workspaceId, {
|
||||
where: {
|
||||
workspaceId,
|
||||
agentId: Not(IsNull()),
|
||||
},
|
||||
withDeleted: true,
|
||||
@@ -44,8 +45,7 @@ export class WorkspaceFlatRoleTargetByAgentIdService extends WorkspaceCacheProvi
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.roleRepository.find({
|
||||
where: { workspaceId },
|
||||
this.roleRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
|
||||
@@ -8,6 +8,7 @@ import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata
|
||||
import { FrontComponentEntity } from 'src/engine/metadata-modules/front-component/entities/front-component.entity';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { PageLayoutEntity } from 'src/engine/metadata-modules/page-layout/entities/page-layout.entity';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -20,7 +21,11 @@ import { PageLayoutEntity } from 'src/engine/metadata-modules/page-layout/entiti
|
||||
]),
|
||||
WorkspaceManyOrAllFlatEntityMapsCacheModule,
|
||||
],
|
||||
providers: [WorkspaceFlatCommandMenuItemMapCacheService],
|
||||
providers: [
|
||||
WorkspaceFlatCommandMenuItemMapCacheService,
|
||||
provideWorkspaceScopedRepository(CommandMenuItemEntity),
|
||||
provideWorkspaceScopedRepository(PageLayoutEntity),
|
||||
],
|
||||
exports: [WorkspaceFlatCommandMenuItemMapCacheService],
|
||||
})
|
||||
export class FlatCommandMenuItemModule {}
|
||||
|
||||
@@ -13,6 +13,8 @@ import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-enti
|
||||
import { FrontComponentEntity } from 'src/engine/metadata-modules/front-component/entities/front-component.entity';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { PageLayoutEntity } from 'src/engine/metadata-modules/page-layout/entities/page-layout.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
||||
import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
|
||||
@@ -21,16 +23,16 @@ import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/
|
||||
@WorkspaceCache('flatCommandMenuItemMaps')
|
||||
export class WorkspaceFlatCommandMenuItemMapCacheService extends WorkspaceCacheProvider<FlatCommandMenuItemMaps> {
|
||||
constructor(
|
||||
@InjectRepository(CommandMenuItemEntity)
|
||||
private readonly commandMenuItemRepository: Repository<CommandMenuItemEntity>,
|
||||
@InjectWorkspaceScopedRepository(CommandMenuItemEntity)
|
||||
private readonly commandMenuItemRepository: WorkspaceScopedRepository<CommandMenuItemEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
@InjectRepository(ObjectMetadataEntity)
|
||||
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
|
||||
@InjectRepository(FrontComponentEntity)
|
||||
private readonly frontComponentRepository: Repository<FrontComponentEntity>,
|
||||
@InjectRepository(PageLayoutEntity)
|
||||
private readonly pageLayoutRepository: Repository<PageLayoutEntity>,
|
||||
@InjectWorkspaceScopedRepository(PageLayoutEntity)
|
||||
private readonly pageLayoutRepository: WorkspaceScopedRepository<PageLayoutEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -43,8 +45,7 @@ export class WorkspaceFlatCommandMenuItemMapCacheService extends WorkspaceCacheP
|
||||
frontComponents,
|
||||
pageLayouts,
|
||||
] = await Promise.all([
|
||||
this.commandMenuItemRepository.find({
|
||||
where: { workspaceId },
|
||||
this.commandMenuItemRepository.find(workspaceId, {
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.applicationRepository.find({
|
||||
@@ -62,8 +63,7 @@ export class WorkspaceFlatCommandMenuItemMapCacheService extends WorkspaceCacheP
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.pageLayoutRepository.find({
|
||||
where: { workspaceId },
|
||||
this.pageLayoutRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
|
||||
@@ -44,6 +44,7 @@ import { ViewFilterEntity } from 'src/engine/metadata-modules/view-filter/entiti
|
||||
import { ViewGroupEntity } from 'src/engine/metadata-modules/view-group/entities/view-group.entity';
|
||||
import { ViewSortEntity } from 'src/engine/metadata-modules/view-sort/entities/view-sort.entity';
|
||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
|
||||
|
||||
@Module({
|
||||
@@ -96,6 +97,23 @@ import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache
|
||||
WorkspaceFlatPageLayoutWidgetMapCacheService,
|
||||
WorkspaceFlatRowLevelPermissionPredicateMapCacheService,
|
||||
WorkspaceFlatRowLevelPermissionPredicateGroupMapCacheService,
|
||||
provideWorkspaceScopedRepository(PermissionFlagEntity),
|
||||
provideWorkspaceScopedRepository(IndexMetadataEntity),
|
||||
provideWorkspaceScopedRepository(ViewEntity),
|
||||
provideWorkspaceScopedRepository(ViewFieldEntity),
|
||||
provideWorkspaceScopedRepository(ViewFieldGroupEntity),
|
||||
provideWorkspaceScopedRepository(ViewFilterEntity),
|
||||
provideWorkspaceScopedRepository(ViewFilterGroupEntity),
|
||||
provideWorkspaceScopedRepository(ViewGroupEntity),
|
||||
provideWorkspaceScopedRepository(ViewSortEntity),
|
||||
provideWorkspaceScopedRepository(PageLayoutEntity),
|
||||
provideWorkspaceScopedRepository(PageLayoutTabEntity),
|
||||
provideWorkspaceScopedRepository(PageLayoutWidgetEntity),
|
||||
provideWorkspaceScopedRepository(ObjectPermissionEntity),
|
||||
provideWorkspaceScopedRepository(FieldPermissionEntity),
|
||||
provideWorkspaceScopedRepository(RoleEntity),
|
||||
provideWorkspaceScopedRepository(RowLevelPermissionPredicateEntity),
|
||||
provideWorkspaceScopedRepository(RowLevelPermissionPredicateGroupEntity),
|
||||
],
|
||||
exports: [
|
||||
WorkspaceManyOrAllFlatEntityMapsCacheService,
|
||||
|
||||
@@ -18,6 +18,8 @@ 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 { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
||||
import { regroupEntitiesByRelatedEntityId } from 'src/engine/workspace-cache/utils/regroup-entities-by-related-entity-id';
|
||||
@@ -32,22 +34,22 @@ export class WorkspaceFlatFieldMetadataMapCacheService extends WorkspaceCachePro
|
||||
constructor(
|
||||
@InjectRepository(FieldMetadataEntity)
|
||||
private readonly fieldMetadataRepository: Repository<FieldMetadataEntity>,
|
||||
@InjectRepository(IndexMetadataEntity)
|
||||
private readonly indexMetadataRepository: Repository<IndexMetadataEntity>,
|
||||
@InjectWorkspaceScopedRepository(IndexMetadataEntity)
|
||||
private readonly indexMetadataRepository: WorkspaceScopedRepository<IndexMetadataEntity>,
|
||||
@InjectRepository(ObjectMetadataEntity)
|
||||
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
@InjectRepository(ViewFieldEntity)
|
||||
private readonly viewFieldRepository: Repository<ViewFieldEntity>,
|
||||
@InjectRepository(ViewFilterEntity)
|
||||
private readonly viewFilterRepository: Repository<ViewFilterEntity>,
|
||||
@InjectRepository(ViewGroupEntity)
|
||||
private readonly viewGroupRepository: Repository<ViewGroupEntity>,
|
||||
@InjectRepository(ViewSortEntity)
|
||||
private readonly viewSortRepository: Repository<ViewSortEntity>,
|
||||
@InjectRepository(ViewEntity)
|
||||
private readonly viewRepository: Repository<ViewEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewFieldEntity)
|
||||
private readonly viewFieldRepository: WorkspaceScopedRepository<ViewFieldEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewFilterEntity)
|
||||
private readonly viewFilterRepository: WorkspaceScopedRepository<ViewFilterEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewGroupEntity)
|
||||
private readonly viewGroupRepository: WorkspaceScopedRepository<ViewGroupEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewSortEntity)
|
||||
private readonly viewSortRepository: WorkspaceScopedRepository<ViewSortEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewEntity)
|
||||
private readonly viewRepository: WorkspaceScopedRepository<ViewEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -69,8 +71,8 @@ export class WorkspaceFlatFieldMetadataMapCacheService extends WorkspaceCachePro
|
||||
where: { workspaceId },
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.indexMetadataRepository.find({
|
||||
where: { workspaceId, isUnique: true },
|
||||
this.indexMetadataRepository.find(workspaceId, {
|
||||
where: { isUnique: true },
|
||||
relations: ['indexFieldMetadatas'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
@@ -84,23 +86,19 @@ export class WorkspaceFlatFieldMetadataMapCacheService extends WorkspaceCachePro
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.viewFieldRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewFieldRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier', 'fieldMetadataId'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.viewFilterRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewFilterRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier', 'fieldMetadataId'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.viewSortRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewSortRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier', 'fieldMetadataId'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.viewRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewRepository.find(workspaceId, {
|
||||
select: [
|
||||
'id',
|
||||
'universalIdentifier',
|
||||
|
||||
@@ -11,6 +11,8 @@ import { fromFieldPermissionEntityToFlatFieldPermission } from 'src/engine/metad
|
||||
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 { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { WorkspaceCacheProvider } from 'src/engine/workspace-cache/interfaces/workspace-cache-provider.service';
|
||||
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
||||
@@ -20,12 +22,12 @@ import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/
|
||||
@WorkspaceCache('flatFieldPermissionMaps')
|
||||
export class WorkspaceFlatFieldPermissionMapCacheService extends WorkspaceCacheProvider<FlatFieldPermissionMaps> {
|
||||
constructor(
|
||||
@InjectRepository(FieldPermissionEntity)
|
||||
private readonly fieldPermissionRepository: Repository<FieldPermissionEntity>,
|
||||
@InjectWorkspaceScopedRepository(FieldPermissionEntity)
|
||||
private readonly fieldPermissionRepository: WorkspaceScopedRepository<FieldPermissionEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
@InjectRepository(RoleEntity)
|
||||
private readonly roleRepository: Repository<RoleEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleEntity)
|
||||
private readonly roleRepository: WorkspaceScopedRepository<RoleEntity>,
|
||||
@InjectRepository(ObjectMetadataEntity)
|
||||
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
|
||||
@InjectRepository(FieldMetadataEntity)
|
||||
@@ -42,8 +44,7 @@ export class WorkspaceFlatFieldPermissionMapCacheService extends WorkspaceCacheP
|
||||
objectMetadatas,
|
||||
fieldMetadatas,
|
||||
] = await Promise.all([
|
||||
this.fieldPermissionRepository.find({
|
||||
where: { workspaceId },
|
||||
this.fieldPermissionRepository.find(workspaceId, {
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.applicationRepository.find({
|
||||
@@ -51,8 +52,7 @@ export class WorkspaceFlatFieldPermissionMapCacheService extends WorkspaceCacheP
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.roleRepository.find({
|
||||
where: { workspaceId },
|
||||
this.roleRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
|
||||
@@ -13,6 +13,8 @@ import { FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metada
|
||||
import { fromIndexMetadataEntityToFlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/utils/from-index-metadata-entity-to-flat-index-metadata.util';
|
||||
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 { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
||||
import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
|
||||
@@ -23,8 +25,8 @@ export class WorkspaceFlatIndexMapCacheService extends WorkspaceCacheProvider<
|
||||
FlatEntityMaps<FlatIndexMetadata>
|
||||
> {
|
||||
constructor(
|
||||
@InjectRepository(IndexMetadataEntity)
|
||||
private readonly indexMetadataRepository: Repository<IndexMetadataEntity>,
|
||||
@InjectWorkspaceScopedRepository(IndexMetadataEntity)
|
||||
private readonly indexMetadataRepository: WorkspaceScopedRepository<IndexMetadataEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
@InjectRepository(ObjectMetadataEntity)
|
||||
@@ -40,10 +42,7 @@ export class WorkspaceFlatIndexMapCacheService extends WorkspaceCacheProvider<
|
||||
): Promise<FlatEntityMaps<FlatIndexMetadata>> {
|
||||
const [indexes, applications, objectMetadatas, fieldMetadatas] =
|
||||
await Promise.all([
|
||||
this.indexMetadataRepository.find({
|
||||
where: {
|
||||
workspaceId,
|
||||
},
|
||||
this.indexMetadataRepository.find(workspaceId, {
|
||||
withDeleted: true,
|
||||
relationLoadStrategy: 'join',
|
||||
relations: ['indexFieldMetadatas'],
|
||||
|
||||
@@ -8,6 +8,7 @@ import { NavigationMenuItemEntity } from 'src/engine/metadata-modules/navigation
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { PageLayoutEntity } from 'src/engine/metadata-modules/page-layout/entities/page-layout.entity';
|
||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -20,7 +21,12 @@ import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entit
|
||||
]),
|
||||
WorkspaceManyOrAllFlatEntityMapsCacheModule,
|
||||
],
|
||||
providers: [WorkspaceFlatNavigationMenuItemMapCacheService],
|
||||
providers: [
|
||||
WorkspaceFlatNavigationMenuItemMapCacheService,
|
||||
provideWorkspaceScopedRepository(NavigationMenuItemEntity),
|
||||
provideWorkspaceScopedRepository(ViewEntity),
|
||||
provideWorkspaceScopedRepository(PageLayoutEntity),
|
||||
],
|
||||
exports: [WorkspaceFlatNavigationMenuItemMapCacheService],
|
||||
})
|
||||
export class FlatNavigationMenuItemModule {}
|
||||
|
||||
@@ -14,6 +14,8 @@ import { NavigationMenuItemEntity } from 'src/engine/metadata-modules/navigation
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { PageLayoutEntity } from 'src/engine/metadata-modules/page-layout/entities/page-layout.entity';
|
||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
||||
|
||||
@@ -21,16 +23,16 @@ import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/uti
|
||||
@WorkspaceCache('flatNavigationMenuItemMaps')
|
||||
export class WorkspaceFlatNavigationMenuItemMapCacheService extends WorkspaceCacheProvider<FlatNavigationMenuItemMaps> {
|
||||
constructor(
|
||||
@InjectRepository(NavigationMenuItemEntity)
|
||||
private readonly navigationMenuItemRepository: Repository<NavigationMenuItemEntity>,
|
||||
@InjectWorkspaceScopedRepository(NavigationMenuItemEntity)
|
||||
private readonly navigationMenuItemRepository: WorkspaceScopedRepository<NavigationMenuItemEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
@InjectRepository(ObjectMetadataEntity)
|
||||
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
|
||||
@InjectRepository(ViewEntity)
|
||||
private readonly viewRepository: Repository<ViewEntity>,
|
||||
@InjectRepository(PageLayoutEntity)
|
||||
private readonly pageLayoutRepository: Repository<PageLayoutEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewEntity)
|
||||
private readonly viewRepository: WorkspaceScopedRepository<ViewEntity>,
|
||||
@InjectWorkspaceScopedRepository(PageLayoutEntity)
|
||||
private readonly pageLayoutRepository: WorkspaceScopedRepository<PageLayoutEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -45,8 +47,7 @@ export class WorkspaceFlatNavigationMenuItemMapCacheService extends WorkspaceCac
|
||||
views,
|
||||
pageLayouts,
|
||||
] = await Promise.all([
|
||||
this.navigationMenuItemRepository.find({
|
||||
where: { workspaceId },
|
||||
this.navigationMenuItemRepository.find(workspaceId, {
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.applicationRepository.find({
|
||||
@@ -59,13 +60,11 @@ export class WorkspaceFlatNavigationMenuItemMapCacheService extends WorkspaceCac
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.viewRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.pageLayoutRepository.find({
|
||||
where: { workspaceId },
|
||||
this.pageLayoutRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
|
||||
@@ -15,6 +15,8 @@ import { IndexMetadataEntity } from 'src/engine/metadata-modules/index-metadata/
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { ObjectPermissionEntity } from 'src/engine/metadata-modules/object-permission/object-permission.entity';
|
||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
||||
import { regroupEntitiesByRelatedEntityId } from 'src/engine/workspace-cache/utils/regroup-entities-by-related-entity-id';
|
||||
@@ -32,12 +34,12 @@ export class WorkspaceFlatObjectMetadataMapCacheService extends WorkspaceCachePr
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
@InjectRepository(FieldMetadataEntity)
|
||||
private readonly fieldMetadataRepository: Repository<FieldMetadataEntity>,
|
||||
@InjectRepository(IndexMetadataEntity)
|
||||
private readonly indexMetadataRepository: Repository<IndexMetadataEntity>,
|
||||
@InjectRepository(ViewEntity)
|
||||
private readonly viewRepository: Repository<ViewEntity>,
|
||||
@InjectRepository(ObjectPermissionEntity)
|
||||
private readonly objectPermissionRepository: Repository<ObjectPermissionEntity>,
|
||||
@InjectWorkspaceScopedRepository(IndexMetadataEntity)
|
||||
private readonly indexMetadataRepository: WorkspaceScopedRepository<IndexMetadataEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewEntity)
|
||||
private readonly viewRepository: WorkspaceScopedRepository<ViewEntity>,
|
||||
@InjectWorkspaceScopedRepository(ObjectPermissionEntity)
|
||||
private readonly objectPermissionRepository: WorkspaceScopedRepository<ObjectPermissionEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -67,18 +69,15 @@ export class WorkspaceFlatObjectMetadataMapCacheService extends WorkspaceCachePr
|
||||
select: ['id', 'universalIdentifier', 'objectMetadataId'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.indexMetadataRepository.find({
|
||||
where: { workspaceId },
|
||||
this.indexMetadataRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier', 'objectMetadataId'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.viewRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier', 'objectMetadataId'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.objectPermissionRepository.find({
|
||||
where: { workspaceId },
|
||||
this.objectPermissionRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier', 'objectMetadataId'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
|
||||
@@ -10,6 +10,8 @@ import { fromObjectPermissionEntityToFlatObjectPermission } from 'src/engine/met
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { ObjectPermissionEntity } from 'src/engine/metadata-modules/object-permission/object-permission.entity';
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { WorkspaceCacheProvider } from 'src/engine/workspace-cache/interfaces/workspace-cache-provider.service';
|
||||
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
||||
@@ -19,12 +21,12 @@ import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/
|
||||
@WorkspaceCache('flatObjectPermissionMaps')
|
||||
export class WorkspaceFlatObjectPermissionMapCacheService extends WorkspaceCacheProvider<FlatObjectPermissionMaps> {
|
||||
constructor(
|
||||
@InjectRepository(ObjectPermissionEntity)
|
||||
private readonly objectPermissionRepository: Repository<ObjectPermissionEntity>,
|
||||
@InjectWorkspaceScopedRepository(ObjectPermissionEntity)
|
||||
private readonly objectPermissionRepository: WorkspaceScopedRepository<ObjectPermissionEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
@InjectRepository(RoleEntity)
|
||||
private readonly roleRepository: Repository<RoleEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleEntity)
|
||||
private readonly roleRepository: WorkspaceScopedRepository<RoleEntity>,
|
||||
@InjectRepository(ObjectMetadataEntity)
|
||||
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
|
||||
) {
|
||||
@@ -36,8 +38,7 @@ export class WorkspaceFlatObjectPermissionMapCacheService extends WorkspaceCache
|
||||
): Promise<FlatObjectPermissionMaps> {
|
||||
const [objectPermissions, applications, roles, objectMetadatas] =
|
||||
await Promise.all([
|
||||
this.objectPermissionRepository.find({
|
||||
where: { workspaceId },
|
||||
this.objectPermissionRepository.find(workspaceId, {
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.applicationRepository.find({
|
||||
@@ -45,8 +46,7 @@ export class WorkspaceFlatObjectPermissionMapCacheService extends WorkspaceCache
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.roleRepository.find({
|
||||
where: { workspaceId },
|
||||
this.roleRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
|
||||
@@ -7,6 +7,7 @@ import { WorkspaceFlatPageLayoutTabMapCacheService } from 'src/engine/metadata-m
|
||||
import { PageLayoutTabEntity } from 'src/engine/metadata-modules/page-layout-tab/entities/page-layout-tab.entity';
|
||||
import { PageLayoutWidgetEntity } from 'src/engine/metadata-modules/page-layout-widget/entities/page-layout-widget.entity';
|
||||
import { PageLayoutEntity } from 'src/engine/metadata-modules/page-layout/entities/page-layout.entity';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -18,7 +19,12 @@ import { PageLayoutEntity } from 'src/engine/metadata-modules/page-layout/entiti
|
||||
]),
|
||||
WorkspaceManyOrAllFlatEntityMapsCacheModule,
|
||||
],
|
||||
providers: [WorkspaceFlatPageLayoutTabMapCacheService],
|
||||
providers: [
|
||||
WorkspaceFlatPageLayoutTabMapCacheService,
|
||||
provideWorkspaceScopedRepository(PageLayoutEntity),
|
||||
provideWorkspaceScopedRepository(PageLayoutTabEntity),
|
||||
provideWorkspaceScopedRepository(PageLayoutWidgetEntity),
|
||||
],
|
||||
exports: [WorkspaceFlatPageLayoutTabMapCacheService],
|
||||
})
|
||||
export class FlatPageLayoutTabModule {}
|
||||
|
||||
@@ -12,6 +12,8 @@ import { transformPageLayoutTabEntityToFlatPageLayoutTab } from 'src/engine/meta
|
||||
import { PageLayoutTabEntity } from 'src/engine/metadata-modules/page-layout-tab/entities/page-layout-tab.entity';
|
||||
import { PageLayoutWidgetEntity } from 'src/engine/metadata-modules/page-layout-widget/entities/page-layout-widget.entity';
|
||||
import { PageLayoutEntity } from 'src/engine/metadata-modules/page-layout/entities/page-layout.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
||||
import { regroupEntitiesByRelatedEntityId } from 'src/engine/workspace-cache/utils/regroup-entities-by-related-entity-id';
|
||||
@@ -21,14 +23,14 @@ import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/
|
||||
@WorkspaceCache('flatPageLayoutTabMaps')
|
||||
export class WorkspaceFlatPageLayoutTabMapCacheService extends WorkspaceCacheProvider<FlatPageLayoutTabMaps> {
|
||||
constructor(
|
||||
@InjectRepository(PageLayoutTabEntity)
|
||||
private readonly pageLayoutTabRepository: Repository<PageLayoutTabEntity>,
|
||||
@InjectRepository(PageLayoutWidgetEntity)
|
||||
private readonly pageLayoutWidgetRepository: Repository<PageLayoutWidgetEntity>,
|
||||
@InjectWorkspaceScopedRepository(PageLayoutTabEntity)
|
||||
private readonly pageLayoutTabRepository: WorkspaceScopedRepository<PageLayoutTabEntity>,
|
||||
@InjectWorkspaceScopedRepository(PageLayoutWidgetEntity)
|
||||
private readonly pageLayoutWidgetRepository: WorkspaceScopedRepository<PageLayoutWidgetEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
@InjectRepository(PageLayoutEntity)
|
||||
private readonly pageLayoutRepository: Repository<PageLayoutEntity>,
|
||||
@InjectWorkspaceScopedRepository(PageLayoutEntity)
|
||||
private readonly pageLayoutRepository: WorkspaceScopedRepository<PageLayoutEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -36,12 +38,10 @@ export class WorkspaceFlatPageLayoutTabMapCacheService extends WorkspaceCachePro
|
||||
async computeForCache(workspaceId: string): Promise<FlatPageLayoutTabMaps> {
|
||||
const [pageLayoutTabs, pageLayoutWidgets, applications, pageLayouts] =
|
||||
await Promise.all([
|
||||
this.pageLayoutTabRepository.find({
|
||||
where: { workspaceId },
|
||||
this.pageLayoutTabRepository.find(workspaceId, {
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.pageLayoutWidgetRepository.find({
|
||||
where: { workspaceId },
|
||||
this.pageLayoutWidgetRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier', 'pageLayoutTabId'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
@@ -50,8 +50,7 @@ export class WorkspaceFlatPageLayoutTabMapCacheService extends WorkspaceCachePro
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.pageLayoutRepository.find({
|
||||
where: { workspaceId },
|
||||
this.pageLayoutRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
|
||||
@@ -10,6 +10,7 @@ import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadat
|
||||
import { PageLayoutTabEntity } from 'src/engine/metadata-modules/page-layout-tab/entities/page-layout-tab.entity';
|
||||
import { PageLayoutWidgetEntity } from 'src/engine/metadata-modules/page-layout-widget/entities/page-layout-widget.entity';
|
||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -26,6 +27,9 @@ import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entit
|
||||
providers: [
|
||||
WorkspaceFlatPageLayoutWidgetMapCacheService,
|
||||
FlatPageLayoutWidgetTypeValidatorService,
|
||||
provideWorkspaceScopedRepository(PageLayoutTabEntity),
|
||||
provideWorkspaceScopedRepository(PageLayoutWidgetEntity),
|
||||
provideWorkspaceScopedRepository(ViewEntity),
|
||||
],
|
||||
exports: [
|
||||
WorkspaceFlatPageLayoutWidgetMapCacheService,
|
||||
|
||||
@@ -15,6 +15,8 @@ import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadat
|
||||
import { PageLayoutTabEntity } from 'src/engine/metadata-modules/page-layout-tab/entities/page-layout-tab.entity';
|
||||
import { PageLayoutWidgetEntity } from 'src/engine/metadata-modules/page-layout-widget/entities/page-layout-widget.entity';
|
||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
||||
import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
|
||||
@@ -23,20 +25,20 @@ import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/
|
||||
@WorkspaceCache('flatPageLayoutWidgetMaps')
|
||||
export class WorkspaceFlatPageLayoutWidgetMapCacheService extends WorkspaceCacheProvider<FlatPageLayoutWidgetMaps> {
|
||||
constructor(
|
||||
@InjectRepository(PageLayoutWidgetEntity)
|
||||
private readonly pageLayoutWidgetRepository: Repository<PageLayoutWidgetEntity>,
|
||||
@InjectWorkspaceScopedRepository(PageLayoutWidgetEntity)
|
||||
private readonly pageLayoutWidgetRepository: WorkspaceScopedRepository<PageLayoutWidgetEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
@InjectRepository(PageLayoutTabEntity)
|
||||
private readonly pageLayoutTabRepository: Repository<PageLayoutTabEntity>,
|
||||
@InjectWorkspaceScopedRepository(PageLayoutTabEntity)
|
||||
private readonly pageLayoutTabRepository: WorkspaceScopedRepository<PageLayoutTabEntity>,
|
||||
@InjectRepository(ObjectMetadataEntity)
|
||||
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
|
||||
@InjectRepository(FieldMetadataEntity)
|
||||
private readonly fieldMetadataRepository: Repository<FieldMetadataEntity>,
|
||||
@InjectRepository(FrontComponentEntity)
|
||||
private readonly frontComponentRepository: Repository<FrontComponentEntity>,
|
||||
@InjectRepository(ViewEntity)
|
||||
private readonly viewRepository: Repository<ViewEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewEntity)
|
||||
private readonly viewRepository: WorkspaceScopedRepository<ViewEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -53,8 +55,7 @@ export class WorkspaceFlatPageLayoutWidgetMapCacheService extends WorkspaceCache
|
||||
frontComponents,
|
||||
views,
|
||||
] = await Promise.all([
|
||||
this.pageLayoutWidgetRepository.find({
|
||||
where: { workspaceId },
|
||||
this.pageLayoutWidgetRepository.find(workspaceId, {
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.applicationRepository.find({
|
||||
@@ -62,8 +63,7 @@ export class WorkspaceFlatPageLayoutWidgetMapCacheService extends WorkspaceCache
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.pageLayoutTabRepository.find({
|
||||
where: { workspaceId },
|
||||
this.pageLayoutTabRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
@@ -82,8 +82,7 @@ export class WorkspaceFlatPageLayoutWidgetMapCacheService extends WorkspaceCache
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.viewRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
|
||||
@@ -6,6 +6,7 @@ import { WorkspaceFlatPageLayoutMapCacheService } from 'src/engine/metadata-modu
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { PageLayoutTabEntity } from 'src/engine/metadata-modules/page-layout-tab/entities/page-layout-tab.entity';
|
||||
import { PageLayoutEntity } from 'src/engine/metadata-modules/page-layout/entities/page-layout.entity';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -16,7 +17,11 @@ import { PageLayoutEntity } from 'src/engine/metadata-modules/page-layout/entiti
|
||||
ObjectMetadataEntity,
|
||||
]),
|
||||
],
|
||||
providers: [WorkspaceFlatPageLayoutMapCacheService],
|
||||
providers: [
|
||||
WorkspaceFlatPageLayoutMapCacheService,
|
||||
provideWorkspaceScopedRepository(PageLayoutEntity),
|
||||
provideWorkspaceScopedRepository(PageLayoutTabEntity),
|
||||
],
|
||||
exports: [WorkspaceFlatPageLayoutMapCacheService],
|
||||
})
|
||||
export class FlatPageLayoutModule {}
|
||||
|
||||
@@ -12,6 +12,8 @@ import { transformPageLayoutEntityToFlatPageLayout } from 'src/engine/metadata-m
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { PageLayoutTabEntity } from 'src/engine/metadata-modules/page-layout-tab/entities/page-layout-tab.entity';
|
||||
import { PageLayoutEntity } from 'src/engine/metadata-modules/page-layout/entities/page-layout.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
||||
import { regroupEntitiesByRelatedEntityId } from 'src/engine/workspace-cache/utils/regroup-entities-by-related-entity-id';
|
||||
@@ -21,10 +23,10 @@ import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/
|
||||
@WorkspaceCache('flatPageLayoutMaps')
|
||||
export class WorkspaceFlatPageLayoutMapCacheService extends WorkspaceCacheProvider<FlatPageLayoutMaps> {
|
||||
constructor(
|
||||
@InjectRepository(PageLayoutEntity)
|
||||
private readonly pageLayoutRepository: Repository<PageLayoutEntity>,
|
||||
@InjectRepository(PageLayoutTabEntity)
|
||||
private readonly pageLayoutTabRepository: Repository<PageLayoutTabEntity>,
|
||||
@InjectWorkspaceScopedRepository(PageLayoutEntity)
|
||||
private readonly pageLayoutRepository: WorkspaceScopedRepository<PageLayoutEntity>,
|
||||
@InjectWorkspaceScopedRepository(PageLayoutTabEntity)
|
||||
private readonly pageLayoutTabRepository: WorkspaceScopedRepository<PageLayoutTabEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
@InjectRepository(ObjectMetadataEntity)
|
||||
@@ -36,12 +38,10 @@ export class WorkspaceFlatPageLayoutMapCacheService extends WorkspaceCacheProvid
|
||||
async computeForCache(workspaceId: string): Promise<FlatPageLayoutMaps> {
|
||||
const [pageLayouts, pageLayoutTabs, applications, objectMetadatas] =
|
||||
await Promise.all([
|
||||
this.pageLayoutRepository.find({
|
||||
where: { workspaceId },
|
||||
this.pageLayoutRepository.find(workspaceId, {
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.pageLayoutTabRepository.find({
|
||||
where: { workspaceId },
|
||||
this.pageLayoutTabRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier', 'pageLayoutId'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
|
||||
@@ -6,6 +6,7 @@ import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata
|
||||
import { WorkspaceFlatPermissionFlagMapCacheService } from 'src/engine/metadata-modules/flat-permission-flag/services/workspace-flat-permission-flag-map-cache.service';
|
||||
import { PermissionFlagEntity } from 'src/engine/metadata-modules/permission-flag/permission-flag.entity';
|
||||
import { RolePermissionFlagEntity } from 'src/engine/metadata-modules/role-permission-flag/role-permission-flag.entity';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -16,7 +17,10 @@ import { RolePermissionFlagEntity } from 'src/engine/metadata-modules/role-permi
|
||||
]),
|
||||
WorkspaceManyOrAllFlatEntityMapsCacheModule,
|
||||
],
|
||||
providers: [WorkspaceFlatPermissionFlagMapCacheService],
|
||||
providers: [
|
||||
WorkspaceFlatPermissionFlagMapCacheService,
|
||||
provideWorkspaceScopedRepository(PermissionFlagEntity),
|
||||
],
|
||||
exports: [WorkspaceFlatPermissionFlagMapCacheService],
|
||||
})
|
||||
export class FlatPermissionFlagModule {}
|
||||
|
||||
@@ -9,6 +9,8 @@ import { type FlatPermissionFlagMaps } from 'src/engine/metadata-modules/flat-pe
|
||||
import { fromPermissionFlagEntityToFlatPermissionFlag } from 'src/engine/metadata-modules/flat-permission-flag/utils/from-permission-flag-entity-to-flat-permission-flag.util';
|
||||
import { PermissionFlagEntity } from 'src/engine/metadata-modules/permission-flag/permission-flag.entity';
|
||||
import { RolePermissionFlagEntity } from 'src/engine/metadata-modules/role-permission-flag/role-permission-flag.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { WorkspaceCacheProvider } from 'src/engine/workspace-cache/interfaces/workspace-cache-provider.service';
|
||||
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
||||
@@ -19,8 +21,8 @@ import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/
|
||||
@WorkspaceCache('flatPermissionFlagMaps')
|
||||
export class WorkspaceFlatPermissionFlagMapCacheService extends WorkspaceCacheProvider<FlatPermissionFlagMaps> {
|
||||
constructor(
|
||||
@InjectRepository(PermissionFlagEntity)
|
||||
private readonly permissionFlagRepository: Repository<PermissionFlagEntity>,
|
||||
@InjectWorkspaceScopedRepository(PermissionFlagEntity)
|
||||
private readonly permissionFlagRepository: WorkspaceScopedRepository<PermissionFlagEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
@InjectRepository(RolePermissionFlagEntity)
|
||||
@@ -32,8 +34,7 @@ export class WorkspaceFlatPermissionFlagMapCacheService extends WorkspaceCachePr
|
||||
async computeForCache(workspaceId: string): Promise<FlatPermissionFlagMaps> {
|
||||
const [permissionFlags, applications, rolePermissionFlags] =
|
||||
await Promise.all([
|
||||
this.permissionFlagRepository.find({
|
||||
where: { workspaceId },
|
||||
this.permissionFlagRepository.find(workspaceId, {
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.applicationRepository.find({
|
||||
|
||||
@@ -10,6 +10,8 @@ import { fromRolePermissionFlagEntityToFlatRolePermissionFlag } from 'src/engine
|
||||
import { PermissionFlagEntity } from 'src/engine/metadata-modules/permission-flag/permission-flag.entity';
|
||||
import { RolePermissionFlagEntity } from 'src/engine/metadata-modules/role-permission-flag/role-permission-flag.entity';
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCacheProvider } from 'src/engine/workspace-cache/interfaces/workspace-cache-provider.service';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
||||
@@ -23,10 +25,10 @@ export class WorkspaceFlatRolePermissionFlagMapCacheService extends WorkspaceCac
|
||||
private readonly rolePermissionFlagRepository: Repository<RolePermissionFlagEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
@InjectRepository(RoleEntity)
|
||||
private readonly roleRepository: Repository<RoleEntity>,
|
||||
@InjectRepository(PermissionFlagEntity)
|
||||
private readonly permissionFlagRepository: Repository<PermissionFlagEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleEntity)
|
||||
private readonly roleRepository: WorkspaceScopedRepository<RoleEntity>,
|
||||
@InjectWorkspaceScopedRepository(PermissionFlagEntity)
|
||||
private readonly permissionFlagRepository: WorkspaceScopedRepository<PermissionFlagEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -45,13 +47,11 @@ export class WorkspaceFlatRolePermissionFlagMapCacheService extends WorkspaceCac
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.roleRepository.find({
|
||||
where: { workspaceId },
|
||||
this.roleRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.permissionFlagRepository.find({
|
||||
where: { workspaceId },
|
||||
this.permissionFlagRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
|
||||
@@ -11,6 +11,8 @@ import { type FlatRoleTargetMaps } from 'src/engine/metadata-modules/flat-role-t
|
||||
import { fromRoleTargetEntityToFlatRoleTarget } from 'src/engine/metadata-modules/flat-role-target/utils/from-role-target-entity-to-flat-role-target.util';
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
||||
import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
|
||||
@@ -19,20 +21,19 @@ import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/
|
||||
@WorkspaceCache('flatRoleTargetMaps')
|
||||
export class WorkspaceFlatRoleTargetMapCacheService extends WorkspaceCacheProvider<FlatRoleTargetMaps> {
|
||||
constructor(
|
||||
@InjectRepository(RoleTargetEntity)
|
||||
private readonly roleTargetRepository: Repository<RoleTargetEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleTargetEntity)
|
||||
private readonly roleTargetRepository: WorkspaceScopedRepository<RoleTargetEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
@InjectRepository(RoleEntity)
|
||||
private readonly roleRepository: Repository<RoleEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleEntity)
|
||||
private readonly roleRepository: WorkspaceScopedRepository<RoleEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
async computeForCache(workspaceId: string): Promise<FlatRoleTargetMaps> {
|
||||
const [roleTargets, applications, roles] = await Promise.all([
|
||||
this.roleTargetRepository.find({
|
||||
where: { workspaceId },
|
||||
this.roleTargetRepository.find(workspaceId, {
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.applicationRepository.find({
|
||||
@@ -40,8 +41,7 @@ export class WorkspaceFlatRoleTargetMapCacheService extends WorkspaceCacheProvid
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.roleRepository.find({
|
||||
where: { workspaceId },
|
||||
this.roleRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
|
||||
@@ -15,6 +15,8 @@ import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { RowLevelPermissionPredicateGroupEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate-group.entity';
|
||||
import { RowLevelPermissionPredicateEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate.entity';
|
||||
import { type FlatRowLevelPermissionPredicateGroupMaps } from 'src/engine/metadata-modules/row-level-permission-predicate/types/flat-row-level-permission-predicate-group-maps.type';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
||||
import { regroupEntitiesByRelatedEntityId } from 'src/engine/workspace-cache/utils/regroup-entities-by-related-entity-id';
|
||||
@@ -24,16 +26,16 @@ import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/
|
||||
@WorkspaceCache('flatRowLevelPermissionPredicateGroupMaps')
|
||||
export class WorkspaceFlatRowLevelPermissionPredicateGroupMapCacheService extends WorkspaceCacheProvider<FlatRowLevelPermissionPredicateGroupMaps> {
|
||||
constructor(
|
||||
@InjectRepository(RowLevelPermissionPredicateGroupEntity)
|
||||
private readonly rowLevelPermissionPredicateGroupRepository: Repository<RowLevelPermissionPredicateGroupEntity>,
|
||||
@InjectWorkspaceScopedRepository(RowLevelPermissionPredicateGroupEntity)
|
||||
private readonly rowLevelPermissionPredicateGroupRepository: WorkspaceScopedRepository<RowLevelPermissionPredicateGroupEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
@InjectRepository(ObjectMetadataEntity)
|
||||
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
|
||||
@InjectRepository(RoleEntity)
|
||||
private readonly roleRepository: Repository<RoleEntity>,
|
||||
@InjectRepository(RowLevelPermissionPredicateEntity)
|
||||
private readonly rowLevelPermissionPredicateRepository: Repository<RowLevelPermissionPredicateEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleEntity)
|
||||
private readonly roleRepository: WorkspaceScopedRepository<RoleEntity>,
|
||||
@InjectWorkspaceScopedRepository(RowLevelPermissionPredicateEntity)
|
||||
private readonly rowLevelPermissionPredicateRepository: WorkspaceScopedRepository<RowLevelPermissionPredicateEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -48,8 +50,7 @@ export class WorkspaceFlatRowLevelPermissionPredicateGroupMapCacheService extend
|
||||
roles,
|
||||
rowLevelPermissionPredicates,
|
||||
] = await Promise.all([
|
||||
this.rowLevelPermissionPredicateGroupRepository.find({
|
||||
where: { workspaceId },
|
||||
this.rowLevelPermissionPredicateGroupRepository.find(workspaceId, {
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.applicationRepository.find({
|
||||
@@ -62,13 +63,11 @@ export class WorkspaceFlatRowLevelPermissionPredicateGroupMapCacheService extend
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.roleRepository.find({
|
||||
where: { workspaceId },
|
||||
this.roleRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.rowLevelPermissionPredicateRepository.find({
|
||||
where: { workspaceId },
|
||||
this.rowLevelPermissionPredicateRepository.find(workspaceId, {
|
||||
select: [
|
||||
'id',
|
||||
'universalIdentifier',
|
||||
|
||||
@@ -16,6 +16,8 @@ import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { RowLevelPermissionPredicateGroupEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate-group.entity';
|
||||
import { RowLevelPermissionPredicateEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate.entity';
|
||||
import { type FlatRowLevelPermissionPredicateMaps } from 'src/engine/metadata-modules/row-level-permission-predicate/types/flat-row-level-permission-predicate-maps.type';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
||||
import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
|
||||
@@ -24,18 +26,18 @@ import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/
|
||||
@WorkspaceCache('flatRowLevelPermissionPredicateMaps')
|
||||
export class WorkspaceFlatRowLevelPermissionPredicateMapCacheService extends WorkspaceCacheProvider<FlatRowLevelPermissionPredicateMaps> {
|
||||
constructor(
|
||||
@InjectRepository(RowLevelPermissionPredicateEntity)
|
||||
private readonly rowLevelPermissionPredicateRepository: Repository<RowLevelPermissionPredicateEntity>,
|
||||
@InjectWorkspaceScopedRepository(RowLevelPermissionPredicateEntity)
|
||||
private readonly rowLevelPermissionPredicateRepository: WorkspaceScopedRepository<RowLevelPermissionPredicateEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
@InjectRepository(FieldMetadataEntity)
|
||||
private readonly fieldMetadataRepository: Repository<FieldMetadataEntity>,
|
||||
@InjectRepository(ObjectMetadataEntity)
|
||||
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
|
||||
@InjectRepository(RoleEntity)
|
||||
private readonly roleRepository: Repository<RoleEntity>,
|
||||
@InjectRepository(RowLevelPermissionPredicateGroupEntity)
|
||||
private readonly rowLevelPermissionPredicateGroupRepository: Repository<RowLevelPermissionPredicateGroupEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleEntity)
|
||||
private readonly roleRepository: WorkspaceScopedRepository<RoleEntity>,
|
||||
@InjectWorkspaceScopedRepository(RowLevelPermissionPredicateGroupEntity)
|
||||
private readonly rowLevelPermissionPredicateGroupRepository: WorkspaceScopedRepository<RowLevelPermissionPredicateGroupEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -51,8 +53,7 @@ export class WorkspaceFlatRowLevelPermissionPredicateMapCacheService extends Wor
|
||||
roles,
|
||||
rowLevelPermissionPredicateGroups,
|
||||
] = await Promise.all([
|
||||
this.rowLevelPermissionPredicateRepository.find({
|
||||
where: { workspaceId },
|
||||
this.rowLevelPermissionPredicateRepository.find(workspaceId, {
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.applicationRepository.find({
|
||||
@@ -70,13 +71,11 @@ export class WorkspaceFlatRowLevelPermissionPredicateMapCacheService extends Wor
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.roleRepository.find({
|
||||
where: { workspaceId },
|
||||
this.roleRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.rowLevelPermissionPredicateGroupRepository.find({
|
||||
where: { workspaceId },
|
||||
this.rowLevelPermissionPredicateGroupRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
|
||||
@@ -5,13 +5,17 @@ import { ApplicationEntity } from 'src/engine/core-modules/application/applicati
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module';
|
||||
import { WorkspaceFlatSkillMapCacheService } from 'src/engine/metadata-modules/flat-skill/services/workspace-flat-skill-map-cache.service';
|
||||
import { SkillEntity } from 'src/engine/metadata-modules/skill/entities/skill.entity';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([ApplicationEntity, SkillEntity]),
|
||||
WorkspaceManyOrAllFlatEntityMapsCacheModule,
|
||||
],
|
||||
providers: [WorkspaceFlatSkillMapCacheService],
|
||||
providers: [
|
||||
WorkspaceFlatSkillMapCacheService,
|
||||
provideWorkspaceScopedRepository(SkillEntity),
|
||||
],
|
||||
exports: [WorkspaceFlatSkillMapCacheService],
|
||||
})
|
||||
export class FlatSkillModule {}
|
||||
|
||||
@@ -10,6 +10,8 @@ import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-enti
|
||||
import { type FlatSkillMaps } from 'src/engine/metadata-modules/flat-skill/types/flat-skill-maps.type';
|
||||
import { fromSkillEntityToFlatSkill } from 'src/engine/metadata-modules/flat-skill/utils/from-skill-entity-to-flat-skill.util';
|
||||
import { SkillEntity } from 'src/engine/metadata-modules/skill/entities/skill.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
||||
import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
|
||||
@@ -18,8 +20,8 @@ import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/
|
||||
@WorkspaceCache('flatSkillMaps')
|
||||
export class WorkspaceFlatSkillMapCacheService extends WorkspaceCacheProvider<FlatSkillMaps> {
|
||||
constructor(
|
||||
@InjectRepository(SkillEntity)
|
||||
private readonly skillRepository: Repository<SkillEntity>,
|
||||
@InjectWorkspaceScopedRepository(SkillEntity)
|
||||
private readonly skillRepository: WorkspaceScopedRepository<SkillEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
) {
|
||||
@@ -28,8 +30,7 @@ export class WorkspaceFlatSkillMapCacheService extends WorkspaceCacheProvider<Fl
|
||||
|
||||
async computeForCache(workspaceId: string): Promise<FlatSkillMaps> {
|
||||
const [skills, applications] = await Promise.all([
|
||||
this.skillRepository.find({
|
||||
where: { workspaceId },
|
||||
this.skillRepository.find(workspaceId, {
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.applicationRepository.find({
|
||||
|
||||
@@ -12,6 +12,8 @@ import { fromViewFieldGroupEntityToFlatViewFieldGroup } from 'src/engine/metadat
|
||||
import { ViewFieldGroupEntity } from 'src/engine/metadata-modules/view-field-group/entities/view-field-group.entity';
|
||||
import { ViewFieldEntity } from 'src/engine/metadata-modules/view-field/entities/view-field.entity';
|
||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
||||
import { regroupEntitiesByRelatedEntityId } from 'src/engine/workspace-cache/utils/regroup-entities-by-related-entity-id';
|
||||
@@ -21,14 +23,14 @@ import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/
|
||||
@WorkspaceCache('flatViewFieldGroupMaps')
|
||||
export class WorkspaceFlatViewFieldGroupMapCacheService extends WorkspaceCacheProvider<FlatViewFieldGroupMaps> {
|
||||
constructor(
|
||||
@InjectRepository(ViewFieldGroupEntity)
|
||||
private readonly viewFieldGroupRepository: Repository<ViewFieldGroupEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewFieldGroupEntity)
|
||||
private readonly viewFieldGroupRepository: WorkspaceScopedRepository<ViewFieldGroupEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
@InjectRepository(ViewEntity)
|
||||
private readonly viewRepository: Repository<ViewEntity>,
|
||||
@InjectRepository(ViewFieldEntity)
|
||||
private readonly viewFieldRepository: Repository<ViewFieldEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewEntity)
|
||||
private readonly viewRepository: WorkspaceScopedRepository<ViewEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewFieldEntity)
|
||||
private readonly viewFieldRepository: WorkspaceScopedRepository<ViewFieldEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -36,8 +38,7 @@ export class WorkspaceFlatViewFieldGroupMapCacheService extends WorkspaceCachePr
|
||||
async computeForCache(workspaceId: string): Promise<FlatViewFieldGroupMaps> {
|
||||
const [viewFieldGroups, applications, views, viewFields] =
|
||||
await Promise.all([
|
||||
this.viewFieldGroupRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewFieldGroupRepository.find(workspaceId, {
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.applicationRepository.find({
|
||||
@@ -45,13 +46,11 @@ export class WorkspaceFlatViewFieldGroupMapCacheService extends WorkspaceCachePr
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.viewRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.viewFieldRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewFieldRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier', 'viewFieldGroupId'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
|
||||
@@ -13,6 +13,8 @@ import { fromViewFieldEntityToFlatViewField } from 'src/engine/metadata-modules/
|
||||
import { ViewFieldGroupEntity } from 'src/engine/metadata-modules/view-field-group/entities/view-field-group.entity';
|
||||
import { ViewFieldEntity } from 'src/engine/metadata-modules/view-field/entities/view-field.entity';
|
||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
||||
import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
|
||||
@@ -21,16 +23,16 @@ import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/
|
||||
@WorkspaceCache('flatViewFieldMaps')
|
||||
export class WorkspaceFlatViewFieldMapCacheService extends WorkspaceCacheProvider<FlatViewFieldMaps> {
|
||||
constructor(
|
||||
@InjectRepository(ViewFieldEntity)
|
||||
private readonly viewFieldRepository: Repository<ViewFieldEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewFieldEntity)
|
||||
private readonly viewFieldRepository: WorkspaceScopedRepository<ViewFieldEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
@InjectRepository(FieldMetadataEntity)
|
||||
private readonly fieldMetadataRepository: Repository<FieldMetadataEntity>,
|
||||
@InjectRepository(ViewEntity)
|
||||
private readonly viewRepository: Repository<ViewEntity>,
|
||||
@InjectRepository(ViewFieldGroupEntity)
|
||||
private readonly viewFieldGroupRepository: Repository<ViewFieldGroupEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewEntity)
|
||||
private readonly viewRepository: WorkspaceScopedRepository<ViewEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewFieldGroupEntity)
|
||||
private readonly viewFieldGroupRepository: WorkspaceScopedRepository<ViewFieldGroupEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -38,8 +40,7 @@ export class WorkspaceFlatViewFieldMapCacheService extends WorkspaceCacheProvide
|
||||
async computeForCache(workspaceId: string): Promise<FlatViewFieldMaps> {
|
||||
const [viewFields, applications, fieldMetadatas, views, viewFieldGroups] =
|
||||
await Promise.all([
|
||||
this.viewFieldRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewFieldRepository.find(workspaceId, {
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.applicationRepository.find({
|
||||
@@ -52,13 +53,11 @@ export class WorkspaceFlatViewFieldMapCacheService extends WorkspaceCacheProvide
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.viewRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.viewFieldGroupRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewFieldGroupRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
|
||||
@@ -12,6 +12,8 @@ import { fromViewFilterGroupEntityToFlatViewFilterGroup } from 'src/engine/metad
|
||||
import { ViewFilterGroupEntity } from 'src/engine/metadata-modules/view-filter-group/entities/view-filter-group.entity';
|
||||
import { ViewFilterEntity } from 'src/engine/metadata-modules/view-filter/entities/view-filter.entity';
|
||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
||||
import { regroupEntitiesByRelatedEntityId } from 'src/engine/workspace-cache/utils/regroup-entities-by-related-entity-id';
|
||||
@@ -21,14 +23,14 @@ import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/
|
||||
@WorkspaceCache('flatViewFilterGroupMaps')
|
||||
export class WorkspaceFlatViewFilterGroupMapCacheService extends WorkspaceCacheProvider<FlatViewFilterGroupMaps> {
|
||||
constructor(
|
||||
@InjectRepository(ViewFilterGroupEntity)
|
||||
private readonly viewFilterGroupRepository: Repository<ViewFilterGroupEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewFilterGroupEntity)
|
||||
private readonly viewFilterGroupRepository: WorkspaceScopedRepository<ViewFilterGroupEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
@InjectRepository(ViewFilterEntity)
|
||||
private readonly viewFilterRepository: Repository<ViewFilterEntity>,
|
||||
@InjectRepository(ViewEntity)
|
||||
private readonly viewRepository: Repository<ViewEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewFilterEntity)
|
||||
private readonly viewFilterRepository: WorkspaceScopedRepository<ViewFilterEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewEntity)
|
||||
private readonly viewRepository: WorkspaceScopedRepository<ViewEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -36,8 +38,7 @@ export class WorkspaceFlatViewFilterGroupMapCacheService extends WorkspaceCacheP
|
||||
async computeForCache(workspaceId: string): Promise<FlatViewFilterGroupMaps> {
|
||||
const [viewFilterGroups, applications, viewFilters, views] =
|
||||
await Promise.all([
|
||||
this.viewFilterGroupRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewFilterGroupRepository.find(workspaceId, {
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.applicationRepository.find({
|
||||
@@ -45,13 +46,11 @@ export class WorkspaceFlatViewFilterGroupMapCacheService extends WorkspaceCacheP
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.viewFilterRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewFilterRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier', 'viewFilterGroupId'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.viewRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
|
||||
@@ -13,6 +13,8 @@ import { fromViewFilterEntityToFlatViewFilter } from 'src/engine/metadata-module
|
||||
import { ViewFilterGroupEntity } from 'src/engine/metadata-modules/view-filter-group/entities/view-filter-group.entity';
|
||||
import { ViewFilterEntity } from 'src/engine/metadata-modules/view-filter/entities/view-filter.entity';
|
||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
||||
import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
|
||||
@@ -21,16 +23,16 @@ import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/
|
||||
@WorkspaceCache('flatViewFilterMaps')
|
||||
export class WorkspaceFlatViewFilterMapCacheService extends WorkspaceCacheProvider<FlatViewFilterMaps> {
|
||||
constructor(
|
||||
@InjectRepository(ViewFilterEntity)
|
||||
private readonly viewFilterRepository: Repository<ViewFilterEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewFilterEntity)
|
||||
private readonly viewFilterRepository: WorkspaceScopedRepository<ViewFilterEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
@InjectRepository(FieldMetadataEntity)
|
||||
private readonly fieldMetadataRepository: Repository<FieldMetadataEntity>,
|
||||
@InjectRepository(ViewFilterGroupEntity)
|
||||
private readonly viewFilterGroupRepository: Repository<ViewFilterGroupEntity>,
|
||||
@InjectRepository(ViewEntity)
|
||||
private readonly viewRepository: Repository<ViewEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewFilterGroupEntity)
|
||||
private readonly viewFilterGroupRepository: WorkspaceScopedRepository<ViewFilterGroupEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewEntity)
|
||||
private readonly viewRepository: WorkspaceScopedRepository<ViewEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -38,8 +40,7 @@ export class WorkspaceFlatViewFilterMapCacheService extends WorkspaceCacheProvid
|
||||
async computeForCache(workspaceId: string): Promise<FlatViewFilterMaps> {
|
||||
const [viewFilters, applications, fieldMetadatas, viewFilterGroups, views] =
|
||||
await Promise.all([
|
||||
this.viewFilterRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewFilterRepository.find(workspaceId, {
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.applicationRepository.find({
|
||||
@@ -52,13 +53,11 @@ export class WorkspaceFlatViewFilterMapCacheService extends WorkspaceCacheProvid
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.viewFilterGroupRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewFilterGroupRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.viewRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
|
||||
@@ -11,6 +11,8 @@ import { FlatViewGroupMaps } from 'src/engine/metadata-modules/flat-view-group/t
|
||||
import { fromViewGroupEntityToFlatViewGroup } from 'src/engine/metadata-modules/flat-view-group/utils/from-view-group-entity-to-flat-view-group.util';
|
||||
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 { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
||||
import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
|
||||
@@ -19,20 +21,19 @@ import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/
|
||||
@WorkspaceCache('flatViewGroupMaps')
|
||||
export class WorkspaceFlatViewGroupMapCacheService extends WorkspaceCacheProvider<FlatViewGroupMaps> {
|
||||
constructor(
|
||||
@InjectRepository(ViewGroupEntity)
|
||||
private readonly viewGroupRepository: Repository<ViewGroupEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewGroupEntity)
|
||||
private readonly viewGroupRepository: WorkspaceScopedRepository<ViewGroupEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
@InjectRepository(ViewEntity)
|
||||
private readonly viewRepository: Repository<ViewEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewEntity)
|
||||
private readonly viewRepository: WorkspaceScopedRepository<ViewEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
async computeForCache(workspaceId: string): Promise<FlatViewGroupMaps> {
|
||||
const [viewGroups, applications, views] = await Promise.all([
|
||||
this.viewGroupRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewGroupRepository.find(workspaceId, {
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.applicationRepository.find({
|
||||
@@ -40,8 +41,7 @@ export class WorkspaceFlatViewGroupMapCacheService extends WorkspaceCacheProvide
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.viewRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
|
||||
@@ -5,6 +5,8 @@ import { Repository } from 'typeorm';
|
||||
|
||||
import { WorkspaceCacheProvider } from 'src/engine/workspace-cache/interfaces/workspace-cache-provider.service';
|
||||
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { FlatViewSortMaps } from 'src/engine/metadata-modules/flat-view-sort/types/flat-view-sort-maps.type';
|
||||
import { ViewSortEntity } from 'src/engine/metadata-modules/view-sort/entities/view-sort.entity';
|
||||
@@ -20,10 +22,10 @@ import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/uti
|
||||
@WorkspaceCache('flatViewSortMaps')
|
||||
export class WorkspaceFlatViewSortMapCacheService extends WorkspaceCacheProvider<FlatViewSortMaps> {
|
||||
constructor(
|
||||
@InjectRepository(ViewSortEntity)
|
||||
private readonly viewSortRepository: Repository<ViewSortEntity>,
|
||||
@InjectRepository(ViewEntity)
|
||||
private readonly viewRepository: Repository<ViewEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewSortEntity)
|
||||
private readonly viewSortRepository: WorkspaceScopedRepository<ViewSortEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewEntity)
|
||||
private readonly viewRepository: WorkspaceScopedRepository<ViewEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
@InjectRepository(FieldMetadataEntity)
|
||||
@@ -35,8 +37,7 @@ export class WorkspaceFlatViewSortMapCacheService extends WorkspaceCacheProvider
|
||||
async computeForCache(workspaceId: string): Promise<FlatViewSortMaps> {
|
||||
const [existingViewSorts, applications, views, fieldMetadatas] =
|
||||
await Promise.all([
|
||||
this.viewSortRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewSortRepository.find(workspaceId, {
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.applicationRepository.find({
|
||||
@@ -44,8 +45,7 @@ export class WorkspaceFlatViewSortMapCacheService extends WorkspaceCacheProvider
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.viewRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
|
||||
@@ -12,6 +12,7 @@ import { ViewFilterEntity } from 'src/engine/metadata-modules/view-filter/entiti
|
||||
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 { ViewSortEntity } from 'src/engine/metadata-modules/view-sort/entities/view-sort.entity';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -28,7 +29,16 @@ import { ViewSortEntity } from 'src/engine/metadata-modules/view-sort/entities/v
|
||||
ViewFilterGroupEntity,
|
||||
]),
|
||||
],
|
||||
providers: [WorkspaceFlatViewMapCacheService],
|
||||
providers: [
|
||||
WorkspaceFlatViewMapCacheService,
|
||||
provideWorkspaceScopedRepository(ViewEntity),
|
||||
provideWorkspaceScopedRepository(ViewFieldEntity),
|
||||
provideWorkspaceScopedRepository(ViewFieldGroupEntity),
|
||||
provideWorkspaceScopedRepository(ViewFilterEntity),
|
||||
provideWorkspaceScopedRepository(ViewFilterGroupEntity),
|
||||
provideWorkspaceScopedRepository(ViewGroupEntity),
|
||||
provideWorkspaceScopedRepository(ViewSortEntity),
|
||||
],
|
||||
exports: [WorkspaceFlatViewMapCacheService],
|
||||
})
|
||||
export class FlatViewModule {}
|
||||
|
||||
@@ -18,6 +18,8 @@ import { ViewFilterEntity } from 'src/engine/metadata-modules/view-filter/entiti
|
||||
import { ViewGroupEntity } from 'src/engine/metadata-modules/view-group/entities/view-group.entity';
|
||||
import { ViewSortEntity } from 'src/engine/metadata-modules/view-sort/entities/view-sort.entity';
|
||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
||||
import { regroupEntitiesByRelatedEntityId } from 'src/engine/workspace-cache/utils/regroup-entities-by-related-entity-id';
|
||||
@@ -27,26 +29,26 @@ import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/
|
||||
@WorkspaceCache('flatViewMaps')
|
||||
export class WorkspaceFlatViewMapCacheService extends WorkspaceCacheProvider<FlatViewMaps> {
|
||||
constructor(
|
||||
@InjectRepository(ViewEntity)
|
||||
private readonly viewRepository: Repository<ViewEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewEntity)
|
||||
private readonly viewRepository: WorkspaceScopedRepository<ViewEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
@InjectRepository(ObjectMetadataEntity)
|
||||
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
|
||||
@InjectRepository(FieldMetadataEntity)
|
||||
private readonly fieldMetadataRepository: Repository<FieldMetadataEntity>,
|
||||
@InjectRepository(ViewFieldEntity)
|
||||
private readonly viewFieldRepository: Repository<ViewFieldEntity>,
|
||||
@InjectRepository(ViewFilterEntity)
|
||||
private readonly viewFilterRepository: Repository<ViewFilterEntity>,
|
||||
@InjectRepository(ViewGroupEntity)
|
||||
private readonly viewGroupRepository: Repository<ViewGroupEntity>,
|
||||
@InjectRepository(ViewFilterGroupEntity)
|
||||
private readonly viewFilterGroupRepository: Repository<ViewFilterGroupEntity>,
|
||||
@InjectRepository(ViewSortEntity)
|
||||
private readonly viewSortRepository: Repository<ViewSortEntity>,
|
||||
@InjectRepository(ViewFieldGroupEntity)
|
||||
private readonly viewFieldGroupRepository: Repository<ViewFieldGroupEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewFieldEntity)
|
||||
private readonly viewFieldRepository: WorkspaceScopedRepository<ViewFieldEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewFilterEntity)
|
||||
private readonly viewFilterRepository: WorkspaceScopedRepository<ViewFilterEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewGroupEntity)
|
||||
private readonly viewGroupRepository: WorkspaceScopedRepository<ViewGroupEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewFilterGroupEntity)
|
||||
private readonly viewFilterGroupRepository: WorkspaceScopedRepository<ViewFilterGroupEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewSortEntity)
|
||||
private readonly viewSortRepository: WorkspaceScopedRepository<ViewSortEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewFieldGroupEntity)
|
||||
private readonly viewFieldGroupRepository: WorkspaceScopedRepository<ViewFieldGroupEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -64,8 +66,7 @@ export class WorkspaceFlatViewMapCacheService extends WorkspaceCacheProvider<Fla
|
||||
viewSorts,
|
||||
viewFieldGroups,
|
||||
] = await Promise.all([
|
||||
this.viewRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewRepository.find(workspaceId, {
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.applicationRepository.find({
|
||||
@@ -83,33 +84,27 @@ export class WorkspaceFlatViewMapCacheService extends WorkspaceCacheProvider<Fla
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.viewFieldRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewFieldRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier', 'viewId'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.viewFilterRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewFilterRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier', 'viewId'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.viewGroupRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewGroupRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier', 'viewId'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.viewFilterGroupRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewFilterGroupRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier', 'viewId'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.viewSortRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewSortRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier', 'viewId'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.viewFieldGroupRepository.find({
|
||||
where: { workspaceId },
|
||||
this.viewFieldGroupRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier', 'viewId'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
|
||||
@@ -5,13 +5,17 @@ import { ApplicationEntity } from 'src/engine/core-modules/application/applicati
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module';
|
||||
import { WorkspaceFlatWebhookMapCacheService } from 'src/engine/metadata-modules/flat-webhook/services/workspace-flat-webhook-map-cache.service';
|
||||
import { WebhookEntity } from 'src/engine/metadata-modules/webhook/entities/webhook.entity';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([ApplicationEntity, WebhookEntity]),
|
||||
WorkspaceManyOrAllFlatEntityMapsCacheModule,
|
||||
],
|
||||
providers: [WorkspaceFlatWebhookMapCacheService],
|
||||
providers: [
|
||||
WorkspaceFlatWebhookMapCacheService,
|
||||
provideWorkspaceScopedRepository(WebhookEntity),
|
||||
],
|
||||
exports: [WorkspaceFlatWebhookMapCacheService],
|
||||
})
|
||||
export class FlatWebhookModule {}
|
||||
|
||||
@@ -10,6 +10,8 @@ import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-enti
|
||||
import { type FlatWebhookMaps } from 'src/engine/metadata-modules/flat-webhook/types/flat-webhook-maps.type';
|
||||
import { fromWebhookEntityToFlatWebhook } from 'src/engine/metadata-modules/flat-webhook/utils/from-webhook-entity-to-flat-webhook.util';
|
||||
import { WebhookEntity } from 'src/engine/metadata-modules/webhook/entities/webhook.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
||||
import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
|
||||
@@ -18,8 +20,8 @@ import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/
|
||||
@WorkspaceCache('flatWebhookMaps')
|
||||
export class WorkspaceFlatWebhookMapCacheService extends WorkspaceCacheProvider<FlatWebhookMaps> {
|
||||
constructor(
|
||||
@InjectRepository(WebhookEntity)
|
||||
private readonly webhookRepository: Repository<WebhookEntity>,
|
||||
@InjectWorkspaceScopedRepository(WebhookEntity)
|
||||
private readonly webhookRepository: WorkspaceScopedRepository<WebhookEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
) {
|
||||
@@ -28,8 +30,8 @@ export class WorkspaceFlatWebhookMapCacheService extends WorkspaceCacheProvider<
|
||||
|
||||
async computeForCache(workspaceId: string): Promise<FlatWebhookMaps> {
|
||||
const [webhooks, applications] = await Promise.all([
|
||||
this.webhookRepository.find({
|
||||
where: { workspaceId, deletedAt: IsNull() },
|
||||
this.webhookRepository.find(workspaceId, {
|
||||
where: { deletedAt: IsNull() },
|
||||
}),
|
||||
this.applicationRepository.find({
|
||||
where: { workspaceId },
|
||||
|
||||
@@ -11,6 +11,7 @@ import { ApplicationEntity } from 'src/engine/core-modules/application/applicati
|
||||
import { PermissionsService } from 'src/engine/metadata-modules/permissions/permissions.service';
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role.service';
|
||||
import { getWorkspaceScopedRepositoryToken } from 'src/engine/twenty-orm/workspace-scoped-repository/get-workspace-scoped-repository-token.util';
|
||||
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
|
||||
|
||||
describe('PermissionsService', () => {
|
||||
@@ -21,7 +22,7 @@ describe('PermissionsService', () => {
|
||||
providers: [
|
||||
PermissionsService,
|
||||
{
|
||||
provide: getRepositoryToken(RoleEntity),
|
||||
provide: getWorkspaceScopedRepositoryToken(RoleEntity),
|
||||
useValue: {},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -32,6 +32,8 @@ import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache
|
||||
ApiKeyRoleService,
|
||||
PermissionsService,
|
||||
provideWorkspaceScopedRepository(ApiKeyEntity),
|
||||
provideWorkspaceScopedRepository(RoleEntity),
|
||||
provideWorkspaceScopedRepository(RoleTargetEntity),
|
||||
],
|
||||
exports: [PermissionsService, ApiKeyRoleService],
|
||||
})
|
||||
|
||||
@@ -25,6 +25,8 @@ import { type UserWorkspacePermissions } from 'src/engine/metadata-modules/permi
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role.service';
|
||||
import { type RolePermissionConfig } from 'src/engine/twenty-orm/types/role-permission-config';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
|
||||
|
||||
@Injectable()
|
||||
@@ -33,8 +35,8 @@ export class PermissionsService {
|
||||
private readonly userRoleService: UserRoleService,
|
||||
private readonly workspaceCacheService: WorkspaceCacheService,
|
||||
private readonly apiKeyRoleService: ApiKeyRoleService,
|
||||
@InjectRepository(RoleEntity)
|
||||
private readonly roleRepository: Repository<RoleEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleEntity)
|
||||
private readonly roleRepository: WorkspaceScopedRepository<RoleEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
) {}
|
||||
@@ -149,8 +151,8 @@ export class PermissionsService {
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
const role = await this.roleRepository.findOne({
|
||||
where: { id: roleId, workspaceId },
|
||||
const role = await this.roleRepository.findOne(workspaceId, {
|
||||
where: { id: roleId },
|
||||
relations: [
|
||||
'rolePermissionFlags',
|
||||
'rolePermissionFlags.permissionFlag',
|
||||
@@ -205,8 +207,8 @@ export class PermissionsService {
|
||||
|
||||
const applicationRoleId = application.defaultRoleId;
|
||||
|
||||
const role = await this.roleRepository.findOne({
|
||||
where: { id: applicationRoleId, workspaceId },
|
||||
const role = await this.roleRepository.findOne(workspaceId, {
|
||||
where: { id: applicationRoleId },
|
||||
relations: [
|
||||
'rolePermissionFlags',
|
||||
'rolePermissionFlags.permissionFlag',
|
||||
@@ -289,8 +291,8 @@ export class PermissionsService {
|
||||
throw new Error('No role IDs provided');
|
||||
}
|
||||
|
||||
const roles = await this.roleRepository.find({
|
||||
where: { id: In(roleIds), workspaceId },
|
||||
const roles = await this.roleRepository.find(workspaceId, {
|
||||
where: { id: In(roleIds) },
|
||||
relations,
|
||||
});
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata
|
||||
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 { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module';
|
||||
|
||||
import { RoleTargetService } from './services/role-target.service';
|
||||
@@ -21,6 +22,7 @@ import { RoleTargetService } from './services/role-target.service';
|
||||
RoleTargetService,
|
||||
WorkspaceUserWorkspaceRoleMapCacheService,
|
||||
WorkspaceApiKeyRoleMapCacheService,
|
||||
provideWorkspaceScopedRepository(RoleTargetEntity),
|
||||
],
|
||||
exports: [RoleTargetService],
|
||||
})
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { IsNull, Not, Repository } from 'typeorm';
|
||||
import { IsNull, Not } from 'typeorm';
|
||||
|
||||
import { WorkspaceCacheProvider } from 'src/engine/workspace-cache/interfaces/workspace-cache-provider.service';
|
||||
|
||||
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
|
||||
@Injectable()
|
||||
@@ -14,16 +15,15 @@ export class WorkspaceApiKeyRoleMapCacheService extends WorkspaceCacheProvider<
|
||||
Record<string, string>
|
||||
> {
|
||||
constructor(
|
||||
@InjectRepository(RoleTargetEntity)
|
||||
private readonly roleTargetRepository: Repository<RoleTargetEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleTargetEntity)
|
||||
private readonly roleTargetRepository: WorkspaceScopedRepository<RoleTargetEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
async computeForCache(workspaceId: string): Promise<Record<string, string>> {
|
||||
const roleTargetsMap = await this.roleTargetRepository.find({
|
||||
const roleTargetsMap = await this.roleTargetRepository.find(workspaceId, {
|
||||
where: {
|
||||
workspaceId,
|
||||
apiKeyId: Not(IsNull()),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IsNull, Not, Repository } from 'typeorm';
|
||||
import { IsNull, Not } from 'typeorm';
|
||||
|
||||
import { WorkspaceCacheProvider } from 'src/engine/workspace-cache/interfaces/workspace-cache-provider.service';
|
||||
|
||||
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
|
||||
import { UserWorkspaceRoleMap } from 'src/engine/metadata-modules/role-target/types/user-workspace-role-map';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
|
||||
@Injectable()
|
||||
@WorkspaceCache('userWorkspaceRoleMap')
|
||||
export class WorkspaceUserWorkspaceRoleMapCacheService extends WorkspaceCacheProvider<UserWorkspaceRoleMap> {
|
||||
constructor(
|
||||
@InjectRepository(RoleTargetEntity)
|
||||
private readonly roleTargetRepository: Repository<RoleTargetEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleTargetEntity)
|
||||
private readonly roleTargetRepository: WorkspaceScopedRepository<RoleTargetEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
async computeForCache(workspaceId: string): Promise<UserWorkspaceRoleMap> {
|
||||
const roleTargetsMap = await this.roleTargetRepository.find({
|
||||
const roleTargetsMap = await this.roleTargetRepository.find(workspaceId, {
|
||||
where: {
|
||||
workspaceId,
|
||||
userWorkspaceId: Not(IsNull()),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -3,10 +3,14 @@ import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { RoleValidationService } from 'src/engine/metadata-modules/role-validation/services/role-validation.service';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([RoleEntity])],
|
||||
providers: [RoleValidationService],
|
||||
providers: [
|
||||
RoleValidationService,
|
||||
provideWorkspaceScopedRepository(RoleEntity),
|
||||
],
|
||||
exports: [RoleValidationService],
|
||||
})
|
||||
export class RoleValidationModule {}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import {
|
||||
PermissionsException,
|
||||
@@ -9,22 +6,23 @@ import {
|
||||
PermissionsExceptionMessage,
|
||||
} from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
|
||||
@Injectable()
|
||||
export class RoleValidationService {
|
||||
constructor(
|
||||
@InjectRepository(RoleEntity)
|
||||
private readonly roleRepository: Repository<RoleEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleEntity)
|
||||
private readonly roleRepository: WorkspaceScopedRepository<RoleEntity>,
|
||||
) {}
|
||||
|
||||
async validateRoleAssignableToUsersOrThrow(
|
||||
roleId: string,
|
||||
workspaceId: string,
|
||||
): Promise<void> {
|
||||
const role = await this.roleRepository.findOne({
|
||||
const role = await this.roleRepository.findOne(workspaceId, {
|
||||
where: {
|
||||
id: roleId,
|
||||
workspaceId,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import { RowLevelPermissionPredicateGroupEntity } from 'src/engine/metadata-modu
|
||||
import { RowLevelPermissionPredicateEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate.entity';
|
||||
import { RowLevelPermissionModule } from 'src/engine/metadata-modules/row-level-permission-predicate/row-level-permission.module';
|
||||
import { UserRoleModule } from 'src/engine/metadata-modules/user-role/user-role.module';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
|
||||
import { WorkspaceMigrationGraphqlApiExceptionInterceptor } from 'src/engine/workspace-manager/workspace-migration/interceptors/workspace-migration-graphql-api-exception.interceptor';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module';
|
||||
@@ -69,6 +70,12 @@ import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace
|
||||
WorkspaceFlatRoleTargetMapCacheService,
|
||||
WorkspaceMigrationGraphqlApiExceptionInterceptor,
|
||||
WorkspaceRolesPermissionsCacheService,
|
||||
provideWorkspaceScopedRepository(RoleEntity),
|
||||
provideWorkspaceScopedRepository(RoleTargetEntity),
|
||||
provideWorkspaceScopedRepository(ObjectPermissionEntity),
|
||||
provideWorkspaceScopedRepository(FieldPermissionEntity),
|
||||
provideWorkspaceScopedRepository(RowLevelPermissionPredicateEntity),
|
||||
provideWorkspaceScopedRepository(RowLevelPermissionPredicateGroupEntity),
|
||||
],
|
||||
exports: [
|
||||
RoleService,
|
||||
|
||||
@@ -36,6 +36,8 @@ import { type UpdateRoleInput } from 'src/engine/metadata-modules/role/dtos/upda
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { fromFlatRoleToRoleDto } from 'src/engine/metadata-modules/role/utils/fromFlatRoleToRoleDto.util';
|
||||
import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role.service';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service';
|
||||
|
||||
@@ -46,8 +48,8 @@ export class RoleService {
|
||||
private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
|
||||
@InjectRepository(WorkspaceEntity)
|
||||
private readonly workspaceRepository: Repository<WorkspaceEntity>,
|
||||
@InjectRepository(RoleEntity)
|
||||
private readonly roleRepository: Repository<RoleEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleEntity)
|
||||
private readonly roleRepository: WorkspaceScopedRepository<RoleEntity>,
|
||||
private readonly userRoleService: UserRoleService,
|
||||
private readonly applicationService: ApplicationService,
|
||||
private readonly apiKeyRoleService: ApiKeyRoleService,
|
||||
@@ -55,10 +57,7 @@ export class RoleService {
|
||||
) {}
|
||||
|
||||
public async getWorkspaceRoles(workspaceId: string): Promise<RoleEntity[]> {
|
||||
return this.roleRepository.find({
|
||||
where: {
|
||||
workspaceId,
|
||||
},
|
||||
return this.roleRepository.find(workspaceId, {
|
||||
relations: {
|
||||
roleTargets: true,
|
||||
rolePermissionFlags: {
|
||||
@@ -74,10 +73,9 @@ export class RoleService {
|
||||
id: string,
|
||||
workspaceId: string,
|
||||
): Promise<RoleEntity | null> {
|
||||
return this.roleRepository.findOne({
|
||||
return this.roleRepository.findOne(workspaceId, {
|
||||
where: {
|
||||
id,
|
||||
workspaceId,
|
||||
},
|
||||
relations: {
|
||||
roleTargets: true,
|
||||
|
||||
@@ -16,6 +16,8 @@ import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { WorkspaceRolesPermissionsCacheService } from 'src/engine/metadata-modules/role/services/workspace-roles-permissions-cache.service';
|
||||
import { RowLevelPermissionPredicateGroupEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate-group.entity';
|
||||
import { RowLevelPermissionPredicateEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate.entity';
|
||||
import { getWorkspaceScopedRepositoryToken } from 'src/engine/twenty-orm/workspace-scoped-repository/get-workspace-scoped-repository-token.util';
|
||||
import { type WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
|
||||
const WORKSPACE_ID = '20202020-0000-4000-8000-000000000000';
|
||||
const ROLE_ID = '11111111-1111-4111-8111-111111111111';
|
||||
@@ -52,12 +54,14 @@ const createBaseRole = (
|
||||
|
||||
describe('WorkspaceRolesPermissionsCacheService', () => {
|
||||
let service: WorkspaceRolesPermissionsCacheService;
|
||||
let roleRepository: jest.Mocked<Pick<Repository<RoleEntity>, 'find'>>;
|
||||
let roleRepository: jest.Mocked<
|
||||
Pick<WorkspaceScopedRepository<RoleEntity>, 'find'>
|
||||
>;
|
||||
let objectMetadataRepository: jest.Mocked<
|
||||
Pick<Repository<ObjectMetadataEntity>, 'find'>
|
||||
>;
|
||||
let objectPermissionRepository: jest.Mocked<
|
||||
Pick<Repository<ObjectPermissionEntity>, 'find'>
|
||||
Pick<WorkspaceScopedRepository<ObjectPermissionEntity>, 'find'>
|
||||
>;
|
||||
let rolePermissionFlagRepository: jest.Mocked<
|
||||
Pick<Repository<RolePermissionFlagEntity>, 'find'>
|
||||
@@ -118,11 +122,11 @@ describe('WorkspaceRolesPermissionsCacheService', () => {
|
||||
useValue: objectMetadataRepository,
|
||||
},
|
||||
{
|
||||
provide: getRepositoryToken(RoleEntity),
|
||||
provide: getWorkspaceScopedRepositoryToken(RoleEntity),
|
||||
useValue: roleRepository,
|
||||
},
|
||||
{
|
||||
provide: getRepositoryToken(ObjectPermissionEntity),
|
||||
provide: getWorkspaceScopedRepositoryToken(ObjectPermissionEntity),
|
||||
useValue: objectPermissionRepository,
|
||||
},
|
||||
{
|
||||
@@ -130,15 +134,19 @@ describe('WorkspaceRolesPermissionsCacheService', () => {
|
||||
useValue: rolePermissionFlagRepository,
|
||||
},
|
||||
{
|
||||
provide: getRepositoryToken(FieldPermissionEntity),
|
||||
provide: getWorkspaceScopedRepositoryToken(FieldPermissionEntity),
|
||||
useValue: fieldPermissionRepository,
|
||||
},
|
||||
{
|
||||
provide: getRepositoryToken(RowLevelPermissionPredicateEntity),
|
||||
provide: getWorkspaceScopedRepositoryToken(
|
||||
RowLevelPermissionPredicateEntity,
|
||||
),
|
||||
useValue: rowLevelPermissionPredicateRepository,
|
||||
},
|
||||
{
|
||||
provide: getRepositoryToken(RowLevelPermissionPredicateGroupEntity),
|
||||
provide: getWorkspaceScopedRepositoryToken(
|
||||
RowLevelPermissionPredicateGroupEntity,
|
||||
),
|
||||
useValue: rowLevelPermissionPredicateGroupRepository,
|
||||
},
|
||||
],
|
||||
|
||||
@@ -17,6 +17,8 @@ import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-t
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { RowLevelPermissionPredicateGroupEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate-group.entity';
|
||||
import { RowLevelPermissionPredicateEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
||||
import { regroupEntitiesByRelatedEntityId } from 'src/engine/workspace-cache/utils/regroup-entities-by-related-entity-id';
|
||||
@@ -28,22 +30,22 @@ export class WorkspaceFlatRoleMapCacheService extends WorkspaceCacheProvider<
|
||||
FlatEntityMaps<FlatRole>
|
||||
> {
|
||||
constructor(
|
||||
@InjectRepository(RoleEntity)
|
||||
private readonly roleRepository: Repository<RoleEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleEntity)
|
||||
private readonly roleRepository: WorkspaceScopedRepository<RoleEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
@InjectRepository(RoleTargetEntity)
|
||||
private readonly roleTargetRepository: Repository<RoleTargetEntity>,
|
||||
@InjectRepository(ObjectPermissionEntity)
|
||||
private readonly objectPermissionRepository: Repository<ObjectPermissionEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleTargetEntity)
|
||||
private readonly roleTargetRepository: WorkspaceScopedRepository<RoleTargetEntity>,
|
||||
@InjectWorkspaceScopedRepository(ObjectPermissionEntity)
|
||||
private readonly objectPermissionRepository: WorkspaceScopedRepository<ObjectPermissionEntity>,
|
||||
@InjectRepository(RolePermissionFlagEntity)
|
||||
private readonly rolePermissionFlagRepository: Repository<RolePermissionFlagEntity>,
|
||||
@InjectRepository(FieldPermissionEntity)
|
||||
private readonly fieldPermissionRepository: Repository<FieldPermissionEntity>,
|
||||
@InjectRepository(RowLevelPermissionPredicateEntity)
|
||||
private readonly rowLevelPermissionPredicateRepository: Repository<RowLevelPermissionPredicateEntity>,
|
||||
@InjectRepository(RowLevelPermissionPredicateGroupEntity)
|
||||
private readonly rowLevelPermissionPredicateGroupRepository: Repository<RowLevelPermissionPredicateGroupEntity>,
|
||||
@InjectWorkspaceScopedRepository(FieldPermissionEntity)
|
||||
private readonly fieldPermissionRepository: WorkspaceScopedRepository<FieldPermissionEntity>,
|
||||
@InjectWorkspaceScopedRepository(RowLevelPermissionPredicateEntity)
|
||||
private readonly rowLevelPermissionPredicateRepository: WorkspaceScopedRepository<RowLevelPermissionPredicateEntity>,
|
||||
@InjectWorkspaceScopedRepository(RowLevelPermissionPredicateGroupEntity)
|
||||
private readonly rowLevelPermissionPredicateGroupRepository: WorkspaceScopedRepository<RowLevelPermissionPredicateGroupEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -61,8 +63,7 @@ export class WorkspaceFlatRoleMapCacheService extends WorkspaceCacheProvider<
|
||||
rowLevelPermissionPredicates,
|
||||
rowLevelPermissionPredicateGroups,
|
||||
] = await Promise.all([
|
||||
this.roleRepository.find({
|
||||
where: { workspaceId },
|
||||
this.roleRepository.find(workspaceId, {
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.applicationRepository.find({
|
||||
@@ -70,13 +71,11 @@ export class WorkspaceFlatRoleMapCacheService extends WorkspaceCacheProvider<
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.roleTargetRepository.find({
|
||||
where: { workspaceId },
|
||||
this.roleTargetRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier', 'roleId'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.objectPermissionRepository.find({
|
||||
where: { workspaceId },
|
||||
this.objectPermissionRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier', 'roleId'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
@@ -85,18 +84,15 @@ export class WorkspaceFlatRoleMapCacheService extends WorkspaceCacheProvider<
|
||||
select: ['id', 'universalIdentifier', 'roleId'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.fieldPermissionRepository.find({
|
||||
where: { workspaceId },
|
||||
this.fieldPermissionRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier', 'roleId'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.rowLevelPermissionPredicateRepository.find({
|
||||
where: { workspaceId },
|
||||
this.rowLevelPermissionPredicateRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier', 'roleId'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.rowLevelPermissionPredicateGroupRepository.find({
|
||||
where: { workspaceId },
|
||||
this.rowLevelPermissionPredicateGroupRepository.find(workspaceId, {
|
||||
select: ['id', 'universalIdentifier', 'roleId'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
|
||||
@@ -23,6 +23,8 @@ import { RolePermissionFlagEntity } from 'src/engine/metadata-modules/role-permi
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { RowLevelPermissionPredicateGroupEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate-group.entity';
|
||||
import { RowLevelPermissionPredicateEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { regroupEntitiesByRelatedEntityId } from 'src/engine/workspace-cache/utils/regroup-entities-by-related-entity-id';
|
||||
|
||||
@@ -40,18 +42,18 @@ export class WorkspaceRolesPermissionsCacheService extends WorkspaceCacheProvide
|
||||
constructor(
|
||||
@InjectRepository(ObjectMetadataEntity)
|
||||
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
|
||||
@InjectRepository(RoleEntity)
|
||||
private readonly roleRepository: Repository<RoleEntity>,
|
||||
@InjectRepository(ObjectPermissionEntity)
|
||||
private readonly objectPermissionRepository: Repository<ObjectPermissionEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleEntity)
|
||||
private readonly roleRepository: WorkspaceScopedRepository<RoleEntity>,
|
||||
@InjectWorkspaceScopedRepository(ObjectPermissionEntity)
|
||||
private readonly objectPermissionRepository: WorkspaceScopedRepository<ObjectPermissionEntity>,
|
||||
@InjectRepository(RolePermissionFlagEntity)
|
||||
private readonly rolePermissionFlagRepository: Repository<RolePermissionFlagEntity>,
|
||||
@InjectRepository(FieldPermissionEntity)
|
||||
private readonly fieldPermissionRepository: Repository<FieldPermissionEntity>,
|
||||
@InjectRepository(RowLevelPermissionPredicateEntity)
|
||||
private readonly rowLevelPermissionPredicateRepository: Repository<RowLevelPermissionPredicateEntity>,
|
||||
@InjectRepository(RowLevelPermissionPredicateGroupEntity)
|
||||
private readonly rowLevelPermissionPredicateGroupRepository: Repository<RowLevelPermissionPredicateGroupEntity>,
|
||||
@InjectWorkspaceScopedRepository(FieldPermissionEntity)
|
||||
private readonly fieldPermissionRepository: WorkspaceScopedRepository<FieldPermissionEntity>,
|
||||
@InjectWorkspaceScopedRepository(RowLevelPermissionPredicateEntity)
|
||||
private readonly rowLevelPermissionPredicateRepository: WorkspaceScopedRepository<RowLevelPermissionPredicateEntity>,
|
||||
@InjectWorkspaceScopedRepository(RowLevelPermissionPredicateGroupEntity)
|
||||
private readonly rowLevelPermissionPredicateGroupRepository: WorkspaceScopedRepository<RowLevelPermissionPredicateGroupEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -68,24 +70,18 @@ export class WorkspaceRolesPermissionsCacheService extends WorkspaceCacheProvide
|
||||
rowLevelPermissionPredicateGroups,
|
||||
workspaceObjectMetadataCollection,
|
||||
] = await Promise.all([
|
||||
this.roleRepository.find({
|
||||
where: { workspaceId },
|
||||
}),
|
||||
this.objectPermissionRepository.find({
|
||||
where: { workspaceId },
|
||||
}),
|
||||
this.roleRepository.find(workspaceId),
|
||||
this.objectPermissionRepository.find(workspaceId),
|
||||
this.rolePermissionFlagRepository.find({
|
||||
where: { workspaceId },
|
||||
relations: ['permissionFlag'],
|
||||
}),
|
||||
this.fieldPermissionRepository.find({
|
||||
where: { workspaceId },
|
||||
this.fieldPermissionRepository.find(workspaceId),
|
||||
this.rowLevelPermissionPredicateRepository.find(workspaceId, {
|
||||
where: { deletedAt: IsNull() },
|
||||
}),
|
||||
this.rowLevelPermissionPredicateRepository.find({
|
||||
where: { workspaceId, deletedAt: IsNull() },
|
||||
}),
|
||||
this.rowLevelPermissionPredicateGroupRepository.find({
|
||||
where: { workspaceId, deletedAt: IsNull() },
|
||||
this.rowLevelPermissionPredicateGroupRepository.find(workspaceId, {
|
||||
where: { deletedAt: IsNull() },
|
||||
}),
|
||||
this.getWorkspaceObjectMetadataCollection(workspaceId),
|
||||
]);
|
||||
|
||||
@@ -11,6 +11,7 @@ import { RowLevelPermissionPredicateGroupEntity } from 'src/engine/metadata-modu
|
||||
import { RowLevelPermissionPredicateEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate.entity';
|
||||
import { RowLevelPermissionPredicateGroupService } from 'src/engine/metadata-modules/row-level-permission-predicate/services/row-level-permission-predicate-group.service';
|
||||
import { RowLevelPermissionPredicateService } from 'src/engine/metadata-modules/row-level-permission-predicate/services/row-level-permission-predicate.service';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module';
|
||||
|
||||
@@ -30,6 +31,7 @@ import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace
|
||||
providers: [
|
||||
RowLevelPermissionPredicateService,
|
||||
RowLevelPermissionPredicateGroupService,
|
||||
provideWorkspaceScopedRepository(RowLevelPermissionPredicateGroupEntity),
|
||||
],
|
||||
exports: [
|
||||
RowLevelPermissionPredicateService,
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
/* @license Enterprise */
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { BillingEntitlementKey } from 'src/engine/core-modules/billing/enums/billing-entitlement-key.enum';
|
||||
import { BillingService } from 'src/engine/core-modules/billing/services/billing.service';
|
||||
@@ -14,6 +12,8 @@ import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/
|
||||
import { fromFlatRowLevelPermissionPredicateGroupToDto } from 'src/engine/metadata-modules/flat-row-level-permission-predicate/utils/from-flat-row-level-permission-predicate-group-to-dto.util';
|
||||
import { RowLevelPermissionPredicateGroupDTO } from 'src/engine/metadata-modules/row-level-permission-predicate/dtos/row-level-permission-predicate-group.dto';
|
||||
import { RowLevelPermissionPredicateGroupEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate-group.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
|
||||
|
||||
@Injectable()
|
||||
@@ -22,8 +22,8 @@ export class RowLevelPermissionPredicateGroupService {
|
||||
private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
|
||||
private readonly workspaceCacheService: WorkspaceCacheService,
|
||||
private readonly billingService: BillingService,
|
||||
@InjectRepository(RowLevelPermissionPredicateGroupEntity)
|
||||
private readonly rowLevelPermissionPredicateGroupRepository: Repository<RowLevelPermissionPredicateGroupEntity>,
|
||||
@InjectWorkspaceScopedRepository(RowLevelPermissionPredicateGroupEntity)
|
||||
private readonly rowLevelPermissionPredicateGroupRepository: WorkspaceScopedRepository<RowLevelPermissionPredicateGroupEntity>,
|
||||
private readonly enterprisePlanService: EnterprisePlanService,
|
||||
) {}
|
||||
|
||||
@@ -122,9 +122,10 @@ export class RowLevelPermissionPredicateGroupService {
|
||||
}
|
||||
|
||||
public async deleteAllRowLevelPermissionPredicateGroups(workspaceId: string) {
|
||||
await this.rowLevelPermissionPredicateGroupRepository.delete({
|
||||
await this.rowLevelPermissionPredicateGroupRepository.delete(
|
||||
workspaceId,
|
||||
});
|
||||
{},
|
||||
);
|
||||
|
||||
await this.workspaceCacheService.invalidateAndRecompute(workspaceId, [
|
||||
'rolesPermissions',
|
||||
|
||||
@@ -6,6 +6,7 @@ import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-t
|
||||
import { RoleTargetModule } from 'src/engine/metadata-modules/role-target/role-target.module';
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role.service';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
|
||||
|
||||
@Module({
|
||||
@@ -15,7 +16,10 @@ import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache
|
||||
WorkspaceCacheModule,
|
||||
RoleTargetModule,
|
||||
],
|
||||
providers: [UserRoleService],
|
||||
providers: [
|
||||
UserRoleService,
|
||||
provideWorkspaceScopedRepository(RoleTargetEntity),
|
||||
],
|
||||
exports: [UserRoleService],
|
||||
})
|
||||
export class UserRoleModule {}
|
||||
|
||||
@@ -15,14 +15,16 @@ import { RoleTargetService } from 'src/engine/metadata-modules/role-target/servi
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager';
|
||||
import { buildSystemAuthContext } from 'src/engine/twenty-orm/utils/build-system-auth-context.util';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
|
||||
import { STANDARD_ROLE } from 'src/engine/workspace-manager/twenty-standard-application/constants/standard-role.constant';
|
||||
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
|
||||
|
||||
export class UserRoleService {
|
||||
constructor(
|
||||
@InjectRepository(RoleTargetEntity)
|
||||
private readonly roleTargetRepository: Repository<RoleTargetEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleTargetEntity)
|
||||
private readonly roleTargetRepository: WorkspaceScopedRepository<RoleTargetEntity>,
|
||||
@InjectRepository(UserWorkspaceEntity)
|
||||
private readonly userWorkspaceRepository: Repository<UserWorkspaceEntity>,
|
||||
private readonly globalWorkspaceOrmManager: GlobalWorkspaceOrmManager,
|
||||
@@ -101,10 +103,9 @@ export class UserRoleService {
|
||||
return new Map();
|
||||
}
|
||||
|
||||
const allRoleTargets = await this.roleTargetRepository.find({
|
||||
const allRoleTargets = await this.roleTargetRepository.find(workspaceId, {
|
||||
where: {
|
||||
userWorkspaceId: In(userWorkspaceIds),
|
||||
workspaceId,
|
||||
},
|
||||
relations: {
|
||||
role: {
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { t } from '@lingui/core/macro';
|
||||
import {
|
||||
isDefined,
|
||||
isFieldMetadataEligibleForFieldsWidget,
|
||||
} from 'twenty-shared/utils';
|
||||
import { IsNull, Repository } from 'typeorm';
|
||||
import { IsNull } from 'typeorm';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
@@ -36,6 +35,8 @@ import {
|
||||
ViewFieldGroupExceptionCode,
|
||||
} from 'src/engine/metadata-modules/view-field-group/exceptions/view-field-group.exception';
|
||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service';
|
||||
|
||||
@@ -45,8 +46,8 @@ export class FieldsWidgetUpsertService {
|
||||
private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService,
|
||||
private readonly workspaceManyOrAllFlatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
|
||||
private readonly applicationService: ApplicationService,
|
||||
@InjectRepository(ViewEntity)
|
||||
private readonly viewRepository: Repository<ViewEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewEntity)
|
||||
private readonly viewRepository: WorkspaceScopedRepository<ViewEntity>,
|
||||
) {}
|
||||
|
||||
async upsertFieldsWidget({
|
||||
@@ -181,8 +182,8 @@ export class FieldsWidgetUpsertService {
|
||||
});
|
||||
}
|
||||
|
||||
const view = await this.viewRepository.findOne({
|
||||
where: { id: viewId, workspaceId, deletedAt: IsNull() },
|
||||
const view = await this.viewRepository.findOne(workspaceId, {
|
||||
where: { id: viewId, deletedAt: IsNull() },
|
||||
});
|
||||
|
||||
if (!isDefined(view)) {
|
||||
|
||||
@@ -9,6 +9,7 @@ import { ViewFieldGroupResolver } from 'src/engine/metadata-modules/view-field-g
|
||||
import { FieldsWidgetUpsertService } from 'src/engine/metadata-modules/view-field-group/services/fields-widget-upsert.service';
|
||||
import { ViewFieldGroupService } from 'src/engine/metadata-modules/view-field-group/services/view-field-group.service';
|
||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/workspace-cache-storage.module';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module';
|
||||
|
||||
@@ -25,6 +26,7 @@ import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace
|
||||
ViewFieldGroupResolver,
|
||||
ViewFieldGroupService,
|
||||
FieldsWidgetUpsertService,
|
||||
provideWorkspaceScopedRepository(ViewEntity),
|
||||
],
|
||||
exports: [ViewFieldGroupService],
|
||||
})
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import { Test, type TestingModule } from '@nestjs/testing';
|
||||
import { getRepositoryToken } from '@nestjs/typeorm';
|
||||
|
||||
import { type Repository } from 'typeorm';
|
||||
import { ViewFilterGroupLogicalOperator } from 'twenty-shared/types';
|
||||
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
|
||||
import { ViewFilterGroupEntity } from 'src/engine/metadata-modules/view-filter-group/entities/view-filter-group.entity';
|
||||
import { ViewFilterGroupService } from 'src/engine/metadata-modules/view-filter-group/services/view-filter-group.service';
|
||||
import { getWorkspaceScopedRepositoryToken } from 'src/engine/twenty-orm/workspace-scoped-repository/get-workspace-scoped-repository-token.util';
|
||||
import { type WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service';
|
||||
|
||||
describe('ViewFilterGroupService', () => {
|
||||
let viewFilterGroupService: ViewFilterGroupService;
|
||||
let viewFilterGroupRepository: Repository<ViewFilterGroupEntity>;
|
||||
let viewFilterGroupRepository: WorkspaceScopedRepository<ViewFilterGroupEntity>;
|
||||
|
||||
const mockViewFilterGroup = {
|
||||
id: 'view-filter-group-id',
|
||||
@@ -30,13 +30,11 @@ describe('ViewFilterGroupService', () => {
|
||||
providers: [
|
||||
ViewFilterGroupService,
|
||||
{
|
||||
provide: getRepositoryToken(ViewFilterGroupEntity),
|
||||
provide: getWorkspaceScopedRepositoryToken(ViewFilterGroupEntity),
|
||||
useValue: {
|
||||
find: jest.fn(),
|
||||
findOne: jest.fn(),
|
||||
create: jest.fn(),
|
||||
save: jest.fn(),
|
||||
softDelete: jest.fn(),
|
||||
delete: jest.fn(),
|
||||
},
|
||||
},
|
||||
@@ -65,9 +63,9 @@ describe('ViewFilterGroupService', () => {
|
||||
viewFilterGroupService = module.get<ViewFilterGroupService>(
|
||||
ViewFilterGroupService,
|
||||
);
|
||||
viewFilterGroupRepository = module.get<Repository<ViewFilterGroupEntity>>(
|
||||
getRepositoryToken(ViewFilterGroupEntity),
|
||||
);
|
||||
viewFilterGroupRepository = module.get<
|
||||
WorkspaceScopedRepository<ViewFilterGroupEntity>
|
||||
>(getWorkspaceScopedRepositoryToken(ViewFilterGroupEntity));
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
@@ -86,9 +84,8 @@ describe('ViewFilterGroupService', () => {
|
||||
const result =
|
||||
await viewFilterGroupService.findByWorkspaceId(workspaceId);
|
||||
|
||||
expect(viewFilterGroupRepository.find).toHaveBeenCalledWith({
|
||||
expect(viewFilterGroupRepository.find).toHaveBeenCalledWith(workspaceId, {
|
||||
where: {
|
||||
workspaceId,
|
||||
deletedAt: expect.anything(),
|
||||
},
|
||||
order: { positionInViewFilterGroup: 'ASC' },
|
||||
@@ -119,9 +116,8 @@ describe('ViewFilterGroupService', () => {
|
||||
viewId,
|
||||
);
|
||||
|
||||
expect(viewFilterGroupRepository.find).toHaveBeenCalledWith({
|
||||
expect(viewFilterGroupRepository.find).toHaveBeenCalledWith(workspaceId, {
|
||||
where: {
|
||||
workspaceId,
|
||||
viewId,
|
||||
deletedAt: expect.anything(),
|
||||
},
|
||||
@@ -149,20 +145,22 @@ describe('ViewFilterGroupService', () => {
|
||||
|
||||
const result = await viewFilterGroupService.findById(id, workspaceId);
|
||||
|
||||
expect(viewFilterGroupRepository.findOne).toHaveBeenCalledWith({
|
||||
where: {
|
||||
id,
|
||||
workspaceId,
|
||||
deletedAt: expect.anything(),
|
||||
expect(viewFilterGroupRepository.findOne).toHaveBeenCalledWith(
|
||||
workspaceId,
|
||||
{
|
||||
where: {
|
||||
id,
|
||||
deletedAt: expect.anything(),
|
||||
},
|
||||
relations: [
|
||||
'workspace',
|
||||
'view',
|
||||
'viewFilters',
|
||||
'parentViewFilterGroup',
|
||||
'childViewFilterGroups',
|
||||
],
|
||||
},
|
||||
relations: [
|
||||
'workspace',
|
||||
'view',
|
||||
'viewFilters',
|
||||
'parentViewFilterGroup',
|
||||
'childViewFilterGroups',
|
||||
],
|
||||
});
|
||||
);
|
||||
expect(result).toEqual(mockViewFilterGroup);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { IsNull, type Repository } from 'typeorm';
|
||||
import { IsNull } from 'typeorm';
|
||||
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
|
||||
@@ -18,14 +17,16 @@ import { type UpdateViewFilterGroupInput } from 'src/engine/metadata-modules/vie
|
||||
import { type ViewFilterGroupDTO } from 'src/engine/metadata-modules/view-filter-group/dtos/view-filter-group.dto';
|
||||
import { ViewFilterGroupEntity } from 'src/engine/metadata-modules/view-filter-group/entities/view-filter-group.entity';
|
||||
import { fromFlatViewFilterGroupToViewFilterGroupDto } from 'src/engine/metadata-modules/view-filter-group/utils/from-flat-view-filter-group-to-view-filter-group-dto.util';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service';
|
||||
|
||||
@Injectable()
|
||||
export class ViewFilterGroupService {
|
||||
constructor(
|
||||
@InjectRepository(ViewFilterGroupEntity)
|
||||
private readonly viewFilterGroupRepository: Repository<ViewFilterGroupEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewFilterGroupEntity)
|
||||
private readonly viewFilterGroupRepository: WorkspaceScopedRepository<ViewFilterGroupEntity>,
|
||||
private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService,
|
||||
private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
|
||||
private readonly applicationService: ApplicationService,
|
||||
@@ -320,9 +321,8 @@ export class ViewFilterGroupService {
|
||||
async findByWorkspaceId(
|
||||
workspaceId: string,
|
||||
): Promise<ViewFilterGroupEntity[]> {
|
||||
return this.viewFilterGroupRepository.find({
|
||||
return this.viewFilterGroupRepository.find(workspaceId, {
|
||||
where: {
|
||||
workspaceId,
|
||||
deletedAt: IsNull(),
|
||||
},
|
||||
order: { positionInViewFilterGroup: 'ASC' },
|
||||
@@ -340,9 +340,8 @@ export class ViewFilterGroupService {
|
||||
workspaceId: string,
|
||||
viewId: string,
|
||||
): Promise<ViewFilterGroupEntity[]> {
|
||||
return this.viewFilterGroupRepository.find({
|
||||
return this.viewFilterGroupRepository.find(workspaceId, {
|
||||
where: {
|
||||
workspaceId,
|
||||
viewId,
|
||||
deletedAt: IsNull(),
|
||||
},
|
||||
@@ -361,20 +360,22 @@ export class ViewFilterGroupService {
|
||||
id: string,
|
||||
workspaceId: string,
|
||||
): Promise<ViewFilterGroupEntity | null> {
|
||||
const viewFilterGroup = await this.viewFilterGroupRepository.findOne({
|
||||
where: {
|
||||
id,
|
||||
workspaceId,
|
||||
deletedAt: IsNull(),
|
||||
const viewFilterGroup = await this.viewFilterGroupRepository.findOne(
|
||||
workspaceId,
|
||||
{
|
||||
where: {
|
||||
id,
|
||||
deletedAt: IsNull(),
|
||||
},
|
||||
relations: [
|
||||
'workspace',
|
||||
'view',
|
||||
'viewFilters',
|
||||
'parentViewFilterGroup',
|
||||
'childViewFilterGroups',
|
||||
],
|
||||
},
|
||||
relations: [
|
||||
'workspace',
|
||||
'view',
|
||||
'viewFilters',
|
||||
'parentViewFilterGroup',
|
||||
'childViewFilterGroups',
|
||||
],
|
||||
});
|
||||
);
|
||||
|
||||
return viewFilterGroup || null;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import { ViewFilterGroupResolver } from 'src/engine/metadata-modules/view-filter
|
||||
import { ViewFilterGroupService } from 'src/engine/metadata-modules/view-filter-group/services/view-filter-group.service';
|
||||
import { ViewPermissionsModule } from 'src/engine/metadata-modules/view-permissions/view-permissions.module';
|
||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/workspace-cache-storage.module';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module';
|
||||
|
||||
@@ -24,7 +25,11 @@ import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace
|
||||
ViewPermissionsModule,
|
||||
],
|
||||
controllers: [ViewFilterGroupController],
|
||||
providers: [ViewFilterGroupService, ViewFilterGroupResolver],
|
||||
providers: [
|
||||
ViewFilterGroupService,
|
||||
ViewFilterGroupResolver,
|
||||
provideWorkspaceScopedRepository(ViewFilterGroupEntity),
|
||||
],
|
||||
exports: [ViewFilterGroupService],
|
||||
})
|
||||
export class ViewFilterGroupModule {}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { IsNull, Repository } from 'typeorm';
|
||||
import { IsNull } from 'typeorm';
|
||||
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
|
||||
@@ -18,14 +17,16 @@ import { UpdateViewFilterInput } from 'src/engine/metadata-modules/view-filter/d
|
||||
import { ViewFilterDTO } from 'src/engine/metadata-modules/view-filter/dtos/view-filter.dto';
|
||||
import { ViewFilterEntity } from 'src/engine/metadata-modules/view-filter/entities/view-filter.entity';
|
||||
import { fromFlatViewFilterToViewFilterDto } from 'src/engine/metadata-modules/view-filter/utils/from-flat-view-filter-to-view-filter-dto.util';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service';
|
||||
|
||||
@Injectable()
|
||||
export class ViewFilterService {
|
||||
constructor(
|
||||
@InjectRepository(ViewFilterEntity)
|
||||
private readonly viewFilterRepository: Repository<ViewFilterEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewFilterEntity)
|
||||
private readonly viewFilterRepository: WorkspaceScopedRepository<ViewFilterEntity>,
|
||||
private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService,
|
||||
private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
|
||||
private readonly applicationService: ApplicationService,
|
||||
@@ -319,9 +320,8 @@ export class ViewFilterService {
|
||||
}
|
||||
|
||||
async findByWorkspaceId(workspaceId: string): Promise<ViewFilterEntity[]> {
|
||||
return this.viewFilterRepository.find({
|
||||
return this.viewFilterRepository.find(workspaceId, {
|
||||
where: {
|
||||
workspaceId,
|
||||
deletedAt: IsNull(),
|
||||
},
|
||||
order: { positionInViewFilterGroup: 'ASC' },
|
||||
@@ -333,9 +333,8 @@ export class ViewFilterService {
|
||||
workspaceId: string,
|
||||
viewId: string,
|
||||
): Promise<ViewFilterEntity[]> {
|
||||
return this.viewFilterRepository.find({
|
||||
return this.viewFilterRepository.find(workspaceId, {
|
||||
where: {
|
||||
workspaceId,
|
||||
viewId,
|
||||
deletedAt: IsNull(),
|
||||
},
|
||||
@@ -348,10 +347,9 @@ export class ViewFilterService {
|
||||
id: string,
|
||||
workspaceId: string,
|
||||
): Promise<ViewFilterEntity | null> {
|
||||
const viewFilter = await this.viewFilterRepository.findOne({
|
||||
const viewFilter = await this.viewFilterRepository.findOne(workspaceId, {
|
||||
where: {
|
||||
id,
|
||||
workspaceId,
|
||||
deletedAt: IsNull(),
|
||||
},
|
||||
relations: ['workspace', 'view', 'viewFilterGroup'],
|
||||
|
||||
@@ -11,6 +11,7 @@ import { ViewFilterService } from 'src/engine/metadata-modules/view-filter/servi
|
||||
import { ViewFilterToolsFactory } from 'src/engine/metadata-modules/view-filter/tools/view-filter-tools.factory';
|
||||
import { ViewPermissionsModule } from 'src/engine/metadata-modules/view-permissions/view-permissions.module';
|
||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/workspace-cache-storage.module';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module';
|
||||
|
||||
@@ -25,7 +26,12 @@ import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace
|
||||
ViewPermissionsModule,
|
||||
],
|
||||
controllers: [ViewFilterController],
|
||||
providers: [ViewFilterService, ViewFilterResolver, ViewFilterToolsFactory],
|
||||
providers: [
|
||||
ViewFilterService,
|
||||
ViewFilterResolver,
|
||||
ViewFilterToolsFactory,
|
||||
provideWorkspaceScopedRepository(ViewFilterEntity),
|
||||
],
|
||||
exports: [ViewFilterService, ViewFilterToolsFactory],
|
||||
})
|
||||
export class ViewFilterModule {}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IsNull, Repository } from 'typeorm';
|
||||
import { IsNull } from 'typeorm';
|
||||
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
|
||||
@@ -25,14 +24,16 @@ import {
|
||||
ViewGroupExceptionCode,
|
||||
} from 'src/engine/metadata-modules/view-group/exceptions/view-group.exception';
|
||||
import { fromFlatViewGroupToViewGroupDto } from 'src/engine/metadata-modules/view-group/utils/from-flat-view-group-to-view-group-dto.util';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service';
|
||||
|
||||
@Injectable()
|
||||
export class ViewGroupService {
|
||||
constructor(
|
||||
@InjectRepository(ViewGroupEntity)
|
||||
private readonly viewGroupRepository: Repository<ViewGroupEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewGroupEntity)
|
||||
private readonly viewGroupRepository: WorkspaceScopedRepository<ViewGroupEntity>,
|
||||
private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService,
|
||||
private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
|
||||
private readonly applicationService: ApplicationService,
|
||||
@@ -379,9 +380,8 @@ export class ViewGroupService {
|
||||
}
|
||||
|
||||
async findByWorkspaceId(workspaceId: string): Promise<ViewGroupEntity[]> {
|
||||
return this.viewGroupRepository.find({
|
||||
return this.viewGroupRepository.find(workspaceId, {
|
||||
where: {
|
||||
workspaceId,
|
||||
deletedAt: IsNull(),
|
||||
},
|
||||
order: { position: 'ASC' },
|
||||
@@ -393,9 +393,8 @@ export class ViewGroupService {
|
||||
workspaceId: string,
|
||||
viewId: string,
|
||||
): Promise<ViewGroupEntity[]> {
|
||||
return this.viewGroupRepository.find({
|
||||
return this.viewGroupRepository.find(workspaceId, {
|
||||
where: {
|
||||
workspaceId,
|
||||
viewId,
|
||||
deletedAt: IsNull(),
|
||||
},
|
||||
@@ -408,10 +407,9 @@ export class ViewGroupService {
|
||||
id: string,
|
||||
workspaceId: string,
|
||||
): Promise<ViewGroupEntity | null> {
|
||||
const viewGroup = await this.viewGroupRepository.findOne({
|
||||
const viewGroup = await this.viewGroupRepository.findOne(workspaceId, {
|
||||
where: {
|
||||
id,
|
||||
workspaceId,
|
||||
deletedAt: IsNull(),
|
||||
},
|
||||
relations: ['workspace', 'view'],
|
||||
|
||||
@@ -12,6 +12,7 @@ import { ViewGroupResolver } from 'src/engine/metadata-modules/view-group/resolv
|
||||
import { ViewGroupService } from 'src/engine/metadata-modules/view-group/services/view-group.service';
|
||||
import { ViewPermissionsModule } from 'src/engine/metadata-modules/view-permissions/view-permissions.module';
|
||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/workspace-cache-storage.module';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module';
|
||||
|
||||
@@ -28,7 +29,11 @@ import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace
|
||||
ViewPermissionsModule,
|
||||
],
|
||||
controllers: [ViewGroupController],
|
||||
providers: [ViewGroupService, ViewGroupResolver],
|
||||
providers: [
|
||||
ViewGroupService,
|
||||
ViewGroupResolver,
|
||||
provideWorkspaceScopedRepository(ViewGroupEntity),
|
||||
],
|
||||
exports: [ViewGroupService],
|
||||
})
|
||||
export class ViewGroupModule {}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { ViewFieldEntity } from 'src/engine/metadata-modules/view-field/entities/view-field.entity';
|
||||
import { ViewFilterGroupEntity } from 'src/engine/metadata-modules/view-filter-group/entities/view-filter-group.entity';
|
||||
@@ -9,20 +6,22 @@ import { ViewFilterEntity } from 'src/engine/metadata-modules/view-filter/entiti
|
||||
import { ViewGroupEntity } from 'src/engine/metadata-modules/view-group/entities/view-group.entity';
|
||||
import { type ViewChildEntityKind } from 'src/engine/metadata-modules/view-permissions/types/view-permissions.types';
|
||||
import { ViewSortEntity } from 'src/engine/metadata-modules/view-sort/entities/view-sort.entity';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
|
||||
@Injectable()
|
||||
export class ViewEntityLookupService {
|
||||
constructor(
|
||||
@InjectRepository(ViewFieldEntity)
|
||||
private readonly viewFieldRepository: Repository<ViewFieldEntity>,
|
||||
@InjectRepository(ViewFilterEntity)
|
||||
private readonly viewFilterRepository: Repository<ViewFilterEntity>,
|
||||
@InjectRepository(ViewFilterGroupEntity)
|
||||
private readonly viewFilterGroupRepository: Repository<ViewFilterGroupEntity>,
|
||||
@InjectRepository(ViewGroupEntity)
|
||||
private readonly viewGroupRepository: Repository<ViewGroupEntity>,
|
||||
@InjectRepository(ViewSortEntity)
|
||||
private readonly viewSortRepository: Repository<ViewSortEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewFieldEntity)
|
||||
private readonly viewFieldRepository: WorkspaceScopedRepository<ViewFieldEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewFilterEntity)
|
||||
private readonly viewFilterRepository: WorkspaceScopedRepository<ViewFilterEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewFilterGroupEntity)
|
||||
private readonly viewFilterGroupRepository: WorkspaceScopedRepository<ViewFilterGroupEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewGroupEntity)
|
||||
private readonly viewGroupRepository: WorkspaceScopedRepository<ViewGroupEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewSortEntity)
|
||||
private readonly viewSortRepository: WorkspaceScopedRepository<ViewSortEntity>,
|
||||
) {}
|
||||
|
||||
async findViewIdByEntityIdAndKind(
|
||||
@@ -32,8 +31,8 @@ export class ViewEntityLookupService {
|
||||
): Promise<string | null> {
|
||||
switch (kind) {
|
||||
case 'viewField': {
|
||||
const row = await this.viewFieldRepository.findOne({
|
||||
where: { id: entityId, workspaceId },
|
||||
const row = await this.viewFieldRepository.findOne(workspaceId, {
|
||||
where: { id: entityId },
|
||||
select: ['viewId'],
|
||||
});
|
||||
|
||||
@@ -42,8 +41,8 @@ export class ViewEntityLookupService {
|
||||
}
|
||||
|
||||
case 'viewFilter': {
|
||||
const row = await this.viewFilterRepository.findOne({
|
||||
where: { id: entityId, workspaceId },
|
||||
const row = await this.viewFilterRepository.findOne(workspaceId, {
|
||||
where: { id: entityId },
|
||||
select: ['viewId'],
|
||||
});
|
||||
|
||||
@@ -52,8 +51,8 @@ export class ViewEntityLookupService {
|
||||
}
|
||||
|
||||
case 'viewFilterGroup': {
|
||||
const row = await this.viewFilterGroupRepository.findOne({
|
||||
where: { id: entityId, workspaceId },
|
||||
const row = await this.viewFilterGroupRepository.findOne(workspaceId, {
|
||||
where: { id: entityId },
|
||||
select: ['viewId'],
|
||||
});
|
||||
|
||||
@@ -62,8 +61,8 @@ export class ViewEntityLookupService {
|
||||
}
|
||||
|
||||
case 'viewGroup': {
|
||||
const row = await this.viewGroupRepository.findOne({
|
||||
where: { id: entityId, workspaceId },
|
||||
const row = await this.viewGroupRepository.findOne(workspaceId, {
|
||||
where: { id: entityId },
|
||||
select: ['viewId'],
|
||||
});
|
||||
|
||||
@@ -72,8 +71,8 @@ export class ViewEntityLookupService {
|
||||
}
|
||||
|
||||
case 'viewSort': {
|
||||
const row = await this.viewSortRepository.findOne({
|
||||
where: { id: entityId, workspaceId },
|
||||
const row = await this.viewSortRepository.findOne(workspaceId, {
|
||||
where: { id: entityId },
|
||||
select: ['viewId'],
|
||||
});
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ import { ViewEntityLookupService } from 'src/engine/metadata-modules/view-permis
|
||||
import { ViewSortEntity } from 'src/engine/metadata-modules/view-sort/entities/view-sort.entity';
|
||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||
import { ViewService } from 'src/engine/metadata-modules/view/services/view.service';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/workspace-cache-storage.module';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module';
|
||||
|
||||
@@ -86,6 +87,12 @@ import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace
|
||||
UpdateViewSortPermissionGuard,
|
||||
DeleteViewSortPermissionGuard,
|
||||
DestroyViewSortPermissionGuard,
|
||||
provideWorkspaceScopedRepository(ViewEntity),
|
||||
provideWorkspaceScopedRepository(ViewFieldEntity),
|
||||
provideWorkspaceScopedRepository(ViewFilterEntity),
|
||||
provideWorkspaceScopedRepository(ViewFilterGroupEntity),
|
||||
provideWorkspaceScopedRepository(ViewGroupEntity),
|
||||
provideWorkspaceScopedRepository(ViewSortEntity),
|
||||
],
|
||||
exports: [
|
||||
ViewService,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { IsNull, Repository } from 'typeorm';
|
||||
import { IsNull } from 'typeorm';
|
||||
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
|
||||
@@ -18,14 +17,16 @@ import { UpdateViewSortInput } from 'src/engine/metadata-modules/view-sort/dtos/
|
||||
import { ViewSortDTO } from 'src/engine/metadata-modules/view-sort/dtos/view-sort.dto';
|
||||
import { ViewSortEntity } from 'src/engine/metadata-modules/view-sort/entities/view-sort.entity';
|
||||
import { fromFlatViewSortToViewSortDto } from 'src/engine/metadata-modules/view-sort/utils/from-flat-view-sort-to-view-sort-dto.util';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service';
|
||||
|
||||
@Injectable()
|
||||
export class ViewSortService {
|
||||
constructor(
|
||||
@InjectRepository(ViewSortEntity)
|
||||
private readonly viewSortRepository: Repository<ViewSortEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewSortEntity)
|
||||
private readonly viewSortRepository: WorkspaceScopedRepository<ViewSortEntity>,
|
||||
private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService,
|
||||
private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
|
||||
private readonly applicationService: ApplicationService,
|
||||
@@ -301,9 +302,8 @@ export class ViewSortService {
|
||||
}
|
||||
|
||||
async findByWorkspaceId(workspaceId: string): Promise<ViewSortEntity[]> {
|
||||
return this.viewSortRepository.find({
|
||||
return this.viewSortRepository.find(workspaceId, {
|
||||
where: {
|
||||
workspaceId,
|
||||
deletedAt: IsNull(),
|
||||
},
|
||||
relations: ['workspace', 'view'],
|
||||
@@ -314,9 +314,8 @@ export class ViewSortService {
|
||||
workspaceId: string,
|
||||
viewId: string,
|
||||
): Promise<ViewSortEntity[]> {
|
||||
return this.viewSortRepository.find({
|
||||
return this.viewSortRepository.find(workspaceId, {
|
||||
where: {
|
||||
workspaceId,
|
||||
viewId,
|
||||
deletedAt: IsNull(),
|
||||
},
|
||||
@@ -328,10 +327,9 @@ export class ViewSortService {
|
||||
id: string,
|
||||
workspaceId: string,
|
||||
): Promise<ViewSortEntity | null> {
|
||||
const viewSort = await this.viewSortRepository.findOne({
|
||||
const viewSort = await this.viewSortRepository.findOne(workspaceId, {
|
||||
where: {
|
||||
id,
|
||||
workspaceId,
|
||||
deletedAt: IsNull(),
|
||||
},
|
||||
relations: ['workspace', 'view'],
|
||||
|
||||
@@ -10,6 +10,7 @@ import { ViewSortResolver } from 'src/engine/metadata-modules/view-sort/resolver
|
||||
import { ViewSortService } from 'src/engine/metadata-modules/view-sort/services/view-sort.service';
|
||||
import { ViewSortToolsFactory } from 'src/engine/metadata-modules/view-sort/tools/view-sort-tools.factory';
|
||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/workspace-cache-storage.module';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module';
|
||||
@@ -25,7 +26,12 @@ import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata
|
||||
ViewPermissionsModule,
|
||||
],
|
||||
controllers: [ViewSortController],
|
||||
providers: [ViewSortService, ViewSortResolver, ViewSortToolsFactory],
|
||||
providers: [
|
||||
ViewSortService,
|
||||
ViewSortResolver,
|
||||
ViewSortToolsFactory,
|
||||
provideWorkspaceScopedRepository(ViewSortEntity),
|
||||
],
|
||||
exports: [ViewSortService, ViewSortToolsFactory],
|
||||
})
|
||||
export class ViewSortModule {}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { t } from '@lingui/core/macro';
|
||||
import {
|
||||
@@ -8,7 +7,7 @@ import {
|
||||
ViewSortDirection,
|
||||
} from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IsNull, Repository } from 'typeorm';
|
||||
import { IsNull } from 'typeorm';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
@@ -43,6 +42,8 @@ import {
|
||||
ViewException,
|
||||
ViewExceptionCode,
|
||||
} from 'src/engine/metadata-modules/view/exceptions/view.exception';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service';
|
||||
|
||||
@@ -75,8 +76,8 @@ export class ViewWidgetUpsertService {
|
||||
private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService,
|
||||
private readonly workspaceManyOrAllFlatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
|
||||
private readonly applicationService: ApplicationService,
|
||||
@InjectRepository(ViewEntity)
|
||||
private readonly viewRepository: Repository<ViewEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewEntity)
|
||||
private readonly viewRepository: WorkspaceScopedRepository<ViewEntity>,
|
||||
) {}
|
||||
|
||||
async upsertViewWidget({
|
||||
@@ -186,13 +187,15 @@ export class ViewWidgetUpsertService {
|
||||
!isDefined(input.viewFilters) &&
|
||||
!isDefined(input.viewSorts)
|
||||
) {
|
||||
const view = await this.viewRepository.findOne({
|
||||
where: {
|
||||
id: upsertContext.viewId,
|
||||
workspaceId: upsertContext.workspaceId,
|
||||
deletedAt: IsNull(),
|
||||
const view = await this.viewRepository.findOne(
|
||||
upsertContext.workspaceId,
|
||||
{
|
||||
where: {
|
||||
id: upsertContext.viewId,
|
||||
deletedAt: IsNull(),
|
||||
},
|
||||
},
|
||||
});
|
||||
);
|
||||
|
||||
if (!isDefined(view)) {
|
||||
throw new ViewException(
|
||||
@@ -354,10 +357,9 @@ export class ViewWidgetUpsertService {
|
||||
);
|
||||
}
|
||||
|
||||
const view = await this.viewRepository.findOne({
|
||||
const view = await this.viewRepository.findOne(upsertContext.workspaceId, {
|
||||
where: {
|
||||
id: upsertContext.viewId,
|
||||
workspaceId: upsertContext.workspaceId,
|
||||
deletedAt: IsNull(),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { APP_LOCALES, SOURCE_LOCALE } from 'twenty-shared/translations';
|
||||
import { ViewType, ViewVisibility } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { I18nService } from 'src/engine/core-modules/i18n/i18n.service';
|
||||
@@ -32,14 +30,16 @@ import { UpdateViewInput } from 'src/engine/metadata-modules/view/dtos/inputs/up
|
||||
import { ViewDTO } from 'src/engine/metadata-modules/view/dtos/view.dto';
|
||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||
import { fromFlatViewToViewDto } from 'src/engine/metadata-modules/view/utils/from-flat-view-to-view-dto.util';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service';
|
||||
|
||||
@Injectable()
|
||||
export class ViewService {
|
||||
constructor(
|
||||
@InjectRepository(ViewEntity)
|
||||
private readonly viewRepository: Repository<ViewEntity>,
|
||||
@InjectWorkspaceScopedRepository(ViewEntity)
|
||||
private readonly viewRepository: WorkspaceScopedRepository<ViewEntity>,
|
||||
private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService,
|
||||
private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
|
||||
private readonly applicationService: ApplicationService,
|
||||
@@ -625,10 +625,9 @@ export class ViewService {
|
||||
id: string,
|
||||
workspaceId: string,
|
||||
): Promise<ViewEntity | null> {
|
||||
const view = await this.viewRepository.findOne({
|
||||
const view = await this.viewRepository.findOne(workspaceId, {
|
||||
where: {
|
||||
id,
|
||||
workspaceId,
|
||||
},
|
||||
relations: [
|
||||
'workspace',
|
||||
|
||||
@@ -19,6 +19,7 @@ import { ViewResolver } from 'src/engine/metadata-modules/view/resolvers/view.re
|
||||
import { ViewQueryParamsService } from 'src/engine/metadata-modules/view/services/view-query-params.service';
|
||||
import { ViewService } from 'src/engine/metadata-modules/view/services/view.service';
|
||||
import { ViewToolsFactory } from 'src/engine/metadata-modules/view/tools/view-tools.factory';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/workspace-cache-storage.module';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module';
|
||||
|
||||
@@ -46,6 +47,7 @@ import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace
|
||||
ViewQueryParamsService,
|
||||
ViewToolsFactory,
|
||||
ViewWidgetUpsertService,
|
||||
provideWorkspaceScopedRepository(ViewEntity),
|
||||
],
|
||||
exports: [
|
||||
ViewService,
|
||||
|
||||
@@ -13,6 +13,7 @@ import { WebhookGraphqlApiExceptionInterceptor } from 'src/engine/metadata-modul
|
||||
import { WebhookToolWorkspaceService } from 'src/engine/metadata-modules/webhook/tools/services/webhook-tool.workspace-service';
|
||||
import { WebhookResolver } from 'src/engine/metadata-modules/webhook/webhook.resolver';
|
||||
import { WebhookService } from 'src/engine/metadata-modules/webhook/webhook.service';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/workspace-cache-storage.module';
|
||||
import { WorkspaceMigrationGraphqlApiExceptionInterceptor } from 'src/engine/workspace-manager/workspace-migration/interceptors/workspace-migration-graphql-api-exception.interceptor';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module';
|
||||
@@ -35,6 +36,7 @@ import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace
|
||||
WebhookGraphqlApiExceptionInterceptor,
|
||||
WorkspaceMigrationGraphqlApiExceptionInterceptor,
|
||||
WebhookToolWorkspaceService,
|
||||
provideWorkspaceScopedRepository(WebhookEntity),
|
||||
],
|
||||
exports: [WebhookService, WebhookToolWorkspaceService],
|
||||
})
|
||||
|
||||
@@ -13,6 +13,8 @@ import { fromDeleteWebhookInputToFlatWebhookOrThrow } from 'src/engine/metadata-
|
||||
import { fromFlatWebhookToWebhookDto } from 'src/engine/metadata-modules/flat-webhook/utils/from-flat-webhook-to-webhook-dto.util';
|
||||
import { fromUpdateWebhookInputToFlatWebhookToUpdateOrThrow } from 'src/engine/metadata-modules/flat-webhook/utils/from-update-webhook-input-to-flat-webhook-to-update-or-throw.util';
|
||||
import { fromWebhookEntityToFlatWebhook } from 'src/engine/metadata-modules/flat-webhook/utils/from-webhook-entity-to-flat-webhook.util';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { type CreateWebhookInput } from 'src/engine/metadata-modules/webhook/dtos/create-webhook.input';
|
||||
import { type UpdateWebhookInput } from 'src/engine/metadata-modules/webhook/dtos/update-webhook.input';
|
||||
import { type WebhookDTO } from 'src/engine/metadata-modules/webhook/dtos/webhook.dto';
|
||||
@@ -24,8 +26,8 @@ import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspa
|
||||
@Injectable()
|
||||
export class WebhookService {
|
||||
constructor(
|
||||
@InjectRepository(WebhookEntity)
|
||||
private readonly webhookRepository: Repository<WebhookEntity>,
|
||||
@InjectWorkspaceScopedRepository(WebhookEntity)
|
||||
private readonly webhookRepository: WorkspaceScopedRepository<WebhookEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService,
|
||||
@@ -45,8 +47,8 @@ export class WebhookService {
|
||||
|
||||
async findAll(workspaceId: string): Promise<WebhookDTO[]> {
|
||||
const [webhooks, applications] = await Promise.all([
|
||||
this.webhookRepository.find({
|
||||
where: { workspaceId, deletedAt: IsNull() },
|
||||
this.webhookRepository.find(workspaceId, {
|
||||
where: { deletedAt: IsNull() },
|
||||
order: { createdAt: 'ASC' },
|
||||
}),
|
||||
this.applicationRepository.find({
|
||||
@@ -70,8 +72,8 @@ export class WebhookService {
|
||||
|
||||
async findById(id: string, workspaceId: string): Promise<WebhookDTO | null> {
|
||||
const [webhook, applications] = await Promise.all([
|
||||
this.webhookRepository.findOne({
|
||||
where: { id, workspaceId, deletedAt: IsNull() },
|
||||
this.webhookRepository.findOne(workspaceId, {
|
||||
where: { id, deletedAt: IsNull() },
|
||||
}),
|
||||
this.applicationRepository.find({
|
||||
where: { workspaceId },
|
||||
|
||||
@@ -15,9 +15,16 @@ const createMockRepository = (): jest.Mocked<Repository<FakeEntity>> =>
|
||||
({
|
||||
findOne: jest.fn().mockResolvedValue(null),
|
||||
findOneOrFail: jest.fn(),
|
||||
findOneBy: jest.fn().mockResolvedValue(null),
|
||||
find: jest.fn().mockResolvedValue([]),
|
||||
count: jest.fn().mockResolvedValue(0),
|
||||
findAndCount: jest.fn().mockResolvedValue([[], 0]),
|
||||
exists: jest.fn().mockResolvedValue(false),
|
||||
existsBy: jest.fn().mockResolvedValue(false),
|
||||
maximum: jest.fn().mockResolvedValue(null),
|
||||
update: jest.fn(),
|
||||
increment: jest.fn(),
|
||||
decrement: jest.fn(),
|
||||
delete: jest.fn(),
|
||||
softDelete: jest.fn(),
|
||||
insert: jest.fn(),
|
||||
@@ -45,15 +52,22 @@ describe('WorkspaceScopedRepository', () => {
|
||||
'findOneOrFail',
|
||||
() => scoped.findOneOrFail(undefined as never, { where: {} }),
|
||||
],
|
||||
['findOneBy', () => scoped.findOneBy(undefined as never, {})],
|
||||
['find', () => scoped.find(undefined as never)],
|
||||
['count', () => scoped.count(undefined as never)],
|
||||
['findAndCount', () => scoped.findAndCount(undefined as never)],
|
||||
['exists', () => scoped.exists(undefined as never)],
|
||||
['existsBy', () => scoped.existsBy(undefined as never, {})],
|
||||
['update', () => scoped.update(undefined as never, {}, {})],
|
||||
['increment', () => scoped.increment(undefined as never, {}, 'count', 1)],
|
||||
['decrement', () => scoped.decrement(undefined as never, {}, 'count', 1)],
|
||||
['delete', () => scoped.delete(undefined as never, {})],
|
||||
['softDelete', () => scoped.softDelete(undefined as never, {})],
|
||||
['insert', () => scoped.insert(undefined as never, {})],
|
||||
['upsert', () => scoped.upsert(undefined as never, {}, ['id'])],
|
||||
['save', () => scoped.save(undefined as never, {})],
|
||||
['saveMany', () => scoped.saveMany(undefined as never, [{}])],
|
||||
['maximum', () => scoped.maximum(undefined as never, 'id')],
|
||||
])('%s throws when workspaceId is undefined', (_name, call) => {
|
||||
expect(call).toThrow(/workspaceId must be a non-empty string/);
|
||||
});
|
||||
@@ -136,6 +150,28 @@ describe('WorkspaceScopedRepository', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('findOneBy', () => {
|
||||
it('merges workspaceId into where', async () => {
|
||||
await scoped.findOneBy(WORKSPACE_ID, { id: 'a' });
|
||||
|
||||
expect(repository.findOneBy).toHaveBeenCalledWith({
|
||||
id: 'a',
|
||||
workspaceId: WORKSPACE_ID,
|
||||
});
|
||||
});
|
||||
|
||||
it('throws if the caller includes workspaceId in where', () => {
|
||||
expect(() =>
|
||||
scoped.findOneBy(WORKSPACE_ID, {
|
||||
id: 'a',
|
||||
workspaceId: OTHER_WORKSPACE_ID,
|
||||
} as never),
|
||||
).toThrow(/do not include `workspaceId`/);
|
||||
|
||||
expect(repository.findOneBy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('find', () => {
|
||||
it('adds workspaceId when no where is provided', async () => {
|
||||
await scoped.find(WORKSPACE_ID);
|
||||
@@ -154,6 +190,53 @@ describe('WorkspaceScopedRepository', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('findAndCount', () => {
|
||||
it('merges workspaceId into where', async () => {
|
||||
await scoped.findAndCount(WORKSPACE_ID, { where: { status: 'queued' } });
|
||||
|
||||
expect(repository.findAndCount).toHaveBeenCalledWith({
|
||||
where: { status: 'queued', workspaceId: WORKSPACE_ID },
|
||||
});
|
||||
});
|
||||
|
||||
it('works without options', async () => {
|
||||
await scoped.findAndCount(WORKSPACE_ID);
|
||||
|
||||
expect(repository.findAndCount).toHaveBeenCalledWith({
|
||||
where: { workspaceId: WORKSPACE_ID },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('exists', () => {
|
||||
it('merges workspaceId into where', async () => {
|
||||
await scoped.exists(WORKSPACE_ID, { where: { status: 'queued' } });
|
||||
|
||||
expect(repository.exists).toHaveBeenCalledWith({
|
||||
where: { status: 'queued', workspaceId: WORKSPACE_ID },
|
||||
});
|
||||
});
|
||||
|
||||
it('works without options', async () => {
|
||||
await scoped.exists(WORKSPACE_ID);
|
||||
|
||||
expect(repository.exists).toHaveBeenCalledWith({
|
||||
where: { workspaceId: WORKSPACE_ID },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('existsBy', () => {
|
||||
it('merges workspaceId into where', async () => {
|
||||
await scoped.existsBy(WORKSPACE_ID, { id: 'a' });
|
||||
|
||||
expect(repository.existsBy).toHaveBeenCalledWith({
|
||||
id: 'a',
|
||||
workspaceId: WORKSPACE_ID,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('update', () => {
|
||||
it('merges workspaceId into the criteria, not the patch', async () => {
|
||||
await scoped.update(WORKSPACE_ID, { id: 'a' }, { status: 'completed' });
|
||||
@@ -177,6 +260,41 @@ describe('WorkspaceScopedRepository', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('increment and decrement', () => {
|
||||
it('increment merges workspaceId into criteria', async () => {
|
||||
await scoped.increment(WORKSPACE_ID, { id: 'a' }, 'count', 1);
|
||||
|
||||
expect(repository.increment).toHaveBeenCalledWith(
|
||||
{ id: 'a', workspaceId: WORKSPACE_ID },
|
||||
'count',
|
||||
1,
|
||||
);
|
||||
});
|
||||
|
||||
it('increment throws if the caller includes workspaceId in the criteria', () => {
|
||||
expect(() =>
|
||||
scoped.increment(
|
||||
WORKSPACE_ID,
|
||||
{ id: 'a', workspaceId: OTHER_WORKSPACE_ID } as never,
|
||||
'count',
|
||||
1,
|
||||
),
|
||||
).toThrow(/do not include `workspaceId`/);
|
||||
|
||||
expect(repository.increment).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('decrement merges workspaceId into criteria', async () => {
|
||||
await scoped.decrement(WORKSPACE_ID, { id: 'a' }, 'count', 1);
|
||||
|
||||
expect(repository.decrement).toHaveBeenCalledWith(
|
||||
{ id: 'a', workspaceId: WORKSPACE_ID },
|
||||
'count',
|
||||
1,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('delete and softDelete', () => {
|
||||
it('delete merges workspaceId into criteria', async () => {
|
||||
await scoped.delete(WORKSPACE_ID, { id: 'a' });
|
||||
@@ -319,6 +437,25 @@ describe('WorkspaceScopedRepository', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('maximum', () => {
|
||||
it('calls with scoped criteria when where is provided', async () => {
|
||||
await scoped.maximum(WORKSPACE_ID, 'id', { status: 'queued' });
|
||||
|
||||
expect(repository.maximum).toHaveBeenCalledWith('id', {
|
||||
status: 'queued',
|
||||
workspaceId: WORKSPACE_ID,
|
||||
});
|
||||
});
|
||||
|
||||
it('calls with only workspaceId when no where is given', async () => {
|
||||
await scoped.maximum(WORKSPACE_ID, 'id');
|
||||
|
||||
expect(repository.maximum).toHaveBeenCalledWith('id', {
|
||||
workspaceId: WORKSPACE_ID,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('createQueryBuilder', () => {
|
||||
it('returns the underlying QueryBuilder unchanged (escape hatch)', () => {
|
||||
scoped.createQueryBuilder('t');
|
||||
|
||||
@@ -39,6 +39,17 @@ export class WorkspaceScopedRepository<T extends WorkspaceScopedEntity> {
|
||||
});
|
||||
}
|
||||
|
||||
findOneBy(
|
||||
workspaceId: string,
|
||||
where: FindOptionsWhere<T>,
|
||||
): Promise<T | null> {
|
||||
this.assertWorkspaceId(workspaceId);
|
||||
|
||||
return this.repository.findOneBy(
|
||||
this.mergeWorkspaceIdIntoCriteria(workspaceId, where),
|
||||
);
|
||||
}
|
||||
|
||||
find(workspaceId: string, options?: FindManyOptions<T>): Promise<T[]> {
|
||||
this.assertWorkspaceId(workspaceId);
|
||||
|
||||
@@ -57,6 +68,51 @@ export class WorkspaceScopedRepository<T extends WorkspaceScopedEntity> {
|
||||
});
|
||||
}
|
||||
|
||||
findAndCount(
|
||||
workspaceId: string,
|
||||
options?: FindManyOptions<T>,
|
||||
): Promise<[T[], number]> {
|
||||
this.assertWorkspaceId(workspaceId);
|
||||
|
||||
return this.repository.findAndCount({
|
||||
...options,
|
||||
where: this.mergeWorkspaceIdIntoWhere(workspaceId, options?.where),
|
||||
});
|
||||
}
|
||||
|
||||
exists(workspaceId: string, options?: FindManyOptions<T>): Promise<boolean> {
|
||||
this.assertWorkspaceId(workspaceId);
|
||||
|
||||
return this.repository.exists({
|
||||
...options,
|
||||
where: this.mergeWorkspaceIdIntoWhere(workspaceId, options?.where),
|
||||
});
|
||||
}
|
||||
|
||||
existsBy(workspaceId: string, where: FindOptionsWhere<T>): Promise<boolean> {
|
||||
this.assertWorkspaceId(workspaceId);
|
||||
|
||||
return this.repository.existsBy(
|
||||
this.mergeWorkspaceIdIntoCriteria(workspaceId, where),
|
||||
);
|
||||
}
|
||||
|
||||
maximum(
|
||||
workspaceId: string,
|
||||
columnName: string,
|
||||
where?: FindOptionsWhere<T>,
|
||||
): Promise<number | null> {
|
||||
this.assertWorkspaceId(workspaceId);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return this.repository.maximum(
|
||||
columnName as any,
|
||||
where
|
||||
? this.mergeWorkspaceIdIntoCriteria(workspaceId, where)
|
||||
: ({ workspaceId } as FindOptionsWhere<T>),
|
||||
);
|
||||
}
|
||||
|
||||
update(
|
||||
workspaceId: string,
|
||||
criteria: FindOptionsWhere<T>,
|
||||
@@ -70,6 +126,36 @@ export class WorkspaceScopedRepository<T extends WorkspaceScopedEntity> {
|
||||
);
|
||||
}
|
||||
|
||||
increment(
|
||||
workspaceId: string,
|
||||
criteria: FindOptionsWhere<T>,
|
||||
propertyPath: string,
|
||||
value: number | string,
|
||||
): Promise<UpdateResult> {
|
||||
this.assertWorkspaceId(workspaceId);
|
||||
|
||||
return this.repository.increment(
|
||||
this.mergeWorkspaceIdIntoCriteria(workspaceId, criteria),
|
||||
propertyPath,
|
||||
value,
|
||||
);
|
||||
}
|
||||
|
||||
decrement(
|
||||
workspaceId: string,
|
||||
criteria: FindOptionsWhere<T>,
|
||||
propertyPath: string,
|
||||
value: number | string,
|
||||
): Promise<UpdateResult> {
|
||||
this.assertWorkspaceId(workspaceId);
|
||||
|
||||
return this.repository.decrement(
|
||||
this.mergeWorkspaceIdIntoCriteria(workspaceId, criteria),
|
||||
propertyPath,
|
||||
value,
|
||||
);
|
||||
}
|
||||
|
||||
delete(
|
||||
workspaceId: string,
|
||||
criteria: FindOptionsWhere<T>,
|
||||
@@ -92,6 +178,14 @@ export class WorkspaceScopedRepository<T extends WorkspaceScopedEntity> {
|
||||
);
|
||||
}
|
||||
|
||||
// softRemove / recover / remove are intentionally absent.
|
||||
// TypeORM's entity-based methods use only the primary key in the WHERE
|
||||
// clause — stamping workspaceId on the entity object does not add an
|
||||
// AND workspace_id = ? guard to the SQL. A leaked entity id could
|
||||
// therefore act on a row from a different workspace.
|
||||
// Use softDelete / delete (criteria-based) instead — they always include
|
||||
// workspaceId in the WHERE clause.
|
||||
|
||||
insert(
|
||||
workspaceId: string,
|
||||
entity: QueryDeepPartialEntity<T> | QueryDeepPartialEntity<T>[],
|
||||
|
||||
@@ -14,6 +14,8 @@ import { RoleDTO } from 'src/engine/metadata-modules/role/dtos/role.dto';
|
||||
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';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import {
|
||||
SEED_APPLE_WORKSPACE_ID,
|
||||
SEED_YCOMBINATOR_WORKSPACE_ID,
|
||||
@@ -35,8 +37,8 @@ export class DevSeederPermissionsService {
|
||||
private readonly objectPermissionService: ObjectPermissionService,
|
||||
@InjectRepository(ObjectMetadataEntity)
|
||||
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
|
||||
@InjectRepository(RoleEntity)
|
||||
private readonly roleRepository: Repository<RoleEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleEntity)
|
||||
private readonly roleRepository: WorkspaceScopedRepository<RoleEntity>,
|
||||
private readonly fieldPermissionService: FieldPermissionService,
|
||||
private readonly roleTargetService: RoleTargetService,
|
||||
@InjectDataSource()
|
||||
@@ -54,10 +56,9 @@ export class DevSeederPermissionsService {
|
||||
workspaceCustomFlatApplication: FlatApplication;
|
||||
light?: boolean;
|
||||
}) {
|
||||
const adminRole = await this.roleRepository.findOne({
|
||||
const adminRole = await this.roleRepository.findOne(workspaceId, {
|
||||
where: {
|
||||
universalIdentifier: STANDARD_ROLE.admin.universalIdentifier,
|
||||
workspaceId,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -15,9 +15,11 @@ import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadat
|
||||
import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module';
|
||||
import { ObjectPermissionModule } from 'src/engine/metadata-modules/object-permission/object-permission.module';
|
||||
import { RoleTargetModule } from 'src/engine/metadata-modules/role-target/role-target.module';
|
||||
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';
|
||||
import { UpgradeModule } from 'src/engine/core-modules/upgrade/upgrade.module';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
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';
|
||||
@@ -62,6 +64,7 @@ import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace
|
||||
DevSeederPermissionsService,
|
||||
DevSeederDataService,
|
||||
TimelineActivitySeederService,
|
||||
provideWorkspaceScopedRepository(RoleEntity),
|
||||
],
|
||||
})
|
||||
export class DevSeederModule {}
|
||||
|
||||
@@ -15,6 +15,7 @@ import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-t
|
||||
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';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module';
|
||||
import { DevSeederModule } from 'src/engine/workspace-manager/dev-seeder/dev-seeder.module';
|
||||
import { TwentyStandardApplicationModule } from 'src/engine/workspace-manager/twenty-standard-application/twenty-standard-application.module';
|
||||
@@ -45,6 +46,9 @@ import { WorkspaceManagerService } from './workspace-manager.service';
|
||||
]),
|
||||
],
|
||||
exports: [WorkspaceManagerService],
|
||||
providers: [WorkspaceManagerService],
|
||||
providers: [
|
||||
WorkspaceManagerService,
|
||||
provideWorkspaceScopedRepository(RoleEntity),
|
||||
],
|
||||
})
|
||||
export class WorkspaceManagerModule {}
|
||||
|
||||
@@ -10,6 +10,8 @@ import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.ent
|
||||
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';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
||||
import { STANDARD_ROLE } from 'src/engine/workspace-manager/twenty-standard-application/constants/standard-role.constant';
|
||||
import { TwentyStandardApplicationService } from 'src/engine/workspace-manager/twenty-standard-application/services/twenty-standard-application.service';
|
||||
@@ -27,8 +29,8 @@ export class WorkspaceManagerService {
|
||||
private readonly twentyStandardApplicationService: TwentyStandardApplicationService,
|
||||
@InjectRepository(WorkspaceEntity)
|
||||
private readonly workspaceRepository: Repository<WorkspaceEntity>,
|
||||
@InjectRepository(RoleEntity)
|
||||
private readonly roleRepository: Repository<RoleEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleEntity)
|
||||
private readonly roleRepository: WorkspaceScopedRepository<RoleEntity>,
|
||||
private readonly applicationService: ApplicationService,
|
||||
) {}
|
||||
|
||||
@@ -97,10 +99,9 @@ export class WorkspaceManagerService {
|
||||
userId: string;
|
||||
workspaceCustomFlatApplication: FlatApplication;
|
||||
}): Promise<void> {
|
||||
const adminRole = await this.roleRepository.findOne({
|
||||
const adminRole = await this.roleRepository.findOne(workspaceId, {
|
||||
where: {
|
||||
universalIdentifier: STANDARD_ROLE.admin.universalIdentifier,
|
||||
workspaceId,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import { UserWorkspaceEntity } from 'src/engine/core-modules/user-workspace/user
|
||||
import { CalendarChannelEntity } from 'src/engine/metadata-modules/calendar-channel/entities/calendar-channel.entity';
|
||||
import { ConnectedAccountEntity } from 'src/engine/metadata-modules/connected-account/entities/connected-account.entity';
|
||||
import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module';
|
||||
import { BlocklistWorkspaceEntity } from 'src/modules/blocklist/standard-objects/blocklist.workspace-entity';
|
||||
import { CalendarEventCleanerModule } from 'src/modules/calendar/calendar-event-cleaner/calendar-event-cleaner.module';
|
||||
@@ -66,6 +67,7 @@ import { RefreshTokensManagerModule } from 'src/modules/connected-account/refres
|
||||
FeatureFlagModule,
|
||||
],
|
||||
providers: [
|
||||
provideWorkspaceScopedRepository(CalendarChannelEntity),
|
||||
CalendarChannelSyncStatusService,
|
||||
CalendarEventsImportService,
|
||||
CalendarFetchEventsService,
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { ExceptionHandlerService } from 'src/engine/core-modules/exception-handler/exception-handler.service';
|
||||
import {
|
||||
type TwentyORMException,
|
||||
TwentyORMExceptionCode,
|
||||
} from 'src/engine/twenty-orm/exceptions/twenty-orm.exception';
|
||||
import { CalendarChannelEntity } from 'src/engine/metadata-modules/calendar-channel/entities/calendar-channel.entity';
|
||||
import {
|
||||
ConnectedAccountRefreshAccessTokenException,
|
||||
ConnectedAccountRefreshAccessTokenExceptionCode,
|
||||
} from 'src/engine/metadata-modules/connected-account/exceptions/connected-account-refresh-tokens.exception';
|
||||
import {
|
||||
type TwentyORMException,
|
||||
TwentyORMExceptionCode,
|
||||
} from 'src/engine/twenty-orm/exceptions/twenty-orm.exception';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { CALENDAR_THROTTLE_MAX_ATTEMPTS } from 'src/modules/calendar/calendar-event-import-manager/constants/calendar-throttle-max-attempts';
|
||||
import {
|
||||
type CalendarEventImportDriverException,
|
||||
@@ -22,7 +22,6 @@ import {
|
||||
CalendarEventImportExceptionCode,
|
||||
} from 'src/modules/calendar/calendar-event-import-manager/exceptions/calendar-event-import.exception';
|
||||
import { CalendarChannelSyncStatusService } from 'src/modules/calendar/common/services/calendar-channel-sync-status.service';
|
||||
import { CalendarChannelEntity } from 'src/engine/metadata-modules/calendar-channel/entities/calendar-channel.entity';
|
||||
export enum CalendarEventImportSyncStep {
|
||||
CALENDAR_EVENT_LIST_FETCH = 'CALENDAR_EVENT_LIST_FETCH',
|
||||
CALENDAR_EVENTS_IMPORT = 'CALENDAR_EVENTS_IMPORT',
|
||||
@@ -34,8 +33,8 @@ export class CalendarEventImportErrorHandlerService {
|
||||
CalendarEventImportErrorHandlerService.name,
|
||||
);
|
||||
constructor(
|
||||
@InjectRepository(CalendarChannelEntity)
|
||||
private readonly calendarChannelRepository: Repository<CalendarChannelEntity>,
|
||||
@InjectWorkspaceScopedRepository(CalendarChannelEntity)
|
||||
private readonly calendarChannelRepository: WorkspaceScopedRepository<CalendarChannelEntity>,
|
||||
private readonly calendarChannelSyncStatusService: CalendarChannelSyncStatusService,
|
||||
private readonly exceptionHandlerService: ExceptionHandlerService,
|
||||
) {}
|
||||
@@ -142,7 +141,8 @@ export class CalendarEventImportErrorHandlerService {
|
||||
}
|
||||
|
||||
await this.calendarChannelRepository.increment(
|
||||
{ id: calendarChannel.id, workspaceId },
|
||||
workspaceId,
|
||||
{ id: calendarChannel.id },
|
||||
'throttleFailureCount',
|
||||
1,
|
||||
);
|
||||
|
||||
@@ -55,6 +55,7 @@ import { MessagingProcessFolderActionsService } from 'src/modules/messaging/mess
|
||||
import { MessagingProcessGroupEmailActionsService } from 'src/modules/messaging/message-import-manager/services/messaging-process-group-email-actions.service';
|
||||
import { MessagingSaveMessagesAndEnqueueContactCreationService } from 'src/modules/messaging/message-import-manager/services/messaging-save-messages-and-enqueue-contact-creation.service';
|
||||
import { MessagingWebhooksModule } from 'src/engine/core-modules/messaging-webhooks/messaging-webhooks.module';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
import { MessageParticipantManagerModule } from 'src/modules/messaging/message-participant-manager/message-participant-manager.module';
|
||||
import { MessagingMonitoringModule } from 'src/modules/messaging/monitoring/messaging-monitoring.module';
|
||||
@Module({
|
||||
@@ -88,6 +89,7 @@ import { MessagingMonitoringModule } from 'src/modules/messaging/monitoring/mess
|
||||
MessagingWebhooksModule,
|
||||
],
|
||||
providers: [
|
||||
provideWorkspaceScopedRepository(MessageChannelEntity),
|
||||
MessagingMessageListFetchCronCommand,
|
||||
MessagingMessagesImportCronCommand,
|
||||
MessagingOngoingStaleCronCommand,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Test, type TestingModule } from '@nestjs/testing';
|
||||
import { getRepositoryToken } from '@nestjs/typeorm';
|
||||
|
||||
import { MessageChannelSyncStatus } from 'twenty-shared/types';
|
||||
|
||||
@@ -8,13 +7,14 @@ import {
|
||||
ConnectedAccountRefreshAccessTokenException,
|
||||
ConnectedAccountRefreshAccessTokenExceptionCode,
|
||||
} from 'src/engine/metadata-modules/connected-account/exceptions/connected-account-refresh-tokens.exception';
|
||||
import { MessageChannelEntity } from 'src/engine/metadata-modules/message-channel/entities/message-channel.entity';
|
||||
import { getWorkspaceScopedRepositoryToken } from 'src/engine/twenty-orm/workspace-scoped-repository/get-workspace-scoped-repository-token.util';
|
||||
import { MessageChannelSyncStatusService } from 'src/modules/messaging/common/services/message-channel-sync-status.service';
|
||||
import {
|
||||
MessageImportExceptionHandlerService,
|
||||
MessageImportSyncStep,
|
||||
} from 'src/modules/messaging/message-import-manager/services/messaging-import-exception-handler.service';
|
||||
import { MessagingMonitoringService } from 'src/modules/messaging/monitoring/services/messaging-monitoring.service';
|
||||
import { MessageChannelEntity } from 'src/engine/metadata-modules/message-channel/entities/message-channel.entity';
|
||||
|
||||
describe('MessageImportExceptionHandlerService — refresh code dispatch', () => {
|
||||
let service: MessageImportExceptionHandlerService;
|
||||
@@ -50,7 +50,7 @@ describe('MessageImportExceptionHandlerService — refresh code dispatch', () =>
|
||||
providers: [
|
||||
MessageImportExceptionHandlerService,
|
||||
{
|
||||
provide: getRepositoryToken(MessageChannelEntity),
|
||||
provide: getWorkspaceScopedRepositoryToken(MessageChannelEntity),
|
||||
useValue: messageChannelRepository,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { MessageChannelSyncStatus } from 'twenty-shared/types';
|
||||
import { ExceptionHandlerService } from 'src/engine/core-modules/exception-handler/exception-handler.service';
|
||||
import {
|
||||
type TwentyORMException,
|
||||
TwentyORMExceptionCode,
|
||||
} from 'src/engine/twenty-orm/exceptions/twenty-orm.exception';
|
||||
import { MessageChannelEntity } from 'src/engine/metadata-modules/message-channel/entities/message-channel.entity';
|
||||
import {
|
||||
ConnectedAccountRefreshAccessTokenException,
|
||||
ConnectedAccountRefreshAccessTokenExceptionCode,
|
||||
} from 'src/engine/metadata-modules/connected-account/exceptions/connected-account-refresh-tokens.exception';
|
||||
import {
|
||||
type TwentyORMException,
|
||||
TwentyORMExceptionCode,
|
||||
} from 'src/engine/twenty-orm/exceptions/twenty-orm.exception';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { MessageChannelSyncStatusService } from 'src/modules/messaging/common/services/message-channel-sync-status.service';
|
||||
import { MESSAGING_THROTTLE_MAX_ATTEMPTS } from 'src/modules/messaging/message-import-manager/constants/messaging-throttle-max-attempts';
|
||||
import {
|
||||
@@ -22,7 +23,6 @@ import {
|
||||
} from 'src/modules/messaging/message-import-manager/drivers/exceptions/message-import-driver.exception';
|
||||
import { MessageNetworkExceptionCode } from 'src/modules/messaging/message-import-manager/drivers/exceptions/message-network.exception';
|
||||
import { MessagingMonitoringService } from 'src/modules/messaging/monitoring/services/messaging-monitoring.service';
|
||||
import { MessageChannelEntity } from 'src/engine/metadata-modules/message-channel/entities/message-channel.entity';
|
||||
|
||||
export enum MessageImportSyncStep {
|
||||
MESSAGE_LIST_FETCH = 'MESSAGE_LIST_FETCH',
|
||||
@@ -33,8 +33,8 @@ export enum MessageImportSyncStep {
|
||||
@Injectable()
|
||||
export class MessageImportExceptionHandlerService {
|
||||
constructor(
|
||||
@InjectRepository(MessageChannelEntity)
|
||||
private readonly messageChannelRepository: Repository<MessageChannelEntity>,
|
||||
@InjectWorkspaceScopedRepository(MessageChannelEntity)
|
||||
private readonly messageChannelRepository: WorkspaceScopedRepository<MessageChannelEntity>,
|
||||
private readonly messageChannelSyncStatusService: MessageChannelSyncStatusService,
|
||||
private readonly exceptionHandlerService: ExceptionHandlerService,
|
||||
private readonly messagingMonitoringService: MessagingMonitoringService,
|
||||
@@ -183,7 +183,8 @@ export class MessageImportExceptionHandlerService {
|
||||
}
|
||||
|
||||
await this.messageChannelRepository.increment(
|
||||
{ id: messageChannel.id, workspaceId },
|
||||
workspaceId,
|
||||
{ id: messageChannel.id },
|
||||
'throttleFailureCount',
|
||||
1,
|
||||
);
|
||||
@@ -194,7 +195,8 @@ export class MessageImportExceptionHandlerService {
|
||||
: undefined;
|
||||
|
||||
await this.messageChannelRepository.update(
|
||||
{ id: messageChannel.id, workspaceId },
|
||||
workspaceId,
|
||||
{ id: messageChannel.id },
|
||||
{
|
||||
throttleRetryAfter: isDefined(throttleRetryAfter)
|
||||
? throttleRetryAfter.toISOString()
|
||||
|
||||
@@ -12,6 +12,7 @@ import { LogicFunctionFromSourceService } from 'src/engine/metadata-modules/logi
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
|
||||
import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager';
|
||||
import { getWorkspaceScopedRepositoryToken } from 'src/engine/twenty-orm/workspace-scoped-repository/get-workspace-scoped-repository-token.util';
|
||||
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
|
||||
import { WorkflowCommonWorkspaceService } from 'src/modules/workflow/common/workspace-services/workflow-common.workspace-service';
|
||||
import { CodeStepBuildService } from 'src/modules/workflow/workflow-builder/workflow-version-step/code-step/services/code-step-build.service';
|
||||
@@ -143,7 +144,7 @@ describe('WorkflowVersionStepOperationsWorkspaceService', () => {
|
||||
useValue: agentService,
|
||||
},
|
||||
{
|
||||
provide: getRepositoryToken(RoleTargetEntity),
|
||||
provide: getWorkspaceScopedRepositoryToken(RoleTargetEntity),
|
||||
useValue: roleTargetRepository,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -27,6 +27,8 @@ import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadat
|
||||
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
|
||||
import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager';
|
||||
import { buildSystemAuthContext } from 'src/engine/twenty-orm/utils/build-system-auth-context.util';
|
||||
import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator';
|
||||
import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository';
|
||||
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
|
||||
import {
|
||||
WorkflowVersionStepException,
|
||||
@@ -70,8 +72,8 @@ export class WorkflowVersionStepOperationsWorkspaceService {
|
||||
private readonly logicFunctionFromSourceService: LogicFunctionFromSourceService,
|
||||
private readonly codeStepBuildService: CodeStepBuildService,
|
||||
private readonly agentService: AgentService,
|
||||
@InjectRepository(RoleTargetEntity)
|
||||
private readonly roleTargetRepository: Repository<RoleTargetEntity>,
|
||||
@InjectWorkspaceScopedRepository(RoleTargetEntity)
|
||||
private readonly roleTargetRepository: WorkspaceScopedRepository<RoleTargetEntity>,
|
||||
@InjectRepository(ObjectMetadataEntity)
|
||||
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
|
||||
private readonly workflowCommonWorkspaceService: WorkflowCommonWorkspaceService,
|
||||
@@ -100,12 +102,14 @@ export class WorkflowVersionStepOperationsWorkspaceService {
|
||||
break;
|
||||
}
|
||||
|
||||
const roleTarget = await this.roleTargetRepository.findOne({
|
||||
where: {
|
||||
agentId: step.settings.input.agentId,
|
||||
workspaceId,
|
||||
const roleTarget = await this.roleTargetRepository.findOne(
|
||||
workspaceId,
|
||||
{
|
||||
where: {
|
||||
agentId: step.settings.input.agentId,
|
||||
},
|
||||
},
|
||||
});
|
||||
);
|
||||
|
||||
await this.agentService.deleteManyAgents({
|
||||
ids: [step.settings.input.agentId],
|
||||
|
||||
@@ -9,6 +9,7 @@ import { LogicFunctionModule } from 'src/engine/metadata-modules/logic-function/
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository';
|
||||
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
|
||||
import { WorkflowCommonModule } from 'src/modules/workflow/common/workflow-common.module';
|
||||
import { WorkflowSchemaModule } from 'src/modules/workflow/workflow-builder/workflow-schema/workflow-schema.module';
|
||||
@@ -43,6 +44,7 @@ import { WorkflowVersionStepWorkspaceService } from 'src/modules/workflow/workfl
|
||||
WorkflowVersionStepCreationWorkspaceService,
|
||||
WorkflowVersionStepUpdateWorkspaceService,
|
||||
WorkflowVersionStepDeletionWorkspaceService,
|
||||
provideWorkspaceScopedRepository(RoleTargetEntity),
|
||||
],
|
||||
exports: [
|
||||
WorkflowVersionStepWorkspaceService,
|
||||
|
||||
Reference in New Issue
Block a user