import { NextRequest, NextResponse } from "next/server"; import { addOpenDayBooking, getPersonOpenDayBookings, getOpenDayEvent, } from "@/lib/db"; import { checkRateLimit, getClientIp } from "@/lib/rateLimit"; import { sanitizeName, sanitizePhone, sanitizeHandle } from "@/lib/validation"; export async function POST(request: NextRequest) { const ip = getClientIp(request); if (!checkRateLimit(ip, 10, 60_000)) { return NextResponse.json( { error: "Слишком много запросов. Попробуйте через минуту." }, { status: 429 } ); } try { const body = await request.json(); const { classId, eventId, name, phone, instagram, telegram } = body; if (!classId || !eventId) { return NextResponse.json({ error: "classId and eventId are required" }, { status: 400 }); } const cleanName = sanitizeName(name); if (!cleanName) { return NextResponse.json({ error: "Имя обязательно" }, { status: 400 }); } const cleanPhone = sanitizePhone(phone); if (!cleanPhone) { return NextResponse.json({ error: "Телефон обязателен" }, { status: 400 }); } const id = addOpenDayBooking(classId, eventId, { name: cleanName, phone: cleanPhone, instagram: sanitizeHandle(instagram), telegram: sanitizeHandle(telegram), }); // Return total bookings for this person (for discount calculation) const totalBookings = getPersonOpenDayBookings(eventId, cleanPhone); const event = getOpenDayEvent(eventId); const pricePerClass = event && totalBookings >= event.discountThreshold ? event.discountPrice : event?.pricePerClass ?? 30; return NextResponse.json({ ok: true, id, totalBookings, pricePerClass }); } catch (e) { const msg = e instanceof Error ? e.message : "Internal error"; if (msg.includes("UNIQUE")) { return NextResponse.json({ error: "Вы уже записаны на это занятие" }, { status: 409 }); } console.error("[open-day-register] POST error:", e); return NextResponse.json({ error: "Internal error" }, { status: 500 }); } }