File

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

Index

Methods

Constructor

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

Methods

Async addAnswer
addAnswer(createAnswerDto: AssessmentAnswerAddDto)
Parameters :
Name Type Optional
createAnswerDto AssessmentAnswerAddDto 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, courseId: number, assessmentId: number)
Parameters :
Name Type Optional
questionId number No
courseId number No
assessmentId number No
Async reorderAnswers
reorderAnswers(answers: literal type[])
Parameters :
Name Type Optional
answers literal type[] No
Returns : Promise<void>
Async saveAnswer
saveAnswer(id: number, updateAnswerDto: AssessmentAnswerSaveDto)
Parameters :
Name Type Optional
id number No
updateAnswerDto AssessmentAnswerSaveDto 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 { AssessmentAnswerDto } from "../dto/quiz/assessment-answer.dto";
import { AssessmentAnswerAddDto } from "../dto/quiz/assessment-answer-create.dto";
import { AssessmentAnswerListDto } from "../dto/quiz/assessment-answer-list.dto";
import { AssessmentAnswerSaveDto } from "../dto/quiz/assessment-answer-update.dto";

@Injectable()
export class AssessmentAnswerService {
  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 assessment answer. The associated course has ${enrollmentCount} enrolled participant(s). Assessment answers for courses with enrollments cannot be modified or deleted.`,
      );
    }
  }

  async getAnswersByQuestion(
    questionId: number,
    courseId: number,
    assessmentId: number,
  ): Promise<AssessmentAnswerListDto[]> {
    const answers = await this.prisma.client.assessmentAnswer.findMany({
      where: {
        assessment_question_id: questionId,
        course_id: courseId,
        assessment_id: assessmentId,
      },
      orderBy: { sort_order: "asc" },
    });

    return plainToInstance(AssessmentAnswerListDto, answers, { excludeExtraneousValues: true });
  }

  async addAnswer(createAnswerDto: AssessmentAnswerAddDto): Promise<AssessmentAnswerDto> {
    // Check if course has enrollments before adding answer
    if (createAnswerDto.course_id) {
      await this.checkCourseEnrollments(createAnswerDto.course_id);
    }

    const answer = await this.prisma.client.assessmentAnswer.create({
      data: {
        course_id: createAnswerDto.course_id,
        assessment_id: createAnswerDto.assessment_id,
        assessment_question_id: createAnswerDto.assessment_question_id,
        answer_text: createAnswerDto.answer_text,
        answer_level: createAnswerDto.answer_level,
        sort_order: createAnswerDto.sort_order ?? 0,
      },
    });

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

  async saveAnswer(id: number, updateAnswerDto: AssessmentAnswerSaveDto): Promise<AssessmentAnswerDto> {
    const existingAnswer = await this.prisma.client.assessmentAnswer.findUnique({
      where: { id },
    });

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

    // Allow editing answer text/metadata even when course has enrollments.

    const answer = await this.prisma.client.assessmentAnswer.update({
      where: { id },
      data: {
        answer_text: updateAnswerDto.answer_text,
        answer_level: updateAnswerDto.answer_level,
        sort_order: updateAnswerDto.sort_order,
      },
    });

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

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

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

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

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

  async reorderAnswers(answers: { id: number; sort_order: number }[]): Promise<void> {
    // Reordering answer sort order is allowed even when course has enrollments.

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

    await Promise.all(updatePromises);
  }
}

results matching ""

    No results matching ""