mirror of
https://github.com/docmost/docmost.git
synced 2026-05-20 00:14:10 +08:00
feat: notifications (#1947)
* feat: notifications * feat: watchers * improvements * handle page move for watchers * make watchers non-blocking * more
This commit is contained in:
@@ -4,6 +4,7 @@ import { GroupController } from './group.controller';
|
||||
import { GroupUserService } from './services/group-user.service';
|
||||
|
||||
@Module({
|
||||
imports: [],
|
||||
controllers: [GroupController],
|
||||
providers: [GroupService, GroupUserService],
|
||||
exports: [GroupService, GroupUserService],
|
||||
|
||||
@@ -10,15 +10,20 @@ import { GroupService } from './group.service';
|
||||
import { KyselyDB } from '@docmost/db/types/kysely.types';
|
||||
import { InjectKysely } from 'nestjs-kysely';
|
||||
import { GroupUserRepo } from '@docmost/db/repos/group/group-user.repo';
|
||||
import { SpaceMemberRepo } from '@docmost/db/repos/space/space-member.repo';
|
||||
import { UserRepo } from '@docmost/db/repos/user/user.repo';
|
||||
import { executeTx } from '@docmost/db/utils';
|
||||
import { WatcherRepo } from '@docmost/db/repos/watcher/watcher.repo';
|
||||
|
||||
@Injectable()
|
||||
export class GroupUserService {
|
||||
constructor(
|
||||
private groupUserRepo: GroupUserRepo,
|
||||
private spaceMemberRepo: SpaceMemberRepo,
|
||||
private userRepo: UserRepo,
|
||||
@Inject(forwardRef(() => GroupService))
|
||||
private groupService: GroupService,
|
||||
private readonly watcherRepo: WatcherRepo,
|
||||
@InjectKysely() private readonly db: KyselyDB,
|
||||
) {}
|
||||
|
||||
@@ -100,6 +105,18 @@ export class GroupUserService {
|
||||
throw new BadRequestException('Group member not found');
|
||||
}
|
||||
|
||||
await this.groupUserRepo.delete(userId, groupId);
|
||||
const spaceIds = await this.spaceMemberRepo.getSpaceIdsByGroupId(groupId);
|
||||
|
||||
// TODO: use queue instead
|
||||
await executeTx(this.db, async (trx) => {
|
||||
await this.groupUserRepo.delete(userId, groupId, { trx });
|
||||
|
||||
for (const spaceId of spaceIds) {
|
||||
await this.watcherRepo.deleteByUsersWithoutSpaceAccess(
|
||||
[userId],
|
||||
spaceId,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,18 +8,27 @@ import {
|
||||
import { CreateGroupDto, DefaultGroup } from '../dto/create-group.dto';
|
||||
import { PaginationOptions } from '@docmost/db/pagination/pagination-options';
|
||||
import { UpdateGroupDto } from '../dto/update-group.dto';
|
||||
import { KyselyTransaction } from '@docmost/db/types/kysely.types';
|
||||
import { KyselyDB, KyselyTransaction } from '@docmost/db/types/kysely.types';
|
||||
import { GroupRepo } from '@docmost/db/repos/group/group.repo';
|
||||
import { GroupUserRepo } from '@docmost/db/repos/group/group-user.repo';
|
||||
import { SpaceMemberRepo } from '@docmost/db/repos/space/space-member.repo';
|
||||
import { Group, InsertableGroup, User } from '@docmost/db/types/entity.types';
|
||||
import { CursorPaginationResult } from '@docmost/db/pagination/cursor-pagination';
|
||||
import { GroupUserService } from './group-user.service';
|
||||
import { WatcherRepo } from '@docmost/db/repos/watcher/watcher.repo';
|
||||
import { executeTx } from '@docmost/db/utils';
|
||||
import { InjectKysely } from 'nestjs-kysely';
|
||||
|
||||
@Injectable()
|
||||
export class GroupService {
|
||||
constructor(
|
||||
private groupRepo: GroupRepo,
|
||||
private groupUserRepo: GroupUserRepo,
|
||||
private spaceMemberRepo: SpaceMemberRepo,
|
||||
@Inject(forwardRef(() => GroupUserService))
|
||||
private groupUserService: GroupUserService,
|
||||
private readonly watcherRepo: WatcherRepo,
|
||||
@InjectKysely() private readonly db: KyselyDB,
|
||||
) {}
|
||||
|
||||
async getGroupInfo(groupId: string, workspaceId: string): Promise<Group> {
|
||||
@@ -68,20 +77,6 @@ export class GroupService {
|
||||
return createdGroup;
|
||||
}
|
||||
|
||||
async createDefaultGroup(
|
||||
workspaceId: string,
|
||||
userId?: string,
|
||||
trx?: KyselyTransaction,
|
||||
): Promise<Group> {
|
||||
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,
|
||||
@@ -141,7 +136,24 @@ export class GroupService {
|
||||
if (group.isDefault) {
|
||||
throw new BadRequestException('You cannot delete a default group');
|
||||
}
|
||||
await this.groupRepo.delete(groupId, workspaceId);
|
||||
|
||||
const [userIds, spaceIds] = await Promise.all([
|
||||
this.groupUserRepo.getUserIdsByGroupId(groupId),
|
||||
this.spaceMemberRepo.getSpaceIdsByGroupId(groupId),
|
||||
]);
|
||||
|
||||
// TODO: use queue instead
|
||||
await executeTx(this.db, async (trx) => {
|
||||
await this.groupRepo.delete(groupId, workspaceId, { trx });
|
||||
|
||||
for (const spaceId of spaceIds) {
|
||||
await this.watcherRepo.deleteByUsersWithoutSpaceAccess(
|
||||
userIds,
|
||||
spaceId,
|
||||
{ trx },
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async findAndValidateGroup(
|
||||
|
||||
Reference in New Issue
Block a user