feat: add course approval history endpoint for instructors to view rejection reasons and approval timeline

This commit is contained in:
JakkrapartXD 2026-02-06 14:52:10 +07:00
parent 11c747edab
commit 832a8f5067
3 changed files with 106 additions and 0 deletions

View file

@ -32,6 +32,7 @@ import {
GetQuizAttemptDetailResponse,
GetEnrolledStudentDetailInput,
GetEnrolledStudentDetailResponse,
GetCourseApprovalHistoryResponse,
} from "../types/CoursesInstructor.types";
import { auditService } from './audit.service';
import { AuditAction } from '@prisma/client';
@ -1103,4 +1104,60 @@ export class CoursesInstructorService {
throw error;
}
}
/**
*
* Get course approval history for instructor to see rejection reasons
*/
static async getCourseApprovalHistory(token: string, courseId: number): Promise<GetCourseApprovalHistoryResponse> {
try {
const decoded = jwt.verify(token, config.jwt.secret) as { id: number };
// Validate instructor access
await this.validateCourseInstructor(token, courseId);
// Get course with approval history
const course = await prisma.course.findUnique({
where: { id: courseId },
include: {
courseApprovals: {
orderBy: { created_at: 'desc' },
include: {
submitter: {
select: { id: true, username: true, email: true }
},
reviewer: {
select: { id: true, username: true, email: true }
}
}
}
}
});
if (!course) {
throw new NotFoundError('Course not found');
}
return {
code: 200,
message: 'Course approval history retrieved successfully',
data: {
course_id: course.id,
course_title: course.title as { th: string; en: string },
current_status: course.status,
approval_history: course.courseApprovals.map(a => ({
id: a.id,
action: a.action,
comment: a.comment,
created_at: a.created_at,
submitter: a.submitter,
reviewer: a.reviewer
}))
}
};
} catch (error) {
logger.error(`Error getting course approval history: ${error}`);
throw error;
}
}
}