Skip to content

Conversation

@Yourz
Copy link
Collaborator

@Yourz Yourz commented Dec 16, 2025

Summary

Discussion here: https://comfy-organization.slack.com/archives/C0A0XANFJRE/p1764899027465379

Implement: Subscription tier query parameter for direct checkout flow

Example button link: /cloud/subscribe?tier=standard

tier could be standard, creator or pro

Changes

  • What:

    • Add a landing page called CloudSubscriptionRedirectView.vue to handling the subscription tier button link parameter
    • Extract subscription handling logic from PriceTable.vue
  • Breaking:

    • Code change touched PriceTable.vue
  • Dependencies:

Review Focus

  • link will redirect to login url, when cloud app not login
  • after login, the cloud app will redirect to CloudSubscriptionRedirect page
  • wait for several seconds, the cloud app will be redirected to checkout page

Screenshots (if applicable)

Kapture 2025-12-16 at 18 43 28

┆Issue is synchronized with this Notion page by Unito

@Yourz Yourz requested a review from a team as a code owner December 16, 2025 10:43
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Dec 16, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 16, 2025

📝 Walkthrough

Walkthrough

Adds a subscription redirect view and route, centralizes subscription checkout into performSubscriptionCheckout with new BillingCycle/TierKey types, updates PricingTable to use the utility, preserves and safely restores previousFullPath through login/signup redirects with a new safety util and tests, and exposes isInitialized on the subscription composable.

Changes

Cohort / File(s) Change Summary
Onboarding — previous path preservation
src/platform/cloud/onboarding/CloudLoginView.vue, src/platform/cloud/onboarding/CloudSignupView.vue, src/platform/cloud/onboarding/UserCheckView.vue, src/platform/cloud/onboarding/utils/previousFullPath.ts, tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts, src/router.ts
Added getSafePreviousFullPath util; router now encodes a previousFullPath query when redirecting unauthenticated users (except root); login/signup views use globalThis.isSecureContext, await router navigation, and on success replace/redirect to a safe previousFullPath when present; UserCheckView uses globalThis.location.href for final redirect; tests validate decoding and safety rules.
New subscription redirect view & tests
src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue, tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
New CloudSubscriptionRedirectView that reads/validates tier from route.query (string or single-element array), waits for subscription init, opens billing portal if active, or triggers checkout for the selected tier; includes tests for missing/invalid/array inputs, billing portal and checkout flows.
Routes
src/platform/cloud/onboarding/onboardingCloudRoutes.ts
Added path: "subscribe" route named cloud-subscribe (meta.requiresAuth) that loads CloudSubscriptionRedirectView.vue.
Centralized checkout utility & types
src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
New exported types BillingCycle and TierKey and performSubscriptionCheckout(tierKey, currentBillingCycle, openInNewTab = true) which validates cloud env and auth, POSTs to /customers/cloud-subscription-checkout/{checkoutTier}, handles errors/toasts, and opens the returned checkout URL (or billing portal).
PricingTable refactor
src/platform/cloud/subscription/components/PricingTable.vue
Removed local initiateCheckout and inline auth/HTTP logic; now delegates to performSubscriptionCheckout and imports shared TierKey/BillingCycle types; cleaned local types and button logic.
Subscription composable
src/platform/cloud/subscription/composables/useSubscription.ts
Added isInitialized flag, ensures it is set true after subscription fetch or logout, and exposes isInitialized from the composable API.
Miscellaneous
lint-staged.config.mjs, src/locales/en/main.json
Added lint-staged.config.mjs with formatAndEslint helper and handlers for staged files; added localization key cloudOnboarding.skipToCloudApp.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Router
    participant CloudLogin as CloudLoginView
    participant CloudSignup as CloudSignupView
    participant UserCheck as UserCheckView
    participant SubRedirect as CloudSubscriptionRedirectView
    participant Firebase as Firebase Auth
    participant Backend

    User->>Router: Request protected route (e.g., /subscribe)
    alt Not authenticated
        Router->>Router: compute encoded previousFullPath (unless '/')
        Router->>CloudLogin: redirect to cloud-login with query
        User->>CloudLogin: complete login/signup
        CloudLogin->>Firebase: authenticate
        Firebase-->>CloudLogin: auth success
        CloudLogin->>UserCheck: navigate to cloud-user-check (preserve query)
    end

    UserCheck->>UserCheck: extract & decode previousFullPath via getSafePreviousFullPath
    alt decoded internal path valid
        UserCheck->>Router: router.replace(decoded path)
    else
        UserCheck->>SubRedirect: continue onboarding flow / route to subscribe
    end

    SubRedirect->>SubRedirect: extract & validate tier from query
    alt invalid or missing
        SubRedirect->>Router: redirect to '/'
    else valid tier
        SubRedirect->>Firebase: ensure auth / check subscription status
        alt has active subscription
            SubRedirect->>Backend: request billing portal
            Backend-->>SubRedirect: portal_url
            SubRedirect->>User: open billing portal
        else
            SubRedirect->>Backend: POST /customers/cloud-subscription-checkout/{checkoutTier}
            Backend-->>SubRedirect: checkout_url
            SubRedirect->>User: open checkout page (new tab or same)
        end
    end
Loading

Possibly related PRs

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat--subscription-tier-button

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
Copy link

github-actions bot commented Dec 16, 2025

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 12/18/2025, 03:50:55 PM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@github-actions
Copy link

github-actions bot commented Dec 16, 2025

🎭 Playwright Test Results

🕵🏻 No test results found

⏰ Completed at: 12/18/2025, 09:54:10 PM UTC

📊 Test Reports by Browser

  • chromium: Deployment failed
  • chromium-2x: Deployment failed
  • chromium-0.5x: Deployment failed
  • mobile-chrome: Deployment failed

🎉 Click on the links above to view detailed test results for each browser configuration.

@github-actions
Copy link

github-actions bot commented Dec 16, 2025

Bundle Size Report

Summary

  • Raw size: 16.6 MB baseline 16.6 MB — 🔴 +207 B
  • Gzip: 3.37 MB baseline 3.37 MB — 🔴 +15 B
  • Brotli: 2.6 MB baseline 2.6 MB — 🔴 +45 B
  • Bundles: 99 current • 99 baseline • 42 added / 42 removed

Category Glance
App Entry Points 🔴 +237 B (3.21 MB) · Other 🟢 -30 B (3.44 MB) · Vendor & Third-Party ⚪ 0 B (8.46 MB) · Graph Workspace ⚪ 0 B (996 kB) · Panels & Settings ⚪ 0 B (297 kB) · UI Components ⚪ 0 B (184 kB) · + 3 more

Per-category breakdown
App Entry Points — 3.21 MB (baseline 3.21 MB) • 🔴 +237 B

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-BZSFjSaE.js (new) 2.98 MB 🔴 +2.98 MB 🔴 +628 kB 🔴 +478 kB
assets/index-b--AMHCr.js (removed) 2.98 MB 🟢 -2.98 MB 🟢 -628 kB 🟢 -478 kB
assets/index-ChNv8oaQ.js (new) 227 kB 🔴 +227 kB 🔴 +48.5 kB 🔴 +39.8 kB
assets/index-DCl3hdq3.js (removed) 227 kB 🟢 -227 kB 🟢 -48.5 kB 🟢 -39.8 kB
assets/index-Bii6Zfwo.js (new) 345 B 🔴 +345 B 🔴 +244 B 🔴 +203 B
assets/index-BjV_7nX2.js (removed) 345 B 🟢 -345 B 🟢 -245 B 🟢 -233 B

Status: 3 added / 3 removed

Graph Workspace — 996 kB (baseline 996 kB) • ⚪ 0 B

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-BJdJ5-Yc.js (removed) 996 kB 🟢 -996 kB 🟢 -195 kB 🟢 -148 kB
assets/GraphView-DVheCfOb.js (new) 996 kB 🔴 +996 kB 🔴 +195 kB 🔴 +148 kB

Status: 1 added / 1 removed

Views & Navigation — 6.54 kB (baseline 6.54 kB) • ⚪ 0 B

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/UserSelectView-DdWpXSBH.js (new) 6.54 kB 🔴 +6.54 kB 🔴 +2.14 kB 🔴 +1.89 kB
assets/UserSelectView-mU8pzQlj.js (removed) 6.54 kB 🟢 -6.54 kB 🟢 -2.14 kB 🟢 -1.89 kB

Status: 1 added / 1 removed

Panels & Settings — 297 kB (baseline 297 kB) • ⚪ 0 B

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/LegacyCreditsPanel-BVB0mkb8.js (removed) 21.4 kB 🟢 -21.4 kB 🟢 -5.16 kB 🟢 -4.51 kB
assets/LegacyCreditsPanel-CHnDkb1t.js (new) 21.4 kB 🔴 +21.4 kB 🔴 +5.16 kB 🔴 +4.51 kB
assets/KeybindingPanel-BC6uQnhi.js (new) 13.6 kB 🔴 +13.6 kB 🔴 +3.42 kB 🔴 +3.03 kB
assets/KeybindingPanel-ycDa0hWr.js (removed) 13.6 kB 🟢 -13.6 kB 🟢 -3.42 kB 🟢 -3.01 kB
assets/ExtensionPanel-D2VTxrzC.js (new) 10.8 kB 🔴 +10.8 kB 🔴 +2.57 kB 🔴 +2.25 kB
assets/ExtensionPanel-lx8CfTVv.js (removed) 10.8 kB 🟢 -10.8 kB 🟢 -2.57 kB 🟢 -2.24 kB
assets/AboutPanel-Bo_hUjhd.js (removed) 9.16 kB 🟢 -9.16 kB 🟢 -2.46 kB 🟢 -2.21 kB
assets/AboutPanel-CTWPClni.js (new) 9.16 kB 🔴 +9.16 kB 🔴 +2.46 kB 🔴 +2.21 kB
assets/ServerConfigPanel-CWCktX05.js (new) 7.07 kB 🔴 +7.07 kB 🔴 +1.98 kB 🔴 +1.76 kB
assets/ServerConfigPanel-OH9rJM2H.js (removed) 7.07 kB 🟢 -7.07 kB 🟢 -1.98 kB 🟢 -1.76 kB
assets/UserPanel-BEGVBIik.js (removed) 6.23 kB 🟢 -6.23 kB 🟢 -1.72 kB 🟢 -1.5 kB
assets/UserPanel-CuAcSPlu.js (new) 6.23 kB 🔴 +6.23 kB 🔴 +1.72 kB 🔴 +1.5 kB
assets/settings-BhbWhsRg.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BvFz-TmQ.js 33.1 kB 33.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BxYnTA2y.js 21.5 kB 21.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-C6bMjAne.js 27.1 kB 27.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-C7Yhp7H7.js 24 kB 24 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CsnOn8G0.js 25.7 kB 25.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-D5BGNZ7M.js 24.8 kB 24.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-D7k3huHm.js 25 kB 25 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DamkILzl.js 26.4 kB 26.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-s1k0gw1Y.js 20.9 kB 20.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 6 added / 6 removed

