Skip to content

Conversation

@jzsfkzm
Copy link
Contributor

@jzsfkzm jzsfkzm commented Nov 27, 2025

refs #1779

Summary by CodeRabbit

  • New Features

    • Payment Methods page and UI: list cards, set default, remove cards, add-card flow, and Payment Popup with 3DS/success handling
    • Account Overview: credits display and Auto Credit Reload toggle (feature-gated)
    • Server-backed wallet settings and default-payment-method tracking; /payment-methods route (auth + feature flag)
  • Tests

    • Expanded suites covering payment flows, wallet settings, auto-reload, and billing components
  • UI

    • Added informational badge variant and minor badge styling tweak

✏️ Tip: You can customize this high-level summary in your review settings.

@jzsfkzm jzsfkzm requested a review from a team as a code owner November 27, 2025 15:15
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 27, 2025

Walkthrough

Adds wallet-settings and default-payment-method APIs, SDK exports and types, React Query keys/hooks, DI wiring, billing UI (AccountOverview, Payment Methods, PaymentPopup), route/page for /payment-methods gated by the "auto_credit_reload" flag, and many tests covering these flows. (50 words)

Changes

Cohort / File(s) Summary
Feature flags
apps/api/src/core/services/feature-flags/feature-flags.ts, apps/deploy-web/src/types/feature-flags.ts
Added AUTO_CREDIT_RELOAD / "auto_credit_reload" feature flag.
Wallet settings SDK & types
packages/http-sdk/src/wallet-settings/*, packages/http-sdk/src/index.ts
New WalletSettingsHttpService (GET/POST/PUT/DELETE) and types (WalletSettings, WalletSettingsResponse, UpdateWalletSettingsParams); exported from SDK index.
Stripe SDK enhancements
packages/http-sdk/src/stripe/stripe.service.ts, packages/http-sdk/src/stripe/stripe.types.ts
Added getDefaultPaymentMethod and setPaymentMethodAsDefault to StripeService; added SetPaymentMethodAsDefaultParams type; added funding to PaymentMethod.card.
App DI wiring
apps/deploy-web/src/services/app-di-container/app-di-container.ts
Wired walletSettings() into the app container using WalletSettingsHttpService with the user-token interceptor.
Query keys & hooks
apps/deploy-web/src/queries/queryKeys.ts, apps/deploy-web/src/queries/index.ts, apps/deploy-web/src/queries/useWalletSettingsQueries.tsx, apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx, apps/deploy-web/src/queries/usePaymentQueries.ts, apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
Added query keys for DEFAULT_PAYMENT_METHOD and WALLET_SETTINGS; new hooks useWalletSettingsQuery / useWalletSettingsMutations; added useDefaultPaymentMethodQuery and setPaymentMethodAsDefault mutation; tests added/updated.
Billing UI — Overview & layout
apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx, apps/deploy-web/src/components/billing-usage/BillingPage.tsx, apps/deploy-web/src/components/billing-usage/BillingUsageLayout.tsx
New AccountOverview (credits + auto-reload toggle); BillingUsageLayout adds PAYMENT_METHODS tab and feature-flag gating; BillingPage conditionally renders AccountOverview.
Payment methods — container / view / row
apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/*, apps/deploy-web/src/components/billing-usage/PaymentMethodsView/*, apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx
Added PaymentMethodsContainer (render-prop, DI), PaymentMethodsView, and PaymentMethodsRow components with callbacks and tests.
Payment methods page & route
apps/deploy-web/src/components/billing-usage/PaymentMethodsPage.tsx, apps/deploy-web/src/pages/payment-methods/index.tsx
New PaymentMethodsPage; Next.js page exported wrapped with guards and getServerSideProps requiring auth and auto_credit_reload feature.
Payment popup & UI variants
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx, packages/ui/components/badge.tsx
New PaymentPopup (amount/coupon forms, 3DS/polling, coupon flow); added info badge variant and adjusted success styling.
Utilities & test seeders
apps/deploy-web/src/utils/urlUtils.ts, apps/deploy-web/tests/seeders/payment.ts
Added UrlService.paymentMethods(); test seeders include createMockSetupIntentResponse and extended mock payment method fields (card.funding, created, validated, isDefault).

Sequence Diagram(s)

sequenceDiagram
    autonumber
    actor User as Browser
    participant UI as Billing UI (AccountOverview / PaymentPopup / PaymentMethodsView)
    participant Hooks as React Query Hooks
    participant DI as App DI Container
    participant SDK as HTTP SDK (WalletSettingsHttpService / StripeService)
    participant API as Backend

    User->>UI: toggle auto-reload / open payment popup / set default card
    UI->>Hooks: call query/mutation hook (WALLET_SETTINGS / DEFAULT_PAYMENT_METHOD / PAYMENT_METHODS)
    Hooks->>DI: obtain service instance (walletSettings / stripe)
    DI->>SDK: invoke WalletSettingsHttpService / StripeService method
    SDK->>API: HTTP request (/v1/wallet-settings, /v1/stripe/...)
    API-->>SDK: response (data or error)
    SDK-->>DI: return extracted data
    DI-->>Hooks: resolve promise
    Hooks->>Hooks: invalidate queries (WALLET_SETTINGS, PAYMENT_METHODS, DEFAULT_PAYMENT_METHOD) on success
    Hooks-->>UI: update UI state / re-render
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas needing extra attention:
    • packages/http-sdk/src/wallet-settings/* — request/response shapes and extractApiData usage.
    • apps/deploy-web/src/components/billing-usage/PaymentPopup/* — 3DS flow, polling, side effects and state resets.
    • React Query invalidation interactions in usePaymentQueries and useWalletSettingsQueries.
    • App DI wiring in app-di-container and interceptor ordering.

Possibly related PRs

Suggested reviewers

  • baktun14
  • ygrishajev
  • stalniy

Poem

🐰 I hopped through types and HTTP threads,

toggled reloads and jingled tiny creds,
cards found defaults, queries cleared the slate,
popups, 3DS, and tests stayed up late,
a rabbit cheers — the billing path is great.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the three main features introduced: AccountOverview component, auto-reload functionality, and a new separate payment methods page.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@codecov
Copy link

codecov bot commented Nov 27, 2025

Codecov Report

❌ Patch coverage is 73.42193% with 80 lines in your changes missing coverage. Please review.
✅ Project coverage is 50.79%. Comparing base (9be49eb) to head (cc36d58).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
.../billing-usage/AccountOverview/AccountOverview.tsx 0.00% 46 Missing ⚠️
...pps/deploy-web/src/pages/payment-methods/index.tsx 0.00% 9 Missing ⚠️
...rc/components/billing-usage/BillingUsageLayout.tsx 0.00% 7 Missing ⚠️
...rc/components/billing-usage/PaymentMethodsPage.tsx 0.00% 7 Missing ⚠️
...y-web/src/components/billing-usage/BillingPage.tsx 0.00% 4 Missing ⚠️
...onents/billing-usage/PaymentPopup/PaymentPopup.tsx 97.05% 3 Missing ⚠️
...ing-usage/PaymentMethodsView/PaymentMethodsRow.tsx 94.11% 2 Missing ⚠️
...ng-usage/PaymentMethodsView/PaymentMethodsView.tsx 94.11% 1 Missing ⚠️
.../src/services/app-di-container/app-di-container.ts 66.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2282      +/-   ##
==========================================
+ Coverage   50.47%   50.79%   +0.31%     
==========================================
  Files        1037     1045       +8     
  Lines       28198    28493     +295     
  Branches     6233     6280      +47     
==========================================
+ Hits        14233    14473     +240     
- Misses      13638    13658      +20     
- Partials      327      362      +35     
Flag Coverage Δ *Carryforward flag
api 81.19% <ø> (ø)
deploy-web 30.07% <73.42%> (+0.89%) ⬆️
log-collector 75.35% <ø> (ø)
notifications 87.94% <ø> (ø)
provider-console 81.48% <ø> (ø)
provider-proxy 84.35% <ø> (ø) Carriedforward from 9be49eb

*This pull request uses carry forward flags. Click here to find out more.

Files with missing lines Coverage Δ
...i/src/core/services/feature-flags/feature-flags.ts 100.00% <ø> (ø)
...aymentMethodsContainer/PaymentMethodsContainer.tsx 100.00% <100.00%> (ø)
apps/deploy-web/src/queries/index.ts 100.00% <100.00%> (ø)
apps/deploy-web/src/queries/queryKeys.ts 100.00% <100.00%> (ø)
apps/deploy-web/src/queries/usePaymentQueries.ts 100.00% <100.00%> (+8.88%) ⬆️
...eploy-web/src/queries/useWalletSettingsQueries.tsx 100.00% <100.00%> (ø)
apps/deploy-web/src/utils/urlUtils.ts 82.66% <100.00%> (+0.23%) ⬆️
...ng-usage/PaymentMethodsView/PaymentMethodsView.tsx 94.11% <94.11%> (ø)
.../src/services/app-di-container/app-di-container.ts 78.82% <66.66%> (+0.66%) ⬆️
...ing-usage/PaymentMethodsView/PaymentMethodsRow.tsx 94.11% <94.11%> (ø)
... and 6 more

... and 88 files with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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: 7

🧹 Nitpick comments (7)
apps/deploy-web/src/components/shared/StripeInput/StripeInput.tsx (2)

2-17: Refine themed helper to handle non-"light" resolvedTheme values more predictably

Right now, anything other than "light" is treated as dark:

return resolvedTheme === "light" ? light : dark;

If resolvedTheme is ever undefined or another value, this will default to dark, which can cause a brief dark flash for users who should be on light theme. Consider inverting the condition so that "dark" is explicit and everything else falls back to light:

-  const themed = useCallback(
-    (light: string, dark: string) => {
-      return resolvedTheme === "light" ? light : dark;
-    },
-    [resolvedTheme]
-  );
+  const themed = useCallback(
+    (light: string, dark: string) => {
+      return resolvedTheme === "dark" ? dark : light;
+    },
+    [resolvedTheme]
+  );

This keeps behavior correct for dark mode while making the default safer if resolvedTheme is temporarily unset or extended in the future.


53-61: Optional: avoid duplicating style logic between base styles and focus/blur handlers

Focus/blur handlers directly mutate borderColor and boxShadow, and those values are now duplicated between the base style (lines 43–49) and the blur handler (lines 60–61). If you touch these styles again, consider centralizing them (e.g., small constants or a helper using themed) so focus/blur can just switch between “base” and “focused” variants, or moving more of this into CSS with theme-aware variables. Not urgent, but it would reduce drift over time.

apps/deploy-web/src/queries/queryKeys.ts (1)

71-79: Confirm cache scoping for getWalletSettingsKey

getWalletSettingsKey returns a single static key ["WALLET_SETTINGS"], so wallet settings are cached globally in React Query. If different users (or networks) can be active in the same client session, make sure you either:

  • reset the query cache on user/network change, or
  • include a user/network discriminator in the key (e.g. user id, network id).

If cache reset is already handled elsewhere, this is fine as‑is.

apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx (1)

1-9: Import organization: group external imports before internal ones.

Consider reordering imports to follow the convention of external dependencies first, then internal imports.

 import type { UpdateWalletSettingsParams, WalletSettings } from "@akashnetwork/http-sdk/src/wallet-settings/wallet-settings.types";
 import type { WalletSettingsHttpService } from "@akashnetwork/http-sdk/src/wallet-settings/wallet-settings-http.service";
+import { act, waitFor } from "@testing-library/react";
 import { mock } from "jest-mock-extended";
 
 import { useWalletSettingsMutations, useWalletSettingsQuery } from "./useWalletSettingsQueries";
-
-import { act, waitFor } from "@testing-library/react";
 import { setupQuery } from "@tests/unit/query-client";
packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (1)

9-12: Constructor can be omitted if it only delegates to super.

If the constructor doesn't add any additional logic, TypeScript will automatically inherit the parent's constructor.

 export class WalletSettingsHttpService extends ApiHttpService {
-  constructor(config?: AxiosRequestConfig) {
-    super(config);
-  }
-
   async getWalletSettings(): Promise<WalletSettings> {
apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (2)

13-16: Simplify queryFn by returning directly.

The intermediate response variable is unnecessary.

     queryKey: QueryKeys.getWalletSettingsKey(),
-    queryFn: async () => {
-      const response = await walletSettings.getWalletSettings();
-      return response;
-    }
+    queryFn: () => walletSettings.getWalletSettings()
   });

24-31: Consider simplifying mutation functions.

The async/await wrapper is redundant when the function just returns the promise.

   const updateWalletSettings = useMutation({
-    mutationFn: async (settings: UpdateWalletSettingsParams): Promise<WalletSettings> => {
-      return await walletSettings.updateWalletSettings(settings);
-    },
+    mutationFn: (settings: UpdateWalletSettingsParams) => walletSettings.updateWalletSettings(settings),
     onSuccess: () => {
       queryClient.invalidateQueries({ queryKey: QueryKeys.getWalletSettingsKey() });
     }
   });

The same simplification can be applied to createWalletSettings and deleteWalletSettings.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eeac563 and 331c3a5.

📒 Files selected for processing (16)
  • apps/api/src/core/services/feature-flags/feature-flags.ts (1 hunks)
  • apps/deploy-web/src/components/shared/PaymentMethodsList/PaymentMethodsList.tsx (2 hunks)
  • apps/deploy-web/src/components/shared/StripeInput/StripeInput.tsx (3 hunks)
  • apps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsx (1 hunks)
  • apps/deploy-web/src/components/user/payment/PaymentPopup.tsx (1 hunks)
  • apps/deploy-web/src/components/user/payment/index.ts (1 hunks)
  • apps/deploy-web/src/pages/payment.tsx (5 hunks)
  • apps/deploy-web/src/queries/index.ts (1 hunks)
  • apps/deploy-web/src/queries/queryKeys.ts (1 hunks)
  • apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx (1 hunks)
  • apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (1 hunks)
  • apps/deploy-web/src/services/app-di-container/app-di-container.ts (2 hunks)
  • apps/deploy-web/src/types/feature-flags.ts (1 hunks)
  • packages/http-sdk/src/index.ts (1 hunks)
  • packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (1 hunks)
  • packages/http-sdk/src/wallet-settings/wallet-settings.types.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{ts,tsx,js}: Never use type any or cast to type any. Always define the proper TypeScript types.
Never use deprecated methods from libraries.
Don't add unnecessary comments to the code.

Files:

  • apps/deploy-web/src/queries/queryKeys.ts
  • apps/deploy-web/src/components/user/payment/index.ts
  • apps/deploy-web/src/types/feature-flags.ts
  • apps/deploy-web/src/components/shared/StripeInput/StripeInput.tsx
  • apps/deploy-web/src/queries/useWalletSettingsQueries.tsx
  • apps/api/src/core/services/feature-flags/feature-flags.ts
  • packages/http-sdk/src/index.ts
  • apps/deploy-web/src/components/user/payment/PaymentPopup.tsx
  • packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts
  • apps/deploy-web/src/components/shared/PaymentMethodsList/PaymentMethodsList.tsx
  • apps/deploy-web/src/pages/payment.tsx
  • packages/http-sdk/src/wallet-settings/wallet-settings.types.ts
  • apps/deploy-web/src/services/app-di-container/app-di-container.ts
  • apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx
  • apps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsx
  • apps/deploy-web/src/queries/index.ts
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/no-jest-mock.mdc)

Don't use jest.mock() in test files. Instead, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test

Use setup function instead of beforeEach in test files. The setup function must be at the bottom of the root describe block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type.

**/*.spec.{ts,tsx}: Use <Subject>.name in the root describe suite description instead of hardcoded class/service name strings to enable automated refactoring tools to find all references
Use either a method name or a condition starting with 'when' for nested suite descriptions in tests
Use present simple, 3rd person singular for test descriptions without prepending 'should'

Files:

  • apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx
{apps/deploy-web,apps/provider-console}/**/*.spec.tsx

📄 CodeRabbit inference engine (.cursor/rules/query-by-in-tests.mdc)

Use queryBy methods instead of getBy methods in test expectations

Files:

  • apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx
🧠 Learnings (6)
📚 Learning: 2025-07-28T10:40:13.595Z
Learnt from: stalniy
Repo: akash-network/console PR: 1480
File: apps/deploy-web/src/hooks/useFlag.tsx:0-0
Timestamp: 2025-07-28T10:40:13.595Z
Learning: In the Akash Network Console project, backend-specific feature flags are intentional and acceptable. The frontend FeatureFlag union type should only include flags that are actually used by the frontend, not all flags defined in the backend. Backend can have internal feature flags for backend-only functionality without requiring frontend synchronization.

Applied to files:

  • apps/deploy-web/src/types/feature-flags.ts
  • apps/api/src/core/services/feature-flags/feature-flags.ts
📚 Learning: 2025-11-12T16:36:02.543Z
Learnt from: baktun14
Repo: akash-network/console PR: 2203
File: apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx:161-168
Timestamp: 2025-11-12T16:36:02.543Z
Learning: In apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx, the organization field captured during payment method setup is internal metadata. Errors from stripe.updateCustomerOrganization should be logged to Sentry but not surfaced to users, and the flow should continue even if the organization update fails, as it's non-critical and not something users can fix.

Applied to files:

  • apps/deploy-web/src/components/user/payment/PaymentPopup.tsx
  • apps/deploy-web/src/components/shared/PaymentMethodsList/PaymentMethodsList.tsx
  • apps/deploy-web/src/pages/payment.tsx
📚 Learning: 2025-09-18T07:50:31.224Z
Learnt from: baktun14
Repo: akash-network/console PR: 1933
File: apps/deploy-web/src/components/onboarding/steps/PaymentVerificationCard/PaymentVerificationCard.tsx:43-63
Timestamp: 2025-09-18T07:50:31.224Z
Learning: PaymentVerificationCard component is wrapped by Stripe Elements provider in its parent component PaymentMethodStep, so PaymentMethodForm inside PaymentVerificationCard has access to Stripe context without needing its own Elements wrapper.

Applied to files:

  • apps/deploy-web/src/components/user/payment/PaymentPopup.tsx
  • apps/deploy-web/src/components/shared/PaymentMethodsList/PaymentMethodsList.tsx
  • apps/deploy-web/src/pages/payment.tsx
📚 Learning: 2025-10-15T16:39:55.348Z
Learnt from: jzsfkzm
Repo: akash-network/console PR: 2039
File: apps/deploy-web/tests/ui/change-wallets.spec.ts:4-10
Timestamp: 2025-10-15T16:39:55.348Z
Learning: In the Akash Console E2E tests using the context-with-extension fixture, the first wallet is automatically created during fixture setup via `importWalletToLeap` in `apps/deploy-web/tests/ui/fixture/wallet-setup.ts`, so tests that call `frontPage.createWallet()` are creating a second wallet to test wallet switching functionality.

Applied to files:

  • apps/deploy-web/src/services/app-di-container/app-di-container.ts
  • apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx
📚 Learning: 2025-11-25T17:45:49.180Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/query-by-in-tests.mdc:0-0
Timestamp: 2025-11-25T17:45:49.180Z
Learning: Applies to {apps/deploy-web,apps/provider-console}/**/*.spec.tsx : Use `queryBy` methods instead of `getBy` methods in test expectations

Applied to files:

  • apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx
📚 Learning: 2025-11-19T15:15:07.283Z
Learnt from: ygrishajev
Repo: akash-network/console PR: 2254
File: apps/api/test/functional/sign-and-broadcast-tx.spec.ts:4-4
Timestamp: 2025-11-19T15:15:07.283Z
Learning: In the Akash Network Console project, when tests use native Node.js fetch (available in Node 18+), fetch-mock should be used for HTTP mocking instead of nock, as nock does not support intercepting native fetch calls. This applies to apps/api/test/functional/sign-and-broadcast-tx.spec.ts and any other tests using native fetch.

Applied to files:

  • apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx
🧬 Code graph analysis (7)
apps/deploy-web/src/components/shared/StripeInput/StripeInput.tsx (2)
apps/deploy-web/src/components/shared/StripeInput/index.ts (1)
  • StripeInput (1-1)
apps/deploy-web/src/components/shared/index.ts (1)
  • StripeInput (5-5)
apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (3)
packages/http-sdk/src/wallet-settings/wallet-settings.types.ts (2)
  • WalletSettings (1-5)
  • UpdateWalletSettingsParams (11-15)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
  • useServices (30-32)
packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (3)
  • updateWalletSettings (22-24)
  • createWalletSettings (18-20)
  • deleteWalletSettings (26-28)
apps/deploy-web/src/components/user/payment/PaymentPopup.tsx (6)
apps/deploy-web/src/hooks/useUser.ts (1)
  • useUser (7-20)
apps/deploy-web/src/queries/usePaymentQueries.ts (1)
  • usePaymentMutations (55-112)
apps/deploy-web/src/hooks/use3DSecure.ts (1)
  • use3DSecure (30-125)
packages/ui/components/custom/snackbar.tsx (1)
  • Snackbar (18-37)
apps/deploy-web/src/utils/stripeErrorHandler.ts (1)
  • handleCouponError (203-221)
packages/ui/components/custom/popup.tsx (1)
  • Popup (101-329)
packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (2)
packages/http-sdk/src/api-http/api-http.service.ts (1)
  • ApiHttpService (9-29)
packages/http-sdk/src/wallet-settings/wallet-settings.types.ts (2)
  • WalletSettings (1-5)
  • UpdateWalletSettingsParams (11-15)
apps/deploy-web/src/components/shared/PaymentMethodsList/PaymentMethodsList.tsx (1)
apps/deploy-web/src/components/shared/PaymentMethodCard/PaymentMethodCard.tsx (1)
  • PaymentMethodCard (20-104)
apps/deploy-web/src/services/app-di-container/app-di-container.ts (3)
packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (1)
  • WalletSettingsHttpService (9-29)
apps/deploy-web/src/services/auth/auth/interceptors.ts (1)
  • withUserToken (15-25)
apps/deploy-web/src/services/auth/auth/auth.service.ts (1)
  • withUserToken (53-63)
apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx (3)
apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (2)
  • useWalletSettingsQuery (8-18)
  • useWalletSettingsMutations (20-56)
packages/http-sdk/src/wallet-settings/wallet-settings.types.ts (2)
  • WalletSettings (1-5)
  • UpdateWalletSettingsParams (11-15)
packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (1)
  • WalletSettingsHttpService (9-29)
⏰ 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). (7)
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: Validate local packages
🔇 Additional comments (19)
apps/deploy-web/src/components/shared/StripeInput/StripeInput.tsx (1)

29-49: Themed base styles for label and input look consistent and self-contained

The use of the themed helper for label color, borders, background, text color, and box-shadow is coherent and keeps all light/dark values localized in one place. No functional issues stand out here, and the transitions remain intact.

apps/deploy-web/src/queries/index.ts (1)

1-8: Barrel export for wallet settings hooks looks good

Re‑exporting ./useWalletSettingsQueries from the queries barrel is consistent with the existing pattern and will make the new hooks available to consumers without breaking anything.

packages/http-sdk/src/index.ts (1)

1-27: HTTP SDK export for WalletSettingsHttpService is consistent

Adding export * from "./wallet-settings/wallet-settings-http.service"; matches the existing barrel pattern and cleanly exposes the new service without side effects.

apps/deploy-web/src/components/user/payment/index.ts (1)

1-4: Auto‑reload popup re‑export is correctly wired

Re‑exporting AutoReloadSettingsPopup from the payment components index keeps the public surface consistent with the other payment popups.

apps/deploy-web/src/types/feature-flags.ts (1)

1-10: New auto_credit_reload feature flag is correctly added

Extending the FeatureFlag union with "auto_credit_reload" is consistent with the new backend flag and matches the intended usage on the payment page. This also aligns with the guideline to only include frontend‑used flags in this union. Based on learnings, this looks correct.

apps/api/src/core/services/feature-flags/feature-flags.ts (1)

1-8: Backend feature flag AUTO_CREDIT_RELOAD definition is consistent

Defining AUTO_CREDIT_RELOAD: "auto_credit_reload" and relying on FeatureFlagValue as typeof FeatureFlags[keyof typeof FeatureFlags] keeps the backend contract in sync with the frontend FeatureFlag union.

packages/http-sdk/src/wallet-settings/wallet-settings.types.ts (1)

1-15: Wallet settings type shapes look appropriate; confirm API nullability

The WalletSettings, WalletSettingsResponse, and UpdateWalletSettingsParams interfaces match the intended usage in WalletSettingsHttpService (required autoReloadEnabled, optional threshold/amount, partial update payload), which is a clean and predictable contract.

One thing to double‑check with the API is whether autoReloadThreshold or autoReloadAmount can ever be null in responses; if so, the field types here may need to be widened to number | null to stay accurate.

apps/deploy-web/src/services/app-di-container/app-di-container.ts (1)

2-12: DI wiring for WalletSettingsHttpService is consistent with existing services

Importing WalletSettingsHttpService and registering a walletSettings factory that wraps it with applyAxiosInterceptors and withUserToken matches the established pattern used for other authenticated HTTP services (usage, auth, tx, etc.). This should integrate cleanly with the rest of the app‑wide service container.

Also applies to: 94-97

apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx (1)

10-204: Well-structured test suite with good coverage.

The tests properly use jest-mock-extended, function .name references for nested describes, and the setupQuery helper. Both success and error scenarios are covered for the query and all three mutations. As per coding guidelines, this follows the recommended patterns.

apps/deploy-web/src/components/shared/PaymentMethodsList/PaymentMethodsList.tsx (2)

18-30: Clean prop addition with sensible default.

The displayOnCard prop is well-typed and has a reasonable default value of true to maintain backward compatibility.


36-63: Good extraction of radio group for code reuse.

Extracting paymentMethodRadioGroup reduces duplication between the card-wrapped and unwrapped variants. The conditional rendering based on displayOnCard is clean and readable.

packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (1)

14-28: Service methods are well-structured and properly typed.

The CRUD operations follow consistent patterns and correctly use extractApiData for response handling. Return types are explicit.

apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (1)

20-55: Well-structured mutations hook with proper cache invalidation.

The hook correctly invalidates the wallet settings query on successful mutations, ensuring UI consistency. The returned object provides a clean API for consumers.

apps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsx (1)

75-85: Good implementation of change detection for save button.

The hasSomethingToSave memo correctly compares current form state against persisted settings, preventing unnecessary API calls when nothing changed.

apps/deploy-web/src/components/user/payment/PaymentPopup.tsx (5)

62-68: Potential issue with empty user ID passed to API.

If user is undefined, an empty string is passed as userId. This could cause API errors or unexpected behavior. Consider disabling the payment action when user is not available, or handling this case more explicitly.

+  const isUserReady = !!user?.id;
+
   const isProcessing = isConfirmingPayment || isPolling;
-  const disabled = !amount || parseFloat(amount) <= 0 || isProcessing || !selectedPaymentMethodId || !!amountError;
+  const disabled = !amount || parseFloat(amount) <= 0 || isProcessing || !selectedPaymentMethodId || !!amountError || !isUserReady;

96-121: Same user ID concern in coupon flow.

The applyCoupon call also uses user?.id || "". Consider applying the same guard here or ensuring the coupon button is disabled when user is unavailable.


37-46: Well-structured 3DS integration.

The 3DS hook is properly configured with success callback that handles polling, success state, form reset, and popup close. Setting showSuccessMessage: false avoids duplicate notifications since success is shown via setShowPaymentSuccess.


123-136: Good validation with clear minimum amount enforcement.

The validation correctly checks for positive amounts and enforces the $20 minimum with appropriate error messages.


160-259: Clean popup structure with proper loading states and error display.

The UI properly handles processing states, displays contextual error information with actionable suggestions, and provides clear user feedback. The dual-card layout for credits and coupons is well-organized.

