// server/api/events/index.post.ts import { createNocoDBEventsClient } from '~/server/utils/nocodb-events'; import { createSessionManager } from '~/server/utils/session'; import type { EventCreateRequest } from '~/utils/types'; export default defineEventHandler(async (event) => { console.log('[api/events.post] ========================='); console.log('[api/events.post] POST /api/events - Create event'); console.log('[api/events.post] Request from:', getClientIP(event)); try { const body = await readBody(event) as EventCreateRequest; console.log('[api/events.post] Event data received:', { title: body.title, event_type: body.event_type, start_datetime: body.start_datetime, end_datetime: body.end_datetime, visibility: body.visibility }); // Get user session using the working session manager const sessionManager = createSessionManager(); const cookieHeader = getHeader(event, 'cookie'); const session = sessionManager.getSession(cookieHeader); if (!session || !session.user) { console.log('[api/events.post] ❌ No valid session found'); throw createError({ statusCode: 401, statusMessage: 'Authentication required' }); } console.log('[api/events.post] ✅ Valid session found for user:', session.user.email); console.log('[api/events.post] User tier:', session.user.tier); // Check if user has permission to create events (board or admin only) if (session.user.tier !== 'board' && session.user.tier !== 'admin') { console.log('[api/events.post] ❌ Insufficient permissions. User tier:', session.user.tier); throw createError({ statusCode: 403, statusMessage: 'Only board members and administrators can create events' }); } // Validate required fields if (!body.title || !body.start_datetime || !body.end_datetime) { console.log('[api/events.post] ❌ Missing required fields'); throw createError({ statusCode: 400, statusMessage: 'Title, start date, and end date are required' }); } // Validate date range const startDate = new Date(body.start_datetime); const endDate = new Date(body.end_datetime); if (startDate >= endDate) { console.log('[api/events.post] ❌ Invalid date range'); throw createError({ statusCode: 400, statusMessage: 'End date must be after start date' }); } // Validate event type const validEventTypes = ['meeting', 'social', 'fundraiser', 'workshop', 'board-only']; if (!validEventTypes.includes(body.event_type)) { console.log('[api/events.post] ❌ Invalid event type:', body.event_type); throw createError({ statusCode: 400, statusMessage: 'Invalid event type' }); } // Validate visibility const validVisibilities = ['public', 'board-only', 'admin-only']; if (!validVisibilities.includes(body.visibility)) { console.log('[api/events.post] ❌ Invalid visibility:', body.visibility); throw createError({ statusCode: 400, statusMessage: 'Invalid visibility setting' }); } // Admin-only visibility can only be set by admins if (body.visibility === 'admin-only' && session.user.tier !== 'admin') { console.log('[api/events.post] ❌ Admin-only event creation attempted by non-admin'); throw createError({ statusCode: 403, statusMessage: 'Only administrators can create admin-only events' }); } console.log('[api/events.post] ✅ Validation passed, creating event...'); const eventsClient = createNocoDBEventsClient(); // Prepare event data const eventData = { title: body.title.trim(), description: body.description?.trim() || '', event_type: body.event_type as 'meeting' | 'social' | 'fundraiser' | 'workshop' | 'board-only', start_datetime: body.start_datetime, end_datetime: body.end_datetime, location: body.location?.trim() || '', is_recurring: body.is_recurring || 'false', recurrence_pattern: body.recurrence_pattern || '', max_attendees: body.max_attendees || '', is_paid: body.is_paid || 'false', cost_members: body.cost_members || '', cost_non_members: body.cost_non_members || '', member_pricing_enabled: body.member_pricing_enabled || 'true', visibility: body.visibility as 'public' | 'board-only' | 'admin-only', status: (body.status || 'active') as 'active' | 'cancelled' | 'completed' | 'draft', creator: session.user.id, current_attendees: '0' }; console.log('[api/events.post] Event data prepared:', Object.keys(eventData)); // Create the event const newEvent = await eventsClient.create(eventData); console.log('[api/events.post] ✅ Event created successfully with ID:', newEvent.id); return { success: true, data: newEvent, message: 'Event created successfully' }; } catch (error: any) { console.error('[api/events.post] ❌ Error creating event:', error); // Re-throw createError instances if (error.statusCode) { throw error; } throw createError({ statusCode: 500, statusMessage: 'Failed to create event' }); } });