import { NextResponse } from "next/server"; import { getServerSession } from "next-auth/next"; import { authOptions } from "@/lib/auth"; import { prisma } from "@/lib/prisma"; import { getHFStorageForUser } from "@/lib/storage/hf"; import crypto from "crypto"; export async function POST(req) { try { const session = await getServerSession(authOptions); if (!session?.user?.id) return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); const formData = await req.formData(); const file = formData.get("file"); if (!file) return NextResponse.json({ error: "No file uploaded" }, { status: 400 }); const ext = (file.name || "").split(".").pop() || "bin"; const randomName = `${crypto.randomUUID()}.${ext}`; const path = `uploads/${session.user.id}/${randomName}`; const storage = getHFStorageForUser({ hfAccessToken: session.user.hfAccessToken, hfUsername: session.user.hfUsername, }); if (storage) { try { const buffer = Buffer.from(await file.arrayBuffer()); const { url, repo, path: storedPath } = await storage.uploadFile(buffer, path); const dbImage = await prisma.userImage.create({ data: { userId: session.user.id, url, hfRepo: repo, hfPath: storedPath }, }); return NextResponse.json({ url, id: dbImage.id, location: "hf", repo, path: storedPath }); } catch (hfErr) { console.warn("[HF_UPLOAD_FAILED]", hfErr.message, "— falling back to MuAPI"); } } const muApiKey = process.env.MU_API_KEY; if (!muApiKey) { return NextResponse.json({ error: "Upload failed: no HF storage configured and no MU_API_KEY fallback set.", }, { status: 500 }); } const forwardData = new FormData(); forwardData.append("file", file); const muRes = await fetch("https://api.muapi.ai/api/v1/upload_file", { method: "POST", headers: { "x-api-key": muApiKey }, body: forwardData, }); if (!muRes.ok) { const errText = await muRes.text(); console.error("[MUAPI_UPLOAD_ERROR]", errText); return NextResponse.json({ error: "Failed to upload file" }, { status: muRes.status }); } const data = await muRes.json(); const uploadedUrl = data.url; if (!uploadedUrl) return NextResponse.json({ error: "Invalid upload response" }, { status: 502 }); const dbImage = await prisma.userImage.create({ data: { userId: session.user.id, url: uploadedUrl }, }); return NextResponse.json({ url: uploadedUrl, id: dbImage.id, location: "muapi" }); } catch (error) { console.error("[UPLOAD_ROUTE_ERROR]", error); return NextResponse.json({ error: error.message }, { status: 500 }); } }