import { NextRequest, NextResponse } from "next/server"; import { auth } from "@clerk/nextjs/server"; import { revalidateTag } from "next/cache"; import { prisma } from "@/lib/prisma"; import { generateMonumentQR } from "@/lib/qrcode"; import { getPublicUrl } from "@/lib/upload"; export async function POST(req: NextRequest) { const { userId } = await auth(); if (!userId) { return NextResponse.json({ error: "Неавторизирано" }, { status: 401 }); } try { const body = await req.json(); const { title, description, bornDate, passedDate, subdomain, templateId, images } = body; if (!title?.trim()) { return NextResponse.json({ error: "Името е задолжително" }, { status: 400 }); } if (!subdomain || subdomain.length < 3) { return NextResponse.json({ error: "Поддоменот мора да има најмалку 3 карактери" }, { status: 400 }); } if (!/^[a-z0-9][a-z0-9-]*[a-z0-9]$/.test(subdomain)) { return NextResponse.json({ error: "Поддоменот може да содржи само мали букви, цифри и цртички" }, { status: 400 }); } if (templateId < 1 || templateId > 3) { return NextResponse.json({ error: "Невалиден шаблон" }, { status: 400 }); } if (!images || images.length === 0 || images.length > 3) { return NextResponse.json({ error: "Потребни се 1-3 фотографии" }, { status: 400 }); } const existing = await prisma.user.findUnique({ where: { subdomain } }); if (existing && existing.clerkId !== userId) { return NextResponse.json({ error: "Поддоменот е веќе зафатен" }, { status: 409 }); } const existingUser = await prisma.user.findUnique({ where: { clerkId: userId } }); let user; if (existingUser) { if (existingUser.subdomain !== subdomain) { revalidateTag(`memorial-${existingUser.subdomain}`); } await prisma.image.deleteMany({ where: { userId: existingUser.id } }); user = await prisma.user.update({ where: { clerkId: userId }, data: { title, description, bornDate: bornDate || null, passedDate: passedDate || null, subdomain, templateId, published: true, images: { create: images.map((img: { key: string }, i: number) => ({ url: getPublicUrl(img.key), key: img.key, order: i + 1, })), }, }, include: { images: true }, }); } else { user = await prisma.user.create({ data: { clerkId: userId, title, description, bornDate: bornDate || null, passedDate: passedDate || null, subdomain, templateId, published: true, images: { create: images.map((img: { key: string }, i: number) => ({ url: getPublicUrl(img.key), key: img.key, order: i + 1, })), }, }, include: { images: true }, }); } revalidateTag("memorial"); revalidateTag(`memorial-${subdomain}`); const qrCode = await generateMonumentQR(subdomain); return NextResponse.json({ success: true, monumentUrl: `https://${subdomain}.${process.env.NEXT_PUBLIC_APP_DOMAIN}`, qrCode, user, }); } catch (error) { console.error("Publish error:", error); return NextResponse.json({ error: "Внатрешна грешка на серверот" }, { status: 500 }); } }