UI Components — 184 kB (baseline 184 kB) • ⚪ 0 B

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/Load3D.vue_vue_type_script_setup_true_lang-CFxjE1Kr.js (removed) 53.5 kB 🟢 -53.5 kB 🟢 -8.45 kB 🟢 -7.25 kB
assets/Load3D.vue_vue_type_script_setup_true_lang-TGpEgAA0.js (new) 53.5 kB 🔴 +53.5 kB 🔴 +8.45 kB 🔴 +7.26 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-BOV6Trzn.js (new) 48.8 kB 🔴 +48.8 kB 🔴 +10.5 kB 🔴 +9.14 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-eHRguUEF.js (removed) 48.8 kB 🟢 -48.8 kB 🟢 -10.5 kB 🟢 -9.14 kB
assets/LazyImage.vue_vue_type_script_setup_true_lang-Dl_EcfmH.js (removed) 48.4 kB 🟢 -48.4 kB 🟢 -10.7 kB 🟢 -9.35 kB
assets/LazyImage.vue_vue_type_script_setup_true_lang-oK--YowX.js (new) 48.4 kB 🔴 +48.4 kB 🔴 +10.7 kB 🔴 +9.36 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-Bn3JXBIy.js (new) 14.3 kB 🔴 +14.3 kB 🔴 +3.73 kB 🔴 +3.29 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-BPKbW2_t.js (removed) 14.3 kB 🟢 -14.3 kB 🟢 -3.74 kB 🟢 -3.29 kB
assets/ComfyQueueButton-34EqADz4.js (removed) 8.49 kB 🟢 -8.49 kB 🟢 -2.49 kB 🟢 -2.22 kB
assets/ComfyQueueButton-BT0Vn_n9.js (new) 8.49 kB 🔴 +8.49 kB 🔴 +2.49 kB 🔴 +2.21 kB
assets/WidgetWithControl.vue_vue_type_script_setup_true_lang-CbtLKqU6.js (removed) 3.68 kB 🟢 -3.68 kB 🟢 -1.45 kB 🟢 -1.31 kB
assets/WidgetWithControl.vue_vue_type_script_setup_true_lang-DnbzLouH.js (new) 3.68 kB 🔴 +3.68 kB 🔴 +1.45 kB 🔴 +1.31 kB
assets/WidgetLayoutField.vue_vue_type_script_setup_true_lang-Bm_t-uLF.js (new) 2.14 kB 🔴 +2.14 kB 🔴 +888 B 🔴 +762 B
assets/WidgetLayoutField.vue_vue_type_script_setup_true_lang-Cak4NEmH.js (removed) 2.14 kB 🟢 -2.14 kB 🟢 -889 B 🟢 -769 B
assets/MediaTitle.vue_vue_type_script_setup_true_lang-CmAnCGjg.js (new) 897 B 🔴 +897 B 🔴 +502 B 🔴 +441 B
assets/MediaTitle.vue_vue_type_script_setup_true_lang-D_8ezSS_.js (removed) 897 B 🟢 -897 B 🟢 -502 B 🟢 -437 B
assets/UserAvatar.vue_vue_type_script_setup_true_lang-C6S4PBEs.js 1.34 kB 1.34 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetButton-B5FcXt9_.js 2.04 kB 2.04 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 8 added / 8 removed

Data & Services — 12.5 kB (baseline 12.5 kB) • ⚪ 0 B

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/keybindingService-B3wd8-R9.js (removed) 7.51 kB 🟢 -7.51 kB 🟢 -1.83 kB 🟢 -1.57 kB
assets/keybindingService-VtkGKP-C.js (new) 7.51 kB 🔴 +7.51 kB 🔴 +1.83 kB 🔴 +1.57 kB
assets/audioService-C7ouadPE.js (removed) 2.2 kB 🟢 -2.2 kB 🟢 -961 B 🟢 -819 B
assets/audioService-DpGrxjfI.js (new) 2.2 kB 🔴 +2.2 kB 🔴 +961 B 🔴 +822 B
assets/serverConfigStore-DDOxHQs5.js 2.83 kB 2.83 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 2 added / 2 removed

Utilities & Hooks — 1.86 kB (baseline 1.86 kB) • ⚪ 0 B

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/audioUtils-63S7TjfH.js (removed) 1.41 kB 🟢 -1.41 kB 🟢 -650 B 🟢 -547 B
assets/audioUtils-YTvPekrY.js (new) 1.41 kB 🔴 +1.41 kB 🔴 +652 B 🔴 +543 B
assets/nodeFilterUtil-CXKCRJ-m.js 460 B 460 B ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 1 added / 1 removed

Vendor & Third-Party — 8.46 MB (baseline 8.46 MB) • ⚪ 0 B

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-chart-4Lxb_aRy.js 452 kB 452 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-other-N5ffP4jf.js 3.86 MB 3.86 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-primevue-BAx-x20c.js 1.96 MB 1.96 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-three-C1LfRdh4.js 1.37 MB 1.37 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-tiptap-DMBnJfDx.js 232 kB 232 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vue-DyquAs8-.js 160 kB 160 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-xterm-BF8peZ5_.js 420 kB 420 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Other — 3.44 MB (baseline 3.44 MB) • 🟢 -30 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/SubscriptionRequiredDialogContent-COneFuUv.js (removed) 28.1 kB 🟢 -28.1 kB 🟢 -6.34 kB 🟢 -5.49 kB
assets/SubscriptionRequiredDialogContent-CLqmjtAF.js (new) 28 kB 🔴 +28 kB 🔴 +6.31 kB 🔴 +5.47 kB
assets/WidgetRecordAudio-Cg6rTblT.js (new) 20.4 kB 🔴 +20.4 kB 🔴 +5.23 kB 🔴 +4.64 kB
assets/WidgetRecordAudio-PzGf0u5i.js (removed) 20.4 kB 🟢 -20.4 kB 🟢 -5.23 kB 🟢 -4.63 kB
assets/AudioPreviewPlayer-Djo3WK62.js (removed) 13.4 kB 🟢 -13.4 kB 🟢 -3.37 kB 🟢 -3.01 kB
assets/AudioPreviewPlayer-gWBTBg8_.js (new) 13.4 kB 🔴 +13.4 kB 🔴 +3.37 kB 🔴 +3.01 kB
assets/ValueControlPopover-CmguTNGm.js (new) 5.49 kB 🔴 +5.49 kB 🔴 +1.7 kB 🔴 +1.52 kB
assets/ValueControlPopover-D3jvr0pq.js (removed) 5.49 kB 🟢 -5.49 kB 🟢 -1.7 kB 🟢 -1.51 kB
assets/WidgetGalleria-Dwi1asqU.js (new) 4.1 kB 🔴 +4.1 kB 🔴 +1.44 kB 🔴 +1.3 kB
assets/WidgetGalleria-wSyR-2bj.js (removed) 4.1 kB 🟢 -4.1 kB 🟢 -1.44 kB 🟢 -1.3 kB
assets/WidgetColorPicker-8MirR9I7.js (new) 3.41 kB 🔴 +3.41 kB 🔴 +1.38 kB 🔴 +1.23 kB
assets/WidgetColorPicker-Dy08R4s9.js (removed) 3.41 kB 🟢 -3.41 kB 🟢 -1.38 kB 🟢 -1.23 kB
assets/WidgetTextarea-CPpV1EvI.js (new) 3.08 kB 🔴 +3.08 kB 🔴 +1.21 kB 🔴 +1.08 kB
assets/WidgetTextarea-DqRocTZY.js (removed) 3.08 kB 🟢 -3.08 kB 🟢 -1.21 kB 🟢 -1.09 kB
assets/WidgetMarkdown-CFt5Ymc3.js (new) 3.08 kB 🔴 +3.08 kB 🔴 +1.28 kB 🔴 +1.13 kB
assets/WidgetMarkdown-VaeVaAn9.js (removed) 3.08 kB 🟢 -3.08 kB 🟢 -1.28 kB 🟢 -1.12 kB
assets/WidgetAudioUI-BDbT7cv2.js (removed) 2.94 kB 🟢 -2.94 kB 🟢 -1.19 kB 🟢 -1.07 kB
assets/WidgetAudioUI-DYSLOMqC.js (new) 2.94 kB 🔴 +2.94 kB 🔴 +1.18 kB 🔴 +1.07 kB
assets/WidgetInputText-DHAWeI9l.js (new) 1.99 kB 🔴 +1.99 kB 🔴 +917 B 🔴 +850 B
assets/WidgetInputText-DZ0jJCnh.js (removed) 1.99 kB 🟢 -1.99 kB 🟢 -919 B 🟢 -856 B
assets/WidgetToggleSwitch-8CyejbWd.js (removed) 1.76 kB 🟢 -1.76 kB 🟢 -832 B 🟢 -728 B
assets/WidgetToggleSwitch-B7a2aGFi.js (new) 1.76 kB 🔴 +1.76 kB 🔴 +830 B 🔴 +728 B
assets/MediaImageBottom--4wbty-E.js (removed) 1.55 kB 🟢 -1.55 kB 🟢 -728 B 🟢 -636 B
assets/MediaImageBottom-cgozwrWt.js (new) 1.55 kB 🔴 +1.55 kB 🔴 +733 B 🔴 +642 B
assets/MediaAudioBottom-3s7o0fEQ.js (new) 1.51 kB 🔴 +1.51 kB 🔴 +730 B 🔴 +646 B
assets/MediaAudioBottom-rE3ISBaG.js (removed) 1.51 kB 🟢 -1.51 kB 🟢 -729 B 🟢 -644 B
assets/Media3DBottom-BPQCqoBh.js (removed) 1.5 kB 🟢 -1.5 kB 🟢 -728 B 🟢 -646 B
assets/Media3DBottom-Ysxg5NqB.js (new) 1.5 kB 🔴 +1.5 kB 🔴 +729 B 🔴 +646 B
assets/MediaVideoBottom-CoVrbfvK.js (new) 1.5 kB 🔴 +1.5 kB 🔴 +727 B 🔴 +645 B
assets/MediaVideoBottom-DdHSxq_w.js (removed) 1.5 kB 🟢 -1.5 kB 🟢 -727 B 🟢 -643 B
assets/Media3DTop-BrmRzOJs.js (removed) 1.49 kB 🟢 -1.49 kB 🟢 -762 B 🟢 -653 B
assets/Media3DTop-CAqMXo3r.js (new) 1.49 kB 🔴 +1.49 kB 🔴 +763 B 🔴 +648 B
assets/WidgetSelect-CMWYcT_3.js (removed) 733 B 🟢 -733 B 🟢 -363 B 🟢 -333 B
assets/WidgetSelect-wLg28VOJ.js (new) 733 B 🔴 +733 B 🔴 +360 B 🔴 +318 B
assets/WidgetInputNumber-Dr9NAavN.js (removed) 673 B 🟢 -673 B 🟢 -349 B 🟢 -286 B
assets/WidgetInputNumber-xSzXMyim.js (new) 673 B 🔴 +673 B 🔴 +345 B 🔴 +295 B
assets/Load3D-C2nT41vV.js (new) 424 B 🔴 +424 B 🔴 +267 B 🔴 +222 B
assets/Load3D-T2jvZajj.js (removed) 424 B 🟢 -424 B 🟢 -265 B 🟢 -221 B
assets/WidgetLegacy-Ca1nb6tU.js (removed) 364 B 🟢 -364 B 🟢 -236 B 🟢 -191 B
assets/WidgetLegacy-D3Hd4WZX.js (new) 364 B 🔴 +364 B 🔴 +237 B 🔴 +193 B
assets/commands-BWp4HdfU.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CcfGaui5.js 14.4 kB 14.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CisfgZf5.js 13.7 kB 13.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CkU12Foh.js 13 kB 13 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CoH2DJa6.js 14.2 kB 14.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-COSt-Bjx.js 14.9 kB 14.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DalfIW5f.js 15.9 kB 15.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DfTl0eCm.js 13.5 kB 13.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DwSJL865.js 13.7 kB 13.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-Zxyx15Vd.js 12.8 kB 12.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BDhxs-bB.js 79.9 kB 79.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BtXVDFw6.js 84.7 kB 84.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Buv6RhU4.js 82.4 kB 82.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CgJ6zvJL.js 97.2 kB 97.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CI9qb0E5.js 112 kB 112 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Cu4LqtW0.js 81.6 kB 81.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Cw9RZWRY.js 89 B 89 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Dm19QY4N.js 92.2 kB 92.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Tihe0h_r.js 71.3 kB 71.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-wPWMutMw.js 70.4 kB 70.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaAudioTop-DbG-lp_Y.js 1.46 kB 1.46 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaImageTop-cYYPK99g.js 1.75 kB 1.75 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaVideoTop-D2Oavg0V.js 2.65 kB 2.65 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-1Vh3MCrN.js 240 kB 240 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-aW9En70v.js 260 kB 260 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BIckSVgU.js 273 kB 273 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BiYpVi7D.js 263 kB 263 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Bw_Jitw_.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CCEXtYfM.js 243 kB 243 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CvmVDWYd.js 323 kB 323 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-D_wreoPJ.js 267 kB 267 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Dz-0ZIBN.js 297 kB 297 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-VZsNmhG7.js 264 kB 264 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetChart-54cAzoul.js 2.48 kB 2.48 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetImageCompare-bTic3jrs.js 2.21 kB 2.21 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetPropFilter-BIbGSUAt.js 1.28 kB 1.28 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 20 added / 20 removed

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 8

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5d1bf6d and 92998fa.

