import { NextRequest, NextResponse } from 'next/server' import { getServerSession } from 'next-auth' import { authOptions } from '@/lib/auth' import { prisma } from '@/lib/prisma' import { uploadFile, buildKey } from '@/lib/spaces' const ALLOWED_TYPES = [ 'application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'text/plain', ] const MAX_SIZE = 50 * 1024 * 1024 // 50MB const STORAGE_LIMITS: Record = { FREE: 1 * 1024 * 1024 * 1024, // 1GB STARTER: 1 * 1024 * 1024 * 1024, // 1GB PRO: 5 * 1024 * 1024 * 1024, // 5GB ENTERPRISE: 20 * 1024 * 1024 * 1024, // 20GB } export async function POST(req: NextRequest) { const session = await getServerSession(authOptions) if (!session?.user?.id) { return NextResponse.json({ error: 'Não autorizado' }, { status: 401 }) } try { const formData = await req.formData() const file = formData.get('file') as File | null if (!file) { return NextResponse.json({ error: 'Nenhum arquivo enviado' }, { status: 400 }) } // Validate file extension (defense in depth) const ext = file.name.split(".").pop()?.toLowerCase() const ALLOWED_EXTENSIONS = ["pdf", "doc", "docx", "txt"] if (!ext || !ALLOWED_EXTENSIONS.includes(ext)) { return NextResponse.json( { error: "Extensão de arquivo não permitida" }, { status: 400 } ) } // Validate mime type if (!ALLOWED_TYPES.includes(file.type)) { return NextResponse.json( { error: 'Tipo de arquivo não permitido. Aceitos: PDF, DOCX, DOC, TXT' }, { status: 400 } ) } // Validate size if (file.size > MAX_SIZE) { return NextResponse.json( { error: 'Arquivo muito grande. Máximo: 50MB' }, { status: 400 } ) } // Check storage limit const user = await prisma.user.findUnique({ where: { id: session.user.id }, select: { plan: true }, }) const storageLimit = STORAGE_LIMITS[user?.plan || 'FREE'] || STORAGE_LIMITS.FREE const usedStorage = await prisma.upload.aggregate({ where: { userId: session.user.id }, _sum: { size: true }, }) const currentUsage = usedStorage._sum.size || 0 if (currentUsage + file.size > storageLimit) { return NextResponse.json( { error: 'Limite de armazenamento atingido. Faça upgrade do plano para mais espaço.' }, { status: 400 } ) } // Upload to Spaces const buffer = Buffer.from(await file.arrayBuffer()) const key = buildKey(session.user.id, file.name) await uploadFile(buffer, key, file.type) // Save to DB const upload = await prisma.upload.create({ data: { userId: session.user.id, filename: file.name, key, size: file.size, mimeType: file.type, }, }) return NextResponse.json({ upload: { id: upload.id, filename: upload.filename, size: upload.size, mimeType: upload.mimeType, createdAt: upload.createdAt, }, }) } catch (error) { console.error('Upload error:', error) return NextResponse.json({ error: 'Erro ao fazer upload' }, { status: 500 }) } } export async function GET(req: NextRequest) { const session = await getServerSession(authOptions) if (!session?.user?.id) { return NextResponse.json({ error: 'Não autorizado' }, { status: 401 }) } const { searchParams } = new URL(req.url) const page = Math.max(1, Math.min(1000, parseInt(searchParams.get('page') || '1'))) const limit = Math.max(1, Math.min(100, parseInt(searchParams.get('limit') || '20'))) const skip = (page - 1) * limit const [uploads, total, storageUsed] = await Promise.all([ prisma.upload.findMany({ where: { userId: session.user.id }, orderBy: { createdAt: 'desc' }, skip, take: limit, select: { id: true, filename: true, size: true, mimeType: true, createdAt: true, }, }), prisma.upload.count({ where: { userId: session.user.id } }), prisma.upload.aggregate({ where: { userId: session.user.id }, _sum: { size: true }, }), ]) const user = await prisma.user.findUnique({ where: { id: session.user.id }, select: { plan: true }, }) const storageLimit = STORAGE_LIMITS[user?.plan || 'FREE'] || STORAGE_LIMITS.FREE return NextResponse.json({ uploads, total, page, totalPages: Math.ceil(total / limit), storageUsed: storageUsed._sum.size || 0, storageLimit, }) }