File

apps/recallassess/recallassess-api/src/api/admin/knowledge-review/services/knowledge-review-answer.service.ts

Index

Methods

Constructor

constructor(prisma: BNestPrismaService)
Parameters :
Name Type Optional
prisma BNestPrismaService No

Methods

Async addAnswer
addAnswer(data: KnowledgeReviewAnswerAddDto)
Parameters :
Name Type Optional
data KnowledgeReviewAnswerAddDto No
Private Async checkCourseEnrollments
checkCourseEnrollments(courseId: number)

Check if the associated course has enrollments

Parameters :
Name Type Optional
courseId number No
Returns : Promise<void>
Async deleteAnswer
deleteAnswer(id: number)
Parameters :
Name Type Optional
id number No
Returns : Promise<void>
Async getAnswersByQuestion
getAnswersByQuestion(questionId: number)
Parameters :
Name Type Optional
questionId number No
Async reorderAnswers
reorderAnswers(answers: literal type[])
Parameters :
Name Type Optional
answers literal type[] No
Returns : Promise<void>
Async saveAnswer
saveAnswer(id: number, data: KnowledgeReviewAnswerSaveDto)
Parameters :
Name Type Optional
id number No
data KnowledgeReviewAnswerSaveDto No
import { BNestPrismaService } from "@bish-nest/core/services/database/prisma/prisma.service";
import { BadRequestException, Injectable, NotFoundException } from "@nestjs/common";
import { plainToInstance } from "class-transformer";
import { KnowledgeReviewAnswerDto } from "../dto/quiz/knowledge-review-answer.dto";
import { KnowledgeReviewAnswerAddDto } from "../dto/quiz/knowledge-review-answer-add.dto";
import { KnowledgeReviewAnswerListDto } from "../dto/quiz/knowledge-review-answer-list.dto";
import { KnowledgeReviewAnswerSaveDto } from "../dto/quiz/knowledge-review-answer-save.dto";

@Injectable()
export class KnowledgeReviewAnswerService {
  constructor(private readonly prisma: BNestPrismaService) {}

  /**
   * Check if the associated course has enrollments
   */
  private async checkCourseEnrollments(courseId: number): Promise<void> {
    const enrollmentCount = await this.prisma.client.learningGroupParticipant.count({
      where: {
        course_id: courseId,
      },
    });

    if (enrollmentCount > 0) {
      throw new BadRequestException(
        `Cannot modify knowledge review answer. The associated course has ${enrollmentCount} enrolled participant(s). Knowledge review answers for courses with enrollments cannot be modified or deleted.`,
      );
    }
  }

  async getAnswersByQuestion(questionId: number): Promise<KnowledgeReviewAnswerListDto[]> {
    const answers = await this.prisma.client.knowledgeReviewAnswer.findMany({
      where: { knowledge_review_question_id: questionId },
      orderBy: { sort_order: "asc" },
    });
    return answers.map((answer: any) =>
      plainToInstance(KnowledgeReviewAnswerListDto, answer, { excludeExtraneousValues: true }),
    );
  }

  async addAnswer(data: KnowledgeReviewAnswerAddDto): Promise<KnowledgeReviewAnswerDto> {
    // Get the question to extract the required foreign key IDs
    const question = await this.prisma.client.knowledgeReviewQuestion.findUnique({
      where: { id: data.knowledge_review_question_id },
      include: {
        knowledgeReview: true,
        course: true,
      },
    });

    if (!question) {
      throw new Error(`Question with ID ${data.knowledge_review_question_id} not found`);
    }

    if (!question.knowledgeReview) {
      throw new Error(`Knowledge Review not found for question ${data.knowledge_review_question_id}`);
    }

    if (!question.course) {
      throw new Error(`Course not found for question ${data.knowledge_review_question_id}`);
    }

    // Check if course has enrollments before adding answer
    await this.checkCourseEnrollments(question.course_id);

    const createData = {
      course_id: question.course_id,
      knowledge_review_id: question.knowledge_review_id,
      knowledge_review_question_id: data.knowledge_review_question_id,
      answer_text: data.answer_text,
      is_correct: data.is_correct ?? false,
      sort_order: data.sort_order ?? 0,
      explanation: data.explanation ?? null,
    };

    // Create the answer with required fields
    const answer = await this.prisma.client.knowledgeReviewAnswer.create({
      data: createData,
    });

    // const answer = {
    //   id: 1,
    //   course_id: question.course_id,
    //   knowledge_review_id: question.knowledge_review_id,
    //   knowledge_review_question_id: data.knowledge_review_question_id,
    //   answer_text: data.answer_text,
    //   is_correct: data.is_correct ?? false,
    //   sort_order: data.sort_order ?? 0,
    // };
    return plainToInstance(KnowledgeReviewAnswerDto, answer, { excludeExtraneousValues: true });
  }

  async saveAnswer(id: number, data: KnowledgeReviewAnswerSaveDto): Promise<KnowledgeReviewAnswerDto> {
    const existingAnswer = await this.prisma.client.knowledgeReviewAnswer.findUnique({
      where: { id },
    });

    if (!existingAnswer) {
      throw new NotFoundException(`Knowledge review answer with ID ${id} not found`);
    }

    // Check if course has enrollments before saving
    await this.checkCourseEnrollments(existingAnswer.course_id);

    const answer = await this.prisma.client.knowledgeReviewAnswer.update({
      where: { id },
      data: {
        answer_text: data.answer_text,
        is_correct: data.is_correct,
        sort_order: data.sort_order,
        explanation: data.explanation,
      },
    });

    return plainToInstance(KnowledgeReviewAnswerDto, answer, { excludeExtraneousValues: true });
  }

  async deleteAnswer(id: number): Promise<void> {
    const existingAnswer = await this.prisma.client.knowledgeReviewAnswer.findUnique({
      where: { id },
    });

    if (!existingAnswer) {
      throw new NotFoundException(`Knowledge review answer with ID ${id} not found`);
    }

    // Check if course has enrollments before deleting
    await this.checkCourseEnrollments(existingAnswer.course_id);

    await this.prisma.client.knowledgeReviewAnswer.delete({
      where: { id },
    });
  }

  async reorderAnswers(answers: { id: number; sort_order: number }[]): Promise<void> {
    // Check enrollments for all answers being reordered
    if (answers.length > 0) {
      const firstAnswer = await this.prisma.client.knowledgeReviewAnswer.findUnique({
        where: { id: answers[0].id },
      });

      if (firstAnswer) {
        await this.checkCourseEnrollments(firstAnswer.course_id);
      }
    }

    const updatePromises = answers.map((answer) =>
      this.prisma.client.knowledgeReviewAnswer.update({
        where: { id: answer.id },
        data: { sort_order: answer.sort_order },
      }),
    );

    await Promise.all(updatePromises);
  }
}

results matching ""

    No results matching ""