Skip to main content

New User Flow

When a user signs up via Clerk, the app automatically provisions a private test organization for them. No manual org creation is required.


Steps

1. Sign-up

The user signs up through Clerk. ClerkProvider has afterSignUpUrl set to the locale root so Clerk never shows its native organization-creation modal.

2. user.created webhook → userCreate

Clerk fires a user.created event to /api/webhooks/clerk. The handler (src/lib/clerk/userCreate.js) does three things in sequence:

a) Create the test organization

Generates a unique slug test-NNNN (nanoid, digits only, collision-checked against MongoDB). Calls organizationFromTemplateCreate which:

  • Creates the MongoDB organization from templates/demo/ files (org data, partners, ROPAs for all configured locales)
  • Creates the matching Clerk organization (name: TEST organization user@email.com, slug: test-NNNN)
  • Saves the Clerk org ID to MongoDB
  • Sets public/demotest.png as the logo in both MongoDB and Clerk

b) Write newTenantSlug to Clerk user metadata

Stores the new slug in user.publicMetadata.newTenantSlug so the client can detect it.

c) Add user to the shared demo org

Adds the user as org:member of the known demo organization so they can browse the demo site while their test org is being provisioned.

3. organization.created webhook → organizationCreate

Clerk fires organization.created when the Clerk org is created in step 2b. The handler looks up the org by Clerk ID (already saved) and syncs the demo logo. This is a no-op in practice since organizationFromTemplateCreate already set the logo.

4. NewTenantModal appears

TenantRedirector (src/lib/clerk/TenantRedirector.jsx) is mounted on every page via the app layout. It polls user.publicMetadata.newTenantSlug every 2 seconds (up to 15 attempts within a 5-minute window for new users). When it finds the slug it shows a dialog:

  • "Your test environment is ready!"
  • Button: Visit my workspace — clears the metadata flag and redirects to test-NNNN.rat.gd
  • Button: Return to demo site — clears the flag, stays on the demo site

Key files

FileRole
src/app/[locale]/layout.jsxClerkProvider with afterSignUpUrl — prevents Clerk's org-creation modal
src/app/api/webhooks/clerk/route.jsWebhook router — dispatches user.created to userCreate
src/lib/clerk/userCreate.jsOrchestrates org creation, metadata write, and demo org membership
src/lib/mongoose/organizationFromTemplateCreate.jsCreates MongoDB org from template + Clerk org
templates/demo/Demo template files (org, partners, ROPAs per locale)
src/lib/clerk/TenantRedirector.jsxPolls metadata and renders the NewTenantModal

Dev notes

Clerk webhooks cannot reach localhost without a tunnel. In dev:

  • The user.created webhook never fires → no test org is created automatically
  • Use ngrok http 3000 or the Clerk CLI dev proxy and update the webhook endpoint in the Clerk dashboard
  • Alternatively, call organizationFromTemplateCreate directly from a script to seed a local test org