import { crmFetch } from '../../../../lib/flats'; // Заявка на просмотр со страницы /ru/apartments → CRM (клиент «BarevClub» и сообщение в группу AREV). /** Не больше 5 заявок с одного адреса за 10 минут — от случайных повторов и ботов */ const hits = new Map(); function limited(ip: string) { const now = Date.now(); const recent = (hits.get(ip) ?? []).filter((t) => now - t < 10 * 60_000); recent.push(now); hits.set(ip, recent); if (hits.size > 5000) hits.clear(); return recent.length > 5; } const json = (body: object, status = 200) => Response.json(body, { status }); export async function POST(req: Request) { const ip = (req.headers.get('x-forwarded-for') ?? '').split(',')[0]!.trim() || 'unknown'; if (limited(ip)) return json({ code: 'TOO_MANY' }, 429); let body: Record; try { body = (await req.json()) as Record; } catch { return json({ code: 'VALIDATION' }, 400); } // скрытое поле: его заполняют только боты if (typeof body.website === 'string' && body.website) return json({ ok: true }); const str = (v: unknown) => (typeof v === 'string' && v.trim() ? v.trim() : undefined); const payload = { leadId: Number(body.leadId), day: str(body.day), time: str(body.time), name: str(body.name), phone: str(body.phone), telegram: str(body.telegram), }; try { const res = await crmFetch('/api/barev/requests', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(payload), }); const data = (await res.json().catch(() => ({}))) as { code?: string }; if (!res.ok) return json({ code: data.code ?? 'FAILED' }, res.status === 401 ? 503 : res.status); return json({ ok: true }); } catch { return json({ code: 'FAILED' }, 502); } }