You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 920af12
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: content/docs/next-saas/concepts/organizations-and-tenancy.mdx
+3Lines changed: 3 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,6 +7,8 @@ description: "The UI calls a customer boundary an Organization. Internal DTOs an
7
7
8
8
## Organization context
9
9
10
+
Registration creates either a private Individual workspace or a Business organization. Both use the same internal `Workspace` model and tenant isolation. An Individual workspace has one member and no invitations; a Business organization supports team roles and invitations. A user may later create and switch to a separate Business organization.
11
+
10
12
`IWorkspaceContextResolver` is the mandatory boundary for tenant-facing services. It starts with an authenticated identity, reloads active membership, and returns the verified `Workspace`, `WorkspaceMember`, user ID, and effective role.
11
13
12
14
A client-provided organization or resource ID only identifies what the caller wants. Authorization comes from persisted membership and an organization-scoped query.
@@ -72,6 +74,7 @@ Invitations are persisted as pending `WorkspaceMember` records with:
72
74
- expiry and send/revoke dates.
73
75
74
76
Acceptance requires an authenticated Identity email matching the invitation. Expired, revoked, already active, or mismatched invitations are rejected. A pending invitation may also be promoted on a subsequent authenticated SaaS request after its email is verified.
77
+
Individual workspaces reject invitations, including acceptance of a previously issued token.
CustomerEntitlementOverride ──overrides──> feature or meter key
19
19
```
20
20
21
-
`SaasPlan` is the durable product identity and public code. A version is an immutable commercial contract after publication. Prices, features, quotas, and trial daysbelong to that version.
21
+
`SaasPlan` is the durable product identity and public code. A version is an immutable commercial contract after publication. Prices, features, quotas, trial days, and account audience belong to that version. Audience can be Both, Individual, or Business; Checkout rejects a plan whose audience does not match the active workspace kind.
Copy file name to clipboardExpand all lines: content/docs/next-saas/features/billing-and-subscriptions.mdx
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,7 +7,7 @@ description: "Stripe owns financial state; Next SaaS maintains a local subscript
7
7
8
8
## User behavior
9
9
10
-
Customers choose a published Price from `/pricing` or `/billing`. `CreateCheckoutSession` returns a Stripe-hosted Checkout URL. After completion, the browser returns to `/billing`, which confirms the Checkout Session, while signed webhooks continue to handle future renewals, failures, portal changes, and cancellation.
10
+
Customers choose a published Price compatible with their active Individual or Business account from `/pricing` or `/billing`. `CreateCheckoutSession` returns a Stripe-hosted Checkout URL. After completion, the browser returns to `/billing`, which confirms the Checkout Session, while signed webhooks continue to handle future renewals, failures, portal changes, and cancellation.
11
11
12
12
The Stripe Customer Portal is the default UI for payment methods, invoices, cancellation, and subscription changes. The template links to Stripe-hosted invoice PDFs rather than generating duplicate tax documents.
- Registration or first SaaS access creates a personal organization when enabled.
10
+
- Registration offers Personal and Business. Personal creates a private, single-member workspace; Business requires an organization name and starts with an owner membership. The internal account kind for Personal is `Individual`.
11
+
- First SaaS access can still provision an Individual workspace when personal workspaces are enabled.
11
12
- Users can create another organization with independent data and billing.
12
13
- The application shell switches the active organization explicitly.
13
14
- Owners and Admins invite members and manage non-owner roles.
15
+
- Personal accounts cannot invite or accept team members; create a Business organization to collaborate.
16
+
- New Business organizations start on shared Free with one seat; a multi-seat Business plan is needed before inviting teammates.
14
17
- Billing members manage subscription state.
15
18
- Ownership transfer is an explicit lifecycle operation.
16
19
@@ -48,7 +51,7 @@ Invitations bind a role and normalized email to a random, one-way-hashed token a
48
51
49
52
## Configuration
50
53
51
-
-`Saas.EnablePersonalWorkspaces` — provision a personal organization when appropriate.
54
+
-`Saas.EnablePersonalWorkspaces` — provision an Individual workspace when appropriate.
52
55
-`Saas.DefaultPlan` — initial published plan code.
Copy file name to clipboardExpand all lines: content/docs/next-saas/features/plans-pricing-trials.mdx
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,7 +11,7 @@ Only platform Admin users manage the catalog from the **Plans** tab at `/admin/p
11
11
12
12
1. Select a durable `SaasPlan`.
13
13
2. Edit or create its draft `SaasPlanVersion`.
14
-
3. Configure public visibility, description, order, contact-sales behavior, and trial days.
14
+
3. Configure account audience, public visibility, description, order, contact-sales behavior, and trial days.
15
15
4. Add monthly/annual `SaasPlanPrice` rows, feature grants, and quota allowances.
16
16
5. Optionally create missing Products and Prices in Stripe.
17
17
6. Save, review active-subscription impact, and publish.
@@ -30,7 +30,7 @@ Publishing retires the prior published version. Existing subscriptions remain pi
30
30
31
31

