// 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) => { try { const body = await readBody(event) as EventCreateRequest; // Get user session using the proper SessionManager const sessionManager = createSessionManager(); const cookieHeader = getHeader(event, 'cookie'); const session = sessionManager.getSession(cookieHeader); if (!session || !session.user) { throw createError({ statusCode: 401, statusMessage: 'Authentication required' }); } // Check if user has permission to create events (board or admin only) if (session.user.tier !== 'board' && session.user.tier !== 'admin') { 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) { 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) { 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)) { throw createError({ statusCode: 400, statusMessage: 'Invalid event type' }); } // Validate visibility const validVisibilities = ['public', 'board-only', 'admin-only']; if (!validVisibilities.includes(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') { throw createError({ statusCode: 403, statusMessage: 'Only administrators can create admin-only events' }); } 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 as 'active' | 'cancelled' | 'completed' | 'draft') || 'active', creator: session.user.id, current_attendees: 0 }; // Create the event const newEvent = await eventsClient.create(eventData); return { success: true, data: newEvent, message: 'Event created successfully' }; } catch (error: any) { console.error('Error creating event:', error); // Re-throw createError instances if (error.statusCode) { throw error; } throw createError({ statusCode: 500, statusMessage: 'Failed to create event' }); } });