/** * @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} 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} 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 }, ); } }