import { NextRequest, NextResponse } from "next/server"; import { promises as fs } from "fs"; import path from "path"; import { getPool } from "@/lib/database"; import { randomUUID } from "crypto"; export const config = { api: { bodyParser: false, // We handle parsing }, }; export async function POST(req: NextRequest) { // Get user-id (for dev); in real world, extract from session/token const userId = req.headers.get("user-id"); if (!userId) { return NextResponse.json({ error: "Not authenticated" }, { status: 401 }); } // Parse the form data try { const formData = await req.formData(); const file = formData.get("file") as File; if (!file) { return NextResponse.json({ error: "No file uploaded" }, { status: 400 }); } // Only allow .blend, .zip, .jpg, .png, .svg for now const filename = file.name; if (!filename.match(/\.(blend|zip|jpg|jpeg|png|svg)$/i)) { return NextResponse.json( { error: "File type not allowed" }, { status: 400 } ); } const saveAs = randomUUID() + path.extname(filename); const uploadsDir = path.resolve(process.cwd(), "uploads"); await fs.mkdir(uploadsDir, { recursive: true }); const filepath = path.join(uploadsDir, saveAs); const buffer = Buffer.from(await file.arrayBuffer()); await fs.writeFile(filepath, buffer); // Write metadata to uploaded_files const pool = getPool(); const result = await pool.query( `INSERT INTO uploaded_files (user_id, original_name, file_path, upload_status) VALUES ($1, $2, $3, $4) RETURNING *`, [userId, filename, filepath, "COMPLETE"] ); const uploadedFile = result.rows[0]; return NextResponse.json({ success: true, file: uploadedFile }); } catch (err: any) { console.error(err); return NextResponse.json( { error: err.message || "Upload failed" }, { status: 500 } ); } }