CLI Generator Fitur & Sinkronisasi Database
Perkakas baris perintah yang melahirkan seluruh file fitur baru sekaligus mendaftarkan skema Prisma, konstanta RBAC, dan menu navigasi secara otomatis.
Membaca sekitar 2 menit
Perkakas baris perintah yang melahirkan seluruh file fitur baru sekaligus mendaftarkan skema Prisma, konstanta RBAC, dan menu navigasi secara otomatis.
Menjalankan npm run make:feature disusul npm run db:sync langsung menyiapkan modul CRUD utuh beserta hak akses penuh untuk Super Admin dalam hitungan detik.
Aturan arsitektur di dokumentasi sering dilanggar karena lupa; mengubah aturan menjadi generator kode membuatnya mustahil terlewat.
Masalahnya dulu
Setelah menetapkan standar arsitektur 8-file, desain komponen terpusat (form-styles.ts, Modal.tsx, Pagination.tsx), serta aturan RBAC, tantangan berikutnya adalah konsistensi. Menulis 8 hingga 10 file baru secara manual setiap kali ingin menambah menu master data baru sangat melelahkan dan rawan salah ketik—apalagi jika proyek dikerjakan bersama tim atau dibantu oleh agen AI.
Mengubah standar arsitektur menjadi mesin pembuat kode
Saya membangun skrip CLI di scripts/make-feature.mjs yang dipanggil lewat perintah npm run make:feature <key> "<Label>" [plural_slug]. Dalam satu kali jalan, skrip ini merakit seluruh file modul di modules/dashboard/<key>/, membungkus halaman di app/(dashboard)/dashboard/<slug>/page.tsx, membuat endpoint GET di app/api/<slug>/route.ts, menyuntikkan model baru ke prisma/schema.prisma, mendaftarkan key fitur ke rbac.constant.ts, dan menambahkan item menu ke navigation.constant.ts. Bahkan tersedia flag --with-image untuk menyertakan fitur unggah gambar lengkap dengan validasi magic bytes.
Jangan hanya menulis dokumen panduan tentang cara membuat fitur yang benar; buatlah perintah CLI yang langsung melahirkan fitur tersebut tanpa cacat.
Implementasi di ngodingan ini
Setelah file di-generate oleh make-feature.mjs, skrip kedua yaitu scripts/sync-features.ts (npm run db:sync) menyelaraskan konstanta fitur di kode dengan tabel database:
// scripts/sync-features.ts
for (const f of FEATURES) {
let feat = await prisma.feature.findUnique({ where: { key: f.key } });
if (!feat) {
feat = await prisma.feature.create({
data: {
key: f.key,
name: f.name,
desc: f.desc,
availableActions: [...ACTIONS],
},
});
console.log(`+ Fitur baru dibuat: ${f.name} (${f.key})`);
}
// Pastikan Super Admin otomatis memiliki permission penuh
const saPerm = await prisma.rolePermission.findFirst({
where: { roleUuid: superAdminRole.uuid, featureUuid: feat.uuid },
});
if (!saPerm) {
await prisma.rolePermission.create({
data: {
roleUuid: superAdminRole.uuid,
featureUuid: feat.uuid,
isRead: true, isAdd: true, isEdit: true, isDelete: true,
},
});
}
}Jebakan dan detail yang harus dijaga
- Injeksi kode yang idempoten: Skrip make-feature.mjs memeriksa terlebih dahulu apakah model Prisma atau konstanta fitur sudah ada di dalam file target sebelum menyisipkan baris baru, sehingga tidak merusak file jika dijalankan ulang.
- Sinkronisasi non-destruktif dengan db:sync: Berbeda dengan db:seed yang mereset tabel untuk kebutuhan inisialisasi awal, perintah npm run db:sync hanya menambahkan fitur yang belum ada dan memberi akses ke Super Admin tanpa mengubah izin role lain yang sudah berjalan di produksi.