feat: Allow instructors to set rejected courses to draft and explicitly set course status to rejected upon administrative rejection.
All checks were successful
Build and Deploy Backend / Build Backend Docker Image (push) Successful in 30s
Build and Deploy Backend / Deploy E-learning Backend to Dev Server (push) Successful in 3s
Build and Deploy Backend / Notify Deployment Status (push) Successful in 1s
Build and Deploy Frontend Management to Dev Server / Build Frontend Management Docker Image (push) Successful in 18s
Build and Deploy Frontend Management to Dev Server / Deploy E-learning Frontend Management to Dev Server (push) Successful in 3s
Build and Deploy Frontend Management to Dev Server / Notify Deployment Status (push) Successful in 1s
All checks were successful
Build and Deploy Backend / Build Backend Docker Image (push) Successful in 30s
Build and Deploy Backend / Deploy E-learning Backend to Dev Server (push) Successful in 3s
Build and Deploy Backend / Notify Deployment Status (push) Successful in 1s
Build and Deploy Frontend Management to Dev Server / Build Frontend Management Docker Image (push) Successful in 18s
Build and Deploy Frontend Management to Dev Server / Deploy E-learning Frontend Management to Dev Server (push) Successful in 3s
Build and Deploy Frontend Management to Dev Server / Notify Deployment Status (push) Successful in 1s
This commit is contained in:
parent
8c40549766
commit
8edc3770eb
4 changed files with 55 additions and 4 deletions
|
|
@ -21,6 +21,7 @@ import {
|
||||||
GetQuizAttemptDetailResponse,
|
GetQuizAttemptDetailResponse,
|
||||||
GetEnrolledStudentDetailResponse,
|
GetEnrolledStudentDetailResponse,
|
||||||
GetCourseApprovalHistoryResponse,
|
GetCourseApprovalHistoryResponse,
|
||||||
|
setCourseDraftResponse,
|
||||||
} from '../types/CoursesInstructor.types';
|
} from '../types/CoursesInstructor.types';
|
||||||
import { CreateCourseValidator } from "../validators/CoursesInstructor.validator";
|
import { CreateCourseValidator } from "../validators/CoursesInstructor.validator";
|
||||||
|
|
||||||
|
|
@ -189,6 +190,22 @@ export class CoursesInstructorController {
|
||||||
return await CoursesInstructorService.sendCourseForReview({ token, course_id: courseId });
|
return await CoursesInstructorService.sendCourseForReview({ token, course_id: courseId });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ตั้งค่าคอร์สเป็น DRAFT
|
||||||
|
* Set course to draft
|
||||||
|
* @param courseId - รหัสคอร์ส / Course ID
|
||||||
|
*/
|
||||||
|
@Post('set-draft/{courseId}')
|
||||||
|
@Security('jwt', ['instructor'])
|
||||||
|
@SuccessResponse('200', 'Course set to draft successfully')
|
||||||
|
@Response('401', 'Invalid or expired token')
|
||||||
|
@Response('404', 'Course not found')
|
||||||
|
public async setCourseDraft(@Request() request: any, @Path() courseId: number): Promise<setCourseDraftResponse> {
|
||||||
|
const token = request.headers.authorization?.replace('Bearer ', '');
|
||||||
|
if (!token) throw new ValidationError('No token provided')
|
||||||
|
return await CoursesInstructorService.setCourseDraft({ token, course_id: courseId });
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ดึงประวัติการส่งอนุมัติคอร์สทั้งหมด
|
* ดึงประวัติการส่งอนุมัติคอร์สทั้งหมด
|
||||||
* Get all course approval history
|
* Get all course approval history
|
||||||
|
|
|
||||||
|
|
@ -300,11 +300,11 @@ export class AdminCourseApprovalService {
|
||||||
}
|
}
|
||||||
|
|
||||||
await prisma.$transaction([
|
await prisma.$transaction([
|
||||||
// Update course status back to DRAFT
|
// Update course status back to REJECTED
|
||||||
prisma.course.update({
|
prisma.course.update({
|
||||||
where: { id: courseId },
|
where: { id: courseId },
|
||||||
data: {
|
data: {
|
||||||
status: 'DRAFT',
|
status: 'REJECTED',
|
||||||
rejection_reason: comment,
|
rejection_reason: comment,
|
||||||
approved_by: null,
|
approved_by: null,
|
||||||
approved_at: null
|
approved_at: null
|
||||||
|
|
@ -318,7 +318,7 @@ export class AdminCourseApprovalService {
|
||||||
reviewed_by: decoded.id,
|
reviewed_by: decoded.id,
|
||||||
action: 'REJECTED',
|
action: 'REJECTED',
|
||||||
previous_status: course.status,
|
previous_status: course.status,
|
||||||
new_status: 'DRAFT',
|
new_status: 'REJECTED',
|
||||||
comment: comment
|
comment: comment
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -331,7 +331,7 @@ export class AdminCourseApprovalService {
|
||||||
entityType: 'Course',
|
entityType: 'Course',
|
||||||
entityId: courseId,
|
entityId: courseId,
|
||||||
oldValue: { status: 'PENDING' },
|
oldValue: { status: 'PENDING' },
|
||||||
newValue: { status: 'DRAFT' },
|
newValue: { status: 'REJECTED' },
|
||||||
metadata: { comment: comment }
|
metadata: { comment: comment }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,8 @@ import {
|
||||||
GetEnrolledStudentDetailInput,
|
GetEnrolledStudentDetailInput,
|
||||||
GetEnrolledStudentDetailResponse,
|
GetEnrolledStudentDetailResponse,
|
||||||
GetCourseApprovalHistoryResponse,
|
GetCourseApprovalHistoryResponse,
|
||||||
|
setCourseDraft,
|
||||||
|
setCourseDraftResponse,
|
||||||
} from "../types/CoursesInstructor.types";
|
} from "../types/CoursesInstructor.types";
|
||||||
import { auditService } from './audit.service';
|
import { auditService } from './audit.service';
|
||||||
import { AuditAction } from '@prisma/client';
|
import { AuditAction } from '@prisma/client';
|
||||||
|
|
@ -327,6 +329,28 @@ export class CoursesInstructorService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async setCourseDraft(setCourseDraft: setCourseDraft): Promise<setCourseDraftResponse> {
|
||||||
|
try {
|
||||||
|
await this.validateCourseInstructor(setCourseDraft.token, setCourseDraft.course_id);
|
||||||
|
await prisma.course.update({
|
||||||
|
where: {
|
||||||
|
id: setCourseDraft.course_id,
|
||||||
|
status: 'REJECTED'
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
status: 'DRAFT'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
message: 'Set course to draft successfully',
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('Failed to set course to draft', { error });
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static async getCourseApprovals(token: string, courseId: number): Promise<{
|
static async getCourseApprovals(token: string, courseId: number): Promise<{
|
||||||
code: number;
|
code: number;
|
||||||
message: string;
|
message: string;
|
||||||
|
|
|
||||||
|
|
@ -171,6 +171,16 @@ export interface sendCourseForReview {
|
||||||
course_id: number;
|
course_id: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface setCourseDraft {
|
||||||
|
token: string;
|
||||||
|
course_id: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface setCourseDraftResponse {
|
||||||
|
code: number;
|
||||||
|
message: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface CourseApprovalData {
|
export interface CourseApprovalData {
|
||||||
id: number;
|
id: number;
|
||||||
course_id: number;
|
course_id: number;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue