fix(workspace): show subscribe prompt for ended subscriptions - #14504
Conversation
🎭 Playwright: ✅ 1778 passed, 0 failed · 2 flaky📊 Browser Reports
🎨 Storybook: ✅ Built — View Storybook📦 Bundle: 8.19 MB gzip 🔴 +168 BDetailsSummary
Category Glance App Entry Points — 3.62 kB (baseline 3.62 kB) • ⚪ 0 BMain entry bundles and manifests
Status: 1 added / 1 removed Graph Workspace — 1.29 MB (baseline 1.29 MB) • ⚪ 0 BGraph editor runtime, canvas, workflow orchestration
Status: 1 added / 1 removed / 1 unchanged Views & Navigation — 111 kB (baseline 111 kB) • ⚪ 0 BTop-level views, pages, and routed surfaces
Status: 12 added / 12 removed / 4 unchanged Panels & Settings — 551 kB (baseline 551 kB) • ⚪ 0 BConfiguration panels, inspectors, and settings screens
Status: 11 added / 11 removed / 15 unchanged User & Accounts — 28.7 kB (baseline 28.7 kB) • ⚪ 0 BAuthentication, profile, and account management bundles
Status: 7 added / 7 removed / 3 unchanged Editors & Dialogs — 124 kB (baseline 124 kB) • ⚪ 0 BModals, dialogs, drawers, and in-app editors
Status: 6 added / 6 removed / 1 unchanged UI Components — 70 kB (baseline 70 kB) • ⚪ 0 BReusable component library chunks
Status: 6 added / 6 removed / 9 unchanged Data & Services — 3.44 MB (baseline 3.44 MB) • ⚪ 0 BStores, services, APIs, and repositories
Status: 14 added / 14 removed / 3 unchanged Utilities & Hooks — 386 kB (baseline 386 kB) • ⚪ 0 BHelpers, composables, and utility bundles
Status: 16 added / 16 removed / 20 unchanged Vendor & Third-Party — 15.7 MB (baseline 15.7 MB) • ⚪ 0 BExternal libraries and shared vendor chunks Status: 16 unchanged Other — 12.7 MB (baseline 12.7 MB) • 🟢 -31 BBundles that do not match a named category
Status: 70 added / 70 removed / 210 unchanged ⚡ Performance Report
✅ No regressions detected. All metrics
Historical variance (last 15 runs)
Trend (last 15 commits on main)
Raw data{
"timestamp": "2026-07-31T21:25:07.775Z",
"gitSha": "f6ad821653bfcbb3314ac0ee54582997fca4f4b5",
"branch": "agent/fix-ended-team-subscription-main",
"measurements": [
{
"name": "canvas-idle",
"durationMs": 2033.329999999978,
"styleRecalcs": 10,
"styleRecalcDurationMs": 5.636,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 396.68,
"heapDeltaBytes": 4970728,
"heapUsedBytes": 72940952,
"domNodes": 20,
"jsHeapTotalBytes": 20049920,
"scriptDurationMs": 16.582,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "canvas-idle",
"durationMs": 2019.1750000000184,
"styleRecalcs": 10,
"styleRecalcDurationMs": 5.364000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 395.40799999999996,
"heapDeltaBytes": 4591652,
"heapUsedBytes": 72462780,
"domNodes": 20,
"jsHeapTotalBytes": 20312064,
"scriptDurationMs": 13.52,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-mouse-sweep",
"durationMs": 1786.0879999999497,
"styleRecalcs": 74,
"styleRecalcDurationMs": 27.698,
"layouts": 12,
"layoutDurationMs": 2.5650000000000004,
"taskDurationMs": 753.3799999999999,
"heapDeltaBytes": -17530340,
"heapUsedBytes": 50443796,
"domNodes": -279,
"jsHeapTotalBytes": 20701184,
"scriptDurationMs": 90.074,
"eventListeners": -148,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-mouse-sweep",
"durationMs": 1753.7599999999998,
"styleRecalcs": 72,
"styleRecalcDurationMs": 25.956,
"layouts": 12,
"layoutDurationMs": 2.601,
"taskDurationMs": 696.9799999999999,
"heapDeltaBytes": -14618332,
"heapUsedBytes": 53391264,
"domNodes": -279,
"jsHeapTotalBytes": 20963328,
"scriptDurationMs": 81.75299999999999,
"eventListeners": -144,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-zoom-sweep",
"durationMs": 1685.432999999989,
"styleRecalcs": 32,
"styleRecalcDurationMs": 11.156999999999998,
"layouts": 6,
"layoutDurationMs": 0.424,
"taskDurationMs": 314.62600000000003,
"heapDeltaBytes": 8061404,
"heapUsedBytes": 75890312,
"domNodes": 79,
"jsHeapTotalBytes": 20574208,
"scriptDurationMs": 14.915999999999999,
"eventListeners": 19,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.670000000000012,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "canvas-zoom-sweep",
"durationMs": 1683.9089999999715,
"styleRecalcs": 30,
"styleRecalcDurationMs": 13.601,
"layouts": 6,
"layoutDurationMs": 0.526,
"taskDurationMs": 309.394,
"heapDeltaBytes": 7920332,
"heapUsedBytes": 75912080,
"domNodes": 80,
"jsHeapTotalBytes": 20312064,
"scriptDurationMs": 14.946000000000002,
"eventListeners": 19,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "dom-widget-clipping",
"durationMs": 512.867999999969,
"styleRecalcs": 12,
"styleRecalcDurationMs": 4.740999999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 280.1,
"heapDeltaBytes": -12220980,
"heapUsedBytes": 55520968,
"domNodes": 20,
"jsHeapTotalBytes": 21884928,
"scriptDurationMs": 37.097,
"eventListeners": 2,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "dom-widget-clipping",
"durationMs": 517.2189999999546,
"styleRecalcs": 13,
"styleRecalcDurationMs": 6.312,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 286.15500000000003,
"heapDeltaBytes": -12266084,
"heapUsedBytes": 55572996,
"domNodes": 22,
"jsHeapTotalBytes": 22147072,
"scriptDurationMs": 39.447,
"eventListeners": 2,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "large-graph-idle",
"durationMs": 2013.7659999999755,
"styleRecalcs": 11,
"styleRecalcDurationMs": 6.6640000000000015,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 542.821,
"heapDeltaBytes": 7417568,
"heapUsedBytes": 68311780,
"domNodes": -280,
"jsHeapTotalBytes": 5566464,
"scriptDurationMs": 66.318,
"eventListeners": -144,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-idle",
"durationMs": 2007.489000000021,
"styleRecalcs": 10,
"styleRecalcDurationMs": 5.958999999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 560.619,
"heapDeltaBytes": 7163728,
"heapUsedBytes": 66305432,
"domNodes": -278,
"jsHeapTotalBytes": 5304320,
"scriptDurationMs": 66.636,
"eventListeners": -144,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-pan",
"durationMs": 2063.0590000000097,
"styleRecalcs": 68,
"styleRecalcDurationMs": 8.917,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 924.1430000000001,
"heapDeltaBytes": 25256912,
"heapUsedBytes": 85933740,
"domNodes": -285,
"jsHeapTotalBytes": 5005312,
"scriptDurationMs": 281.857,
"eventListeners": -144,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-pan",
"durationMs": 2090.7989999999472,
"styleRecalcs": 69,
"styleRecalcDurationMs": 9.826999999999998,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 974.8489999999999,
"heapDeltaBytes": 6483260,
"heapUsedBytes": 66986768,
"domNodes": -279,
"jsHeapTotalBytes": 5005312,
"scriptDurationMs": 315.62600000000003,
"eventListeners": -144,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "large-graph-zoom",
"durationMs": 3102.418,
"styleRecalcs": 67,
"styleRecalcDurationMs": 11.548000000000002,
"layouts": 60,
"layoutDurationMs": 5.432,
"taskDurationMs": 1140.181,
"heapDeltaBytes": -9294900,
"heapUsedBytes": 54419340,
"domNodes": -281,
"jsHeapTotalBytes": 6877184,
"scriptDurationMs": 349.40900000000005,
"eventListeners": -146,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-zoom",
"durationMs": 3071.5149999999767,
"styleRecalcs": 67,
"styleRecalcDurationMs": 11.346999999999998,
"layouts": 60,
"layoutDurationMs": 5.542999999999999,
"taskDurationMs": 1071.321,
"heapDeltaBytes": 23084824,
"heapUsedBytes": 84567344,
"domNodes": 18,
"jsHeapTotalBytes": 8126464,
"scriptDurationMs": 346.52700000000004,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "minimap-idle",
"durationMs": 2022.7199999999925,
"styleRecalcs": 9,
"styleRecalcDurationMs": 5.347000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 553.028,
"heapDeltaBytes": 7803436,
"heapUsedBytes": 67889988,
"domNodes": -282,
"jsHeapTotalBytes": 4255744,
"scriptDurationMs": 69.563,
"eventListeners": -144,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "minimap-idle",
"durationMs": 2005.4349999999204,
"styleRecalcs": 11,
"styleRecalcDurationMs": 7.143000000000002,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 557.2969999999999,
"heapDeltaBytes": 7245520,
"heapUsedBytes": 68985736,
"domNodes": -280,
"jsHeapTotalBytes": 4517888,
"scriptDurationMs": 71.29100000000001,
"eventListeners": -144,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "subgraph-dom-widget-clipping",
"durationMs": 525.2040000000306,
"styleRecalcs": 47,
"styleRecalcDurationMs": 7.129,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 299.69500000000005,
"heapDeltaBytes": -12045480,
"heapUsedBytes": 55870804,
"domNodes": 20,
"jsHeapTotalBytes": 22147072,
"scriptDurationMs": 81.96,
"eventListeners": 8,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "subgraph-dom-widget-clipping",
"durationMs": 532.54000000004,
"styleRecalcs": 47,
"styleRecalcDurationMs": 7.792000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 311.824,
"heapDeltaBytes": -11783364,
"heapUsedBytes": 56307656,
"domNodes": 20,
"jsHeapTotalBytes": 22147072,
"scriptDurationMs": 88.894,
"eventListeners": 8,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-idle",
"durationMs": 2014.7820000000252,
"styleRecalcs": 10,
"styleRecalcDurationMs": 5.583000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 380.163,
"heapDeltaBytes": 4469436,
"heapUsedBytes": 72323824,
"domNodes": 20,
"jsHeapTotalBytes": 20836352,
"scriptDurationMs": 11.884,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-idle",
"durationMs": 2018.2389999999941,
"styleRecalcs": 10,
"styleRecalcDurationMs": 5.168000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 380.863,
"heapDeltaBytes": 4370036,
"heapUsedBytes": 72321988,
"domNodes": 20,
"jsHeapTotalBytes": 21098496,
"scriptDurationMs": 11.654000000000002,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-mouse-sweep",
"durationMs": 1702.496999999994,
"styleRecalcs": 77,
"styleRecalcDurationMs": 26.346,
"layouts": 16,
"layoutDurationMs": 3.0100000000000002,
"taskDurationMs": 613.84,
"heapDeltaBytes": -20811772,
"heapUsedBytes": 47148200,
"domNodes": -279,
"jsHeapTotalBytes": 21487616,
"scriptDurationMs": 59.26,
"eventListeners": -148,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-mouse-sweep",
"durationMs": 1670.3719999999862,
"styleRecalcs": 76,
"styleRecalcDurationMs": 23.791,
"layouts": 16,
"layoutDurationMs": 2.618,
"taskDurationMs": 619.746,
"heapDeltaBytes": -20548496,
"heapUsedBytes": 47460540,
"domNodes": -277,
"jsHeapTotalBytes": 20963328,
"scriptDurationMs": 58.51899999999999,
"eventListeners": -144,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-transition-enter",
"durationMs": 899.10500000002,
"styleRecalcs": 19,
"styleRecalcDurationMs": 21.876999999999995,
"layouts": 15,
"layoutDurationMs": 8.453000000000003,
"taskDurationMs": 693.0289999999999,
"heapDeltaBytes": 29141560,
"heapUsedBytes": 97057912,
"domNodes": 13673,
"jsHeapTotalBytes": 16515072,
"scriptDurationMs": 20.278000000000006,
"eventListeners": 2369,
"totalBlockingTimeMs": 104,
"frameDurationMs": 16.66999999999998,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "viewport-pan-sweep",
"durationMs": 8104.662000000018,
"styleRecalcs": 249,
"styleRecalcDurationMs": 23.552999999999997,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 3320.383,
"heapDeltaBytes": 9641188,
"heapUsedBytes": 69278844,
"domNodes": -282,
"jsHeapTotalBytes": 7626752,
"scriptDurationMs": 931.362,
"eventListeners": -128,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "viewport-pan-sweep",
"durationMs": 8111.9939999999815,
"styleRecalcs": 248,
"styleRecalcDurationMs": 22.865,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 3237.2769999999996,
"heapDeltaBytes": 9385024,
"heapUsedBytes": 68538568,
"domNodes": -282,
"jsHeapTotalBytes": 7364608,
"scriptDurationMs": 920.4879999999999,
"eventListeners": -128,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.670000000000012,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "vue-large-graph-idle",
"durationMs": 11051.126000000011,
"styleRecalcs": 0,
"styleRecalcDurationMs": 0,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 11035.012999999999,
"heapDeltaBytes": -54103744,
"heapUsedBytes": 173333004,
"domNodes": -8316,
"jsHeapTotalBytes": -3608576,
"scriptDurationMs": 400.213,
"eventListeners": -16391,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.219999999999953,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "vue-large-graph-idle",
"durationMs": 11325.916000000007,
"styleRecalcs": 0,
"styleRecalcDurationMs": 0,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 11308.831999999999,
"heapDeltaBytes": -55546816,
"heapUsedBytes": 172527840,
"domNodes": -8312,
"jsHeapTotalBytes": -8593408,
"scriptDurationMs": 418.69300000000004,
"eventListeners": -16389,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.220000000000073,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "vue-large-graph-pan",
"durationMs": 14094.107000000007,
"styleRecalcs": 67,
"styleRecalcDurationMs": 12.057000000000013,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 14074.375,
"heapDeltaBytes": -31218892,
"heapUsedBytes": 177772288,
"domNodes": -8316,
"jsHeapTotalBytes": -14692352,
"scriptDurationMs": 693.059,
"eventListeners": -16385,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.220000000000073,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "vue-large-graph-pan",
"durationMs": 13501.315999999973,
"styleRecalcs": 67,
"styleRecalcDurationMs": 11.208999999999996,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 13481.961,
"heapDeltaBytes": -41488192,
"heapUsedBytes": 166814336,
"domNodes": -8312,
"jsHeapTotalBytes": -13049856,
"scriptDurationMs": 674.715,
"eventListeners": -16392,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.219999999999953,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "workflow-execution",
"durationMs": 448.40799999997216,
"styleRecalcs": 19,
"styleRecalcDurationMs": 14.763,
"layouts": 4,
"layoutDurationMs": 0.9909999999999999,
"taskDurationMs": 95.43000000000002,
"heapDeltaBytes": -15746340,
"heapUsedBytes": 51126048,
"domNodes": 154,
"jsHeapTotalBytes": 7729152,
"scriptDurationMs": 8.664,
"eventListeners": 65,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "workflow-execution",
"durationMs": 439.94099999997616,
"styleRecalcs": 14,
"styleRecalcDurationMs": 11.507000000000001,
"layouts": 2,
"layoutDurationMs": 0.268,
"taskDurationMs": 80.55000000000001,
"heapDeltaBytes": -16009196,
"heapUsedBytes": 50991116,
"domNodes": 121,
"jsHeapTotalBytes": 7467008,
"scriptDurationMs": 6.720000000000001,
"eventListeners": 67,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.669999999999998,
"p95FrameDurationMs": 16.700000000000273
}
]
} |
📝 WalkthroughWalkthroughBilling fixtures and workspace mocks now support ended Standard subscriptions. Workspace subscription rendering shows the unsubscribed prompt and ChangesEnded subscription billing
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant BrowserTest
participant CloudWorkspaceMockHelper
participant BillingStatusAPI
participant PlansAPI
participant SubscriptionPanel
BrowserTest->>CloudWorkspaceMockHelper: Configure ended Standard billing status
CloudWorkspaceMockHelper->>BillingStatusAPI: Return supplied billing status
CloudWorkspaceMockHelper->>PlansAPI: Return plan derived from billing status
SubscriptionPanel->>BillingStatusAPI: Read subscription status
SubscriptionPanel->>PlansAPI: Read current plan
SubscriptionPanel-->>BrowserTest: Show unsubscribed prompt and Subscribe Now
Possibly related PRs
Suggested labels: Suggested reviewers: Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (1 inconclusive)
✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
📄 Knowledge reviewDosu skipped reviewing this PR because your organization has used its |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@browser_tests/fixtures/helpers/CloudWorkspaceMockHelper.ts`:
- Line 154: Update the billing mock response around current_plan_slug and the
plans collection so every current_plan_slug, including standard-monthly for
ended Standard billing, has a matching plan in /api/billing/plans. Include the
Standard plan or derive the collection from the billing status while preserving
the existing TEAM_PRO_PLAN behavior.
In `@src/platform/workspace/components/SubscriptionPanelContentWorkspace.test.ts`:
- Around line 537-543: Update the test case around the subscription-state mocks
so it sets only mockSubscriptionStatus.value to 'ended' while retaining the
active subscription, billing status, team-plan guard, Standard tier, and
standard-monthly slug values. Ensure the test exercises the ended-status
precedence rather than selecting the unsubscribed view through
mockIsActiveSubscription, mockBillingStatus, or mockHasTeamPlan.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: a68fbead-5ac6-4001-b7e5-1a965639b29e
📒 Files selected for processing (4)
browser_tests/fixtures/data/cloudWorkspace.tsbrowser_tests/fixtures/helpers/CloudWorkspaceMockHelper.tsbrowser_tests/tests/dialogs/endedSubscription.spec.tssrc/platform/workspace/components/SubscriptionPanelContentWorkspace.test.ts
There was a problem hiding this comment.
🔍 Cursor Review — Consolidated panel
Triggered by @wei-hai.
✅ No high-signal findings.
Panel: 8/8 reviewers contributed findings.
Codecov Report✅ All modified and coverable lines are covered by tests. @@ Coverage Diff @@
## main #14504 +/- ##
==========================================
+ Coverage 79.32% 79.36% +0.03%
==========================================
Files 1767 1767
Lines 114127 113952 -175
Branches 36779 36605 -174
==========================================
- Hits 90536 90434 -102
+ Misses 23049 22975 -74
- Partials 542 543 +1
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 24 files with indirect coverage changes 🚀 New features to boost your workflow:
|
dante01yoon
left a comment
There was a problem hiding this comment.
Reviewed current head bc6b09154c47ae2a0ba43c01451d0c6dfeb5fbde against the stated terminal-subscription precedence behavior. The component regression keeps stale active/paid/team-plan guards enabled, the cloud fixture returns a matching current plan, and the cloud E2E covers the user-visible prompt. No blocking findings.
|
|
|
…subscriptions (#14509) ## Summary Backport of #14504 to `core/1.47`. - Resolves the release-branch cherry-pick conflicts while preserving the existing cancellation behavior. - Treats `subscription_status: ended` as terminal even when paid-plan metadata is stale. - Includes component and cloud E2E regression coverage adapted to this release branch. ## Validation - 27 component tests passed - App and browser typechecks - Targeted formatting and lint checks - `knip` push hook
… subscriptions (#14510) ## Summary Backport of #14504 to `cloud/1.48`. - Resolves the release-branch cherry-pick conflicts while preserving the existing cancellation behavior. - Treats `subscription_status: ended` as terminal even when paid-plan metadata is stale. - Includes component and cloud E2E regression coverage adapted to this release branch. ## Validation - 31 component tests passed - App and browser typechecks - Targeted formatting and lint checks - `knip` push hook
…subscriptions (#14511) ## Summary Backport of #14504 to `core/1.48`. - Resolves the release-branch cherry-pick conflicts while preserving the existing cancellation behavior. - Treats `subscription_status: ended` as terminal even when paid-plan metadata is stale. - Includes component and cloud E2E regression coverage adapted to this release branch. ## Validation - 31 component tests passed - App and browser typechecks - Targeted formatting and lint checks - `knip` push hook
|
|
|
…omfy-Org#14607) After cancelling a subscription on Stripe's side, access is correctly revoked, but Plans & Pricing still showed the lost plan as "Current Plan" with a disabled button, so the user could not resubscribe to it. The other tiers also mislabelled as "Change to X" instead of "Subscribe to X". ## Root cause An ended subscription still reports its `plan_slug` and `subscription_tier` on `GET /api/billing/status` (only `is_active` flips to false). The pricing table modelled just two states for the plan you hold — active (disabled "Current Plan") and cancel-scheduled (enabled "Resubscribe") — and `isCancelled` is derived from `subscription_status === 'canceled'` only, so an `ended` subscription fell into the active bucket. This is the residual half of Comfy-Org#14504, which fixed the same `ended` blind spot in the subscription panel but not here. ## Change `UnifiedPricingTable.vue` treats `subscription_status: 'ended'` as holding no current plan, so the CTA becomes an enabled "Subscribe to <plan>". Applies to both the personal tier cards (`isCurrentPlan`, `currentTierKey`) and the team credit stop (`isTeamSubscribed`). Backend needs no change — the subscribe path already treats an ended subscription as "no subscription". ## Verification - Two regression tests added; both fail on `main` and pass with the fix. - `UnifiedPricingTable` suite: 12 passed, incl. under `--coverage` (matching CI). - Workspace + billing + subscription suites: 84 files, 1339 tests passed. - `vue-tsc --noEmit`, eslint, oxfmt clean.
Summary
subscription_status: endedas terminal even whenis_activeand paid-plan metadata lag behind.Root cause
The subscription panel required
endedandis_active=false. When the terminal status arrived first, stale active/plan data suppressed the subscribe prompt.flowchart LR subgraph BEFORE[Before] direction TB B1[Billing state loads] --> B2{"ended AND is_active=false?"} B2 -- Yes --> B3[Show subscribe prompt] B2 -- "No: ended + stale active" --> B4[Show stale Standard plan] end subgraph AFTER[After] direction TB A1[Billing state loads] --> A2{"subscription_status = ended?"} A2 -- Yes --> A3[Show subscribe prompt] A2 -- No --> A4{"Active paid plan?"} A4 -- Yes --> A5[Show current plan] A4 -- No --> A3 endReview focus
SubscriptionPanelContentWorkspace.vue: ended status now takes precedence over stale paid-plan guards.CloudWorkspaceMockHelper.ts:current_plan_slugalways has a matching plan.Validation
knip