Skip to content

fix(pricing): align landing actions with subscription state - #7239

Merged
AmyShang-alt merged 4 commits into
mainfrom
agent/landing-pricing-subscription-state
Aug 21, 2026
Merged

fix(pricing): align landing actions with subscription state#7239
AmyShang-alt merged 4 commits into
mainfrom
agent/landing-pricing-subscription-state

Conversation

@Siri-Ray

@Siri-Ray Siri-Ray commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Why

The public Pricing page can read the signed-in user's billing summary, but it previously reduced that state to a Personal tier. That made month/year changes, first-month eligibility, pending changes, cancel-at-period-end, and Personal-checkout restrictions look actionable when Vela would reject or reroute them.

This PR makes Landing's catalog an honest preview of the checkout behavior while leaving Vela authoritative for workspace roles, Team subscription mutations, seats, and payment state. It also restores the existing signed-in account avatar and account menu on Pricing only, where subscription context is relevant.

What users will see

  • Team plans can switch between monthly and yearly pricing, totals, and checkout targets.
  • Signed-in Personal subscribers land on their current billing interval.
  • Same-interval tier upgrades remain actionable; tier + interval changes are disabled with guidance to switch back first.
  • Same-tier monthly-to-yearly changes remain actionable; yearly-to-monthly changes are blocked with guidance to cancel the subscription first.
  • Current, canceling, scheduled, checkout-unavailable, downgrade, and intro-ineligible states have explicit labels and pricing.
  • Cancel-at-period-end is shown on the current plan card without a duplicate page-level status banner.
  • Signed-in users see their avatar, Console link, and Sign out action in the Pricing header only. Other Landing routes keep the account module disabled.

Surface area

  • UI — new page / dialog / panel / menu item / setting / empty state in apps/web or apps/desktop (including Electron menu bar)
  • Keyboard shortcut — new or changed
  • CLI / env var — new od subcommand or flag, new tools-dev / tools-pack flag, or new OD_* env var
  • API / contract — new /api/* endpoint, new SSE event, or changed shape in packages/contracts
  • Extension point — new entry under skills/, design-systems/, design-templates/, or craft/, or change to the skills protocol
  • i18n keys — added new translation keys (see TRANSLATIONS.md for the locale workflow)
  • New top-level dependency — adding any new entry to the root package.json (dependencies or devDependencies); workspace-package package.json files are out of scope. Include a paragraph on what we get vs. what bytes we ship (see CONTRIBUTING.md → Code style)
  • Default behavior change — changes what existing users experience without opting in (default model, default setting, file/SQLite schema, auto-network on startup, auto-install)
  • None — internal refactor, docs, tests, or translation update only

Screenshots

The review document contains the state matrix and nine screenshots covering default Personal pricing, the Pricing-only account menu, dual changes, Team monthly pricing, a yearly subscriber switching to the Monthly tab, checkout restrictions, scheduled changes, cancel-at-period-end, and the Vela fallback toast:

https://powerformer.feishu.cn/docx/DU1RdSqQRoMxqNxFtCic7huRn7e

Bug fix verification

  • Test paths: apps/landing-page/tests/pricing-current-plan.test.ts, apps/landing-page/tests/pricing-contract.test.ts, and apps/landing-page/tests/header-download-cta.test.ts
  • Did the test go red on main and green on this branch? yes
  • The resolver cases were added red-first for interval upgrades, dual changes, checkout restrictions, scheduled changes, canceling state, and portal availability. The Pricing-only account opt-in contract also failed before the Header/Layout implementation.

Validation

  • pnpm --filter @open-design/landing-page test — 198 passed
  • pnpm --filter @open-design/landing-page typecheck — 0 errors, 0 warnings, 179 existing hints
  • pnpm --filter @open-design/landing-page build:static — 6,739 pages built
  • pnpm guard
  • pnpm typecheck
  • focused post-merge Pricing/header tests — 70 passed
  • Browser QA with mocked billing summaries:
    • monthly Go defaults to Monthly; higher same-period upgrades enabled
    • yearly selection enables same-tier conversion and blocks dual changes
    • a yearly subscriber switching to Monthly cannot change the same tier and sees “取消订阅后可变更套餐”
    • Personal checkout restriction disables Personal CTAs while preserving Team handoff
    • Pricing renders avatar, Console, and Sign out; /faq/ renders no account module
    • cancel-at-period-end has no page-level banner and remains visible on the current plan card
  • git diff --check

Related

@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

🚀 Landing page preview

This PR is deployed to a Cloudflare Pages preview — not staging or production:

@lefarcen

Copy link
Copy Markdown
Contributor

Saw the draft — keeping /pricing/ aligned with the live billing state and limiting the account chrome to that route looks like the right direction. We can do the full pass once this is marked ready for review.

@lefarcen
lefarcen requested a review from mrcfps August 21, 2026 08:58
@lefarcen lefarcen added size/XL PR changes 700-1500 lines risk/medium Medium risk: regular code changes type/bugfix Bug fix labels Aug 21, 2026
@Siri-Ray
Siri-Ray marked this pull request as ready for review August 21, 2026 09:36
@lefarcen

Copy link
Copy Markdown
Contributor

Ready for review noted — leaving the current head with @mrcfps for the code pass.

@mrcfps mrcfps left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Siri-Ray thanks for the careful Pricing subscription-state work — this is a solid fix.

I reviewed the changed ranges across the resolver (resolvePersonalPlanAction / loadPersonalPricingContext), Pricing page CTA wiring (interval sync, intro eligibility, disable/re-enable + syncCtas), Team monthly/yearly checkout labels, and the Pricing-only account opt-in. The action matrix matches the stated product rules (same-interval upgrades, monthly→yearly, blocked dual changes and yearly→monthly, scheduled/canceling/checkout-unavailable), href restoration after re-enable looks correct, and the focused red-spec coverage plus header/Pricing opt-in contracts give good confidence.

No actionable correctness, safety, or maintainability issues on this head. Nice job landing a clear preview of Vela’s boundaries without overreaching into Team/workspace authority.

🔁 Powered by Looper · runner=reviewer · agent=opencode · An autonomous AI dev team for your GitHub repos.

@AmyShang-alt
AmyShang-alt added this pull request to the merge queue Aug 21, 2026
Merged via the queue into main with commit 8bc9b9f Aug 21, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk/medium Medium risk: regular code changes size/XL PR changes 700-1500 lines type/bugfix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants