import { NextResponse } from "next/server" import { unlink } from "fs/promises" import path from "path" import { requireAuth, requirePermission, PermissionDeniedError } from "@/shared/lib/auth-guard" import { Permissions } from "@/shared/types/permissions" import { deleteFileAttachment, getFileAttachment, } from "@/modules/files/data-access" export const dynamic = "force-dynamic" interface RouteContext { params: Promise<{ id: string }> } /** * GET /api/files/[id] * 获取文件信息(需要登录) */ export async function GET(_req: Request, ctx: RouteContext) { try { await requireAuth() const { id } = await ctx.params const file = await getFileAttachment(id) if (!file) { return NextResponse.json( { success: false, message: "File not found" }, { status: 404 } ) } return NextResponse.json({ success: true, file }) } catch (e) { const message = e instanceof Error ? e.message : "Failed to fetch file" const status = message.includes("auth_required") ? 401 : 500 return NextResponse.json({ success: false, message }, { status }) } } /** * DELETE /api/files/[id] * 删除文件(需要 FILE_DELETE 权限) */ export async function DELETE(_req: Request, ctx: RouteContext) { try { await requirePermission(Permissions.FILE_DELETE) const { id } = await ctx.params const file = await getFileAttachment(id) if (!file) { return NextResponse.json( { success: false, message: "File not found" }, { status: 404 } ) } // 删除磁盘文件(静默失败,记录仍会被删除) const absolutePath = path.join(process.cwd(), "public", file.storagePath) try { await unlink(absolutePath) } catch { // 文件可能已不存在,忽略错误 } const ok = await deleteFileAttachment(id) if (!ok) { return NextResponse.json( { success: false, message: "Failed to delete file record" }, { status: 500 } ) } return NextResponse.json({ success: true, message: "File deleted" }) } catch (e) { if (e instanceof PermissionDeniedError) { return NextResponse.json( { success: false, message: e.message }, { status: 403 } ) } const message = e instanceof Error ? e.message : "Failed to delete file" return NextResponse.json({ success: false, message }, { status: 500 }) } }