achmadya.dev
~/projects / mandor-plate

Mandor Plate

A reusable SaaS boilerplate with an API, dashboard, database, and tests in one monorepo.

Mandor Plate preview
Content language

Mengapa saya membuatnya

Setiap aplikasi SaaS membutuhkan fondasi yang hampir sama: authentication, protected route, dashboard, migration, form, table, dan test. Bagian ini penting, tetapi jarang menjadi pembeda produk.

Saya membuat Mandor Plate agar fondasi tersebut tidak perlu dibangun ulang. Project baru dapat dimulai dari aplikasi yang sudah terhubung, bukan repository kosong atau kumpulan konfigurasi yang belum diuji.

Boilerplate ini juga menyesuaikan cara saya bekerja dengan AI. Frontend dan backend ditempatkan dalam satu monorepo agar AI coding assistant dapat membaca dan mengubah seluruh alur fitur dari satu workspace.

Repository: github.com/achmadya-dev/mandor-plate

Apa yang saya bangun

Mandor Plate adalah boilerplate full-stack berbasis Turborepo. Isinya bukan template yang terpisah, tetapi aplikasi kecil yang dapat dijalankan dan dikembangkan secara end-to-end.

Fondasi yang tersedia:

  • NestJS API: REST API, Swagger, JWT authentication, dan struktur yang siap dikembangkan untuk RBAC.
  • Next.js dashboard: protected page, pola dashboard, dan BFF route handler.
  • PostgreSQL: TypeORM migration, seed data, dan Docker Compose.
  • Shared contract: Zod schema yang digunakan oleh API dan web app.
  • Data dan form state: TanStack Query dan TanStack Form.
  • UI foundation: shadcn/ui, Radix, dan Tailwind CSS.
  • Quality checks: lint, typecheck, Jest, dan Playwright.

Fondasi ini mengurus kebutuhan yang berulang. Setiap aplikasi tetap bebas menentukan entity, permission, workflow, dan desain sesuai domainnya.

Mengapa menggunakan monorepo

Frontend dan backend sering dipisahkan ke dua repository. Cara ini dapat bekerja, tetapi membuat perubahan lintas stack membutuhkan lebih banyak koordinasi dan context switching.

Dalam Mandor Plate, API, web app, shared contract, dan konfigurasi test berada dalam satu workspace. Satu perubahan contract dapat langsung ditelusuri ke handler API, query web, form, dan E2E test.

Struktur ini juga membantu AI coding assistant. AI tidak perlu menebak hubungan antara dua repository atau kehilangan context saat berpindah workspace.

Monorepo bukan berarti semua kode dicampur. Setiap bagian tetap memiliki tanggung jawab yang jelas:

  • API mengatur domain behavior, authentication, dan persistence.
  • Web app mengatur user workflow, state, dan presentation.
  • Shared package mengatur contract antara API dan web.
  • Docker Compose mengatur local infrastructure.
  • Quality checks memverifikasi perubahan lintas package.

Struktur aplikasi

Hubungan utama di dalam workspace dapat diringkas seperti berikut:

Merender diagram...

Shared contract menjaga input dan output tetap konsisten. BFF menjadi boundary server-side untuk dashboard. API menjalankan aturan domain dan mengakses PostgreSQL.

Boundary tersebut membuat setiap bagian dapat diganti tanpa membongkar seluruh aplikasi. UI dapat berubah tanpa memindahkan aturan domain, dan API dapat berubah tanpa menyalin validasi ke web.

Cara membangun satu fitur

Saya menggunakan vertical slice agar satu fitur dikerjakan sampai benar-benar dapat digunakan, bukan selesai di satu layer saja.

Merender diagram...

Alur ini memberi AI dan developer urutan kerja yang jelas. Perubahan dimulai dari contract, melewati backend dan database, lalu selesai di UI serta test.

Quality checks menjadi feedback loop. Fitur belum dianggap selesai hanya karena satu package berhasil dikompilasi.

Cara menggunakan kembali

Saat memulai aplikasi baru, saya menggunakan alur berikut:

  1. Menjalankan PostgreSQL dan Maildev dengan Docker Compose.
  2. Menjalankan migration dan seed database.
  3. Menjalankan API dan dashboard dari workspace yang sama.
  4. Mengganti contoh entity, navigation, permission, dan visual language.
  5. Membangun fitur sebagai vertical slice.
  6. Menjalankan lint, typecheck, unit test, dan E2E test.

Tujuannya bukan membuat semua aplikasi terlihat sama. Mandor Plate hanya menyediakan titik awal yang sudah bekerja agar waktu dapat digunakan untuk memahami dan membangun domain produk.

Masalah yang diselesaikan

Mandor Plate menyelesaikan tiga masalah yang sering berulang:

  • Setup berulang: fondasi authentication, dashboard, database, dan test tidak dibuat dari awal.
  • Context terpecah: frontend dan backend dapat dipahami dalam satu workspace.
  • Verifikasi terpisah: quality checks memeriksa perubahan dari contract sampai UI.

Boilerplate tidak menghapus keputusan teknis. Ia menyimpan keputusan yang sering berulang agar dapat diuji, diperbaiki, dan digunakan kembali.

Pelajaran yang saya dapat

Boilerplate yang berguna harus dapat dijalankan. Daftar teknologi saja tidak cukup jika API, database, web, dan test belum memiliki alur kerja bersama.

Monorepo adalah batas context, bukan sekadar struktur folder. Bagi AI coding assistant, satu workspace membuat dampak perubahan lebih mudah ditelusuri dari backend sampai frontend.

Reusable tidak berarti universal. Fondasi yang terlalu spesifik sulit dipakai ulang, sedangkan fondasi yang terlalu kosong tidak menghemat waktu.

Quality checks harus tersedia sejak awal. Lint, typecheck, unit test, dan E2E membantu developer serta AI memastikan bahwa perubahan bekerja di seluruh stack.

Mandor Plate bukan produk jadi atau dashboard template yang kaku. Ia adalah baseline aplikasi untuk membangun SaaS berikutnya dengan lebih cepat, terstruktur, dan mudah diverifikasi.

metadata
role
Developer / Maintainer
period
June 2026 - Present
stack
NestJSNext.jsPostgreSQLTypeScriptTurborepo
Related