115 lines
5.8 KiB
Markdown
115 lines
5.8 KiB
Markdown
# Pricing Improvements PRD
|
|||
|
|
|
||
|
|
## Status
|
||
|
|
- Draft
|
||
|
|
|
||
|
|
## Date
|
||
|
|
- February 17, 2026
|
||
|
|
|
||
|
|
## Purpose
|
||
|
|
Define a single, extensible pricing framework for ClassroomIO so current and future features can be clearly assigned to `BASIC`, `EARLY_ADOPTER`, or `ENTERPRISE` plans.
|
||
|
|
|
||
|
|
## Problem Statement
|
||
|
|
Plan definitions currently exist in multiple places (marketing plan copy, app UI gates, and plan constants). Some gates are only `free vs paid`, while product pricing has three tiers. We need one source of truth for feature entitlements so we can add features later without ambiguity.
|
||
|
|
|
||
|
|
## Goals
|
||
|
|
1. Keep one canonical plan-to-feature matrix for product and engineering.
|
||
|
|
2. Reflect the current in-app pricing behavior.
|
||
|
|
3. Add a future-feature allocation table so new capabilities can be assigned to plans consistently.
|
||
|
|
4. Explicitly classify Enterprise-only features (including SSO).
|
||
|
|
|
||
|
|
## Non-Goals
|
||
|
|
- Rebuilding billing provider integrations in this phase.
|
||
|
|
- Redesigning public pricing page copy in this phase.
|
||
|
|
- Shipping all entitlement backend checks in one release.
|
||
|
|
|
||
|
|
## Confirmed Decisions
|
||
|
|
1. Plan model remains `BASIC`, `EARLY_ADOPTER`, `ENTERPRISE`.
|
||
|
|
2. SSO is an Enterprise-only feature.
|
||
|
|
3. For assessment roadmap: code execution is out of scope.
|
||
|
|
4. For assessment roadmap: file upload limits are `2MB` (Basic/Free) and `10MB` (Paid plans).
|
||
|
|
|
||
|
|
## Data Sources Checked
|
||
|
|
- `packages/utils/src/plans/data.json`
|
||
|
|
- `packages/utils/src/plans/constants.ts`
|
||
|
|
- `apps/website/src/routes/pricing/+page.svelte`
|
||
|
|
- `apps/dashboard/src/lib/utils/store/org.ts`
|
||
|
|
- `apps/dashboard/src/lib/features/settings/pages/teams.svelte`
|
||
|
|
- `apps/dashboard/src/lib/features/settings/pages/domains.svelte`
|
||
|
|
- `apps/dashboard/src/lib/features/course/components/lesson/video/upload-video.svelte`
|
||
|
|
- `apps/dashboard/src/lib/features/course/components/lesson/document/add-document-modal.svelte`
|
||
|
|
- `apps/dashboard/src/lib/features/course/components/ceritficate/design.svelte`
|
||
|
|
- `apps/dashboard/src/lib/features/course/pages/settings.svelte`
|
||
|
|
- `apps/dashboard/src/lib/features/course/components/people/share-qr-image.svelte`
|
||
|
|
- `apps/dashboard/src/lib/features/ui/upgrade-powered-by.svelte`
|
||
|
|
- `apps/dashboard/src/lib/features/audience/pages/audience.svelte`
|
||
|
|
- `apps/dashboard/src/routes/org/[slug]/audience/+page.svelte`
|
||
|
|
- `prd/enterprise-sso/README.md`
|
||
|
|
|
||
|
|
## Plan Definitions in App
|
||
|
|
|
||
|
|
| Plan Key | Display Name | Pricing Source |
|
||
|
|
| --- | --- | --- |
|
||
|
|
| `BASIC` | Free / Basic | `packages/utils/src/plans/data.json` |
|
||
|
|
| `EARLY_ADOPTER` | Early Adopters | `packages/utils/src/plans/data.json` |
|
||
|
|
| `ENTERPRISE` | Enterprise | `packages/utils/src/plans/data.json` |
|
||
|
|
|
||
|
|
## Current In-App Entitlement Behavior
|
||
|
|
|
||
|
|
| Capability | BASIC | EARLY_ADOPTER | ENTERPRISE | Status |
|
||
|
|
| --- | --- | --- | --- | --- |
|
||
|
|
| Audience capacity | 20 | 10,000 | Unlimited | Live (`currentOrgMaxAudience`) |
|
||
|
|
| Team member invite/remove | No | Yes | Yes | Live (gated by `isFreePlan`) |
|
||
|
|
| Lesson video upload tab | No | Yes | Yes | Live (gated by `isFreePlan`) |
|
||
|
|
| Lesson document upload | No | Yes | Yes | Live (gated by `isFreePlan`) |
|
||
|
|
| Certificate customization | No | Yes | Yes | Live (gated by `isFreePlan`) |
|
||
|
|
| Lesson download toggle | No | Yes | Yes | Live (gated by `isFreePlan`) |
|
||
|
|
| Course download action | No | Yes | Yes | Live (gated by `isFreePlan`) |
|
||
|
|
| Powered-by branding visibility | Required | Hidden | Hidden | Live (free-only rendering) |
|
||
|
|
| QR invite ClassroomIO branding | Required | Hidden | Hidden | Live (free-only rendering) |
|
||
|
|
| Custom domain management | No | Yes (current UI behavior) | Yes | Live (currently `isFreePlan` gate) |
|
||
|
|
|
||
|
|
## Enterprise-Only Features
|
||
|
|
|
||
|
|
| Feature | BASIC | EARLY_ADOPTER | ENTERPRISE | Status |
|
||
|
|
| --- | --- | --- | --- | --- |
|
||
|
|
| SSO (SAML/OIDC) | No | No | Yes | Planned (`prd/enterprise-sso/README.md`) |
|
||
|
|
| SCIM lifecycle provisioning | No | No | Yes | Planned (phase after SSO) |
|
||
|
|
|
||
|
|
## Future Feature Allocation Backlog
|
||
|
|
|
||
|
|
| Feature Candidate | BASIC | EARLY_ADOPTER | ENTERPRISE | Status | Notes |
|
||
|
|
| --- | --- | --- | --- | --- | --- |
|
||
|
|
| Advanced assessment types (matching, ordering, audio/video, hotspot) | No | Yes | Yes | Proposed | From exercise question-types roadmap |
|
||
|
|
| Assessment file upload limit | 2MB | 10MB | 10MB | Proposed | Applies to assignment/test file submissions |
|
||
|
|
| Advanced assessment analytics (item analysis) | No | Yes | Yes | Proposed | Basic keeps completion + score only |
|
||
|
|
| Exercise-level resubmission controls | Yes | Yes | Yes | Proposed | Policy is by exercise, not by question type |
|
||
|
|
|
||
|
|
## Gaps To Fix (Pricing Improvements)
|
||
|
|
1. Move from broad `isFreePlan` checks to explicit feature entitlements per plan.
|
||
|
|
2. Align in-app enforcement with published plan matrix where they differ.
|
||
|
|
3. Add backend entitlement checks for all gated actions (not UI-only checks).
|
||
|
|
4. Add a central entitlement API used by dashboard and API services.
|
||
|
|
|
||
|
|
## Functional Requirements
|
||
|
|
1. Create a canonical entitlement registry keyed by plan and feature code.
|
||
|
|
2. Add `entitlement` checks in backend routes/services for gated actions.
|
||
|
|
3. Keep frontend checks for UX, but backend remains source of truth.
|
||
|
|
4. Return clear upgrade-required errors with plan context.
|
||
|
|
5. Preserve behavior for existing orgs during rollout.
|
||
|
|
|
||
|
|
## Rollout Plan
|
||
|
|
1. Phase 1: Normalize feature registry and map all current gates.
|
||
|
|
2. Phase 2: Add backend enforcement for current gated features.
|
||
|
|
3. Phase 3: Introduce new feature allocations (assessment roadmap, SSO gating, future additions).
|
||
|
|
|
||
|
|
## Success Metrics
|
||
|
|
- 0 critical mismatches between pricing page promises and app enforcement.
|
||
|
|
- Reduction in support tickets about "why this feature is locked/unlocked".
|
||
|
|
- Faster launch cycle for pricing new features (single matrix update + entitlement key).
|
||
|
|
|
||
|
|
## Open Questions
|
||
|
|
- Should custom domain remain available to all paid plans or become Enterprise-only in enforcement?
|
||
|
|
- Which future features should be `EARLY_ADOPTER+` versus strictly `ENTERPRISE`?
|
||
|
|
- Do we need plan-level audit reporting for entitlement failures?
|