📒 Files selected for processing (8)
  • src/platform/cloud/onboarding/CloudLoginView.vue (1 hunks)
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue (1 hunks)
  • src/platform/cloud/onboarding/UserCheckView.vue (3 hunks)
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts (1 hunks)
  • src/platform/cloud/subscription/components/PricingTable.vue (2 hunks)
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts (1 hunks)
  • src/router.ts (2 hunks)
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (12)
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/router.ts
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Minimize the surface area (exported values) of each module and composable

Files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/router.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/router.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/router.ts
**/*.{ts,tsx,js,jsx,vue,json}

📄 CodeRabbit inference engine (AGENTS.md)

Code style: Use 2-space indentation, single quotes, no trailing semicolons, and 80-character line width (see .prettierrc)

Files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/router.ts
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Imports must be sorted and grouped by plugin; run pnpm format before committing
Use TypeScript for type safety; never use any type - use proper TypeScript types
Never use as any type assertions; fix the underlying type issue instead
Use es-toolkit for utility functions
Write code that is expressive and self-documenting; avoid comments unless absolutely necessary; do not add or retain redundant comments
Keep functions short and functional
Minimize nesting in code (e.g., deeply nested if or for statements); apply the Arrow Anti-Pattern principle
Avoid mutable state; prefer immutability and assignment at point of declaration
Favor pure functions, especially testable ones

Files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/router.ts
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/platform/cloud/subscription/components/PricingTable.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/platform/cloud/subscription/components/PricingTable.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3 SFCs (Single File Components) with Composition API only; do not use Options API
Vue components must use <script setup lang="ts"> for component logic
Use Vue 3.5 TypeScript style for default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer useModel to separately defining a prop and emit
Use Tailwind 4 utility classes for styling; avoid using <style> blocks in Vue components
Use semantic Tailwind values from style.css theme instead of the dark: variant; for example, use bg-node-component-surface instead of dark: prefixes
Always use cn() utility from @/utils/tailwindUtil to merge Tailwind class names; do not use :class="[]" syntax
Use ref for reactive state in Vue Composition API components
Implement computed properties with computed() from Vue; avoid using a ref with a watch if a computed would work instead
Use watch and watchEffect for side effects in Vue components
Implement lifecycle hooks using onMounted, onUpdated, and other Vue lifecycle functions
Use provide/inject for dependency injection; do not use dependency injection if a Store or shared composable would be simpler
Do not import Vue macros unnecessarily; only use when needed
Be judicious with addition of new refs or other state: prefer props, avoid redundant computed, and prefer computed over watch
Use VueUse functions for performance-enhancing styles
In Vue Components, implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Implement proper error handling in Vue components
Follow Vue 3 style guide and naming conventions
Use vue-i18n in composition API for any string literals; place new translation entries in src/locales/en/main.json
Avoid new usage of PrimeVue components; prefer shadcn/vue or Reka UI instead

Files:

  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
tests-ui/**/*.test.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (tests-ui/CLAUDE.md)

tests-ui/**/*.test.{js,ts,jsx,tsx}: Write tests for new features
Follow existing test patterns in the codebase
Use existing test utilities rather than writing custom utilities
Mock external dependencies in tests
Always prefer vitest mock functions over writing verbose manual mocks

