Files
classroomio/prd/pricing-improvements/README.md
T

115 lines
5.8 KiB
Markdown
Raw Normal View History

2026-03-09 11:18:22 +01:00
# 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?