'use server'; import { auth } from "@/auth"; import { getFreshAccessToken } from "@/lib/auth-utils"; import { prisma } from "@/lib/prisma"; import { revalidatePath } from "next/cache"; // createFolderAction remains the same... export async function uploadFileAction(formData: FormData) { const session = await auth(); if (!session?.user?.id) throw new Error("Unauthorized"); const file = formData.get("file") as File; const description = formData.get("description") as string || ""; const parentId = formData.get("parentId") as string | null; // Parse the dynamic metadata from the client const customMetadataRaw = formData.get("customMetadata") as string; const customMetadata = customMetadataRaw ? JSON.parse(customMetadataRaw) : {}; if (!file) throw new Error("No file selected"); const accessToken = await getFreshAccessToken(session.user.id); const rootFolder = "WebCalibre"; const internalId = crypto.randomUUID(); // 1. Create OneDrive Storage Folder const createSubFolderRes = await fetch(`https://graph.microsoft.com/v1.0/me/drive/root:/${rootFolder}:/children`, { method: "POST", headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "application/json" }, body: JSON.stringify({ name: internalId, folder: {} }) }); if (!createSubFolderRes.ok) throw new Error("Storage directory creation failed"); const subFolderData = await createSubFolderRes.json(); // 2. Upload Session & File Transfer (Existing logic is fine) const sessionUrl = `https://graph.microsoft.com/v1.0/me/drive/items/${subFolderData.id}:/${encodeURIComponent(file.name)}:/createUploadSession`; const sessionRes = await fetch(sessionUrl, { method: "POST", headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "application/json" }, body: JSON.stringify({ item: { "@microsoft.graph.conflictBehavior": "replace" } }) }); const { uploadUrl } = await sessionRes.json(); const buffer = Buffer.from(await file.arrayBuffer()); await fetch(uploadUrl, { method: "PUT", headers: { "Content-Length": `${file.size}`, "Content-Range": `bytes 0-${file.size - 1}/${file.size}` }, body: buffer }); // 3. Final Database Record with Merged Metadata const extension = file.name.split('.').pop()?.toUpperCase() || "UNKNOWN"; await prisma.fileNode.create({ data: { id: internalId, name: file.name, description: description, size: BigInt(file.size), isFolder: false, path: `/${rootFolder}/${internalId}/${file.name}`, ownerId: session.user.id, parentId: parentId || null, metadata: { ...customMetadata, // User's dynamic keys (Latitude, Author, etc.) type: extension, // System keys (preserved for UI icons) mimeType: file.type } } }); revalidatePath("/dashboard"); return { success: true }; }