Plans (Limits + Defaults)¶
The Plans tab is the platform-admin lever for everything plan-tier-specific: how much each plan can do, and what AI it gets out of the box.
URL: /admin?tab=plans
Two sub-tabs in one card:
| Sub-tab | What it controls |
|---|---|
| Plan Limits | Quotas: projects, members, credits, file size, feature gates per plan |
| Plan Defaults (AI) | Default model + provider that new workspaces on each plan inherit |
Plans, in display order: Free · Pro · Business · Enterprise. (The shipping constant is PLAN_ORDER = ["free", "pro", "business", "enterprise"]; note that "Team" is not a plan; if you've seen it referenced elsewhere, that's a stale name.)
Sub-tab: Plan Limits¶
Each plan is an expandable card. The card shows the plan emoji, its name, and a CUSTOMIZED amber pill if any value diverges from the hardcoded default in @doable/shared's PLAN_LIMITS.
The eight limit fields¶
| Field | Type | Notes |
|---|---|---|
| Max Projects | number | Per workspace |
| Max Members | number | Per workspace |
| Daily Credits | number | AI credit allowance per day |
| Monthly Credits | number | AI credit allowance per month |
| Max File Size | number (MB) | Stored as bytes; UI displays KB/MB/GB |
| Custom Domains | toggle | Allow workspaces to attach their own domain |
| Analytics | toggle | Allow workspaces to see analytics dashboards |
| Priority Support | toggle | Surface a "priority" support channel |
Actions¶
- Edit: open the inline form, change values, Save.
- Reset: restore the hardcoded defaults for that plan (only visible when
isOverridden). - "Last updated" timestamp at the bottom of the card.
Temporary changes for QA
For a one-off limit increase, prefer a per-workspace override (Users & AI tab) over editing the plan itself. Plan edits affect every workspace on that tier.
Sub-tab: Plan Defaults (AI)¶
Sets the default AI model and provider that new workspaces on each plan inherit. Existing workspaces can also be back-filled with Apply to Existing.
Each plan card shows:
- Plan emoji + name
- A one-line summary of the current default, e.g. "Copilot · gpt-4o" or "No default configured"
- Configure button: opens an inline form
- Apply to Existing button: only appears once a default is configured
Configuring a plan default¶
The form has a Source toggle with three states:
| Source | What it means |
|---|---|
| None | New workspaces start with no AI; they must add their own keys via /ai-settings |
| GitHub Copilot | Use a platform-owned Copilot account; pick the account, then the model |
| Custom Provider | Use a platform-managed provider (Anthropic, OpenAI, etc.); pick the provider, then the model |
In both Copilot and Custom Provider modes, the model selector is dynamic (filled from the live model list of the chosen account/provider). A "Type custom model ID" sentinel at the bottom lets you enter any model identifier the provider supports, not just the curated list.
Saving writes the choice to /admin/platform-ai-defaults/:plan. New signups on that plan get a cloned copy of the Copilot account or provider in their workspace automatically; see Provider Bridge.
Applying to existing workspaces¶
Click Apply to Existing on a configured plan card to backfill the default into every workspace on that tier that does not already have an AI configured.
A footer toggle controls the destructive variant:
Overwrite existing workspace AI settings when applying to existing (off by default)
Leave this off unless you actually mean to overwrite per-workspace overrides. With overwrite off, the operation is safe: it only fills workspaces with no AI configured.
Inheritance contract¶
The info box at the bottom of the panel spells this out:
- New signups inherit the plan default automatically.
- The platform's Copilot account or provider is cloned into the user's workspace (with re-encrypted tokens via
pgp_sym_encrypt); the workspace owns its own copy. - Users can still override their workspace's AI in
/ai-settingsat any time. - Apply to Existing only fills unconfigured workspaces unless the overwrite toggle is on.
Common tasks¶
- Tighten Free plan for a closed beta: Max Projects 1, no Custom Domains, Daily Credits 100.
- Set Business plan to 50 max projects, custom domains on, analytics on.
- Set Pro plan default AI = Copilot account
acme-bot, modelclaude-sonnet-4. - Configure "Custom Provider" default for Enterprise = a platform-managed Anthropic key +
claude-opus-4. - Back-fill all existing Pro workspaces with the new default (overwrite off, so people who already set their own keys keep them).
- Reset Free plan back to hardcoded defaults after a campaign ends.
How limits are enforced¶
The Limits values feed PLAN_LIMITS in @doable/shared. Credit deductions happen on every AI request; when a workspace exhausts its allowance, further AI calls return a quota error until the period resets.
Plan Defaults feed the platform-AI allocation logic in services/api/src/routes/admin-ai.ts and the Provider Bridge clone path.
See also: Users | Feature Flags | AI: Provider Bridge | For Platform Admins: First-time setup