project init
This commit is contained in:
141
apps/api/src/courses/lessons.service.ts
Normal file
141
apps/api/src/courses/lessons.service.ts
Normal file
@ -0,0 +1,141 @@
|
||||
import { Injectable, NotFoundException, ForbiddenException } from '@nestjs/common';
|
||||
import { PrismaService } from '../common/prisma/prisma.service';
|
||||
import { Lesson } from '@coursecraft/database';
|
||||
import { CoursesService } from './courses.service';
|
||||
import { ChaptersService } from './chapters.service';
|
||||
import { CreateLessonDto } from './dto/create-lesson.dto';
|
||||
import { UpdateLessonDto } from './dto/update-lesson.dto';
|
||||
|
||||
@Injectable()
|
||||
export class LessonsService {
|
||||
constructor(
|
||||
private prisma: PrismaService,
|
||||
private coursesService: CoursesService,
|
||||
private chaptersService: ChaptersService
|
||||
) {}
|
||||
|
||||
async create(chapterId: string, userId: string, dto: CreateLessonDto): Promise<Lesson> {
|
||||
const chapter = await this.chaptersService.findById(chapterId);
|
||||
if (!chapter) {
|
||||
throw new NotFoundException('Chapter not found');
|
||||
}
|
||||
|
||||
const isOwner = await this.coursesService.checkOwnership(chapter.courseId, userId);
|
||||
if (!isOwner) {
|
||||
throw new ForbiddenException('You can only edit your own courses');
|
||||
}
|
||||
|
||||
// Get max order
|
||||
const maxOrder = await this.prisma.lesson.aggregate({
|
||||
where: { chapterId },
|
||||
_max: { order: true },
|
||||
});
|
||||
|
||||
const order = (maxOrder._max.order ?? -1) + 1;
|
||||
|
||||
return this.prisma.lesson.create({
|
||||
data: {
|
||||
chapterId,
|
||||
title: dto.title,
|
||||
content: dto.content as any,
|
||||
order,
|
||||
durationMinutes: dto.durationMinutes,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async findById(id: string): Promise<Lesson | null> {
|
||||
return this.prisma.lesson.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
chapter: {
|
||||
select: {
|
||||
id: true,
|
||||
title: true,
|
||||
courseId: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async update(lessonId: string, userId: string, dto: UpdateLessonDto): Promise<Lesson> {
|
||||
const lesson = await this.prisma.lesson.findUnique({
|
||||
where: { id: lessonId },
|
||||
include: {
|
||||
chapter: {
|
||||
select: { courseId: true },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!lesson) {
|
||||
throw new NotFoundException('Lesson not found');
|
||||
}
|
||||
|
||||
const isOwner = await this.coursesService.checkOwnership(lesson.chapter.courseId, userId);
|
||||
if (!isOwner) {
|
||||
throw new ForbiddenException('You can only edit your own courses');
|
||||
}
|
||||
|
||||
return this.prisma.lesson.update({
|
||||
where: { id: lessonId },
|
||||
data: {
|
||||
title: dto.title,
|
||||
content: dto.content as any,
|
||||
durationMinutes: dto.durationMinutes,
|
||||
videoUrl: dto.videoUrl,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async delete(lessonId: string, userId: string): Promise<void> {
|
||||
const lesson = await this.prisma.lesson.findUnique({
|
||||
where: { id: lessonId },
|
||||
include: {
|
||||
chapter: {
|
||||
select: { courseId: true },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!lesson) {
|
||||
throw new NotFoundException('Lesson not found');
|
||||
}
|
||||
|
||||
const isOwner = await this.coursesService.checkOwnership(lesson.chapter.courseId, userId);
|
||||
if (!isOwner) {
|
||||
throw new ForbiddenException('You can only edit your own courses');
|
||||
}
|
||||
|
||||
await this.prisma.lesson.delete({
|
||||
where: { id: lessonId },
|
||||
});
|
||||
}
|
||||
|
||||
async reorder(chapterId: string, userId: string, lessonIds: string[]): Promise<Lesson[]> {
|
||||
const chapter = await this.chaptersService.findById(chapterId);
|
||||
if (!chapter) {
|
||||
throw new NotFoundException('Chapter not found');
|
||||
}
|
||||
|
||||
const isOwner = await this.coursesService.checkOwnership(chapter.courseId, userId);
|
||||
if (!isOwner) {
|
||||
throw new ForbiddenException('You can only edit your own courses');
|
||||
}
|
||||
|
||||
await Promise.all(
|
||||
lessonIds.map((id, index) =>
|
||||
this.prisma.lesson.update({
|
||||
where: { id },
|
||||
data: { order: index },
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
return this.prisma.lesson.findMany({
|
||||
where: { chapterId },
|
||||
orderBy: { order: 'asc' },
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user