Perbaikan update route
Perbaikan update route
Section titled “Perbaikan update route”Hanya mengubah field yang benar-benar dikirim.
Berkas: alat/hari-3/Praktik 9/perbaikan/update-route.js
// =====================================================================// Praktik 9 - versi perbaikan update/route.js//// Perubahan dari versi modul://// 1. requireAuth() dijalankan sebelum body dibaca.//// 2. HANYA field yang benar-benar dikirim yang ikut di-update. Versi modul// selalu menulis// data: { role: data.role, is_active: data.is_active }// sehingga permintaan yang hanya ingin mengubah role tetap mengirim// is_active: undefined. Perilaku Prisma untuk undefined adalah// "jangan ubah", jadi kebetulan tidak merusak — tetapi ini bergantung// pada detail implementasi, bukan pada niat penulis kode. Kalau// suatu saat nilainya null (bukan undefined), kolomnya benar-benar// dikosongkan.//// 3. Ada penjagaan agar super_admin tidak bisa diturunkan menjadi admin// lewat API ini. Versi modul membatasi daftar role, tetapi tidak// melindungi akun super_admin yang sudah ada dari perubahan is_active.//// 4. Ada penjagaan agar pengguna tidak menonaktifkan dirinya sendiri.//// 5. Respons memakai select yang sama seperti list — tanpa kolom password.//// Letakkan berkas ini di: src/app/api/users/update/route.js// =====================================================================
import { NextResponse } from "next/server";import { requireAuth } from "../../../../../lib/auth/verifyBearerToken";import { db } from "../../../../../lib/db";import { ROLE_DAPAT_DIUBAH } from "../../../../../lib/auth/roles";
export async function POST(request) { const { payload, error, status } = requireAuth(request, "super_admin"); if (error) { return NextResponse.json({ message: error }, { status }); }
let data; try { data = await request.json(); } catch { return NextResponse.json({ message: "Body harus berupa JSON" }, { status: 400 }); }
const userId = typeof data.user_id === "string" ? data.user_id : ""; if (!userId) { return NextResponse.json({ message: "user_id wajib diisi" }, { status: 400 }); }
const adaRole = data.role !== undefined; const adaIsActive = data.is_active !== undefined;
if (!adaRole && !adaIsActive) { return NextResponse.json( { message: "Tidak ada field yang diubah" }, { status: 400 }, ); }
if (adaRole && !ROLE_DAPAT_DIUBAH.includes(data.role)) { return NextResponse.json( { message: `Role tidak valid. Pilihan: ${ROLE_DAPAT_DIUBAH.join(", ")}` }, { status: 400 }, ); } if (adaIsActive && typeof data.is_active !== "boolean") { return NextResponse.json({ message: "is_active harus true atau false" }, { status: 400 }); }
// Jangan biarkan super_admin menonaktifkan atau menurunkan dirinya sendiri. if (payload.user_id === userId) { if (adaIsActive && data.is_active === false) { return NextResponse.json( { message: "Tidak bisa menonaktifkan akun sendiri" }, { status: 400 }, ); } if (adaRole && data.role !== "super_admin") { return NextResponse.json( { message: "Tidak bisa menurunkan role akun sendiri" }, { status: 400 }, ); } }
try { const target = await db.users.findUnique({ where: { user_id: userId }, select: { user_id: true, role: true, is_active: true }, }); if (!target) { return NextResponse.json({ message: "User tidak ditemukan" }, { status: 404 }); }
// Akun super_admin tidak boleh diturunkan lewat endpoint ini. // Untuk itu perlu jalur terpisah dengan pencatatan audit. if (target.role === "super_admin" && adaRole && data.role !== "super_admin") { return NextResponse.json( { message: "Role super_admin tidak dapat diubah lewat endpoint ini" }, { status: 403 }, ); }
// Hanya sertakan field yang dikirim. const perubahan = {}; if (adaRole) perubahan.role = data.role; if (adaIsActive) perubahan.is_active = data.is_active;
const pengguna = await db.users.update({ where: { user_id: userId }, data: perubahan, select: { user_id: true, nama: true, email: true, role: true, is_active: true, }, });
return NextResponse.json( { message: "Berhasil memperbarui data user", data: pengguna }, { status: 200 }, ); } catch (err) { console.error("[users/update]", err); return NextResponse.json({ message: "Terjadi kesalahan pada server" }, { status: 500 }); }}