Skip to content

[backport cloud/1.43] feat: add frontend subscription success recovery - #11476

Merged
benceruleanlu merged 2 commits into
cloud/1.43from
bl/backport-11286-cloud-1.43
Apr 21, 2026
Merged

[backport cloud/1.43] feat: add frontend subscription success recovery#11476
benceruleanlu merged 2 commits into
cloud/1.43from
bl/backport-11286-cloud-1.43

Conversation

@benceruleanlu

@benceruleanlu benceruleanlu commented Apr 20, 2026

Copy link
Copy Markdown
Member

Backports #11286

Summary

  • backport frontend subscription success recovery to cloud/1.43

Backport Delta

  • 18ef350db is the cherry-pick of main's ecb7fd479 from feat: add frontend subscription success recovery #11286
  • the backport-only review surface is intentionally small:
    • src/platform/cloud/subscription/components/PricingTable.test.ts: adapt the assertions to cloud/1.43's existing mount-based test harness
    • src/platform/cloud/subscription/constants/tierPricing.ts: one-line type-only export (type SubscriptionTier -> export type SubscriptionTier)
  • runtime review should therefore mostly follow feat: add frontend subscription success recovery #11286 rather than treating this as a novel branch-specific implementation

Why

The automated backport failed because cloud/1.43 had drifted in PricingTable.test.ts. The runtime code itself cherry-picked cleanly; the only non-test branch-local change was the small SubscriptionTier export needed to match the API surface expected by the backported code.

Validation

  • pnpm exec vitest run src/platform/cloud/subscription/composables/useSubscription.test.ts src/platform/cloud/subscription/components/PricingTable.test.ts src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.test.ts src/platform/telemetry/providers/cloud/GtmTelemetryProvider.test.ts
  • pnpm typecheck

┆Issue is synchronized with this Notion page by Unito

@benceruleanlu benceruleanlu added the backport Backporting a PR onto a release candidate label Apr 20, 2026
@vercel

vercel Bot commented Apr 20, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
website-frontend Error Error Apr 20, 2026 4:51pm

Request Review

@coderabbitai

coderabbitai Bot commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Ignore keyword(s) in the title.

