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

Why I built it

Most SaaS applications begin with the same foundation: authentication, protected routes, a dashboard, migrations, forms, tables, and tests. These parts matter, but they rarely differentiate the product.

I built Mandor Plate so I would not recreate that foundation for every idea. A new project can start from a connected application instead of an empty repository or untested configuration.

The boilerplate also reflects how I work with AI. Frontend and backend live in one monorepo, giving an AI coding assistant one workspace in which to trace and change an entire feature.

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

What I built

Mandor Plate is a full-stack Turborepo boilerplate. It is a small runnable application, not a collection of disconnected templates.

The foundation includes:

  • NestJS API: REST endpoints, Swagger, JWT authentication, and an RBAC-ready structure.
  • Next.js dashboard: protected pages, dashboard patterns, and BFF route handlers.
  • PostgreSQL: TypeORM migrations, seed data, and Docker Compose.
  • Shared contracts: Zod schemas used by the API and web application.
  • Data and form state: TanStack Query and TanStack Form.
  • UI foundation: shadcn/ui, Radix, and Tailwind CSS.
  • Quality checks: lint, typecheck, Jest, and Playwright.

The foundation handles recurring mechanics. Each product remains free to define its own entities, permissions, workflows, and visual language.

Why a monorepo

Separate frontend and backend repositories can work, but every cross-stack change requires more coordination and context switching.

Mandor Plate keeps the API, web application, shared contracts, and tests in one workspace. A contract change can be traced directly to its API handler, web query, form, and E2E test.

That visibility also helps an AI coding assistant. It does not need to infer how two repositories relate or lose context while switching workspaces.

The code is still divided by responsibility:

  • The API owns domain behavior, authentication, and persistence.
  • The web application owns user workflows, state, and presentation.
  • The shared package owns the API-web contract.
  • Docker Compose owns local infrastructure.
  • Quality checks verify changes across packages.

Application structure

Merender diagram...

Shared contracts keep inputs and outputs aligned. The BFF is the dashboard's server-side boundary. The API applies domain rules and accesses PostgreSQL.

These boundaries allow one layer to change without dismantling the application. The UI can evolve without moving domain rules, and the API can change without duplicating validation in the web app.

Building one feature

I use vertical slices so a feature is completed as a usable workflow rather than stopping at one layer.

Merender diagram...

The sequence gives developers and AI a visible path. Work starts at the contract, crosses the backend and database, and ends in the UI and tests.

Quality checks form the feedback loop. A feature is not complete merely because one package compiles.

Reusing the foundation

My starting loop for a new application is:

  1. Start PostgreSQL and Maildev with Docker Compose.
  2. Run migrations and seed the database.
  3. Start the API and dashboard from one workspace.
  4. Replace the example entities, navigation, permissions, and visual language.
  5. Build features as vertical slices.
  6. Run lint, typecheck, unit tests, and E2E tests.

The goal is not to make every product look alike. Mandor Plate provides a working starting point so the time can go into understanding and building the product domain.

Problems it solves

Mandor Plate addresses three recurring problems:

  • Repeated setup: authentication, dashboard, database, and tests do not start from zero.
  • Split context: frontend and backend can be understood in one workspace.
  • Fragmented verification: quality checks cover the path from contract to UI.

The boilerplate does not remove technical decisions. It stores recurring ones in a foundation that can be tested, improved, and reused.

What I learned

A useful boilerplate must run. A technology list has little value if the API, database, web application, and tests do not share a working path.

A monorepo is a context boundary, not merely a folder structure. For an AI coding assistant, one workspace makes the impact of a change easier to trace across the stack.

Reusable does not mean universal. A foundation that is too specific is hard to reuse; one that is too empty saves no time.

Quality checks belong in the foundation. Lint, typecheck, unit tests, and E2E tests help both developers and AI verify that a change works across the application.

Mandor Plate is not a finished product or a rigid dashboard template. It is an application baseline for building the next SaaS product with less setup and a clearer path to verification.

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