NeahStable/app/api/calendars/route.ts
2026-01-15 13:22:43 +01:00

184 lines
6.1 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 { getCachedCalendarData, cacheCalendarData } from "@/lib/redis";
import { logger } from "@/lib/logger";
/**
* Handles the GET request to retrieve calendars for the authenticated user.
*
* @param {NextRequest} req - The incoming request object.
* @returns {Promise<NextResponse>} - A promise that resolves to a JSON response containing the calendars or an error message.
*
* The function performs the following steps:
* 1. Retrieves the server session using `getServerSession`.
* 2. Checks if the user is authenticated by verifying the presence of `session.user.id`.
* - If not authenticated, returns a 401 response with an error message.
* 3. Attempts to fetch the calendars associated with the authenticated user from the database.
* - If successful, returns the calendars in a JSON response.
* - If an error occurs during the database query, logs the error and returns a 500 response with an error message.
*/
export async function GET(req: NextRequest) {
const session = await getServerSession(authOptions);
if (!session?.user?.id) {
return NextResponse.json({ error: "Non authentifié" }, { status: 401 });
}
try {
// Check for force refresh parameter
const url = new URL(req.url);
const forceRefresh = url.searchParams.get('refresh') === 'true';
// Try to get data from cache if not forcing refresh
if (!forceRefresh) {
const cachedData = await getCachedCalendarData(session.user.id);
if (cachedData) {
logger.debug('[CALENDAR] Using cached calendar data', {
userId: session.user.id,
calendarCount: cachedData.length,
});
return NextResponse.json(cachedData);
}
}
// If no cache or forcing refresh, fetch from database
logger.debug('[CALENDAR] Fetching calendar data from database', {
userId: session.user.id,
});
// Get user's personal calendars
const personalCalendars = await prisma.calendar.findMany({
where: {
userId: session.user.id,
},
include: {
events: {
orderBy: {
start: 'asc'
}
},
mission: {
include: {
missionUsers: true
}
}
},
orderBy: {
createdAt: "desc",
},
});
// Get mission calendars where user is associated via MissionUser
const missionUserRelations = await prisma.missionUser.findMany({
where: {
userId: session.user.id,
},
include: {
mission: {
include: {
calendars: {
include: {
events: {
orderBy: {
start: 'asc'
}
},
mission: {
include: {
missionUsers: true
}
}
}
}
}
}
}
});
// Extract mission calendars (excluding those already in personalCalendars)
// Use a Set to avoid duplicate calendars by ID
const personalCalendarIds = new Set(personalCalendars.map(cal => cal.id));
const missionCalendars = missionUserRelations
.flatMap(mu => mu.mission.calendars)
.filter(cal => !personalCalendarIds.has(cal.id)); // Exclude calendars already in personalCalendars
// Combine personal and mission calendars
const calendars = [...personalCalendars, ...missionCalendars];
// Remove duplicate calendars by ID (in case same calendar appears multiple times)
const uniqueCalendars = Array.from(
new Map(calendars.map(cal => [cal.id, cal])).values()
);
logger.debug('[CALENDAR] Fetched calendars with events', {
userId: session.user.id,
personalCount: personalCalendars.length,
missionCount: missionCalendars.length,
totalCount: uniqueCalendars.length,
});
// Cache the results
await cacheCalendarData(session.user.id, uniqueCalendars);
return NextResponse.json(uniqueCalendars);
} catch (error) {
logger.error('[CALENDAR] Erreur lors de la récupération des calendriers', {
error: error instanceof Error ? error.message : String(error),
});
return NextResponse.json({ error: "Erreur serveur" }, { status: 500 });
}
}
/**
* Handles the POST request to create a new calendar.
*
* @param {NextRequest} req - The incoming request object.
* @returns {Promise<NextResponse>} The response object containing the created calendar or an error message.
*
* @throws {Error} If there is an issue with the request or server.
*
* The function performs the following steps:
* 1. Retrieves the server session using `getServerSession`.
* 2. Checks if the user is authenticated by verifying the presence of `session.user.id`.
* 3. Parses the request body to extract `name`, `color`, and `description`.
* 4. Validates that the `name` field is provided.
* 5. Creates a new calendar entry in the database using Prisma.
* 6. Returns the created calendar with a 201 status code.
* 7. Catches and logs any errors, returning a 500 status code with an error message.
*/
export async function POST(req: NextRequest) {
const session = await getServerSession(authOptions);
if (!session?.user?.id) {
return NextResponse.json({ error: "Non authentifié" }, { status: 401 });
}
try {
const { name, color, description } = await req.json();
// Validation
if (!name) {
return NextResponse.json(
{ error: "Le nom du calendrier est requis" },
{ status: 400 }
);
}
const calendar = await prisma.calendar.create({
data: {
name,
color: color || "#0082c9",
description,
userId: session.user.id,
},
});
return NextResponse.json(calendar, { status: 201 });
} catch (error) {
console.error("Erreur lors de la création du calendrier:", error);
return NextResponse.json({ error: "Erreur serveur" }, { status: 500 });
}
}