Files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.ts: Write tests for all changes, especially bug fixes to catch future regressions
Unit/component test files must be named **/*.test.ts or in tests-ui/ directory
Do not write change detector tests that just assert default values
Do not write tests dependent on non-behavioral features like utility classes or styles
Be parsimonious in testing; do not write redundant tests; see composable tests approach
Follow 'Don't Mock What You Don't Own' principle - avoid mocking external dependencies
Do not write tests that just test the mocks; ensure tests fail when code behaves unexpectedly
Leverage Vitest's mocking utilities where possible for test mocking
Keep module mocks contained in test files; do not use global mutable state within test files; use vi.hoisted() if necessary
For Component testing, use Vue Test Utils and follow advice about making components easy to test
Aim for behavioral coverage of critical and new features in unit tests

Files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
🧠 Learnings (29)
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/UserCheckView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use Teleport/Suspense when needed for component rendering

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/UserCheckView.vue
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Use Suspense for async components

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/router.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/router.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/router.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks

Applied to files:

  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Use Vue 3 SFCs (Single File Components) with Composition API only; do not use Options API

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Write tests for new features

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : For Component testing, use Vue Test Utils and follow advice about making components easy to test

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Keep module mocks contained in test files; do not use global mutable state within test files; use `vi.hoisted()` if necessary

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Leverage Vitest's mocking utilities where possible for test mocking

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Mock external dependencies in tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Follow existing test patterns in the codebase

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Mocks should be cleanly written and easy to understand, with reusable mocks where possible

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Always prefer vitest mock functions over writing verbose manual mocks

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-10T03:09:13.807Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:13.807Z
Learning: In test files, prefer selecting or asserting on accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests validate actual user-facing behavior and accessibility, reducing reliance on implementation details like test IDs.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Be judicious with addition of new refs or other state: prefer props, avoid redundant `computed`, and prefer `computed` over `watch`

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Steps component with Stepper without panels

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Implement proper error handling in Vue components

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InlineMessage component with Message

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing styles

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitch

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Sidebar component with Drawer

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
🧬 Code graph analysis (1)
src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts (2)
src/stores/firebaseAuthStore.ts (2)
  • useFirebaseAuthStore (53-473)
  • FirebaseAuthStoreError (46-51)
src/config/comfyApi.ts (1)
  • getComfyApiBaseUrl (21-31)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: deploy-and-comment
  • GitHub Check: test
  • GitHub Check: setup
  • GitHub Check: lint-and-format
  • GitHub Check: collect
🔇 Additional comments (9)
src/platform/cloud/onboarding/CloudLoginView.vue (1)

108-108: LGTM!

Preserving route query parameters when navigating to cloud-user-check ensures the subscription flow and previousFullPath redirect logic work correctly after login.

src/platform/cloud/onboarding/onboardingCloudRoutes.ts (1)

68-75: LGTM!

The new subscription-redirect route follows the existing patterns, uses lazy loading, and correctly requires authentication via meta.requiresAuth.

src/router.ts (2)

152-162: LGTM!

The previousFullPath query parameter preservation is well-implemented. Encoding with encodeURIComponent ensures URL-safety, and excluding the root path prevents unnecessary query pollution for standard navigation.


175-178: Consistent query preservation for web login redirects.

Reusing the same query object ensures consistent behavior across both authentication redirect paths.

src/platform/cloud/onboarding/UserCheckView.vue (1)

44-47: LGTM!

Standard handling for vue-router query parameters that can be either string or array.

src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue (1)

66-88: LGTM!

The template follows project guidelines: semantic Tailwind classes (bg-comfy-menu-secondary-bg), proper i18n integration, and accessible alt text for the logo.

src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts (2)

49-69: Error handling is thorough.

The nested try-catch pattern handles multiple failure modes (network error reading text, JSON parse failure, missing message field) with appropriate fallbacks. This defensive approach aligns with existing patterns in firebaseAuthStore.ts.


82-88: LGTM!

The URL handling correctly supports both new-tab (window.open) and same-tab (globalThis.location.href) scenarios. Using globalThis for the redirect is a good choice for broader environment compatibility.

src/platform/cloud/subscription/components/PricingTable.vue (1)

285-285: The call to performSubscriptionCheckout(tierKey) at line 285 is correct. The function signature specifies openInNewTab: boolean = true, making the parameter optional with an appropriate default. Using the default behavior (opening checkout in a new tab) is the intended design for the pricing table context, as evidenced by the alternative call in CloudSubscriptionRedirectView.vue which explicitly passes false to redirect the current page instead.

Comment on lines 64 to 77
if (previousFullPath.value) {
try {
const decodedPath = decodeURIComponent(previousFullPath.value)
// Only allow relative paths (internal redirects)
if (decodedPath.startsWith('/') && !decodedPath.startsWith('//')) {
router.replace(decodedPath)
return
}
// If invalid, fall through to normal onboarding flow
} catch (error) {
// Malformed URI, fall through to normal onboarding flow
console.warn('Invalid previousFullPath parameter:', error)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Read the UserCheckView.vue file
cat -n src/platform/cloud/onboarding/UserCheckView.vue | head -80

# Search for other redirect/URL validation patterns
rg -n 'router\.(replace|push)' --type=vue --type=ts -B2 -A2 | head -50

# Search for any URL validation utilities
fd -e ts -e js | xargs grep -l 'startsWith.*\/\/' 2>/dev/null | head -10

# Check if there are any URL validation utilities in utils directory
find src -name '*url*' -o -name '*route*' -o -name '*redirect*' | grep -E '\.(ts|js)$'

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 3508


Security validation for internal redirects is correct and prevents protocol-relative attacks.

The check at line 68 correctly prevents //evil.com style attacks, and error handling properly falls through on decode failures. However, note that decodeURIComponent() at line 66 is redundant since Vue Router 4 already decodes query parameters—consider removing this call and directly using the previousFullPath value.

🤖 Prompt for AI Agents
In src/platform/cloud/onboarding/UserCheckView.vue around lines 64 to 77, the
call to decodeURIComponent on previousFullPath.value is redundant because Vue
Router already decodes query params; remove the decodeURIComponent call and use
previousFullPath.value directly in the validation, keep the existing checks to
ensure it starts with '/' and not with '//' and remove or simplify the try/catch
used solely for decode errors so malformed-URI handling is not needed while
preserving the security validation and the fallback to the normal onboarding
flow.

Comment on lines 28 to 35
export async function performSubscriptionCheckout(
tierKey: TierKey,
openInNewTab: boolean = true
): Promise<void> {
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if there are existing or planned tests for subscriptionCheckoutUtil

echo "=== Search for test files referencing subscriptionCheckoutUtil ==="
rg -l 'subscriptionCheckoutUtil|performSubscriptionCheckout' --type=ts -g '*.test.ts' -g '*.spec.ts' 2>/dev/null || echo "No test files found with these references"

echo ""
echo "=== Check for any test file in the same directory ==="
fd -type f -path '*subscription*' -name '*.test.ts' -o -name '*.spec.ts'

echo ""
echo "=== Check if CloudSubscriptionRedirectView tests exist ==="
fd -type f -name '*CloudSubscriptionRedirectView*' | head -20

echo ""
echo "=== Search for mocking of performSubscriptionCheckout ==="
rg 'mock.*performSubscriptionCheckout|performSubscriptionCheckout.*mock' --type=ts 2>/dev/null || echo "No mocking found"

echo ""
echo "=== Search for any vitest/jest mock setup of this function ==="
rg 'vi\.mock.*subscriptionCheckoutUtil|jest\.mock.*subscriptionCheckoutUtil' --type=ts 2>/dev/null || echo "No mocks found"

echo ""
echo "=== List all test files in tests-ui directory ==="
fd -type f -name '*.test.ts' -o -name '*.test.js' | head -30

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1029


🏁 Script executed:

#!/bin/bash
# Corrected script to check for tests

echo "=== Search for test files referencing the function ==="
rg 'performSubscriptionCheckout' --type ts -g '*.test.ts' 2>/dev/null | head -20 || echo "No matches in test files"

echo ""
echo "=== Search broadly for all test files ==="
fd '\.test\.ts$' | head -30

echo ""
echo "=== Check tests-ui directory ==="
ls -la tests-ui/ 2>/dev/null | head -20 || echo "tests-ui directory not found"

echo ""
echo "=== Search for CloudSubscriptionRedirectView across all ts/js files ==="
rg 'CloudSubscriptionRedirectView' --type ts --type js 2>/dev/null | head -10 || echo "Not found"

echo ""
echo "=== Check subscription-related test files ==="
fd 'subscription' | grep -E '\.(test|spec)\.(ts|js)$'

echo ""
echo "=== Get overall structure of tests ==="
find . -maxdepth 2 -type d -name 'test*' -o -name '__test*' -o -name 'spec*' 2>/dev/null | head -20

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 3927


🏁 Script executed:

#!/bin/bash
# Check the CloudSubscriptionRedirectView test file for mocks

echo "=== Content of CloudSubscriptionRedirectView.test.ts ==="
cat tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts

echo ""
echo "=== Search for performSubscriptionCheckout in all subscription test files ==="
rg 'performSubscriptionCheckout' tests-ui/tests/platform/cloud/subscription/ 2>/dev/null || echo "Not found in subscription tests"

echo ""
echo "=== Check if subscriptionCheckoutUtil is imported in test files ==="
rg 'subscriptionCheckoutUtil' tests-ui/tests/ 2>/dev/null || echo "Not found"

echo ""
echo "=== Check if there's a test file in the utils directory ==="
find tests-ui/tests/platform/cloud/subscription -name '*util*' -o -name '*checkout*'

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 2991


🏁 Script executed:

#!/bin/bash
# Check the subscriptionCheckoutUtil file to understand what it does

echo "=== Content of subscriptionCheckoutUtil.ts ==="
cat src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts

echo ""
echo "=== Search for imports and usages of performSubscriptionCheckout ==="
rg 'performSubscriptionCheckout' src/ --type ts -B 2 -A 2

echo ""
echo "=== Check if this function is called from CloudSubscriptionRedirectView ==="
rg 'performSubscriptionCheckout' src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue 2>/dev/null || echo "Not found in CloudSubscriptionRedirectView"

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 3343


Add dedicated unit tests for the subscription checkout utility.

This utility handles critical checkout logic including authentication validation, HTTP error handling with multiple fallback paths, JSON response parsing, and window navigation—none of which are tested directly. While CloudSubscriptionRedirectView uses this function, its tests do not cover the utility's edge cases. Consider adding tests for: auth failures, HTTP error responses with various formats, JSON parsing failures, and both navigation modes (new tab vs. redirect).

🤖 Prompt for AI Agents
In src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts around
lines 28 to 31, add dedicated unit tests that exercise all edge cases of
performSubscriptionCheckout: write tests that (1) simulate authentication
failure by mocking the auth/token provider to throw or return invalid
credentials and assert the function rejects or handles it as expected, (2) mock
fetch to return HTTP error responses with different payloads (plain text, JSON
with message field, empty body) and assert the error handling/fallback messages,
(3) mock fetch to return malformed JSON to verify JSON parsing failure paths are
handled, and (4) test both navigation modes by stubbing window.open and
window.location.assign (or window.location.href) to ensure new-tab and redirect
behaviors are executed correctly; use spies/mocks to assert calls and expected
side effects. Ensure each test isolates network/auth via dependency injection or
jest.spyOn/global.fetch mock and restores globals after tests.

Comment on lines 41 to 53
const response = await fetch(
`${getComfyApiBaseUrl()}/customers/cloud-subscription-checkout/${tierKey}`,
{
method: 'POST',
headers: { ...authHeader, 'Content-Type': 'application/json' }
}
)
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider removing unnecessary Content-Type header.

The POST request has no body, so the Content-Type: application/json header is unnecessary and could potentially cause issues with some servers that validate content type against body presence.

   const response = await fetch(
     `${getComfyApiBaseUrl()}/customers/cloud-subscription-checkout/${tierKey}`,
     {
       method: 'POST',
-      headers: { ...authHeader, 'Content-Type': 'application/json' }
+      headers: { ...authHeader }
     }
   )
🤖 Prompt for AI Agents
In src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts around
lines 41 to 47, the POST fetch includes a 'Content-Type: application/json'
header despite having no request body; remove that header (only send authHeader)
so the request doesn't advertise a JSON body it doesn't send and avoid potential
server validation issues.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 92998fa and 0df9c60.

📒 Files selected for processing (3)
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue (1 hunks)
  • src/platform/cloud/subscription/components/PricingTable.vue (2 hunks)
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (11)
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3 SFCs (Single File Components) with Composition API only; do not use Options API
Vue components must use <script setup lang="ts"> for component logic
Use Vue 3.5 TypeScript style for default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer useModel to separately defining a prop and emit
Use Tailwind 4 utility classes for styling; avoid using <style> blocks in Vue components
Use semantic Tailwind values from style.css theme instead of the dark: variant; for example, use bg-node-component-surface instead of dark: prefixes
Always use cn() utility from @/utils/tailwindUtil to merge Tailwind class names; do not use :class="[]" syntax
Use ref for reactive state in Vue Composition API components
Implement computed properties with computed() from Vue; avoid using a ref with a watch if a computed would work instead
Use watch and watchEffect for side effects in Vue components
Implement lifecycle hooks using onMounted, onUpdated, and other Vue lifecycle functions
Use provide/inject for dependency injection; do not use dependency injection if a Store or shared composable would be simpler
Do not import Vue macros unnecessarily; only use when needed
Be judicious with addition of new refs or other state: prefer props, avoid redundant computed, and prefer computed over watch
Use VueUse functions for performance-enhancing styles
In Vue Components, implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Implement proper error handling in Vue components
Follow Vue 3 style guide and naming conventions
Use vue-i18n in composition API for any string literals; place new translation entries in src/locales/en/main.json
Avoid new usage of PrimeVue components; prefer shadcn/vue or Reka UI instead

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
**/*.{ts,tsx,js,jsx,vue,json}

