import { NextResponse } from 'next/server' import prisma from '@/lib/prisma' import { getAuthUser } from '@/lib/auth' import { createCollectionSchema, updateCollectionSchema, parseBody } from '@/lib/validations' import { checkRateLimit, getClientIdentifier, getRateLimitHeaders } from '@/lib/rate-limit' import type { Prisma } from '@prisma/client' export const dynamic = 'force-dynamic' // Get user's collections — with pagination export async function GET(req: Request) { try { const { searchParams } = new URL(req.url) const userId = searchParams.get('userId') const isPublic = searchParams.get('public') === 'true' const limit = Math.min(parseInt(searchParams.get('limit') || '20'), 100) const offset = Math.max(parseInt(searchParams.get('offset') || '0'), 0) if (!userId) { return NextResponse.json([], { status: 200 }) } const where: Prisma.CollectionWhereInput = { userId } if (isPublic) { where.isPublic = true } const [collections, total] = await Promise.all([ prisma.collection.findMany({ where, include: { prompts: { include: { prompt: { select: { id: true, slug: true, title: true, description: true, category: true, }, }, }, }, user: { select: { name: true, username: true, image: true, }, }, }, orderBy: { updatedAt: 'desc' }, take: limit, skip: offset, }), prisma.collection.count({ where }), ]) return NextResponse.json({ collections, total, hasMore: offset + collections.length < total }) } catch (error) { console.error('Get collections error:', error) return NextResponse.json( { error: 'Failed to fetch collections' }, { status: 500 } ) } } // Create new collection — requires auth export async function POST(req: Request) { try { const authUser = await getAuthUser() if (!authUser) { return NextResponse.json({ error: 'Authentication required' }, { status: 401 }) } // Rate limit const identifier = getClientIdentifier(req, authUser.id) const rateLimit = await checkRateLimit(`collections:${identifier}`, true) if (!rateLimit.success) { return NextResponse.json({ error: rateLimit.error }, { status: 429 }) } const body = await req.json() const parsed = parseBody(createCollectionSchema, body) if (!parsed.success) return parsed.response const { name, description, isPublic } = parsed.data const collection = await prisma.collection.create({ data: { name, description: description || null, userId: authUser.id, isPublic: isPublic || false, }, }) return NextResponse.json(collection) } catch (error) { console.error('Create collection error:', error) return NextResponse.json( { error: 'Failed to create collection' }, { status: 500 } ) } } // Update collection — requires auth + ownership export async function PATCH(req: Request) { try { const authUser = await getAuthUser() if (!authUser) { return NextResponse.json({ error: 'Authentication required' }, { status: 401 }) } const body = await req.json() const parsed = parseBody(updateCollectionSchema, body) if (!parsed.success) return parsed.response const { id, name, description, isPublic } = parsed.data // Verify ownership const existing = await prisma.collection.findUnique({ where: { id }, select: { userId: true }, }) if (!existing || existing.userId !== authUser.id) { return NextResponse.json({ error: 'Not found or not authorized' }, { status: 403 }) } const collection = await prisma.collection.update({ where: { id }, data: { ...(name && { name }), ...(description !== undefined && { description }), ...(isPublic !== undefined && { isPublic }), }, }) return NextResponse.json(collection) } catch (error) { console.error('Update collection error:', error) return NextResponse.json( { error: 'Failed to update collection' }, { status: 500 } ) } } // Delete collection — requires auth + ownership export async function DELETE(req: Request) { try { const authUser = await getAuthUser() if (!authUser) { return NextResponse.json({ error: 'Authentication required' }, { status: 401 }) } const { searchParams } = new URL(req.url) const id = searchParams.get('id') if (!id) { return NextResponse.json( { error: 'Collection ID is required' }, { status: 400 } ) } // Verify ownership const existing = await prisma.collection.findUnique({ where: { id }, select: { userId: true }, }) if (!existing || existing.userId !== authUser.id) { return NextResponse.json({ error: 'Not found or not authorized' }, { status: 403 }) } await prisma.collection.delete({ where: { id } }) return NextResponse.json({ success: true }) } catch (error) { console.error('Delete collection error:', error) return NextResponse.json( { error: 'Failed to delete collection' }, { status: 500 } ) } }