feat: Add token-based authorization to category deletion and enhance user registration with error handling and audit logging.

This commit is contained in:
JakkrapartXD 2026-02-12 17:55:45 +07:00
parent 45941fbe6c
commit af14610442
16 changed files with 1003 additions and 236 deletions

View file

@ -347,6 +347,15 @@ export class CoursesInstructorService {
id: courseId
}
});
await auditService.logSync({
userId: courseInstructorId.user_id,
action: AuditAction.DELETE,
entityType: 'Course',
entityId: courseId,
metadata: {
operation: 'delete_course'
}
});
return {
code: 200,
message: 'Course deleted successfully',
@ -386,6 +395,15 @@ export class CoursesInstructorService {
status: 'PENDING'
}
});
await auditService.logSync({
userId: decoded.id,
action: AuditAction.UPDATE,
entityType: 'Course',
entityId: sendCourseForReview.course_id,
metadata: {
operation: 'send_course_for_review'
}
});
return {
code: 200,
message: 'Course sent for review successfully',
@ -447,8 +465,6 @@ export class CoursesInstructorService {
total: number;
}> {
try {
const decoded = jwt.verify(token, config.jwt.secret) as { id: number; type: string };
// Validate instructor access
await this.validateCourseInstructor(token, courseId);
@ -601,6 +617,18 @@ export class CoursesInstructorService {
}
});
const decoded = jwt.decode(addinstructorCourse.token) as { id: number } | null;
await auditService.logSync({
userId: decoded?.id || 0,
action: AuditAction.CREATE,
entityType: 'Course',
entityId: addinstructorCourse.course_id,
metadata: {
operation: 'add_instructor_to_course',
instructor_id: user.id,
}
});
return {
code: 200,
message: 'Instructor added to course successfully',
@ -633,6 +661,19 @@ export class CoursesInstructorService {
},
}
});
await auditService.logSync({
userId: decoded?.id || 0,
action: AuditAction.DELETE,
entityType: 'Course',
entityId: removeinstructorCourse.course_id,
metadata: {
operation: 'remove_instructor_from_course',
instructor_id: removeinstructorCourse.user_id,
course_id: removeinstructorCourse.course_id,
}
});
return {
code: 200,
message: 'Instructor removed from course successfully',
@ -729,6 +770,19 @@ export class CoursesInstructorService {
is_primary: true,
}
});
await auditService.logSync({
userId: decoded?.id || 0,
action: AuditAction.UPDATE,
entityType: 'Course',
entityId: setprimaryCourseInstructor.course_id,
metadata: {
operation: 'set_primary_instructor',
instructor_id: setprimaryCourseInstructor.user_id,
course_id: setprimaryCourseInstructor.course_id,
}
});
return {
code: 200,
message: 'Primary instructor set successfully',
@ -784,7 +838,6 @@ export class CoursesInstructorService {
static async getEnrolledStudents(input: GetEnrolledStudentsInput): Promise<GetEnrolledStudentsResponse> {
try {
const { token, course_id, page = 1, limit = 20, search, status } = input;
const decoded = jwt.verify(token, config.jwt.secret) as { id: number };
// Validate instructor
await this.validateCourseInstructor(token, course_id);
@ -1062,7 +1115,6 @@ export class CoursesInstructorService {
static async getQuizAttemptDetail(input: GetQuizAttemptDetailInput): Promise<GetQuizAttemptDetailResponse> {
try {
const { token, course_id, lesson_id, student_id } = input;
const decoded = jwt.verify(token, config.jwt.secret) as { id: number };
// Validate instructor
await this.validateCourseInstructor(token, course_id);