import { NextResponse } from "next/server"; import { readFile } from "fs/promises"; import { existsSync } from "fs"; import { unlink } from "fs/promises"; import path from "path"; import db from "@/lib/db"; export async function GET(request, { params }) { const { fileId } = await params; try { // Get file info from database const file = db.prepare(` SELECT * FROM file_attachments WHERE file_id = ? `).get(parseInt(fileId)); if (!file) { return NextResponse.json( { error: "File not found" }, { status: 404 } ); } // Construct the full file path const fullPath = path.join(process.cwd(), "public", file.file_path); // Check if file exists if (!existsSync(fullPath)) { return NextResponse.json( { error: "File not found on disk" }, { status: 404 } ); } // Read the file const fileBuffer = await readFile(fullPath); // Return the file with appropriate headers return new NextResponse(fileBuffer, { headers: { "Content-Type": file.mime_type || "application/octet-stream", "Content-Disposition": `attachment; filename="${encodeURIComponent(file.original_filename)}"`, "Content-Length": fileBuffer.length.toString(), }, }); } catch (error) { console.error("Error downloading file:", error); return NextResponse.json( { error: "Failed to download file" }, { status: 500 } ); } } export async function PUT(request, { params }) { const { fileId } = await params; try { const body = await request.json(); const { description, original_filename } = body; // Validate input if (description !== undefined && typeof description !== 'string') { return NextResponse.json( { error: "Description must be a string" }, { status: 400 } ); } if (original_filename !== undefined && typeof original_filename !== 'string') { return NextResponse.json( { error: "Original filename must be a string" }, { status: 400 } ); } // Check if file exists const existingFile = db.prepare(` SELECT * FROM file_attachments WHERE file_id = ? `).get(parseInt(fileId)); if (!existingFile) { return NextResponse.json( { error: "File not found" }, { status: 404 } ); } // Build update query const updates = []; const values = []; if (description !== undefined) { updates.push('description = ?'); values.push(description); } if (original_filename !== undefined) { updates.push('original_filename = ?'); values.push(original_filename); } if (updates.length === 0) { return NextResponse.json( { error: "No valid fields to update" }, { status: 400 } ); } values.push(parseInt(fileId)); const result = db.prepare(` UPDATE file_attachments SET ${updates.join(', ')} WHERE file_id = ? `).run(...values); if (result.changes === 0) { return NextResponse.json( { error: "File not found" }, { status: 404 } ); } // Get updated file const updatedFile = db.prepare(` SELECT * FROM file_attachments WHERE file_id = ? `).get(parseInt(fileId)); return NextResponse.json(updatedFile); } catch (error) { console.error("Error updating file:", error); return NextResponse.json( { error: "Failed to update file" }, { status: 500 } ); } } export async function DELETE(request, { params }) { const { fileId } = await params; try { // Get file info from database const file = db.prepare(` SELECT * FROM file_attachments WHERE file_id = ? `).get(parseInt(fileId)); if (!file) { return NextResponse.json( { error: "File not found" }, { status: 404 } ); } // Delete physical file try { const fullPath = path.join(process.cwd(), "public", file.file_path); await unlink(fullPath); } catch (fileError) { console.warn("Could not delete physical file:", fileError.message); // Continue with database deletion even if file doesn't exist } // Delete from database const result = db.prepare(` DELETE FROM file_attachments WHERE file_id = ? `).run(parseInt(fileId)); if (result.changes === 0) { return NextResponse.json( { error: "File not found" }, { status: 404 } ); } return NextResponse.json({ success: true }); } catch (error) { console.error("Error deleting file:", error); return NextResponse.json( { error: "Failed to delete file" }, { status: 500 } ); } }