// app/api/playlists/route.ts import { NextResponse } from "next/server"; import { getServerSession } from "next-auth"; import { authOptions } from "@/lib/auth-options"; import { prisma } from "@/lib/prisma"; type VideoWithCourses = { videoCourses?: Array<{ courseId: string; exclusive: boolean }> }; function mapRestrictedCourseIds(video: VideoWithCourses) { if (!video?.videoCourses?.length) return []; return video.videoCourses .filter((assignment) => assignment.exclusive) .map((assignment) => assignment.courseId); } function filterRestrictedVideos(videos: any[], userCourseIds: string[]) { return videos .filter((video) => { const restrictedCourseIds = mapRestrictedCourseIds(video); if (restrictedCourseIds.length === 0) return true; return restrictedCourseIds.some((courseId: string) => userCourseIds.includes(courseId) ); }) .map((video) => ({ ...video, restrictedCourseIds: mapRestrictedCourseIds(video), })); } export async function GET(req: Request) { const session = await getServerSession(authOptions); if (!session?.user?.email) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } const user = await prisma.user.findUnique({ where: { email: session.user.email }, include: { enrollments: { include: { course: true }, }, }, }); const courseIds = user?.enrollments.map((e) => e.courseId) ?? []; // Get playlists directly assigned to enrolled courses const coursesWithPlaylists = await prisma.course.findMany({ where: { id: { in: courseIds } }, include: { playlists: { include: { videos: { include: { uploader: { select: { id: true, name: true, image: true, }, }, videoCourses: true, }, orderBy: { index: "asc" }, }, courses: { include: { course: true }, }, }, orderBy: { sortOrder: "asc" }, }, }, orderBy: { title: "asc" }, }); // Also get playlists assigned to courses via CoursePlaylist mapping const additionalPlaylists = await prisma.coursePlaylist.findMany({ where: { courseId: { in: courseIds } }, include: { playlist: { include: { videos: { include: { uploader: { select: { id: true, name: true, image: true, }, }, videoCourses: true, }, orderBy: { index: "asc" }, }, courses: { include: { course: true }, }, }, }, course: true, }, }); // Merge results: add additional playlists to their respective courses const playlistMap = new Map(); additionalPlaylists.forEach(({ course, playlist }) => { if (!playlistMap.has(course.id)) { playlistMap.set(course.id, []); } playlist.videos = filterRestrictedVideos(playlist.videos, courseIds); playlistMap.get(course.id).push(playlist); }); coursesWithPlaylists.forEach((course) => { course.playlists.forEach((playlist) => { playlist.videos = filterRestrictedVideos(playlist.videos, courseIds); }); const additional = playlistMap.get(course.id) || []; const existingIds = new Set(course.playlists.map((p) => p.id)); const newPlaylists = additional.filter((p: any) => !existingIds.has(p.id)); newPlaylists.forEach((playlist: any) => { playlist.videos = filterRestrictedVideos(playlist.videos, courseIds); }); course.playlists.push(...newPlaylists); course.playlists.sort((a, b) => a.sortOrder - b.sortOrder); }); return NextResponse.json({ subjects: coursesWithPlaylists }); }