Summary
Implement the user-facing Pro upgrade and subscription surfaces that build on US-005 catalog paywall behavior.
This plan combines the upgrade entry points from US-016 with the Pro status visibility from US-017, so the app has one coherent subscription UX: catalog cards, correction prompts, navbar plan state, /plans, and the user page all use the same entitlement and CTA logic.
Implementation Changes
- Add a reusable
ProPlanComparisonComponent.
- Supports
page, modal, and compact variants.
- Shows Free vs Pro benefits, including latest free exercises, full catalog, and Pro AI correction.
- Shows price as
$3/month.
- Shows the correct CTA based on session entitlement:
- anonymous: “Log in to upgrade”
- logged-in Free: “Upgrade to Pro”
- Pro active/canceling: “Manage subscription”
- Emits semantic events:
loginRequested, checkoutRequested, manageSubscriptionRequested, dismissRequested.
- Add a
ProUpgradeModalComponent.
- Uses
ProPlanComparisonComponent in modal mode.
- Has a clear dismiss action.
- Preserves catalog/results state when dismissed.
- Accepts source values such as
pro_catalog_modal or pro_correction_prompt.
- Add a standalone
/plans route.
- Uses
ProPlanComparisonComponent in page mode.
- Anonymous CTA routes to login with
returnUrl=/plans.
- Logged-in Free CTA starts checkout.
- Pro CTA opens subscription management.
- Add a
ProUpgradeCtaService.
- Reads
AuthSessionStore entitlement state.
- Routes anonymous users to login with safe
returnUrl and source.
- Starts checkout for logged-in Free users using US-002 checkout contract.
- Opens Stripe Customer Portal for Pro users using US-003 portal contract.
- Add navbar/user-area plan visibility.
- Show a small
Free or Pro plan badge.
- Free/anonymous users can navigate to
/plans.
- Pro users see
Pro; manage action should route to the user page or open portal if appropriate.
Catalog And Correction Entry Points
- Build on US-005 access metadata in
ExerciseGridComponent.
- Pro users navigate to all cards normally.
- Free/anonymous users navigate to free cards normally.
- Free/anonymous users clicking Pro cards stay on catalog and open
ProUpgradeModalComponent.
- Card UX:
- keep Pro cards readable and browsable,
- use a premium-style
Pro badge with workspace_premium or auto_awesome,
- avoid disabled/locked language,
- use copy like “Unlock with Pro.”
- In the exercise results area, show a compact non-blocking Pro prompt only when:
- user is Free or anonymous,
- result uses standard/static correction,
- AI refinement is unavailable because it is Pro.
- Prompt CTA behavior:
- anonymous: route to
/auth/login with current exercise returnUrl and source=pro_correction_prompt,
- logged-in Free: start checkout,
- Pro: do not show the prompt.
User Page Subscription Status
- Extend the user page to show plan status from US-001 session entitlement.
- User page status behavior:
- Free: show
Free plan with an upgrade CTA.
- Pro active: show
Pro active with a manage subscription button.
- Pro canceling: show
Pro active until {currentPeriodEndUtc} with a manage subscription button.
- Pro expired: show
Free plan with an upgrade CTA.
- The manage subscription button opens Stripe Customer Portal using the US-003 portal endpoint.
- If the portal request fails, show a non-blocking error and keep the user on the page.
- Dates should be shown in the user’s locale, but the source field remains
currentPeriodEndUtc.
API And Types
- Depends on US-001 session entitlement fields:
- plan/free/pro state,
- canceling state,
- expired state,
currentPeriodEndUtc.
- Depends on US-002 checkout start endpoint for logged-in Free upgrade CTAs.
- Depends on US-003 customer portal endpoint for Pro manage CTAs.
- No new backend catalog enforcement belongs in this story; direct content/audio enforcement remains US-006.
Acceptance Criteria
- Locked/Pro exercise cards show a Pro upgrade CTA or modal entry point for Free/anonymous users.
- Static correction result can mention AI correction is Pro.
- Navbar/user area can show current plan.
- Anonymous upgrade CTAs require login before checkout and preserve return URL/source.
- User page shows plan status.
- Canceling Pro users see access end date.
- Manage subscription button opens Stripe Customer Portal.
- Reusable plan comparison component is used by
/plans and modal/compact entry points.
Test Plan
Catalog tests:
- Free/anonymous Pro cards show a Pro badge.
- Free/anonymous Pro card click opens the Pro modal and does not navigate.
- Free cards still navigate with initial proposition state.
- Pro users can navigate to all cards.
Modal/plans tests:
- modal renders Free vs Pro benefits and
$3/month.
- modal dismiss preserves catalog state.
/plans renders the same comparison component in page mode.
- anonymous CTA routes to login with correct
returnUrl and source.
- logged-in Free CTA starts checkout.
- Pro CTA opens subscription management.
Correction result tests:
- Free/anonymous static result shows compact Pro AI prompt.
- Pro result does not show the prompt.
- prompt CTA uses current exercise URL as return URL for anonymous users.
Navbar tests:
- anonymous/Free users see Free plan state or upgrade entry point.
- Pro users see Pro status.
User page tests:
- Free users see Free plan and upgrade CTA.
- Pro active users see Pro active and manage subscription.
- Canceling users see access end date and manage subscription.
- Expired users see Free plan and upgrade CTA.
- Manage subscription opens Stripe portal.
- Portal failure shows non-blocking error.
Regression tests:
- existing exercise grid loading, filters, pagination, and result rendering continue to work.
- home latest exercises remains compatible.
Assumptions
- This plan intentionally combines US-016 and US-017 into one subscription UX implementation.
- The standalone route should be
/plans.
- US-005 provides catalog
requiresPro or accessLevel metadata before this work starts.
- US-001 entitlement data is available in
AuthSessionStore.
- US-002 checkout exists before logged-in Free CTAs are wired.
- US-003 portal exists before Pro manage CTAs are wired.
Summary
Implement the user-facing Pro upgrade and subscription surfaces that build on US-005 catalog paywall behavior.
This plan combines the upgrade entry points from US-016 with the Pro status visibility from US-017, so the app has one coherent subscription UX: catalog cards, correction prompts, navbar plan state,
/plans, and the user page all use the same entitlement and CTA logic.Implementation Changes
ProPlanComparisonComponent.page,modal, andcompactvariants.$3/month.loginRequested,checkoutRequested,manageSubscriptionRequested,dismissRequested.ProUpgradeModalComponent.ProPlanComparisonComponentin modal mode.pro_catalog_modalorpro_correction_prompt./plansroute.ProPlanComparisonComponentin page mode.returnUrl=/plans.ProUpgradeCtaService.AuthSessionStoreentitlement state.returnUrlandsource.FreeorProplan badge./plans.Pro; manage action should route to the user page or open portal if appropriate.Catalog And Correction Entry Points
ExerciseGridComponent.ProUpgradeModalComponent.Probadge withworkspace_premiumorauto_awesome,/auth/loginwith current exercisereturnUrlandsource=pro_correction_prompt,User Page Subscription Status
Free planwith an upgrade CTA.Pro activewith a manage subscription button.Pro active until {currentPeriodEndUtc}with a manage subscription button.Free planwith an upgrade CTA.currentPeriodEndUtc.API And Types
currentPeriodEndUtc.Acceptance Criteria
/plansand modal/compact entry points.Test Plan
Catalog tests:
Modal/plans tests:
$3/month./plansrenders the same comparison component in page mode.returnUrlandsource.Correction result tests:
Navbar tests:
User page tests:
Regression tests:
Assumptions
/plans.requiresProoraccessLevelmetadata before this work starts.AuthSessionStore.