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

@ -18,7 +18,7 @@ export class RecommendedCoursesService {
/**
* List all approved courses (for admin to manage recommendations)
*/
static async listApprovedCourses(): Promise<ListApprovedCoursesResponse> {
static async listApprovedCourses(token: string): Promise<ListApprovedCoursesResponse> {
try {
const courses = await prisma.course.findMany({
where: { status: 'APPROVED' },
@ -94,6 +94,19 @@ export class RecommendedCoursesService {
};
} catch (error) {
logger.error('Failed to list approved courses', { error });
const decoded = jwt.decode(token) as { id: number } | null;
if (decoded?.id) {
await auditService.logSync({
userId: decoded.id,
action: AuditAction.ERROR,
entityType: 'RecommendedCourses',
entityId: 0,
metadata: {
operation: 'list_approved_courses',
error: error instanceof Error ? error.message : String(error)
}
});
}
throw error;
}
}
@ -101,7 +114,7 @@ export class RecommendedCoursesService {
/**
* Get course by ID (for admin to view details)
*/
static async getCourseById(courseId: number): Promise<GetCourseByIdResponse> {
static async getCourseById(token: string, courseId: number): Promise<GetCourseByIdResponse> {
try {
const course = await prisma.course.findUnique({
where: { id: courseId },
@ -179,6 +192,19 @@ export class RecommendedCoursesService {
};
} catch (error) {
logger.error('Failed to get course by ID', { error });
const decoded = jwt.decode(token) as { id: number } | null;
if (decoded?.id) {
await auditService.logSync({
userId: decoded.id,
action: AuditAction.ERROR,
entityType: 'RecommendedCourses',
entityId: 0,
metadata: {
operation: 'get_course_by_id',
error: error instanceof Error ? error.message : String(error)
}
});
}
throw error;
}
}
@ -229,6 +255,17 @@ export class RecommendedCoursesService {
};
} catch (error) {
logger.error('Failed to toggle recommended status', { error });
const decoded = jwt.decode(token) as { id: number } | null;
await auditService.logSync({
userId: decoded?.id || 0,
action: AuditAction.ERROR,
entityType: 'RecommendedCourses',
entityId: courseId,
metadata: {
operation: 'toggle_recommended',
error: error instanceof Error ? error.message : String(error)
}
});
throw error;
}
}