📄 CodeRabbit inference engine (AGENTS.md)

Code style: Use 2-space indentation, single quotes, no trailing semicolons, and 80-character line width (see .prettierrc)

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Imports must be sorted and grouped by plugin; run pnpm format before committing
Use TypeScript for type safety; never use any type - use proper TypeScript types
Never use as any type assertions; fix the underlying type issue instead
Use es-toolkit for utility functions
Write code that is expressive and self-documenting; avoid comments unless absolutely necessary; do not add or retain redundant comments
Keep functions short and functional
Minimize nesting in code (e.g., deeply nested if or for statements); apply the Arrow Anti-Pattern principle
Avoid mutable state; prefer immutability and assignment at point of declaration
Favor pure functions, especially testable ones

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/platform/cloud/subscription/components/PricingTable.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/platform/cloud/subscription/components/PricingTable.vue
tests-ui/**/*.test.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (tests-ui/CLAUDE.md)

tests-ui/**/*.test.{js,ts,jsx,tsx}: Write tests for new features
Follow existing test patterns in the codebase
Use existing test utilities rather than writing custom utilities
Mock external dependencies in tests
Always prefer vitest mock functions over writing verbose manual mocks

Files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.ts: Write tests for all changes, especially bug fixes to catch future regressions
Unit/component test files must be named **/*.test.ts or in tests-ui/ directory
Do not write change detector tests that just assert default values
Do not write tests dependent on non-behavioral features like utility classes or styles
Be parsimonious in testing; do not write redundant tests; see composable tests approach
Follow 'Don't Mock What You Don't Own' principle - avoid mocking external dependencies
Do not write tests that just test the mocks; ensure tests fail when code behaves unexpectedly
Leverage Vitest's mocking utilities where possible for test mocking
Keep module mocks contained in test files; do not use global mutable state within test files; use vi.hoisted() if necessary
For Component testing, use Vue Test Utils and follow advice about making components easy to test
Aim for behavioral coverage of critical and new features in unit tests

Files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
🧠 Learnings (30)
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{components,composables}/**/*.{ts,tsx,vue} : Use vue-i18n for ALL user-facing strings by adding them to `src/locales/en/main.json`

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-05T20:35:28.330Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/locales/en/main.json:2257-2272
Timestamp: 2025-12-05T20:35:28.330Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, vue-i18n pluralization uses a two-parameter pattern: `t('key', { count: value })` where the `count` property in the interpolation object automatically triggers plural selection from pipe-separated locale strings (e.g., "no items | 1 item | {count} items"). This is the correct pattern used throughout the codebase, as validated by Playwright tests.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Write tests for new features

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : For Component testing, use Vue Test Utils and follow advice about making components easy to test

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Follow existing test patterns in the codebase

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Leverage Vitest's mocking utilities where possible for test mocking

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Unit/component test files must be named `**/*.test.ts` or in `tests-ui/` directory

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test user workflows in browser tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Mock external dependencies in tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test across multiple viewports

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Aim for behavioral coverage of critical and new features in unit tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Mocks should be cleanly written and easy to understand, with reusable mocks where possible

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Always prefer vitest mock functions over writing verbose manual mocks

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.{ts,tsx,vue} : Never use `as any` type assertions; fix the underlying type issue instead

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Keep module mocks contained in test files; do not use global mutable state within test files; use `vi.hoisted()` if necessary

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.{ts,tsx,vue} : Favor pure functions, especially testable ones

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Be parsimonious in testing; do not write redundant tests; see composable tests approach

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Follow 'Don't Mock What You Don't Own' principle - avoid mocking external dependencies

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Check tests-ui/README.md for test guidelines

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Do not write tests that just test the mocks; ensure tests fail when code behaves unexpectedly

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-10T03:09:13.807Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:13.807Z
Learning: In test files, prefer selecting or asserting on accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests validate actual user-facing behavior and accessibility, reducing reliance on implementation details like test IDs.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: lint-and-format
  • GitHub Check: test
  • GitHub Check: setup
  • GitHub Check: collect
🔇 Additional comments (4)
tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts (1)

91-147: LGTM - Comprehensive test coverage for the redirect component.

The test suite properly covers all key scenarios: missing/invalid subscription types redirecting home, valid types triggering checkout, active subscriptions opening billing portal, and array query parameter handling. Good use of vi.hoisted() for mock setup and proper async handling with flushPromises.

src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue (1)

69-91: Template implementation looks good.

The template is clean with proper i18n integration, accessible alt text for the logo, and conditional rendering. Uses Tailwind classes appropriately per guidelines.

src/platform/cloud/subscription/components/PricingTable.vue (2)

175-176: Good refactor: imports TierKey from the centralized utility.

This addresses the previous review feedback to avoid type duplication. The type import is properly separated with import type.


275-291: Clean delegation to centralized checkout utility.

The handleSubscribe function properly delegates to performSubscriptionCheckout while maintaining local loading state management and the existing billing portal flow for active subscriptions. Error handling remains intact via wrapWithErrorHandlingAsync.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0df9c60 and 4e7c0ce.

📒 Files selected for processing (3)
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue (1 hunks)
  • src/platform/cloud/subscription/composables/useSubscription.ts (3 hunks)
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (13)
tests-ui/**/*.test.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (tests-ui/CLAUDE.md)

tests-ui/**/*.test.{js,ts,jsx,tsx}: Write tests for new features
Follow existing test patterns in the codebase
Use existing test utilities rather than writing custom utilities
Mock external dependencies in tests
Always prefer vitest mock functions over writing verbose manual mocks

Files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
**/*.{ts,tsx,js,jsx,vue,json}

📄 CodeRabbit inference engine (AGENTS.md)

Code style: Use 2-space indentation, single quotes, no trailing semicolons, and 80-character line width (see .prettierrc)

Files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Imports must be sorted and grouped by plugin; run pnpm format before committing
Use TypeScript for type safety; never use any type - use proper TypeScript types
Never use as any type assertions; fix the underlying type issue instead
Use es-toolkit for utility functions
Write code that is expressive and self-documenting; avoid comments unless absolutely necessary; do not add or retain redundant comments
Keep functions short and functional
Minimize nesting in code (e.g., deeply nested if or for statements); apply the Arrow Anti-Pattern principle
Avoid mutable state; prefer immutability and assignment at point of declaration
Favor pure functions, especially testable ones

Files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.ts: Write tests for all changes, especially bug fixes to catch future regressions
Unit/component test files must be named **/*.test.ts or in tests-ui/ directory
Do not write change detector tests that just assert default values
Do not write tests dependent on non-behavioral features like utility classes or styles
Be parsimonious in testing; do not write redundant tests; see composable tests approach
Follow 'Don't Mock What You Don't Own' principle - avoid mocking external dependencies
Do not write tests that just test the mocks; ensure tests fail when code behaves unexpectedly
Leverage Vitest's mocking utilities where possible for test mocking
Keep module mocks contained in test files; do not use global mutable state within test files; use vi.hoisted() if necessary
For Component testing, use Vue Test Utils and follow advice about making components easy to test
Aim for behavioral coverage of critical and new features in unit tests

Files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Minimize the surface area (exported values) of each module and composable

Files:

  • src/platform/cloud/subscription/composables/useSubscription.ts
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/{services,composables}/**/*.{ts,tsx}: Use api.apiURL() for backend endpoints instead of constructing URLs directly
Use api.fileURL() for static file access instead of constructing URLs directly

Files:

  • src/platform/cloud/subscription/composables/useSubscription.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/platform/cloud/subscription/composables/useSubscription.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/platform/cloud/subscription/composables/useSubscription.ts
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3 SFCs (Single File Components) with Composition API only; do not use Options API
Vue components must use <script setup lang="ts"> for component logic
Use Vue 3.5 TypeScript style for default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer useModel to separately defining a prop and emit
Use Tailwind 4 utility classes for styling; avoid using <style> blocks in Vue components
Use semantic Tailwind values from style.css theme instead of the dark: variant; for example, use bg-node-component-surface instead of dark: prefixes
Always use cn() utility from @/utils/tailwindUtil to merge Tailwind class names; do not use :class="[]" syntax
Use ref for reactive state in Vue Composition API components
Implement computed properties with computed() from Vue; avoid using a ref with a watch if a computed would work instead
Use watch and watchEffect for side effects in Vue components
Implement lifecycle hooks using onMounted, onUpdated, and other Vue lifecycle functions
Use provide/inject for dependency injection; do not use dependency injection if a Store or shared composable would be simpler
Do not import Vue macros unnecessarily; only use when needed
Be judicious with addition of new refs or other state: prefer props, avoid redundant computed, and prefer computed over watch
Use VueUse functions for performance-enhancing styles
In Vue Components, implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Implement proper error handling in Vue components
Follow Vue 3 style guide and naming conventions
Use vue-i18n in composition API for any string literals; place new translation entries in src/locales/en/main.json
Avoid new usage of PrimeVue components; prefer shadcn/vue or Reka UI instead

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
🧠 Learnings (28)
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Write tests for new features

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : For Component testing, use Vue Test Utils and follow advice about making components easy to test

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Follow existing test patterns in the codebase

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Leverage Vitest's mocking utilities where possible for test mocking

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Unit/component test files must be named `**/*.test.ts` or in `tests-ui/` directory

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test user workflows in browser tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Mock external dependencies in tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test across multiple viewports

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Keep module mocks contained in test files; do not use global mutable state within test files; use `vi.hoisted()` if necessary

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Mocks should be cleanly written and easy to understand, with reusable mocks where possible

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Always prefer vitest mock functions over writing verbose manual mocks

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.{ts,tsx,vue} : Never use `as any` type assertions; fix the underlying type issue instead

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.{ts,tsx,vue} : Favor pure functions, especially testable ones

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Be parsimonious in testing; do not write redundant tests; see composable tests approach

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Aim for behavioral coverage of critical and new features in unit tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Check tests-ui/README.md for test guidelines

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
📚 Learning: 2025-12-10T03:09:13.807Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:13.807Z
Learning: In test files, prefer selecting or asserting on accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests validate actual user-facing behavior and accessibility, reducing reliance on implementation details like test IDs.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{components,composables}/**/*.{ts,tsx,vue} : Use vue-i18n for ALL user-facing strings by adding them to `src/locales/en/main.json`

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-05T20:35:28.330Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/locales/en/main.json:2257-2272
Timestamp: 2025-12-05T20:35:28.330Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, vue-i18n pluralization uses a two-parameter pattern: `t('key', { count: value })` where the `count` property in the interpolation object automatically triggers plural selection from pipe-separated locale strings (e.g., "no items | 1 item | {count} items"). This is the correct pattern used throughout the codebase, as validated by Playwright tests.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: deploy-and-comment
  • GitHub Check: collect
  • GitHub Check: lint-and-format
  • GitHub Check: setup
  • GitHub Check: test
