// server/api/events/index.post.ts import { createNocoDBEventsClient } from '~/server/utils/nocodb-events'; import type { EventCreateRequest } from '~/utils/types'; export default defineEventHandler(async (event) => { try { const body = await readBody(event) as EventCreateRequest; // Get user session for authentication and authorization const session = await getUserSession(event); 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, 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, status: body.status || '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) { console.error('Error creating event:', error); // Re-throw createError instances if (error.statusCode) { throw error; } throw createError({ statusCode: 500, statusMessage: 'Failed to create event' }); } }); // Helper function to get user session (same as in index.get.ts) async function getUserSession(event: any) { try { const sessionCookie = getCookie(event, 'session') || getHeader(event, 'authorization'); if (!sessionCookie) return null; return { user: { id: 'user-id', // Replace with actual session logic tier: 'board' // Replace with actual session logic } }; } catch { return null; } }