Comment on lines 185 to 203
<div className="space-y-2">
<Label htmlFor="reloadAmount-input">
Reload Credit Balance to
<span className="ml-1 text-muted-foreground">(minimum ${MIN_RELOAD_AMOUNT})</span>
</Label>
<div className="flex">
<span className="self-center text-muted-foreground">$</span>
<Input
id="reloadAmount"
type="number"
min={MIN_RELOAD_AMOUNT}
step="1"
value={reloadAmount}
onChange={handleReloadAmountChange}
disabled={isPending}
className="flex-grow pl-2"
placeholder={DEFAULT_RELOAD_AMOUNT.toString()}
/>
</div>
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

Label htmlFor doesn't match input id - accessibility issue.

Same issue here: htmlFor="reloadAmount-input" but input has id="reloadAmount".

-          <Label htmlFor="reloadAmount-input">
+          <Label htmlFor="reloadAmount">
             Reload Credit Balance to
             <span className="ml-1 text-muted-foreground">(minimum ${MIN_RELOAD_AMOUNT})</span>
           </Label>
📝 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
<div className="space-y-2">
<Label htmlFor="reloadAmount-input">
Reload Credit Balance to
<span className="ml-1 text-muted-foreground">(minimum ${MIN_RELOAD_AMOUNT})</span>
</Label>
<div className="flex">
<span className="self-center text-muted-foreground">$</span>
<Input
id="reloadAmount"
type="number"
min={MIN_RELOAD_AMOUNT}
step="1"
value={reloadAmount}
onChange={handleReloadAmountChange}
disabled={isPending}
className="flex-grow pl-2"
placeholder={DEFAULT_RELOAD_AMOUNT.toString()}
/>
</div>
<div className="space-y-2">
<Label htmlFor="reloadAmount">
Reload Credit Balance to
<span className="ml-1 text-muted-foreground">(minimum ${MIN_RELOAD_AMOUNT})</span>
</Label>
<div className="flex">
<span className="self-center text-muted-foreground">$</span>
<Input
id="reloadAmount"
type="number"
min={MIN_RELOAD_AMOUNT}
step="1"
value={reloadAmount}
onChange={handleReloadAmountChange}
disabled={isPending}
className="flex-grow pl-2"
placeholder={DEFAULT_RELOAD_AMOUNT.toString()}
/>
</div>
🤖 Prompt for AI Agents
In apps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsx
around lines 185 to 203, the Label uses htmlFor="reloadAmount-input" while the
Input has id="reloadAmount", causing an accessibility mismatch; fix by making
the htmlFor and id identical (either change the Label to htmlFor="reloadAmount"
or change the Input id to "reloadAmount-input"), and update any other references
to that id accordingly so the label correctly targets the input.

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: 0

♻️ Duplicate comments (1)
apps/deploy-web/src/pages/payment.tsx (1)

318-357: Fix literal &lt; in auto‑reload summary text

In the “Auto Reload” box, the text uses &lt;, which will render literally instead of as the < symbol. Replace it with the actual character (or {"<"} if needed) so the message reads correctly, e.g.:

-                  Reload ${walletSettings?.autoReloadAmount || DEFAULT_RELOAD_AMOUNT} when &lt; ${walletSettings?.autoReloadThreshold || DEFAULT_THRESHOLD}
+                  Reload ${walletSettings?.autoReloadAmount || DEFAULT_RELOAD_AMOUNT} when < ${walletSettings?.autoReloadThreshold || DEFAULT_THRESHOLD}
🧹 Nitpick comments (2)
apps/deploy-web/src/pages/payment.tsx (2)

39-74: HalfBox/WideBox component abstractions and typings look good

The new layout helpers are clean, and HalfBoxProps/WideBoxProps are well-typed without using any, in line with the typing guidelines. If you want to avoid drift with the design system in future, you could import and reuse the Button’s own variant type instead of duplicating the string union, but what you have is already type‑safe.


82-83: Auto‑reload state/mutations are wired correctly; consider guarding rapid toggles

The new auto‑reload state (showAutoReloadSettings, wallet settings hooks) and handleReloadChange implementation (with defaults, try/catch, and user feedback) look solid and satisfy the “no any” guideline. To harden UX, consider disabling the Switch while the underlying create/update wallet settings mutation is in flight (e.g., track a local isUpdating flag tied to those mutations) so users can’t spam the toggle and fire overlapping requests.

Also applies to: 112-116, 276-301

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 331c3a5 and 2ca6f36.

📒 Files selected for processing (2)
  • apps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsx (1 hunks)
  • apps/deploy-web/src/pages/payment.tsx (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsx
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{ts,tsx,js}: Never use type any or cast to type any. Always define the proper TypeScript types.
Never use deprecated methods from libraries.
Don't add unnecessary comments to the code.

Files:

  • apps/deploy-web/src/pages/payment.tsx
🧠 Learnings (4)
📚 Learning: 2025-11-12T16:36:02.543Z
Learnt from: baktun14
Repo: akash-network/console PR: 2203
File: apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx:161-168
Timestamp: 2025-11-12T16:36:02.543Z
Learning: In apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx, the organization field captured during payment method setup is internal metadata. Errors from stripe.updateCustomerOrganization should be logged to Sentry but not surfaced to users, and the flow should continue even if the organization update fails, as it's non-critical and not something users can fix.

Applied to files:

  • apps/deploy-web/src/pages/payment.tsx
📚 Learning: 2025-11-25T17:45:39.561Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/general.mdc:0-0
Timestamp: 2025-11-25T17:45:39.561Z
Learning: Applies to **/*.{ts,tsx,js} : Never use type `any` or cast to type `any`. Always define the proper TypeScript types.

Applied to files:

  • apps/deploy-web/src/pages/payment.tsx
📚 Learning: 2025-10-31T11:26:42.138Z
Learnt from: stalniy
Repo: akash-network/console PR: 2138
File: apps/api/src/billing/lib/batch-signing-client/batch-signing-client.service.ts:379-382
Timestamp: 2025-10-31T11:26:42.138Z
Learning: In TypeScript/JavaScript, the pattern of checking a cached value and then performing an async operation to fetch it without proper synchronization is race condition unsafe:
```typescript
private async getAddress() {
  if (!this.address) {
    this.address = await this.wallet.getFirstAddress();
  }
  return this.address;
}
```
Multiple concurrent calls can all pass the `if (!this.address)` check before any of them sets the value, leading to duplicate async operations. This should be flagged as a race condition. Proper synchronization (mutex, atomic promise caching, or guaranteed single-threaded execution) is required.

Applied to files:

  • apps/deploy-web/src/pages/payment.tsx
📚 Learning: 2025-09-18T07:50:31.224Z
Learnt from: baktun14
Repo: akash-network/console PR: 1933
File: apps/deploy-web/src/components/onboarding/steps/PaymentVerificationCard/PaymentVerificationCard.tsx:43-63
Timestamp: 2025-09-18T07:50:31.224Z
Learning: PaymentVerificationCard component is wrapped by Stripe Elements provider in its parent component PaymentMethodStep, so PaymentMethodForm inside PaymentVerificationCard has access to Stripe context without needing its own Elements wrapper.

Applied to files:

  • apps/deploy-web/src/pages/payment.tsx
🧬 Code graph analysis (1)
apps/deploy-web/src/pages/payment.tsx (5)
apps/deploy-web/src/hooks/useFlag.tsx (1)
  • useFlag (8-8)
apps/deploy-web/src/hooks/useWalletBalance.ts (1)
  • useWalletBalance (36-77)
apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (2)
  • useWalletSettingsQuery (8-18)
  • useWalletSettingsMutations (20-56)
apps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsx (3)
  • DEFAULT_THRESHOLD (12-12)
  • DEFAULT_RELOAD_AMOUNT (13-13)
  • AutoReloadSettingsPopup (20-214)
apps/deploy-web/src/components/shared/PaymentMethodsList/PaymentMethodsList.tsx (1)
  • PaymentMethodsList (21-74)
⏰ 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). (7)
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: Validate local packages
🔇 Additional comments (3)
apps/deploy-web/src/pages/payment.tsx (3)

359-384: Auto‑reload payment methods and billing layout integration looks consistent

Using PaymentMethodsList in selectable mode plus a dedicated “Add New Payment Method” CTA, followed by the BillingContainer/BillingView section, keeps behavior and composition aligned with existing shared components; no functional issues stand out here.


393-463: Legacy payment flow preserved cleanly behind feature flag

The fallback branch for when isAutoCreditReloadEnabled is false retains the existing payment methods list, payment form, blockchain‑outage alert, and inline error handling, just restructured slightly—behavior appears unchanged and coherent.


486-496: Conditional rendering of new popups looks safe

PaymentPopup and AutoReloadSettingsPopup are both gated by their respective show* flags and receive minimal, focused props (including setShowPaymentSuccess for the top‑up flow), so they won’t mount unexpectedly and integrate cleanly with the page state.

@jzsfkzm jzsfkzm force-pushed the features/1779-auto-top-up-settings branch from 2ca6f36 to 1a5327e Compare November 27, 2025 16:04
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: 0

♻️ Duplicate comments (1)
apps/deploy-web/src/pages/payment.tsx (1)

353-353: Replace HTML entity with the actual character.

The &lt; HTML entity will render literally as "<" instead of "<" in JSX.

Apply this diff:

-                  Reload ${walletSettings?.autoReloadAmount || DEFAULT_RELOAD_AMOUNT} when &lt; ${walletSettings?.autoReloadThreshold || DEFAULT_THRESHOLD}
+                  Reload ${walletSettings?.autoReloadAmount || DEFAULT_RELOAD_AMOUNT} when < ${walletSettings?.autoReloadThreshold || DEFAULT_THRESHOLD}
🧹 Nitpick comments (2)
apps/deploy-web/src/components/user/payment/PaymentPopup.tsx (1)

1-260: Well-structured payment component with comprehensive error handling.

The component properly handles the payment flow including 3D Secure authentication, coupon application, validation, and error states. Error handling is thorough with try-catch blocks and user-friendly messages.

Consider extracting shared validation and payment logic into utility functions if the duplication with payment.tsx becomes a maintenance concern. The validation logic (lines 123-136) and error handling patterns are currently duplicated between this component and the payment page.

apps/deploy-web/src/pages/payment.tsx (1)

318-466: Feature flag gating and conditional rendering properly implemented.

The auto-reload UI path and traditional payment path are clearly separated via feature flag. The Switch component now correctly defaults to false when wallet settings haven't loaded (addressing previous feedback), and both UI paths are well-structured.

Consider extracting shared validation and payment logic into utility functions to reduce duplication between this page and PaymentPopup.tsx. The validation logic (lines 243-256), payment handling, and error handling patterns are duplicated but currently acceptable for component isolation.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2ca6f36 and 1a5327e.

📒 Files selected for processing (15)
  • apps/api/src/core/services/feature-flags/feature-flags.ts (1 hunks)
  • apps/deploy-web/src/components/shared/PaymentMethodsList/PaymentMethodsList.tsx (2 hunks)
  • apps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsx (1 hunks)
  • apps/deploy-web/src/components/user/payment/PaymentPopup.tsx (1 hunks)
  • apps/deploy-web/src/components/user/payment/index.ts (1 hunks)
  • apps/deploy-web/src/pages/payment.tsx (5 hunks)
  • apps/deploy-web/src/queries/index.ts (1 hunks)
  • apps/deploy-web/src/queries/queryKeys.ts (1 hunks)
  • apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx (1 hunks)
  • apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (1 hunks)
  • apps/deploy-web/src/services/app-di-container/app-di-container.ts (2 hunks)
  • apps/deploy-web/src/types/feature-flags.ts (1 hunks)
  • packages/http-sdk/src/index.ts (1 hunks)
  • packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (1 hunks)
  • packages/http-sdk/src/wallet-settings/wallet-settings.types.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (10)
  • packages/http-sdk/src/wallet-settings/wallet-settings.types.ts
  • apps/deploy-web/src/queries/useWalletSettingsQueries.tsx
  • packages/http-sdk/src/index.ts
  • apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx
  • apps/deploy-web/src/components/user/payment/index.ts
  • apps/deploy-web/src/queries/index.ts
  • packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts
  • apps/deploy-web/src/services/app-di-container/app-di-container.ts
  • apps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsx
  • apps/deploy-web/src/components/shared/PaymentMethodsList/PaymentMethodsList.tsx
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{ts,tsx,js}: Never use type any or cast to type any. Always define the proper TypeScript types.
Never use deprecated methods from libraries.
Don't add unnecessary comments to the code.

Files:

  • apps/api/src/core/services/feature-flags/feature-flags.ts
  • apps/deploy-web/src/pages/payment.tsx
  • apps/deploy-web/src/types/feature-flags.ts
  • apps/deploy-web/src/queries/queryKeys.ts
  • apps/deploy-web/src/components/user/payment/PaymentPopup.tsx
🧠 Learnings (5)
📚 Learning: 2025-07-28T10:40:13.595Z
Learnt from: stalniy
Repo: akash-network/console PR: 1480
File: apps/deploy-web/src/hooks/useFlag.tsx:0-0
Timestamp: 2025-07-28T10:40:13.595Z
Learning: In the Akash Network Console project, backend-specific feature flags are intentional and acceptable. The frontend FeatureFlag union type should only include flags that are actually used by the frontend, not all flags defined in the backend. Backend can have internal feature flags for backend-only functionality without requiring frontend synchronization.

Applied to files:

  • apps/api/src/core/services/feature-flags/feature-flags.ts
  • apps/deploy-web/src/types/feature-flags.ts
📚 Learning: 2025-11-12T16:36:02.543Z
Learnt from: baktun14
Repo: akash-network/console PR: 2203
File: apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx:161-168
Timestamp: 2025-11-12T16:36:02.543Z
Learning: In apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx, the organization field captured during payment method setup is internal metadata. Errors from stripe.updateCustomerOrganization should be logged to Sentry but not surfaced to users, and the flow should continue even if the organization update fails, as it's non-critical and not something users can fix.

Applied to files:

  • apps/deploy-web/src/pages/payment.tsx
  • apps/deploy-web/src/components/user/payment/PaymentPopup.tsx
📚 Learning: 2025-11-25T17:45:39.561Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/general.mdc:0-0
Timestamp: 2025-11-25T17:45:39.561Z
Learning: Applies to **/*.{ts,tsx,js} : Never use type `any` or cast to type `any`. Always define the proper TypeScript types.

Applied to files:

  • apps/deploy-web/src/pages/payment.tsx
📚 Learning: 2025-10-31T11:26:42.138Z
Learnt from: stalniy
Repo: akash-network/console PR: 2138
File: apps/api/src/billing/lib/batch-signing-client/batch-signing-client.service.ts:379-382
Timestamp: 2025-10-31T11:26:42.138Z
Learning: In TypeScript/JavaScript, the pattern of checking a cached value and then performing an async operation to fetch it without proper synchronization is race condition unsafe:
```typescript
private async getAddress() {
  if (!this.address) {
    this.address = await this.wallet.getFirstAddress();
  }
  return this.address;
}
```
Multiple concurrent calls can all pass the `if (!this.address)` check before any of them sets the value, leading to duplicate async operations. This should be flagged as a race condition. Proper synchronization (mutex, atomic promise caching, or guaranteed single-threaded execution) is required.

Applied to files:

  • apps/deploy-web/src/pages/payment.tsx
📚 Learning: 2025-09-18T07:50:31.224Z
Learnt from: baktun14
Repo: akash-network/console PR: 1933
File: apps/deploy-web/src/components/onboarding/steps/PaymentVerificationCard/PaymentVerificationCard.tsx:43-63
Timestamp: 2025-09-18T07:50:31.224Z
Learning: PaymentVerificationCard component is wrapped by Stripe Elements provider in its parent component PaymentMethodStep, so PaymentMethodForm inside PaymentVerificationCard has access to Stripe context without needing its own Elements wrapper.

Applied to files:

  • apps/deploy-web/src/pages/payment.tsx
  • apps/deploy-web/src/components/user/payment/PaymentPopup.tsx
🧬 Code graph analysis (1)
apps/deploy-web/src/pages/payment.tsx (8)
apps/deploy-web/src/hooks/useWalletBalance.ts (1)
  • useWalletBalance (36-77)
apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (2)
  • useWalletSettingsQuery (8-18)
  • useWalletSettingsMutations (20-56)
apps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsx (3)
  • DEFAULT_THRESHOLD (12-12)
  • DEFAULT_RELOAD_AMOUNT (13-13)
  • AutoReloadSettingsPopup (20-214)
apps/deploy-web/src/components/shared/PaymentMethodsList/PaymentMethodsList.tsx (1)
  • PaymentMethodsList (21-74)
apps/deploy-web/src/components/billing-usage/BillingContainer/BillingContainer.tsx (1)
  • BillingContainer (42-178)
apps/deploy-web/src/components/billing-usage/BillingView/BillingView.tsx (1)
  • BillingView (60-316)
apps/deploy-web/src/components/user/payment/PaymentForm.tsx (1)
  • PaymentForm (18-100)
apps/deploy-web/src/components/user/payment/PaymentPopup.tsx (1)
  • PaymentPopup (22-260)
⏰ 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). (7)
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: Validate local packages
🔇 Additional comments (6)
apps/deploy-web/src/queries/queryKeys.ts (1)

75-76: LGTM!

The new wallet settings query key follows the established pattern and is appropriately positioned alongside other payment-related keys.

apps/deploy-web/src/types/feature-flags.ts (1)

9-10: LGTM!

The new auto_credit_reload feature flag is properly added to the union type and aligns with its usage in the payment page UI.

apps/api/src/core/services/feature-flags/feature-flags.ts (1)

4-5: LGTM!

The new feature flag constant is properly defined and follows the existing naming convention. The trailing comma addition maintains formatting consistency.

apps/deploy-web/src/pages/payment.tsx (3)

39-61: LGTM!

The HalfBox component provides a clean abstraction for the auto-reload dashboard cards. The button variant type is now properly typed (correctly addressing the previous review feedback).


63-74: LGTM!

The WideBox component provides a consistent layout wrapper for the auto-reload dashboard sections.


276-301: LGTM!

The async callback now includes proper error handling with try-catch blocks and user feedback via snackbars for both success and failure cases, correctly addressing the previous review feedback.

@jzsfkzm jzsfkzm force-pushed the features/1779-auto-top-up-settings branch from 1a5327e to 0d62c20 Compare November 28, 2025 07:09
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

♻️ Duplicate comments (2)
apps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsx (1)

156-175: Fix label htmlFor / input id mismatches for accessibility

Both auto‑reload inputs have label htmlFor values that don’t match the corresponding input ids, breaking click‑to‑focus and screen‑reader association:

  • Label uses htmlFor="threshold-input" but input id="threshold".
  • Label uses htmlFor="reloadAmount-input" but input id="reloadAmount".

Align them as follows:

-              <Label htmlFor="threshold-input">
+              <Label htmlFor="threshold">
...
-                <Input
-                  id="threshold"
+                <Input
+                  id="threshold"
...
-              <Label htmlFor="reloadAmount-input">
+              <Label htmlFor="reloadAmount">
...
-                <Input
-                  id="reloadAmount"
+                <Input
+                  id="reloadAmount"

Also applies to: 182-199

apps/deploy-web/src/pages/payment.tsx (1)

353-353: Replace HTML entity with the actual character.

The &lt; HTML entity will render literally as "<" instead of "<" in JSX. Use the < character directly.

Apply this diff:

-                  Reload ${walletSettings?.autoReloadAmount || DEFAULT_RELOAD_AMOUNT} when &lt; ${walletSettings?.autoReloadThreshold || DEFAULT_THRESHOLD}
+                  Reload ${walletSettings?.autoReloadAmount || DEFAULT_RELOAD_AMOUNT} when < ${walletSettings?.autoReloadThreshold || DEFAULT_THRESHOLD}
🧹 Nitpick comments (7)
packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (1)

14-27: Specify generics on HTTP calls to avoid implicit any and tighten typing

Right now the get/post/put + extractApiData calls rely on default generics, effectively flowing any through the pipeline. To better align with the “no any” guideline and get compile‑time safety on response shapes, explicitly pass WalletSettings:

   async getWalletSettings(): Promise<WalletSettings> {
-    return this.extractApiData(await this.get("/v1/wallet-settings"));
+    const response = await this.get<WalletSettings>("/v1/wallet-settings");
+    return this.extractApiData<WalletSettings>(response);
   }

   async createWalletSettings(settings: WalletSettings): Promise<WalletSettings> {
-    return this.extractApiData(await this.post("/v1/wallet-settings", { data: settings }));
+    const response = await this.post<WalletSettings>("/v1/wallet-settings", { data: settings });
+    return this.extractApiData<WalletSettings>(response);
   }

   async updateWalletSettings(settings: UpdateWalletSettingsParams): Promise<WalletSettings> {
-    return this.extractApiData(await this.put("/v1/wallet-settings", { data: settings }));
+    const response = await this.put<WalletSettings>("/v1/wallet-settings", { data: settings });
+    return this.extractApiData<WalletSettings>(response);
   }
apps/deploy-web/src/components/user/payment/PaymentPopup.tsx (2)

55-69: Avoid sending an empty userId to the payment API

user?.id || "" means we can initiate a payment with an empty user id if the user is not yet loaded. That’s hard to recover from and will surface as a generic Stripe/API error.

