import { NextResponse } from "next/server" import { getInvitationByToken } from "@/lib/db/queries/invitations" import { getPhotoUploadByInvitationId, upsertPhotoUpload } from "@/lib/db/queries/uploads" import { isRsvpClosed } from "@/lib/rsvp-deadline" import { getUploadBucket } from "@/lib/storage/s3" import { deleteUploadObject, isObjectKeyForInvitation } from "@/lib/storage/uploads" import { completeUploadSchema } from "@/lib/validation/upload" export const runtime = "nodejs" export async function POST(request: Request) { if (isRsvpClosed()) { return NextResponse.json({ message: "Upload deadline has passed" }, { status: 403 }) } const parsed = completeUploadSchema.safeParse(await request.json()) if (!parsed.success) { return NextResponse.json({ message: "Invalid upload completion" }, { status: 400 }) } const invitation = await getInvitationByToken(parsed.data.token) if (!invitation) { return NextResponse.json({ message: "Invitation not found" }, { status: 404 }) } if (!isObjectKeyForInvitation(parsed.data.objectKey, invitation.invitation.id)) { return NextResponse.json({ message: "Invalid object key" }, { status: 400 }) } const previousUpload = await getPhotoUploadByInvitationId(invitation.invitation.id) const upload = await upsertPhotoUpload({ invitationId: invitation.invitation.id, bucket: getUploadBucket(), objectKey: parsed.data.objectKey, originalFilename: parsed.data.filename, contentType: parsed.data.contentType, sizeBytes: parsed.data.sizeBytes, }) if (previousUpload && previousUpload.object_key !== parsed.data.objectKey) { await deleteUploadObject(previousUpload.object_key).catch(() => undefined) } return NextResponse.json({ upload }) }