⛔ Ignored keywords (2)
  • [release]
  • [backport

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: aad0a61f-94bf-491f-85c3-3ca499ce9ffb

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bl/backport-11286-cloud-1.43

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented Apr 20, 2026

Copy link
Copy Markdown

🎭 Playwright: ✅ 1020 passed, 0 failed · 1 flaky

📊 Browser Reports
  • chromium: View Report (✅ 1006 / ❌ 0 / ⚠️ 1 / ⏭️ 1)
  • chromium-2x: View Report (✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0)
  • chromium-0.5x: View Report (✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0)
  • mobile-chrome: View Report (✅ 11 / ❌ 0 / ⚠️ 0 / ⏭️ 0)

@github-actions

github-actions Bot commented Apr 20, 2026

Copy link
Copy Markdown

🎨 Storybook: ✅ Built — View Storybook

Details

⏰ Completed at: 04/21/2026, 10:11:12 PM UTC

Links

@codecov

codecov Bot commented Apr 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.30303% with 52 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
.../subscription/utils/subscriptionCheckoutTracker.ts 83.20% 22 Missing ⚠️
.../cloud/subscription/composables/useSubscription.ts 81.81% 16 Missing and 2 partials ⚠️
src/composables/auth/useAuthActions.ts 0.00% 3 Missing ⚠️
src/platform/telemetry/TelemetryRegistry.ts 0.00% 3 Missing ⚠️
...orm/cloud/subscription/components/PricingTable.vue 84.61% 1 Missing and 1 partial ⚠️
...metry/providers/cloud/MixpanelTelemetryProvider.ts 0.00% 2 Missing ⚠️
...n/components/SubscriptionRequiredDialogContent.vue 0.00% 1 Missing ⚠️
...oud/subscription/utils/subscriptionCheckoutUtil.ts 80.00% 1 Missing ⚠️
@@              Coverage Diff              @@
##             cloud/1.43   #11476   +/-   ##
=============================================
  Coverage              ?   43.72%           
=============================================
  Files                 ?     1334           
  Lines                 ?    68860           
  Branches              ?    18251           
=============================================
  Hits                  ?    30111           
  Misses                ?    38155           
  Partials              ?      594           
Files with missing lines Coverage Δ
...atform/cloud/subscription/constants/tierPricing.ts 100.00% <ø> (ø)
.../telemetry/providers/cloud/GtmTelemetryProvider.ts 65.38% <100.00%> (ø)
...emetry/providers/cloud/PostHogTelemetryProvider.ts 47.34% <100.00%> (ø)
src/platform/telemetry/types.ts 100.00% <ø> (ø)
...n/components/SubscriptionRequiredDialogContent.vue 0.00% <0.00%> (ø)
...oud/subscription/utils/subscriptionCheckoutUtil.ts 69.56% <80.00%> (ø)
...orm/cloud/subscription/components/PricingTable.vue 95.42% <84.61%> (ø)
...metry/providers/cloud/MixpanelTelemetryProvider.ts 0.00% <0.00%> (ø)
src/composables/auth/useAuthActions.ts 1.25% <0.00%> (ø)
src/platform/telemetry/TelemetryRegistry.ts 0.00% <0.00%> (ø)
... and 2 more
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Apr 20, 2026

Copy link
Copy Markdown

📦 Bundle Size

⏳ Size data collection in progress…

⚡ Performance Report

canvas-idle: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 60.4 MB heap
canvas-mouse-sweep: · 60.0 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 56.1 MB heap
canvas-zoom-sweep: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 64.1 MB heap
dom-widget-clipping: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 47.1 MB heap
large-graph-idle: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 53.4 MB heap
large-graph-pan: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 68.0 MB heap
large-graph-zoom: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 59.1 MB heap
minimap-idle: · 60.0 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 55.2 MB heap
subgraph-dom-widget-clipping: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 47.4 MB heap
subgraph-idle: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 60.1 MB heap
subgraph-mouse-sweep: · 60.0 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 52.2 MB heap
viewport-pan-sweep: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 73.2 MB heap
vue-large-graph-idle: · 56.3 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 160.1 MB heap
vue-large-graph-pan: · 56.3 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 152.5 MB heap
workflow-execution: · 60.0 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 46.5 MB heap

No baseline found — showing absolute values.

Metric Value
canvas-idle: avg frame time 17ms
canvas-idle: p95 frame time 17ms
canvas-idle: layout duration 0ms
canvas-idle: style recalc duration 12ms
canvas-idle: layout count 0
canvas-idle: style recalc count 11
canvas-idle: task duration 410ms
canvas-idle: script duration 28ms
canvas-idle: TBT 0ms
canvas-idle: heap used 60.4 MB
canvas-idle: DOM nodes 22
canvas-idle: event listeners 6
canvas-mouse-sweep: avg frame time 17ms
canvas-mouse-sweep: p95 frame time 17ms
canvas-mouse-sweep: layout duration 4ms
canvas-mouse-sweep: style recalc duration 45ms
canvas-mouse-sweep: layout count 12
canvas-mouse-sweep: style recalc count 82
canvas-mouse-sweep: task duration 969ms
canvas-mouse-sweep: script duration 136ms
canvas-mouse-sweep: TBT 0ms
canvas-mouse-sweep: heap used 56.1 MB
canvas-mouse-sweep: DOM nodes 64
canvas-mouse-sweep: event listeners 6
canvas-zoom-sweep: avg frame time 17ms
canvas-zoom-sweep: p95 frame time 17ms
canvas-zoom-sweep: layout duration 1ms
canvas-zoom-sweep: style recalc duration 19ms
canvas-zoom-sweep: layout count 6
canvas-zoom-sweep: style recalc count 31
canvas-zoom-sweep: task duration 344ms
canvas-zoom-sweep: script duration 31ms
canvas-zoom-sweep: TBT 0ms
canvas-zoom-sweep: heap used 64.1 MB
canvas-zoom-sweep: DOM nodes 77
canvas-zoom-sweep: event listeners 19
dom-widget-clipping: avg frame time 17ms
dom-widget-clipping: p95 frame time 17ms
dom-widget-clipping: layout duration 0ms
dom-widget-clipping: style recalc duration 12ms
dom-widget-clipping: layout count 0
dom-widget-clipping: style recalc count 13
dom-widget-clipping: task duration 355ms
dom-widget-clipping: script duration 69ms
dom-widget-clipping: TBT 0ms
dom-widget-clipping: heap used 47.1 MB
dom-widget-clipping: DOM nodes 21
dom-widget-clipping: event listeners 2
large-graph-idle: avg frame time 17ms
large-graph-idle: p95 frame time 17ms
large-graph-idle: layout duration 0ms
large-graph-idle: style recalc duration 11ms
large-graph-idle: layout count 0
large-graph-idle: style recalc count 10
large-graph-idle: task duration 590ms
large-graph-idle: script duration 110ms
large-graph-idle: TBT 0ms
large-graph-idle: heap used 53.4 MB
large-graph-idle: DOM nodes -259
large-graph-idle: event listeners -127
large-graph-pan: avg frame time 17ms
large-graph-pan: p95 frame time 17ms
large-graph-pan: layout duration 0ms
large-graph-pan: style recalc duration 15ms
large-graph-pan: layout count 0
large-graph-pan: style recalc count 68
large-graph-pan: task duration 1120ms
large-graph-pan: script duration 426ms
large-graph-pan: TBT 0ms
large-graph-pan: heap used 68.0 MB
large-graph-pan: DOM nodes -263
large-graph-pan: event listeners -127
large-graph-zoom: avg frame time 17ms
large-graph-zoom: p95 frame time 17ms
large-graph-zoom: layout duration 8ms
large-graph-zoom: style recalc duration 17ms
large-graph-zoom: layout count 60
large-graph-zoom: style recalc count 66
large-graph-zoom: task duration 1356ms
large-graph-zoom: script duration 503ms
large-graph-zoom: TBT 0ms
large-graph-zoom: heap used 59.1 MB
large-graph-zoom: DOM nodes -264
large-graph-zoom: event listeners -123
minimap-idle: avg frame time 17ms
minimap-idle: p95 frame time 17ms
minimap-idle: layout duration 0ms
minimap-idle: style recalc duration 11ms
minimap-idle: layout count 0
minimap-idle: style recalc count 9
minimap-idle: task duration 587ms
minimap-idle: script duration 104ms
minimap-idle: TBT 0ms
minimap-idle: heap used 55.2 MB
minimap-idle: DOM nodes -262
minimap-idle: event listeners -127
subgraph-dom-widget-clipping: avg frame time 17ms
subgraph-dom-widget-clipping: p95 frame time 17ms
subgraph-dom-widget-clipping: layout duration 0ms
subgraph-dom-widget-clipping: style recalc duration 12ms
subgraph-dom-widget-clipping: layout count 0
subgraph-dom-widget-clipping: style recalc count 48
subgraph-dom-widget-clipping: task duration 368ms
subgraph-dom-widget-clipping: script duration 127ms
subgraph-dom-widget-clipping: TBT 0ms
subgraph-dom-widget-clipping: heap used 47.4 MB
subgraph-dom-widget-clipping: DOM nodes 22
subgraph-dom-widget-clipping: event listeners 8
subgraph-idle: avg frame time 17ms
subgraph-idle: p95 frame time 17ms
subgraph-idle: layout duration 0ms
subgraph-idle: style recalc duration 10ms
subgraph-idle: layout count 0
subgraph-idle: style recalc count 11
subgraph-idle: task duration 345ms
subgraph-idle: script duration 17ms
subgraph-idle: TBT 0ms
subgraph-idle: heap used 60.1 MB
subgraph-idle: DOM nodes 22
subgraph-idle: event listeners 6
subgraph-mouse-sweep: avg frame time 17ms
subgraph-mouse-sweep: p95 frame time 17ms
subgraph-mouse-sweep: layout duration 5ms
subgraph-mouse-sweep: style recalc duration 41ms
subgraph-mouse-sweep: layout count 16
subgraph-mouse-sweep: style recalc count 76
subgraph-mouse-sweep: task duration 722ms
subgraph-mouse-sweep: script duration 107ms
subgraph-mouse-sweep: TBT 0ms
subgraph-mouse-sweep: heap used 52.2 MB
subgraph-mouse-sweep: DOM nodes 63
subgraph-mouse-sweep: event listeners 4
viewport-pan-sweep: avg frame time 17ms
viewport-pan-sweep: p95 frame time 17ms
viewport-pan-sweep: layout duration 0ms
viewport-pan-sweep: style recalc duration 47ms
viewport-pan-sweep: layout count 0
viewport-pan-sweep: style recalc count 252
viewport-pan-sweep: task duration 3922ms
viewport-pan-sweep: script duration 1307ms
viewport-pan-sweep: TBT 0ms
viewport-pan-sweep: heap used 73.2 MB
viewport-pan-sweep: DOM nodes -256
viewport-pan-sweep: event listeners -107
vue-large-graph-idle: avg frame time 18ms
vue-large-graph-idle: p95 frame time 17ms
vue-large-graph-idle: layout duration 0ms
vue-large-graph-idle: style recalc duration 0ms
vue-large-graph-idle: layout count 0
vue-large-graph-idle: style recalc count 0
vue-large-graph-idle: task duration 12582ms
vue-large-graph-idle: script duration 626ms
vue-large-graph-idle: TBT 0ms
vue-large-graph-idle: heap used 160.1 MB
vue-large-graph-idle: DOM nodes -9848
vue-large-graph-idle: event listeners -23961
vue-large-graph-pan: avg frame time 18ms
vue-large-graph-pan: p95 frame time 17ms
vue-large-graph-pan: layout duration 0ms
vue-large-graph-pan: style recalc duration 15ms
vue-large-graph-pan: layout count 0
vue-large-graph-pan: style recalc count 66
vue-large-graph-pan: task duration 14566ms
vue-large-graph-pan: script duration 884ms
vue-large-graph-pan: TBT 0ms
vue-large-graph-pan: heap used 152.5 MB
vue-large-graph-pan: DOM nodes -9851
vue-large-graph-pan: event listeners -23981
workflow-execution: avg frame time 17ms
workflow-execution: p95 frame time 17ms
workflow-execution: layout duration 1ms
workflow-execution: style recalc duration 23ms
workflow-execution: layout count 5
workflow-execution: style recalc count 17
workflow-execution: task duration 121ms
workflow-execution: script duration 29ms
workflow-execution: TBT 0ms
workflow-execution: heap used 46.5 MB
workflow-execution: DOM nodes 156
workflow-execution: event listeners 71
Raw data
{
  "timestamp": "2026-04-21T22:22:29.301Z",
  "gitSha": "7ccac3714c15ebc3097df8fcf72abb5378a8e0a1",
  "branch": "bl/backport-11286-cloud-1.43",
  "measurements": [
    {
      "name": "canvas-idle",
      "durationMs": 2047.376000000014,
      "styleRecalcs": 11,
      "styleRecalcDurationMs": 11.151,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 399.938,
      "heapDeltaBytes": 20907920,
      "heapUsedBytes": 63949292,
      "domNodes": 22,
      "jsHeapTotalBytes": 22806528,
      "scriptDurationMs": 22.938,
      "eventListeners": 6,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "canvas-idle",
      "durationMs": 2045.7320000000436,
      "styleRecalcs": 12,
      "styleRecalcDurationMs": 13.394000000000004,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 419.288,
      "heapDeltaBytes": 20349280,
      "heapUsedBytes": 62888140,
      "domNodes": 24,
      "jsHeapTotalBytes": 22282240,
      "scriptDurationMs": 28.317999999999994,
      "eventListeners": 6,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333335,
      "p95FrameDurationMs": 16.699999999999818
    },
    {
      "name": "canvas-idle",
      "durationMs": 2024.5879999999943,
      "styleRecalcs": 11,
      "styleRecalcDurationMs": 11.739999999999998,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 409.672,
      "heapDeltaBytes": 20368676,
      "heapUsedBytes": 63333068,
      "domNodes": 22,
      "jsHeapTotalBytes": 22544384,
      "scriptDurationMs": 28.669,
      "eventListeners": 6,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "canvas-mouse-sweep",
      "durationMs": 2009.017,
      "styleRecalcs": 82,
      "styleRecalcDurationMs": 44.998,
      "layouts": 12,
      "layoutDurationMs": 3.502,
      "taskDurationMs": 1019.25,
      "heapDeltaBytes": 16041212,
      "heapUsedBytes": 58871060,
      "domNodes": 66,
      "jsHeapTotalBytes": 23855104,
      "scriptDurationMs": 140.112,
      "eventListeners": 6,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "canvas-mouse-sweep",
      "durationMs": 1791.7879999999968,
      "styleRecalcs": 75,
      "styleRecalcDurationMs": 36.36200000000001,
      "layouts": 12,
      "layoutDurationMs": 3.184,
      "taskDurationMs": 750.0070000000001,
      "heapDeltaBytes": 16007872,
      "heapUsedBytes": 58876916,
      "domNodes": 58,
      "jsHeapTotalBytes": 23330816,
      "scriptDurationMs": 136.154,
      "eventListeners": 6,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.670000000000012,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "canvas-mouse-sweep",
      "durationMs": 1990.1120000000674,
      "styleRecalcs": 83,
      "styleRecalcDurationMs": 45.561,
      "layouts": 12,
      "layoutDurationMs": 3.9239999999999995,
      "taskDurationMs": 968.653,
      "heapDeltaBytes": 15934668,
      "heapUsedBytes": 60499012,
      "domNodes": 64,
      "jsHeapTotalBytes": 23592960,
      "scriptDurationMs": 130.596,
      "eventListeners": 6,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333335,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "canvas-zoom-sweep",
      "durationMs": 1727.2279999999682,
      "styleRecalcs": 31,
      "styleRecalcDurationMs": 19.407,
      "layouts": 6,
      "layoutDurationMs": 0.6069999999999999,
      "taskDurationMs": 328.90200000000004,
      "heapDeltaBytes": 15253140,
      "heapUsedBytes": 66348844,
      "domNodes": 77,
      "jsHeapTotalBytes": 22282240,
      "scriptDurationMs": 26.163,
      "eventListeners": 19,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333335,
      "p95FrameDurationMs": 16.699999999999818
    },
    {
      "name": "canvas-zoom-sweep",
      "durationMs": 1740.714999999966,
      "styleRecalcs": 30,
      "styleRecalcDurationMs": 18.396000000000004,
      "layouts": 6,
      "layoutDurationMs": 0.541,
      "taskDurationMs": 343.72999999999996,
      "heapDeltaBytes": 24970200,
      "heapUsedBytes": 67894272,
      "domNodes": 78,
      "jsHeapTotalBytes": 20709376,
      "scriptDurationMs": 30.941,
      "eventListeners": 19,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.670000000000012,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "canvas-zoom-sweep",
      "durationMs": 1742.9050000000643,
      "styleRecalcs": 32,
      "styleRecalcDurationMs": 18.53,
      "layouts": 6,
      "layoutDurationMs": 0.5790000000000001,
      "taskDurationMs": 353.3999999999999,
      "heapDeltaBytes": 15707772,
      "heapUsedBytes": 67209320,
      "domNodes": 76,
      "jsHeapTotalBytes": 23330816,
      "scriptDurationMs": 30.804000000000006,
      "eventListeners": 19,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "dom-widget-clipping",
      "durationMs": 640.232999999995,
      "styleRecalcs": 12,
      "styleRecalcDurationMs": 16.817999999999998,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 411.906,
      "heapDeltaBytes": 7659092,
      "heapUsedBytes": 51820704,
      "domNodes": 20,
      "jsHeapTotalBytes": 13369344,
      "scriptDurationMs": 81.04899999999999,
      "eventListeners": 0,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.700000000000273
    },
    {
      "name": "dom-widget-clipping",
      "durationMs": 564.5260000000007,
      "styleRecalcs": 13,
      "styleRecalcDurationMs": 12.28,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 351.411,
      "heapDeltaBytes": 6480600,
      "heapUsedBytes": 49377788,
      "domNodes": 21,
      "jsHeapTotalBytes": 13369344,
      "scriptDurationMs": 68.862,
      "eventListeners": 2,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000273
    },
    {
      "name": "dom-widget-clipping",
      "durationMs": 561.2989999999627,
      "styleRecalcs": 13,
      "styleRecalcDurationMs": 9.103000000000002,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 354.658,
      "heapDeltaBytes": 6516372,
      "heapUsedBytes": 49186372,
      "domNodes": 22,
      "jsHeapTotalBytes": 12845056,
      "scriptDurationMs": 68.238,
      "eventListeners": 2,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.663333333333338,
      "p95FrameDurationMs": 16.700000000000273
    },
    {
      "name": "large-graph-idle",
      "durationMs": 2036.0510000000147,
      "styleRecalcs": 11,
      "styleRecalcDurationMs": 11.318999999999999,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 590.1959999999999,
      "heapDeltaBytes": 5021728,
      "heapUsedBytes": 56002816,
      "domNodes": -259,
      "jsHeapTotalBytes": 16707584,
      "scriptDurationMs": 105.03500000000001,
      "eventListeners": -127,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333335,
      "p95FrameDurationMs": 16.699999999999818
    },
    {
      "name": "large-graph-idle",
      "durationMs": 2059.4010000000367,
      "styleRecalcs": 10,
      "styleRecalcDurationMs": 11.348999999999998,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 579.495,
      "heapDeltaBytes": 4869448,
      "heapUsedBytes": 56023712,
      "domNodes": -258,
      "jsHeapTotalBytes": 16183296,
      "scriptDurationMs": 110.22299999999998,
      "eventListeners": -125,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333335,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "large-graph-idle",
      "durationMs": 2039.0350000000126,
      "styleRecalcs": 10,
      "styleRecalcDurationMs": 10.567999999999998,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 632.46,
      "heapDeltaBytes": 4064564,
      "heapUsedBytes": 54767008,
      "domNodes": -259,
      "jsHeapTotalBytes": 16707584,
      "scriptDurationMs": 116.89,
      "eventListeners": -127,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.699999999999818
    },
    {
      "name": "large-graph-pan",
      "durationMs": 2140.338999999983,
      "styleRecalcs": 68,
      "styleRecalcDurationMs": 15.328000000000001,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 1119.961,
      "heapDeltaBytes": 13274312,
      "heapUsedBytes": 67170964,
      "domNodes": -263,
      "jsHeapTotalBytes": 18485248,
      "scriptDurationMs": 426.312,
      "eventListeners": -127,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "large-graph-pan",
      "durationMs": 2140.2929999999856,
      "styleRecalcs": 69,
      "styleRecalcDurationMs": 16.084,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 1093.969,
      "heapDeltaBytes": 17202792,
      "heapUsedBytes": 71317220,
      "domNodes": -262,
      "jsHeapTotalBytes": 18223104,
      "scriptDurationMs": 392.37,
      "eventListeners": -127,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "large-graph-pan",
      "durationMs": 2159.240999999952,
      "styleRecalcs": 68,
      "styleRecalcDurationMs": 15.355999999999998,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 1159.312,
      "heapDeltaBytes": 18199532,
      "heapUsedBytes": 72331136,
      "domNodes": -263,
      "jsHeapTotalBytes": 18485248,
      "scriptDurationMs": 435.573,
      "eventListeners": -127,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "large-graph-zoom",
      "durationMs": 3114.787999999976,
      "styleRecalcs": 64,
      "styleRecalcDurationMs": 15.501999999999999,
      "layouts": 60,
      "layoutDurationMs": 7.718000000000001,
      "taskDurationMs": 1356.4289999999999,
      "heapDeltaBytes": 7736380,
      "heapUsedBytes": 63868420,
      "domNodes": -268,
      "jsHeapTotalBytes": 17551360,
      "scriptDurationMs": 496.25800000000004,
      "eventListeners": -127,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.670000000000012,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "large-graph-zoom",
      "durationMs": 3181.3720000000103,
      "styleRecalcs": 66,
      "styleRecalcDurationMs": 17.103000000000005,
      "layouts": 60,
      "layoutDurationMs": 7.292999999999999,
      "taskDurationMs": 1353.914,
      "heapDeltaBytes": 2660000,
      "heapUsedBytes": 58148664,
      "domNodes": -264,
      "jsHeapTotalBytes": 17494016,
      "scriptDurationMs": 503.40700000000004,
      "eventListeners": -123,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.699999999999818
    },
    {
      "name": "large-graph-zoom",
      "durationMs": 3184.443000000101,
      "styleRecalcs": 66,
      "styleRecalcDurationMs": 16.928,
      "layouts": 60,
      "layoutDurationMs": 7.502,
      "taskDurationMs": 1405.713,
      "heapDeltaBytes": 7269600,
      "heapUsedBytes": 61991976,
      "domNodes": -264,
      "jsHeapTotalBytes": 17494016,
      "scriptDurationMs": 517.072,
      "eventListeners": -123,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "minimap-idle",
      "durationMs": 2052.9879999999707,
      "styleRecalcs": 10,
      "styleRecalcDurationMs": 10.790000000000001,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 572.314,
      "heapDeltaBytes": 3701280,
      "heapUsedBytes": 57829268,
      "domNodes": -260,
      "jsHeapTotalBytes": 16707584,
      "scriptDurationMs": 102.461,
      "eventListeners": -127,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "minimap-idle",
      "durationMs": 2026.8140000000017,
      "styleRecalcs": 9,
      "styleRecalcDurationMs": 11.049,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 589.036,
      "heapDeltaBytes": 2826388,
      "heapUsedBytes": 57196068,
      "domNodes": -263,
      "jsHeapTotalBytes": 15921152,
      "scriptDurationMs": 106.067,
      "eventListeners": -127,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "minimap-idle",
      "durationMs": 2055.7770000000346,
      "styleRecalcs": 9,
      "styleRecalcDurationMs": 9.701999999999998,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 587.3159999999999,
      "heapDeltaBytes": 3417524,
      "heapUsedBytes": 57839472,
      "domNodes": -262,
      "jsHeapTotalBytes": 16289792,
      "scriptDurationMs": 103.93699999999998,
      "eventListeners": -127,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "subgraph-dom-widget-clipping",
      "durationMs": 567.1060000000239,
      "styleRecalcs": 48,
      "styleRecalcDurationMs": 11.787,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 367.109,
      "heapDeltaBytes": 6769276,
      "heapUsedBytes": 49777200,
      "domNodes": 22,
      "jsHeapTotalBytes": 13631488,
      "scriptDurationMs": 126.57499999999999,
      "eventListeners": 8,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "subgraph-dom-widget-clipping",
      "durationMs": 589.4669999999564,
      "styleRecalcs": 48,
      "styleRecalcDurationMs": 13.052000000000001,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 368.19199999999995,
      "heapDeltaBytes": 6528564,
      "heapUsedBytes": 49333052,
      "domNodes": 22,
      "jsHeapTotalBytes": 13107200,
      "scriptDurationMs": 124.13,
      "eventListeners": 8,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000273
    },
    {
      "name": "subgraph-dom-widget-clipping",
      "durationMs": 574.9869999999646,
      "styleRecalcs": 48,
      "styleRecalcDurationMs": 12.479999999999999,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 380.818,
      "heapDeltaBytes": 6798080,
      "heapUsedBytes": 49653248,
      "domNodes": 22,
      "jsHeapTotalBytes": 13369344,
      "scriptDurationMs": 133.14999999999998,
      "eventListeners": 8,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000273
    },
    {
      "name": "subgraph-idle",
      "durationMs": 2007.7679999999987,
      "styleRecalcs": 10,
      "styleRecalcDurationMs": 9.440999999999997,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 344.78600000000006,
      "heapDeltaBytes": 19855880,
      "heapUsedBytes": 63030448,
      "domNodes": 20,
      "jsHeapTotalBytes": 22806528,
      "scriptDurationMs": 14.327000000000002,
      "eventListeners": 4,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66999999999998,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "subgraph-idle",
      "durationMs": 1999.621999999988,
      "styleRecalcs": 11,
      "styleRecalcDurationMs": 9.926999999999998,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 343.602,
      "heapDeltaBytes": 19891840,
      "heapUsedBytes": 63151256,
      "domNodes": 22,
      "jsHeapTotalBytes": 22806528,
      "scriptDurationMs": 16.567999999999998,
      "eventListeners": 6,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "subgraph-idle",
      "durationMs": 2022.9960000000347,
      "styleRecalcs": 11,
      "styleRecalcDurationMs": 13.175,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 384.80099999999993,
      "heapDeltaBytes": 19909492,
      "heapUsedBytes": 62797640,
      "domNodes": 22,
      "jsHeapTotalBytes": 22544384,
      "scriptDurationMs": 21.303,
      "eventListeners": 6,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "subgraph-mouse-sweep",
      "durationMs": 1715.0210000000072,
      "styleRecalcs": 76,
      "styleRecalcDurationMs": 36.806,
      "layouts": 16,
      "layoutDurationMs": 4.465999999999999,
      "taskDurationMs": 681.0749999999999,
      "heapDeltaBytes": 11587796,
      "heapUsedBytes": 54763428,
      "domNodes": 62,
      "jsHeapTotalBytes": 23330816,
      "scriptDurationMs": 103.53099999999999,
      "eventListeners": 4,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "subgraph-mouse-sweep",
      "durationMs": 1701.3650000000098,
      "styleRecalcs": 76,
      "styleRecalcDurationMs": 40.949,
      "layouts": 16,
      "layoutDurationMs": 5.395,
      "taskDurationMs": 722.276,
      "heapDeltaBytes": 11897428,
      "heapUsedBytes": 54648232,
      "domNodes": 63,
      "jsHeapTotalBytes": 22544384,
      "scriptDurationMs": 106.534,
      "eventListeners": 4,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "subgraph-mouse-sweep",
      "durationMs": 2028.3409999999549,
      "styleRecalcs": 84,
      "styleRecalcDurationMs": 52.201,
      "layouts": 16,
      "layoutDurationMs": 5.109,
      "taskDurationMs": 954.6730000000001,
      "heapDeltaBytes": 11854160,
      "heapUsedBytes": 55121312,
      "domNodes": 74,
      "jsHeapTotalBytes": 22544384,
      "scriptDurationMs": 108.944,
      "eventListeners": 6,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "viewport-pan-sweep",
      "durationMs": 8201.220999999976,
      "styleRecalcs": 251,
      "styleRecalcDurationMs": 44.379999999999995,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 4049.6800000000003,
      "heapDeltaBytes": 33703608,
      "heapUsedBytes": 84311380,
      "domNodes": -257,
      "jsHeapTotalBytes": 24252416,
      "scriptDurationMs": 1454.283,
      "eventListeners": -107,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "viewport-pan-sweep",
      "durationMs": 8202.46800000001,
      "styleRecalcs": 252,
      "styleRecalcDurationMs": 46.758,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 3791.911,
      "heapDeltaBytes": 25029732,
      "heapUsedBytes": 76084324,
      "domNodes": -254,
      "jsHeapTotalBytes": 19533824,
      "scriptDurationMs": 1294.87,
      "eventListeners": -107,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.670000000000012,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "viewport-pan-sweep",
      "durationMs": 8199.415000000045,
      "styleRecalcs": 252,
      "styleRecalcDurationMs": 47.684000000000005,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 3921.89,
      "heapDeltaBytes": 26028048,
      "heapUsedBytes": 76738840,
      "domNodes": -256,
      "jsHeapTotalBytes": 19533824,
      "scriptDurationMs": 1306.594,
      "eventListeners": -107,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "vue-large-graph-idle",
      "durationMs": 12652.519999999982,
      "styleRecalcs": 0,
      "styleRecalcDurationMs": 0,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 12639.368,
      "heapDeltaBytes": -55665000,
      "heapUsedBytes": 160840804,
      "domNodes": -9848,
      "jsHeapTotalBytes": 19226624,
      "scriptDurationMs": 619.5390000000001,
      "eventListeners": -23961,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 17.776666666666642,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "vue-large-graph-idle",
      "durationMs": 12593.43100000001,
      "styleRecalcs": 0,
      "styleRecalcDurationMs": 0,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 12581.898000000001,
      "heapDeltaBytes": -48661148,
      "heapUsedBytes": 168092508,
      "domNodes": -9848,
      "jsHeapTotalBytes": 27877376,
      "scriptDurationMs": 625.75,
      "eventListeners": -23963,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 17.776666666666763,
      "p95FrameDurationMs": 16.80000000000291
    },
    {
      "name": "vue-large-graph-idle",
      "durationMs": 12582.164000000033,
      "styleRecalcs": 0,
      "styleRecalcDurationMs": 0,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 12570.054999999998,
      "heapDeltaBytes": -47201660,
      "heapUsedBytes": 167879888,
      "domNodes": -9848,
      "jsHeapTotalBytes": 27877376,
      "scriptDurationMs": 628.057,
      "eventListeners": -23959,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 17.220000000000073,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "vue-large-graph-pan",
      "durationMs": 15383.500999999967,
      "styleRecalcs": 73,
      "styleRecalcDurationMs": 14.91300000000001,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 15359.679,
      "heapDeltaBytes": -60727204,
      "heapUsedBytes": 159893504,
      "domNodes": -9848,
      "jsHeapTotalBytes": -11182080,
      "scriptDurationMs": 883.6619999999999,
      "eventListeners": -23981,
      "totalBlockingTimeMs": 2,
      "frameDurationMs": 17.776666666666642,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "vue-large-graph-pan",
      "durationMs": 14518.59799999994,
      "styleRecalcs": 66,
      "styleRecalcDurationMs": 14.27299999999998,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 14490.479000000001,
      "heapDeltaBytes": -60390756,
      "heapUsedBytes": 149646652,
      "domNodes": -9851,
      "jsHeapTotalBytes": -11444224,
      "scriptDurationMs": 877.788,
      "eventListeners": -23985,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 17.776666666666642,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "vue-large-graph-pan",
      "durationMs": 14589.923999999995,
      "styleRecalcs": 65,
      "styleRecalcDurationMs": 14.70699999999997,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 14565.978,
      "heapDeltaBytes": -49557260,
      "heapUsedBytes": 166428228,
      "domNodes": -9879,
      "jsHeapTotalBytes": 26042368,
      "scriptDurationMs": 889.624,
      "eventListeners": -23953,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 18.333333333333332,
      "p95FrameDurationMs": 33.39999999999782
    },
    {
      "name": "workflow-execution",
      "durationMs": 477.19399999999723,
      "styleRecalcs": 22,
      "styleRecalcDurationMs": 33.154999999999994,
      "layouts": 5,
      "layoutDurationMs": 1.6420000000000001,
      "taskDurationMs": 141.022,
      "heapDeltaBytes": 4792812,
      "heapUsedBytes": 49527184,
      "domNodes": 192,
      "jsHeapTotalBytes": 0,
      "scriptDurationMs": 29.088,
      "eventListeners": 71,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.663333333333338,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "workflow-execution",
      "durationMs": 445.81800000003113,
      "styleRecalcs": 17,
      "styleRecalcDurationMs": 23.380000000000003,
      "layouts": 4,
      "layoutDurationMs": 1.087,
      "taskDurationMs": 116.10500000000002,
      "heapDeltaBytes": 4375592,
      "heapUsedBytes": 48733576,
      "domNodes": 156,
      "jsHeapTotalBytes": 0,
      "scriptDurationMs": 24.138,
      "eventListeners": 71,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.799999999999727
    },
    {
      "name": "workflow-execution",
      "durationMs": 447.34699999992245,
      "styleRecalcs": 16,
      "styleRecalcDurationMs": 21.258999999999997,
      "layouts": 5,
      "layoutDurationMs": 1.2730000000000004,
      "taskDurationMs": 120.838,
      "heapDeltaBytes": 4482516,
      "heapUsedBytes": 48534984,
      "domNodes": 156,
      "jsHeapTotalBytes": 262144,
      "scriptDurationMs": 28.549000000000003,
      "eventListeners": 71,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.663333333333338,
      "p95FrameDurationMs": 16.800000000000182
    }
  ]
}

@benceruleanlu
benceruleanlu marked this pull request as ready for review April 20, 2026 19:02
@dosubot dosubot Bot added the size:XL This PR changes 500-999 lines, ignoring generated files. label Apr 20, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e25f3caa63

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +258 to +259
} catch {
return attempt

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Persist pending checkout fallback when storage writes fail

If localStorage.setItem throws (for example in quota-exceeded or restricted-storage browser modes), this branch returns an ephemeral attempt object but does not preserve any recoverable state. The new recovery path in useSubscription is gated on hasPendingSubscriptionCheckoutAttempt() (storage-backed), and this commit also removed the old focus polling fallback from the dialog, so users who complete checkout in those environments can come back without an automatic status re-fetch or subscription_success event until a manual refresh/navigation triggers one. Consider keeping an in-memory fallback and emitting the checkout-changed event even when persistence fails.

Useful? React with 👍 / 👎.

@christian-byrne christian-byrne 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.

Can you backport the dependent PR first and then try to get a clean backport with the second PR? Both can be done by just adding labels to the PRs

Improving our subscription detection system. Optimal will have to come
after BE team brings personal billing to cloud repo off of comfy api.

- replace the dialog-local focus poller with a frontend checkout tracker
stored in `localStorage`
- recover pending subscription checkouts from app boot plus global page
lifecycle (`pageshow`, `visibilitychange`) with bounded retries only
while an attempt is pending
- emit `subscription_success` through GTM with frontend-derived metadata
once subscription state reaches the expected target tier/cycle

This is the frontend-only 80/20 path. It fixes the brittle "old tab must
regain focus" behavior without adding new backend endpoints or backend
event storage. The browser records one pending checkout attempt when
checkout is opened, and any returning cloud tab can recover it later by
comparing current subscription state against the expected target plan.

- browser-scoped, not backend-authoritative
- no server transaction id
- scheduled downgrades through the billing portal are intentionally not
inferred as immediate success events
- still best-effort compared with the backend outbox/WebSocket approach

- `pnpm exec vitest run
src/platform/cloud/subscription/composables/useSubscription.test.ts
src/platform/telemetry/providers/cloud/GtmTelemetryProvider.test.ts`
- `pnpm typecheck`

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-11286-feat-add-frontend-subscription-success-recovery-3436d73d3650814d9f74c89e6926aa84)
by [Unito](https://www.unito.io)
@benceruleanlu
benceruleanlu force-pushed the bl/backport-11286-cloud-1.43 branch from e25f3ca to 5eccc60 Compare April 21, 2026 22:09
@benceruleanlu

Copy link
Copy Markdown
Member Author

I rebased this onto current cloud/1.43 and resolved the remaining conflict in PricingTable.test.ts.

The dependent PR here appears to be the PricingTable test migration from Vue Test Utils to Testing Library, not a runtime dependency of this feature. The original backport conflict was only in that test file because this subscription recovery PR was authored after the test had already been migrated on main, while cloud/1.43 still had the old VTU version when the backport was first opened.

That test migration is now present on cloud/1.43, so the conflict resolution keeps the current Testing Library shape of the test file and applies the subscription recovery test additions in that style.

Validation: pnpm exec vitest run src/platform/cloud/subscription/components/PricingTable.test.ts

@benceruleanlu

Copy link
Copy Markdown
Member Author

Above is Codex, but I am not aware of any dependent PRs, in reference to your comment. I also do not think it's possible to get a clean backport of this PR, as we need test changes and a type to be exported. But if that is true, then this PR is neither the first nor the second PRs you mentioned, which is why I'm confused.

@benceruleanlu
benceruleanlu merged commit b6f439f into cloud/1.43 Apr 21, 2026
33 checks passed
@benceruleanlu
benceruleanlu deleted the bl/backport-11286-cloud-1.43 branch April 21, 2026 22:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport Backporting a PR onto a release candidate size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants