Lewati ke konten utama

Beranda / Proyek / APMNU — Asosiasi Profesor Muslimat NU

Proyek pilihan

APMNU — Asosiasi Profesor Muslimat NU

Platform organisasi untuk para profesor perempuan NU: situs publik, portal mandiri profesor, dan panel admin dalam satu monorepo Nuxt + NestJS.

Peran

Project Manager & Full-Stack Developer

Durasi

4 bulan

Tim

4 pengembang

APMNU — Asosiasi Profesor Muslimat NU: tampilan lanskap
APMNU — Asosiasi Profesor Muslimat NU: tampilan potret

Teknologi

NestJS · Nuxt 4 · Prisma · PostgreSQL · TypeScript · Zod · Turborepo · Tailwind CSS · Docker · GitHub Actions

Diagram arsitektur

Pilih simpul untuk membaca keputusan di baliknya

graph LR A[Situs Publik<br/>Nuxt] --> C[REST API<br/>NestJS] B[Dashboard Admin<br/>Nuxt] --> C C --> D[(PostgreSQL<br/>Prisma)] E[packages/schemas<br/>Zod] -.-> A E -.-> B E -.-> C click A call archNote() click B call archNote() click C call archNote() click D call archNote() click E call archNote()
A Situs Publik · Nuxt
Situs publik dan dashboard admin adalah dua aplikasi Nuxt yang terpisah, jadi kode admin tidak pernah ikut terkirim ke pengunjung yang hanya membaca direktori.
B Dashboard Admin · Nuxt
Dashboard admin adalah aplikasi tersendiri, bukan route yang dipagari role di dalam situs publik — bundle publik lebih ringan, permukaan serangan lebih kecil. Konsekuensinya, layout harus dibagi lewat packages/ui.
C REST API · NestJS
Satu REST API melayani kedua frontend: 90 endpoint di 12 modul domain, dengan dokumentasi Swagger yang dibuat dari definisi yang sama.
D PostgreSQL · Prisma
Status pendaftaran (PENDING/APPROVED/REJECTED/NEED_REVISION) dan status keanggotaan (ACTIVE/EMERITUS/DECEASED) dimodelkan sebagai dua konsep terpisah di sini. Keduanya terlihat mirip, dan mencampurnya adalah awal mula bug data.
E packages/schemas · Zod
Skema Zod bersama adalah alasan aturan bisnis tidak pernah bergeser: API dan kedua frontend memvalidasi dengan definisi yang sama persis, bukan tiga salinan dari aturan yang sama.

Platform untuk Asosiasi Profesor Muslimat NU: direktori profesor publik, portal mandiri untuk para profesor, dan panel admin untuk mengelola keanggotaan dan konten. Saya memimpin tim 4 pengembang sebagai Project Manager sekaligus kontributor utama — mulai dari menerjemahkan kebutuhan klien menjadi PRD sampai serah terima dokumentasi.

Masalah

Data para profesor perempuan NU tersebar di dokumen resmi organisasi. Tidak ada direktori publik yang bisa dicari, tidak ada alur pendaftaran anggota yang terverifikasi, dan pengumuman kegiatan bergantung pada kanal yang tidak terhubung satu sama lain. Organisasi juga butuh cara agar para profesornya bisa dihubungi sebagai pembicara tanpa admin yang menjadi perantara.

Solusi

Membangun monorepo berisi tiga aplikasi — REST API, situs publik, dan dashboard admin — di atas satu skema data. Pendaftaran anggota berjalan lewat review admin bertahap, profesor bisa melengkapi profilnya sendiri setelah disetujui, dan konten organisasi dikelola oleh staf non-teknis lewat panel admin.

Keputusan Arsitektur

  • Turborepo dengan packages/schemas berisi skema Zod bersama — API dan kedua frontend memvalidasi dengan definisi yang sama persis, jadi aturan bisnis tidak pernah bergeser antar aplikasi
  • SK Guru Besar adalah satu-satunya dasar verifikasi keanggotaan, sehingga profesor bisa mengubah semua field lain tanpa persetujuan admin kedua — beban admin berkurang tanpa melemahkan validitas data
  • Status pendaftaran (PENDING/APPROVED/REJECTED/NEED_REVISION) dimodelkan terpisah dari status keanggotaan (ACTIVE/EMERITUS/DECEASED) — keduanya terlihat mirip dan sering dicampur, dan di situlah bug data bermula
  • Dashboard admin adalah aplikasi terpisah, bukan route yang dipagari role di dalam situs publik — bundle publik tetap ringan dan permukaan serangan tetap kecil
  • “Undang sebagai Pembicara” memakai mailto: langsung ke alamat profesor, bukan pesan internal — menghindari membangun kotak masuk yang tidak akan dipakai siapa pun
  • Penamaan menu sengaja dibuat netral terhadap pemangku jabatan (“Jejak Intelektual”, bukan nama ketua) supaya tidak basi ketika kepengurusan berganti
  • Ketiga aplikasi dikirim sebagai image Docker terpisah yang di-push ke GHCR dengan tag berdasarkan SHA commit — deploy dan rollback tinggal ganti tag, tanpa build di server
  • CI memakai deteksi perubahan per path, jadi PR yang menyentuh satu aplikasi tidak memicu lint, typecheck, dan build untuk ketiganya

Trade-off

  • Memilih mailto: daripada pesan internal: kehilangan pelacakan percakapan, tapi menghemat satu modul penuh yang kebutuhannya tidak pernah terbukti
  • Membiarkan profesor mengubah field non-SK tanpa verifikasi ulang: menerima sedikit risiko data tidak akurat demi menghilangkan bottleneck admin
  • Dua aplikasi Nuxt terpisah berarti sebagian layout dan komponen harus dibagi lewat packages/ui — biaya setup lebih besar di awal, terbayar ketika kedua aplikasi tumbuh ke arah yang berbeda

Fitur

  • Direktori profesor publik yang bisa dicari dan difilter
  • Pendaftaran anggota dengan alur review admin bertahap
  • Kartu anggota digital berbasis QR
  • Portal mandiri tempat profesor mengisi riwayat pendidikan, publikasi, dan URL akademik
  • Manajemen berita dan konten organisasi lewat rich text editor
  • Visualisasi sebaran anggota
  • Halaman kontak organisasi berbasis form
  • Dokumentasi API otomatis lewat Swagger

Poin untuk CV

  • Membangun platform organisasi dari nol: situs publik, portal admin, dan REST API dalam satu monorepo
  • Memimpin tim pengembang lewat sprint planning dan meeting mingguan sambil menjadi jembatan langsung ke klien
  • Menerjemahkan kebutuhan klien menjadi PRD dan item backlog di Jira dan Linear, lalu mendistribusikan pekerjaan ke tim
  • Memimpin migrasi tracker dari Linear ke Jira
  • Menetapkan standar dokumentasi fitur, konvensi API (Swagger dan Zod), dan alur rilis yang diikuti seluruh tim
  • Menggerakkan migrasi konten dan data awal dari dokumen resmi organisasi, serta menulis panduan pengguna untuk serah terima
  • Menyiapkan pipeline CI/CD dari lint dan typecheck sampai build image dan deploy otomatis ke VPS staging dan produksi

Tantangan yang Diselesaikan

  • Menjaga validasi tetap konsisten antara API dan dua frontend tanpa menduplikasi aturannya
  • Merancang alur revisi pendaftaran yang terbaca jelas, baik bagi pendaftar maupun admin yang mereview
  • Membangun kosakata domain yang disepakati tim, supaya istilah organisasi tidak saling tertukar di kode
  • Memindahkan tim dari Linear ke Jira di tengah proyek tanpa kehilangan konteks backlog

Pelajaran

  • Menyepakati kosakata domain sejak awal mencegah satu kelas bug yang sulit dilacak — status pendaftaran dan status keanggotaan terlihat mirip sampai keduanya dipakai keliru di produksi
  • Mencatat keputusan arsitektur sebagai ADR membuat pertanyaan “kenapa dibuat begini” bisa dijawab tanpa mengganggu orang yang menulisnya
  • Bekerja sebagai PM sekaligus pengembang, menulis PRD lebih dulu memaksa kejelasan yang justru mempercepat implementasi