mirror of
https://github.com/docmost/docmost.git
synced 2025-11-20 19:01:12 +10:00
Refactoring
* replace TypeORM with Kysely query builder * refactor migrations * other changes and fixes
This commit is contained in:
@ -1,43 +0,0 @@
|
||||
import {
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
Entity,
|
||||
JoinColumn,
|
||||
ManyToOne,
|
||||
PrimaryGeneratedColumn,
|
||||
Unique,
|
||||
UpdateDateColumn,
|
||||
} from 'typeorm';
|
||||
import { User } from '../../user/entities/user.entity';
|
||||
import { Group } from './group.entity';
|
||||
|
||||
@Entity('group_users')
|
||||
@Unique(['groupId', 'userId'])
|
||||
export class GroupUser {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@Column()
|
||||
userId: string;
|
||||
|
||||
@ManyToOne(() => User, {
|
||||
onDelete: 'CASCADE',
|
||||
})
|
||||
@JoinColumn({ name: 'userId' })
|
||||
user: User;
|
||||
|
||||
@Column()
|
||||
groupId: string;
|
||||
|
||||
@ManyToOne(() => Group, (group) => group.groupUsers, {
|
||||
onDelete: 'CASCADE',
|
||||
})
|
||||
@JoinColumn({ name: 'groupId' })
|
||||
group: Group;
|
||||
|
||||
@CreateDateColumn()
|
||||
createdAt: Date;
|
||||
|
||||
@UpdateDateColumn()
|
||||
updatedAt: Date;
|
||||
}
|
||||
@ -1,61 +0,0 @@
|
||||
import {
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
Entity,
|
||||
JoinColumn,
|
||||
ManyToOne,
|
||||
OneToMany,
|
||||
PrimaryGeneratedColumn,
|
||||
UpdateDateColumn,
|
||||
} from 'typeorm';
|
||||
import { GroupUser } from './group-user.entity';
|
||||
import { Workspace } from '../../workspace/entities/workspace.entity';
|
||||
import { User } from '../../user/entities/user.entity';
|
||||
import { Unique } from 'typeorm';
|
||||
import { SpaceMember } from '../../space/entities/space-member.entity';
|
||||
|
||||
@Entity('groups')
|
||||
@Unique(['name', 'workspaceId'])
|
||||
export class Group {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@Column({ length: 255 })
|
||||
name: string;
|
||||
|
||||
@Column({ type: 'text', nullable: true })
|
||||
description: string;
|
||||
|
||||
@Column({ type: 'boolean', default: false })
|
||||
isDefault: boolean;
|
||||
|
||||
@Column()
|
||||
workspaceId: string;
|
||||
|
||||
@ManyToOne(() => Workspace, (workspace) => workspace.groups, {
|
||||
onDelete: 'CASCADE',
|
||||
})
|
||||
@JoinColumn({ name: 'workspaceId' })
|
||||
workspace: Workspace;
|
||||
|
||||
@Column({ nullable: true })
|
||||
creatorId: string;
|
||||
|
||||
@ManyToOne(() => User)
|
||||
@JoinColumn({ name: 'creatorId' })
|
||||
creator: User;
|
||||
|
||||
@CreateDateColumn()
|
||||
createdAt: Date;
|
||||
|
||||
@UpdateDateColumn()
|
||||
updatedAt: Date;
|
||||
|
||||
@OneToMany(() => GroupUser, (groupUser) => groupUser.group)
|
||||
groupUsers: GroupUser[];
|
||||
|
||||
@OneToMany(() => SpaceMember, (spaceMembership) => spaceMembership.group)
|
||||
spaces: SpaceMember[];
|
||||
|
||||
memberCount?: number;
|
||||
}
|
||||
@ -10,8 +10,6 @@ import { GroupService } from './services/group.service';
|
||||
import { CreateGroupDto } from './dto/create-group.dto';
|
||||
import { AuthUser } from '../../decorators/auth-user.decorator';
|
||||
import { AuthWorkspace } from '../../decorators/auth-workspace.decorator';
|
||||
import { User } from '../user/entities/user.entity';
|
||||
import { Workspace } from '../workspace/entities/workspace.entity';
|
||||
import { GroupUserService } from './services/group-user.service';
|
||||
import { GroupIdDto } from './dto/group-id.dto';
|
||||
import { PaginationOptions } from '../../helpers/pagination/pagination-options';
|
||||
@ -19,12 +17,11 @@ import { AddGroupUserDto } from './dto/add-group-user.dto';
|
||||
import { RemoveGroupUserDto } from './dto/remove-group-user.dto';
|
||||
import { UpdateGroupDto } from './dto/update-group.dto';
|
||||
import { Action } from '../casl/ability.action';
|
||||
import { Group } from './entities/group.entity';
|
||||
import { GroupUser } from './entities/group-user.entity';
|
||||
import { PoliciesGuard } from '../casl/guards/policies.guard';
|
||||
import { CheckPolicies } from '../casl/decorators/policies.decorator';
|
||||
import { AppAbility } from '../casl/abilities/casl-ability.factory';
|
||||
import { JwtAuthGuard } from '../../guards/jwt-auth.guard';
|
||||
import { User, Workspace } from '@docmost/db/types/entity.types';
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Controller('groups')
|
||||
@ -45,7 +42,7 @@ export class GroupController {
|
||||
}
|
||||
|
||||
@UseGuards(PoliciesGuard)
|
||||
@CheckPolicies((ability: AppAbility) => ability.can(Action.Read, Group))
|
||||
@CheckPolicies((ability: AppAbility) => ability.can(Action.Read, 'Group'))
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@Post('/info')
|
||||
getGroup(
|
||||
@ -57,7 +54,7 @@ export class GroupController {
|
||||
}
|
||||
|
||||
@UseGuards(PoliciesGuard)
|
||||
@CheckPolicies((ability: AppAbility) => ability.can(Action.Manage, Group))
|
||||
@CheckPolicies((ability: AppAbility) => ability.can(Action.Manage, 'Group'))
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@Post('create')
|
||||
createGroup(
|
||||
@ -69,7 +66,7 @@ export class GroupController {
|
||||
}
|
||||
|
||||
@UseGuards(PoliciesGuard)
|
||||
@CheckPolicies((ability: AppAbility) => ability.can(Action.Manage, Group))
|
||||
@CheckPolicies((ability: AppAbility) => ability.can(Action.Manage, 'Group'))
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@Post('update')
|
||||
updateGroup(
|
||||
@ -81,7 +78,7 @@ export class GroupController {
|
||||
}
|
||||
|
||||
@UseGuards(PoliciesGuard)
|
||||
@CheckPolicies((ability: AppAbility) => ability.can(Action.Read, GroupUser))
|
||||
@CheckPolicies((ability: AppAbility) => ability.can(Action.Read, 'GroupUser'))
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@Post('members')
|
||||
getGroupMembers(
|
||||
@ -97,7 +94,9 @@ export class GroupController {
|
||||
}
|
||||
|
||||
@UseGuards(PoliciesGuard)
|
||||
@CheckPolicies((ability: AppAbility) => ability.can(Action.Manage, GroupUser))
|
||||
@CheckPolicies((ability: AppAbility) =>
|
||||
ability.can(Action.Manage, 'GroupUser'),
|
||||
)
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@Post('members/add')
|
||||
addGroupMember(
|
||||
@ -113,7 +112,9 @@ export class GroupController {
|
||||
}
|
||||
|
||||
@UseGuards(PoliciesGuard)
|
||||
@CheckPolicies((ability: AppAbility) => ability.can(Action.Manage, GroupUser))
|
||||
@CheckPolicies((ability: AppAbility) =>
|
||||
ability.can(Action.Manage, 'GroupUser'),
|
||||
)
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@Post('members/remove')
|
||||
removeGroupMember(
|
||||
@ -129,7 +130,7 @@ export class GroupController {
|
||||
}
|
||||
|
||||
@UseGuards(PoliciesGuard)
|
||||
@CheckPolicies((ability: AppAbility) => ability.can(Action.Manage, Group))
|
||||
@CheckPolicies((ability: AppAbility) => ability.can(Action.Manage, 'Group'))
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@Post('delete')
|
||||
deleteGroup(
|
||||
|
||||
@ -1,22 +1,11 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { GroupService } from './services/group.service';
|
||||
import { GroupController } from './group.controller';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { Group } from './entities/group.entity';
|
||||
import { GroupUser } from './entities/group-user.entity';
|
||||
import { GroupRepository } from './respositories/group.repository';
|
||||
import { GroupUserRepository } from './respositories/group-user.repository';
|
||||
import { GroupUserService } from './services/group-user.service';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([Group, GroupUser])],
|
||||
controllers: [GroupController],
|
||||
providers: [
|
||||
GroupService,
|
||||
GroupUserService,
|
||||
GroupRepository,
|
||||
GroupUserRepository,
|
||||
],
|
||||
providers: [GroupService, GroupUserService],
|
||||
exports: [GroupService, GroupUserService],
|
||||
})
|
||||
export class GroupModule {}
|
||||
|
||||
@ -1,10 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { DataSource, Repository } from 'typeorm';
|
||||
import { GroupUser } from '../entities/group-user.entity';
|
||||
|
||||
@Injectable()
|
||||
export class GroupUserRepository extends Repository<GroupUser> {
|
||||
constructor(private dataSource: DataSource) {
|
||||
super(GroupUser, dataSource.createEntityManager());
|
||||
}
|
||||
}
|
||||
@ -1,10 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { DataSource, Repository } from 'typeorm';
|
||||
import { Group } from '../entities/group.entity';
|
||||
|
||||
@Injectable()
|
||||
export class GroupRepository extends Repository<Group> {
|
||||
constructor(private dataSource: DataSource) {
|
||||
super(Group, dataSource.createEntityManager());
|
||||
}
|
||||
}
|
||||
@ -1,48 +1,35 @@
|
||||
import {
|
||||
BadRequestException,
|
||||
Injectable,
|
||||
NotFoundException,
|
||||
} from '@nestjs/common';
|
||||
import { DataSource, EntityManager } from 'typeorm';
|
||||
import { GroupUserRepository } from '../respositories/group-user.repository';
|
||||
import { BadRequestException, Injectable } from '@nestjs/common';
|
||||
import { PaginationOptions } from '../../../helpers/pagination/pagination-options';
|
||||
import { transactionWrapper } from '../../../helpers/db.helper';
|
||||
import { User } from '../../user/entities/user.entity';
|
||||
import { GroupUser } from '../entities/group-user.entity';
|
||||
import { PaginationMetaDto } from '../../../helpers/pagination/pagination-meta-dto';
|
||||
import { PaginatedResult } from '../../../helpers/pagination/paginated-result';
|
||||
import { Group } from '../entities/group.entity';
|
||||
import { GroupService } from './group.service';
|
||||
import { KyselyDB, KyselyTransaction } from '@docmost/db/types/kysely.types';
|
||||
import { executeTx } from '@docmost/db/utils';
|
||||
import { InjectKysely } from 'nestjs-kysely';
|
||||
import { GroupRepo } from '@docmost/db/repos/group/group.repo';
|
||||
import { GroupUserRepo } from '@docmost/db/repos/group/group-user.repo';
|
||||
import { User } from '@docmost/db/types/entity.types';
|
||||
|
||||
@Injectable()
|
||||
export class GroupUserService {
|
||||
constructor(
|
||||
private groupUserRepository: GroupUserRepository,
|
||||
private groupRepo: GroupRepo,
|
||||
private groupUserRepo: GroupUserRepo,
|
||||
private groupService: GroupService,
|
||||
private dataSource: DataSource,
|
||||
@InjectKysely() private readonly db: KyselyDB,
|
||||
) {}
|
||||
|
||||
async getGroupUsers(
|
||||
groupId,
|
||||
groupId: string,
|
||||
workspaceId: string,
|
||||
paginationOptions: PaginationOptions,
|
||||
): Promise<PaginatedResult<User>> {
|
||||
await this.groupService.findAndValidateGroup(groupId, workspaceId);
|
||||
|
||||
const [groupUsers, count] = await this.groupUserRepository.findAndCount({
|
||||
relations: ['user'],
|
||||
where: {
|
||||
groupId: groupId,
|
||||
group: {
|
||||
workspaceId: workspaceId,
|
||||
},
|
||||
},
|
||||
|
||||
take: paginationOptions.limit,
|
||||
skip: paginationOptions.skip,
|
||||
});
|
||||
|
||||
const users = groupUsers.map((groupUser: GroupUser) => groupUser.user);
|
||||
const { users, count } = await this.groupUserRepo.getGroupUsersPaginated(
|
||||
groupId,
|
||||
paginationOptions,
|
||||
);
|
||||
|
||||
const paginationMeta = new PaginationMetaDto({ count, paginationOptions });
|
||||
|
||||
@ -52,23 +39,18 @@ export class GroupUserService {
|
||||
async addUserToDefaultGroup(
|
||||
userId: string,
|
||||
workspaceId: string,
|
||||
manager?: EntityManager,
|
||||
trx?: KyselyTransaction,
|
||||
): Promise<void> {
|
||||
return await transactionWrapper(
|
||||
async (manager) => {
|
||||
const defaultGroup = await this.groupService.getDefaultGroup(
|
||||
await executeTx(
|
||||
this.db,
|
||||
async (trx) => {
|
||||
const defaultGroup = await this.groupRepo.getDefaultGroup(
|
||||
workspaceId,
|
||||
manager,
|
||||
);
|
||||
await this.addUserToGroup(
|
||||
userId,
|
||||
defaultGroup.id,
|
||||
workspaceId,
|
||||
manager,
|
||||
trx,
|
||||
);
|
||||
await this.addUserToGroup(userId, defaultGroup.id, workspaceId, trx);
|
||||
},
|
||||
this.dataSource,
|
||||
manager,
|
||||
trx,
|
||||
);
|
||||
}
|
||||
|
||||
@ -76,46 +58,33 @@ export class GroupUserService {
|
||||
userId: string,
|
||||
groupId: string,
|
||||
workspaceId: string,
|
||||
manager?: EntityManager,
|
||||
): Promise<GroupUser> {
|
||||
return await transactionWrapper(
|
||||
async (manager) => {
|
||||
const group = await manager.findOneBy(Group, {
|
||||
id: groupId,
|
||||
workspaceId: workspaceId,
|
||||
});
|
||||
trx?: KyselyTransaction,
|
||||
): Promise<void> {
|
||||
await executeTx(
|
||||
this.db,
|
||||
async (trx) => {
|
||||
await this.groupService.findAndValidateGroup(groupId, workspaceId);
|
||||
const groupUserExists = await this.groupUserRepo.getGroupUserById(
|
||||
userId,
|
||||
groupId,
|
||||
trx,
|
||||
);
|
||||
|
||||
if (!group) {
|
||||
throw new NotFoundException('Group not found');
|
||||
}
|
||||
|
||||
const userExists = await manager.exists(User, {
|
||||
where: { id: userId, workspaceId },
|
||||
});
|
||||
|
||||
if (!userExists) {
|
||||
throw new NotFoundException('User not found');
|
||||
}
|
||||
|
||||
const existingGroupUser = await manager.findOneBy(GroupUser, {
|
||||
userId: userId,
|
||||
groupId: groupId,
|
||||
});
|
||||
|
||||
if (existingGroupUser) {
|
||||
if (groupUserExists) {
|
||||
throw new BadRequestException(
|
||||
'User is already a member of this group',
|
||||
);
|
||||
}
|
||||
|
||||
const groupUser = new GroupUser();
|
||||
groupUser.userId = userId;
|
||||
groupUser.groupId = groupId;
|
||||
|
||||
return manager.save(groupUser);
|
||||
await this.groupUserRepo.insertGroupUser(
|
||||
{
|
||||
userId,
|
||||
groupId,
|
||||
},
|
||||
trx,
|
||||
);
|
||||
},
|
||||
this.dataSource,
|
||||
manager,
|
||||
trx,
|
||||
);
|
||||
}
|
||||
|
||||
@ -135,22 +104,15 @@ export class GroupUserService {
|
||||
);
|
||||
}
|
||||
|
||||
const groupUser = await this.getGroupUser(userId, groupId);
|
||||
const groupUser = await this.groupUserRepo.getGroupUserById(
|
||||
userId,
|
||||
groupId,
|
||||
);
|
||||
|
||||
if (!groupUser) {
|
||||
throw new BadRequestException('Group member not found');
|
||||
}
|
||||
|
||||
await this.groupUserRepository.delete({
|
||||
userId,
|
||||
groupId,
|
||||
});
|
||||
}
|
||||
|
||||
async getGroupUser(userId: string, groupId: string): Promise<GroupUser> {
|
||||
return await this.groupUserRepository.findOneBy({
|
||||
userId,
|
||||
groupId,
|
||||
});
|
||||
await this.groupUserRepo.delete(userId, groupId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,87 +4,64 @@ import {
|
||||
NotFoundException,
|
||||
} from '@nestjs/common';
|
||||
import { CreateGroupDto, DefaultGroup } from '../dto/create-group.dto';
|
||||
import { GroupRepository } from '../respositories/group.repository';
|
||||
import { Group } from '../entities/group.entity';
|
||||
import { plainToInstance } from 'class-transformer';
|
||||
import { User } from '../../user/entities/user.entity';
|
||||
import { PaginationMetaDto } from '../../../helpers/pagination/pagination-meta-dto';
|
||||
import { PaginatedResult } from '../../../helpers/pagination/paginated-result';
|
||||
import { PaginationOptions } from '../../../helpers/pagination/pagination-options';
|
||||
import { UpdateGroupDto } from '../dto/update-group.dto';
|
||||
import { DataSource, EntityManager } from 'typeorm';
|
||||
import { transactionWrapper } from '../../../helpers/db.helper';
|
||||
import { KyselyTransaction } from '@docmost/db/types/kysely.types';
|
||||
import { GroupRepo } from '@docmost/db/repos/group/group.repo';
|
||||
import { Group, InsertableGroup, User } from '@docmost/db/types/entity.types';
|
||||
|
||||
@Injectable()
|
||||
export class GroupService {
|
||||
constructor(
|
||||
private groupRepository: GroupRepository,
|
||||
private dataSource: DataSource,
|
||||
) {}
|
||||
constructor(private groupRepo: GroupRepo) {}
|
||||
|
||||
async createGroup(
|
||||
authUser: User,
|
||||
workspaceId: string,
|
||||
createGroupDto: CreateGroupDto,
|
||||
trx?: KyselyTransaction,
|
||||
): Promise<Group> {
|
||||
const group = plainToInstance(Group, createGroupDto);
|
||||
group.creatorId = authUser.id;
|
||||
group.workspaceId = workspaceId;
|
||||
|
||||
const groupExists = await this.findGroupByName(
|
||||
const groupExists = await this.groupRepo.findByName(
|
||||
createGroupDto.name,
|
||||
workspaceId,
|
||||
);
|
||||
if (groupExists) {
|
||||
throw new BadRequestException('Group name already exists');
|
||||
}
|
||||
const insertableGroup: InsertableGroup = {
|
||||
name: createGroupDto.name,
|
||||
description: createGroupDto.description,
|
||||
isDefault: false,
|
||||
creatorId: authUser.id,
|
||||
workspaceId: workspaceId,
|
||||
};
|
||||
|
||||
return await this.groupRepository.save(group);
|
||||
return await this.groupRepo.insertGroup(insertableGroup, trx);
|
||||
}
|
||||
|
||||
async createDefaultGroup(
|
||||
workspaceId: string,
|
||||
userId?: string,
|
||||
manager?: EntityManager,
|
||||
trx?: KyselyTransaction,
|
||||
): Promise<Group> {
|
||||
return await transactionWrapper(
|
||||
async (manager: EntityManager) => {
|
||||
const group = new Group();
|
||||
group.name = DefaultGroup.EVERYONE;
|
||||
group.isDefault = true;
|
||||
group.creatorId = userId ?? null;
|
||||
group.workspaceId = workspaceId;
|
||||
return await manager.save(group);
|
||||
},
|
||||
this.dataSource,
|
||||
manager,
|
||||
);
|
||||
}
|
||||
|
||||
async getDefaultGroup(
|
||||
workspaceId: string,
|
||||
manager: EntityManager,
|
||||
): Promise<Group> {
|
||||
return await transactionWrapper(
|
||||
async (manager: EntityManager) => {
|
||||
return await manager.findOneBy(Group, {
|
||||
isDefault: true,
|
||||
workspaceId,
|
||||
});
|
||||
},
|
||||
this.dataSource,
|
||||
manager,
|
||||
);
|
||||
const insertableGroup: InsertableGroup = {
|
||||
name: DefaultGroup.EVERYONE,
|
||||
isDefault: true,
|
||||
creatorId: userId ?? null,
|
||||
workspaceId: workspaceId,
|
||||
};
|
||||
return await this.groupRepo.insertGroup(insertableGroup, trx);
|
||||
}
|
||||
|
||||
async updateGroup(
|
||||
workspaceId: string,
|
||||
updateGroupDto: UpdateGroupDto,
|
||||
): Promise<Group> {
|
||||
const group = await this.groupRepository.findOneBy({
|
||||
id: updateGroupDto.groupId,
|
||||
workspaceId: workspaceId,
|
||||
});
|
||||
const group = await this.groupRepo.findById(
|
||||
updateGroupDto.groupId,
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
if (!group) {
|
||||
throw new NotFoundException('Group not found');
|
||||
@ -94,7 +71,7 @@ export class GroupService {
|
||||
throw new BadRequestException('You cannot update a default group');
|
||||
}
|
||||
|
||||
const groupExists = await this.findGroupByName(
|
||||
const groupExists = await this.groupRepo.findByName(
|
||||
updateGroupDto.name,
|
||||
workspaceId,
|
||||
);
|
||||
@ -110,20 +87,21 @@ export class GroupService {
|
||||
group.description = updateGroupDto.description;
|
||||
}
|
||||
|
||||
return await this.groupRepository.save(group);
|
||||
await this.groupRepo.update(
|
||||
{
|
||||
name: updateGroupDto.name,
|
||||
description: updateGroupDto.description,
|
||||
},
|
||||
group.id,
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
async getGroupInfo(groupId: string, workspaceId: string): Promise<Group> {
|
||||
const group = await this.groupRepository
|
||||
.createQueryBuilder('group')
|
||||
.where('group.id = :groupId', { groupId })
|
||||
.andWhere('group.workspaceId = :workspaceId', { workspaceId })
|
||||
.loadRelationCountAndMap(
|
||||
'group.memberCount',
|
||||
'group.groupUsers',
|
||||
'groupUsers',
|
||||
)
|
||||
.getOne();
|
||||
// todo: add member count
|
||||
const group = await this.groupRepo.findById(groupId, workspaceId);
|
||||
|
||||
if (!group) {
|
||||
throw new NotFoundException('Group not found');
|
||||
@ -136,17 +114,10 @@ export class GroupService {
|
||||
workspaceId: string,
|
||||
paginationOptions: PaginationOptions,
|
||||
): Promise<PaginatedResult<Group>> {
|
||||
const [groups, count] = await this.groupRepository
|
||||
.createQueryBuilder('group')
|
||||
.where('group.workspaceId = :workspaceId', { workspaceId })
|
||||
.loadRelationCountAndMap(
|
||||
'group.memberCount',
|
||||
'group.groupUsers',
|
||||
'groupUsers',
|
||||
)
|
||||
.take(paginationOptions.limit)
|
||||
.skip(paginationOptions.skip)
|
||||
.getManyAndCount();
|
||||
const { groups, count } = await this.groupRepo.getGroupsPaginated(
|
||||
workspaceId,
|
||||
paginationOptions,
|
||||
);
|
||||
|
||||
const paginationMeta = new PaginationMetaDto({ count, paginationOptions });
|
||||
|
||||
@ -158,34 +129,18 @@ export class GroupService {
|
||||
if (group.isDefault) {
|
||||
throw new BadRequestException('You cannot delete a default group');
|
||||
}
|
||||
await this.groupRepository.delete(groupId);
|
||||
await this.groupRepo.delete(groupId, workspaceId);
|
||||
}
|
||||
|
||||
async findAndValidateGroup(
|
||||
groupId: string,
|
||||
workspaceId: string,
|
||||
): Promise<Group> {
|
||||
const group = await this.groupRepository.findOne({
|
||||
where: {
|
||||
id: groupId,
|
||||
workspaceId: workspaceId,
|
||||
},
|
||||
});
|
||||
const group = await this.groupRepo.findById(groupId, workspaceId);
|
||||
if (!group) {
|
||||
throw new NotFoundException('Group not found');
|
||||
}
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
async findGroupByName(
|
||||
groupName: string,
|
||||
workspaceId: string,
|
||||
): Promise<Group> {
|
||||
return this.groupRepository
|
||||
.createQueryBuilder('group')
|
||||
.where('LOWER(group.name) = LOWER(:groupName)', { groupName })
|
||||
.andWhere('group.workspaceId = :workspaceId', { workspaceId })
|
||||
.getOne();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user