@ftisindia/create-app
v0.2.0
Published
One-command scaffolder for the Phase 1 NestJS foundation starter.
Readme
@ftisindia/create-app
A create-next-app-style scaffolder that generates a production-ready NestJS
modular-monolith starter — with authentication, organisations, memberships,
invitations, per-organisation RBAC, request context, audit logs, typed settings, Swagger
docs, health checks, and a guided one-command local setup.
The CLI command is ftis-nest.
Quick start
npx @ftisindia/create-app@latest my-appOr install once and use the short command anywhere:
npm i -g @ftisindia/create-app
ftis-nest my-appThen bootstrap and run the generated app:
cd my-app
npm run setup:local # creates DBs, runs migrations, seeds demo data, prints login
npm run start:devOpen:
- Swagger API docs — http://localhost:3000/docs
- Health check — http://localhost:3000/health
Usage
ftis-nest <project-name|.> [options]
npx @ftisindia/create-app <project-name|.> [options]<project-name> is the folder to create. Use . to scaffold into the current directory
(it must be empty).
Options
| Option | Description |
|--------|-------------|
| --no-install | Copy files only; skip npm install and prisma generate |
| --no-git | Skip git init / add / initial commit |
| --pm <name> | Package manager to use: npm, pnpm, or yarn |
| --help | Show help |
Prerequisites
- Node.js 20+
- PostgreSQL running locally, or a reachable
DATABASE_URL
What you get
The generated app is a modular monolith with these modules ready to use:
- Auth — email/password + Google OAuth handoff, JWT access/refresh, logout
- Organisations / Memberships / Invitations — multi-tenant org model with roles and invites
- Access Control (RBAC) — per-organisation roles and permissions (CASL) with a permission registry
- Audit — org-scoped audit logs
- Settings — typed per-organisation settings
- Health — database connectivity check
- Sample — a reference module to copy when adding your own
Plus global request validation, a consistent error envelope, Swagger at /docs,
request-context scoping, Prisma with migrations and seed scripts, and a gen:module
generator.
Common scripts in the generated app
npm run setup:local # one-command local bootstrap (non-destructive)
npm run start:dev # watch mode
npm run build # production build
npm test # unit tests
npm run test:e2e # end-to-end tests
npm run gen:module # scaffold a new moduleSee the generated app's own README.md and docs/ for full guidance, including how to
add a module and the architecture rules.
License
Released under the PolyForm Noncommercial License 1.0.0 — free for any noncommercial
use. Commercial use requires a separate commercial license from
ftisindia.com. See the bundled LICENSE file.
Generating a module with gen:module
Every project this CLI generates ships a gen:module script. In any generated project,
run it to scaffold a new feature module that already follows the project's auth, RBAC,
request-context, and audit conventions.
npm run gen:module -- billingNote the
--before the name — it tells npm to pass the argument through to the generator. Names are normalized automatically, sobilling,Billing,"invoice items", andinvoiceItemsall resolve to the same module.
What it generates
For a name like billing, you get:
src/modules/billing/billing.module.ts— the NestJS module (wires controller + service)src/modules/billing/dto/billing-echo.dto.ts— a sample DTO (class-validator + Swagger)src/modules/billing/application/services/billing.service.ts— a service withgetStatus()andecho()that use Prisma, request context, and write an audit-log rowsrc/modules/billing/presentation/billing.controller.ts— an org-scoped controller guarded byJwtAuthGuard,OrgScopeGuard, andPermissionGuard, exposing:GET /organisations/:orgId/billing/status— requiresbilling.readPOST /organisations/:orgId/billing/echo— requiresbilling.update
test/billing.spec.ts— a starter unit test
It also keeps RBAC in sync automatically by appending to:
src/modules/access-control/types/permission-key.ts— addsbilling.readandbilling.updatesrc/modules/access-control/types/route-permission-registry.ts— adds the two route entries (startup and tests fail if a guarded route is missing here)
The generator never overwrites existing files — it stops if any target already exists.
Two steps to finish
- Register the module in
src/app.module.ts(the generator prints this reminder):import { BillingModule } from './modules/billing/billing.module'; // add BillingModule to the @Module({ imports: [...] }) array - Re-seed permissions so the new keys exist in the database and can be granted to roles:
Then assignnpm run prisma:seedbilling.read/billing.updateto the appropriate role(s).
Start the app and the new guarded endpoints are live (visible in Swagger at /docs).
When not to use it
- You need a non-org-scoped or public route. The output is hard-wired to
/organisations/:orgId/<name>with the org guards. Build global/unauthenticated endpoints by hand instead. - You're extending an existing module. It scaffolds a brand-new module and refuses to overwrite — add files to the existing module manually.
- Your feature doesn't map to simple read/update permissions. It generates exactly
<name>.readand<name>.update; for richer permission sets, edit the generatedpermission-key.tsand registry entries afterward. - You want a different shape than the
status+echoreference endpoints. Treat the output as a starting point, or copysrc/modules/sample(seedocs/SAMPLE_MODULE.md) for a fuller reference.
