NeahStable/app/api/calendars/[calendarId]/route.ts
2026-01-21 00:34:52 +01:00

186 lines
5.4 KiB
TypeScript

import { NextRequest, NextResponse } from "next/server";
import { getServerSession } from "next-auth/next";
import { authOptions } from "@/app/api/auth/options";
import { prisma } from "@/lib/prisma";
import logger from "@/utils/logger";
/**
* GET /api/calendars/[calendarId]
* Retrieves a specific calendar
*/
export async function GET(
req: NextRequest,
{ params }: { params: Promise<{ calendarId: string }> }
) {
const session = await getServerSession(authOptions);
if (!session?.user?.id) {
return NextResponse.json({ error: "Non authentifié" }, { status: 401 });
}
try {
const { calendarId } = await params;
const calendar = await prisma.calendar.findUnique({
where: { id: calendarId },
include: {
events: {
orderBy: {
start: 'asc'
}
},
mission: true,
},
});
if (!calendar) {
return NextResponse.json({ error: "Calendrier non trouvé" }, { status: 404 });
}
// Check if user has access to this calendar
const hasAccess =
calendar.userId === session.user.id || // User owns the calendar
calendar.isPublic || // Calendar is public
(calendar.mission && calendar.mission.creatorId === session.user.id); // User created the mission
if (!hasAccess) {
return NextResponse.json({ error: "Non autorisé" }, { status: 403 });
}
return NextResponse.json(calendar);
} catch (error) {
logger.error('Error fetching calendar', { error });
return NextResponse.json({ error: "Erreur serveur" }, { status: 500 });
}
}
/**
* DELETE /api/calendars/[calendarId]
* Deletes a calendar and all its events
*/
export async function DELETE(
req: NextRequest,
{ params }: { params: Promise<{ calendarId: string }> }
) {
const session = await getServerSession(authOptions);
if (!session?.user?.id) {
return NextResponse.json({ error: "Non authentifié" }, { status: 401 });
}
try {
const { calendarId } = await params;
const calendar = await prisma.calendar.findUnique({
where: { id: calendarId },
include: {
mission: true,
},
});
if (!calendar) {
return NextResponse.json({ error: "Calendrier non trouvé" }, { status: 404 });
}
// Check permissions
// Only allow deletion if:
// 1. User owns the calendar
// 2. OR it's a group calendar (starts with "Groupe:")
// 3. OR user created the associated mission
const isOwner = calendar.userId === session.user.id;
const isGroupCalendar = calendar.name.startsWith("Groupe:");
const isMissionCreator = calendar.mission && calendar.mission.creatorId === session.user.id;
if (!isOwner && !isGroupCalendar && !isMissionCreator) {
return NextResponse.json(
{ error: "Vous n'avez pas la permission de supprimer ce calendrier" },
{ status: 403 }
);
}
// For group calendars, verify the group no longer exists
if (isGroupCalendar) {
logger.info('Deleting group calendar', {
calendarId,
calendarName: calendar.name,
userId: session.user.id
});
}
// Delete the calendar (cascade will delete events)
await prisma.calendar.delete({
where: { id: calendarId },
});
logger.info('Calendar deleted successfully', {
calendarId,
calendarName: calendar.name
});
return NextResponse.json({ success: true, message: "Calendrier supprimé avec succès" });
} catch (error) {
logger.error('Error deleting calendar', { error });
return NextResponse.json({ error: "Erreur lors de la suppression du calendrier" }, { status: 500 });
}
}
/**
* PATCH /api/calendars/[calendarId]
* Updates calendar properties (name, color, description, etc.)
*/
export async function PATCH(
req: NextRequest,
{ params }: { params: Promise<{ calendarId: string }> }
) {
const session = await getServerSession(authOptions);
if (!session?.user?.id) {
return NextResponse.json({ error: "Non authentifié" }, { status: 401 });
}
try {
const { calendarId } = await params;
const body = await req.json();
const calendar = await prisma.calendar.findUnique({
where: { id: calendarId },
include: {
mission: true,
},
});
if (!calendar) {
return NextResponse.json({ error: "Calendrier non trouvé" }, { status: 404 });
}
// Check permissions
const isOwner = calendar.userId === session.user.id;
const isMissionCreator = calendar.mission && calendar.mission.creatorId === session.user.id;
if (!isOwner && !isMissionCreator) {
return NextResponse.json(
{ error: "Vous n'avez pas la permission de modifier ce calendrier" },
{ status: 403 }
);
}
// Update calendar
const updatedCalendar = await prisma.calendar.update({
where: { id: calendarId },
data: {
...(body.name && { name: body.name }),
...(body.color && { color: body.color }),
...(body.description !== undefined && { description: body.description }),
...(body.isPublic !== undefined && { isPublic: body.isPublic }),
},
});
logger.info('Calendar updated successfully', {
calendarId,
updatedFields: Object.keys(body)
});
return NextResponse.json(updatedCalendar);
} catch (error) {
logger.error('Error updating calendar', { error });
return NextResponse.json({ error: "Erreur lors de la mise à jour du calendrier" }, { status: 500 });
}
}