GitHub Action
Automated sync to Hugging Face
bcce530
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 }
)
}
}