your message
This commit is contained in:
@ -14,35 +14,171 @@ export class GroupsService {
|
||||
});
|
||||
}
|
||||
|
||||
async addMember(groupId: string, userId: string, role = 'student'): Promise<any> {
|
||||
return this.prisma.groupMember.create({
|
||||
data: { groupId, userId, role },
|
||||
async ensureDefaultGroup(courseId: string): Promise<any> {
|
||||
const existing = await this.prisma.courseGroup.findFirst({
|
||||
where: { courseId, isDefault: true },
|
||||
});
|
||||
if (existing) return existing;
|
||||
|
||||
return this.prisma.courseGroup.create({
|
||||
data: {
|
||||
courseId,
|
||||
name: 'Основная группа',
|
||||
description: 'Обсуждение курса и вопросы преподавателю',
|
||||
isDefault: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async getDefaultGroup(courseId: string, userId: string): Promise<any> {
|
||||
const group = await this.ensureDefaultGroup(courseId);
|
||||
await this.assertCanReadGroup(group.id, userId);
|
||||
|
||||
const [messages, members] = await Promise.all([
|
||||
this.getGroupMessages(group.id, userId),
|
||||
this.getGroupMembers(group.id, userId),
|
||||
]);
|
||||
return { group, messages, members };
|
||||
}
|
||||
|
||||
async addMember(groupId: string, requesterId: string, targetUserId: string, role = 'student'): Promise<any> {
|
||||
const group = await this.prisma.courseGroup.findUnique({
|
||||
where: { id: groupId },
|
||||
include: { course: { select: { authorId: true } } },
|
||||
});
|
||||
if (!group) throw new NotFoundException('Group not found');
|
||||
if (group.course.authorId !== requesterId) {
|
||||
throw new ForbiddenException('Only course author can add members manually');
|
||||
}
|
||||
|
||||
return this.prisma.groupMember.upsert({
|
||||
where: { groupId_userId: { groupId, userId: targetUserId } },
|
||||
create: { groupId, userId: targetUserId, role },
|
||||
update: { role },
|
||||
});
|
||||
}
|
||||
|
||||
async getGroupMembers(groupId: string, userId: string): Promise<any> {
|
||||
await this.assertCanReadGroup(groupId, userId);
|
||||
return this.prisma.groupMember.findMany({
|
||||
where: { groupId },
|
||||
include: {
|
||||
user: {
|
||||
select: { id: true, name: true, email: true, avatarUrl: true },
|
||||
},
|
||||
},
|
||||
orderBy: { joinedAt: 'asc' },
|
||||
});
|
||||
}
|
||||
|
||||
async getGroupMessages(groupId: string, userId: string): Promise<any> {
|
||||
const member = await this.prisma.groupMember.findUnique({
|
||||
where: { groupId_userId: { groupId, userId } },
|
||||
});
|
||||
if (!member) throw new ForbiddenException('Not a member of this group');
|
||||
await this.assertCanReadGroup(groupId, userId);
|
||||
|
||||
return this.prisma.groupMessage.findMany({
|
||||
where: { groupId },
|
||||
include: { user: { select: { id: true, name: true, avatarUrl: true } } },
|
||||
orderBy: { createdAt: 'asc' },
|
||||
take: 100,
|
||||
take: 200,
|
||||
});
|
||||
}
|
||||
|
||||
async sendMessage(groupId: string, userId: string, content: string): Promise<any> {
|
||||
const member = await this.prisma.groupMember.findUnique({
|
||||
where: { groupId_userId: { groupId, userId } },
|
||||
});
|
||||
if (!member) throw new ForbiddenException('Not a member of this group');
|
||||
await this.assertCanReadGroup(groupId, userId);
|
||||
|
||||
return this.prisma.groupMessage.create({
|
||||
data: { groupId, userId, content },
|
||||
include: { user: { select: { id: true, name: true, avatarUrl: true } } },
|
||||
});
|
||||
}
|
||||
|
||||
async createInviteLink(groupId: string, userId: string): Promise<any> {
|
||||
const group = await this.prisma.courseGroup.findUnique({
|
||||
where: { id: groupId },
|
||||
include: { course: { select: { authorId: true } } },
|
||||
});
|
||||
if (!group) throw new NotFoundException('Group not found');
|
||||
if (group.course.authorId !== userId) {
|
||||
throw new ForbiddenException('Only course author can create invite links');
|
||||
}
|
||||
|
||||
const appUrl = process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3080';
|
||||
return {
|
||||
groupId,
|
||||
inviteUrl: `${appUrl}/dashboard/groups/${groupId}`,
|
||||
};
|
||||
}
|
||||
|
||||
async joinByInvite(groupId: string, userId: string): Promise<any> {
|
||||
const group = await this.prisma.courseGroup.findUnique({
|
||||
where: { id: groupId },
|
||||
include: {
|
||||
course: {
|
||||
select: { id: true, authorId: true, price: true },
|
||||
},
|
||||
},
|
||||
});
|
||||
if (!group) throw new NotFoundException('Group not found');
|
||||
|
||||
const hasEnrollment = await this.prisma.enrollment.findUnique({
|
||||
where: { userId_courseId: { userId, courseId: group.course.id } },
|
||||
});
|
||||
const hasPurchase = await this.prisma.purchase.findUnique({
|
||||
where: { userId_courseId: { userId, courseId: group.course.id } },
|
||||
});
|
||||
|
||||
if (!hasEnrollment && !hasPurchase && group.course.authorId !== userId) {
|
||||
throw new ForbiddenException('Enroll or purchase course first');
|
||||
}
|
||||
|
||||
return this.prisma.groupMember.upsert({
|
||||
where: { groupId_userId: { groupId, userId } },
|
||||
create: { groupId, userId, role: group.course.authorId === userId ? 'teacher' : 'student' },
|
||||
update: {},
|
||||
});
|
||||
}
|
||||
|
||||
async isMember(groupId: string, userId: string): Promise<boolean> {
|
||||
const member = await this.prisma.groupMember.findUnique({
|
||||
where: { groupId_userId: { groupId, userId } },
|
||||
select: { id: true },
|
||||
});
|
||||
return Boolean(member);
|
||||
}
|
||||
|
||||
private async assertCanReadGroup(groupId: string, userId: string): Promise<void> {
|
||||
const group = await this.prisma.courseGroup.findUnique({
|
||||
where: { id: groupId },
|
||||
include: {
|
||||
course: {
|
||||
select: { id: true, authorId: true },
|
||||
},
|
||||
},
|
||||
});
|
||||
if (!group) {
|
||||
throw new NotFoundException('Group not found');
|
||||
}
|
||||
|
||||
if (group.course.authorId === userId) return;
|
||||
|
||||
const member = await this.prisma.groupMember.findUnique({
|
||||
where: { groupId_userId: { groupId, userId } },
|
||||
select: { id: true },
|
||||
});
|
||||
if (member) return;
|
||||
|
||||
const enrollment = await this.prisma.enrollment.findUnique({
|
||||
where: { userId_courseId: { userId, courseId: group.course.id } },
|
||||
select: { id: true },
|
||||
});
|
||||
if (enrollment) {
|
||||
await this.prisma.groupMember.upsert({
|
||||
where: { groupId_userId: { groupId, userId } },
|
||||
create: { groupId, userId, role: 'student' },
|
||||
update: {},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
throw new ForbiddenException('No access to this group');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user