import { NextRequest, NextResponse } from 'next/server'; import { Event } from '../../types'; import { v4 as uuid } from 'uuid'; import clickhouse from '@/lib/clickhouse'; // Handler for POST request to track events export async function POST(req: NextRequest) { try { // Parse request body const eventData = await req.json(); // Validate required fields if (!eventData.event_type) { return NextResponse.json( { error: 'Missing required field: event_type' }, { status: 400 } ); } // Set default values for required fields if missing const event: Event = { // Core event fields event_id: eventData.event_id || uuid(), event_time: eventData.event_time || new Date().toISOString(), event_type: eventData.event_type, event_attributes: eventData.event_attributes || '{}', // Link information link_id: eventData.link_id || '', link_slug: eventData.link_slug || '', link_label: eventData.link_label || '', link_title: eventData.link_title || '', link_original_url: eventData.link_original_url || '', link_attributes: eventData.link_attributes || '{}', link_created_at: eventData.link_created_at || new Date().toISOString(), link_expires_at: eventData.link_expires_at || null, link_tags: eventData.link_tags || '[]', // User information user_id: eventData.user_id || '', user_name: eventData.user_name || '', user_email: eventData.user_email || '', user_attributes: eventData.user_attributes || '{}', // Team information team_id: eventData.team_id || '', team_name: eventData.team_name || '', team_attributes: eventData.team_attributes || '{}', // Project information project_id: eventData.project_id || '', project_name: eventData.project_name || '', project_attributes: eventData.project_attributes || '{}', // QR code information qr_code_id: eventData.qr_code_id || '', qr_code_name: eventData.qr_code_name || '', qr_code_attributes: eventData.qr_code_attributes || '{}', // Visitor information visitor_id: eventData.visitor_id || uuid(), session_id: eventData.session_id || uuid(), ip_address: eventData.ip_address || req.headers.get('x-forwarded-for')?.toString() || '', country: eventData.country || '', city: eventData.city || '', device_type: eventData.device_type || '', browser: eventData.browser || '', os: eventData.os || '', user_agent: eventData.user_agent || req.headers.get('user-agent')?.toString() || '', // Referrer information referrer: eventData.referrer || req.headers.get('referer')?.toString() || '', utm_source: eventData.utm_source || '', utm_medium: eventData.utm_medium || '', utm_campaign: eventData.utm_campaign || '', // Interaction information time_spent_sec: eventData.time_spent_sec || 0, is_bounce: eventData.is_bounce !== undefined ? eventData.is_bounce : true, is_qr_scan: eventData.is_qr_scan !== undefined ? eventData.is_qr_scan : false, conversion_type: eventData.conversion_type || '', conversion_value: eventData.conversion_value || 0, }; // Insert event into ClickHouse await clickhouse.insert({ table: 'events', values: [event], format: 'JSONEachRow', }); // Return success response return NextResponse.json({ success: true, message: 'Event tracked successfully', event_id: event.event_id }, { status: 201 }); } catch (error) { console.error('Error tracking event:', error); return NextResponse.json( { error: 'Failed to track event', details: (error as Error).message }, { status: 500 } ); } }