import { NextResponse } from 'next/server'; import { getServerSession } from 'next-auth'; import { authOptions } from "@/app/api/auth/options"; import { prisma } from '@/lib/prisma'; import { deleteMissionLogo } from '@/lib/mission-uploads'; // Helper function to check authentication async function checkAuth(request: Request) { const session = await getServerSession(authOptions); if (!session?.user?.id) { console.error('Unauthorized access attempt:', { url: request.url, method: request.method, headers: Object.fromEntries(request.headers) }); return { authorized: false, userId: null }; } return { authorized: true, userId: session.user.id }; } // GET endpoint to retrieve a mission by ID export async function GET(request: Request, props: { params: Promise<{ missionId: string }> }) { const params = await props.params; try { const { authorized, userId } = await checkAuth(request); if (!authorized || !userId) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } const { missionId } = params; if (!missionId) { return NextResponse.json({ error: 'Mission ID is required' }, { status: 400 }); } // Get mission with detailed info const mission = await prisma.mission.findFirst({ where: { id: missionId, OR: [ { creatorId: userId }, { missionUsers: { some: { userId } } } ] }, include: { creator: { select: { id: true, email: true } }, missionUsers: { select: { id: true, role: true, user: { select: { id: true, email: true } } } }, attachments: { select: { id: true, filename: true, filePath: true, fileType: true, fileSize: true, createdAt: true }, orderBy: { createdAt: 'desc' } } } }); if (!mission) { return NextResponse.json({ error: 'Mission not found or access denied' }, { status: 404 }); } return NextResponse.json(mission); } catch (error) { console.error('Error retrieving mission:', error); return NextResponse.json({ error: 'Internal server error', details: error instanceof Error ? error.message : String(error) }, { status: 500 }); } } // PUT endpoint to update a mission export async function PUT(request: Request, props: { params: Promise<{ missionId: string }> }) { const params = await props.params; try { const { authorized, userId } = await checkAuth(request); if (!authorized || !userId) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } const { missionId } = params; if (!missionId) { return NextResponse.json({ error: 'Mission ID is required' }, { status: 400 }); } // Check if mission exists and user has access to modify it const existingMission = await prisma.mission.findFirst({ where: { id: missionId, OR: [ { creatorId: userId }, { missionUsers: { some: { userId, role: { in: ['gardien-temps', 'gardien-parole'] } } } } ] } }); if (!existingMission) { return NextResponse.json({ error: 'Mission not found or not authorized to update' }, { status: 404 }); } // Parse the request body const body = await request.json(); const { name, logo, oddScope, niveau, intention, missionType, donneurDOrdre, projection, services, participation, profils, guardians, volunteers } = body; // Update the mission data const updatedMission = await prisma.mission.update({ where: { id: missionId }, data: { name, logo, oddScope: oddScope || undefined, niveau, intention, missionType, donneurDOrdre, projection, services: services || undefined, participation, profils: profils || undefined } }); // Update guardians if provided if (guardians) { // Get current guardians const currentGuardians = await prisma.missionUser.findMany({ where: { missionId, role: { in: ['gardien-temps', 'gardien-parole', 'gardien-memoire'] } } }); // Delete all guardians if (currentGuardians.length > 0) { await prisma.missionUser.deleteMany({ where: { missionId, role: { in: ['gardien-temps', 'gardien-parole', 'gardien-memoire'] } } }); } // Add new guardians const guardianRoles = ['gardien-temps', 'gardien-parole', 'gardien-memoire']; const guardianEntries = Object.entries(guardians) .filter(([role, userId]) => guardianRoles.includes(role) && userId) .map(([role, userId]) => ({ role, userId: userId as string, missionId })); if (guardianEntries.length > 0) { await prisma.missionUser.createMany({ data: guardianEntries }); } } // Update volunteers if provided if (volunteers) { // Get current volunteers const currentVolunteers = await prisma.missionUser.findMany({ where: { missionId, role: 'volontaire' } }); // Delete all volunteers if (currentVolunteers.length > 0) { await prisma.missionUser.deleteMany({ where: { missionId, role: 'volontaire' } }); } // Add new volunteers if (volunteers.length > 0) { const volunteerEntries = volunteers.map((userId: string) => ({ role: 'volontaire', userId, missionId })); await prisma.missionUser.createMany({ data: volunteerEntries }); } } return NextResponse.json({ success: true, mission: { id: updatedMission.id, name: updatedMission.name, updatedAt: updatedMission.updatedAt } }); } catch (error) { console.error('Error updating mission:', error); return NextResponse.json({ error: 'Internal server error', details: error instanceof Error ? error.message : String(error) }, { status: 500 }); } } // DELETE endpoint to remove a mission export async function DELETE(request: Request, props: { params: Promise<{ missionId: string }> }) { const params = await props.params; try { const { authorized, userId } = await checkAuth(request); if (!authorized || !userId) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } const { missionId } = params; if (!missionId) { return NextResponse.json({ error: 'Mission ID is required' }, { status: 400 }); } // Check if mission exists and user is the creator const mission = await prisma.mission.findFirst({ where: { id: missionId, creatorId: userId // Only creator can delete a mission }, include: { attachments: true } }); if (!mission) { return NextResponse.json({ error: 'Mission not found or not authorized to delete' }, { status: 404 }); } // Delete logo if exists if (mission.logo) { try { await deleteMissionLogo(mission.logo); } catch (error) { console.error('Error deleting mission logo:', error); // Continue deletion even if logo deletion fails } } // Delete mission (cascade will handle missionUsers and attachments) await prisma.mission.delete({ where: { id: missionId } }); return NextResponse.json({ success: true }); } catch (error) { console.error('Error deleting mission:', error); return NextResponse.json({ error: 'Internal server error', details: error instanceof Error ? error.message : String(error) }, { status: 500 }); } }