32
32
33
-
`MyApp/plans.json` seeds these records only for an empty database.
33
+
`MyApp/plans.json` seeds these records only for an empty database. The default catalog includes shared Free, Individual-only Personal, and Business-only Pro, Business, and Enterprise plans. Plan audience is part of each published version's contract.
34
34
35
35
## APIs
36
36
@@ -44,11 +44,11 @@ Publishing retires the prior published version. Existing subscriptions remain pi
44
44
45
45
Amounts are integer minor currency units. Supported currencies are defined globally by `Saas.SupportedCurrencies`; annual billing is globally controlled by `Saas.EnableAnnualBilling`.
46
46
47
-
A self-service paid Price must be active, positive, published, and mapped to a Stripe `price_...` identifier. Free plans require no Stripe Price. Contact-sales plans intentionally bypass self-service Checkout.
47
+
A self-service paid Price must be active, positive, published, available to the active account kind, and mapped to a Stripe `price_...` identifier. Free plans require no Stripe Price. Contact-sales plans intentionally bypass self-service Checkout. The pricing page offers Personal and Business plan tabs above the cards, with monthly/annual billing alongside; signed-in Checkout remains bound to the active workspace kind.
48
48
49
49

50
50
51
-
Stripe catalog provisioning uses plan metadata and idempotency keys. It saves returned Price mappings directly into the draft but never publishes a plan automatically. Live provisioning requires explicit opt-in.
51
+
**Create missing in Stripe** saves the current plan as a draft when needed, including unsaved edits, before provisioning. Stripe catalog provisioning uses plan metadata and idempotency keys. It saves returned Price mappings directly into the draft but never publishes a plan automatically. Live provisioning requires explicit opt-in.
Copy file name to clipboardExpand all lines: content/docs/next-saas/getting-started/connect-stripe-sandbox.mdx
+4-5Lines changed: 4 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -35,11 +35,10 @@ Sign in as `admin@email.com`, open the **Plans** tab at `/admin/plans`, and repe
35
35
36
36
1. Select the plan.
37
37
2. Open its pricing configuration.
38
-
3. Create or edit a draft.
39
-
4. Confirm monthly and annual amounts and currencies.
40
-
5. Click **Create missing in Stripe**.
41
-
6. Review the returned `price_...` mappings.
42
-
7. Publish the draft. The mappings are saved automatically, so no second draft save is required.
38
+
3. Confirm monthly and annual amounts and currencies, editing them if needed.
39
+
4. Click **Create missing in Stripe**. This saves a draft automatically when needed, then provisions the Stripe catalog.
40
+
5. Review the returned `price_...` mappings.
41
+
6. Publish the draft. The mappings are saved automatically, so no second draft save is required.
43
42
44
43
Free and contact-sales plans are skipped. Published subscriptions remain pinned to their existing plan version; publishing a new draft does not silently rewrite customer contracts.
Copy file name to clipboardExpand all lines: content/docs/next-saas/getting-started/project-tour.mdx
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -70,6 +70,7 @@ Configuration follows the `Configure.*.cs` convention:
70
70
71
71
-`app/page.tsx` and `app/(content)` provide the public site and Markdown-backed content routes.
72
72
-`app/dashboard`, `documents`, `usage`, `billing`, `team`, and `settings` are customer pages.
73
+
-`app/signup` offers Personal and Business account types; `app/pricing` lets visitors switch between their plan catalogs above the plan cards, alongside the monthly/annual billing selector.
73
74
-`app/admin` contains the role-gated, static Operations Center routes.
74
75
-`components/app-shell.tsx` switches between organization navigation and capability-aware Operations Center navigation.
75
76
-`components/admin-center-page.tsx` composes the shared heading and focused content for each operator route.
Copy file name to clipboardExpand all lines: content/docs/next-saas/operations/external-services.mdx
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -13,7 +13,7 @@ Required production values are publishable key, secret/restricted key, and webho
13
13
POST https://your-host/stripe/webhook
14
14
```
15
15
16
-
Provision Products and recurring Prices from the plan draft UI only when catalog provisioning policy allows it. Automatic live provisioning is disabled by default. Verify currency, interval, amount, trial policy, and metadata before publishing a plan.
16
+
Provision Products and recurring Prices from the plan editor only when catalog provisioning policy allows it. The button saves a draft first when needed, including unsaved edits. Automatic live provisioning is disabled by default. Verify currency, interval, amount, trial policy, and metadata before publishing a plan.
"psql --username postgres --dbname next_saas --command='select \"Code\", \"Name\" from \"SaasPlan\" order by \"DisplayOrder\";'"
232
232
```
233
233
234
-
The schema must contain the Identity and SaaS tables. The plan query must return Free, Pro, Business, and Enterprise.
234
+
The schema must contain the Identity and SaaS tables. The plan query must return Free, Personal, Pro, Business, and Enterprise.
235
235
236
236
Verify both public health endpoints:
237
237
@@ -245,7 +245,7 @@ Both responses must be `Healthy`.
245
245
246
246
## 8. Verify clean application and Stripe state
247
247
248
-
Sign in with the temporary bootstrap administrator. Confirm `/admin`, `/admin/plans`, and the public pricing page load. Create a disposable customer user and confirm a new personal organization is created.
248
+
Sign in with the temporary bootstrap administrator. Confirm `/admin`, `/admin/plans`, and the public pricing page load. Create a disposable Individual customer user and confirm a private workspace is created. Create a Business customer user and confirm a named organization is created.
249
249
250
250
The new PostgreSQL database must not contain users, organizations, subscriptions, usage records, or Stripe mappings from the retired deployment.
0 commit comments