import { NextResponse } from 'next/server'; import { getServerSession } from 'next-auth'; import { authOptions } from '@/lib/auth'; import { prisma } from '@/lib/prisma'; import { logger } from '@/lib/logger'; export async function POST( request: Request, props: { params: Promise<{ missionId: string }> } ) { const params = await props.params; const { missionId } = params; try { // Check authentication const session = await getServerSession(authOptions); if (!session?.user?.id) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } const body = await request.json(); const { userId, userEmail, role } = body; if (!userId) { return NextResponse.json( { error: 'userId is required' }, { status: 400 } ); } // Get mission details const mission = await prisma.mission.findUnique({ where: { id: missionId }, select: { id: true, name: true, creatorId: true, leantimeProjectId: true, outlineCollectionId: true, rocketChatChannelId: true, giteaRepositoryUrl: true, }, }); if (!mission) { return NextResponse.json({ error: 'Mission not found' }, { status: 404 }); } // Check if user is authorized (creator or admin) const isCreator = mission.creatorId === session.user.id; const isAdmin = session.user.role?.includes('admin'); if (!isCreator && !isAdmin) { return NextResponse.json({ error: 'Forbidden' }, { status: 403 }); } // Remove user from mission in database await prisma.missionUser.deleteMany({ where: { missionId, userId, }, }); // Extract repo name from Gitea URL let repoName = ''; if (mission.giteaRepositoryUrl) { try { const url = new URL(mission.giteaRepositoryUrl); const pathParts = url.pathname.split('/').filter(Boolean); repoName = pathParts[pathParts.length - 1] || ''; } catch { const match = mission.giteaRepositoryUrl.match(/\/([^\/]+)\/?$/); repoName = match ? match[1] : ''; } } // Prepare data for N8N webhook const n8nData = { missionId: mission.id, missionName: mission.name, userId, userEmail, role: role || 'volontaire', repoName, leantimeProjectId: mission.leantimeProjectId || '', outlineCollectionId: mission.outlineCollectionId || '', rocketChatChannelId: mission.rocketChatChannelId || '', giteaRepositoryUrl: mission.giteaRepositoryUrl || '', }; // Call N8N webhook const webhookUrl = process.env.N8N_REMOVE_USER_WEBHOOK_URL || 'https://brain.slm-lab.net/webhook/NeahMissionRemoveUser'; const apiKey = process.env.N8N_API_KEY || ''; logger.debug('Calling N8N RemoveUser webhook', { missionId, userId, userEmail, }); const response = await fetch(webhookUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey, }, body: JSON.stringify(n8nData), }); if (!response.ok) { const errorText = await response.text(); logger.error('N8N RemoveUser webhook error', { status: response.status, error: errorText.substring(0, 200), }); // Continue even if N8N fails, database is already updated } return NextResponse.json({ success: true, message: 'User removed successfully', }); } catch (error) { logger.error('Error removing user from mission', { error: error instanceof Error ? error.message : String(error), missionId, }); return NextResponse.json( { error: 'Failed to remove user', details: error instanceof Error ? error.message : String(error) }, { status: 500 } ); } }