import { deleteMember, handleNocoDbError, getMemberById } from '~/server/utils/nocodb'; import { createSessionManager } from '~/server/utils/session'; import { deleteKeycloakUser } from '~/server/utils/keycloak-admin'; export default defineEventHandler(async (event) => { const id = getRouterParam(event, 'id'); console.log('[api/members/[id].delete] ========================='); console.log('[api/members/[id].delete] DELETE /api/members/' + id); console.log('[api/members/[id].delete] Request from:', getClientIP(event)); if (!id) { throw createError({ statusCode: 400, statusMessage: 'Member ID is required' }); } try { // Validate session and require Admin privileges (delete is more sensitive) const sessionManager = createSessionManager(); const cookieHeader = getCookie(event, 'monacousa-session') ? getHeader(event, 'cookie') : undefined; const session = sessionManager.getSession(cookieHeader); if (!session?.user) { throw createError({ statusCode: 401, statusMessage: 'Authentication required' }); } const userTier = session.user.tier; if (userTier !== 'admin') { throw createError({ statusCode: 403, statusMessage: 'Administrator privileges required to delete members' }); } console.log('[api/members/[id].delete] Authorized user:', session.user.email, 'Tier:', userTier); // First, get the member data to check for Keycloak ID let member; try { member = await getMemberById(id); console.log('[api/members/[id].delete] Retrieved member for deletion:', member.first_name, member.last_name); if (member.keycloak_id) { console.log('[api/members/[id].delete] Member has Keycloak ID:', member.keycloak_id); } else { console.log('[api/members/[id].delete] Member has no Keycloak ID - NocoDB only deletion'); } } catch (memberError: any) { console.error('[api/members/[id].delete] Failed to retrieve member data:', memberError); // Continue with deletion attempt even if we can't get member data } // If member has a Keycloak account, try to delete it first if (member?.keycloak_id) { try { console.log('[api/members/[id].delete] Attempting Keycloak user deletion...'); await deleteKeycloakUser(member.keycloak_id); console.log('[api/members/[id].delete] ✅ Keycloak user deleted successfully'); } catch (keycloakError: any) { console.error('[api/members/[id].delete] ⚠️ Failed to delete Keycloak user:', keycloakError); console.error('[api/members/[id].delete] Continuing with member deletion despite Keycloak failure'); // Don't throw here - we want to continue with NocoDB deletion // This prevents orphaned NocoDB records if Keycloak is temporarily unavailable } } // Delete member from NocoDB const result = await deleteMember(id); console.log('[api/members/[id].delete] ✅ Member deleted successfully from NocoDB:', id); // Log completion status if (member?.keycloak_id) { console.log('[api/members/[id].delete] ✅ Enhanced deletion completed (NocoDB + Keycloak cleanup)'); } else { console.log('[api/members/[id].delete] ✅ Standard deletion completed (NocoDB only)'); } return { success: true, data: { id }, message: 'Member deleted successfully' }; } catch (error: any) { console.error('[api/members/[id].delete] ❌ Error deleting member:', error); handleNocoDbError(error, 'deleteMember', 'Member'); } });