136 lines
4.6 KiB
TypeScript
136 lines
4.6 KiB
TypeScript
|
|
// server/api/events/[id].delete.ts
|
||
|
|
import { createNocoDBEventsClient } from '~/server/utils/nocodb-events';
|
||
|
|
import { createSessionManager } from '~/server/utils/session';
|
||
|
|
|
||
|
|
export default defineEventHandler(async (event) => {
|
||
|
|
console.log('[api/events/[id].delete] =========================');
|
||
|
|
console.log('[api/events/[id].delete] DELETE /api/events/[id] - Delete event');
|
||
|
|
console.log('[api/events/[id].delete] Request from:', getClientIP(event));
|
||
|
|
|
||
|
|
try {
|
||
|
|
const eventId = getRouterParam(event, 'id');
|
||
|
|
|
||
|
|
if (!eventId) {
|
||
|
|
throw createError({
|
||
|
|
statusCode: 400,
|
||
|
|
statusMessage: 'Event ID is required'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
console.log('[api/events/[id].delete] Deleting event:', eventId);
|
||
|
|
|
||
|
|
// 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) {
|
||
|
|
throw createError({
|
||
|
|
statusCode: 401,
|
||
|
|
statusMessage: 'Authentication required'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check if user has permission to delete events (board or admin only)
|
||
|
|
const userTier = session.user.tier;
|
||
|
|
if (userTier !== 'board' && userTier !== 'admin') {
|
||
|
|
throw createError({
|
||
|
|
statusCode: 403,
|
||
|
|
statusMessage: 'Only board members and admins can delete events'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
console.log('[api/events/[id].delete] ✅ User authorized to delete events:', session.user.email, 'tier:', userTier);
|
||
|
|
|
||
|
|
const eventsClient = createNocoDBEventsClient();
|
||
|
|
|
||
|
|
// First, get the event to verify it exists and get the event_id for RSVP cleanup
|
||
|
|
let eventToDelete;
|
||
|
|
try {
|
||
|
|
eventToDelete = await eventsClient.findOne(eventId);
|
||
|
|
console.log('[api/events/[id].delete] Found event to delete:', eventToDelete.title, 'event_id:', eventToDelete.event_id);
|
||
|
|
} catch (error: any) {
|
||
|
|
if (error.statusCode === 404) {
|
||
|
|
throw createError({
|
||
|
|
statusCode: 404,
|
||
|
|
statusMessage: 'Event not found'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
throw error;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Get all RSVPs for this event to clean them up
|
||
|
|
const eventIdentifier = eventToDelete.event_id || eventToDelete.id || (eventToDelete as any).Id;
|
||
|
|
console.log('[api/events/[id].delete] Getting RSVPs for event identifier:', eventIdentifier);
|
||
|
|
|
||
|
|
const eventRSVPs = await eventsClient.getEventRSVPs(eventIdentifier.toString());
|
||
|
|
console.log('[api/events/[id].delete] Found', eventRSVPs.length, 'RSVPs to delete');
|
||
|
|
|
||
|
|
// Delete all RSVPs first
|
||
|
|
let deletedRSVPs = 0;
|
||
|
|
for (const rsvp of eventRSVPs) {
|
||
|
|
try {
|
||
|
|
// Delete RSVP using its database Id
|
||
|
|
const rsvpId = rsvp.Id || rsvp.id;
|
||
|
|
if (rsvpId) {
|
||
|
|
console.log('[api/events/[id].delete] Deleting RSVP:', rsvpId);
|
||
|
|
await $fetch(eventsClient.constructor.prototype.createEventTableUrl('EventRSVPs'), {
|
||
|
|
method: 'DELETE',
|
||
|
|
headers: {
|
||
|
|
'xc-token': eventsClient.constructor.prototype.getNocoDbConfiguration().token,
|
||
|
|
},
|
||
|
|
body: {
|
||
|
|
Id: parseInt(rsvpId.toString())
|
||
|
|
}
|
||
|
|
});
|
||
|
|
deletedRSVPs++;
|
||
|
|
}
|
||
|
|
} catch (rsvpError: any) {
|
||
|
|
console.log('[api/events/[id].delete] ⚠️ Error deleting RSVP:', rsvp.Id || rsvp.id, rsvpError);
|
||
|
|
// Continue with other RSVPs even if one fails
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
console.log('[api/events/[id].delete] Deleted', deletedRSVPs, 'RSVPs');
|
||
|
|
|
||
|
|
// Now delete the event itself using its database Id
|
||
|
|
const eventDatabaseId = (eventToDelete as any).Id || eventToDelete.id;
|
||
|
|
if (!eventDatabaseId) {
|
||
|
|
throw createError({
|
||
|
|
statusCode: 500,
|
||
|
|
statusMessage: 'Could not determine event database ID for deletion'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
console.log('[api/events/[id].delete] Deleting event with database ID:', eventDatabaseId);
|
||
|
|
await eventsClient.delete(eventDatabaseId.toString());
|
||
|
|
|
||
|
|
console.log('[api/events/[id].delete] ✅ Successfully deleted event and all associated RSVPs');
|
||
|
|
|
||
|
|
return {
|
||
|
|
success: true,
|
||
|
|
message: `Event "${eventToDelete.title}" and ${deletedRSVPs} associated RSVPs deleted successfully`,
|
||
|
|
deleted: {
|
||
|
|
event: {
|
||
|
|
id: eventDatabaseId,
|
||
|
|
event_id: eventToDelete.event_id,
|
||
|
|
title: eventToDelete.title
|
||
|
|
},
|
||
|
|
rsvps_deleted: deletedRSVPs
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
} catch (error: any) {
|
||
|
|
console.error('[api/events/[id].delete] ❌ Error deleting event:', error);
|
||
|
|
|
||
|
|
if (error.statusCode) {
|
||
|
|
throw error;
|
||
|
|
}
|
||
|
|
|
||
|
|
throw createError({
|
||
|
|
statusCode: 500,
|
||
|
|
statusMessage: 'Failed to delete event'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
});
|