-
Notifications
You must be signed in to change notification settings - Fork 77
feat: account overview, auto reload, and separate payment method page #2282
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: account overview, auto reload, and separate payment method page #2282
Conversation
WalkthroughAdds 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
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report❌ Patch coverage is 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
*This pull request uses carry forward flags. Click here to find out more.
🚀 New features to boost your workflow:
|
There was a problem hiding this 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: Refinethemedhelper to handle non-"light"resolvedThemevalues more predictablyRight now, anything other than
"light"is treated as dark:return resolvedTheme === "light" ? light : dark;If
resolvedThemeis everundefinedor 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
resolvedThemeis temporarily unset or extended in the future.
53-61: Optional: avoid duplicating style logic between base styles and focus/blur handlersFocus/blur handlers directly mutate
borderColorandboxShadow, 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 usingthemed) 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 forgetWalletSettingsKey
getWalletSettingsKeyreturns 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
responsevariable 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/awaitwrapper 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
createWalletSettingsanddeleteWalletSettings.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 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 typeanyor cast to typeany. 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.tsapps/deploy-web/src/components/user/payment/index.tsapps/deploy-web/src/types/feature-flags.tsapps/deploy-web/src/components/shared/StripeInput/StripeInput.tsxapps/deploy-web/src/queries/useWalletSettingsQueries.tsxapps/api/src/core/services/feature-flags/feature-flags.tspackages/http-sdk/src/index.tsapps/deploy-web/src/components/user/payment/PaymentPopup.tsxpackages/http-sdk/src/wallet-settings/wallet-settings-http.service.tsapps/deploy-web/src/components/shared/PaymentMethodsList/PaymentMethodsList.tsxapps/deploy-web/src/pages/payment.tsxpackages/http-sdk/src/wallet-settings/wallet-settings.types.tsapps/deploy-web/src/services/app-di-container/app-di-container.tsapps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsxapps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsxapps/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, usejest-mock-extendedto create mocks and pass mocks as dependencies to the service under testUse
setupfunction instead ofbeforeEachin test files. Thesetupfunction must be at the bottom of the rootdescribeblock, 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>.namein 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
queryBymethods instead ofgetBymethods 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.tsapps/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.tsxapps/deploy-web/src/components/shared/PaymentMethodsList/PaymentMethodsList.tsxapps/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.tsxapps/deploy-web/src/components/shared/PaymentMethodsList/PaymentMethodsList.tsxapps/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.tsapps/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-containedThe use of the
themedhelper 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 goodRe‑exporting
./useWalletSettingsQueriesfrom 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 forWalletSettingsHttpServiceis consistentAdding
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 wiredRe‑exporting
AutoReloadSettingsPopupfrom 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: Newauto_credit_reloadfeature flag is correctly addedExtending the
FeatureFlagunion 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 flagAUTO_CREDIT_RELOADdefinition is consistentDefining
AUTO_CREDIT_RELOAD: "auto_credit_reload"and relying onFeatureFlagValueastypeof FeatureFlags[keyof typeof FeatureFlags]keeps the backend contract in sync with the frontendFeatureFlagunion.packages/http-sdk/src/wallet-settings/wallet-settings.types.ts (1)
1-15: Wallet settings type shapes look appropriate; confirm API nullabilityThe
WalletSettings,WalletSettingsResponse, andUpdateWalletSettingsParamsinterfaces match the intended usage inWalletSettingsHttpService(requiredautoReloadEnabled, optional threshold/amount, partial update payload), which is a clean and predictable contract.One thing to double‑check with the API is whether
autoReloadThresholdorautoReloadAmountcan ever benullin responses; if so, the field types here may need to be widened tonumber | nullto stay accurate.apps/deploy-web/src/services/app-di-container/app-di-container.ts (1)
2-12: DI wiring forWalletSettingsHttpServiceis consistent with existing servicesImporting
WalletSettingsHttpServiceand registering awalletSettingsfactory that wraps it withapplyAxiosInterceptorsandwithUserTokenmatches 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.namereferences for nested describes, and thesetupQueryhelper. 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
displayOnCardprop is well-typed and has a reasonable default value oftrueto maintain backward compatibility.
36-63: Good extraction of radio group for code reuse.Extracting
paymentMethodRadioGroupreduces duplication between the card-wrapped and unwrapped variants. The conditional rendering based ondisplayOnCardis 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
extractApiDatafor 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
hasSomethingToSavememo 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
useris undefined, an empty string is passed asuserId. 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
applyCouponcall also usesuser?.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: falseavoids duplicate notifications since success is shown viasetShowPaymentSuccess.
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.
apps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsx
Outdated
Show resolved
Hide resolved
apps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsx
Outdated
Show resolved
Hide resolved
| <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> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| <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.
There was a problem hiding this 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<in auto‑reload summary textIn the “Auto Reload” box, the text uses
<, 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 < ${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 goodThe new layout helpers are clean, and
HalfBoxProps/WideBoxPropsare well-typed without usingany, 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 ownvarianttype 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 togglesThe new auto‑reload state (
showAutoReloadSettings, wallet settings hooks) andhandleReloadChangeimplementation (with defaults, try/catch, and user feedback) look solid and satisfy the “noany” guideline. To harden UX, consider disabling the Switch while the underlying create/update wallet settings mutation is in flight (e.g., track a localisUpdatingflag 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
📒 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 typeanyor cast to typeany. 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 consistentUsing
PaymentMethodsListin selectable mode plus a dedicated “Add New Payment Method” CTA, followed by theBillingContainer/BillingViewsection, keeps behavior and composition aligned with existing shared components; no functional issues stand out here.
393-463: Legacy payment flow preserved cleanly behind feature flagThe fallback branch for when
isAutoCreditReloadEnabledis 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
PaymentPopupandAutoReloadSettingsPopupare both gated by their respectiveshow*flags and receive minimal, focused props (includingsetShowPaymentSuccessfor the top‑up flow), so they won’t mount unexpectedly and integrate cleanly with the page state.
2ca6f36 to
1a5327e
Compare
There was a problem hiding this 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
<HTML entity will render literally as "<" instead of "<" in JSX.Apply this diff:
- Reload ${walletSettings?.autoReloadAmount || DEFAULT_RELOAD_AMOUNT} when < ${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.tsxbecomes 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
falsewhen 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
📒 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 typeanyor cast to typeany. 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.tsapps/deploy-web/src/pages/payment.tsxapps/deploy-web/src/types/feature-flags.tsapps/deploy-web/src/queries/queryKeys.tsapps/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.tsapps/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.tsxapps/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.tsxapps/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_reloadfeature 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
HalfBoxcomponent 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
WideBoxcomponent 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.
1a5327e to
0d62c20
Compare
There was a problem hiding this 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 labelhtmlFor/ inputidmismatches for accessibilityBoth auto‑reload inputs have label
htmlForvalues that don’t match the corresponding inputids, breaking click‑to‑focus and screen‑reader association:
- Label uses
htmlFor="threshold-input"but inputid="threshold".- Label uses
htmlFor="reloadAmount-input"but inputid="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
<HTML entity will render literally as "<" instead of "<" in JSX. Use the<character directly.Apply this diff:
- Reload ${walletSettings?.autoReloadAmount || DEFAULT_RELOAD_AMOUNT} when < ${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 implicitanyand tighten typingRight now the
get/post/put+extractApiDatacalls rely on default generics, effectively flowinganythrough the pipeline. To better align with the “noany” guideline and get compile‑time safety on response shapes, explicitly passWalletSettings: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 emptyuserIdto 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” stateCurrently
isProcessingdoesn’t includeisApplyingCoupon, 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 intoisProcessing:- 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 asetuphelper and shallower imports for maintainabilityThe test flows and assertions look good, and they use
jest-mock-extendedas required. Two optional tweaks:
- You repeat the
walletSettingsServicemock +setupQuerywiring in several tests. To align with the project’s “setup function” test pattern and reduce duplication, you could extract a smallsetuphelper inside theuseWalletSettingsQueriesdescribe (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 loadingWhile
isLoadingis true, you render a spinner butisPendingis still false andhasSomethingToSavereturnstrue(becausewalletSettingsis 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
isLoadingintoisPending:- 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
handleReloadChangecallback 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.isBlockchainDownis 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
📒 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 typeanyor cast to typeany. 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.tsapps/deploy-web/src/queries/useWalletSettingsQueries.spec.tsxapps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsxapps/deploy-web/src/components/user/payment/PaymentPopup.tsxapps/deploy-web/src/components/user/payment/index.tspackages/http-sdk/src/wallet-settings/wallet-settings-http.service.tsapps/deploy-web/src/queries/index.tsapps/deploy-web/src/types/feature-flags.tsapps/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, usejest-mock-extendedto create mocks and pass mocks as dependencies to the service under testUse
setupfunction instead ofbeforeEachin test files. Thesetupfunction must be at the bottom of the rootdescribeblock, 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>.namein 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
queryBymethods instead ofgetBymethods 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.tsapps/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.tsxapps/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.tsxapps/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 forAutoReloadSettingsPopupis correctThe 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 usageAdding
"maintenance_banner"and"auto_credit_reload"to theFeatureFlagunion is consistent with the pattern of only exposing flags actually used in the frontend (the payment page consumesauto_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 frontendFeatureFlagunion and the payment page’s use ofuseFlag("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
HalfBoxcomponent is properly typed with explicit prop types, addressing the previousanytype 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
PaymentPopupandAutoReloadSettingsPopupcomponents are properly integrated with conditional rendering.
apps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsx
Outdated
Show resolved
Hide resolved
0d62c20 to
fac1e7b
Compare
There was a problem hiding this 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 forNaN. WhenparseFloatreturnsNaN, both comparisons fail andamountErroris 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- callingsetReloadAmount(parseFloat(e.target.value))can storeNaNwhen 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,parseFloatreturnsNaN, 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
<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 < ${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
📒 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 typeanyor cast to typeany. 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.tsapps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsxapps/deploy-web/src/components/user/payment/PaymentPopup.tsxapps/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.tsxapps/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.tsxapps/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
apps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsx
Outdated
Show resolved
Hide resolved
ygrishajev
left a comment
There was a problem hiding this 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 🙏
apps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsx
Outdated
Show resolved
Hide resolved
apps/deploy-web/src/components/user/payment/AutoReloadSettingsPopup.tsx
Outdated
Show resolved
Hide resolved
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
Show resolved
Hide resolved
fac1e7b to
99b1bac
Compare
There was a problem hiding this 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 forfunding.The
fundingfield is currently typed asstring, 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
📒 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 typeanyor cast to typeany. 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.tsxapps/deploy-web/src/queries/index.tspackages/http-sdk/src/stripe/stripe.types.tsapps/deploy-web/src/utils/urlUtils.tsapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsxapps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsxapps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsxapps/deploy-web/src/pages/payment-methods/index.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsxapps/deploy-web/src/queries/usePaymentQueries.tspackages/http-sdk/src/wallet-settings/wallet-settings.types.tsapps/deploy-web/src/types/feature-flags.tsapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsxapps/deploy-web/tests/seeders/payment.tsapps/deploy-web/src/components/billing-usage/PaymentMethodsPage.tsxapps/deploy-web/src/queries/useWalletSettingsQueries.tsxpackages/http-sdk/src/stripe/stripe.service.tsapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsxapps/deploy-web/src/components/billing-usage/BillingPage.tsxapps/api/src/core/services/feature-flags/feature-flags.tspackages/ui/components/badge.tsxapps/deploy-web/src/services/app-di-container/app-di-container.tsapps/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, usejest-mock-extendedto create mocks and pass mocks as dependencies to the service under testUse
setupfunction instead ofbeforeEachin test files. Thesetupfunction must be at the bottom of the rootdescribeblock, 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>.namein 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.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsxapps/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
queryBymethods instead ofgetBymethods in test expectations
Files:
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsxapps/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.tsapps/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.tsxapps/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.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsxapps/deploy-web/tests/seeders/payment.tsapps/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.tsxapps/deploy-web/src/pages/payment-methods/index.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsxapps/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.tsxapps/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.tsapps/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 (
fingerprintandfunding) 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
validatedandisDefaultfields can be overridden via theoverridesparameter when needed.
57-60: LGTM!The new
createMockSetupIntentResponsefunction 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
SetPaymentMethodAsDefaultParamsinterface is correctly defined with the requiredidfield.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
AccountOverviewcomponent 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 frontendFeatureFlagunion 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
setPaymentMethodAsDefaultmutation 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_reloadfeature 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
WalletSettingsHttpServiceis properly integrated into the DI container with thewithUserTokeninterceptor 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
setPaymentMethodAsDefaultmethod 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
setupfunction 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
PaymentMethodsPagecomponent 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.namefor the root describe block and implements thesetupfunction 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_reloadfeature 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
UpdateWalletSettingsParamsappropriately 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.
.../deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx
Outdated
Show resolved
Hide resolved
.../deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx
Outdated
Show resolved
Hide resolved
.../deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx
Outdated
Show resolved
Hide resolved
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx
Outdated
Show resolved
Hide resolved
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx
Outdated
Show resolved
Hide resolved
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsx
Outdated
Show resolved
Hide resolved
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
Show resolved
Hide resolved
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
Show resolved
Hide resolved
apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx
Outdated
Show resolved
Hide resolved
apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx
Outdated
Show resolved
Hide resolved
apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx
Outdated
Show resolved
Hide resolved
apps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsx
Outdated
Show resolved
Hide resolved
.../deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx
Outdated
Show resolved
Hide resolved
.../deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx
Outdated
Show resolved
Hide resolved
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx
Outdated
Show resolved
Hide resolved
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
Outdated
Show resolved
Hide resolved
There was a problem hiding this 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
selectedPaymentMethodIddependency is unnecessary since the effect only readspaymentMethodsand setsselectedPaymentMethodId. 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 usinganytype for mock components and dependencies.The mock components and
mockDependenciesobject useanyextensively, 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
mockDependenciesastypeof DEPENDENCIESinstead ofany.Also applies to: 39-45, 47-58
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (2)
46-61: Consider simplifyingcardandvalidUntilto useMemo.These callbacks take
paymentMethodas a parameter even though it's already in scope. Since they return JSX and are called with the samepaymentMethodfrom props, they would be cleaner asuseMemovalues.- 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
defaultBadgememo depends on the entirepaymentMethodobject but only usespaymentMethod.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
DEPENDENCIESconstant should be exported so tests can properly type thedependenciesprop override.-const DEPENDENCIES = { +export const DEPENDENCIES = { usePaymentMethodsQuery, usePaymentMutations, useSetupIntentMutation };
37-40: WraponAddCardSuccessin 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
isDropdownOpenvariable is module-level mutable state that persists between tests. While it appears to work due to howMockDropdownMenuupdates 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 usinganytype for mock components.Multiple mock components and
mockDependenciesuseanytype, 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
mockDependenciesproperly.Also applies to: 34-38, 56-61, 63-72
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 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 typeanyor cast to typeany. 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.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsxpackages/ui/components/badge.tsxapps/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, usejest-mock-extendedto create mocks and pass mocks as dependencies to the service under testUse
setupfunction instead ofbeforeEachin test files. Thesetupfunction must be at the bottom of the rootdescribeblock, 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>.namein 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.tsxapps/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
queryBymethods instead ofgetBymethods in test expectations
Files:
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsxapps/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.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsxapps/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.tsxapps/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.tsxapps/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.tsxapps/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.tsxapps/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.tsxapps/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.tsxapps/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.tsxapps/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
successandinfovariants now correctly usehover:bg-green-600/80andhover:bg-blue-600/80respectively, which are valid Tailwind utilities. The missingbg-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.namefor the root describe block, enabling automated refactoring tools to find all references.
374-427: LGTM!The
setupfunction 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
useCallbackhooks now correctly includeonSetPaymentMethodAsDefault,onRemovePaymentMethod, andpaymentMethod.idin their dependency arrays.
86-124: LGTM!The component structure is well-organized with proper conditional rendering for the dropdown menu based on
hasOtherPaymentMethodsandisDefaultflags. The dependency injection pattern viadallows for clean testing.apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsx (2)
42-46: LGTM!The
onAddPaymentMethodcallback now correctly includescreateSetupIntentandresetSetupIntentin the dependency array.
23-35: Consider handling or awaiting mutation promises, or verify global error handling is configured.The
mutateAsynccalls are fire-and-forget without local error handling. In TanStack Query v5, whileonErrorcallbacks are still supported at the mutation level or viaMutationCache, unhandled rejections could cause issues if no global error handling is configured. Verify that either:
- A
MutationCachewithonErrorhandler is configured in yourQueryClientsetup, ordefaultOptions.mutations.onErroris configured, or- These specific mutations include error handling via mutation options or
try/catchat the call site.apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsx (4)
74-74: LGTM!Good use of
PaymentMethodsRow.namefor 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
setupfunction follows coding guidelines: positioned at bottom, inline type definition, creates and returns the component with mocks, avoids shared state.
dc4e315 to
1519b96
Compare
There was a problem hiding this 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: Replaceanytypes with proper TypeScript types in mock components.Mock components use
anyextensively 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: UsequeryBymethods instead ofgetBymethods in test expectations.Per coding guidelines for
{apps/deploy-web,apps/provider-console}/**/*.spec.tsx, usequeryBymethods instead ofgetBymethods 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 inexpect()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
inputparameter usesanyfor 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: Replaceanytypes with proper types in mock form implementation.The
createMockFormfunction and submit handlers useanytypes.+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 toany.The eslint-disable comment at line 918 casts
dependenciestoany, 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
dependenciesobject match the expected types fromDEPENDENCIESin the component.apps/deploy-web/src/queries/usePaymentQueries.spec.tsx (1)
191-241: Consider usingQueryKeysinstead 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 inQueryKeys, these tests would pass incorrectly or fail silently. Consider importing and using the actualQueryKeysmethods 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 usinganytype for mock dependencies.Per coding guidelines, avoid using
anytype. Consider importing theDEPENDENCIEStype 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
typeofpattern:import { DEPENDENCIES } from "./PaymentMethodsRow"; const mockDependencies: typeof DEPENDENCIES = { ... };
16-21: Global mutable state for mock could cause test interference.The
isDropdownOpenvariable 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
onSuccesshandlers 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
useMemohere 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: unknownbut 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
Buttoncomponent 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 addingButtonto theDEPENDENCIESobject and accessing it asd.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
📒 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 typeanyor cast to typeany. 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.tsxapps/deploy-web/src/queries/useWalletSettingsQueries.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsxpackages/http-sdk/src/wallet-settings/wallet-settings-http.service.tsapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsxapps/deploy-web/src/queries/usePaymentQueries.tsapps/deploy-web/src/pages/payment-methods/index.tsxapps/deploy-web/src/queries/usePaymentQueries.spec.tsxapps/deploy-web/src/types/feature-flags.tsapps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsxapps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsxpackages/http-sdk/src/index.tsapps/deploy-web/src/components/billing-usage/BillingPage.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsxpackages/ui/components/badge.tsxapps/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, usejest-mock-extendedto create mocks and pass mocks as dependencies to the service under testUse
setupfunction instead ofbeforeEachin test files. Thesetupfunction must be at the bottom of the rootdescribeblock, 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>.namein 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.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsxapps/deploy-web/src/queries/usePaymentQueries.spec.tsxapps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsxapps/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
queryBymethods instead ofgetBymethods in test expectations
Files:
apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsxapps/deploy-web/src/queries/usePaymentQueries.spec.tsxapps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsxapps/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.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsxapps/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.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.spec.tsxapps/deploy-web/src/queries/usePaymentQueries.spec.tsxapps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsxapps/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.tsxapps/deploy-web/src/queries/usePaymentQueries.spec.tsxapps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsxapps/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.tsxapps/deploy-web/src/queries/usePaymentQueries.spec.tsxapps/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.tsxapps/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.tsxapps/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.tsxapps/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.tsxapps/deploy-web/src/queries/usePaymentQueries.spec.tsxapps/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.tsapps/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.
successandinfoboth use the correcthover:bg-.../80syntax 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 ofPaymentPopup.namein 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
setupfunction is correctly placed at the bottom of the rootdescribeblock, 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 avoidsjest.mock()as per coding guidelines.apps/deploy-web/src/queries/usePaymentQueries.ts (2)
27-37: LGTM!The new
useDefaultPaymentMethodQueryhook follows the established pattern in this file, properly using theQueryKeysutility and the Stripe service. The type annotation is consistent with other query hooks.
118-127: LGTM!The
setPaymentMethodAsDefaultmutation 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-structuredsetupfunction.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
setupQueryWithClienthelper appropriately exposes thequeryClientfor 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
useDefaultPaymentMethodQueryfollows 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-structuredsetupfunction 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, usesextractApiDatafor response unwrapping, and has appropriate TypeScript typing. The CRUD operations map cleanly to REST endpoints.
19-21: Verify thatputmethod is available in the base class.The
ApiHttpServiceclass shown in the relevant snippets only overridespost,patch, andgetmethods. Ensure thatputis available (likely inherited fromHttpService). If not, consider usingpatchfor partial updates or addingputtoApiHttpService.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.namein the describe block as required by coding guidelines.
374-427: LGTM!The
setupfunction 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
queryBymethods 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
toggleAutoReloadcallback correctly handles both creating new settings and updating existing settings, with appropriate success feedback.
54-56: LGTM!The
isReloadChangeDisabledlogic 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
useIsManagedWalletUseranduseIsRegisteredUser, while the server-side only checksisAuthenticatedandisFeatureEnabled("auto_credit_reload"). If theauto_credit_reloadfeature 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; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 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.
...oy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
Show resolved
Hide resolved
...oy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx
Show resolved
Hide resolved
1519b96 to
35b56e4
Compare
There was a problem hiding this 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.
openMenuuses a function declaration whilecloseMenuuses 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: Replaceanytypes with proper type definitions.The mock components use
anyfor 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
anyor cast to typeany. Always define the proper TypeScript types."
102-144: UsequeryBymethods instead ofgetByin assertions.Per coding guidelines for test files in this path, use
queryBymethods 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
queryBymethods instead ofgetBymethods in test expectations."
759-941: Movesetupfunction inside the describe block.The
setupfunction should be at the bottom of the rootdescribeblock, not outside it.Move the entire
setupfunction inside thedescribe(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
setupfunction must be at the bottom of the rootdescribeblock."apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx (3)
46-52:useCallbackprovides no benefit here.Since
cardreceivespaymentMethodas 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:useCallbackwith inline invocation.This has the same problem as
cardabove. 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:closeMenuis missing from dependency arrays.Both callbacks reference
closeMenuwhich is recreated on each render. InlinesetOpen(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 viaQueryKeysconstants instead of raw arrays.The invalidation tests currently hard‑code
["PAYMENT_METHODS"]and["DEFAULT_PAYMENT_METHOD"]. Importing and usingQueryKeys.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
📒 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 typeanyor cast to typeany. 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.tsxapps/deploy-web/src/queries/usePaymentQueries.tsapps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsxpackages/http-sdk/src/stripe/stripe.service.tsapps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsxapps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsxapps/deploy-web/src/queries/usePaymentQueries.spec.tsxapps/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, usejest-mock-extendedto create mocks and pass mocks as dependencies to the service under testUse
setupfunction instead ofbeforeEachin test files. Thesetupfunction must be at the bottom of the rootdescribeblock, 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>.namein 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.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsxapps/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
queryBymethods instead ofgetBymethods in test expectations
Files:
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsxapps/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.tsxapps/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.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsxapps/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.tsxapps/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.tsxapps/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
useRefforsubmittedAmountRefto 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: unknowntyping 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
createMockFormhelper and the call-counting approach formockUseFormeffectively 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.namefor 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
PaymentMethodtype 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
useMemoto 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 testsThe suite exercises all key behaviors of
PaymentMethodsContainer(data/defaulting, loading flag, both mutations, setup-intent flow,showAddPaymentMethodstate, andonAddCardSuccessrefetch) and wires dependencies via thedependenciesprop with strongly typed mocks. Thesetuphelper at the bottom of the rootdescribefollows 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 forpaymentMethods. The previousmutatevsmutateAsyncmismatch is also correctly aligned with the container implementation now.As per coding guidelines, this spec matches the expected
setuppattern and avoidsjest.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 typedUseQueryOptions<PaymentMethod>) is consistent with existing patterns and keeps the query easily configurable viaoptions.
118-135: Good invalidation strategy for setting default payment method.The mutation correctly wraps the service call and invalidates both
PAYMENT_METHODSandDEFAULT_PAYMENT_METHODquery keys, keeping list and default views in sync with minimal extra logic.apps/deploy-web/src/queries/usePaymentQueries.spec.tsx (2)
25-46: Test helpersetupQueryWithClientis a solid pattern.Creating an isolated
QueryClientand injecting it viaservices.queryClientkeeps tests deterministic and makes spying oninvalidateQueriesstraightforward without touching global React Query state.
64-77: Default payment method query coverage is appropriate.The test exercises
useDefaultPaymentMethodQueryend‑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.totalDeploymentGrantsUSDas the displayed amount; givenuseWalletBalancealso exposestotalUsdand 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: ConfirmsetPaymentMethodAsDefaultresponse shape (array vs single item).This is typed as
Promise<PaymentMethod[]>, but downstream usage and tests may treat it like a singlePaymentMethod. Please confirm the backend contract forPOST /v1/stripe/payment-methods/defaultand align the return type and mocks/consumers (either change this toPromise<PaymentMethod>or update callers to handle an array and rename accordingly for clarity).
35b56e4 to
017483b
Compare
There was a problem hiding this 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
setupQueryWithClientfunction duplicates the QueryClient creation logic. Consider refactoring the existingsetupQueryhelper to optionally return thequeryClient, 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 existingcloseMenufunction.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
onAddCardSuccessfunction is recreated on every render, potentially causing unnecessary re-renders of child components. While the render-prop pattern somewhat mitigates this, wrapping it inuseCallbackwould be more consistent with the other handlers and follow React best practices.Additionally, the function is marked
asyncbut doesn'tawaitanything. Consider either awaitingrefetchPaymentMethods()or removing theasynckeyword.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
📒 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 typeanyor cast to typeany. 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.tsxapps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsxapps/deploy-web/src/pages/payment-methods/index.tsxpackages/http-sdk/src/wallet-settings/wallet-settings-http.service.tsapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsxapps/deploy-web/src/queries/usePaymentQueries.tspackages/http-sdk/src/wallet-settings/wallet-settings.types.tsapps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsxapps/deploy-web/src/queries/usePaymentQueries.spec.tsxapps/deploy-web/src/types/feature-flags.tsapps/api/src/core/services/feature-flags/feature-flags.tspackages/http-sdk/src/index.tsapps/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, usejest-mock-extendedto create mocks and pass mocks as dependencies to the service under testUse
setupfunction instead ofbeforeEachin test files. Thesetupfunction must be at the bottom of the rootdescribeblock, 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>.namein 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.tsxapps/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
queryBymethods instead ofgetBymethods in test expectations
Files:
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsxapps/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.tsxapps/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.tsxapps/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.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsxapps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsxapps/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.tsxapps/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.tsapps/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
paymentMethodsroute 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
FeatureFlagsconstant object.apps/deploy-web/src/queries/usePaymentQueries.ts (2)
27-37: LGTM!The
useDefaultPaymentMethodQueryhook follows the established pattern used by other query hooks in this file and correctly uses the appropriate query key.
118-127: LGTM!The
setPaymentMethodAsDefaultmutation 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
extractApiDatafor 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.
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx
Outdated
Show resolved
Hide resolved
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.tsx
Show resolved
Hide resolved
apps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsView.tsx
Outdated
Show resolved
Hide resolved
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
Outdated
Show resolved
Hide resolved
There was a problem hiding this 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 viaerrorHandlerfor observability symmetry.In
onPayment, thrown/Stripe errors are surfaced to the user and snackbars, but unlike the coupon path you don’t send them througherrorHandler.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: Avoidanyin test helpers and dependency wiring; keep types explicit.This spec uses
anyin many places (mock components’ props, RHF helpers, config objects) and also castsdependenciestoany(lines 927‑934), which conflicts with the project rule to never useany/ cast toany. 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
setupinput, replaceanywith narrower or domain types orunknown: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 usesscreen.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
📒 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 typeanyor cast to typeany. 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.tsxapps/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, usejest-mock-extendedto create mocks and pass mocks as dependencies to the service under testUse
setupfunction instead ofbeforeEachin test files. Thesetupfunction must be at the bottom of the rootdescribeblock, 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>.namein 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
queryBymethods instead ofgetBymethods 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
DEPENDENCIESmap, typedPaymentPopupProps, and the 3DSonSuccessflow 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.
141dab7 to
a4a562e
Compare
There was a problem hiding this 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 usehover:bg-green-600/80andhover:bg-blue-600/80.Optional: Consider consistent class ordering for maintainability.
The
successandinfovariants placeborder-transparentfirst, while thedefault,secondary, anddestructivevariants 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,
onAddCardSuccessshould be wrapped inuseCallback.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 unitsThe extra
fingerprint,funding,created,validated, andisDefaultfields align well with the HTTP SDKPaymentMethodshape and will make tests more realistic. Two optional tweaks you might consider:
- Include
"prepaid"/"unknown"in thefundingvariants to exercise the full"credit" | "debit" | "prepaid" | "unknown"union in tests.- If the backend continues to use Stripe’s
createdsemantics (Unix seconds), you may want to switch fromnew 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
createMockItemsstill usesany, 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 helperThe
setupQueryWithClienthelper cleanly surfaces aQueryClientinstance for spying while still reusingsetupQueryfor wrapper creation. Becauseservices.queryClientis spread after the default insetupQuery, the wrapper ends up using the samequeryClientinstance you return here, so the spy observes the real invalidations.There is a small amount of redundant work since
setupQuerystill creates its ownQueryClientthat’s then overridden via services. If this pattern grows, consider extendingsetupQueryto optionally accept an existingQueryClient(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 helpersThe 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.invalidateQueriesis 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
📒 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 typeanyor cast to typeany. 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.tsxapps/deploy-web/src/queries/usePaymentQueries.spec.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsxapps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsxpackages/http-sdk/src/stripe/stripe.service.tsapps/deploy-web/src/components/billing-usage/BillingUsageLayout.tsxpackages/ui/components/badge.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsxapps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsxapps/deploy-web/tests/seeders/payment.tsapps/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, usejest-mock-extendedto create mocks and pass mocks as dependencies to the service under testUse
setupfunction instead ofbeforeEachin test files. Thesetupfunction must be at the bottom of the rootdescribeblock, 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>.namein 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.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsxapps/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
queryBymethods instead ofgetBymethods in test expectations
Files:
apps/deploy-web/src/queries/usePaymentQueries.spec.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsxapps/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.tsxapps/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.tsxapps/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.tsxapps/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.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsxapps/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.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsView/PaymentMethodsRow.spec.tsxapps/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.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsxapps/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_reloadfeature 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.namein the root describe- Test descriptions use present simple, 3rd person singular
- Uses
queryByfor negative assertions appropriately
155-226: LGTM!The
setupfunction 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, andonAddPaymentMethodare correct with proper dependencies.Also applies to: 35-40, 47-51
53-57: LGTM!The
isInProgressderived 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.namein the root describe- Test descriptions use present simple, 3rd person singular
- Uses
queryByfor negative assertions andgetByfor positive assertions- No
jest.mock()usage; mocks are created inline- Covers rendering, interactions, callbacks, edge cases, and state management
402-442: LGTM!The
setupfunction 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
setupfunction 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 flowsThe new
createMockSetupIntentResponsemirrors 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 callsThe new
getDefaultPaymentMethoduses the sameextractApiData+/v1/stripe/payment-methods/defaultpattern as the other Stripe endpoints. No issues spotted here.
13-17: Verify setPaymentMethodAsDefault return type against actual implementation and test behavior
setPaymentMethodAsDefaultis typed to returnPromise<PaymentMethod[]>, but tests reportedly configure it to resolve to a singlePaymentMethodinstance without array handling. Before making changes:
- Confirm the actual backend API response shape
- Verify whether the implementation should return
Promise<PaymentMethod>orPromise<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‑structuredThe new
"fetches default payment method"test correctly wires a typedStripeServicemock, runsuseDefaultPaymentMethodQuerythrough the shared test harness, and asserts both the service call and the successful data propagation. This gives good coverage for the new query hook.
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
Show resolved
Hide resolved
a4a562e to
cc36d58
Compare
There was a problem hiding this 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 guidelinesTwo style points relative to the test guidelines:
Many positive assertions use
screen.getBy*orscreen.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.tsxis to usequeryBy*/queryAllBy*in expectations, and reservegetBy*for when you’re actually retrieving an element to interact with (e.g., beforefireEvent.clickorfireEvent.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
describelabels 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 withwhen” convention from the test description guidelines. Over time, you might want to migrate these to something likedescribe("onPayment", ...)ordescribe("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-safeThe
setupfunction at the bottom of the rootdescribefollows the prescribed pattern: single parameter with inline type, no explicit return type, no shared state, and typed mocks for the query/mutation hooks. UsinghasOwnPropertyto distinguish omitted vs. explicitlyundefinedpaymentMethodsis 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 correctThe
setPaymentMethodAsDefaultmutation delegates tostripe.setPaymentMethodAsDefault({ id })and invalidates bothgetPaymentMethodsKeyandgetDefaultPaymentMethodKey, which should keep the UI in sync after changing the default. Returning it fromusePaymentMutationsalongsideremovePaymentMethodfits the existing API.packages/http-sdk/src/wallet-settings/wallet-settings-http.service.ts (1)
6-25: WalletSettingsHttpService follows established SDK patternsThe new service cleanly encapsulates
/v1/wallet-settingsCRUD operations, usesWalletSettings/UpdateWalletSettingsParamstypes, and relies onextractApiDatalike 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
responsevariable 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
onAddCardSuccessfunction 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
setShowAddPaymentMethodfrom 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
isInProgressvalue is recomputed on every render. Wrapping it inuseMemocould 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 handlersThe payment and coupon flows look logically correct and are well-guarded, but there are a few small UX/behavior tweaks you might consider:
error/errorActionare only cleared viaclearError(). If a user closes and reopens the popup after an error, they’ll see the old error again. CallingclearError()inonClose(or whenopenflips from false → true) would avoid stale errors.applyCoupontreats any non-error response (includingamountAdded === 0) as “Coupon applied successfully!”. If0is 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 reusingisProcessingto 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 explicitany/as anyin mocks and setup with typed propsThis file relies heavily on
any(mock component props, form helpers, setup input types, anddependencies as any), which goes against the project guideline to avoidanyin TS/TSX files.Concretely:
- Mock components (
MockPopup,MockCard*,MockForm,MockFormField,MockFormInput,MockLoadingButton,MockFormattedNumber,MockAlert,MockButton,MockXmark,MockSnackbar) all declare props asany.setup’s input usesconfirmPaymentResponse?: any,applyCouponResponse?: any,stripeErrorResponse?: any.- Helpers like
createMockFormandpaymentSubmitHandler/couponSubmitHandleralso useany.dependenciesis cast toanywith an eslint override before passing intoPaymentPopup.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 ofany.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
setupinput instead ofany.Typing
dependenciesstructurally, for example:import { DEPENDENCIES } from "./PaymentPopup"; const dependencies: typeof DEPENDENCIES = { /* mocks */ }; const props: React.ComponentProps<typeof PaymentPopup> = { // ... dependencies, };which removes the need for
as anyand 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 behaviorThe “Payment Form Validation” tests only exercise
trigger/setValueon the mocked form and then assert thatmockUseFormwas called or thatgetValuesreturns 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
zodResolveranduseFormrun, or- Asserting that invalid amounts do not result in
confirmPaymentbeing 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
📒 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 typeanyor cast to typeany. 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.tsapps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsxpackages/http-sdk/src/wallet-settings/wallet-settings-http.service.tsapps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsxapps/deploy-web/src/queries/usePaymentQueries.tsapps/deploy-web/src/queries/index.tsapps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsxapps/deploy-web/src/queries/useWalletSettingsQueries.tsxapps/api/src/core/services/feature-flags/feature-flags.tspackages/http-sdk/src/stripe/stripe.service.tsapps/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, usejest-mock-extendedto create mocks and pass mocks as dependencies to the service under testUse
setupfunction instead ofbeforeEachin test files. Thesetupfunction must be at the bottom of the rootdescribeblock, 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>.namein 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.tsxapps/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
queryBymethods instead ofgetBymethods in test expectations
Files:
apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsxapps/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.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsxapps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.tsxapps/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.tsxapps/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.tsapps/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 fileRe-exporting
./useWalletSettingsQuerieshere 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 consistentThe new
AUTO_CREDIT_RELOAD: "auto_credit_reload"entry follows the existing pattern and automatically extendsFeatureFlagValue. No issues here.apps/deploy-web/src/services/app-di-container/app-di-container.ts (2)
1-12: WalletSettingsHttpService correctly added to HTTP SDK importsIncluding
WalletSettingsHttpServicealongside the other HTTP services keeps the DI surface aligned with the SDK exports. No issues.
94-97: DI registration for walletSettings matches existing patternsThe
walletSettingsprovider usesWalletSettingsHttpService(apiConfig)wrapped withwithUserToken, consistent with other authenticated API services (e.g.,deploymentSetting,usage). This should integrate cleanly withuseServices.apps/deploy-web/src/components/billing-usage/PaymentMethodsContainer/PaymentMethodsContainer.spec.tsx (1)
14-154: Comprehensive container behavior coverage and guideline-compliant testsThe tests thoroughly exercise data shaping, mutation callbacks,
showAddPaymentMethodtoggling,setupIntenthandling, andisInProgressaggregation. Naming, assertions, and the absence ofgetBy*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 patternsThe new
useDefaultPaymentMethodQueryuses the dedicated query key andstripe.getDefaultPaymentMethod()insideuseQuery, matching the conventions used byusePaymentMethodsQuery. Looks consistent and type-safe.packages/http-sdk/src/stripe/stripe.service.ts (3)
13-17: New SetPaymentMethodAsDefaultParams type integration is cleanPulling
SetPaymentMethodAsDefaultParamsinto the service’s type imports keeps the method signature strongly typed without introducingany.
32-35: getDefaultPaymentMethod endpoint aligns with Stripe payment-methods API shape
getDefaultPaymentMethod()usesextractApiDataon/v1/stripe/payment-methods/default, mirroring existing payment-methods endpoints and returning a typedPaymentMethod. No concerns.
60-62: setPaymentMethodAsDefault endpoint and payload are consistent
setPaymentMethodAsDefault(params)posts{ data: params }to/v1/stripe/payment-methods/defaultand returnsPaymentMethod[], 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 PaymentMethodsPageWrapping
PaymentMethodsPagewithGuardandcomposeGuards(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
getServerSidePropsusesdefineServerSidePropswithisAuthenticatedandisFeatureEnabled("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 testabilityExporting
DEPENDENCIESand threading it via thedependenciesprop 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-coveredThe way
isProcessing/disableddrive the loading state of the Pay button, the “select a payment method” hint, and the detailedPayment Erroralert (including suggestion text and a clear button that wires intoclearError) 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 flowsThe 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
onSuccesscallback behavior withsubmittedAmountRef.- 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
setuphelper plus mock forms make these flows explicit and maintainable. From a functional perspective, this coverage looks very good.Also applies to: 490-768
refs #1779
Summary by CodeRabbit
New Features
Tests
UI
✏️ Tip: You can customize this high-level summary in your review settings.