Consider explicitly guarding and surfacing a clear UI error instead, and then passing a non‑nullable id:

   const onPayment = async (paymentMethodId: string) => {
-    if (!amount) return;
+    if (!amount) return;
+
+    if (!user?.id) {
+      console.error("Payment attempted without a user id");
+      setError("Unable to process payment. Please refresh the page and try again.");
+      return;
+    }

     // Capture the submitted amount before starting the payment flow
     submittedAmountRef.current = amount;
     clearError();

     try {
       const response = await confirmPayment({
-        userId: user?.id || "",
+        userId: user.id,
         paymentMethodId,
         amount: parseFloat(amount),
         currency: "usd"
       });

156-159: Optionally treat coupon application as part of the “processing” state

Currently isProcessing doesn’t include isApplyingCoupon, so a user can start a coupon request and immediately fire a payment (or vice versa). If you want to serialize these operations and simplify UX, you can fold coupon state into isProcessing:

-  const isProcessing = isConfirmingPayment || isPolling;
-  const disabled = !amount || parseFloat(amount) <= 0 || isProcessing || !selectedPaymentMethodId || !!amountError;
-  const disabledCoupon = !coupon || isProcessing || isApplyingCoupon;
+  const isProcessing = isConfirmingPayment || isPolling || isApplyingCoupon;
+  const disabled = !amount || parseFloat(amount) <= 0 || isProcessing || !selectedPaymentMethodId || !!amountError;
+  const disabledCoupon = !coupon || isProcessing;

This keeps the UX linear and avoids overlapping payment/coupon operations.

apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx (1)

1-203: Tests are correct; consider a setup helper and shallower imports for maintainability

The test flows and assertions look good, and they use jest-mock-extended as required. Two optional tweaks:

  • You repeat the walletSettingsService mock + setupQuery wiring in several tests. To align with the project’s “setup function” test pattern and reduce duplication, you could extract a small setup helper inside the useWalletSettingsQueries describe (ideally near the bottom of the block) that returns { result, walletSettingsService } with overridable method mocks.
  • The type imports reach into @akashnetwork/http-sdk/src/.... For better encapsulation against internal path changes, consider importing these from the package’s public entrypoint instead (e.g. @akashnetwork/http-sdk), if available.
apps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsx (1)

116-138: Disable “Save Changes” while initial settings are loading

While isLoading is true, you render a spinner but isPending is still false and hasSomethingToSave returns true (because walletSettings is undefined), so the “Save Changes” button is enabled and will create settings with default values even before the current settings are loaded.

To avoid accidental writes during initial load, you can fold isLoading into isPending:

-  const isPending = updateWalletSettings.isPending || createWalletSettings.isPending;
+  const isPending = isLoading || updateWalletSettings.isPending || createWalletSettings.isPending;

This will automatically keep the action disabled until the existing settings have been fetched.

apps/deploy-web/src/pages/payment.tsx (2)

276-301: Consider disabling the Switch during mutation to prevent multiple rapid toggles.

While the error handling is properly implemented, the handleReloadChange callback doesn't prevent rapid consecutive toggles. The user could click the Switch multiple times before the first mutation completes, potentially causing race conditions or confusing UI state.

Consider tracking mutation pending state and passing it to disable the Switch:

+  const isMutating = updateWalletSettings.isPending || createWalletSettings.isPending;
+
   // In render:
-  <Switch checked={walletSettings?.autoReloadEnabled ?? false} onCheckedChange={handleReloadChange} disabled={paymentMethods.length === 0} />
+  <Switch checked={walletSettings?.autoReloadEnabled ?? false} onCheckedChange={handleReloadChange} disabled={paymentMethods.length === 0 || isMutating} />

318-391: Consider adding blockchain outage alert to the auto-reload UI path.

The non-auto-reload path (lines 421-429) displays a blockchain outage warning when settings.isBlockchainDown is true, but the auto-reload path doesn't include this alert. Users making payments through this flow should also be informed about potential delays.

Consider adding the alert after the grid on line 357:

           </HalfBox>
         </div>
+
+        {settings.isBlockchainDown && (
+          <Alert variant="warning" className="mt-4">
+            <p className="font-medium">
+              We are currently experiencing a temporary blockchain outage, which may cause delays in processing your payments.
+            </p>
+          </Alert>
+        )}

         <WideBox title="Payment Methods">
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1a5327e and 0d62c20.

📒 Files selected for processing (15)
  • apps/api/src/core/services/feature-flags/feature-flags.ts (1 hunks)
  • apps/deploy-web/src/components/shared/PaymentMethodsList/PaymentMethodsList.tsx (2 hunks)
  • apps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsx (1 hunks)
  • apps/deploy-web/src/components/user/payment/PaymentPopup.tsx (1 hunks)
  • apps/deploy-web/src/components/user/payment/index.ts (1 hunks)
  • apps/deploy-web/src/pages/payment.tsx (5 hunks)
  • apps/deploy-web/src/queries/index.ts (1 hunks)
  • apps/deploy-web/src/queries/queryKeys.ts (1 hunks)
  • apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx (1 hunks)
  • apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (1 hunks)
  • apps/deploy-web/src/services/app-di-container/app-di-container.ts (2 hunks)
  • apps/deploy-web/src/types/feature-flags.ts (1 hunks)
  • packages/http-sdk/src/index.ts (1 hunks)
  • packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (1 hunks)
  • packages/http-sdk/src/wallet-settings/wallet-settings.types.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
  • apps/deploy-web/src/components/shared/PaymentMethodsList/PaymentMethodsList.tsx
  • packages/http-sdk/src/index.ts
  • apps/deploy-web/src/queries/useWalletSettingsQueries.tsx
  • apps/deploy-web/src/services/app-di-container/app-di-container.ts
  • apps/deploy-web/src/queries/queryKeys.ts
  • packages/http-sdk/src/wallet-settings/wallet-settings.types.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{ts,tsx,js}: Never use type any or cast to type any. Always define the proper TypeScript types.
Never use deprecated methods from libraries.
Don't add unnecessary comments to the code.

Files:

  • apps/api/src/core/services/feature-flags/feature-flags.ts
  • apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx
  • apps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsx
  • apps/deploy-web/src/components/user/payment/PaymentPopup.tsx
  • apps/deploy-web/src/components/user/payment/index.ts
  • packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts
  • apps/deploy-web/src/queries/index.ts
  • apps/deploy-web/src/types/feature-flags.ts
  • apps/deploy-web/src/pages/payment.tsx
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/no-jest-mock.mdc)

Don't use jest.mock() in test files. Instead, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test

Use setup function instead of beforeEach in test files. The setup function must be at the bottom of the root describe block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type.

**/*.spec.{ts,tsx}: Use <Subject>.name in the root describe suite description instead of hardcoded class/service name strings to enable automated refactoring tools to find all references
Use either a method name or a condition starting with 'when' for nested suite descriptions in tests
Use present simple, 3rd person singular for test descriptions without prepending 'should'

Files:

  • apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx
{apps/deploy-web,apps/provider-console}/**/*.spec.tsx

📄 CodeRabbit inference engine (.cursor/rules/query-by-in-tests.mdc)

Use queryBy methods instead of getBy methods in test expectations

Files:

  • apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx
🧠 Learnings (8)
📚 Learning: 2025-07-28T10:40:13.595Z
Learnt from: stalniy
Repo: akash-network/console PR: 1480
File: apps/deploy-web/src/hooks/useFlag.tsx:0-0
Timestamp: 2025-07-28T10:40:13.595Z
Learning: In the Akash Network Console project, backend-specific feature flags are intentional and acceptable. The frontend FeatureFlag union type should only include flags that are actually used by the frontend, not all flags defined in the backend. Backend can have internal feature flags for backend-only functionality without requiring frontend synchronization.

Applied to files:

  • apps/api/src/core/services/feature-flags/feature-flags.ts
  • apps/deploy-web/src/types/feature-flags.ts
📚 Learning: 2025-10-15T16:39:55.348Z
Learnt from: jzsfkzm
Repo: akash-network/console PR: 2039
File: apps/deploy-web/tests/ui/change-wallets.spec.ts:4-10
Timestamp: 2025-10-15T16:39:55.348Z
Learning: In the Akash Console E2E tests using the context-with-extension fixture, the first wallet is automatically created during fixture setup via `importWalletToLeap` in `apps/deploy-web/tests/ui/fixture/wallet-setup.ts`, so tests that call `frontPage.createWallet()` are creating a second wallet to test wallet switching functionality.

Applied to files:

  • apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx
📚 Learning: 2025-11-25T17:45:49.180Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/query-by-in-tests.mdc:0-0
Timestamp: 2025-11-25T17:45:49.180Z
Learning: Applies to {apps/deploy-web,apps/provider-console}/**/*.spec.tsx : Use `queryBy` methods instead of `getBy` methods in test expectations

Applied to files:

  • apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx
📚 Learning: 2025-11-19T15:15:07.283Z
Learnt from: ygrishajev
Repo: akash-network/console PR: 2254
File: apps/api/test/functional/sign-and-broadcast-tx.spec.ts:4-4
Timestamp: 2025-11-19T15:15:07.283Z
Learning: In the Akash Network Console project, when tests use native Node.js fetch (available in Node 18+), fetch-mock should be used for HTTP mocking instead of nock, as nock does not support intercepting native fetch calls. This applies to apps/api/test/functional/sign-and-broadcast-tx.spec.ts and any other tests using native fetch.

Applied to files:

  • apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx
📚 Learning: 2025-11-12T16:36:02.543Z
Learnt from: baktun14
Repo: akash-network/console PR: 2203
File: apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx:161-168
Timestamp: 2025-11-12T16:36:02.543Z
Learning: In apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx, the organization field captured during payment method setup is internal metadata. Errors from stripe.updateCustomerOrganization should be logged to Sentry but not surfaced to users, and the flow should continue even if the organization update fails, as it's non-critical and not something users can fix.

Applied to files:

  • apps/deploy-web/src/components/user/payment/PaymentPopup.tsx
  • apps/deploy-web/src/pages/payment.tsx
📚 Learning: 2025-09-18T07:50:31.224Z
Learnt from: baktun14
Repo: akash-network/console PR: 1933
File: apps/deploy-web/src/components/onboarding/steps/PaymentVerificationCard/PaymentVerificationCard.tsx:43-63
Timestamp: 2025-09-18T07:50:31.224Z
Learning: PaymentVerificationCard component is wrapped by Stripe Elements provider in its parent component PaymentMethodStep, so PaymentMethodForm inside PaymentVerificationCard has access to Stripe context without needing its own Elements wrapper.

Applied to files:

  • apps/deploy-web/src/components/user/payment/PaymentPopup.tsx
  • apps/deploy-web/src/pages/payment.tsx
📚 Learning: 2025-11-25T17:45:39.561Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/general.mdc:0-0
Timestamp: 2025-11-25T17:45:39.561Z
Learning: Applies to **/*.{ts,tsx,js} : Never use type `any` or cast to type `any`. Always define the proper TypeScript types.

Applied to files:

  • apps/deploy-web/src/pages/payment.tsx
📚 Learning: 2025-10-31T11:26:42.138Z
Learnt from: stalniy
Repo: akash-network/console PR: 2138
File: apps/api/src/billing/lib/batch-signing-client/batch-signing-client.service.ts:379-382
Timestamp: 2025-10-31T11:26:42.138Z
Learning: In TypeScript/JavaScript, the pattern of checking a cached value and then performing an async operation to fetch it without proper synchronization is race condition unsafe:
```typescript
private async getAddress() {
  if (!this.address) {
    this.address = await this.wallet.getFirstAddress();
  }
  return this.address;
}
```
Multiple concurrent calls can all pass the `if (!this.address)` check before any of them sets the value, leading to duplicate async operations. This should be flagged as a race condition. Proper synchronization (mutex, atomic promise caching, or guaranteed single-threaded execution) is required.

Applied to files:

  • apps/deploy-web/src/pages/payment.tsx
🧬 Code graph analysis (3)
apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx (3)
apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (2)
  • useWalletSettingsQuery (8-18)
  • useWalletSettingsMutations (20-56)
packages/http-sdk/src/wallet-settings/wallet-settings.types.ts (2)
  • WalletSettings (1-5)
  • UpdateWalletSettingsParams (11-15)
packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (1)
  • WalletSettingsHttpService (9-29)
apps/deploy-web/src/components/user/payment/PaymentPopup.tsx (8)
apps/deploy-web/src/hooks/useUser.ts (1)
  • useUser (7-20)
apps/deploy-web/src/queries/usePaymentQueries.ts (1)
  • usePaymentMutations (55-112)
apps/deploy-web/src/hooks/use3DSecure.ts (1)
  • use3DSecure (30-125)
packages/ui/components/custom/snackbar.tsx (1)
  • Snackbar (18-37)
apps/deploy-web/src/utils/stripeErrorHandler.ts (1)
  • handleCouponError (203-221)
packages/ui/components/input.tsx (1)
  • Input (123-123)
packages/ui/components/loading-button.tsx (1)
  • LoadingButton (41-41)
packages/ui/components/button.tsx (1)
  • Button (46-46)
packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (2)
packages/http-sdk/src/api-http/api-http.service.ts (1)
  • ApiHttpService (9-29)
packages/http-sdk/src/wallet-settings/wallet-settings.types.ts (2)
  • WalletSettings (1-5)
  • UpdateWalletSettingsParams (11-15)
⏰ 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). (7)
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: Validate local packages
🔇 Additional comments (10)
apps/deploy-web/src/queries/index.ts (1)

8-8: Barrel re‑export looks consistent

export * from "./useWalletSettingsQueries"; follows the existing query barrel pattern and cleanly exposes the new hooks.

apps/deploy-web/src/components/user/payment/index.ts (1)

2-2: Public export wiring for AutoReloadSettingsPopup is correct

The new export aligns with the existing payment component barrel and makes the popup available to consumers.

apps/deploy-web/src/types/feature-flags.ts (1)

9-10: New frontend feature flags are aligned with usage

Adding "maintenance_banner" and "auto_credit_reload" to the FeatureFlag union is consistent with the pattern of only exposing flags actually used in the frontend (the payment page consumes auto_credit_reload). Based on learnings, backend‑only flags remain separated, which is good.

apps/api/src/core/services/feature-flags/feature-flags.ts (1)

4-6: Backend flag definition matches frontend usage

AUTO_CREDIT_RELOAD: "auto_credit_reload" is consistent with the frontend FeatureFlag union and the payment page’s use of useFlag("auto_credit_reload"), keeping flag values synchronized.

apps/deploy-web/src/pages/payment.tsx (6)

1-35: LGTM!

Imports are well-organized and all appear to be utilized in the component.


39-61: LGTM!

The HalfBox component is properly typed with explicit prop types, addressing the previous any type concern. The component structure is clean and follows React patterns.


63-75: LGTM!

Simple and clean container component.


76-116: LGTM!

The new hooks and state management for the auto-reload feature are properly integrated following existing patterns in the component.


392-466: LGTM!

The fallback (non-auto-reload) UI path maintains the existing functionality with proper error handling and blockchain outage alerts.


486-496: LGTM!

The new PaymentPopup and AutoReloadSettingsPopup components are properly integrated with conditional rendering.

@jzsfkzm jzsfkzm force-pushed the features/1779-auto-top-up-settings branch from 0d62c20 to fac1e7b Compare November 28, 2025 09:06
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/deploy-web/src/pages/payment.tsx (1)

243-256: Add NaN check to amount validation.

Similar to the issue in PaymentPopup, this validation doesn't check for NaN. When parseFloat returns NaN, both comparisons fail and amountError is incorrectly cleared.

Apply this diff:

   const validateAmount = (value: number) => {
+    if (isNaN(value)) {
+      setAmountError("Please enter a valid amount");
+      return false;
+    }
+
     if (value <= 0) {
       setAmountError("Amount must be greater than $0");
       return false;
     }
♻️ Duplicate comments (3)
apps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsx (2)

76-79: Prevent storing NaN in state.

Same issue as onThresholdChange - calling setReloadAmount(parseFloat(e.target.value)) can store NaN when input is invalid.

Apply this diff:

   const onReloadAmountChange = (e: React.ChangeEvent<HTMLInputElement>) => {
-    validateReloadAmount(e.target.value);
-    setReloadAmount(parseFloat(e.target.value));
+    const value = e.target.value;
+    if (validateReloadAmount(value)) {
+      setReloadAmount(parseFloat(value));
+    }
   };

55-58: Prevent storing NaN in state.

The handler calls setThreshold(parseFloat(e.target.value)) regardless of validation result. If the input is empty or invalid, parseFloat returns NaN, which gets stored and could be sent to the API.

Apply this diff:

   const onThresholdChange = (e: React.ChangeEvent<HTMLInputElement>) => {
-    validateThreshold(e.target.value);
-    setThreshold(parseFloat(e.target.value));
+    const value = e.target.value;
+    if (validateThreshold(value)) {
+      setThreshold(parseFloat(value));
+    }
   };
apps/deploy-web/src/pages/payment.tsx (1)

357-357: Replace HTML entity with the actual character.

The &lt; HTML entity in the template literal will render literally as "<" instead of "<". This is a past review comment that was marked but not yet addressed.

Apply this diff:

-                  Reload ${walletSettings?.autoReloadAmount || DEFAULT_RELOAD_AMOUNT} when &lt; ${walletSettings?.autoReloadThreshold || DEFAULT_THRESHOLD}
+                  Reload ${walletSettings?.autoReloadAmount || DEFAULT_RELOAD_AMOUNT} when < ${walletSettings?.autoReloadThreshold || DEFAULT_THRESHOLD}
🧹 Nitpick comments (1)
packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (1)

7-9: Remove unnecessary constructor.

The constructor only calls super(config) with the same argument, which is the default behavior. You can safely remove it.

Apply this diff:

 export class WalletSettingsHttpService extends ApiHttpService {
-  constructor(config?: AxiosRequestConfig) {
-    super(config);
-  }
-
   async getWalletSettings() {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0d62c20 and fac1e7b.

📒 Files selected for processing (4)
  • apps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsx (1 hunks)
  • apps/deploy-web/src/components/user/payment/PaymentPopup.tsx (1 hunks)
  • apps/deploy-web/src/pages/payment.tsx (5 hunks)
  • packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{ts,tsx,js}: Never use type any or cast to type any. Always define the proper TypeScript types.
Never use deprecated methods from libraries.
Don't add unnecessary comments to the code.

Files:

  • packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts
  • apps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsx
  • apps/deploy-web/src/components/user/payment/PaymentPopup.tsx
  • apps/deploy-web/src/pages/payment.tsx
🧠 Learnings (4)
📚 Learning: 2025-11-12T16:36:02.543Z
Learnt from: baktun14
Repo: akash-network/console PR: 2203
File: apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx:161-168
Timestamp: 2025-11-12T16:36:02.543Z
Learning: In apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx, the organization field captured during payment method setup is internal metadata. Errors from stripe.updateCustomerOrganization should be logged to Sentry but not surfaced to users, and the flow should continue even if the organization update fails, as it's non-critical and not something users can fix.

Applied to files:

  • apps/deploy-web/src/components/user/payment/PaymentPopup.tsx
  • apps/deploy-web/src/pages/payment.tsx
📚 Learning: 2025-09-18T07:50:31.224Z
Learnt from: baktun14
Repo: akash-network/console PR: 1933
File: apps/deploy-web/src/components/onboarding/steps/PaymentVerificationCard/PaymentVerificationCard.tsx:43-63
Timestamp: 2025-09-18T07:50:31.224Z
Learning: PaymentVerificationCard component is wrapped by Stripe Elements provider in its parent component PaymentMethodStep, so PaymentMethodForm inside PaymentVerificationCard has access to Stripe context without needing its own Elements wrapper.

Applied to files:

  • apps/deploy-web/src/components/user/payment/PaymentPopup.tsx
  • apps/deploy-web/src/pages/payment.tsx
📚 Learning: 2025-11-25T17:45:39.561Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/general.mdc:0-0
Timestamp: 2025-11-25T17:45:39.561Z
Learning: Applies to **/*.{ts,tsx,js} : Never use type `any` or cast to type `any`. Always define the proper TypeScript types.

Applied to files:

  • apps/deploy-web/src/pages/payment.tsx
📚 Learning: 2025-10-31T11:26:42.138Z
Learnt from: stalniy
Repo: akash-network/console PR: 2138
File: apps/api/src/billing/lib/batch-signing-client/batch-signing-client.service.ts:379-382
Timestamp: 2025-10-31T11:26:42.138Z
Learning: In TypeScript/JavaScript, the pattern of checking a cached value and then performing an async operation to fetch it without proper synchronization is race condition unsafe:
```typescript
private async getAddress() {
  if (!this.address) {
    this.address = await this.wallet.getFirstAddress();
  }
  return this.address;
}
```
Multiple concurrent calls can all pass the `if (!this.address)` check before any of them sets the value, leading to duplicate async operations. This should be flagged as a race condition. Proper synchronization (mutex, atomic promise caching, or guaranteed single-threaded execution) is required.

Applied to files:

  • apps/deploy-web/src/pages/payment.tsx
🧬 Code graph analysis (2)
apps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsx (8)
apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (2)
  • useWalletSettingsQuery (8-18)
  • useWalletSettingsMutations (20-56)
packages/http-sdk/src/wallet-settings/wallet-settings.types.ts (1)
  • WalletSettings (1-5)
packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (2)
  • updateWalletSettings (19-21)
  • createWalletSettings (15-17)
packages/ui/components/custom/snackbar.tsx (1)
  • Snackbar (18-37)
packages/ui/components/label.tsx (1)
  • Label (17-17)
packages/ui/components/switch.tsx (1)
  • Switch (52-52)
packages/ui/components/input.tsx (1)
  • Input (123-123)
packages/ui/components/alert/alert.tsx (1)
  • AlertTitle (39-39)
apps/deploy-web/src/pages/payment.tsx (10)
apps/deploy-web/src/hooks/useFlag.tsx (1)
  • useFlag (8-8)
apps/deploy-web/src/hooks/useWalletBalance.ts (1)
  • useWalletBalance (36-77)
apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (2)
  • useWalletSettingsQuery (8-18)
  • useWalletSettingsMutations (20-56)
apps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsx (3)
  • DEFAULT_THRESHOLD (12-12)
  • DEFAULT_RELOAD_AMOUNT (13-13)
  • AutoReloadSettingsPopup (20-222)
packages/ui/components/spinner.tsx (1)
  • Spinner (10-39)
apps/deploy-web/src/components/shared/PaymentMethodsList/PaymentMethodsList.tsx (1)
  • PaymentMethodsList (21-74)
apps/deploy-web/src/components/billing-usage/BillingContainer/BillingContainer.tsx (1)
  • BillingContainer (42-178)
apps/deploy-web/src/components/billing-usage/BillingView/BillingView.tsx (1)
  • BillingView (60-316)
apps/deploy-web/src/components/user/payment/PaymentForm.tsx (1)
  • PaymentForm (18-100)
apps/deploy-web/src/components/user/payment/PaymentPopup.tsx (1)
  • PaymentPopup (22-266)
⏰ 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). (7)
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: Validate local packages

Copy link
Contributor

@ygrishajev ygrishajev left a comment

Choose a reason for hiding this comment

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

UI looks great! could you pls also address the comments 🙏

@jzsfkzm jzsfkzm force-pushed the features/1779-auto-top-up-settings branch from fac1e7b to 99b1bac Compare December 4, 2025 12:46
@jzsfkzm jzsfkzm changed the title feat: payment page with auto-top-up settings feat: account overview, auto reload, and separate payment method page Dec 4, 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: 9

🧹 Nitpick comments (2)
packages/http-sdk/src/stripe/stripe.types.ts (1)

39-39: Consider using a more specific type for funding.

The funding field is currently typed as string, but Stripe's API defines it more narrowly. Consider using a union type for better type safety:

-    funding: string;
+    funding: "credit" | "debit" | "prepaid" | "unknown";

This provides compile-time safety when handling funding types.

apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx (1)

4-4: Remove unused empty import.

This empty import statement serves no purpose and should be removed.

Apply this diff:

 import { FormattedNumber } from "react-intl";
 import { Button, Card, CardContent, CardFooter, CardHeader, CardTitle, Snackbar, Switch } from "@akashnetwork/ui/components";
-import {} from "@akashnetwork/ui/components";
 import { LinearProgress } from "@mui/material";
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fac1e7b and 99b1bac.

📒 Files selected for processing (28)
  • apps/api/src/core/services/feature-flags/feature-flags.ts (1 hunks)
  • apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/BillingPage.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/BillingUsageLayout.tsx (3 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsPage.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (1 hunks)
  • apps/deploy-web/src/pages/payment-methods/index.tsx (1 hunks)
  • apps/deploy-web/src/queries/index.ts (1 hunks)
  • apps/deploy-web/src/queries/queryKeys.ts (1 hunks)
  • apps/deploy-web/src/queries/usePaymentQueries.ts (1 hunks)
  • apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx (1 hunks)
  • apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (1 hunks)
  • apps/deploy-web/src/services/app-di-container/app-di-container.ts (2 hunks)
  • apps/deploy-web/src/types/feature-flags.ts (1 hunks)
  • apps/deploy-web/src/utils/urlUtils.ts (1 hunks)
  • apps/deploy-web/tests/seeders/payment.ts (2 hunks)
  • packages/http-sdk/src/index.ts (1 hunks)
  • packages/http-sdk/src/stripe/stripe.service.ts (2 hunks)
  • packages/http-sdk/src/stripe/stripe.types.ts (2 hunks)
  • packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (1 hunks)
  • packages/http-sdk/src/wallet-settings/wallet-settings.types.ts (1 hunks)
  • packages/ui/components/badge.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/http-sdk/src/index.ts
  • apps/deploy-web/src/queries/queryKeys.ts
  • packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts
  • apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{ts,tsx,js}: Never use type any or cast to type any. Always define the proper TypeScript types.
Never use deprecated methods from libraries.
Don't add unnecessary comments to the code.

Files:

  • apps/deploy-web/src/components/billing-usage/BillingUsageLayout.tsx
  • apps/deploy-web/src/queries/index.ts
  • packages/http-sdk/src/stripe/stripe.types.ts
  • apps/deploy-web/src/utils/urlUtils.ts
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
  • apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx
  • apps/deploy-web/src/pages/payment-methods/index.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx
  • apps/deploy-web/src/queries/usePaymentQueries.ts
  • packages/http-sdk/src/wallet-settings/wallet-settings.types.ts
  • apps/deploy-web/src/types/feature-flags.ts
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
  • apps/deploy-web/tests/seeders/payment.ts
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsPage.tsx
  • apps/deploy-web/src/queries/useWalletSettingsQueries.tsx
  • packages/http-sdk/src/stripe/stripe.service.ts
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx
  • apps/deploy-web/src/components/billing-usage/BillingPage.tsx
  • apps/api/src/core/services/feature-flags/feature-flags.ts
  • packages/ui/components/badge.tsx
  • apps/deploy-web/src/services/app-di-container/app-di-container.ts
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/no-jest-mock.mdc)

Don't use jest.mock() in test files. Instead, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test

Use setup function instead of beforeEach in test files. The setup function must be at the bottom of the root describe block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type.

**/*.spec.{ts,tsx}: Use <Subject>.name in the root describe suite description instead of hardcoded class/service name strings to enable automated refactoring tools to find all references
Use either a method name or a condition starting with 'when' for nested suite descriptions in tests
Use present simple, 3rd person singular for test descriptions without prepending 'should'

Files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
{apps/deploy-web,apps/provider-console}/**/*.spec.tsx

📄 CodeRabbit inference engine (.cursor/rules/query-by-in-tests.mdc)

Use queryBy methods instead of getBy methods in test expectations

Files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
🧠 Learnings (7)
📚 Learning: 2025-11-25T17:45:49.180Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/query-by-in-tests.mdc:0-0
Timestamp: 2025-11-25T17:45:49.180Z
Learning: Applies to {apps/deploy-web,apps/provider-console}/**/*.spec.tsx : Use `queryBy` methods instead of `getBy` methods in test expectations

