When teams outgrow ad-hoc scripts and spreadsheet workflows, the first real product decision is rarely about features. It is about whether the foundation can carry identity, tenancy, permissions, and audit without every new module reinventing the wheel.
We use NestJS as a modular monolith because it maps cleanly to domain boundaries: authentication, workspace lifecycle, access control, and product-specific workflows each live in focused modules with explicit imports. Prisma and PostgreSQL give us typed queries, migration discipline, and the relational model B2B customers expect for memberships, roles, and audit history.
The pattern that pays off most is separating platform concerns from product concerns early. Zenit Suite Core owns sessions, workspaces, and permissions; products like Vendra consume those APIs instead of embedding their own auth stacks. That keeps security fixes centralized and reduces drift across repositories.
Operational reliability comes from boring defaults: structured logging with request IDs, health checks that verify database connectivity, and migrations that run before new code serves traffic. We treat breaking schema changes as coordinated releases, not silent deploys.
If you are standing up a SaaS backend today, optimize for clarity over cleverness. A well-bounded modular monolith beats a premature microservices split—and it leaves room to extract services later when the boundaries are proven in production.

