import { NextRequest, NextResponse } from "next/server"; import { auth } from "@/auth"; import { prisma } from "@/lib/db"; const VALID_ROLES = ["viewer", "reviewer", "editor", "admin"]; async function requireAdmin(orgId: string, userId: string) { const membership = await prisma.orgMember.findFirst({ where: { userId, organizationId: orgId }, }); if (!membership || !["owner", "admin"].includes(membership.role)) { return null; } return membership; } export async function PATCH( req: NextRequest, { params }: { params: Promise<{ id: string }> } ) { try { const session = await auth(); if (!session?.user?.orgId || !session.user.id) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } const callerMembership = await requireAdmin(session.user.orgId, session.user.id); if (!callerMembership) { return NextResponse.json({ error: "Forbidden" }, { status: 403 }); } const { id } = await params; const { role } = await req.json(); if (!role || !VALID_ROLES.includes(role)) { return NextResponse.json( { error: `Role must be one of: ${VALID_ROLES.join(", ")}` }, { status: 400 } ); } const target = await prisma.orgMember.findFirst({ where: { id, organizationId: session.user.orgId }, }); if (!target) { return NextResponse.json({ error: "Member not found" }, { status: 404 }); } if (target.role === "owner") { return NextResponse.json( { error: "Cannot change the owner's role" }, { status: 403 } ); } if (target.userId === session.user.id) { return NextResponse.json( { error: "You cannot change your own role" }, { status: 403 } ); } const updated = await prisma.orgMember.update({ where: { id }, data: { role }, include: { user: { select: { id: true, email: true, displayName: true } } }, }); return NextResponse.json({ member: updated }); } catch (error) { console.error("[org/members/[id]] PATCH error:", error); return NextResponse.json({ error: "Failed to update member" }, { status: 500 }); } } export async function DELETE( _req: NextRequest, { params }: { params: Promise<{ id: string }> } ) { try { const session = await auth(); if (!session?.user?.orgId || !session.user.id) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } const callerMembership = await requireAdmin(session.user.orgId, session.user.id); if (!callerMembership) { return NextResponse.json({ error: "Forbidden" }, { status: 403 }); } const { id } = await params; const target = await prisma.orgMember.findFirst({ where: { id, organizationId: session.user.orgId }, }); if (!target) { return NextResponse.json({ error: "Member not found" }, { status: 404 }); } if (target.role === "owner") { return NextResponse.json( { error: "Cannot remove the organization owner" }, { status: 403 } ); } if (target.userId === session.user.id) { return NextResponse.json( { error: "You cannot remove yourself" }, { status: 403 } ); } await prisma.$transaction([ prisma.orgMember.delete({ where: { id } }), prisma.user.updateMany({ where: { id: target.userId, activeOrgId: session.user.orgId }, data: { activeOrgId: null }, }), ]); return NextResponse.json({ success: true }); } catch (error) { console.error("[org/members/[id]] DELETE error:", error); return NextResponse.json({ error: "Failed to remove member" }, { status: 500 }); } }