Cool Clicker

Tasting Resting besting testing lorem ipsum newsome
Cool Clicker
import { NextRequest, NextResponse } from 'next/server'
import { getServerSession } from 'next-auth'
import { authOptions } from '@/lib/auth'
import { prisma } from '@/lib/prisma'
import { z } from 'zod'
import { checkCourseUnlockViaLessons } from '@/lib/course-access'

export const dynamic = 'force-dynamic'

// Validation schemas
const paramsSchema = z.object({
  id: z.string().uuid('Invalid resource ID')
})

interface RouteParams {
  params: Promise<{ id: string }>
}

/**
 * GET /api/resources/[id]/lessons - Get all lessons that use this resource
 */
export async function GET(
  request: NextRequest,
  { params }: RouteParams
) {
  try {
    const session = await getServerSession(authOptions)
    const resolvedParams = await params
    const paramsResult = paramsSchema.safeParse(resolvedParams)

    if (!paramsResult.success) {
      return NextResponse.json(
        { error: 'Invalid resource ID' },
        { status: 400 }
      )
    }

    const { id } = paramsResult.data

    // Check if resource exists
    const resource = await prisma.resource.findUnique({
      where: { id },
      select: { 
        id: true,
        userId: true,
        price: true,
        noteId: true,
        createdAt: true,
        user: {
          select: {
            id: true,
            username: true,
            pubkey: true,
            lud16: true,
          }
        }
      }
    })

    if (!resource) {
      return NextResponse.json(
        { error: 'Resource not found' },
        { status: 404 }
      )
    }

    // Fetch lessons that use this resource
    const lessons = await prisma.lesson.findMany({
      where: { resourceId: id },
      include: {
        course: {
          select: {
            id: true,
            userId: true,
            price: true,
            noteId: true,
          }
        }
      },
      orderBy: [
        { courseId: 'asc' },
        { index: 'asc' }
      ]
    })

    // Check access permissions for paid content
    const isOwner = session?.user?.id === resource.userId
    const isPaidResource = resource.price > 0

    if (isPaidResource && !isOwner) {
      let hasAccess = false

      if (session?.user?.id) {
        const hasPurchasedResource = await prisma.purchase.findFirst({
          where: {
            userId: session.user.id,
            resourceId: id,
            amountPaid: { gte: resource.price }
          }
        })

        const courseAccess = await checkCourseUnlockViaLessons({
          userId: session.user.id,
          resourceId: id,
          lessons
        })

        hasAccess = Boolean(hasPurchasedResource) || courseAccess.unlockedViaCourse
      }

      if (!hasAccess) {
        return NextResponse.json({
          success: true,
          data: {
            id: resource.id,
            price: resource.price,
            noteId: resource.noteId,
            createdAt: resource.createdAt,
            user: resource.user,
            isPaid: true,
            requiresPurchase: true,
            unlockedViaCourse: false,
            unlockingCourseId: null,
          }
        })
      }
    }

    // Group lessons by course for better organization
    const lessonsByCourse = lessons.reduce((acc, lesson) => {
      if (!lesson.course) return acc
      
      const courseId = lesson.course.id
      if (!acc[courseId]) {
        acc[courseId] = {
          course: lesson.course,
          lessons: []
        }
      }
      
      acc[courseId].lessons.push({
        id: lesson.id,
        index: lesson.index,
        createdAt: lesson.createdAt,
        updatedAt: lesson.updatedAt,
      })
      
      return acc
    }, {} as Record<string, {
      course: {
        id: string
        userId: string
        price: number
        noteId: string | null
      },
      lessons: Array<{
        id: string
        index: number
        createdAt: Date
        updatedAt: Date
      }>
    }>)

    return NextResponse.json({
      success: true,
      data: {
        resourceId: id,
        lessonCount: lessons.length,
        courses: Object.values(lessonsByCourse),
        lessons: lessons.map(lesson => ({
          id: lesson.id,
          courseId: lesson.courseId,
          index: lesson.index,
          createdAt: lesson.createdAt,
          updatedAt: lesson.updatedAt,
        }))
      }
    })
  } catch (error) {
    console.error('Failed to fetch resource lessons:', error)
    return NextResponse.json(
      { error: 'Failed to fetch resource lessons' },
      { status: 500 }
    )
  }
}

No comments yet.