Seeding roles & permissions
Idempotent bootstrap of system roles, permissions, and assignments.
Your code references roles by name ('admin', 'member') and permissions by name ('orders.read'). They need to exist in the database for guards to work. This recipe shows the canonical bootstrap: idempotent, safe to run on every deploy, and tagged isSystem: true so the admin console can't accidentally edit them.
The seeder service
Register it
OnApplicationBootstrap runs once after every successful module init — your DB is reconciled on every deploy. Skipping in NODE_ENV=test keeps test runs fast and predictable.
Or: run-once, on demand
If you'd rather not run on every boot (large catalogs), expose it as a CLI command:
Run with pnpm tsx scripts/seed-roles.ts.
Assigning a default role on signup
Now that the rows exist, you can reference them by name in the signup hook:
Granting permissions ad-hoc
For one-off escalations (granting a specific user a specific permission outside the role system), use RoleService to create a per-user role rather than poking permissions directly. It keeps the role/permission model clean and auditable.