🔇 Additional comments (3)
src/platform/cloud/subscription/composables/useSubscription.ts (1)

39-39: LGTM! Initialization flag properly guards subscription state.

The isInitialized flag correctly tracks subscription status initialization across all code paths. The try/finally block ensures the flag is set to true even when fetchSubscriptionStatus fails, preventing components from waiting indefinitely. The immediate: true watcher guarantees initialization runs on composable setup.

Also applies to: 197-201, 205-205, 246-246

tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts (1)

1-150: LGTM! Comprehensive test coverage with clean mocking.

The test suite effectively covers the subscription redirect flow:

  • Validates handling of missing, invalid, and valid query parameters
  • Verifies active subscription branches to billing portal instead of checkout
  • Tests array-type query parameter extraction
  • Mocking patterns follow Vitest best practices with vi.hoisted() and proper cleanup
src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue (1)

33-96: LGTM! Robust redirect flow with proper initialization handling.

The component correctly:

  • Extracts and validates subscriptionType from query parameters (handles both string and array)
  • Awaits subscription initialization with until(isInitialized).toBe(true) to prevent race conditions
  • Branches appropriately between billing portal (active subscription) and checkout flow
  • Wraps async logic with error handling
  • Uses i18n for all user-facing strings

Comment on lines +23 to +33
const getTierDisplayName = (tierKey: TierKey | null): string => {
if (!tierKey) return ''
const names: Record<TierKey, string> = {
standard: t('subscription.tiers.standard.name'),
creator: t('subscription.tiers.creator.name'),
pro: t('subscription.tiers.pro.name')
}
return names[tierKey]
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider using a computed property for tier display name.

While getTierDisplayName correctly achieves reactivity by calling t() inline, it creates a new names object on every invocation. Refactoring to a computed property would cache the result and follow Vue's idiomatic pattern for derived state.

Apply this diff to use a computed property:

-const selectedTierKey = ref<TierKey | null>(null)
-
-const getTierDisplayName = (tierKey: TierKey | null): string => {
-  if (!tierKey) return ''
-  const names: Record<TierKey, string> = {
-    standard: t('subscription.tiers.standard.name'),
-    creator: t('subscription.tiers.creator.name'),
-    pro: t('subscription.tiers.pro.name')
-  }
-  return names[tierKey]
-}
+const selectedTierKey = ref<TierKey | null>(null)
+
+const tierDisplayName = computed(() => {
+  if (!selectedTierKey.value) return ''
+  const names: Record<TierKey, string> = {
+    standard: t('subscription.tiers.standard.name'),
+    creator: t('subscription.tiers.creator.name'),
+    pro: t('subscription.tiers.pro.name')
+  }
+  return names[selectedTierKey.value]
+})

Update the template to use the computed property:

       <p
         v-if="selectedTierKey"
         class="font-inter text-base font-normal leading-normal text-base-foreground"
       >
         {{
           t('subscription.subscribeTo', {
-            plan: getTierDisplayName(selectedTierKey)
+            plan: tierDisplayName
           })
         }}
       </p>
🤖 Prompt for AI Agents
In src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue around lines
23 to 31, replace the getTierDisplayName function (which recreates the names
object on every call) with a Vue computed property that depends on the current
tierKey and returns the translated display name; import computed from 'vue',
create a computed like tierDisplayName that returns '' when tierKey is null and
otherwise returns the appropriate t(...) value (you can build the small mapping
once inside the computed or use a switch), remove the getTierDisplayName
function, and update the template to use tierDisplayName instead of calling
getTierDisplayName.

@Yourz Yourz enabled auto-merge (squash) December 16, 2025 15:28
@Yourz Yourz force-pushed the feat--subscription-tier-button branch from 4e7c0ce to 127ade7 Compare December 18, 2025 11:57
@Yourz Yourz requested review from a team, KarryCharon, Yorha4D and shinshin86 as code owners December 18, 2025 11:57
@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:L This PR changes 100-499 lines, ignoring generated files. labels Dec 18, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts (1)

1-87: Overall structure is sound, but past review comments remain unaddressed.

The checkout utility provides a clean abstraction for subscription checkout logic. However, two previously raised concerns from past reviews have not been addressed:

  1. Missing unit tests (lines 31-35): The function handles critical flows including authentication, HTTP errors with multiple fallback paths, JSON parsing failures, and navigation—none of which are directly tested.

  2. Unnecessary Content-Type header (line 51): The POST request includes 'Content-Type': application/json' despite having no request body.

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4e7c0ce and 127ade7.

📒 Files selected for processing (14)
  • lint-staged.config.mjs (1 hunks)
  • src/locales/en/main.json (1 hunks)
  • src/platform/cloud/onboarding/CloudLoginView.vue (2 hunks)
  • src/platform/cloud/onboarding/CloudSignupView.vue (3 hunks)
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue (1 hunks)
  • src/platform/cloud/onboarding/UserCheckView.vue (1 hunks)
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts (1 hunks)
  • src/platform/cloud/onboarding/utils/previousFullPath.ts (1 hunks)
  • src/platform/cloud/subscription/components/PricingTable.vue (3 hunks)
  • src/platform/cloud/subscription/composables/useSubscription.ts (3 hunks)
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts (1 hunks)
  • src/router.ts (2 hunks)
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts (1 hunks)
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (13)
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

src/**/*.{vue,ts}: Avoid using ref and watch together - use computed instead if possible
Do not add ref if a prop would suffice; do not add computed if the ref/prop directly would work; use watch only when computed won't accomplish the goal
Leverage VueUse functions for performance-enhancing styles

Files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

src/**/*.ts: Extract complex type definitions that are inlined in multiple related places - name them for reuse
Minimize the surface area (exported values) of each module and composable
Favor pure functions, especially testable ones

Files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

src/**/*.{ts,tsx,vue}: ESLint rules: Vue + TS rules, no floating promises, unused imports disallowed, i18n raw text restrictions in templates
Use es-toolkit for utility functions
Avoid mutable state - prefer immutability and assignment at point of declaration
Never use any type - use proper TypeScript types
Never use as any type assertions - fix the underlying type issue

Files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
src/**/*.{js,ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript exclusively - no new JavaScript files

Files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
src/**/*.{ts,tsx,vue,js}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,tsx,vue,js}: Indent with 2 spaces, use single quotes, no trailing semicolons, line width 80 - see .prettierrc
Sort and group imports by plugin, run pnpm format before committing

Files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Do not use function expressions - use function declarations instead when possible

Files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/{services,composables}/**/*.{ts,tsx}: Use api.apiURL() for backend endpoints instead of constructing URLs directly
Use api.fileURL() for static file access instead of constructing URLs directly

Files:

  • src/platform/cloud/subscription/composables/useSubscription.ts
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

src/**/*.vue: Vue 3 SFCs must use Composition API only - no Options API
Use <script setup lang="ts"> for component logic
Use Tailwind 4 utility classes for styling - avoid <style> blocks
Use cn() utility from @/utils/tailwindUtil to merge Tailwind class names - never use :class="[]" syntax
Never use the dark: Tailwind variant - use semantic values from style.css theme instead (e.g., bg-node-component-surface)
Use Vue 3.5+ TypeScript style default prop declaration with reactive destructuring - prefer useModel to prop/emit pairs, do not use withDefaults
Do not import Vue macros unnecessarily
Use vue-i18n in composition API for string literals - place translation entries in src/locales/en/main.json
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Avoid new usage of PrimeVue components

Files:

  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
tests-ui/**/*.test.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (tests-ui/CLAUDE.md)

tests-ui/**/*.test.{js,ts,jsx,tsx}: Write tests for new features
Follow existing test patterns in the codebase
Use existing test utilities rather than writing custom utilities
Mock external dependencies in tests
Always prefer vitest mock functions over writing verbose manual mocks

Files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
tests-ui/**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

tests-ui/**/*.test.ts: Write tests for all changes, especially bug fixes to catch future regressions
Unit/Component test files must use pattern **/*.test.ts
Do not write change detector tests - do not just assert that defaults are certain values
Do not write tests dependent on non-behavioral features like utility classes or styles
Be parsimonious in testing - do not write redundant tests
Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly
For mocking, leverage Vitest's utilities where possible
Keep module mocks contained - do not use global mutable state within test files, use vi.hoisted() if necessary
For Component testing, use Vue Test Utils and follow advice about making components easy to test
Aim for behavioral coverage of critical and new features

Files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
🧠 Learnings (52)
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-12-09T04:35:43.971Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/locales/en/main.json:774-780
Timestamp: 2025-12-09T04:35:43.971Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, locale files other than `src/locales/en/main.json` are generated automatically on every release. Developers only need to add English (en) key/values in `src/locales/en/main.json` when making PRs; manual updates to other locale files (fr, ja, ko, ru, zh, zh-TW, es, ar, tr, etc.) are not required and should not be suggested in reviews.

Applied to files:

  • src/locales/en/main.json
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks

Applied to files:

  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use Teleport/Suspense when needed for component rendering

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.vue : Use Suspense for async components

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.{ts,tsx,vue,js} : Sort and group imports by plugin, run `pnpm format` before committing

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : Run ESLint instead of manually figuring out whitespace fixes or other trivial style concerns using the `pnpm lint:fix` command

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.{ts,tsx,vue} : ESLint rules: Vue + TS rules, no floating promises, unused imports disallowed, i18n raw text restrictions in templates

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.{ts,tsx,vue,js} : Indent with 2 spaces, use single quotes, no trailing semicolons, line width 80 - see `.prettierrc`

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.{js,ts,tsx,vue} : Use TypeScript exclusively - no new JavaScript files

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Use es-toolkit for utility functions

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-16T17:41:58.464Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T17:41:58.464Z
Learning: Run tests, typecheck, lint, and format checks during development workflow

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Unit/Component test files must use pattern `**/*.test.ts`

Applied to files:

  • lint-staged.config.mjs
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `vitest` for unit testing in this project

Applied to files:

  • lint-staged.config.mjs
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Quality gates must pass: `pnpm lint`, `pnpm typecheck`, `pnpm knip`, and relevant tests

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).

Applied to files:

  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.

Applied to files:

  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{components,composables}/**/*.{ts,tsx,vue} : Use vue-i18n for ALL user-facing strings by adding them to `src/locales/en/main.json`

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-05T20:35:28.330Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/locales/en/main.json:2257-2272
Timestamp: 2025-12-05T20:35:28.330Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, vue-i18n pluralization uses a two-parameter pattern: `t('key', { count: value })` where the `count` property in the interpolation object automatically triggers plural selection from pipe-separated locale strings (e.g., "no items | 1 item | {count} items"). This is the correct pattern used throughout the codebase, as validated by Playwright tests.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.{vue,ts} : Do not add `ref` if a prop would suffice; do not add `computed` if the ref/prop directly would work; use `watch` only when `computed` won't accomplish the goal

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.{vue,ts} : Avoid using `ref` and `watch` together - use `computed` instead if possible

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Implement computed properties with computed()

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Write tests for new features

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : For Component testing, use Vue Test Utils and follow advice about making components easy to test

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Aim for behavioral coverage of critical and new features

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : For mocking, leverage Vitest's utilities where possible

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Follow existing test patterns in the codebase

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Keep module mocks contained - do not use global mutable state within test files, use `vi.hoisted()` if necessary

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Be parsimonious in testing - do not write redundant tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test user workflows in browser tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Mocks should be cleanly written and easy to understand, with reusable mocks where possible

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Always prefer vitest mock functions over writing verbose manual mocks

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Never use `as any` type assertions - fix the underlying type issue

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Do not write change detector tests - do not just assert that defaults are certain values

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Check tests-ui/README.md for test guidelines

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test across multiple viewports

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Mock external dependencies in tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
📚 Learning: 2025-12-10T03:09:13.807Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:13.807Z
Learning: In test files, prefer selecting or asserting on accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests validate actual user-facing behavior and accessibility, reducing reliance on implementation details like test IDs.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Use existing test utilities rather than writing custom utilities

Applied to files:

  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Tests should be cross-platform compatible using `path.resolve`, `path.join`, and `path.sep` for Windows, macOS, and Linux compatibility

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Check assets/ directory for test data when writing tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Follow naming conventions for browser tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `test` instead of `it` for defining test cases in vitest

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Prefer the use of `test.extend` over loose variables; import `test as baseTest` from `vitest`

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
🧬 Code graph analysis (2)
src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts (2)
src/stores/firebaseAuthStore.ts (1)
  • FirebaseAuthStoreError (46-51)
src/config/comfyApi.ts (1)
  • getComfyApiBaseUrl (21-31)
tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts (1)
src/platform/cloud/onboarding/utils/previousFullPath.ts (1)
  • getSafePreviousFullPath (16-27)
🔇 Additional comments (21)
lint-staged.config.mjs (2)

1-2: LGTM!

The Node.js path module import uses the modern node: protocol prefix, which is the recommended approach.


3-10: LGTM! Typecheck runs on entire project.

The configuration correctly separates JavaScript and TypeScript/Vue file handling. Note that pnpm typecheck (line 8) runs on the entire project rather than just staged files, which is necessary since TypeScript type-checking requires full project context. This may add latency when staging many files, but is standard practice.

src/platform/cloud/onboarding/UserCheckView.vue (1)

84-84: LGTM: Consistent use of globalThis for location.

The change from window.location.href to globalThis.location.href aligns with the environment-agnostic pattern used elsewhere in this PR's onboarding views.

src/locales/en/main.json (1)

2101-2101: LGTM: Clear localization key for cloud navigation.

The new skipToCloudApp key provides user-facing text for quick navigation within cloud onboarding flows. The key name and value are clear and follow existing conventions.

src/platform/cloud/onboarding/onboardingCloudRoutes.ts (1)

69-75: LGTM: Well-formed route for subscription redirect.

The new cloud-subscribe route is properly configured with authentication guard (requiresAuth: true) and lazy-loads the CloudSubscriptionRedirectView component. The route definition follows the existing patterns in the file.

tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts (1)

1-38: LGTM: Comprehensive test coverage for path safety.

The test suite provides excellent behavioral coverage of getSafePreviousFullPath, verifying:

  • Null return for missing values
  • Proper decoding of valid internal paths
  • Security: rejection of protocol-relative URLs (//evil.com)
  • Security: rejection of absolute external URLs
  • Error handling: rejection of malformed encodings

Test names are descriptive and follow vitest conventions.

src/router.ts (1)

152-178: LGTM: Clean previousFullPath preservation for post-login redirects.

The router now captures and encodes the current path before redirecting to cloud-login, enabling proper restoration after authentication. The root path ('/') is explicitly excluded from this mechanism, which is appropriate as it's the default landing page.

The implementation consistently applies the query object to both requiresAuth and general authentication checks, ensuring uniform redirect behavior.

src/platform/cloud/onboarding/CloudSignupView.vue (4)

103-103: LGTM: Import aligns with safe redirect functionality.

The import of getSafePreviousFullPath enables the component to safely restore the user's previous path after sign-up, integrating with the broader previousFullPath redirect mechanism introduced in this PR.


114-114: LGTM: Consistent globalThis usage.

Replacing window.isSecureContext with globalThis.isSecureContext maintains consistency with other onboarding views in this PR.


119-121: LGTM: Proper async navigation.

Making navigateToLogin async and awaiting router.push ensures navigation completes before control returns, which is the correct pattern for programmatic routing.


130-137: LGTM: Smart post-signup redirect with fallback.

The updated onSuccess flow now checks for a safe previous path and redirects there if available, falling back to the root. This improves UX by returning users to their intended destination (e.g., the subscription page they were visiting before being prompted to sign up).

src/platform/cloud/subscription/composables/useSubscription.ts (3)

39-39: LGTM: Initialization flag tracks subscription data readiness.

Adding isInitialized provides a clear signal to consumers about when subscription data has been fetched, enabling proper loading states and conditional rendering.


197-206: LGTM: Robust initialization tracking with try/finally.

The try/finally ensures isInitialized is set to true regardless of fetch success or failure, preventing indefinite loading states. Both login and logout paths properly update the flag.


246-246: LGTM: Exposing initialization state to consumers.

Adding isInitialized to the public API allows components to gate subscription-related UI until data is ready, improving user experience and preventing race conditions.

src/platform/cloud/onboarding/utils/previousFullPath.ts (1)

3-27: LGTM! Solid security implementation for redirect path validation.

The utility correctly prevents open redirect vulnerabilities by:

  • Safely decoding URI components with error handling
  • Rejecting protocol-relative URLs (//evil.com)
  • Validating that paths are relative and in-app only
  • Handling both string and array query parameters

The implementation follows security best practices for redirect validation.

src/platform/cloud/onboarding/CloudLoginView.vue (1)

87-114: LGTM! Clean integration of safe redirect logic.

The changes correctly integrate the previousFullPath utility:

  • Uses globalThis.isSecureContext for better portability than window
  • Properly awaits router operations
  • Conditionally redirects to the safe previous path when available
  • Falls back to the default cloud-user-check route when no previous path exists

The implementation enhances the post-login navigation flow without breaking existing behavior.

tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts (1)

1-150: LGTM! Comprehensive test coverage following best practices.

The test suite effectively covers all critical scenarios:

  • Invalid/missing tier redirects to home
  • Valid tier displays correct copy and initiates checkout
  • Active subscription opens billing portal instead of checkout
  • Array query parameter handling uses the first value

The implementation:

  • Uses Vitest utilities properly with vi.hoisted() for contained mocks
  • Tests behavioral outcomes rather than implementation details
  • Includes proper setup/teardown in beforeEach
  • Avoids redundant or change-detector tests

Based on coding guidelines for test files.

src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue (2)

67-67: Hardcoded billing cycle should be configurable or use a constant.

The billing cycle is hardcoded to 'monthly' when calling performSubscriptionCheckout. This might be intentional for the initial redirect flow, but consider:

  1. If this should always be monthly, extract it as a named constant (e.g., const DEFAULT_BILLING_CYCLE: BillingCycle = 'monthly') for clarity
  2. If it should be configurable, consider reading from route query params or component props

Could you clarify whether the monthly billing cycle is the intended default for subscription redirects, or should this be configurable?


60-68: LGTM! Race condition properly addressed.

The subscription initialization check correctly prevents the race condition flagged in previous reviews. The component now waits for isInitialized before checking isActiveSubscription.value, ensuring users with existing subscriptions are properly directed to the billing portal instead of checkout.

src/platform/cloud/subscription/components/PricingTable.vue (2)

255-259: LGTM! Clean refactoring to centralized checkout utility.

The component successfully:

  • Imports shared types (TierKey, BillingCycle) from the utility, eliminating duplication
  • Delegates checkout logic to performSubscriptionCheckout
  • Maintains existing functionality while improving code reuse

This addresses the previous review comment about importing the shared TierKey type.


363-369: Good use of function declaration style.

The block-style function declaration for getButtonSeverity follows the repository's coding guidelines that prefer function declarations over function expressions for pure functions.

Based on learnings about preferring function declarations.

Comment on lines +12 to +21
function formatAndEslint(fileNames) {
// Convert absolute paths to relative paths for better ESLint resolution
const relativePaths = fileNames.map((f) => path.relative(process.cwd(), f))
const joinedPaths = relativePaths.map((p) => `"${p}"`).join(' ')
return [
`pnpm exec prettier --cache --write ${joinedPaths}`,
`pnpm exec oxlint --fix ${joinedPaths}`,
`pnpm exec eslint --cache --fix --no-warn-ignored ${joinedPaths}`
]
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider shell-escaping for defensive coding.

The implementation is solid and follows standard lint-staged patterns. The command ordering (prettier → oxlint → eslint) is logical, and the use of --cache flags improves performance.

However, line 15's quote wrapping could theoretically be vulnerable if filenames contain quotes or special shell characters (e.g., file"name.ts becomes "file"name.ts", which breaks the command). While source files rarely have such names and lint-staged typically provides sanitized paths, consider using a proper shell-escape utility (e.g., from es-toolkit or a dedicated package) for more robust handling.

Example with shell escaping
+import { escapeShellArg } from 'es-toolkit' // or similar utility
+
 function formatAndEslint(fileNames) {
   // Convert absolute paths to relative paths for better ESLint resolution
   const relativePaths = fileNames.map((f) => path.relative(process.cwd(), f))
-  const joinedPaths = relativePaths.map((p) => `"${p}"`).join(' ')
+  const joinedPaths = relativePaths.map((p) => escapeShellArg(p)).join(' ')
   return [
     `pnpm exec prettier --cache --write ${joinedPaths}`,
     `pnpm exec oxlint --fix ${joinedPaths}`,
     `pnpm exec eslint --cache --fix --no-warn-ignored ${joinedPaths}`
   ]
 }

Note: Check if es-toolkit provides shell escaping, otherwise use a dedicated package like shell-quote.

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +3 to +4
import Button from 'primevue/button'
import ProgressSpinner from 'primevue/progressspinner'
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider using custom button components instead of PrimeVue.

The coding guidelines specify "Avoid new usage of PrimeVue components" for Vue files. Consider using the repository's custom button components from @/components/button/ (such as TextButton.vue) instead of PrimeVue's Button component for consistency with the design system.

Note: ProgressSpinner might be acceptable if no custom alternative exists, but the skip button at Line 101-107 could use a custom component.

As per coding guidelines for src/**/*.vue files.

🤖 Prompt for AI Agents
In src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue around lines
3 to 4 and the skip button usage at lines 101 to 107, replace the PrimeVue
Button import/usage with the repository's custom button component (eg. import
TextButton from '@/components/button/TextButton.vue' or the appropriate export)
and update the template to use that component in place of <Button>, mapping
props/events to the custom component's API; keep ProgressSpinner if no custom
spinner exists and remove the unused PrimeVue Button import. Ensure the custom
button preserves the same styling/behavior (click handler, disabled state,
classes) as the current skip button.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 127ade7 and 2bb3723.

📒 Files selected for processing (1)
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
tests-ui/**/*.test.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (tests-ui/CLAUDE.md)

tests-ui/**/*.test.{js,ts,jsx,tsx}: Write tests for new features
Follow existing test patterns in the codebase
Use existing test utilities rather than writing custom utilities
Mock external dependencies in tests
Always prefer vitest mock functions over writing verbose manual mocks

Files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
tests-ui/**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

tests-ui/**/*.test.ts: Write tests for all changes, especially bug fixes to catch future regressions
Unit/Component test files must use pattern **/*.test.ts
Do not write change detector tests - do not just assert that defaults are certain values
Do not write tests dependent on non-behavioral features like utility classes or styles
Be parsimonious in testing - do not write redundant tests
Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly
For mocking, leverage Vitest's utilities where possible
Keep module mocks contained - do not use global mutable state within test files, use vi.hoisted() if necessary
For Component testing, use Vue Test Utils and follow advice about making components easy to test
Aim for behavioral coverage of critical and new features

Files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
🧠 Learnings (24)
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : For Component testing, use Vue Test Utils and follow advice about making components easy to test

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Write tests for new features

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : For mocking, leverage Vitest's utilities where possible

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Aim for behavioral coverage of critical and new features

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Follow existing test patterns in the codebase

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Keep module mocks contained - do not use global mutable state within test files, use `vi.hoisted()` if necessary

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Unit/Component test files must use pattern `**/*.test.ts`

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Be parsimonious in testing - do not write redundant tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test user workflows in browser tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Mocks should be cleanly written and easy to understand, with reusable mocks where possible

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Always prefer vitest mock functions over writing verbose manual mocks

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Never use `as any` type assertions - fix the underlying type issue

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Do not write change detector tests - do not just assert that defaults are certain values

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Check tests-ui/README.md for test guidelines

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test across multiple viewports

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Mock external dependencies in tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-10T03:09:13.807Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:13.807Z
Learning: In test files, prefer selecting or asserting on accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests validate actual user-facing behavior and accessibility, reducing reliance on implementation details like test IDs.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: setup
  • GitHub Check: test
  • GitHub Check: collect
  • GitHub Check: lint-and-format
🔇 Additional comments (5)
tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts (5)

1-7: LGTM!

Imports and the flushPromises utility follow standard patterns for Vue component testing with Vitest.


9-20: LGTM!

Router mocks are properly structured. The module-level mockQuery is reset in beforeEach, keeping test isolation intact.


22-55: LGTM!

Good use of vi.hoisted() for mocks that need hoisting. The mock patterns are clean and follow Vitest best practices per the coding guidelines.


57-93: LGTM!

The createI18nInstance provides focused minimal translations. The mountView helper is clean and properly awaits promise resolution.


139-147: LGTM!

Good test for the active subscription edge case—verifies billing portal is opened instead of checkout.

Comment on lines +109 to +113
test('redirects to home when subscriptionType is invalid', async () => {
await mountView({ subscriptionType: 'invalid' })

expect(mockRouterPush).toHaveBeenCalledWith('/')
})
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Incorrect query parameter name: test passes for wrong reasons.

This test uses subscriptionType but the component (per PR objectives) uses tier as the query parameter. The test passes because there's no valid tier param present, so the component redirects—but the test intent is to verify invalid tier handling.

🔎 Apply this diff to fix the parameter name:
   test('redirects to home when subscriptionType is invalid', async () => {
-    await mountView({ subscriptionType: 'invalid' })
+    await mountView({ tier: 'invalid' })

     expect(mockRouterPush).toHaveBeenCalledWith('/')
   })
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
test('redirects to home when subscriptionType is invalid', async () => {
await mountView({ subscriptionType: 'invalid' })
expect(mockRouterPush).toHaveBeenCalledWith('/')
})
test('redirects to home when subscriptionType is invalid', async () => {
await mountView({ tier: 'invalid' })
expect(mockRouterPush).toHaveBeenCalledWith('/')
})
🤖 Prompt for AI Agents
In
tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
around lines 109 to 113, the test passes for the wrong reason because it sets
the query key subscriptionType instead of tier; update the test to pass an
invalid tier query parameter (i.e., call mountView({ tier: 'invalid' })) so the
component's actual query handling is exercised and the redirect assertion
remains unchanged.

Comment on lines +115 to +137
test('shows subscription copy when subscriptionType is valid', async () => {
const { wrapper } = await mountView({ tier: 'creator' })

// Should not redirect to home
expect(mockRouterPush).not.toHaveBeenCalledWith('/')

// Shows copy under logo
expect(wrapper.text()).toContain('Subscribe to Creator')

// Triggers checkout flow
expect(mockPerformSubscriptionCheckout).toHaveBeenCalledWith(
'creator',
'monthly',
false
)

// Shows loading affordances
expect(wrapper.findComponent({ name: 'ProgressSpinner' }).exists()).toBe(
true
)
const skipLink = wrapper.get('a[href="/"]')
expect(skipLink.text()).toContain('Skip to the cloud app')
})
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Good behavioral coverage, but test name is inconsistent with implementation.

The test body correctly uses tier but the test name says "subscriptionType". Consider updating the test name for consistency.

🔎 Suggested fix:
-  test('shows subscription copy when subscriptionType is valid', async () => {
+  test('shows subscription copy when tier is valid', async () => {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
test('shows subscription copy when subscriptionType is valid', async () => {
const { wrapper } = await mountView({ tier: 'creator' })
// Should not redirect to home
expect(mockRouterPush).not.toHaveBeenCalledWith('/')
// Shows copy under logo
expect(wrapper.text()).toContain('Subscribe to Creator')
// Triggers checkout flow
expect(mockPerformSubscriptionCheckout).toHaveBeenCalledWith(
'creator',
'monthly',
false
)
// Shows loading affordances
expect(wrapper.findComponent({ name: 'ProgressSpinner' }).exists()).toBe(
true
)
const skipLink = wrapper.get('a[href="/"]')
expect(skipLink.text()).toContain('Skip to the cloud app')
})
test('shows subscription copy when tier is valid', async () => {
const { wrapper } = await mountView({ tier: 'creator' })
// Should not redirect to home
expect(mockRouterPush).not.toHaveBeenCalledWith('/')
// Shows copy under logo
expect(wrapper.text()).toContain('Subscribe to Creator')
// Triggers checkout flow
expect(mockPerformSubscriptionCheckout).toHaveBeenCalledWith(
'creator',
'monthly',
false
)
// Shows loading affordances
expect(wrapper.findComponent({ name: 'ProgressSpinner' }).exists()).toBe(
true
)
const skipLink = wrapper.get('a[href="/"]')
expect(skipLink.text()).toContain('Skip to the cloud app')
})
🤖 Prompt for AI Agents
In
tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
around lines 115 to 137 the test title says "shows subscription copy when
subscriptionType is valid" but the implementation uses the prop `tier`; update
the test name to match the implementation — e.g., change the description string
to "shows subscription copy when tier is valid" (or similar wording that
references "tier" instead of "subscriptionType") so the test name accurately
reflects what it's testing.

Comment on lines +149 to +161
test('uses first value when subscriptionType is an array', async () => {
const { wrapper } = await mountView({
tier: ['creator', 'pro']
})

expect(mockRouterPush).not.toHaveBeenCalledWith('/')
expect(wrapper.text()).toContain('Subscribe to Creator')
expect(mockPerformSubscriptionCheckout).toHaveBeenCalledWith(
'creator',
'monthly',
false
)
})
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Test name inconsistency with implementation.

The test body correctly uses tier but the test name says "subscriptionType". For consistency with the actual query parameter used:

🔎 Suggested fix:
-  test('uses first value when subscriptionType is an array', async () => {
+  test('uses first value when tier is an array', async () => {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
test('uses first value when subscriptionType is an array', async () => {
const { wrapper } = await mountView({
tier: ['creator', 'pro']
})
expect(mockRouterPush).not.toHaveBeenCalledWith('/')
expect(wrapper.text()).toContain('Subscribe to Creator')
expect(mockPerformSubscriptionCheckout).toHaveBeenCalledWith(
'creator',
'monthly',
false
)
})
test('uses first value when tier is an array', async () => {
const { wrapper } = await mountView({
tier: ['creator', 'pro']
})
expect(mockRouterPush).not.toHaveBeenCalledWith('/')
expect(wrapper.text()).toContain('Subscribe to Creator')
expect(mockPerformSubscriptionCheckout).toHaveBeenCalledWith(
'creator',
'monthly',
false
)
})
🤖 Prompt for AI Agents
In
tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
around lines 149 to 161, the test name references "subscriptionType" but the
test uses the query parameter `tier`; update the test name to reflect the actual
parameter (e.g., "uses first value when tier is an array") so the description
matches the implementation and run the tests to confirm no other name mismatches
exist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

preview 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