Applied to files:

  • apps/deploy-web/src/queries/index.ts
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
📚 Learning: 2025-11-25T17:45:44.790Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/no-jest-mock.mdc:0-0
Timestamp: 2025-11-25T17:45:44.790Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use `jest.mock()` in test files. Instead, use `jest-mock-extended` to create mocks and pass mocks as dependencies to the service under test

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
📚 Learning: 2025-11-25T17:45:52.965Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-11-25T17:45:52.965Z
Learning: Applies to **/*.spec.{ts,tsx} : Use `setup` function instead of `beforeEach` in test files. The `setup` function must be at the bottom of the root `describe` block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
  • apps/deploy-web/tests/seeders/payment.ts
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
📚 Learning: 2025-11-12T16:36:02.543Z
Learnt from: baktun14
Repo: akash-network/console PR: 2203
File: apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx:161-168
Timestamp: 2025-11-12T16:36:02.543Z
Learning: In apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx, the organization field captured during payment method setup is internal metadata. Errors from stripe.updateCustomerOrganization should be logged to Sentry but not surfaced to users, and the flow should continue even if the organization update fails, as it's non-critical and not something users can fix.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
  • apps/deploy-web/src/pages/payment-methods/index.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
📚 Learning: 2025-09-18T07:50:31.224Z
Learnt from: baktun14
Repo: akash-network/console PR: 1933
File: apps/deploy-web/src/components/onboarding/steps/PaymentVerificationCard/PaymentVerificationCard.tsx:43-63
Timestamp: 2025-09-18T07:50:31.224Z
Learning: PaymentVerificationCard component is wrapped by Stripe Elements provider in its parent component PaymentMethodStep, so PaymentMethodForm inside PaymentVerificationCard has access to Stripe context without needing its own Elements wrapper.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx
📚 Learning: 2025-07-28T10:40:13.595Z
Learnt from: stalniy
Repo: akash-network/console PR: 1480
File: apps/deploy-web/src/hooks/useFlag.tsx:0-0
Timestamp: 2025-07-28T10:40:13.595Z
Learning: In the Akash Network Console project, backend-specific feature flags are intentional and acceptable. The frontend FeatureFlag union type should only include flags that are actually used by the frontend, not all flags defined in the backend. Backend can have internal feature flags for backend-only functionality without requiring frontend synchronization.

Applied to files:

  • apps/deploy-web/src/types/feature-flags.ts
  • apps/api/src/core/services/feature-flags/feature-flags.ts
📚 Learning: 2025-10-15T16:39:55.348Z
Learnt from: jzsfkzm
Repo: akash-network/console PR: 2039
File: apps/deploy-web/tests/ui/change-wallets.spec.ts:4-10
Timestamp: 2025-10-15T16:39:55.348Z
Learning: In the Akash Console E2E tests using the context-with-extension fixture, the first wallet is automatically created during fixture setup via `importWalletToLeap` in `apps/deploy-web/tests/ui/fixture/wallet-setup.ts`, so tests that call `frontPage.createWallet()` are creating a second wallet to test wallet switching functionality.

Applied to files:

  • apps/deploy-web/src/services/app-di-container/app-di-container.ts
🧬 Code graph analysis (12)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx (4)
packages/http-sdk/src/stripe/stripe.types.ts (2)
  • SetupIntentResponse (68-70)
  • PaymentMethod (30-43)
apps/deploy-web/tests/seeders/payment.ts (1)
  • createMockPaymentMethod (3-22)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (1)
  • DEPENDENCIES (18-27)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (2)
  • DEPENDENCIES (9-20)
  • PaymentMethodsView (35-103)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (9)
apps/deploy-web/src/hooks/useUser.ts (1)
  • useUser (7-20)
apps/deploy-web/src/queries/usePaymentQueries.ts (1)
  • usePaymentMutations (55-123)
apps/deploy-web/src/hooks/use3DSecure.ts (1)
  • use3DSecure (30-125)
packages/ui/components/custom/snackbar.tsx (1)
  • Snackbar (18-37)
apps/deploy-web/src/utils/stripeErrorHandler.ts (1)
  • handleCouponError (203-221)
packages/ui/components/form.tsx (2)
  • Form (133-133)
  • FormField (133-133)
packages/ui/components/input.tsx (1)
  • FormInput (123-123)
packages/ui/components/loading-button.tsx (1)
  • LoadingButton (41-41)
packages/ui/components/button.tsx (1)
  • Button (46-46)
apps/deploy-web/src/pages/payment-methods/index.tsx (5)
apps/deploy-web/src/hoc/guard/guard.hoc.tsx (2)
  • Guard (9-29)
  • composeGuards (31-44)
apps/deploy-web/src/components/billing-usage/PaymentMethodsPage.tsx (1)
  • PaymentMethodsPage (9-18)
apps/deploy-web/src/hooks/useUser.ts (1)
  • useIsRegisteredUser (22-29)
apps/deploy-web/src/lib/nextjs/defineServerSideProps/defineServerSideProps.ts (1)
  • defineServerSideProps (44-92)
apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.ts (1)
  • isFeatureEnabled (6-8)
apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx (2)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (2)
  • DEPENDENCIES (9-20)
  • PaymentMethodsViewProps (22-33)
packages/http-sdk/src/stripe/stripe.service.ts (3)
  • createSetupIntent (24-26)
  • setPaymentMethodAsDefault (56-58)
  • removePaymentMethod (32-34)
apps/deploy-web/src/queries/usePaymentQueries.ts (1)
packages/http-sdk/src/stripe/stripe.service.ts (1)
  • setPaymentMethodAsDefault (56-58)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx (3)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (1)
  • PaymentMethodsRow (37-133)
apps/deploy-web/tests/seeders/payment.ts (1)
  • createMockPaymentMethod (3-22)
packages/http-sdk/src/stripe/stripe.types.ts (1)
  • PaymentMethod (30-43)
apps/deploy-web/src/components/billing-usage/PaymentMethodsPage.tsx (4)
apps/provider-console/src/components/layout/Layout.tsx (1)
  • Layout (22-43)
apps/deploy-web/src/components/billing-usage/BillingUsageLayout.tsx (1)
  • BillingUsageLayout (25-65)
apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx (1)
  • PaymentMethodsContainer (17-57)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (1)
  • PaymentMethodsView (35-103)
apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (3)
packages/http-sdk/src/wallet-settings/wallet-settings.types.ts (2)
  • WalletSettings (1-3)
  • UpdateWalletSettingsParams (9-11)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
  • useServices (30-32)
packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (3)
  • updateWalletSettings (19-21)
  • createWalletSettings (15-17)
  • deleteWalletSettings (23-25)
packages/http-sdk/src/stripe/stripe.service.ts (3)
packages/http-sdk/src/stripe/stripe.types.ts (2)
  • SetPaymentMethodAsDefaultParams (118-120)
  • PaymentMethod (30-43)
apps/api/src/billing/http-schemas/stripe.schema.ts (1)
  • PaymentMethod (236-236)
apps/api/src/billing/services/stripe/stripe.service.ts (1)
  • PaymentMethod (35-35)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (2)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (1)
  • DEPENDENCIES (18-27)
packages/http-sdk/src/stripe/stripe.types.ts (2)
  • PaymentMethod (30-43)
  • SetupIntentResponse (68-70)
apps/deploy-web/src/components/billing-usage/BillingPage.tsx (3)
apps/deploy-web/src/hooks/useFlag.tsx (1)
  • useFlag (8-8)
apps/deploy-web/src/components/billing-usage/BillingUsageLayout.tsx (1)
  • BillingUsageLayout (25-65)
apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx (1)
  • AccountOverview (16-147)
apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx (5)
apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx (1)
  • PaymentMethodsContainer (17-57)
apps/deploy-web/tests/seeders/payment.ts (1)
  • createMockPaymentMethod (3-22)
apps/deploy-web/src/queries/usePaymentQueries.ts (3)
  • usePaymentMethodsQuery (15-25)
  • usePaymentMutations (55-123)
  • useSetupIntentMutation (45-53)
apps/deploy-web/tests/unit/container-testing-child-capturer.tsx (1)
  • createContainerTestingChildCapturer (25-27)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (1)
  • PaymentMethodsViewProps (22-33)
⏰ 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). (10)
  • GitHub Check: validate (apps/deploy-web) / validate-unsafe
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: Validate local packages
🔇 Additional comments (23)
apps/api/src/core/services/feature-flags/feature-flags.ts (1)

4-5: LGTM!

The new feature flag follows the existing naming conventions and patterns. The trailing comma on line 4 is good practice for future additions.

apps/deploy-web/tests/seeders/payment.ts (3)

11-12: LGTM!

The additional card fields (fingerprint and funding) are properly randomized using Faker and align with the updated PaymentMethod types.


18-20: LGTM!

The new root-level fields are sensible defaults for test data. The validated and isDefault fields can be overridden via the overrides parameter when needed.


57-60: LGTM!

The new createMockSetupIntentResponse function provides a clean mock for setup intent responses, consistent with the existing pattern.

packages/http-sdk/src/stripe/stripe.types.ts (1)

118-120: LGTM!

The SetPaymentMethodAsDefaultParams interface is correctly defined with the required id field.

apps/deploy-web/src/queries/index.ts (1)

8-8: LGTM!

The new export follows the existing pattern and correctly exposes wallet settings queries through the central index.

apps/deploy-web/src/utils/urlUtils.ts (1)

41-41: LGTM!

The new paymentMethods() URL helper follows the established pattern and is logically placed alongside related billing URLs.

apps/deploy-web/src/components/billing-usage/BillingPage.tsx (3)

8-9: LGTM!

The imports are clean and necessary for the feature flag integration.


12-12: LGTM!

The feature flag check correctly uses the "auto_credit_reload" flag to control the visibility of auto-reload functionality.


18-18: LGTM!

The conditional rendering properly gates the AccountOverview component behind the feature flag, ensuring it only displays when auto-reload is enabled.

apps/deploy-web/src/types/feature-flags.ts (1)

9-10: LGTM!

The "auto_credit_reload" flag is correctly added to the frontend FeatureFlag union type and aligns with the backend flag definition. Based on learnings, this is appropriate since the flag is actively used in the frontend (e.g., BillingPage).

apps/deploy-web/src/queries/usePaymentQueries.ts (2)

106-114: LGTM!

The setPaymentMethodAsDefault mutation is well-structured, follows the existing pattern, and correctly invalidates the payment methods query on success to ensure the UI reflects the updated default status.


120-121: LGTM!

The new mutation is properly exported alongside the existing mutations, maintaining consistency with the hook's public API.

apps/deploy-web/src/components/billing-usage/BillingUsageLayout.tsx (1)

11-11: LGTM! Feature flag integration is well-implemented.

The conditional rendering of the Payment Methods tab based on the auto_credit_reload feature flag is correctly implemented. The grid layout dynamically adjusts between 2 and 3 columns, and the routing logic follows the existing pattern.

Also applies to: 27-27, 48-48, 52-56

apps/deploy-web/src/services/app-di-container/app-di-container.ts (1)

10-11: LGTM! DI container wiring follows established patterns.

The WalletSettingsHttpService is properly integrated into the DI container with the withUserToken interceptor applied, consistent with other authenticated services in the container.

Also applies to: 94-97

packages/http-sdk/src/stripe/stripe.service.ts (1)

56-58: LGTM! Method implementation follows service patterns.

The setPaymentMethodAsDefault method is correctly implemented, following the same patterns as other mutation methods in the service (e.g., confirmPayment, validatePaymentMethodAfter3DS).

apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx (1)

374-427: LGTM! Test setup function follows coding standards.

The setup function is correctly positioned at the bottom of the root describe block, accepts a single parameter with inline type definition, avoids shared state, and properly returns the test context without a specified return type.

apps/deploy-web/src/components/billing-usage/PaymentMethodsPage.tsx (1)

9-18: LGTM! Clean component composition.

The PaymentMethodsPage component properly composes the billing usage layout with the container-view pattern, integrating well with the feature-flagged tab structure.

apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx (1)

14-14: LGTM! Test suite follows coding standards.

The test suite correctly uses PaymentMethodsContainer.name for the root describe block and implements the setup function following all coding guidelines. Test coverage is comprehensive, covering data rendering, loading states, mutations, and state management.

Also applies to: 121-182

apps/deploy-web/src/pages/payment-methods/index.tsx (1)

8-13: LGTM! Proper page protection with layered guards.

The page implements proper protection with both server-side checks (authentication + feature flag) and client-side guards (managed wallet user + registered user), ensuring the payment methods page is only accessible when the auto_credit_reload feature is enabled for authenticated users.

packages/http-sdk/src/wallet-settings/wallet-settings.types.ts (1)

1-11: LGTM! Clean type definitions.

The wallet settings types are well-structured with clear interfaces for the settings data, response wrapper, and update parameters. The use of optional properties in UpdateWalletSettingsParams appropriately supports partial updates.

apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (1)

8-56: LGTM! Clean React Query implementation.

The hooks follow React Query best practices with proper typing, consistent query key usage, and cache invalidation on mutations.

apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (1)

35-103: LGTM! Well-structured view component.

The component follows the dependency injection pattern correctly, handles loading and empty states appropriately, and maintains proper type safety throughout.

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: 0

🧹 Nitpick comments (8)
apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx (1)

27-35: Remove unnecessary dependency from useEffect.

The selectedPaymentMethodId dependency is unnecessary since the effect only reads paymentMethods and sets selectedPaymentMethodId. Including it causes the effect to re-run whenever the state changes, which is redundant.

Apply this diff:

   useEffect(() => {
     if (paymentMethods.length > 0) {
       const defaultPaymentMethod = paymentMethods.find(method => method.isDefault);
 
       if (defaultPaymentMethod) {
         setSelectedPaymentMethodId(defaultPaymentMethod.id);
       }
     }
-  }, [paymentMethods, selectedPaymentMethodId]);
+  }, [paymentMethods]);
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx (1)

19-27: Avoid using any type for mock components and dependencies.

The mock components and mockDependencies object use any extensively, which violates the coding guidelines. Define proper types for mock component props to maintain type safety in tests.

Consider defining prop types for each mock:

-const MockPaymentMethodsRow = ({ paymentMethod, onSetPaymentMethodAsDefault, onRemovePaymentMethod, hasOtherPaymentMethods }: any) => (
+const MockPaymentMethodsRow = ({ paymentMethod, onSetPaymentMethodAsDefault, onRemovePaymentMethod, hasOtherPaymentMethods }: {
+  paymentMethod: PaymentMethod;
+  onSetPaymentMethodAsDefault: (id: string) => void;
+  onRemovePaymentMethod: (id: string) => void;
+  hasOtherPaymentMethods: boolean;
+}) => (

Similarly for other mock components, and type mockDependencies as typeof DEPENDENCIES instead of any.

Also applies to: 39-45, 47-58

apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (2)

46-61: Consider simplifying card and validUntil to useMemo.

These callbacks take paymentMethod as a parameter even though it's already in scope. Since they return JSX and are called with the same paymentMethod from props, they would be cleaner as useMemo values.

-  const card = useCallback((paymentMethod: PaymentMethod) => {
-    return (
-      <>
-        {capitalizeFirstLetter(paymentMethod.card?.brand || "")} {paymentMethod.card?.funding} **** {paymentMethod.card?.last4}
-      </>
-    );
-  }, []);
+  const cardLabel = useMemo(() => {
+    return `${capitalizeFirstLetter(paymentMethod.card?.brand || "")} ${paymentMethod.card?.funding} **** ${paymentMethod.card?.last4}`;
+  }, [paymentMethod.card?.brand, paymentMethod.card?.funding, paymentMethod.card?.last4]);

-  const validUntil = useCallback((paymentMethod: PaymentMethod) => {
-    const month = paymentMethod.card?.exp_month?.toString().padStart(2, "0");
-    return (
-      <>
-        {month}/{paymentMethod.card?.exp_year}
-      </>
-    );
-  }, []);
+  const validUntil = useMemo(() => {
+    const month = paymentMethod.card?.exp_month?.toString().padStart(2, "0");
+    return `${month}/${paymentMethod.card?.exp_year}`;
+  }, [paymentMethod.card?.exp_month, paymentMethod.card?.exp_year]);

Then update the JSX:

-        {card(paymentMethod)} {defaultBadge}
+        {cardLabel} {defaultBadge}
...
-        Valid until {validUntil(paymentMethod)}
+        Valid until {validUntil}

74-74: Narrow the useMemo dependency.

The defaultBadge memo depends on the entire paymentMethod object but only uses paymentMethod.isDefault. This causes unnecessary re-renders when other properties change.

-  }, [paymentMethod]);
+  }, [paymentMethod.isDefault]);
apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx (2)

6-10: Export DEPENDENCIES for test usage.

The DEPENDENCIES constant should be exported so tests can properly type the dependencies prop override.

-const DEPENDENCIES = {
+export const DEPENDENCIES = {
   usePaymentMethodsQuery,
   usePaymentMutations,
   useSetupIntentMutation
 };

37-40: Wrap onAddCardSuccess in useCallback for stable reference.

This callback is passed to children but isn't memoized, causing potential unnecessary re-renders of child components on each parent render.

-  const onAddCardSuccess = async () => {
+  const onAddCardSuccess = useCallback(async () => {
     setShowAddPaymentMethod(false);
-    refetchPaymentMethods();
-  };
+    await refetchPaymentMethods();
+  }, [refetchPaymentMethods]);
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx (2)

16-21: Global mutable state may cause test isolation issues.

The isDropdownOpen variable is module-level mutable state that persists between tests. While it appears to work due to how MockDropdownMenu updates it, this pattern can cause flaky tests if test execution order matters.

Consider using a ref or resetting the state in the setup function:

-let isDropdownOpen = false;
+// Use a container object to allow reset
+const dropdownState = { isOpen: false };

 const MockDropdownMenu = ({ children, modal: _modal, open }: any) => {
-  isDropdownOpen = open;
+  dropdownState.isOpen = open;
   return <div data-testid="dropdown-menu">{children}</div>;
 };

And reset in setup:

 function setup(...) {
+  dropdownState.isOpen = false;
   // ... rest of setup
 }

13-14: Avoid using any type for mock components.

Multiple mock components and mockDependencies use any type, violating the coding guidelines. Define proper prop types for mocks.

-const MockTableRow = ({ children, className }: any) => <tr className={className}>{children}</tr>;
+const MockTableRow = ({ children, className }: { children: React.ReactNode; className?: string }) => (
+  <tr className={className}>{children}</tr>
+);

Apply similar typing to other mock components and type mockDependencies properly.

Also applies to: 34-38, 56-61, 63-72

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 99b1bac and dc4e315.

📒 Files selected for processing (8)
  • apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (1 hunks)
  • packages/http-sdk/src/stripe/stripe.types.ts (2 hunks)
  • packages/ui/components/badge.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/http-sdk/src/stripe/stripe.types.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{ts,tsx,js}: Never use type any or cast to type any. Always define the proper TypeScript types.
Never use deprecated methods from libraries.
Don't add unnecessary comments to the code.

Files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
  • packages/ui/components/badge.tsx
  • apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/no-jest-mock.mdc)

Don't use jest.mock() in test files. Instead, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test

Use setup function instead of beforeEach in test files. The setup function must be at the bottom of the root describe block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type.

**/*.spec.{ts,tsx}: Use <Subject>.name in the root describe suite description instead of hardcoded class/service name strings to enable automated refactoring tools to find all references
Use either a method name or a condition starting with 'when' for nested suite descriptions in tests
Use present simple, 3rd person singular for test descriptions without prepending 'should'

Files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
{apps/deploy-web,apps/provider-console}/**/*.spec.tsx

📄 CodeRabbit inference engine (.cursor/rules/query-by-in-tests.mdc)

Use queryBy methods instead of getBy methods in test expectations

Files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
🧠 Learnings (10)
📓 Common learnings
Learnt from: baktun14
Repo: akash-network/console PR: 1725
File: apps/api/src/utils/constants.ts:5-5
Timestamp: 2025-07-24T17:00:52.361Z
Learning: In the Akash Network Console project, when cross-cutting concerns or broader refactoring issues are identified during PR review, the preferred approach is to create a separate GitHub issue to track the work rather than expanding the scope of the current PR. This maintains focus and allows for proper planning of architectural improvements.
📚 Learning: 2025-11-12T16:36:02.543Z
Learnt from: baktun14
Repo: akash-network/console PR: 2203
File: apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx:161-168
Timestamp: 2025-11-12T16:36:02.543Z
Learning: In apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx, the organization field captured during payment method setup is internal metadata. Errors from stripe.updateCustomerOrganization should be logged to Sentry but not surfaced to users, and the flow should continue even if the organization update fails, as it's non-critical and not something users can fix.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx
📚 Learning: 2025-09-18T07:50:31.224Z
Learnt from: baktun14
Repo: akash-network/console PR: 1933
File: apps/deploy-web/src/components/onboarding/steps/PaymentVerificationCard/PaymentVerificationCard.tsx:43-63
Timestamp: 2025-09-18T07:50:31.224Z
Learning: PaymentVerificationCard component is wrapped by Stripe Elements provider in its parent component PaymentMethodStep, so PaymentMethodForm inside PaymentVerificationCard has access to Stripe context without needing its own Elements wrapper.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx
📚 Learning: 2025-11-25T17:45:52.965Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-11-25T17:45:52.965Z
Learning: Applies to **/*.spec.{ts,tsx} : Use `setup` function instead of `beforeEach` in test files. The `setup` function must be at the bottom of the root `describe` block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
📚 Learning: 2025-11-25T17:45:44.790Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/no-jest-mock.mdc:0-0
Timestamp: 2025-11-25T17:45:44.790Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use `jest.mock()` in test files. Instead, use `jest-mock-extended` to create mocks and pass mocks as dependencies to the service under test

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
📚 Learning: 2025-11-25T17:45:49.180Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/query-by-in-tests.mdc:0-0
Timestamp: 2025-11-25T17:45:49.180Z
Learning: Applies to {apps/deploy-web,apps/provider-console}/**/*.spec.tsx : Use `queryBy` methods instead of `getBy` methods in test expectations

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
📚 Learning: 2025-07-11T10:46:43.711Z
Learnt from: stalniy
Repo: akash-network/console PR: 1660
File: apps/deploy-web/src/components/alerts/DeploymentAlertsContainer/DeploymentAlertsContainer.spec.tsx:54-56
Timestamp: 2025-07-11T10:46:43.711Z
Learning: In apps/{deploy-web,provider-console}/**/*.spec.tsx files: Use `getBy` methods instead of `queryBy` methods when testing element presence with `toBeInTheDocument()` because `getBy` throws an error and shows DOM state when element is not found, providing better debugging information than `queryBy` which returns null.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
📚 Learning: 2025-11-25T17:45:58.258Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/test-descriptions.mdc:0-0
Timestamp: 2025-11-25T17:45:58.258Z
Learning: Applies to **/*.spec.{ts,tsx} : Use either a method name or a condition starting with 'when' for nested suite descriptions in tests

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
📚 Learning: 2025-11-25T17:45:58.258Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/test-descriptions.mdc:0-0
Timestamp: 2025-11-25T17:45:58.258Z
Learning: Applies to **/*.spec.{ts,tsx} : Use present simple, 3rd person singular for test descriptions without prepending 'should'

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
📚 Learning: 2025-11-25T17:45:58.258Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/test-descriptions.mdc:0-0
Timestamp: 2025-11-25T17:45:58.258Z
Learning: Applies to **/*.spec.{ts,tsx} : Use `<Subject>.name` in the root describe suite description instead of hardcoded class/service name strings to enable automated refactoring tools to find all references

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
🧬 Code graph analysis (4)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (9)
apps/deploy-web/src/hooks/useUser.ts (1)
  • useUser (7-20)
apps/deploy-web/src/queries/usePaymentQueries.ts (1)
  • usePaymentMutations (55-123)
apps/deploy-web/src/hooks/use3DSecure.ts (1)
  • use3DSecure (30-125)
packages/ui/components/custom/snackbar.tsx (1)
  • Snackbar (18-37)
apps/deploy-web/src/utils/stripeErrorHandler.ts (1)
  • handleCouponError (203-221)
packages/ui/components/form.tsx (2)
  • Form (133-133)
  • FormField (133-133)
packages/ui/components/input.tsx (1)
  • FormInput (123-123)
packages/ui/components/loading-button.tsx (1)
  • LoadingButton (41-41)
packages/ui/components/button.tsx (1)
  • Button (46-46)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx (3)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (1)
  • PaymentMethodsRow (29-125)
apps/deploy-web/tests/seeders/payment.ts (1)
  • createMockPaymentMethod (3-22)
packages/http-sdk/src/stripe/stripe.types.ts (1)
  • PaymentMethod (30-43)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (3)
packages/http-sdk/src/stripe/stripe.types.ts (1)
  • PaymentMethod (30-43)
apps/deploy-web/src/utils/stringUtils.ts (1)
  • capitalizeFirstLetter (13-15)
packages/http-sdk/src/stripe/stripe.service.ts (1)
  • removePaymentMethod (32-34)
apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx (5)
apps/deploy-web/src/queries/usePaymentQueries.ts (1)
  • usePaymentMethodsQuery (15-25)
apps/deploy-web/src/hooks/useWalletBalance.ts (1)
  • useWalletBalance (36-77)
apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (2)
  • useWalletSettingsQuery (8-18)
  • useWalletSettingsMutations (20-56)
apps/deploy-web/src/components/user/payment/PaymentSuccessAnimation.tsx (1)
  • PaymentSuccessAnimation (24-202)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (1)
  • PaymentPopup (52-292)
⏰ 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). (9)
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: Validate local packages
🔇 Additional comments (13)
packages/ui/components/badge.tsx (1)

14-15: LGTM! Previous hover state issue has been resolved.

Both the success and info variants now correctly use hover:bg-green-600/80 and hover:bg-blue-600/80 respectively, which are valid Tailwind utilities. The missing bg- prefix issue from the previous review has been addressed.

apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (2)

148-152: Previous concern addressed.

The user validation before applying coupon has been properly implemented, matching the pattern used in onPayment. The component now correctly guards against missing user IDs in both payment flows.


240-240: Previous concern addressed.

The error alert title has been updated to "Payment Error", which is more accurate for both loading and confirmation failures.

apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx (2)

60-60: LGTM!

Good use of PaymentMethodsView.name for the root describe block, enabling automated refactoring tools to find all references.


374-427: LGTM!

The setup function follows the coding guidelines: positioned at the bottom, accepts a single parameter with inline type definition, creates the object under test, returns it along with mocks, and avoids shared state.

apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (2)

76-84: LGTM!

The useCallback hooks now correctly include onSetPaymentMethodAsDefault, onRemovePaymentMethod, and paymentMethod.id in their dependency arrays.


86-124: LGTM!

The component structure is well-organized with proper conditional rendering for the dropdown menu based on hasOtherPaymentMethods and isDefault flags. The dependency injection pattern via d allows for clean testing.

apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx (2)

42-46: LGTM!

The onAddPaymentMethod callback now correctly includes createSetupIntent and resetSetupIntent in the dependency array.


23-35: Consider handling or awaiting mutation promises, or verify global error handling is configured.

The mutateAsync calls are fire-and-forget without local error handling. In TanStack Query v5, while onError callbacks are still supported at the mutation level or via MutationCache, unhandled rejections could cause issues if no global error handling is configured. Verify that either:

  • A MutationCache with onError handler is configured in your QueryClient setup, or
  • defaultOptions.mutations.onError is configured, or
  • These specific mutations include error handling via mutation options or try/catch at the call site.
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx (4)

74-74: LGTM!

Good use of PaymentMethodsRow.name for the root describe block, enabling automated refactoring.


75-174: LGTM!

Comprehensive rendering tests covering card details, brand capitalization, month padding, default badge visibility, and conditional dropdown button rendering. The tests use appropriate assertion methods.


302-349: LGTM!

Good edge case coverage including missing card brand, payment method without card object, and two-digit month handling. These tests ensure the component degrades gracefully.


402-442: LGTM!

The setup function follows coding guidelines: positioned at bottom, inline type definition, creates and returns the component with mocks, avoids shared state.

@jzsfkzm jzsfkzm force-pushed the features/1779-auto-top-up-settings branch from dc4e315 to 1519b96 Compare December 4, 2025 14:59
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

🧹 Nitpick comments (12)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx (5)

10-98: Replace any types with proper TypeScript types in mock components.

Mock components use any extensively for props (e.g., MockPopup, MockCard, MockFormField, etc.). Per coding guidelines, define proper interfaces for these mock component props.

Example refactor for a few components:

+interface MockPopupProps {
+  children: React.ReactNode;
+  open: boolean;
+  title: string;
+  actions?: Array<{ onClick: () => void; label: string }>;
+}
+
-const MockPopup = ({ children, open, title, actions }: any) => {
+const MockPopup: React.FC<MockPopupProps> = ({ children, open, title, actions }) => {
   if (!open) return null;
   return (
     <div data-testid="popup">
       <h1>{title}</h1>
       {actions &&
-        actions.map((action: any, i: number) => (
+        actions.map((action, i) => (
           <button key={i} onClick={action.onClick}>
             {action.label}
           </button>
         ))}
       {children}
     </div>
   );
 };

Apply similar typing to other mock components (MockCard, MockFormField, MockFormInput, etc.).


102-106: Use queryBy methods instead of getBy methods in test expectations.

Per coding guidelines for {apps/deploy-web,apps/provider-console}/**/*.spec.tsx, use queryBy methods instead of getBy methods in test expectations.

     it("renders popup when open is true", () => {
       setup({ open: true });
-      expect(screen.getByTestId("popup")).toBeInTheDocument();
-      expect(screen.getByText("Add Funds")).toBeInTheDocument();
+      expect(screen.queryByTestId("popup")).toBeInTheDocument();
+      expect(screen.queryByText("Add Funds")).toBeInTheDocument();
     });

This pattern should be applied throughout the test file wherever getBy* is used in expect() assertions. Examples include lines 115-116, 121-122, 127-128, 133, 138, 346, 356, 572-575, 604, 608, 642, 646, 680, 684, 703, 720, 730, 741.


759-778: Define proper types for setup function input parameter.

The input parameter uses any for several properties which violates coding guidelines.

