import { NextRequest, NextResponse } from "next/server"; import { Pool } from "pg"; import { requireAdmin, requireSuperAdmin } from "@/lib/auth-utils"; const pool = new Pool({ connectionString: process.env.DATABASE_URL, }); // GET /api/admin/roles/[id] - Get a single role export async function GET( request: NextRequest, { params }: { params: Promise<{ id: string }> } ) { const { error } = await requireAdmin(); if (error) return error; try { const { id } = await params; const result = await pool.query( `SELECT r.id, r.name, r.description, r.permissions, r.is_system, r.created_at, r.updated_at, COUNT(DISTINCT u.id) as user_count FROM "role" r LEFT JOIN "user" u ON u.role = r.name WHERE r.id = $1 GROUP BY r.id`, [id] ); if (result.rows.length === 0) { return NextResponse.json({ error: "Role not found" }, { status: 404 }); } return NextResponse.json({ role: result.rows[0] }); } catch (error) { console.error("Error fetching role:", error); return NextResponse.json( { error: "Failed to fetch role" }, { status: 500 } ); } } // PATCH /api/admin/roles/[id] - Update a role export async function PATCH( request: NextRequest, { params }: { params: Promise<{ id: string }> } ) { const { error } = await requireSuperAdmin(); if (error) return error; try { const { id } = await params; const body = await request.json(); const { name, description, permissions } = body; // Check if role exists const existingRole = await pool.query( 'SELECT id, is_system, name FROM "role" WHERE id = $1', [id] ); if (existingRole.rows.length === 0) { return NextResponse.json({ error: "Role not found" }, { status: 404 }); } // Prevent modifying system roles' names if (existingRole.rows[0].is_system && name && name !== existingRole.rows[0].name) { return NextResponse.json( { error: "Cannot rename system roles" }, { status: 400 } ); } // Build update query const updates: string[] = []; const values: (string | null)[] = []; let paramIndex = 1; if (name !== undefined) { updates.push(`name = $${paramIndex++}`); values.push(name); } if (description !== undefined) { updates.push(`description = $${paramIndex++}`); values.push(description); } if (permissions !== undefined) { updates.push(`permissions = $${paramIndex++}`); values.push(JSON.stringify(permissions)); } if (updates.length === 0) { return NextResponse.json( { error: "No fields to update" }, { status: 400 } ); } updates.push(`updated_at = NOW()`); values.push(id); const result = await pool.query( `UPDATE "role" SET ${updates.join(", ")} WHERE id = $${paramIndex} RETURNING id, name, description, permissions, is_system, updated_at`, values ); return NextResponse.json({ role: result.rows[0] }); } catch (error) { console.error("Error updating role:", error); return NextResponse.json( { error: "Failed to update role" }, { status: 500 } ); } } // DELETE /api/admin/roles/[id] - Delete a role export async function DELETE( request: NextRequest, { params }: { params: Promise<{ id: string }> } ) { const { error } = await requireSuperAdmin(); if (error) return error; try { const { id } = await params; // Check if role exists and is not a system role const existingRole = await pool.query( 'SELECT id, is_system, name FROM "role" WHERE id = $1', [id] ); if (existingRole.rows.length === 0) { return NextResponse.json({ error: "Role not found" }, { status: 404 }); } if (existingRole.rows[0].is_system) { return NextResponse.json( { error: "Cannot delete system roles" }, { status: 400 } ); } // Check if role is assigned to any users const usersWithRole = await pool.query( 'SELECT COUNT(*) as count FROM "user" WHERE role = $1', [existingRole.rows[0].name] ); if (parseInt(usersWithRole.rows[0].count) > 0) { return NextResponse.json( { error: "Cannot delete role that is assigned to users" }, { status: 400 } ); } await pool.query('DELETE FROM "role" WHERE id = $1', [id]); return NextResponse.json({ success: true }); } catch (error) { console.error("Error deleting role:", error); return NextResponse.json( { error: "Failed to delete role" }, { status: 500 } ); } }