import { prisma } from '../config/database'; import { Prisma } from '@prisma/client'; import { config } from '../config'; import { logger } from '../config/logger'; import { listCourseResponse, getCourseResponse } from '../types/courses.types'; import { UnauthorizedError, ValidationError, ForbiddenError } from '../middleware/errorHandler'; import { getPresignedUrl } from '../config/minio'; export class CoursesService { async ListCourses(category_id?: number): Promise { try { const where: Prisma.CourseWhereInput = { status: 'APPROVED', }; if (category_id) { where.category_id = category_id; } const courses = await prisma.course.findMany({ where }); // Generate presigned URLs for thumbnails const coursesWithUrls = await Promise.all( courses.map(async (course) => { let thumbnail_presigned_url: string | null = null; if (course.thumbnail_url) { try { thumbnail_presigned_url = await getPresignedUrl(course.thumbnail_url, 3600); } catch (err) { logger.warn(`Failed to generate presigned URL for thumbnail: ${err}`); } } return { ...course, thumbnail_url: thumbnail_presigned_url, }; }) ); return { code: 200, message: 'Courses fetched successfully', total: coursesWithUrls.length, data: coursesWithUrls, }; } catch (error) { logger.error('Failed to fetch courses', { error }); throw error; } } async GetCourseById(id: number): Promise { try { const course = await prisma.course.findFirst({ where: { id, status: 'APPROVED' // Only show approved courses to students } }); if (!course) { return { code: 200, message: 'no Course fetched successfully', data: null, }; } // Generate presigned URL for thumbnail let thumbnail_presigned_url: string | null = null; if (course.thumbnail_url) { try { thumbnail_presigned_url = await getPresignedUrl(course.thumbnail_url, 3600); } catch (err) { logger.warn(`Failed to generate presigned URL for thumbnail: ${err}`); } } return { code: 200, message: 'Course fetched successfully', data: { ...course, thumbnail_url: thumbnail_presigned_url, }, }; } catch (error) { logger.error('Failed to fetch course', { error }); throw error; } } }