+interface ConfirmPaymentResponse {
+  success?: boolean;
+  requiresAction?: boolean;
+  clientSecret?: string;
+  paymentIntentId?: string;
+}
+
+interface ApplyCouponResponse {
+  amountAdded?: number;
+  error?: string;
+}
+
+interface StripeErrorResponse {
+  message: string;
+  userAction?: string;
+}
+
 function setup(
   input: {
     open?: boolean;
     onClose?: jest.Mock;
     selectedPaymentMethodId?: string;
     setShowPaymentSuccess?: jest.Mock;
     userId?: string;
-    confirmPaymentResponse?: any;
+    confirmPaymentResponse?: ConfirmPaymentResponse;
     confirmPaymentError?: Error;
-    applyCouponResponse?: any;
+    applyCouponResponse?: ApplyCouponResponse;
     applyCouponError?: Error;
     isConfirmingPayment?: boolean;
     isApplyingCoupon?: boolean;
     isPolling?: boolean;
     pollForPayment?: jest.Mock;
     start3DSecure?: jest.Mock;
-    stripeErrorResponse?: any;
+    stripeErrorResponse?: StripeErrorResponse;
     mockUse3DSecure?: jest.Mock;
   } = {}
 ) {

803-848: Replace any types with proper types in mock form implementation.

The createMockForm function and submit handlers use any types.

+type FormValues = Record<string, unknown>;
+type SubmitHandler<T> = (values: T) => Promise<void> | void;
+
   // Store submit handlers for testing
-  let paymentSubmitHandler: any = null;
-  let couponSubmitHandler: any = null;
+  let paymentSubmitHandler: SubmitHandler<{ amount: number }> | null = null;
+  let couponSubmitHandler: SubmitHandler<{ coupon: string }> | null = null;

   // Create mock form instances
-  const createMockForm = (defaultValues: any, handlerSetter: (handler: any) => void) => {
+  const createMockForm = <T extends FormValues>(
+    defaultValues: T,
+    handlerSetter: (handler: SubmitHandler<T>) => void
+  ) => {
     const values = { ...defaultValues };

     const form = {
       control: {
-        setValue: (fieldName: string, value: any) => {
+        setValue: (fieldName: keyof T, value: T[keyof T]) => {
           values[fieldName] = value;
         },
-        getValues: (fieldName?: string) => {
+        getValues: (fieldName?: keyof T) => {
           if (fieldName) return values[fieldName];
           return values;
         }
       },
-      handleSubmit: (handler: any) => {
+      handleSubmit: (handler: SubmitHandler<T>) => {
         handlerSetter(handler);
         return async (e?: React.FormEvent) => {
           if (e && e.preventDefault) e.preventDefault();

913-920: Consider creating a proper mock dependencies type instead of casting to any.

The eslint-disable comment at line 918 casts dependencies to any, which bypasses type safety. Consider creating a partial mock type that satisfies the component's requirements.

+type MockDependencies = Partial<React.ComponentProps<typeof PaymentPopup>["dependencies"]>;
+
   const props: React.ComponentProps<typeof PaymentPopup> = {
     open: input.open ?? false,
     onClose: mockOnClose,
     selectedPaymentMethodId: input.selectedPaymentMethodId,
     setShowPaymentSuccess: mockSetShowPaymentSuccess,
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    dependencies: dependencies as any
+    dependencies: dependencies as NonNullable<React.ComponentProps<typeof PaymentPopup>["dependencies"]>
   };

Alternatively, ensure all required properties in the dependencies object match the expected types from DEPENDENCIES in the component.

apps/deploy-web/src/queries/usePaymentQueries.spec.tsx (1)

191-241: Consider using QueryKeys instead of hardcoded strings for query key assertions.

The tests use hardcoded strings like ["PAYMENT_METHODS"] and ["DEFAULT_PAYMENT_METHOD"]. If the query key values change in QueryKeys, these tests would pass incorrectly or fail silently. Consider importing and using the actual QueryKeys methods for consistency.

+import { QueryKeys } from "./queryKeys";
 
 // In assertions:
-expect(invalidateQueriesSpy).toHaveBeenCalledWith({ queryKey: ["PAYMENT_METHODS"] });
-expect(invalidateQueriesSpy).toHaveBeenCalledWith({ queryKey: ["DEFAULT_PAYMENT_METHOD"] });
+expect(invalidateQueriesSpy).toHaveBeenCalledWith({ queryKey: QueryKeys.getPaymentMethodsKey() });
+expect(invalidateQueriesSpy).toHaveBeenCalledWith({ queryKey: QueryKeys.getDefaultPaymentMethodKey() });
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx (2)

63-72: Avoid using any type for mock dependencies.

Per coding guidelines, avoid using any type. Consider importing the DEPENDENCIES type from the component or defining a more specific type.

-const mockDependencies: any = {
+import type { PaymentMethodsRowProps } from "./PaymentMethodsRow";
+
+const mockDependencies: NonNullable<PaymentMethodsRowProps["dependencies"]> = {
   TableRow: MockTableRow,
   TableCell: MockTableCell,
   // ... rest of dependencies
 };

Alternatively, if the type isn't exported, you can use typeof pattern:

import { DEPENDENCIES } from "./PaymentMethodsRow";

const mockDependencies: typeof DEPENDENCIES = { ... };

16-21: Global mutable state for mock could cause test interference.

The isDropdownOpen variable is module-level mutable state. While each test re-renders the component, if tests run in parallel or don't properly clean up, this could lead to flaky tests. Consider encapsulating this state within the mock or resetting it in the setup function.

Consider moving the state management inside the mock or resetting it:

+function resetMockState() {
+  isDropdownOpen = false;
+}

 function setup(input = {}) {
+  resetMockState();
   // ... rest of setup
 }
apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (1)

20-56: Consider extracting shared onSuccess logic.

All three mutations have identical onSuccess handlers that invalidate the wallet settings query. This could be DRYed up by extracting a shared callback.

Example refactor:

 export const useWalletSettingsMutations = () => {
   const { walletSettings } = useServices();
   const queryClient = useQueryClient();
+
+  const invalidateWalletSettings = () => {
+    queryClient.invalidateQueries({ queryKey: QueryKeys.getWalletSettingsKey() });
+  };

   const updateWalletSettings = useMutation({
     mutationFn: async (settings: UpdateWalletSettingsParams): Promise<WalletSettings> => {
       return await walletSettings.updateWalletSettings(settings);
     },
-    onSuccess: () => {
-      queryClient.invalidateQueries({ queryKey: QueryKeys.getWalletSettingsKey() });
-    }
+    onSuccess: invalidateWalletSettings
   });

   const createWalletSettings = useMutation({
     mutationFn: async (settings: WalletSettings): Promise<WalletSettings> => {
       return await walletSettings.createWalletSettings(settings);
     },
-    onSuccess: () => {
-      queryClient.invalidateQueries({ queryKey: QueryKeys.getWalletSettingsKey() });
-    }
+    onSuccess: invalidateWalletSettings
   });

   const deleteWalletSettings = useMutation({
     mutationFn: async (): Promise<void> => {
       return await walletSettings.deleteWalletSettings();
     },
-    onSuccess: () => {
-      queryClient.invalidateQueries({ queryKey: QueryKeys.getWalletSettingsKey() });
-    }
+    onSuccess: invalidateWalletSettings
   });

   return {
     updateWalletSettings,
     createWalletSettings,
     deleteWalletSettings
   };
 };
apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx (2)

26-28: Simplify unnecessary memoization.

The useMemo here only returns a simple property access with no computation, making it unnecessary overhead.

Apply this diff:

-  const defaultPaymentMethodId = useMemo(() => {
-    return defaultPaymentMethod?.id;
-  }, [defaultPaymentMethod]);
+  const defaultPaymentMethodId = defaultPaymentMethod?.id;

47-48: Consider more specific error handling.

The catch block uses error: unknown but doesn't attempt to extract any useful error information for debugging or user feedback. While the generic error message is acceptable for users, logging the actual error would help with debugging.

Consider logging the error:

       } catch (error: unknown) {
+        console.error('Failed to update auto reload settings:', error);
         enqueueSnackbar(<Snackbar title="Failed to update Auto Reload settings" iconVariant="error" />, { variant: "error" });
       }

Or use a logging service if available in the codebase.

apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (1)

87-89: Add Button to DEPENDENCIES for consistency.

The Button component is imported directly and used here without going through the dependency injection pattern, unlike all other UI components in this file (Card, Spinner, Table, etc.). For consistency and improved testability, consider adding Button to the DEPENDENCIES object and accessing it as d.Button.

Apply this diff:

 export const DEPENDENCIES = {
   useTheme,
   PaymentMethodsRow,
   AddPaymentMethodPopup,
+  Button,
   Card,
   CardHeader,

And update the usage:

           <div>
-            <Button onClick={onAddPaymentMethod} className="mb-4 mt-4">
+            <d.Button onClick={onAddPaymentMethod} className="mb-4 mt-4">
               Add Payment Method
-            </Button>
+            </d.Button>
           </div>
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dc4e315 and 1519b96.

📒 Files selected for processing (30)
  • apps/api/src/core/services/feature-flags/feature-flags.ts (1 hunks)
  • apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/BillingPage.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/BillingUsageLayout.tsx (3 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsPage.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (1 hunks)
  • apps/deploy-web/src/pages/payment-methods/index.tsx (1 hunks)
  • apps/deploy-web/src/queries/index.ts (1 hunks)
  • apps/deploy-web/src/queries/queryKeys.ts (1 hunks)
  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx (4 hunks)
  • apps/deploy-web/src/queries/usePaymentQueries.ts (2 hunks)
  • apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx (1 hunks)
  • apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (1 hunks)
  • apps/deploy-web/src/services/app-di-container/app-di-container.ts (2 hunks)
  • apps/deploy-web/src/types/feature-flags.ts (1 hunks)
  • apps/deploy-web/src/utils/urlUtils.ts (1 hunks)
  • apps/deploy-web/tests/seeders/payment.ts (2 hunks)
  • packages/http-sdk/src/index.ts (1 hunks)
  • packages/http-sdk/src/stripe/stripe.service.ts (3 hunks)
  • packages/http-sdk/src/stripe/stripe.types.ts (2 hunks)
  • packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (1 hunks)
  • packages/http-sdk/src/wallet-settings/wallet-settings.types.ts (1 hunks)
  • packages/ui/components/badge.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (14)
  • apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx
  • apps/deploy-web/src/queries/queryKeys.ts
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsPage.tsx
  • apps/deploy-web/src/components/billing-usage/BillingUsageLayout.tsx
  • apps/deploy-web/src/queries/index.ts
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
  • apps/deploy-web/src/services/app-di-container/app-di-container.ts
  • apps/deploy-web/tests/seeders/payment.ts
  • packages/http-sdk/src/stripe/stripe.service.ts
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx
  • packages/http-sdk/src/stripe/stripe.types.ts
  • packages/http-sdk/src/wallet-settings/wallet-settings.types.ts
  • apps/deploy-web/src/utils/urlUtils.ts
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{ts,tsx,js}: Never use type any or cast to type any. Always define the proper TypeScript types.
Never use deprecated methods from libraries.
Don't add unnecessary comments to the code.

Files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
  • apps/deploy-web/src/queries/useWalletSettingsQueries.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
  • packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx
  • apps/deploy-web/src/queries/usePaymentQueries.ts
  • apps/deploy-web/src/pages/payment-methods/index.tsx
  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
  • apps/deploy-web/src/types/feature-flags.ts
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
  • apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx
  • packages/http-sdk/src/index.ts
  • apps/deploy-web/src/components/billing-usage/BillingPage.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
  • packages/ui/components/badge.tsx
  • apps/api/src/core/services/feature-flags/feature-flags.ts
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/no-jest-mock.mdc)

Don't use jest.mock() in test files. Instead, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test

Use setup function instead of beforeEach in test files. The setup function must be at the bottom of the root describe block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type.

**/*.spec.{ts,tsx}: Use <Subject>.name in the root describe suite description instead of hardcoded class/service name strings to enable automated refactoring tools to find all references
Use either a method name or a condition starting with 'when' for nested suite descriptions in tests
Use present simple, 3rd person singular for test descriptions without prepending 'should'

Files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
{apps/deploy-web,apps/provider-console}/**/*.spec.tsx

📄 CodeRabbit inference engine (.cursor/rules/query-by-in-tests.mdc)

Use queryBy methods instead of getBy methods in test expectations

Files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
🧠 Learnings (12)
📓 Common learnings
Learnt from: baktun14
Repo: akash-network/console PR: 1725
File: apps/api/src/utils/constants.ts:5-5
Timestamp: 2025-07-24T17:00:52.361Z
Learning: In the Akash Network Console project, when cross-cutting concerns or broader refactoring issues are identified during PR review, the preferred approach is to create a separate GitHub issue to track the work rather than expanding the scope of the current PR. This maintains focus and allows for proper planning of architectural improvements.
📚 Learning: 2025-11-12T16:36:02.543Z
Learnt from: baktun14
Repo: akash-network/console PR: 2203
File: apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx:161-168
Timestamp: 2025-11-12T16:36:02.543Z
Learning: In apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx, the organization field captured during payment method setup is internal metadata. Errors from stripe.updateCustomerOrganization should be logged to Sentry but not surfaced to users, and the flow should continue even if the organization update fails, as it's non-critical and not something users can fix.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx
  • apps/deploy-web/src/pages/payment-methods/index.tsx
📚 Learning: 2025-11-25T17:45:52.965Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-11-25T17:45:52.965Z
Learning: Applies to **/*.spec.{ts,tsx} : Use `setup` function instead of `beforeEach` in test files. The `setup` function must be at the bottom of the root `describe` block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
📚 Learning: 2025-11-25T17:45:44.790Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/no-jest-mock.mdc:0-0
Timestamp: 2025-11-25T17:45:44.790Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use `jest.mock()` in test files. Instead, use `jest-mock-extended` to create mocks and pass mocks as dependencies to the service under test

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
📚 Learning: 2025-11-25T17:45:49.180Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/query-by-in-tests.mdc:0-0
Timestamp: 2025-11-25T17:45:49.180Z
Learning: Applies to {apps/deploy-web,apps/provider-console}/**/*.spec.tsx : Use `queryBy` methods instead of `getBy` methods in test expectations

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
📚 Learning: 2025-11-25T17:45:58.258Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/test-descriptions.mdc:0-0
Timestamp: 2025-11-25T17:45:58.258Z
Learning: Applies to **/*.spec.{ts,tsx} : Use `<Subject>.name` in the root describe suite description instead of hardcoded class/service name strings to enable automated refactoring tools to find all references

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
📚 Learning: 2025-11-25T17:45:58.258Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/test-descriptions.mdc:0-0
Timestamp: 2025-11-25T17:45:58.258Z
Learning: Applies to **/*.spec.{ts,tsx} : Use present simple, 3rd person singular for test descriptions without prepending 'should'

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
📚 Learning: 2025-11-25T17:45:58.258Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/test-descriptions.mdc:0-0
Timestamp: 2025-11-25T17:45:58.258Z
Learning: Applies to **/*.spec.{ts,tsx} : Use either a method name or a condition starting with 'when' for nested suite descriptions in tests

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
📚 Learning: 2025-07-11T10:46:43.711Z
Learnt from: stalniy
Repo: akash-network/console PR: 1660
File: apps/deploy-web/src/components/alerts/DeploymentAlertsContainer/DeploymentAlertsContainer.spec.tsx:54-56
Timestamp: 2025-07-11T10:46:43.711Z
Learning: In apps/{deploy-web,provider-console}/**/*.spec.tsx files: Use `getBy` methods instead of `queryBy` methods when testing element presence with `toBeInTheDocument()` because `getBy` throws an error and shows DOM state when element is not found, providing better debugging information than `queryBy` which returns null.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
📚 Learning: 2025-09-18T07:50:31.224Z
Learnt from: baktun14
Repo: akash-network/console PR: 1933
File: apps/deploy-web/src/components/onboarding/steps/PaymentVerificationCard/PaymentVerificationCard.tsx:43-63
Timestamp: 2025-09-18T07:50:31.224Z
Learning: PaymentVerificationCard component is wrapped by Stripe Elements provider in its parent component PaymentMethodStep, so PaymentMethodForm inside PaymentVerificationCard has access to Stripe context without needing its own Elements wrapper.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx
📚 Learning: 2025-11-19T15:15:07.283Z
Learnt from: ygrishajev
Repo: akash-network/console PR: 2254
File: apps/api/test/functional/sign-and-broadcast-tx.spec.ts:4-4
Timestamp: 2025-11-19T15:15:07.283Z
Learning: In the Akash Network Console project, when tests use native Node.js fetch (available in Node 18+), fetch-mock should be used for HTTP mocking instead of nock, as nock does not support intercepting native fetch calls. This applies to apps/api/test/functional/sign-and-broadcast-tx.spec.ts and any other tests using native fetch.

Applied to files:

  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
📚 Learning: 2025-07-28T10:40:13.595Z
Learnt from: stalniy
Repo: akash-network/console PR: 1480
File: apps/deploy-web/src/hooks/useFlag.tsx:0-0
Timestamp: 2025-07-28T10:40:13.595Z
Learning: In the Akash Network Console project, backend-specific feature flags are intentional and acceptable. The frontend FeatureFlag union type should only include flags that are actually used by the frontend, not all flags defined in the backend. Backend can have internal feature flags for backend-only functionality without requiring frontend synchronization.

Applied to files:

  • apps/deploy-web/src/types/feature-flags.ts
  • apps/api/src/core/services/feature-flags/feature-flags.ts
🧬 Code graph analysis (9)
apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx (6)
apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx (1)
  • PaymentMethodsContainer (17-63)
apps/deploy-web/tests/seeders/payment.ts (2)
  • createMockPaymentMethod (3-22)
  • createMockSetupIntentResponse (57-60)
apps/deploy-web/tests/ui/fixture/context-with-extension.ts (1)
  • expect (78-78)
apps/deploy-web/src/queries/usePaymentQueries.ts (3)
  • usePaymentMethodsQuery (15-25)
  • usePaymentMutations (67-136)
  • useSetupIntentMutation (57-65)
apps/deploy-web/tests/unit/container-testing-child-capturer.tsx (1)
  • createContainerTestingChildCapturer (25-27)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (1)
  • PaymentMethodsViewProps (22-33)
apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (3)
packages/http-sdk/src/wallet-settings/wallet-settings.types.ts (2)
  • WalletSettings (1-3)
  • UpdateWalletSettingsParams (9-11)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
  • useServices (30-32)
packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (3)
  • updateWalletSettings (19-21)
  • createWalletSettings (15-17)
  • deleteWalletSettings (23-25)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx (4)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (2)
  • PaymentMethodsView (35-103)
  • DEPENDENCIES (9-20)
packages/http-sdk/src/stripe/stripe.types.ts (2)
  • SetupIntentResponse (68-70)
  • PaymentMethod (30-43)
apps/deploy-web/tests/seeders/payment.ts (1)
  • createMockPaymentMethod (3-22)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (1)
  • DEPENDENCIES (10-19)
packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (2)
packages/http-sdk/src/api-http/api-http.service.ts (1)
  • ApiHttpService (9-29)
packages/http-sdk/src/wallet-settings/wallet-settings.types.ts (2)
  • WalletSettings (1-3)
  • UpdateWalletSettingsParams (9-11)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (6)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (1)
  • DEPENDENCIES (10-19)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (1)
  • DEPENDENCIES (30-55)
packages/http-sdk/src/stripe/stripe.types.ts (2)
  • PaymentMethod (30-43)
  • SetupIntentResponse (68-70)
apps/deploy-web/tests/ui/fixture/Leap/contentScripts.js (1)
  • d (2105-2105)
apps/deploy-web/tests/ui/fixture/Leap/injectLeap.js (1)
  • p (9465-9465)
packages/ui/components/button.tsx (1)
  • Button (46-46)
apps/deploy-web/src/pages/payment-methods/index.tsx (5)
apps/deploy-web/src/hoc/guard/guard.hoc.tsx (2)
  • Guard (9-29)
  • composeGuards (31-44)
apps/deploy-web/src/components/billing-usage/PaymentMethodsPage.tsx (1)
  • PaymentMethodsPage (9-18)
apps/deploy-web/src/hooks/useUser.ts (1)
  • useIsRegisteredUser (22-29)
apps/deploy-web/src/lib/nextjs/defineServerSideProps/defineServerSideProps.ts (1)
  • defineServerSideProps (44-92)
apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.ts (1)
  • isFeatureEnabled (6-8)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx (1)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (1)
  • PaymentPopup (80-324)
apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx (5)
apps/deploy-web/src/hooks/useWalletBalance.ts (1)
  • useWalletBalance (36-77)
apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (2)
  • useWalletSettingsQuery (8-18)
  • useWalletSettingsMutations (20-56)
packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (2)
  • updateWalletSettings (19-21)
  • createWalletSettings (15-17)
apps/deploy-web/src/components/user/payment/PaymentSuccessAnimation.tsx (1)
  • PaymentSuccessAnimation (24-202)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (1)
  • PaymentPopup (80-324)
apps/deploy-web/src/components/billing-usage/BillingPage.tsx (3)
apps/deploy-web/src/hooks/useFlag.tsx (1)
  • useFlag (8-8)
apps/deploy-web/src/components/billing-usage/BillingUsageLayout.tsx (1)
  • BillingUsageLayout (25-65)
apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx (1)
  • AccountOverview (15-138)
⏰ 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). (9)
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: Validate local packages
🔇 Additional comments (24)
packages/ui/components/badge.tsx (1)

14-15: New badge variants look correct and Tailwind classes are valid.

success and info both use the correct hover:bg-.../80 syntax and are consistent with the existing variant pattern. No issues from a typing or styling-utility perspective.

apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx (2)

100-100: Good use of PaymentPopup.name in the root describe block.

This follows the coding guidelines and enables automated refactoring tools to find all references.


759-941: Setup function structure follows the required pattern.

The setup function is correctly placed at the bottom of the root describe block, accepts a single parameter with inline type definition, creates the object under test, and returns it along with useful test helpers. The dependency injection pattern avoids jest.mock() as per coding guidelines.

apps/deploy-web/src/queries/usePaymentQueries.ts (2)

27-37: LGTM!

The new useDefaultPaymentMethodQuery hook follows the established pattern in this file, properly using the QueryKeys utility and the Stripe service. The type annotation is consistent with other query hooks.


118-127: LGTM!

The setPaymentMethodAsDefault mutation correctly invalidates both the payment methods list and the default payment method query cache on success, ensuring UI consistency after the operation.

apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx (1)

121-182: Well-structured setup function.

The setup function follows the coding guidelines: positioned at the bottom of the describe block, accepts a single parameter with inline type definition, avoids shared state, and returns all necessary test artifacts without a specified return type.

apps/deploy-web/src/queries/usePaymentQueries.spec.tsx (2)

26-46: Helper function for testing query invalidation is well-designed.

The setupQueryWithClient helper appropriately exposes the queryClient for spy verification while configuring sensible defaults for testing (no retries, disabled refetch behaviors). This is a reusable pattern for mutation tests that need to verify cache invalidation.


64-77: LGTM!

New test for useDefaultPaymentMethodQuery follows the established pattern and verifies the service call and successful data return.

apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx (1)

402-442: Well-structured setup function following guidelines.

The setup function is correctly positioned at the bottom of the describe block, accepts a single parameter with inline type definition, avoids shared state by creating fresh mocks per call, and returns test artifacts without a specified return type.

packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (2)

6-26: LGTM - Clean service implementation.

The service follows the established patterns in the SDK, properly extends ApiHttpService, uses extractApiData for response unwrapping, and has appropriate TypeScript typing. The CRUD operations map cleanly to REST endpoints.


19-21: Verify that put method is available in the base class.

The ApiHttpService class shown in the relevant snippets only overrides post, patch, and get methods. Ensure that put is available (likely inherited from HttpService). If not, consider using patch for partial updates or adding put to ApiHttpService.

packages/http-sdk/src/index.ts (1)

25-25: LGTM!

The export follows the established pattern for service exports.

apps/api/src/core/services/feature-flags/feature-flags.ts (1)

4-5: LGTM!

The new feature flag follows the established naming convention and is properly integrated into the FeatureFlags constant.

apps/deploy-web/src/types/feature-flags.ts (1)

9-10: LGTM!

The feature flag type addition is consistent with the flag's usage in the billing UI and payment methods pages.

apps/deploy-web/src/components/billing-usage/BillingPage.tsx (1)

8-18: LGTM!

The feature flag integration is clean and properly gates the AccountOverview component rendering.

apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (1)

8-17: LGTM!

The query hook follows React Query best practices with proper key management and type safety.

apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx (3)

60-60: LGTM!

The test suite correctly uses PaymentMethodsView.name in the describe block as required by coding guidelines.


374-427: LGTM!

The setup function follows the coding guidelines: positioned at the bottom of the root describe block, creates the component under test, accepts a single parameter with inline type definition, and returns both the render result and mocks for assertions.


62-93: LGTM!

Test cases properly use queryBy methods in expectations (line 71) as required by coding guidelines, and descriptions follow the present simple, 3rd person pattern without "should".

apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx (3)

30-52: LGTM!

The toggleAutoReload callback correctly handles both creating new settings and updating existing settings, with appropriate success feedback.


54-56: LGTM!

The isReloadChangeDisabled logic correctly prevents toggling the auto-reload switch when there's no payment method or when mutations are in progress.


93-102: LGTM!

The "Add funds" button is correctly disabled when there's no default payment method or when the wallet balance is still loading.

apps/deploy-web/src/pages/payment-methods/index.tsx (1)

8-13: Verify server-side and client-side guard consistency.

The client-side guards check useIsManagedWalletUser and useIsRegisteredUser, while the server-side only checks isAuthenticated and isFeatureEnabled("auto_credit_reload"). If the auto_credit_reload feature flag is not scoped specifically to managed wallet users, there is a mismatch that could allow users without managed wallets to pass the server-side check but be blocked client-side, causing a brief flash of content before redirect.

Confirm whether isFeatureEnabled("auto_credit_reload") is gated to managed wallet users or if an additional server-side managed wallet check is needed to match the client-side guard.

apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (1)

85-90: Verify that the 3-card limit is enforced.

The footer displays "At most, 3 cards can be used at once," but this view doesn't show any validation preventing users from adding more than 3 payment methods. Ensure that the limit is enforced either in the container component, backend, or by disabling the "Add Payment Method" button when the limit is reached.

const { data: walletSettings } = useWalletSettingsQuery();
const { updateWalletSettings, createWalletSettings } = useWalletSettingsMutations();

const isLoading = isLoadingDefaultPaymentMethod;
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

Incomplete loading state check.

The isLoading variable only checks isLoadingDefaultPaymentMethod, but the component also depends on wallet balance and wallet settings data. If these are still loading, the component might render with incomplete data.

Consider whether other loading states should be included:

-  const isLoading = isLoadingDefaultPaymentMethod;
+  const isLoading = isLoadingDefaultPaymentMethod || isWalletBalanceLoading;

Or if wallet settings loading should also block the initial render, though that data has a default fallback (walletSettings?.autoReloadEnabled ?? false).

📝 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
const isLoading = isLoadingDefaultPaymentMethod;
const isLoading = isLoadingDefaultPaymentMethod || isWalletBalanceLoading;
🤖 Prompt for AI Agents
In
apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx
around line 24, the isLoading variable currently only uses
isLoadingDefaultPaymentMethod which can allow the component to render while
wallet balance or wallet settings are still loading; update isLoading to combine
the relevant loading flags (e.g., isLoadingDefaultPaymentMethod ||
isLoadingWalletBalance || isLoadingWalletSettings) so the component waits for
all required data before rendering, or if you intentionally want to allow wallet
settings to fallback, include only the flags you need (balance + default
payment) and keep the fallback for settings as is.

@jzsfkzm jzsfkzm force-pushed the features/1779-auto-top-up-settings branch from 1519b96 to 35b56e4 Compare December 4, 2025 15:06
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: 0

♻️ Duplicate comments (1)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (1)

42-44: Inconsistent function declaration style.

openMenu uses a function declaration while closeMenu uses an arrow function. Consider using consistent style throughout.

🧹 Nitpick comments (7)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx (3)

10-98: Replace any types with proper type definitions.

The mock components use any for props which violates the coding guidelines. Define proper interfaces for each mock component.

Example for MockPopup:

-const MockPopup = ({ children, open, title, actions }: any) => {
+interface MockPopupProps {
+  children?: React.ReactNode;
+  open: boolean;
+  title?: string;
+  actions?: Array<{ label: string; onClick: () => void }>;
+}
+
+const MockPopup = ({ children, open, title, actions }: MockPopupProps) => {

Apply similar typing for other mock components (MockCard, MockCardHeader, MockFormField, MockFormInput, MockLoadingButton, etc.).

As per coding guidelines: "Never use type any or cast to type any. Always define the proper TypeScript types."


102-144: Use queryBy methods instead of getBy in assertions.

Per coding guidelines for test files in this path, use queryBy methods in test expectations for clearer failure messages.

Example changes:

 it("renders popup when open is true", () => {
   setup({ open: true });
-  expect(screen.getByTestId("popup")).toBeInTheDocument();
-  expect(screen.getByText("Add Funds")).toBeInTheDocument();
+  expect(screen.queryByTestId("popup")).toBeInTheDocument();
+  expect(screen.queryByText("Add Funds")).toBeInTheDocument();
 });

 it("renders payment form with amount input", () => {
   setup({ open: true });
-  expect(screen.getByLabelText("Amount (USD)")).toBeInTheDocument();
-  expect(screen.getByPlaceholderText("0.00")).toBeInTheDocument();
+  expect(screen.queryByLabelText("Amount (USD)")).toBeInTheDocument();
+  expect(screen.queryByPlaceholderText("0.00")).toBeInTheDocument();
 });

Apply this pattern throughout the test file. As per coding guidelines: "Use queryBy methods instead of getBy methods in test expectations."


759-941: Move setup function inside the describe block.

The setup function should be at the bottom of the root describe block, not outside it.

Move the entire setup function inside the describe(PaymentPopup.name, () => { ... }) block, placing it after all the nested describe blocks:

 describe(PaymentPopup.name, () => {
   describe("Rendering", () => {
     // ... tests
   });
   // ... other describe blocks ...
   describe("Processing States", () => {
     // ... tests
   });
+
+  function setup(
+    input: {
+      // ... input type definition
+    } = {}
+  ) {
+    // ... setup implementation
+  }
 });
-
-function setup(
-  input: {
-    // ... input type definition
-  } = {}
-) {
-  // ... setup implementation
-}

As per coding guidelines: "The setup function must be at the bottom of the root describe block."

apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (3)

46-52: useCallback provides no benefit here.

Since card receives paymentMethod as an argument and is called inline (card(paymentMethod)), memoizing the function reference has no performance benefit. Convert to a regular helper function or inline the logic.

-  const card = useCallback((paymentMethod: PaymentMethod) => {
-    return (
-      <>
-        {capitalizeFirstLetter(paymentMethod.card?.brand || "")} {paymentMethod.card?.funding} **** {paymentMethod.card?.last4}
-      </>
-    );
-  }, []);
+  const cardLabel = `${capitalizeFirstLetter(paymentMethod.card?.brand || "")} ${paymentMethod.card?.funding} **** ${paymentMethod.card?.last4}`;

Then in JSX use {cardLabel} instead of {card(paymentMethod)}.


54-61: Same issue: useCallback with inline invocation.

This has the same problem as card above. The padding logic can be computed directly.

-  const validUntil = useCallback((paymentMethod: PaymentMethod) => {
-    const month = paymentMethod.card?.exp_month?.toString().padStart(2, "0");
-    return (
-      <>
-        {month}/{paymentMethod.card?.exp_year}
-      </>
-    );
-  }, []);
+  const validUntilLabel = `${paymentMethod.card?.exp_month?.toString().padStart(2, "0")}/${paymentMethod.card?.exp_year}`;

Then use {validUntilLabel} in the JSX.


76-84: closeMenu is missing from dependency arrays.

Both callbacks reference closeMenu which is recreated on each render. Inline setOpen(false) directly to satisfy exhaustive-deps and simplify the code.

 const setPaymentAsDefault = useCallback(() => {
   onSetPaymentMethodAsDefault(paymentMethod.id);
-  closeMenu();
+  setOpen(false);
 }, [onSetPaymentMethodAsDefault, paymentMethod.id]);

 const removePaymentMethod = useCallback(() => {
   onRemovePaymentMethod(paymentMethod.id);
-  closeMenu();
+  setOpen(false);
 }, [onRemovePaymentMethod, paymentMethod.id]);
apps/deploy-web/src/queries/usePaymentQueries.spec.tsx (1)

174-241: Consider asserting invalidations via QueryKeys constants instead of raw arrays.

The invalidation tests currently hard‑code ["PAYMENT_METHODS"] and ["DEFAULT_PAYMENT_METHOD"]. Importing and using QueryKeys.getPaymentMethodsKey() / getDefaultPaymentMethodKey() here would keep tests aligned with the query-key source of truth and reduce future churn if keys change.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1519b96 and 35b56e4.

📒 Files selected for processing (10)
  • apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (1 hunks)
  • apps/deploy-web/src/queries/queryKeys.ts (1 hunks)
  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx (4 hunks)
  • apps/deploy-web/src/queries/usePaymentQueries.ts (2 hunks)
  • packages/http-sdk/src/stripe/stripe.service.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx
  • apps/deploy-web/src/queries/queryKeys.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{ts,tsx,js}: Never use type any or cast to type any. Always define the proper TypeScript types.
Never use deprecated methods from libraries.
Don't add unnecessary comments to the code.

Files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx
  • apps/deploy-web/src/queries/usePaymentQueries.ts
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
  • packages/http-sdk/src/stripe/stripe.service.ts
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
  • apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/no-jest-mock.mdc)

Don't use jest.mock() in test files. Instead, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test

Use setup function instead of beforeEach in test files. The setup function must be at the bottom of the root describe block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type.

**/*.spec.{ts,tsx}: Use <Subject>.name in the root describe suite description instead of hardcoded class/service name strings to enable automated refactoring tools to find all references
Use either a method name or a condition starting with 'when' for nested suite descriptions in tests
Use present simple, 3rd person singular for test descriptions without prepending 'should'

Files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
{apps/deploy-web,apps/provider-console}/**/*.spec.tsx

📄 CodeRabbit inference engine (.cursor/rules/query-by-in-tests.mdc)

Use queryBy methods instead of getBy methods in test expectations

Files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
🧠 Learnings (9)
📓 Common learnings
Learnt from: baktun14
Repo: akash-network/console PR: 1725
File: apps/api/src/utils/constants.ts:5-5
Timestamp: 2025-07-24T17:00:52.361Z
Learning: In the Akash Network Console project, when cross-cutting concerns or broader refactoring issues are identified during PR review, the preferred approach is to create a separate GitHub issue to track the work rather than expanding the scope of the current PR. This maintains focus and allows for proper planning of architectural improvements.
📚 Learning: 2025-11-25T17:45:44.790Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/no-jest-mock.mdc:0-0
Timestamp: 2025-11-25T17:45:44.790Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use `jest.mock()` in test files. Instead, use `jest-mock-extended` to create mocks and pass mocks as dependencies to the service under test

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
📚 Learning: 2025-11-25T17:45:52.965Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-11-25T17:45:52.965Z
Learning: Applies to **/*.spec.{ts,tsx} : Use `setup` function instead of `beforeEach` in test files. The `setup` function must be at the bottom of the root `describe` block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
📚 Learning: 2025-11-12T16:36:02.543Z
Learnt from: baktun14
Repo: akash-network/console PR: 2203
File: apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx:161-168
Timestamp: 2025-11-12T16:36:02.543Z
Learning: In apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx, the organization field captured during payment method setup is internal metadata. Errors from stripe.updateCustomerOrganization should be logged to Sentry but not surfaced to users, and the flow should continue even if the organization update fails, as it's non-critical and not something users can fix.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
📚 Learning: 2025-11-19T15:15:07.283Z
Learnt from: ygrishajev
Repo: akash-network/console PR: 2254
File: apps/api/test/functional/sign-and-broadcast-tx.spec.ts:4-4
Timestamp: 2025-11-19T15:15:07.283Z
Learning: In the Akash Network Console project, when tests use native Node.js fetch (available in Node 18+), fetch-mock should be used for HTTP mocking instead of nock, as nock does not support intercepting native fetch calls. This applies to apps/api/test/functional/sign-and-broadcast-tx.spec.ts and any other tests using native fetch.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
📚 Learning: 2025-09-18T07:50:31.224Z
Learnt from: baktun14
Repo: akash-network/console PR: 1933
File: apps/deploy-web/src/components/onboarding/steps/PaymentVerificationCard/PaymentVerificationCard.tsx:43-63
Timestamp: 2025-09-18T07:50:31.224Z
Learning: PaymentVerificationCard component is wrapped by Stripe Elements provider in its parent component PaymentMethodStep, so PaymentMethodForm inside PaymentVerificationCard has access to Stripe context without needing its own Elements wrapper.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
📚 Learning: 2025-11-25T17:45:49.180Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/query-by-in-tests.mdc:0-0
Timestamp: 2025-11-25T17:45:49.180Z
Learning: Applies to {apps/deploy-web,apps/provider-console}/**/*.spec.tsx : Use `queryBy` methods instead of `getBy` methods in test expectations

Applied to files:

  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
📚 Learning: 2025-07-11T10:46:43.711Z
Learnt from: stalniy
Repo: akash-network/console PR: 1660
File: apps/deploy-web/src/components/alerts/DeploymentAlertsContainer/DeploymentAlertsContainer.spec.tsx:54-56
Timestamp: 2025-07-11T10:46:43.711Z
Learning: In apps/{deploy-web,provider-console}/**/*.spec.tsx files: Use `getBy` methods instead of `queryBy` methods when testing element presence with `toBeInTheDocument()` because `getBy` throws an error and shows DOM state when element is not found, providing better debugging information than `queryBy` which returns null.

Applied to files:

  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
📚 Learning: 2025-10-31T11:26:42.138Z
Learnt from: stalniy
Repo: akash-network/console PR: 2138
File: apps/api/src/billing/lib/batch-signing-client/batch-signing-client.service.ts:379-382
Timestamp: 2025-10-31T11:26:42.138Z
Learning: In TypeScript/JavaScript, the pattern of checking a cached value and then performing an async operation to fetch it without proper synchronization is race condition unsafe:
```typescript
private async getAddress() {
  if (!this.address) {
    this.address = await this.wallet.getFirstAddress();
  }
  return this.address;
}
```
Multiple concurrent calls can all pass the `if (!this.address)` check before any of them sets the value, leading to duplicate async operations. This should be flagged as a race condition. Proper synchronization (mutex, atomic promise caching, or guaranteed single-threaded execution) is required.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx
🧬 Code graph analysis (7)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (4)
packages/http-sdk/src/stripe/stripe.types.ts (1)
  • PaymentMethod (30-43)
apps/deploy-web/src/utils/stringUtils.ts (1)
  • capitalizeFirstLetter (13-15)
packages/ui/components/badge.tsx (1)
  • Badge (32-32)
packages/http-sdk/src/stripe/stripe.service.ts (1)
  • removePaymentMethod (36-38)
apps/deploy-web/src/queries/usePaymentQueries.ts (5)
packages/http-sdk/src/stripe/stripe.types.ts (1)
  • PaymentMethod (30-43)
apps/api/src/billing/http-schemas/stripe.schema.ts (1)
  • PaymentMethod (236-236)
apps/api/src/billing/services/stripe/stripe.service.ts (1)
  • PaymentMethod (35-35)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
  • useServices (30-32)
packages/http-sdk/src/stripe/stripe.service.ts (1)
  • setPaymentMethodAsDefault (60-62)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx (1)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (1)
  • PaymentPopup (80-324)
packages/http-sdk/src/stripe/stripe.service.ts (3)
packages/http-sdk/src/stripe/stripe.types.ts (2)
  • PaymentMethod (30-43)
  • SetPaymentMethodAsDefaultParams (118-120)
apps/api/src/billing/http-schemas/stripe.schema.ts (1)
  • PaymentMethod (236-236)
apps/api/src/billing/services/stripe/stripe.service.ts (1)
  • PaymentMethod (35-35)
apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx (6)
apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx (1)
  • PaymentMethodsContainer (17-63)
apps/deploy-web/tests/seeders/payment.ts (2)
  • createMockPaymentMethod (3-22)
  • createMockSetupIntentResponse (57-60)
packages/http-sdk/src/stripe/stripe.types.ts (2)
  • PaymentMethod (30-43)
  • SetupIntentResponse (68-70)
apps/deploy-web/src/queries/usePaymentQueries.ts (3)
  • usePaymentMethodsQuery (15-25)
  • usePaymentMutations (67-136)
  • useSetupIntentMutation (57-65)
apps/deploy-web/tests/unit/container-testing-child-capturer.tsx (1)
  • createContainerTestingChildCapturer (25-27)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (1)
  • PaymentMethodsViewProps (22-33)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (3)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (1)
  • DEPENDENCIES (10-19)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (1)
  • DEPENDENCIES (9-20)
packages/http-sdk/src/stripe/stripe.service.ts (2)
  • confirmPayment (52-54)
  • applyCoupon (44-46)
apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx (5)
apps/deploy-web/src/queries/usePaymentQueries.ts (1)
  • useDefaultPaymentMethodQuery (27-37)
apps/deploy-web/src/hooks/useWalletBalance.ts (1)
  • useWalletBalance (36-77)
apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (2)
  • useWalletSettingsQuery (8-18)
  • useWalletSettingsMutations (20-56)
packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (2)
  • updateWalletSettings (19-21)
  • createWalletSettings (15-17)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (1)
  • PaymentPopup (80-324)
⏰ 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). (9)
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: Validate local packages
🔇 Additional comments (19)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (6)

1-55: LGTM - Imports and DI pattern.

The dependency injection pattern aligns well with related components (PaymentMethodsView.tsx, PaymentMethodsRow.tsx) and enables proper testability.


57-78: LGTM - Form schemas and props interface.

The validation schemas properly enforce business rules (minimum $20 payment), and the props interface is well-defined with appropriate typing.


80-129: LGTM - Hook setup and state management.

Good use of useRef for submittedAmountRef to preserve the submitted amount across async operations and re-renders. The 3D Secure success callback properly sequences the success flow.


131-176: LGTM - Payment submission handler.

Proper validation guards, error handling, and branching for 3D Secure vs immediate success flows. The error: unknown typing in the catch block follows TypeScript best practices.


178-207: LGTM - Coupon submission handler.

User validation is properly implemented, and error handling covers both API error responses and exceptions.


209-323: LGTM - Component rendering.

The computed state logic and conditional rendering are well-structured. The error display properly shows both the error message and actionable suggestion.

apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx (2)

803-862: Good form mock implementation.

The createMockForm helper and the call-counting approach for mockUseForm effectively simulate react-hook-form behavior while allowing proper test isolation.


100-756: Comprehensive test coverage.

The test suite thoroughly covers rendering conditions, form validation, payment flows, coupon handling, 3D Secure integration, error states, and UI processing indicators. The use of PaymentPopup.name for the describe block follows best practices for refactoring support.

apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (4)

1-8: LGTM!

Imports are appropriate and the PaymentMethod type is correctly imported from the SDK.


10-19: Good pattern for testability.

The dependency injection approach allows for easy mocking in unit tests.


63-74: LGTM!

Good use of useMemo to avoid recreating the badge JSX unnecessarily.


86-124: LGTM!

The conditional rendering logic for the dropdown menu is correct, and the multiple dismiss handlers (mouseLeave, clickAway, action callbacks) provide good UX.

apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx (1)

14-182: Comprehensive, guideline-compliant container tests

The suite exercises all key behaviors of PaymentMethodsContainer (data/defaulting, loading flag, both mutations, setup-intent flow, showAddPaymentMethod state, and onAddCardSuccess refetch) and wires dependencies via the dependencies prop with strongly typed mocks. The setup helper at the bottom of the root describe follows the repo’s testing guidelines (inline parameter type, no explicit return type, no shared state) and cleanly handles the “no override vs undefined override” distinction for paymentMethods. The previous mutate vs mutateAsync mismatch is also correctly aligned with the container implementation now.

As per coding guidelines, this spec matches the expected setup pattern and avoids jest.mock.

apps/deploy-web/src/queries/usePaymentQueries.ts (2)

27-37: Dedicated default payment method query looks good.

Hook wiring (DI via useServices, QueryKeys.getDefaultPaymentMethodKey(), and typed UseQueryOptions<PaymentMethod>) is consistent with existing patterns and keeps the query easily configurable via options.


118-135: Good invalidation strategy for setting default payment method.

The mutation correctly wraps the service call and invalidates both PAYMENT_METHODS and DEFAULT_PAYMENT_METHOD query keys, keeping list and default views in sync with minimal extra logic.

apps/deploy-web/src/queries/usePaymentQueries.spec.tsx (2)

25-46: Test helper setupQueryWithClient is a solid pattern.

Creating an isolated QueryClient and injecting it via services.queryClient keeps tests deterministic and makes spying on invalidateQueries straightforward without touching global React Query state.


64-77: Default payment method query coverage is appropriate.

The test exercises useDefaultPaymentMethodQuery end‑to‑end with a mocked service, asserting both the service call and the successful data exposure on the hook result.

apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx (1)

88-90: Confirm which wallet balance field should represent “Credits Remaining”.

The card uses walletBalance.totalDeploymentGrantsUSD as the displayed amount; given useWalletBalance also exposes totalUsd and other aggregates, please verify that “Credits Remaining” is intended to show only grant-based credits rather than the full spendable balance, and adjust the field if product semantics require a different total.

packages/http-sdk/src/stripe/stripe.service.ts (1)

60-62: Confirm setPaymentMethodAsDefault response shape (array vs single item).

This is typed as Promise<PaymentMethod[]>, but downstream usage and tests may treat it like a single PaymentMethod. Please confirm the backend contract for POST /v1/stripe/payment-methods/default and align the return type and mocks/consumers (either change this to Promise<PaymentMethod> or update callers to handle an array and rename accordingly for clarity).

@jzsfkzm jzsfkzm force-pushed the features/1779-auto-top-up-settings branch from 35b56e4 to 017483b Compare December 4, 2025 15:19
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

🧹 Nitpick comments (4)
apps/deploy-web/src/queries/usePaymentQueries.spec.tsx (1)

25-46: Consider refactoring to avoid duplication.

The setupQueryWithClient function duplicates the QueryClient creation logic. Consider refactoring the existing setupQuery helper to optionally return the queryClient, or extract QueryClient creation to a shared function.

Example approach:

// Modify existing setupQuery to return queryClient
export function setupQuery<T>(hook: () => T, options?: RenderAppHookOptions): RenderHookResult<T, unknown> & { queryClient: QueryClient } {
  const queryClient = new QueryClient({
    defaultOptions: {
      queries: {
        retry: false,
        refetchOnWindowFocus: false,
        refetchOnReconnect: false
      }
    }
  });
  // ... rest of implementation
  return { ...renderHook(hook, { wrapper }), queryClient };
}
packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (1)

7-9: Optional: Remove redundant constructor.

The constructor only calls super(config) without any additional logic. Since JavaScript/TypeScript automatically calls the parent constructor when none is defined, this can be safely removed for cleaner code.

Apply this diff:

 export class WalletSettingsHttpService extends ApiHttpService {
-  constructor(config?: AxiosRequestConfig) {
-    super(config);
-  }
-
   async getWalletSettings() {
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (1)

101-107: Optional: Use existing closeMenu function.

Line 103 creates an inline function () => setOpen(false) which is recreated on every render. For consistency and a minor performance improvement, consider using the existing closeMenu function.

Apply this diff:

             <d.DropdownMenuContent
               align="end"
-              onMouseLeave={() => setOpen(false)}
+              onMouseLeave={closeMenu}
               onClick={e => {
apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx (1)

37-40: Wrap onAddCardSuccess in useCallback for consistency.

The onAddCardSuccess function is recreated on every render, potentially causing unnecessary re-renders of child components. While the render-prop pattern somewhat mitigates this, wrapping it in useCallback would be more consistent with the other handlers and follow React best practices.

Additionally, the function is marked async but doesn't await anything. Consider either awaiting refetchPaymentMethods() or removing the async keyword.

Apply this diff:

-  const onAddCardSuccess = async () => {
+  const onAddCardSuccess = useCallback(async () => {
     setShowAddPaymentMethod(false);
-    refetchPaymentMethods();
-  };
+    await refetchPaymentMethods();
+  }, [refetchPaymentMethods]);

Or if awaiting is not necessary:

-  const onAddCardSuccess = async () => {
+  const onAddCardSuccess = useCallback(() => {
     setShowAddPaymentMethod(false);
     refetchPaymentMethods();
-  };
+  }, [refetchPaymentMethods]);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 35b56e4 and 017483b.

📒 Files selected for processing (30)
  • apps/api/src/core/services/feature-flags/feature-flags.ts (1 hunks)
  • apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/BillingPage.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/BillingUsageLayout.tsx (3 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsPage.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (1 hunks)
  • apps/deploy-web/src/pages/payment-methods/index.tsx (1 hunks)
  • apps/deploy-web/src/queries/index.ts (1 hunks)
  • apps/deploy-web/src/queries/queryKeys.ts (1 hunks)
  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx (4 hunks)
  • apps/deploy-web/src/queries/usePaymentQueries.ts (2 hunks)
  • apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx (1 hunks)
  • apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (1 hunks)
  • apps/deploy-web/src/services/app-di-container/app-di-container.ts (2 hunks)
  • apps/deploy-web/src/types/feature-flags.ts (1 hunks)
  • apps/deploy-web/src/utils/urlUtils.ts (1 hunks)
  • apps/deploy-web/tests/seeders/payment.ts (2 hunks)
  • packages/http-sdk/src/index.ts (1 hunks)
  • packages/http-sdk/src/stripe/stripe.service.ts (3 hunks)
  • packages/http-sdk/src/stripe/stripe.types.ts (2 hunks)
  • packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (1 hunks)
  • packages/http-sdk/src/wallet-settings/wallet-settings.types.ts (1 hunks)
  • packages/ui/components/badge.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (15)
  • apps/deploy-web/src/queries/queryKeys.ts
  • apps/deploy-web/src/queries/index.ts
  • apps/deploy-web/src/queries/useWalletSettingsQueries.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsPage.tsx
  • packages/http-sdk/src/stripe/stripe.service.ts
  • apps/deploy-web/src/services/app-di-container/app-di-container.ts
  • packages/ui/components/badge.tsx
  • apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx
  • apps/deploy-web/src/components/billing-usage/BillingPage.tsx
  • apps/deploy-web/tests/seeders/payment.ts
  • apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx
  • packages/http-sdk/src/stripe/stripe.types.ts
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{ts,tsx,js}: Never use type any or cast to type any. Always define the proper TypeScript types.
Never use deprecated methods from libraries.
Don't add unnecessary comments to the code.

Files:

  • apps/deploy-web/src/components/billing-usage/BillingUsageLayout.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx
  • apps/deploy-web/src/pages/payment-methods/index.tsx
  • packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx
  • apps/deploy-web/src/queries/usePaymentQueries.ts
  • packages/http-sdk/src/wallet-settings/wallet-settings.types.ts
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx
  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
  • apps/deploy-web/src/types/feature-flags.ts
  • apps/api/src/core/services/feature-flags/feature-flags.ts
  • packages/http-sdk/src/index.ts
  • apps/deploy-web/src/utils/urlUtils.ts
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/no-jest-mock.mdc)

Don't use jest.mock() in test files. Instead, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test

Use setup function instead of beforeEach in test files. The setup function must be at the bottom of the root describe block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type.

**/*.spec.{ts,tsx}: Use <Subject>.name in the root describe suite description instead of hardcoded class/service name strings to enable automated refactoring tools to find all references
Use either a method name or a condition starting with 'when' for nested suite descriptions in tests
Use present simple, 3rd person singular for test descriptions without prepending 'should'

Files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
{apps/deploy-web,apps/provider-console}/**/*.spec.tsx

📄 CodeRabbit inference engine (.cursor/rules/query-by-in-tests.mdc)

Use queryBy methods instead of getBy methods in test expectations

Files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
🧠 Learnings (9)
📓 Common learnings
Learnt from: baktun14
Repo: akash-network/console PR: 1725
File: apps/api/src/utils/constants.ts:5-5
Timestamp: 2025-07-24T17:00:52.361Z
Learning: In the Akash Network Console project, when cross-cutting concerns or broader refactoring issues are identified during PR review, the preferred approach is to create a separate GitHub issue to track the work rather than expanding the scope of the current PR. This maintains focus and allows for proper planning of architectural improvements.
📚 Learning: 2025-11-25T17:45:44.790Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/no-jest-mock.mdc:0-0
Timestamp: 2025-11-25T17:45:44.790Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use `jest.mock()` in test files. Instead, use `jest-mock-extended` to create mocks and pass mocks as dependencies to the service under test

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
📚 Learning: 2025-11-25T17:45:52.965Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-11-25T17:45:52.965Z
Learning: Applies to **/*.spec.{ts,tsx} : Use `setup` function instead of `beforeEach` in test files. The `setup` function must be at the bottom of the root `describe` block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
📚 Learning: 2025-11-12T16:36:02.543Z
Learnt from: baktun14
Repo: akash-network/console PR: 2203
File: apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx:161-168
Timestamp: 2025-11-12T16:36:02.543Z
Learning: In apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx, the organization field captured during payment method setup is internal metadata. Errors from stripe.updateCustomerOrganization should be logged to Sentry but not surfaced to users, and the flow should continue even if the organization update fails, as it's non-critical and not something users can fix.

Applied to files:

  • apps/deploy-web/src/pages/payment-methods/index.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx
📚 Learning: 2025-09-18T07:50:31.224Z
Learnt from: baktun14
Repo: akash-network/console PR: 1933
File: apps/deploy-web/src/components/onboarding/steps/PaymentVerificationCard/PaymentVerificationCard.tsx:43-63
Timestamp: 2025-09-18T07:50:31.224Z
Learning: PaymentVerificationCard component is wrapped by Stripe Elements provider in its parent component PaymentMethodStep, so PaymentMethodForm inside PaymentVerificationCard has access to Stripe context without needing its own Elements wrapper.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
📚 Learning: 2025-11-25T17:45:49.180Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/query-by-in-tests.mdc:0-0
Timestamp: 2025-11-25T17:45:49.180Z
Learning: Applies to {apps/deploy-web,apps/provider-console}/**/*.spec.tsx : Use `queryBy` methods instead of `getBy` methods in test expectations

Applied to files:

  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
📚 Learning: 2025-07-11T10:46:43.711Z
Learnt from: stalniy
Repo: akash-network/console PR: 1660
File: apps/deploy-web/src/components/alerts/DeploymentAlertsContainer/DeploymentAlertsContainer.spec.tsx:54-56
Timestamp: 2025-07-11T10:46:43.711Z
Learning: In apps/{deploy-web,provider-console}/**/*.spec.tsx files: Use `getBy` methods instead of `queryBy` methods when testing element presence with `toBeInTheDocument()` because `getBy` throws an error and shows DOM state when element is not found, providing better debugging information than `queryBy` which returns null.

Applied to files:

  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
📚 Learning: 2025-11-19T15:15:07.283Z
Learnt from: ygrishajev
Repo: akash-network/console PR: 2254
File: apps/api/test/functional/sign-and-broadcast-tx.spec.ts:4-4
Timestamp: 2025-11-19T15:15:07.283Z
Learning: In the Akash Network Console project, when tests use native Node.js fetch (available in Node 18+), fetch-mock should be used for HTTP mocking instead of nock, as nock does not support intercepting native fetch calls. This applies to apps/api/test/functional/sign-and-broadcast-tx.spec.ts and any other tests using native fetch.

Applied to files:

  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
📚 Learning: 2025-07-28T10:40:13.595Z
Learnt from: stalniy
Repo: akash-network/console PR: 1480
File: apps/deploy-web/src/hooks/useFlag.tsx:0-0
Timestamp: 2025-07-28T10:40:13.595Z
Learning: In the Akash Network Console project, backend-specific feature flags are intentional and acceptable. The frontend FeatureFlag union type should only include flags that are actually used by the frontend, not all flags defined in the backend. Backend can have internal feature flags for backend-only functionality without requiring frontend synchronization.

Applied to files:

  • apps/deploy-web/src/types/feature-flags.ts
  • apps/api/src/core/services/feature-flags/feature-flags.ts
🧬 Code graph analysis (7)
apps/deploy-web/src/components/billing-usage/BillingUsageLayout.tsx (3)
apps/deploy-web/src/hooks/useFlag.tsx (1)
  • useFlag (8-8)
apps/deploy-web/src/utils/urlUtils.ts (1)
  • UrlService (16-82)
apps/provider-console/src/utils/styleUtils.ts (1)
  • cn (4-6)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx (1)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (1)
  • PaymentPopup (80-324)
apps/deploy-web/src/pages/payment-methods/index.tsx (5)
apps/deploy-web/src/hoc/guard/guard.hoc.tsx (2)
  • Guard (9-29)
  • composeGuards (31-44)
apps/deploy-web/src/components/billing-usage/PaymentMethodsPage.tsx (1)
  • PaymentMethodsPage (9-18)
apps/deploy-web/src/hooks/useUser.ts (1)
  • useIsRegisteredUser (22-29)
apps/deploy-web/src/lib/nextjs/defineServerSideProps/defineServerSideProps.ts (1)
  • defineServerSideProps (44-92)
apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.ts (1)
  • isFeatureEnabled (6-8)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (3)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (1)
  • DEPENDENCIES (10-19)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (1)
  • DEPENDENCIES (30-55)
packages/http-sdk/src/stripe/stripe.types.ts (2)
  • PaymentMethod (30-43)
  • SetupIntentResponse (68-70)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (2)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (1)
  • DEPENDENCIES (9-20)
packages/http-sdk/src/stripe/stripe.service.ts (2)
  • confirmPayment (52-54)
  • applyCoupon (44-46)
apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx (2)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (2)
  • DEPENDENCIES (9-20)
  • PaymentMethodsViewProps (22-33)
packages/http-sdk/src/stripe/stripe.service.ts (1)
  • createSetupIntent (24-26)
apps/deploy-web/src/queries/usePaymentQueries.spec.tsx (4)
apps/deploy-web/tests/unit/query-client.tsx (2)
  • RenderAppHookOptions (36-39)
  • setupQuery (9-30)
apps/deploy-web/tests/seeders/payment.ts (1)
  • createMockPaymentMethod (3-22)
apps/deploy-web/src/queries/usePaymentQueries.ts (2)
  • useDefaultPaymentMethodQuery (27-37)
  • usePaymentMutations (67-136)
apps/log-collector/fluent-bit/script/define-outputs.js (1)
  • result (42-42)
⏰ 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). (9)
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: Validate local packages
🔇 Additional comments (21)
apps/deploy-web/src/utils/urlUtils.ts (1)

41-41: LGTM!

The new paymentMethods route follows the established pattern and is correctly placed in the User section.

apps/api/src/core/services/feature-flags/feature-flags.ts (1)

4-5: LGTM!

The new feature flags follow the established pattern and are correctly added to the FeatureFlags constant object.

apps/deploy-web/src/queries/usePaymentQueries.ts (2)

27-37: LGTM!

The useDefaultPaymentMethodQuery hook follows the established pattern used by other query hooks in this file and correctly uses the appropriate query key.


118-127: LGTM!

The setPaymentMethodAsDefault mutation correctly invalidates both the payment methods list and the default payment method queries on success, ensuring cache consistency.

apps/deploy-web/src/queries/usePaymentQueries.spec.tsx (3)

64-77: LGTM!

The test properly verifies that the default payment method is fetched and follows the established testing patterns in this file.


195-220: LGTM!

The test correctly verifies that the validatePaymentMethodAfter3DS mutation invalidates the payment methods query.


222-241: LGTM!

The test properly verifies that both payment methods and default payment method queries are invalidated when a payment method is set as default.

apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (3)

30-55: LGTM!

The DEPENDENCIES map enables effective dependency injection for testing, following a good pattern seen elsewhere in the codebase.


131-176: LGTM!

The payment submission logic properly validates user presence, handles 3DS flow when required, and includes appropriate error handling. The submitted amount is captured before the flow begins for use in callbacks.


178-207: LGTM!

The coupon submission logic correctly validates user presence before applying the coupon and handles both error responses and exceptions appropriately.

apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx (2)

100-757: LGTM!

The test suite provides comprehensive coverage of the PaymentPopup component, including rendering, form validation, payment submission, coupon handling, 3DS flow, error handling, and processing states. The tests follow the project's coding guidelines correctly.


759-941: LGTM!

The setup function follows the project's testing conventions: it's positioned at the bottom of the describe block, creates and returns all necessary test doubles, accepts a single inline-typed parameter, and avoids shared state.

packages/http-sdk/src/index.ts (1)

25-25: LGTM!

The wallet-settings service export follows the established pattern and is correctly positioned in the file.

apps/deploy-web/src/types/feature-flags.ts (1)

9-10: LGTM!

The new feature flags are correctly added to the frontend FeatureFlag union type. Based on learnings, these flags are appropriately placed here as they are used by the frontend.

apps/deploy-web/src/components/billing-usage/BillingUsageLayout.tsx (1)

11-56: LGTM! Clean feature flag integration.

The payment methods tab integration is well-implemented with proper feature flag gating, dynamic layout adjustment, and routing. The conditional rendering ensures the UI adapts seamlessly when the feature is enabled or disabled.

packages/http-sdk/src/wallet-settings/wallet-settings.types.ts (1)

1-11: LGTM! Well-defined TypeScript interfaces.

The type definitions are clear and properly structured for wallet settings operations, with appropriate use of optional fields for partial updates.

apps/deploy-web/src/pages/payment-methods/index.tsx (1)

8-13: LGTM! Proper layered protection.

The page correctly implements both server-side (authentication + feature flag) and client-side (managed wallet + registered user) guards, ensuring secure and appropriate access control.

packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (1)

11-25: LGTM! Consistent HTTP service implementation.

The CRUD methods follow the established patterns in the codebase, with proper use of extractApiData for response processing and appropriate HTTP verbs for each operation.

apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (1)

76-84: LGTM! Dependencies correctly included.

The useCallback hooks now properly include all dependencies, addressing the previous review feedback.

apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (1)

50-56: LGTM! Proper loading state handling.

The loading state correctly renders a centered spinner, providing good UX while data is being fetched.

apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx (1)

23-35: LGTM! Callbacks properly memoized.

The dependency arrays now correctly include all referenced values, addressing previous review feedback.

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: 0

🧹 Nitpick comments (3)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (1)

134-182: Also report payment failures via errorHandler for observability symmetry.

In onPayment, thrown/Stripe errors are surfaced to the user and snackbars, but unlike the coupon path you don’t send them through errorHandler.reportError. Given coupon exceptions are logged with full context (lines 213‑219), it would be good to mirror that here so payment failures also end up in the central error pipeline/Sentry with a clear category and message.

     } catch (error: unknown) {
       const errorInfo = d.handleStripeError(error);
 
       setError(errorInfo.message);
       setErrorAction(errorInfo.userAction);
       enqueueSnackbar(<d.Snackbar title={errorInfo.message} iconVariant="error" />, { variant: "error" });
+      errorHandler.reportError({
+        error,
+        message: "Payment error",
+        tags: { category: "payment" }
+      });
     }

Based on learnings, errors in the payment flows are expected to be logged through the error handler service.

apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx (2)

9-99: Avoid any in test helpers and dependency wiring; keep types explicit.

This spec uses any in many places (mock components’ props, RHF helpers, config objects) and also casts dependencies to any (lines 927‑934), which conflicts with the project rule to never use any / cast to any. Tightening these types will make the tests safer against refactors and keep them aligned with the app code.

Concrete suggestions (pattern you can apply throughout):

  • Give mock components minimal explicit props instead of any, e.g.:
-const MockPopup = ({ children, open, title, actions }: any) => {
+interface MockPopupProps {
+  open: boolean;
+  title?: string;
+  actions?: { label: string; onClick: () => void }[];
+  children?: React.ReactNode;
+}
+
+const MockPopup = ({ children, open, title, actions }: MockPopupProps) => {
  • For RHF field helpers, use more specific shapes instead of any:
-const MockFormField = ({ control, name, render }: any) => {
+type MockControl = {
+  setValue: (name: string, value: unknown) => void;
+  getValues: (name: string) => unknown;
+};
+
+const MockFormField = ({
+  control,
+  name,
+  render
+}: { control: MockControl; name: string; render: (args: { field: { name: string; value: unknown; onChange: (e: React.ChangeEvent<HTMLInputElement> | unknown) => void } }) => React.ReactNode }) => {
  • In setup input, replace any with narrower or domain types or unknown:
   input: {
@@
-    confirmPaymentResponse?: any;
+    confirmPaymentResponse?: { success?: boolean; requiresAction?: boolean; clientSecret?: string; paymentIntentId?: string };
@@
-    applyCouponResponse?: any;
+    applyCouponResponse?: { amountAdded?: number; error?: unknown };
@@
-    stripeErrorResponse?: any;
+    stripeErrorResponse?: { message: string; userAction?: string };
  • Avoid dependencies as any; assert the concrete type instead:
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    dependencies: dependencies as any
+    dependencies

(or, if TS complains, assert against the actual prop shape rather than any:

dependencies: dependencies satisfies React.ComponentProps<typeof PaymentPopup>["dependencies"];

)

Applying this pattern across the mocks and helpers will satisfy the “no any” rule while keeping the tests maintainable.

As per coding guidelines.

Also applies to: 771-804


100-768: Align RTL expectations and describe labels with project testing conventions.

Within apps/deploy-web specs the guidelines call for using queryBy* methods in expectations and having nested suite descriptions as method names or conditions starting with "when". This file currently uses screen.getBy* extensively in expectations (e.g., lines 103‑106, 113‑117, 259‑263, 724‑753) and uses generic nested describe labels such as "Rendering", "Payment Submission", "Error Handling".

To bring this spec in line with those conventions:

  • Prefer queryBy*/findBy* for expectations:
- expect(screen.getByTestId("popup")).toBeInTheDocument();
+ expect(screen.queryByTestId("popup")).toBeInTheDocument();
@@
- const submitButton = screen.getAllByTestId("loading-button")[0];
+ const submitButton = screen.queryAllByTestId("loading-button")[0];

(and similarly for other getByText, getByLabelText, getByPlaceholderText, etc., used only for assertions)

  • Consider renaming nested suites to method/condition style, e.g.:
-describe("Rendering", () => {
+describe("when rendering", () => {
@@
-describe("Payment Submission", () => {
+describe("when submitting payment", () => {

This keeps the tests consistent with the rest of the codebase and makes them easier to scan with the agreed naming patterns.

As per coding guidelines.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 017483b and 141dab7.

📒 Files selected for processing (4)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{ts,tsx,js}: Never use type any or cast to type any. Always define the proper TypeScript types.
Never use deprecated methods from libraries.
Don't add unnecessary comments to the code.

Files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/no-jest-mock.mdc)

Don't use jest.mock() in test files. Instead, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test

Use setup function instead of beforeEach in test files. The setup function must be at the bottom of the root describe block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type.

**/*.spec.{ts,tsx}: Use <Subject>.name in the root describe suite description instead of hardcoded class/service name strings to enable automated refactoring tools to find all references
Use either a method name or a condition starting with 'when' for nested suite descriptions in tests
Use present simple, 3rd person singular for test descriptions without prepending 'should'

Files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
{apps/deploy-web,apps/provider-console}/**/*.spec.tsx

📄 CodeRabbit inference engine (.cursor/rules/query-by-in-tests.mdc)

Use queryBy methods instead of getBy methods in test expectations

Files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
🧠 Learnings (5)
📓 Common learnings
Learnt from: baktun14
Repo: akash-network/console PR: 1725
File: apps/api/src/utils/constants.ts:5-5
Timestamp: 2025-07-24T17:00:52.361Z
Learning: In the Akash Network Console project, when cross-cutting concerns or broader refactoring issues are identified during PR review, the preferred approach is to create a separate GitHub issue to track the work rather than expanding the scope of the current PR. This maintains focus and allows for proper planning of architectural improvements.
📚 Learning: 2025-11-25T17:45:44.790Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/no-jest-mock.mdc:0-0
Timestamp: 2025-11-25T17:45:44.790Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use `jest.mock()` in test files. Instead, use `jest-mock-extended` to create mocks and pass mocks as dependencies to the service under test

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
📚 Learning: 2025-11-25T17:45:52.965Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-11-25T17:45:52.965Z
Learning: Applies to **/*.spec.{ts,tsx} : Use `setup` function instead of `beforeEach` in test files. The `setup` function must be at the bottom of the root `describe` block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
📚 Learning: 2025-11-12T16:36:02.543Z
Learnt from: baktun14
Repo: akash-network/console PR: 2203
File: apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx:161-168
Timestamp: 2025-11-12T16:36:02.543Z
Learning: In apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx, the organization field captured during payment method setup is internal metadata. Errors from stripe.updateCustomerOrganization should be logged to Sentry but not surfaced to users, and the flow should continue even if the organization update fails, as it's non-critical and not something users can fix.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
📚 Learning: 2025-09-18T07:50:31.224Z
Learnt from: baktun14
Repo: akash-network/console PR: 1933
File: apps/deploy-web/src/components/onboarding/steps/PaymentVerificationCard/PaymentVerificationCard.tsx:43-63
Timestamp: 2025-09-18T07:50:31.224Z
Learning: PaymentVerificationCard component is wrapped by Stripe Elements provider in its parent component PaymentMethodStep, so PaymentMethodForm inside PaymentVerificationCard has access to Stripe context without needing its own Elements wrapper.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
🧬 Code graph analysis (2)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx (1)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (1)
  • PaymentPopup (82-338)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (1)
packages/http-sdk/src/stripe/stripe.service.ts (2)
  • confirmPayment (52-54)
  • applyCoupon (44-46)
⏰ 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). (11)
  • GitHub Check: validate (apps/log-collector) / validate-unsafe
  • GitHub Check: validate (apps/notifications) / validate-unsafe
  • GitHub Check: validate / validate-app
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: Validate local packages
🔇 Additional comments (1)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (1)

31-125: Well-structured DI surface and payment/3DS wiring.

The DEPENDENCIES map, typed PaymentPopupProps, and the 3DS onSuccess flow are cleanly designed and keep the component nicely testable and side‑effect boundaries explicit. The success paths (both immediate and 3DS) consistently poll for payment, show success, reset forms, and close the popup, which is exactly what we want for this UI.

@jzsfkzm jzsfkzm force-pushed the features/1779-auto-top-up-settings branch from 141dab7 to a4a562e Compare December 5, 2025 08:31
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

🧹 Nitpick comments (5)
packages/ui/components/badge.tsx (1)

14-15: Hover states correctly implemented!

The previous critical issue regarding the missing bg- prefix in hover states has been successfully resolved. Both variants now correctly use hover:bg-green-600/80 and hover:bg-blue-600/80.

Optional: Consider consistent class ordering for maintainability.

The success and info variants place border-transparent first, while the default, secondary, and destructive variants place it last. Although Tailwind CSS class order doesn't affect the output, maintaining consistent ordering improves code readability.

If you prefer consistency, consider reordering to match the other variants:

-        success: "border-transparent bg-green-600 text-white hover:bg-green-600/80",
-        info: "border-transparent bg-blue-600 text-white hover:bg-blue-600/80",
+        success: "bg-green-600 text-white hover:bg-green-600/80 border-transparent",
+        info: "bg-blue-600 text-white hover:bg-blue-600/80 border-transparent",
apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx (1)

42-45: Wrap onAddCardSuccess in useCallback for consistency.

For consistency with the other callback handlers and to prevent unnecessary re-renders when child components are memoized, onAddCardSuccess should be wrapped in useCallback.

Apply this diff:

-  const onAddCardSuccess = async () => {
+  const onAddCardSuccess = useCallback(async () => {
     setShowAddPaymentMethod(false);
     refetchPaymentMethods();
-  };
+  }, [refetchPaymentMethods]);
apps/deploy-web/tests/seeders/payment.ts (1)

11-12: Mock PaymentMethod additions look good; consider fuller coverage and timestamp units

The extra fingerprint, funding, created, validated, and isDefault fields align well with the HTTP SDK PaymentMethod shape and will make tests more realistic. Two optional tweaks you might consider:

  • Include "prepaid" / "unknown" in the funding variants to exercise the full "credit" | "debit" | "prepaid" | "unknown" union in tests.
  • If the backend continues to use Stripe’s created semantics (Unix seconds), you may want to switch from new Date().getTime() (ms) to seconds for closer end‑to‑end fidelity, or at least confirm that consumers don’t assume a specific unit.

Also, note that createMockItems still uses any, but that predates this PR; given it’s a cross‑cutting clean‑up, it’s probably better handled via a separate tech‑debt issue rather than expanding this change set. Based on learnings, cross‑cutting refactors are usually tracked as separate issues.

Also applies to: 18-20

apps/deploy-web/src/queries/usePaymentQueries.spec.tsx (2)

2-3: setupQueryWithClient correctly exposes QueryClient; minor duplication in test helper

The setupQueryWithClient helper cleanly surfaces a QueryClient instance for spying while still reusing setupQuery for wrapper creation. Because services.queryClient is spread after the default in setupQuery, the wrapper ends up using the same queryClient instance you return here, so the spy observes the real invalidations.

There is a small amount of redundant work since setupQuery still creates its own QueryClient that’s then overridden via services. If this pattern grows, consider extending setupQuery to optionally accept an existing QueryClient (and return it) to avoid the extra instance, but that’s not blocking for this PR.

Also applies to: 23-27, 37-46


179-241: Solid coverage for cache invalidation; consider reusing QueryKeys helpers

The new/updated tests for:

  • Removing a payment method,
  • Validating a payment method after 3DS, and
  • Setting a payment method as default

do a nice job of asserting that QueryClient.invalidateQueries is called with the expected keys after the respective mutations complete.

To reduce duplication and keep tests resilient to future key changes, you might want to import and use the actual query key helpers, e.g. QueryKeys.getPaymentMethodsKey() / QueryKeys.getDefaultPaymentMethodKey(), instead of hard‑coding ["PAYMENT_METHODS"] and ["DEFAULT_PAYMENT_METHOD"] in expectations.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 141dab7 and a4a562e.

📒 Files selected for processing (30)
  • apps/api/src/core/services/feature-flags/feature-flags.ts (1 hunks)
  • apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/BillingPage.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/BillingUsageLayout.tsx (3 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsPage.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (1 hunks)
  • apps/deploy-web/src/pages/payment-methods/index.tsx (1 hunks)
  • apps/deploy-web/src/queries/index.ts (1 hunks)
  • apps/deploy-web/src/queries/queryKeys.ts (1 hunks)
  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx (4 hunks)
  • apps/deploy-web/src/queries/usePaymentQueries.ts (2 hunks)
  • apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx (1 hunks)
  • apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (1 hunks)
  • apps/deploy-web/src/services/app-di-container/app-di-container.ts (2 hunks)
  • apps/deploy-web/src/types/feature-flags.ts (1 hunks)
  • apps/deploy-web/src/utils/urlUtils.ts (1 hunks)
  • apps/deploy-web/tests/seeders/payment.ts (2 hunks)
  • packages/http-sdk/src/index.ts (1 hunks)
  • packages/http-sdk/src/stripe/stripe.service.ts (3 hunks)
  • packages/http-sdk/src/stripe/stripe.types.ts (2 hunks)
  • packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (1 hunks)
  • packages/http-sdk/src/wallet-settings/wallet-settings.types.ts (1 hunks)
  • packages/ui/components/badge.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (18)
  • packages/http-sdk/src/wallet-settings/wallet-settings.types.ts
  • apps/deploy-web/src/utils/urlUtils.ts
  • packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts
  • apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx
  • apps/deploy-web/src/components/billing-usage/BillingPage.tsx
  • apps/deploy-web/src/pages/payment-methods/index.tsx
  • packages/http-sdk/src/index.ts
  • apps/deploy-web/src/queries/queryKeys.ts
  • apps/deploy-web/src/queries/useWalletSettingsQueries.tsx
  • apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx
  • packages/http-sdk/src/stripe/stripe.types.ts
  • apps/deploy-web/src/queries/index.ts
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx
  • apps/deploy-web/src/services/app-di-container/app-di-container.ts
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
  • apps/api/src/core/services/feature-flags/feature-flags.ts
  • apps/deploy-web/src/queries/usePaymentQueries.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{ts,tsx,js}: Never use type any or cast to type any. Always define the proper TypeScript types.
Never use deprecated methods from libraries.
Don't add unnecessary comments to the code.

Files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsPage.tsx
  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
  • packages/http-sdk/src/stripe/stripe.service.ts
  • apps/deploy-web/src/components/billing-usage/BillingUsageLayout.tsx
  • packages/ui/components/badge.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
  • apps/deploy-web/tests/seeders/payment.ts
  • apps/deploy-web/src/types/feature-flags.ts
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/no-jest-mock.mdc)

Don't use jest.mock() in test files. Instead, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test

Use setup function instead of beforeEach in test files. The setup function must be at the bottom of the root describe block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type.

**/*.spec.{ts,tsx}: Use <Subject>.name in the root describe suite description instead of hardcoded class/service name strings to enable automated refactoring tools to find all references
Use either a method name or a condition starting with 'when' for nested suite descriptions in tests
Use present simple, 3rd person singular for test descriptions without prepending 'should'

Files:

  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
{apps/deploy-web,apps/provider-console}/**/*.spec.tsx

📄 CodeRabbit inference engine (.cursor/rules/query-by-in-tests.mdc)

Use queryBy methods instead of getBy methods in test expectations

Files:

  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
🧠 Learnings (12)
📓 Common learnings
Learnt from: baktun14
Repo: akash-network/console PR: 1725
File: apps/api/src/utils/constants.ts:5-5
Timestamp: 2025-07-24T17:00:52.361Z
Learning: In the Akash Network Console project, when cross-cutting concerns or broader refactoring issues are identified during PR review, the preferred approach is to create a separate GitHub issue to track the work rather than expanding the scope of the current PR. This maintains focus and allows for proper planning of architectural improvements.
📚 Learning: 2025-11-25T17:45:49.180Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/query-by-in-tests.mdc:0-0
Timestamp: 2025-11-25T17:45:49.180Z
Learning: Applies to {apps/deploy-web,apps/provider-console}/**/*.spec.tsx : Use `queryBy` methods instead of `getBy` methods in test expectations

Applied to files:

  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
📚 Learning: 2025-07-11T10:46:43.711Z
Learnt from: stalniy
Repo: akash-network/console PR: 1660
File: apps/deploy-web/src/components/alerts/DeploymentAlertsContainer/DeploymentAlertsContainer.spec.tsx:54-56
Timestamp: 2025-07-11T10:46:43.711Z
Learning: In apps/{deploy-web,provider-console}/**/*.spec.tsx files: Use `getBy` methods instead of `queryBy` methods when testing element presence with `toBeInTheDocument()` because `getBy` throws an error and shows DOM state when element is not found, providing better debugging information than `queryBy` which returns null.

Applied to files:

  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
📚 Learning: 2025-11-19T15:15:07.283Z
Learnt from: ygrishajev
Repo: akash-network/console PR: 2254
File: apps/api/test/functional/sign-and-broadcast-tx.spec.ts:4-4
Timestamp: 2025-11-19T15:15:07.283Z
Learning: In the Akash Network Console project, when tests use native Node.js fetch (available in Node 18+), fetch-mock should be used for HTTP mocking instead of nock, as nock does not support intercepting native fetch calls. This applies to apps/api/test/functional/sign-and-broadcast-tx.spec.ts and any other tests using native fetch.

Applied to files:

  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
📚 Learning: 2025-11-25T17:45:44.790Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/no-jest-mock.mdc:0-0
Timestamp: 2025-11-25T17:45:44.790Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use `jest.mock()` in test files. Instead, use `jest-mock-extended` to create mocks and pass mocks as dependencies to the service under test

Applied to files:

  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
📚 Learning: 2025-11-25T17:45:52.965Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-11-25T17:45:52.965Z
Learning: Applies to **/*.spec.{ts,tsx} : Use `setup` function instead of `beforeEach` in test files. The `setup` function must be at the bottom of the root `describe` block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type.

Applied to files:

  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
📚 Learning: 2025-11-12T16:36:02.543Z
Learnt from: baktun14
Repo: akash-network/console PR: 2203
File: apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx:161-168
Timestamp: 2025-11-12T16:36:02.543Z
Learning: In apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx, the organization field captured during payment method setup is internal metadata. Errors from stripe.updateCustomerOrganization should be logged to Sentry but not surfaced to users, and the flow should continue even if the organization update fails, as it's non-critical and not something users can fix.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
📚 Learning: 2025-09-18T07:50:31.224Z
Learnt from: baktun14
Repo: akash-network/console PR: 1933
File: apps/deploy-web/src/components/onboarding/steps/PaymentVerificationCard/PaymentVerificationCard.tsx:43-63
Timestamp: 2025-09-18T07:50:31.224Z
Learning: PaymentVerificationCard component is wrapped by Stripe Elements provider in its parent component PaymentMethodStep, so PaymentMethodForm inside PaymentVerificationCard has access to Stripe context without needing its own Elements wrapper.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
📚 Learning: 2025-11-25T17:45:58.258Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/test-descriptions.mdc:0-0
Timestamp: 2025-11-25T17:45:58.258Z
Learning: Applies to **/*.spec.{ts,tsx} : Use either a method name or a condition starting with 'when' for nested suite descriptions in tests

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
📚 Learning: 2025-11-25T17:45:58.258Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/test-descriptions.mdc:0-0
Timestamp: 2025-11-25T17:45:58.258Z
Learning: Applies to **/*.spec.{ts,tsx} : Use present simple, 3rd person singular for test descriptions without prepending 'should'

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
📚 Learning: 2025-11-25T17:45:58.258Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/test-descriptions.mdc:0-0
Timestamp: 2025-11-25T17:45:58.258Z
Learning: Applies to **/*.spec.{ts,tsx} : Use `<Subject>.name` in the root describe suite description instead of hardcoded class/service name strings to enable automated refactoring tools to find all references

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
📚 Learning: 2025-07-28T10:40:13.595Z
Learnt from: stalniy
Repo: akash-network/console PR: 1480
File: apps/deploy-web/src/hooks/useFlag.tsx:0-0
Timestamp: 2025-07-28T10:40:13.595Z
Learning: In the Akash Network Console project, backend-specific feature flags are intentional and acceptable. The frontend FeatureFlag union type should only include flags that are actually used by the frontend, not all flags defined in the backend. Backend can have internal feature flags for backend-only functionality without requiring frontend synchronization.

Applied to files:

  • apps/deploy-web/src/types/feature-flags.ts
🧬 Code graph analysis (7)
apps/deploy-web/src/components/billing-usage/PaymentMethodsPage.tsx (4)
apps/provider-console/src/components/layout/Layout.tsx (1)
  • Layout (22-43)
apps/deploy-web/src/components/billing-usage/BillingUsageLayout.tsx (1)
  • BillingUsageLayout (25-65)
apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx (1)
  • PaymentMethodsContainer (17-75)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (1)
  • PaymentMethodsView (39-112)
apps/deploy-web/src/queries/usePaymentQueries.spec.tsx (4)
apps/deploy-web/tests/unit/query-client.tsx (2)
  • RenderAppHookOptions (36-39)
  • setupQuery (9-30)
apps/deploy-web/tests/seeders/payment.ts (1)
  • createMockPaymentMethod (3-22)
packages/http-sdk/src/stripe/stripe.service.ts (1)
  • StripeService (19-103)
apps/deploy-web/src/queries/usePaymentQueries.ts (2)
  • useDefaultPaymentMethodQuery (27-37)
  • usePaymentMutations (67-136)
apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx (5)
apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx (1)
  • PaymentMethodsContainer (17-75)
apps/deploy-web/tests/seeders/payment.ts (2)
  • createMockPaymentMethod (3-22)
  • createMockSetupIntentResponse (57-60)
packages/http-sdk/src/stripe/stripe.types.ts (2)
  • PaymentMethod (30-43)
  • SetupIntentResponse (68-70)
apps/deploy-web/src/queries/usePaymentQueries.ts (3)
  • usePaymentMethodsQuery (15-25)
  • usePaymentMutations (67-136)
  • useSetupIntentMutation (57-65)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (1)
  • PaymentMethodsViewProps (25-37)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (4)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (1)
  • DEPENDENCIES (10-19)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (1)
  • DEPENDENCIES (10-23)
packages/http-sdk/src/stripe/stripe.service.ts (2)
  • confirmPayment (52-54)
  • applyCoupon (44-46)
apps/api/src/billing/services/wallet-balance-reload-check/wallet-balance-reload-check.handler.ts (1)
  • user (137-156)
packages/http-sdk/src/stripe/stripe.service.ts (2)
packages/http-sdk/src/stripe/stripe.types.ts (2)
  • PaymentMethod (30-43)
  • SetPaymentMethodAsDefaultParams (118-120)
apps/api/src/billing/services/stripe/stripe.service.ts (1)
  • PaymentMethod (35-35)
apps/deploy-web/src/components/billing-usage/BillingUsageLayout.tsx (3)
apps/deploy-web/src/hooks/useFlag.tsx (1)
  • useFlag (8-8)
apps/deploy-web/src/utils/urlUtils.ts (1)
  • UrlService (16-82)
apps/provider-console/src/utils/styleUtils.ts (1)
  • cn (4-6)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx (1)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (1)
  • PaymentPopup (82-338)
⏰ 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). (9)
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: Validate local packages
🔇 Additional comments (18)
apps/deploy-web/src/types/feature-flags.ts (1)

9-10: LGTM!

The addition of the auto_credit_reload feature flag to the union type is correct and aligns with the backend flag definition mentioned in the AI summary.

apps/deploy-web/src/components/billing-usage/BillingUsageLayout.tsx (3)

11-11: LGTM!

The feature flag import and initialization are correct.

Also applies to: 16-16, 27-27


34-36: LGTM!

The routing logic for the PAYMENT_METHODS tab is correct and properly integrated into the switch statement.


48-56: LGTM!

The conditional rendering of the Payment Methods tab and the grid layout adjustment based on the feature flag are implemented correctly. The tab is only shown when the flag is enabled, and the grid adapts from 2 to 3 columns accordingly.

apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx (2)

14-153: LGTM!

The test suite comprehensively covers all aspects of the PaymentMethodsContainer component, including rendering, loading states, mutations, and state management. The tests follow the coding guidelines correctly:

  • Uses PaymentMethodsContainer.name in the root describe
  • Test descriptions use present simple, 3rd person singular
  • Uses queryBy for negative assertions appropriately

155-226: LGTM!

The setup function follows the coding guidelines correctly:

  • Positioned at the bottom of the root describe block
  • Accepts a single parameter with inline type definition
  • Avoids shared state
  • Does not have a specified return type
  • Creates mocks and returns them for test assertions
apps/deploy-web/src/components/billing-usage/PaymentMethodsPage.tsx (1)

1-18: LGTM!

The PaymentMethodsPage component is well-structured with clean composition. It properly wires together the Layout, BillingUsageLayout, and the PaymentMethodsContainer/PaymentMethodsView pair using the render-prop pattern.

apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx (3)

28-33: LGTM!

The useCallback implementations for onSetPaymentMethodAsDefault, onRemovePaymentMethod, and onAddPaymentMethod are correct with proper dependencies.

Also applies to: 35-40, 47-51


53-57: LGTM!

The isInProgress derived state correctly aggregates all loading and pending flags from the various operations.


59-74: LGTM!

The render-prop pattern implementation correctly passes all necessary props to children, enabling flexible UI composition.

apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx (2)

74-349: LGTM!

The test suite is comprehensive and follows all coding guidelines correctly:

  • Uses PaymentMethodsRow.name in the root describe
  • Test descriptions use present simple, 3rd person singular
  • Uses queryBy for negative assertions and getBy for positive assertions
  • No jest.mock() usage; mocks are created inline
  • Covers rendering, interactions, callbacks, edge cases, and state management

402-442: LGTM!

The setup function follows the coding guidelines correctly:

  • Positioned at the bottom of the root describe block
  • Accepts a single parameter with inline type definition
  • Avoids shared state
  • Does not have a specified return type
  • Properly creates and returns mock functions for assertions
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (1)

1-337: Well-implemented payment popup component.

The code properly addresses previous review feedback, implements comprehensive error handling with user validation guards, integrates 3D Secure flow correctly, and maintains clean TypeScript types throughout. The dependency injection pattern enhances testability.

apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx (1)

771-955: Excellent setup function implementation.

The setup function correctly follows coding guidelines: positioned at the bottom of the root describe block, accepts a single parameter with inline type definition, avoids shared state, creates comprehensive mocks, and has no specified return type. The dependency injection approach enables thorough testing of various scenarios.

apps/deploy-web/tests/seeders/payment.ts (1)

57-60: createMockSetupIntentResponse helper is consistent with clientSecret‑based flows

The new createMockSetupIntentResponse mirrors the expected { clientSecret } response shape and matches the existing setup‑intent ID/secret pattern. Looks good for tests that only care about the client secret.

packages/http-sdk/src/stripe/stripe.service.ts (2)

32-34: getDefaultPaymentMethod wiring is consistent with existing StripeService calls

The new getDefaultPaymentMethod uses the same extractApiData + /v1/stripe/payment-methods/default pattern as the other Stripe endpoints. No issues spotted here.


13-17: Verify setPaymentMethodAsDefault return type against actual implementation and test behavior

setPaymentMethodAsDefault is typed to return Promise<PaymentMethod[]>, but tests reportedly configure it to resolve to a single PaymentMethod instance without array handling. Before making changes:

  • Confirm the actual backend API response shape
  • Verify whether the implementation should return Promise<PaymentMethod> or Promise<PaymentMethod[]>
  • Align tests and usages to match the confirmed signature

This impacts type safety and consumer expectations of the API contract.

apps/deploy-web/src/queries/usePaymentQueries.spec.tsx (1)

64-77: Default payment method query test is well‑structured

The new "fetches default payment method" test correctly wires a typed StripeService mock, runs useDefaultPaymentMethodQuery through the shared test harness, and asserts both the service call and the successful data propagation. This gives good coverage for the new query hook.

@jzsfkzm jzsfkzm force-pushed the features/1779-auto-top-up-settings branch from a4a562e to cc36d58 Compare December 8, 2025 20:40
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: 0

♻️ Duplicate comments (1)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx (1)

100-769: Align expectations and suite naming with test guidelines

Two style points relative to the test guidelines:

  • Many positive assertions use screen.getBy* or screen.getAllBy* directly in expectations (e.g., Lines 103–106, 113–135, 136–139, 259–263, 583–588, 615–627, 653–665, 691–703, 725–733, 735–743, 753–766). The current rule for {apps/deploy-web,apps/provider-console}/**/*.spec.tsx is to use queryBy*/queryAllBy* in expectations, and reserve getBy* for when you’re actually retrieving an element to interact with (e.g., before fireEvent.click or fireEvent.change). This was already noted in an earlier review on this file.

    Example change:

  • expect(screen.getByTestId("popup")).toBeInTheDocument();

  • expect(screen.getByText("Add Funds")).toBeInTheDocument();

  • expect(screen.queryByTestId("popup")).toBeInTheDocument();
  • expect(screen.queryByText("Add Funds")).toBeInTheDocument();
    
    You can keep `getBy*` for cases like fetching the "Cancel" button or inputs prior to `fireEvent`.
    
  • Nested describe labels such as "Rendering", "Payment Form Validation", "Payment Submission", "Coupon Submission", "3D Secure Flow", "Error Handling", "Cancel Functionality", and "Processing States" don’t follow the “method name or condition starting with when” convention from the test description guidelines. Over time, you might want to migrate these to something like describe("onPayment", ...) or describe("when open is true", ...) for better consistency with other suites.

Given the size of the file, it’s reasonable to handle these as a style pass (or a follow-up refactor) rather than blocking this functional change.

As per coding guidelines.

🧹 Nitpick comments (10)
apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx (1)

155-225: setup helper is well-structured and type-safe

The setup function at the bottom of the root describe follows the prescribed pattern: single parameter with inline type, no explicit return type, no shared state, and typed mocks for the query/mutation hooks. Using hasOwnProperty to distinguish omitted vs. explicitly undefined paymentMethods is a nice touch for testing the container’s defaulting logic.

apps/deploy-web/src/queries/usePaymentQueries.ts (1)

118-135: setPaymentMethodAsDefault mutation and cache invalidation look correct

The setPaymentMethodAsDefault mutation delegates to stripe.setPaymentMethodAsDefault({ id }) and invalidates both getPaymentMethodsKey and getDefaultPaymentMethodKey, which should keep the UI in sync after changing the default. Returning it from usePaymentMutations alongside removePaymentMethod fits the existing API.

packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (1)

6-25: WalletSettingsHttpService follows established SDK patterns

The new service cleanly encapsulates /v1/wallet-settings CRUD operations, uses WalletSettings / UpdateWalletSettingsParams types, and relies on extractApiData like other HTTP services. This should integrate smoothly with the DI container and wallet settings queries.

apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (1)

13-16: Consider simplifying the queryFn.

The response variable is redundant since you're immediately returning it.

Apply this diff to simplify:

     queryFn: async () => {
-      const response = await walletSettings.getWalletSettings();
-      return response;
+      return walletSettings.getWalletSettings();
     }
apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx (3)

42-45: Wrap callback in useCallback for performance.

The onAddCardSuccess function is passed to children as a prop but isn't memoized, which can cause unnecessary re-renders.

Apply this diff:

- const onAddCardSuccess = async () => {
+ const onAddCardSuccess = useCallback(async () => {
    setShowAddPaymentMethod(false);
    refetchPaymentMethods();
- };
+ }, [refetchPaymentMethods]);

47-51: Include setState in useCallback dependencies.

While setShowAddPaymentMethod from useState is stable, including it in the dependency array follows React best practices and satisfies exhaustive-deps linting rules.

Apply this diff:

  const onAddPaymentMethod = useCallback(() => {
    resetSetupIntent();
    createSetupIntent();
    setShowAddPaymentMethod(true);
- }, [createSetupIntent, resetSetupIntent]);
+ }, [createSetupIntent, resetSetupIntent, setShowAddPaymentMethod]);

53-57: Consider memoizing derived state.

The isInProgress value is recomputed on every render. Wrapping it in useMemo could provide a minor performance benefit.

Apply this diff:

+ import React, { useCallback, useMemo, useState } from "react";
+
  const isInProgress =
-   isLoadingPaymentMethods ||
+   useMemo(() => isLoadingPaymentMethods ||
    isRefetchingPaymentMethods ||
    paymentMutations.setPaymentMethodAsDefault.isPending ||
-   paymentMutations.removePaymentMethod.isPending;
+   paymentMutations.removePaymentMethod.isPending, [
+     isLoadingPaymentMethods,
+     isRefetchingPaymentMethods,
+     paymentMutations.setPaymentMethodAsDefault.isPending,
+     paymentMutations.removePaymentMethod.isPending
+   ]);
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (1)

134-221: Minor UX/flow polish in payment and coupon handlers

The payment and coupon flows look logically correct and are well-guarded, but there are a few small UX/behavior tweaks you might consider:

  • error / errorAction are only cleared via clearError(). If a user closes and reopens the popup after an error, they’ll see the old error again. Calling clearError() in onClose (or when open flips from false → true) would avoid stale errors.
  • applyCoupon treats any non-error response (including amountAdded === 0) as “Coupon applied successfully!”. If 0 is effectively a no-op, you might want a different message or branch so users aren’t confused by “success” with no added credits.
  • While a payment is confirming or polling, the coupon button stays enabled (only the payment path is gated by isProcessing). If concurrent payment + coupon mutations are undesirable, consider reusing isProcessing to also disable/mark loading for the coupon button.

All of these are non-blocking but would tighten the UX.

apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx (2)

10-99: Replace explicit any / as any in mocks and setup with typed props

This file relies heavily on any (mock component props, form helpers, setup input types, and dependencies as any), which goes against the project guideline to avoid any in TS/TSX files.

Concretely:

  • Mock components (MockPopup, MockCard*, MockForm, MockFormField, MockFormInput, MockLoadingButton, MockFormattedNumber, MockAlert, MockButton, MockXmark, MockSnackbar) all declare props as any.
  • setup’s input uses confirmPaymentResponse?: any, applyCouponResponse?: any, stripeErrorResponse?: any.
  • Helpers like createMockForm and paymentSubmitHandler/couponSubmitHandler also use any.
  • dependencies is cast to any with an eslint override before passing into PaymentPopup.

To keep tests type-safe and aligned with the guidelines, consider:

  • Introducing small interfaces for the mock component props (e.g. MockPopupProps, MockFormFieldProps, MockFormInputProps extends InputHTMLAttributes<HTMLInputElement>, etc.) instead of any.

  • Defining minimal response types for the mutation results, e.g.:

    type ConfirmPaymentTestResponse = {
      success?: boolean;
      requiresAction?: boolean;
      clientSecret?: string;
      paymentIntentId?: string;
    };
    
    type ApplyCouponTestResponse = {
      error?: string;
      amountAdded?: number;
    };
    
    type StripeErrorInfo = {
      message: string;
      userAction?: string;
    };

    and using these in the setup input instead of any.

  • Typing dependencies structurally, for example:

    import { DEPENDENCIES } from "./PaymentPopup";
    
    const dependencies: typeof DEPENDENCIES = { /* mocks */ };
    
    const props: React.ComponentProps<typeof PaymentPopup> = {
      // ...
      dependencies,
    };

    which removes the need for as any and the eslint suppression.

This keeps the tests strongly typed while still allowing flexible mocks.

Also applies to: 771-804, 808-810, 815-857, 867-873, 885-925, 927-934


147-184: Validation tests currently don’t assert observable behavior

The “Payment Form Validation” tests only exercise trigger/setValue on the mocked form and then assert that mockUseForm was called or that getValues returns a number. They don’t verify that validation errors are surfaced or that invalid values prevent submission.

If you want these tests to be meaningful, consider:

  • Asserting on visible validation feedback (e.g., error text) by letting the real zodResolver and useForm run, or
  • Asserting that invalid amounts do not result in confirmPayment being invoked, while valid ones do.

If validating via real RHF/zod is too heavy here, it might be simpler to drop the negative-value/minimum tests and keep only the “accepts valid amount” test that checks the handler logic.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a4a562e and cc36d58.

📒 Files selected for processing (30)
  • apps/api/src/core/services/feature-flags/feature-flags.ts (1 hunks)
  • apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/BillingPage.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/BillingUsageLayout.tsx (3 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsPage.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (1 hunks)
  • apps/deploy-web/src/pages/payment-methods/index.tsx (1 hunks)
  • apps/deploy-web/src/queries/index.ts (1 hunks)
  • apps/deploy-web/src/queries/queryKeys.ts (1 hunks)
  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx (4 hunks)
  • apps/deploy-web/src/queries/usePaymentQueries.ts (2 hunks)
  • apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx (1 hunks)
  • apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (1 hunks)
  • apps/deploy-web/src/services/app-di-container/app-di-container.ts (2 hunks)
  • apps/deploy-web/src/types/feature-flags.ts (1 hunks)
  • apps/deploy-web/src/utils/urlUtils.ts (1 hunks)
  • apps/deploy-web/tests/seeders/payment.ts (2 hunks)
  • packages/http-sdk/src/index.ts (1 hunks)
  • packages/http-sdk/src/stripe/stripe.service.ts (3 hunks)
  • packages/http-sdk/src/stripe/stripe.types.ts (2 hunks)
  • packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (1 hunks)
  • packages/http-sdk/src/wallet-settings/wallet-settings.types.ts (1 hunks)
  • packages/ui/components/badge.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/http-sdk/src/wallet-settings/wallet-settings.types.ts
🚧 Files skipped from review as they are similar to previous changes (17)
  • packages/http-sdk/src/stripe/stripe.types.ts
  • apps/deploy-web/src/queries/queryKeys.ts
  • apps/deploy-web/src/components/billing-usage/BillingPage.tsx
  • apps/deploy-web/src/components/billing-usage/BillingUsageLayout.tsx
  • packages/ui/components/badge.tsx
  • apps/deploy-web/src/utils/urlUtils.ts
  • apps/deploy-web/src/queries/usePaymentQueries.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsPage.tsx
  • apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx
  • packages/http-sdk/src/index.ts
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx
  • apps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsx
  • apps/deploy-web/tests/seeders/payment.ts
  • apps/deploy-web/src/types/feature-flags.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{ts,tsx,js}: Never use type any or cast to type any. Always define the proper TypeScript types.
Never use deprecated methods from libraries.
Don't add unnecessary comments to the code.

Files:

  • apps/deploy-web/src/services/app-di-container/app-di-container.ts
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
  • packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx
  • apps/deploy-web/src/queries/usePaymentQueries.ts
  • apps/deploy-web/src/queries/index.ts
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
  • apps/deploy-web/src/queries/useWalletSettingsQueries.tsx
  • apps/api/src/core/services/feature-flags/feature-flags.ts
  • packages/http-sdk/src/stripe/stripe.service.ts
  • apps/deploy-web/src/pages/payment-methods/index.tsx
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/no-jest-mock.mdc)

Don't use jest.mock() in test files. Instead, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test

Use setup function instead of beforeEach in test files. The setup function must be at the bottom of the root describe block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type.

**/*.spec.{ts,tsx}: Use <Subject>.name in the root describe suite description instead of hardcoded class/service name strings to enable automated refactoring tools to find all references
Use either a method name or a condition starting with 'when' for nested suite descriptions in tests
Use present simple, 3rd person singular for test descriptions without prepending 'should'

Files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
{apps/deploy-web,apps/provider-console}/**/*.spec.tsx

📄 CodeRabbit inference engine (.cursor/rules/query-by-in-tests.mdc)

Use queryBy methods instead of getBy methods in test expectations

Files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
🧠 Learnings (11)
📓 Common learnings
Learnt from: baktun14
Repo: akash-network/console PR: 1725
File: apps/api/src/utils/constants.ts:5-5
Timestamp: 2025-07-24T17:00:52.361Z
Learning: In the Akash Network Console project, when cross-cutting concerns or broader refactoring issues are identified during PR review, the preferred approach is to create a separate GitHub issue to track the work rather than expanding the scope of the current PR. This maintains focus and allows for proper planning of architectural improvements.
📚 Learning: 2025-11-12T16:36:02.543Z
Learnt from: baktun14
Repo: akash-network/console PR: 2203
File: apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx:161-168
Timestamp: 2025-11-12T16:36:02.543Z
Learning: In apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx, the organization field captured during payment method setup is internal metadata. Errors from stripe.updateCustomerOrganization should be logged to Sentry but not surfaced to users, and the flow should continue even if the organization update fails, as it's non-critical and not something users can fix.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx
  • apps/deploy-web/src/pages/payment-methods/index.tsx
📚 Learning: 2025-09-18T07:50:31.224Z
Learnt from: baktun14
Repo: akash-network/console PR: 1933
File: apps/deploy-web/src/components/onboarding/steps/PaymentVerificationCard/PaymentVerificationCard.tsx:43-63
Timestamp: 2025-09-18T07:50:31.224Z
Learning: PaymentVerificationCard component is wrapped by Stripe Elements provider in its parent component PaymentMethodStep, so PaymentMethodForm inside PaymentVerificationCard has access to Stripe context without needing its own Elements wrapper.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
📚 Learning: 2025-11-25T17:45:52.965Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-11-25T17:45:52.965Z
Learning: Applies to **/*.spec.{ts,tsx} : Use `setup` function instead of `beforeEach` in test files. The `setup` function must be at the bottom of the root `describe` block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
📚 Learning: 2025-11-19T15:15:07.283Z
Learnt from: ygrishajev
Repo: akash-network/console PR: 2254
File: apps/api/test/functional/sign-and-broadcast-tx.spec.ts:4-4
Timestamp: 2025-11-19T15:15:07.283Z
Learning: In the Akash Network Console project, when tests use native Node.js fetch (available in Node 18+), fetch-mock should be used for HTTP mocking instead of nock, as nock does not support intercepting native fetch calls. This applies to apps/api/test/functional/sign-and-broadcast-tx.spec.ts and any other tests using native fetch.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
📚 Learning: 2025-11-25T17:45:49.180Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/query-by-in-tests.mdc:0-0
Timestamp: 2025-11-25T17:45:49.180Z
Learning: Applies to {apps/deploy-web,apps/provider-console}/**/*.spec.tsx : Use `queryBy` methods instead of `getBy` methods in test expectations

Applied to files:

  • apps/deploy-web/src/queries/index.ts
  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
📚 Learning: 2025-11-25T17:45:44.790Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/no-jest-mock.mdc:0-0
Timestamp: 2025-11-25T17:45:44.790Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use `jest.mock()` in test files. Instead, use `jest-mock-extended` to create mocks and pass mocks as dependencies to the service under test

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
📚 Learning: 2025-07-11T10:46:43.711Z
Learnt from: stalniy
Repo: akash-network/console PR: 1660
File: apps/deploy-web/src/components/alerts/DeploymentAlertsContainer/DeploymentAlertsContainer.spec.tsx:54-56
Timestamp: 2025-07-11T10:46:43.711Z
Learning: In apps/{deploy-web,provider-console}/**/*.spec.tsx files: Use `getBy` methods instead of `queryBy` methods when testing element presence with `toBeInTheDocument()` because `getBy` throws an error and shows DOM state when element is not found, providing better debugging information than `queryBy` which returns null.

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
📚 Learning: 2025-11-25T17:45:58.258Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/test-descriptions.mdc:0-0
Timestamp: 2025-11-25T17:45:58.258Z
Learning: Applies to **/*.spec.{ts,tsx} : Use present simple, 3rd person singular for test descriptions without prepending 'should'

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
📚 Learning: 2025-11-25T17:45:58.258Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/test-descriptions.mdc:0-0
Timestamp: 2025-11-25T17:45:58.258Z
Learning: Applies to **/*.spec.{ts,tsx} : Use `<Subject>.name` in the root describe suite description instead of hardcoded class/service name strings to enable automated refactoring tools to find all references

Applied to files:

  • apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
📚 Learning: 2025-07-28T10:40:13.595Z
Learnt from: stalniy
Repo: akash-network/console PR: 1480
File: apps/deploy-web/src/hooks/useFlag.tsx:0-0
Timestamp: 2025-07-28T10:40:13.595Z
Learning: In the Akash Network Console project, backend-specific feature flags are intentional and acceptable. The frontend FeatureFlag union type should only include flags that are actually used by the frontend, not all flags defined in the backend. Backend can have internal feature flags for backend-only functionality without requiring frontend synchronization.

Applied to files:

  • apps/api/src/core/services/feature-flags/feature-flags.ts
🧬 Code graph analysis (7)
apps/deploy-web/src/services/app-di-container/app-di-container.ts (3)
packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (1)
  • WalletSettingsHttpService (6-26)
apps/deploy-web/src/services/auth/auth/auth.service.ts (1)
  • withUserToken (53-63)
apps/deploy-web/src/services/auth/auth/interceptors.ts (1)
  • withUserToken (15-25)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (1)
packages/http-sdk/src/stripe/stripe.service.ts (2)
  • confirmPayment (52-54)
  • applyCoupon (44-46)
apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx (1)
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx (2)
  • DEPENDENCIES (10-23)
  • PaymentMethodsViewProps (25-37)
apps/deploy-web/src/queries/usePaymentQueries.ts (5)
packages/http-sdk/src/stripe/stripe.types.ts (1)
  • PaymentMethod (30-43)
apps/api/src/billing/http-schemas/stripe.schema.ts (1)
  • PaymentMethod (236-236)
apps/api/src/billing/services/stripe/stripe.service.ts (1)
  • PaymentMethod (35-35)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
  • useServices (31-33)
packages/http-sdk/src/stripe/stripe.service.ts (1)
  • setPaymentMethodAsDefault (60-62)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx (1)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (1)
  • PaymentPopup (82-338)
apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (3)
packages/http-sdk/src/wallet-settings/wallet-settings.types.ts (2)
  • WalletSettings (1-3)
  • UpdateWalletSettingsParams (9-11)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
  • useServices (31-33)
packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (3)
  • updateWalletSettings (19-21)
  • createWalletSettings (15-17)
  • deleteWalletSettings (23-25)
apps/deploy-web/src/pages/payment-methods/index.tsx (5)
apps/deploy-web/src/hoc/guard/guard.hoc.tsx (2)
  • Guard (9-29)
  • composeGuards (31-44)
apps/deploy-web/src/components/billing-usage/PaymentMethodsPage.tsx (1)
  • PaymentMethodsPage (9-18)
apps/deploy-web/src/hooks/useUser.ts (1)
  • useIsRegisteredUser (22-29)
apps/deploy-web/src/lib/nextjs/defineServerSideProps/defineServerSideProps.ts (1)
  • defineServerSideProps (44-92)
apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.ts (1)
  • isFeatureEnabled (6-8)
⏰ 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). (9)
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: Validate local packages
🔇 Additional comments (20)
apps/deploy-web/src/queries/index.ts (1)

8-8: Expose wallet settings queries via barrel file

Re-exporting ./useWalletSettingsQueries here keeps the queries surface consistent and discoverable alongside other hooks. Looks good.

apps/api/src/core/services/feature-flags/feature-flags.ts (1)

4-5: AUTO_CREDIT_RELOAD flag wiring is consistent

The new AUTO_CREDIT_RELOAD: "auto_credit_reload" entry follows the existing pattern and automatically extends FeatureFlagValue. No issues here.

apps/deploy-web/src/services/app-di-container/app-di-container.ts (2)

1-12: WalletSettingsHttpService correctly added to HTTP SDK imports

Including WalletSettingsHttpService alongside the other HTTP services keeps the DI surface aligned with the SDK exports. No issues.


94-97: DI registration for walletSettings matches existing patterns

The walletSettings provider uses WalletSettingsHttpService(apiConfig) wrapped with withUserToken, consistent with other authenticated API services (e.g., deploymentSetting, usage). This should integrate cleanly with useServices.

apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx (1)

14-154: Comprehensive container behavior coverage and guideline-compliant tests

The tests thoroughly exercise data shaping, mutation callbacks, showAddPaymentMethod toggling, setupIntent handling, and isInProgress aggregation. Naming, assertions, and the absence of getBy* queries align with the repo’s testing guidelines for *.spec.tsx.

apps/deploy-web/src/queries/usePaymentQueries.ts (1)

27-37: useDefaultPaymentMethodQuery mirrors existing query patterns

The new useDefaultPaymentMethodQuery uses the dedicated query key and stripe.getDefaultPaymentMethod() inside useQuery, matching the conventions used by usePaymentMethodsQuery. Looks consistent and type-safe.

packages/http-sdk/src/stripe/stripe.service.ts (3)

13-17: New SetPaymentMethodAsDefaultParams type integration is clean

Pulling SetPaymentMethodAsDefaultParams into the service’s type imports keeps the method signature strongly typed without introducing any.


32-35: getDefaultPaymentMethod endpoint aligns with Stripe payment-methods API shape

getDefaultPaymentMethod() uses extractApiData on /v1/stripe/payment-methods/default, mirroring existing payment-methods endpoints and returning a typed PaymentMethod. No concerns.


60-62: setPaymentMethodAsDefault endpoint and payload are consistent

setPaymentMethodAsDefault(params) posts { data: params } to /v1/stripe/payment-methods/default and returns PaymentMethod[], which matches the frontend’s usage pattern (ignoring the response but relying on cache invalidation). Implementation looks sound.

apps/deploy-web/src/pages/payment-methods/index.tsx (2)

1-8: Client-side guards correctly protect PaymentMethodsPage

Wrapping PaymentMethodsPage with Guard and composeGuards(useIsManagedWalletUser, useIsRegisteredUser) is consistent with existing guarded pages and ensures only eligible users see the UI.


10-13: Server-side gating with auth + auto_credit_reload feature flag is appropriate

getServerSideProps uses defineServerSideProps with isAuthenticated and isFeatureEnabled("auto_credit_reload", ctx), so the route 404s when the feature is off or the user is unauthenticated. This complements the client-side guards and ties neatly into the new feature flag.

apps/deploy-web/src/queries/useWalletSettingsQueries.tsx (2)

1-6: LGTM!

The imports are properly structured with correct type imports from the http-sdk and React Query libraries.


20-56: LGTM!

The mutations follow a consistent pattern with proper type safety and query invalidation. All three mutations correctly invalidate the wallet settings cache on success, ensuring the UI stays in sync.

apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx (4)

1-10: LGTM!

The imports and DEPENDENCIES object are well-structured, enabling dependency injection for testing.


12-15: LGTM!

The render-prop pattern is correctly typed, enabling flexible composition and testability.


17-26: LGTM!

The component setup properly wires dependencies and hooks following React best practices.


59-74: LGTM!

The render-prop implementation correctly passes all necessary props to children, enabling flexible composition.

apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx (2)

31-57: Well-structured dependency injection surface for testability

Exporting DEPENDENCIES and threading it via the dependencies prop keeps the component highly testable and aligns with the DI pattern used elsewhere in the app. No issues here from a correctness or design standpoint.


223-299: Render logic and error presentation look consistent and well-covered

The way isProcessing/disabled drive the loading state of the Pay button, the “select a payment method” hint, and the detailed Payment Error alert (including suggestion text and a clear button that wires into clearError) is coherent and matches the behaviors exercised in the spec. No further issues on this part.

apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx (1)

186-488: Comprehensive behavioral coverage for payment, coupon, 3DS, and error flows

The suite does a solid job of exercising the key behaviors of PaymentPopup:

  • Payment submission paths for success, missing method, unauthenticated user, requires-action (3DS), and thrown errors.
  • 3D Secure configuration and onSuccess callback behavior with submittedAmountRef.
  • Coupon submission success, error responses, and thrown exceptions, including logging via errorHandler.
  • Error alert rendering/clearing and processing/disabled states across payment and coupon paths.
  • Cancel button wiring and popup open/closed rendering.

The DI-based setup helper plus mock forms make these flows explicit and maintainable. From a functional perspective, this coverage looks very good.

Also applies to: 490-768

@ygrishajev ygrishajev merged commit 46b0a99 into akash-network:main Dec 9, 2025
63 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants