waveform/app/api/channels/[channelId]/route.ts

144 lines
4 KiB
TypeScript

/**
* @file app/api/channels/[channelId]/route.ts
* @description API route handler for updating and deleting channels.
*/
import { auth } from "@/auth";
import { db } from "@/db";
import { channels, members } from "@/db/schema";
import { and, eq } from "drizzle-orm";
import { NextResponse } from "next/server";
/**
* Handles PATCH requests to update an existing channel's name.
*
* @async
* @function PATCH
* @param {Request} req - The incoming HTTP request object containing the updated channel name in the body.
* @param {Object} context - The route context parameters.
* @param {Promise<{ channelId: string }>} context.params - A promise resolving to the route parameters containing the channel ID.
* @returns {Promise<NextResponse>} A JSON response containing the updated channel object or an error message.
*/
export async function PATCH(
req: Request,
{ params }: { params: Promise<{ channelId: string }> },
) {
try {
const { channelId } = await params;
const session = await auth();
const { name } = await req.json();
if (!session?.user?.id) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
if (!name || !name.trim()) {
return NextResponse.json(
{ error: "Channel name cannot be empty" },
{ status: 400 },
);
}
const [existingChannel] = await db
.select()
.from(channels)
.where(eq(channels.id, channelId))
.limit(1);
if (!existingChannel) {
return NextResponse.json({ error: "Channel not found" }, { status: 404 });
}
// Check if the user is a member of the server
const [member] = await db
.select()
.from(members)
.where(
and(
eq(members.userId, session.user.id),
eq(members.serverId, existingChannel.serverId),
),
)
.limit(1);
if (!member) {
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
}
// Update Channel
const [updatedChannel] = await db
.update(channels)
.set({ name: name.trim() })
.where(eq(channels.id, channelId))
.returning();
return NextResponse.json(updatedChannel);
} catch (error) {
console.error("API Channel PATCH error:", error);
return NextResponse.json(
{ error: "Internal Server Error" },
{ status: 500 },
);
}
}
/**
* Handles DELETE requests to remove an existing channel.
*
* @async
* @function DELETE
* @param {Request} req - The incoming HTTP request object.
* @param {Object} context - The route context parameters.
* @param {Promise<{ channelId: string }>} context.params - A promise resolving to the route parameters containing the channel ID.
* @returns {Promise<NextResponse>} A JSON response confirming deletion or returning an error message.
*/
export async function DELETE(
req: Request,
{ params }: { params: Promise<{ channelId: string }> },
) {
try {
const { channelId } = await params;
const session = await auth();
if (!session?.user?.id) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
const [existingChannel] = await db
.select()
.from(channels)
.where(eq(channels.id, channelId))
.limit(1);
if (!existingChannel) {
return NextResponse.json({ error: "Channel not found" }, { status: 404 });
}
// Check if the user is a member of the server
const [member] = await db
.select()
.from(members)
.where(
and(
eq(members.userId, session.user.id),
eq(members.serverId, existingChannel.serverId),
),
)
.limit(1);
if (!member) {
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
}
// Delete Channel
await db.delete(channels).where(eq(channels.id, channelId));
return NextResponse.json({ success: true });
} catch (error) {
console.error("API Channel DELETE error:", error);
return NextResponse.json(
{ error: "Internal Server Error" },
{ status: 500 },
);
}
}