feat(api): implement event management endpoints for GET, DELETE, and PATCH operations

This commit is contained in:
Dominik 2025-06-14 11:41:10 +02:00
parent 62d45fb590
commit ae8c4da25d
Signed by: dominik
GPG key ID: 06A4003FC5049644
2 changed files with 412 additions and 2 deletions

View file

@ -0,0 +1,410 @@
import { prisma } from '@/prisma';
import { auth } from '@/auth';
import { NextResponse } from 'next/server';
/**
* @swagger
* /api/event/{eventID}:
* get:
* summary: Get details of a specific event
* description: Returns the details of an event by its ID.
* parameters:
* - in: path
* name: eventID
* required: true
* schema:
* type: string
* description: The ID of the event to retrieve.
* responses:
* 200:
* description: Event details retrieved successfully.
* content:
* application/json:
* schema:
* type: object
* properties:
* success:
* type: boolean
* event:
* $ref: '#/components/schemas/Event'
* 401:
* description: Not authenticated.
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/ErrorResponse'
* example:
* success: false
* message: Not authenticated
* 404:
* description: User or event not found.
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/ErrorResponse'
*/
export const GET = auth(async (req, { params }) => {
if (!req.auth)
return NextResponse.json(
{ success: false, message: 'Not authenticated' },
{ status: 401 },
);
if (!req.auth.user || !req.auth.user.id)
return NextResponse.json(
{ success: false, message: 'User not found' },
{ status: 404 },
);
const dbUser = await prisma.user.findUnique({
where: {
id: req.auth.user.id,
},
});
if (!dbUser) {
return NextResponse.json(
{ success: false, message: 'User not found' },
{ status: 404 },
);
}
const eventID = (await params).eventID;
const event = await prisma.meeting.findUnique({
where: {
id: eventID,
},
include: {
organizer: true,
participants: {
include: {
user: true,
},
},
},
});
if (!event) {
return NextResponse.json(
{ success: false, message: 'Event not found' },
{ status: 404 },
);
}
return NextResponse.json(
{
success: true,
event: {
id: event.id,
title: event.title,
description: event.description,
start_time: event.start_time,
end_time: event.end_time,
status: event.status,
location: event.location,
organizer: {
id: event.organizer.id,
name: event.organizer.name,
},
participants: event.participants.map((participant) => ({
id: participant.user.id,
name: participant.user.name,
})),
},
},
{ status: 200 },
);
});
/**
* @swagger
* /api/event/{eventID}:
* delete:
* summary: Delete a specific event
* description: Deletes an event by its ID if the user is the organizer.
* parameters:
* - in: path
* name: eventID
* required: true
* schema:
* type: string
* description: The ID of the event to delete.
* responses:
* 200:
* description: Event deleted successfully.
* content:
* application/json:
* schema:
* type: object
* properties:
* success:
* type: boolean
* message:
* type: string
* 401:
* description: Not authenticated.
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/ErrorResponse'
* example:
* success: false
* message: Not authenticated
* 403:
* description: User is not the organizer.
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/ErrorResponse'
* example:
* success: false
* message: You are not the organizer of this event
* 404:
* description: User or event not found.
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/ErrorResponse'
*/
export const DELETE = auth(async (req, { params }) => {
if (!req.auth)
return NextResponse.json(
{ success: false, message: 'Not authenticated' },
{ status: 401 },
);
if (!req.auth.user || !req.auth.user.id)
return NextResponse.json(
{ success: false, message: 'User not found' },
{ status: 404 },
);
const dbUser = await prisma.user.findUnique({
where: {
id: req.auth.user.id,
},
});
if (!dbUser) {
return NextResponse.json(
{ success: false, message: 'User not found' },
{ status: 404 },
);
}
const eventID = (await params).eventID;
const event = await prisma.meeting.findUnique({
where: {
id: eventID,
},
});
if (!event) {
return NextResponse.json(
{ success: false, message: 'Event not found' },
{ status: 404 },
);
}
if (event.organizer_id !== dbUser.id) {
return NextResponse.json(
{ success: false, message: 'You are not the organizer of this event' },
{ status: 403 },
);
}
await prisma.meeting.delete({
where: {
id: eventID,
},
});
return NextResponse.json(
{ success: true, message: 'Event deleted successfully' },
{ status: 200 },
);
});
/**
* @swagger
* /api/event/{eventID}:
* patch:
* summary: Update a specific event
* description: Updates an event by its ID if the user is the organizer.
* parameters:
* - in: path
* name: eventID
* required: true
* schema:
* type: string
* description: The ID of the event to update.
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* title:
* type: string
* description:
* type: string
* start_time:
* type: string
* format: date-time
* end_time:
* type: string
* format: date-time
* location:
* type: string
* status:
* type: string
* enum: [TENTATIVE, CONFIRMED, CANCELLED]
* responses:
* 200:
* description: Event updated successfully.
* content:
* application/json:
* schema:
* type: object
* properties:
* success:
* type: boolean
* event:
* $ref: '#/components/schemas/Event'
* 400:
* description: Invalid input data.
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/ErrorResponse'
* 401:
* description: Not authenticated.
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/ErrorResponse'
* example:
* success: false
* message: Not authenticated
* 403:
* description: User is not the organizer.
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/ErrorResponse'
* example:
* success: false
* message: You are not the organizer of this event
* 404:
* description: User or event not found.
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/ErrorResponse'
* example:
* success: false
* message: User or event not found
*/
export const PATCH = auth(async (req, { params }) => {
if (!req.auth)
return NextResponse.json(
{ success: false, message: 'Not authenticated' },
{ status: 401 },
);
if (!req.auth.user || !req.auth.user.id)
return NextResponse.json(
{ success: false, message: 'User not found' },
{ status: 404 },
);
const dbUser = await prisma.user.findUnique({
where: {
id: req.auth.user.id,
},
});
if (!dbUser) {
return NextResponse.json(
{ success: false, message: 'User not found' },
{ status: 404 },
);
}
const eventID = (await params).eventID;
const event = await prisma.meeting.findUnique({
where: {
id: eventID,
},
});
if (!event) {
return NextResponse.json(
{ success: false, message: 'Event not found' },
{ status: 404 },
);
}
if (event.organizer_id !== dbUser.id) {
return NextResponse.json(
{ success: false, message: 'You are not the organizer of this event' },
{ status: 403 },
);
}
const body = await req.json();
const { title, description, start_time, end_time, location, status } = body;
if (!title && !description && !start_time && !end_time && !location && !status) {
return NextResponse.json(
{ success: false, message: 'No fields to update' },
{ status: 400 },
);
}
const updateData: Record<string, string> = {};
if (title) updateData.title = title;
if (description) updateData.description = description;
if (start_time) {
const startTimeValidation = new Date(start_time);
if (isNaN(startTimeValidation.getTime())) {
return NextResponse.json(
{ success: false, message: 'Invalid start time' },
{ status: 400 },
);
}
updateData.start_time = startTimeValidation.getTime().toString();
}
if (end_time) {
const endTimeValidation = new Date(end_time);
if (isNaN(endTimeValidation.getTime())) {
return NextResponse.json(
{ success: false, message: 'Invalid end time' },
{ status: 400 },
);
}
updateData.end_time = endTimeValidation.getTime().toString();
}
if (location) updateData.location = location;
if (status) {
const validStatuses = ['TENTATIVE', 'CONFIRMED', 'CANCELLED'];
if (!validStatuses.includes(status.toUpperCase())) {
return NextResponse.json(
{ success: false, message: 'Invalid status' },
{ status: 400 },
);
}
updateData.status = status.toUpperCase();
}
const updatedEvent = await prisma.meeting.update({
where: {
id: eventID,
},
data: updateData,
});
return NextResponse.json({ success: true, event: updatedEvent }, { status: 200 });
});

View file

@ -89,7 +89,7 @@ export const GET = auth(async function GET(req) {
/**
* @swagger
* /api/user/me:
* put:
* patch:
* description: Update the information of the currently authenticated user.
* requestBody:
* required: true
@ -163,7 +163,7 @@ export const GET = auth(async function GET(req) {
* message: 'No fields to update'
* }
*/
export const PUT = auth(async function PUT(req) {
export const PATCH = auth(async function PATCH(req) {
if (!req.auth)
return NextResponse.json(
{ success: false, message: 'Not authenticated' },