Skip to content

feat(billing): validate payment methods trial#1750

Merged
baktun14 merged 11 commits intomainfrom
features/validate-payment-methods-trial
Jul 30, 2025
Merged

feat(billing): validate payment methods trial#1750
baktun14 merged 11 commits intomainfrom
features/validate-payment-methods-trial

Conversation

@baktun14
Copy link
Contributor

@baktun14 baktun14 commented Jul 29, 2025

#1732

Summary by CodeRabbit

  • New Features

    • Added support for storing and managing user payment methods, including a new database table, repository, and schema.
    • Enhanced backend to handle Stripe webhook events for payment method attachment and detachment.
    • Added checks to prevent removal of payment methods during trial periods and detect duplicate trial accounts using the same payment method.
    • Improved onboarding and payment UI with error handling and messaging for wallet creation and payment method management.
    • Added a "Back to Console" link in the onboarding page for easier navigation.
  • Bug Fixes

    • Improved error state tracking and display for managed wallet creation failures during onboarding.
    • Disabled payment method removal UI during trial periods to prevent unauthorized actions.
  • Tests

    • Added comprehensive tests for error handling utilities and payment method UI components.
    • Extended Stripe service tests to cover duplicate trial account detection.
  • Chores

    • Updated type definitions and utility functions for consistent error handling across the application.
    • Improved internal code organization by exporting new types, schemas, and repositories.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 29, 2025

Walkthrough

This change introduces a new payment_methods table and associated repository, schema, and service logic for managing payment methods and detecting duplicate usage across accounts. It updates backend controllers, services, and web UI components to support error handling, trial restrictions, and improved user feedback. Type definitions, error utilities, and comprehensive tests are added.

Changes

Cohort / File(s) Change Summary
Database Table & Migration
apps/api/drizzle/0017_sloppy_morg.sql, apps/api/drizzle/0018_spooky_baron_strucker.sql, apps/api/drizzle/meta/0017_snapshot.json, apps/api/drizzle/meta/0018_snapshot.json, apps/api/drizzle/meta/_journal.json
Adds payment_methods table with columns and foreign key to userSetting, creates multiple indexes on the table, updates schema snapshots and migration journal.
Payment Method Schema & Repository
apps/api/src/billing/model-schemas/payment-method/payment-method.schema.ts, apps/api/src/billing/model-schemas/index.ts, apps/api/src/billing/repositories/payment-method/payment-method.repository.ts, apps/api/src/billing/repositories/index.ts
Introduces Drizzle ORM schema and repository for payment_methods, with indexes and relations; exports added in index files.
Stripe Service, Controller, and Webhook
apps/api/src/billing/services/stripe/stripe.service.ts, apps/api/src/billing/services/stripe/stripe.service.spec.ts, apps/api/src/billing/controllers/wallet/wallet.controller.ts, apps/api/src/billing/controllers/stripe/stripe.controller.ts, apps/api/src/billing/services/stripe-webhook/stripe-webhook.service.ts
Adds duplicate payment method detection, trial enforcement in controller, webhook handlers for payment method attach/detach events; updates tests and controller logic.
Error Types & Utilities
apps/deploy-web/src/types/errors.ts, apps/deploy-web/src/types/index.ts, apps/deploy-web/src/utils/errorUtils.ts, apps/deploy-web/src/utils/errorUtils.test.ts, apps/deploy-web/src/utils/stripeErrorHandler.ts
Adds error type definitions, extraction utilities, and tests; refactors error handling to use shared types.
Onboarding & Payment UI Components
apps/deploy-web/src/components/onboarding/steps/PaymentMethodsDisplay/PaymentMethodsDisplay.tsx, apps/deploy-web/src/components/onboarding/steps/PaymentMethodsDisplay/PaymentMethodsDisplay.test.tsx, apps/deploy-web/src/components/onboarding/steps/PaymentMethodStep/PaymentMethodStep.tsx, apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx, apps/deploy-web/src/components/onboarding/OnboardingPage.tsx, apps/deploy-web/src/components/onboarding/steps/PaymentVerificationCard/PaymentVerificationCard.tsx
Adds error display and handling props, dependency injection for URL service, UI improvements, and comprehensive tests for payment method display and error handling.
Wallet Context & Hook
apps/deploy-web/src/context/WalletProvider/WalletProvider.tsx, apps/deploy-web/src/hooks/useManagedWallet.ts
Exposes managed wallet error state in context and hook, updates memoization dependencies.
Payment Methods List & Page
apps/deploy-web/src/components/user/payment/PaymentMethodsList.tsx, apps/deploy-web/src/pages/payment.tsx
Adds isTrialing prop to control visibility of remove button based on trial status.
Dependency Injection Container
apps/deploy-web/src/services/app-di-container/app-di-container.ts
Registers urlService provider for URL utilities injection.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant WebApp
    participant API
    participant Stripe
    participant DB

    User->>WebApp: Add Payment Method
    WebApp->>Stripe: Request to attach payment method
    Stripe-->>API: payment_method.attached webhook
    API->>DB: Insert payment_methods record
    API-->>Stripe: 200 OK

    User->>WebApp: Start Trial
    WebApp->>API: Request to create wallet
    API->>Stripe: Fetch payment methods
    API->>DB: Check for duplicate fingerprints
    alt Duplicate found
        API-->>WebApp: 403 error (duplicate trial)
    else No duplicate
        API->>DB: Create wallet
        API-->>WebApp: Success
    end

    User->>WebApp: Remove Payment Method
    alt User is trialing
        WebApp-->>User: Show error (cannot remove during trial)
    else Not trialing
        WebApp->>API: Request to remove payment method
        API->>Stripe: Detach payment method
        Stripe-->>API: payment_method.detached webhook
        API->>DB: Remove payment_methods record
        API-->>WebApp: Success
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers

  • stalniy
  • ygrishajev

Poem

In burrows deep, a schema grows,
New payment methods now compose.
With checks for trials, and errors caught,
Duplicate cards? They shall be naught!
UI alerts and warnings bright,
Guide users through the payment night.
A hop, a skip, review in sight! 🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between edff0c5 and 82750cb.

📒 Files selected for processing (3)
  • apps/deploy-web/src/components/onboarding/steps/PaymentMethodsDisplay/PaymentMethodsDisplay.test.tsx (1 hunks)
  • apps/deploy-web/src/components/onboarding/steps/PaymentMethodsDisplay/PaymentMethodsDisplay.tsx (5 hunks)
  • apps/deploy-web/src/services/app-di-container/app-di-container.ts (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • apps/deploy-web/src/services/app-di-container/app-di-container.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/deploy-web/src/components/onboarding/steps/PaymentMethodsDisplay/PaymentMethodsDisplay.test.tsx
  • apps/deploy-web/src/components/onboarding/steps/PaymentMethodsDisplay/PaymentMethodsDisplay.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch features/validate-payment-methods-trial

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@codecov
Copy link

codecov bot commented Jul 29, 2025

Codecov Report

❌ Patch coverage is 40.95238% with 62 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.30%. Comparing base (fa722aa) to head (82750cb).
⚠️ Report is 6 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
.../services/stripe-webhook/stripe-webhook.service.ts 20.75% 36 Missing and 6 partials ⚠️
...tories/payment-method/payment-method.repository.ts 52.63% 9 Missing ⚠️
...rc/billing/controllers/wallet/wallet.controller.ts 0.00% 5 Missing ⚠️
...rc/billing/controllers/stripe/stripe.controller.ts 0.00% 1 Missing ⚠️
...el-schemas/payment-method/payment-method.schema.ts 85.71% 1 Missing ⚠️
.../PaymentMethodContainer/PaymentMethodContainer.tsx 75.00% 1 Missing ⚠️
...-web/src/context/WalletProvider/WalletProvider.tsx 0.00% 1 Missing ⚠️
apps/deploy-web/src/hooks/useManagedWallet.ts 0.00% 1 Missing ⚠️
.../src/services/app-di-container/app-di-container.ts 66.66% 1 Missing ⚠️

❌ Your patch status has failed because the patch coverage (38.94%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1750      +/-   ##
==========================================
- Coverage   72.59%   72.30%   -0.30%     
==========================================
  Files         625      624       -1     
  Lines       14908    14937      +29     
  Branches     2606     2633      +27     
==========================================
- Hits        10823    10800      -23     
+ Misses       3862     3792      -70     
- Partials      223      345     +122     
Flag Coverage Δ *Carryforward flag
api 79.74% <38.94%> (-0.56%) ⬇️
deploy-web 58.64% <60.00%> (+0.45%) ⬆️
log-collector ?
notifications 87.25% <ø> (ø) Carriedforward from edff0c5
provider-console 80.95% <ø> (ø) Carriedforward from edff0c5
provider-proxy 85.00% <ø> (ø) Carriedforward from edff0c5

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

Files with missing lines Coverage Δ
.../api/src/billing/services/stripe/stripe.service.ts 92.63% <100.00%> (+0.43%) ⬆️
apps/deploy-web/src/types/index.ts 100.00% <100.00%> (ø)
apps/deploy-web/src/utils/stripeErrorHandler.ts 88.09% <ø> (ø)
...rc/billing/controllers/stripe/stripe.controller.ts 21.12% <0.00%> (-0.31%) ⬇️
...el-schemas/payment-method/payment-method.schema.ts 85.71% <85.71%> (ø)
.../PaymentMethodContainer/PaymentMethodContainer.tsx 93.02% <75.00%> (-1.98%) ⬇️
...-web/src/context/WalletProvider/WalletProvider.tsx 19.49% <0.00%> (ø)
apps/deploy-web/src/hooks/useManagedWallet.ts 23.07% <0.00%> (ø)
.../src/services/app-di-container/app-di-container.ts 92.39% <66.66%> (-2.00%) ⬇️
...rc/billing/controllers/wallet/wallet.controller.ts 88.00% <0.00%> (-3.67%) ⬇️
... and 2 more

... and 52 files with indirect coverage changes

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

@baktun14 baktun14 marked this pull request as ready for review July 29, 2025 15:00
@baktun14 baktun14 requested a review from a team as a code owner July 29, 2025 15:00
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (4)
apps/deploy-web/src/utils/errorUtils.test.ts (1)

4-220: LGTM: Comprehensive test coverage for error utilities

The test suite provides excellent coverage for all error utility functions with well-structured test cases covering:

  • All supported error formats (HTTP errors, Error objects, structured errors)
  • Edge cases like null/undefined values and empty strings
  • Type coercion scenarios for unexpected input types

The tests are clear, well-organized, and thoroughly validate the error handling logic.

Note: Consider using a setup function as specified in the coding guidelines, even though the current test structure works well for these utility function tests.

apps/api/drizzle/meta/0017_snapshot.json (2)

406-432: Redundant composite index includes primary key column id

deployment_settings.id_auto_top_up_enabled_closed_idx starts with id, which is already covered by the table’s primary-key index.
Because PostgreSQL can only use the left-most prefix of a b-tree, the presence of id first renders the remaining columns (auto_top_up_enabled, closed) unusable for filter conditions that don’t also constrain id, defeating the purpose of the composite.

Consider:

-        "id_auto_top_up_enabled_closed_idx": {
-          "columns": ["id", "auto_top_up_enabled", "closed"],
+        "auto_top_up_enabled_closed_idx": {
+          "columns": ["auto_top_up_enabled", "closed"],

or, more selectively, ("user_id", "auto_top_up_enabled", "closed") if queries filter by owner.


228-351: Table naming style is inconsistent (userSetting vs snake_case)

Legacy camel-case table userSetting co-exists with newly added snake_case tables (payment_methods, deployment_settings, …).
Mixed-case identifiers require quoting in every SQL statement and are easy to mis-type. Standardising on one naming convention (typically lowercase snake_case) will reduce friction and tooling surprises.

apps/deploy-web/src/components/onboarding/steps/PaymentVerificationCard/PaymentVerificationCard.tsx (1)

33-37: Consider the semantic implications of changing from <p> to <div> elements.

The change from paragraph elements to generic divs removes semantic meaning. While functionally equivalent, this could impact accessibility and SEO. If this change is for styling purposes, consider using CSS to achieve the desired layout while preserving semantic HTML.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 746028c and 574c0ef.

📒 Files selected for processing (27)
  • apps/api/drizzle/0017_sloppy_morg.sql (1 hunks)
  • apps/api/drizzle/meta/0017_snapshot.json (1 hunks)
  • apps/api/drizzle/meta/_journal.json (1 hunks)
  • apps/api/src/billing/controllers/stripe/stripe.controller.ts (1 hunks)
  • apps/api/src/billing/controllers/wallet/wallet.controller.ts (1 hunks)
  • apps/api/src/billing/model-schemas/index.ts (1 hunks)
  • apps/api/src/billing/model-schemas/payment-method/payment-method.schema.ts (1 hunks)
  • apps/api/src/billing/repositories/index.ts (1 hunks)
  • apps/api/src/billing/repositories/payment-method/payment-method.repository.ts (1 hunks)
  • apps/api/src/billing/services/stripe-webhook/stripe-webhook.service.ts (4 hunks)
  • apps/api/src/billing/services/stripe/stripe.service.spec.ts (3 hunks)
  • apps/api/src/billing/services/stripe/stripe.service.ts (3 hunks)
  • apps/deploy-web/src/components/onboarding/OnboardingPage.tsx (2 hunks)
  • apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx (5 hunks)
  • apps/deploy-web/src/components/onboarding/steps/PaymentMethodStep/PaymentMethodStep.tsx (4 hunks)
  • apps/deploy-web/src/components/onboarding/steps/PaymentMethodsDisplay/PaymentMethodsDisplay.test.tsx (1 hunks)
  • apps/deploy-web/src/components/onboarding/steps/PaymentMethodsDisplay/PaymentMethodsDisplay.tsx (5 hunks)
  • apps/deploy-web/src/components/onboarding/steps/PaymentVerificationCard/PaymentVerificationCard.tsx (1 hunks)
  • apps/deploy-web/src/components/user/payment/PaymentMethodsList.tsx (2 hunks)
  • apps/deploy-web/src/context/WalletProvider/WalletProvider.tsx (4 hunks)
  • apps/deploy-web/src/hooks/useManagedWallet.ts (2 hunks)
  • apps/deploy-web/src/pages/payment.tsx (3 hunks)
  • apps/deploy-web/src/types/errors.ts (1 hunks)
  • apps/deploy-web/src/types/index.ts (1 hunks)
  • apps/deploy-web/src/utils/errorUtils.test.ts (1 hunks)
  • apps/deploy-web/src/utils/errorUtils.ts (1 hunks)
  • apps/deploy-web/src/utils/stripeErrorHandler.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/general.mdc)

Never use type any or cast to type any. Always define the proper TypeScript types.

Files:

  • apps/api/src/billing/repositories/index.ts
  • apps/api/src/billing/controllers/stripe/stripe.controller.ts
  • apps/deploy-web/src/components/onboarding/steps/PaymentMethodStep/PaymentMethodStep.tsx
  • apps/deploy-web/src/components/onboarding/steps/PaymentVerificationCard/PaymentVerificationCard.tsx
  • apps/api/src/billing/controllers/wallet/wallet.controller.ts
  • apps/deploy-web/src/components/onboarding/OnboardingPage.tsx
  • apps/api/src/billing/model-schemas/payment-method/payment-method.schema.ts
  • apps/deploy-web/src/types/index.ts
  • apps/api/src/billing/services/stripe/stripe.service.ts
  • apps/deploy-web/src/pages/payment.tsx
  • apps/api/src/billing/repositories/payment-method/payment-method.repository.ts
  • apps/api/src/billing/model-schemas/index.ts
  • apps/api/src/billing/services/stripe-webhook/stripe-webhook.service.ts
  • apps/deploy-web/src/utils/stripeErrorHandler.ts
  • apps/deploy-web/src/types/errors.ts
  • apps/deploy-web/src/hooks/useManagedWallet.ts
  • apps/api/src/billing/services/stripe/stripe.service.spec.ts
  • apps/deploy-web/src/components/user/payment/PaymentMethodsList.tsx
  • apps/deploy-web/src/context/WalletProvider/WalletProvider.tsx
  • apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx
  • apps/deploy-web/src/utils/errorUtils.test.ts
  • apps/deploy-web/src/components/onboarding/steps/PaymentMethodsDisplay/PaymentMethodsDisplay.test.tsx
  • apps/deploy-web/src/components/onboarding/steps/PaymentMethodsDisplay/PaymentMethodsDisplay.tsx
  • apps/deploy-web/src/utils/errorUtils.ts
**/*.{js,ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/general.mdc)

**/*.{js,ts,tsx}: Never use deprecated methods from libraries.
Don't add unnecessary comments to the code

Files:

  • apps/api/src/billing/repositories/index.ts
  • apps/api/src/billing/controllers/stripe/stripe.controller.ts
  • apps/deploy-web/src/components/onboarding/steps/PaymentMethodStep/PaymentMethodStep.tsx
  • apps/deploy-web/src/components/onboarding/steps/PaymentVerificationCard/PaymentVerificationCard.tsx
  • apps/api/src/billing/controllers/wallet/wallet.controller.ts
  • apps/deploy-web/src/components/onboarding/OnboardingPage.tsx
  • apps/api/src/billing/model-schemas/payment-method/payment-method.schema.ts
  • apps/deploy-web/src/types/index.ts
  • apps/api/src/billing/services/stripe/stripe.service.ts
  • apps/deploy-web/src/pages/payment.tsx
  • apps/api/src/billing/repositories/payment-method/payment-method.repository.ts
  • apps/api/src/billing/model-schemas/index.ts
  • apps/api/src/billing/services/stripe-webhook/stripe-webhook.service.ts
  • apps/deploy-web/src/utils/stripeErrorHandler.ts
  • apps/deploy-web/src/types/errors.ts
  • apps/deploy-web/src/hooks/useManagedWallet.ts
  • apps/api/src/billing/services/stripe/stripe.service.spec.ts
  • apps/deploy-web/src/components/user/payment/PaymentMethodsList.tsx
  • apps/deploy-web/src/context/WalletProvider/WalletProvider.tsx
  • apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx
  • apps/deploy-web/src/utils/errorUtils.test.ts
  • apps/deploy-web/src/components/onboarding/steps/PaymentMethodsDisplay/PaymentMethodsDisplay.test.tsx
  • apps/deploy-web/src/components/onboarding/steps/PaymentMethodsDisplay/PaymentMethodsDisplay.tsx
  • apps/deploy-web/src/utils/errorUtils.ts
**/*.spec.{ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/no-jest-mock.mdc)

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

**/*.spec.{ts,tsx}: Use setup function instead of beforeEach in test files
setup function must be at the bottom of the root describe block in test files
setup function creates an object under test and returns it
setup function should accept a single parameter with inline type definition
Don't use shared state in setup function
Don't specify return type of setup function

Files:

  • apps/api/src/billing/services/stripe/stripe.service.spec.ts
🧠 Learnings (10)
apps/deploy-web/src/types/index.ts (1)

Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/query-by-in-tests.mdc:0-0
Timestamp: 2025-07-21T08:24:27.953Z
Learning: Applies to apps/{deploy-web,provider-console}/**/*.spec.tsx : Use queryBy methods instead of getBy methods in test expectations in .spec.tsx files

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

Learnt from: baktun14
PR: #1432
File: apps/deploy-web/src/components/deployments/DeploymentAlerts/DeploymentCloseAlert.tsx:38-38
Timestamp: 2025-06-05T21:07:51.985Z
Learning: The ContactPointSelect component in apps/deploy-web/src/components/alerts/ContactPointSelectForm/ContactPointSelect.tsx uses the useFormContext hook internally to connect to React Hook Form, so it doesn't need to be wrapped in a FormField component.

Learnt from: ygrishajev
PR: #1512
File: apps/deploy-web/src/components/deployments/DeploymentBalanceAlert/DeploymentBalanceAlert.tsx:47-68
Timestamp: 2025-06-19T16:00:05.428Z
Learning: In React Hook Form setups with zod validation, child components using useFormContext() can rely on parent form validation rather than implementing local input validation. Invalid inputs like NaN from parseFloat() are handled by the parent schema validation, eliminating the need for additional local validation in child components.

apps/api/src/billing/repositories/payment-method/payment-method.repository.ts (1)

Learnt from: stalniy
PR: #1436
File: apps/api/src/provider/repositories/provider/provider.repository.ts:79-90
Timestamp: 2025-06-08T03:07:13.871Z
Learning: The getProvidersHostUriByAttributes method in apps/api/src/provider/repositories/provider/provider.repository.ts already has comprehensive test coverage in provider.repository.spec.ts, including tests for complex HAVING clause logic with COUNT(*) FILTER (WHERE ...) syntax, signature conditions (anyOf/allOf), and glob pattern matching.

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

Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/general.mdc:0-0
Timestamp: 2025-07-27T12:16:08.566Z
Learning: Applies to **/*.{js,ts,tsx} : Never use deprecated methods from libraries.

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

Learnt from: jzsfkzm
PR: #1498
File: apps/api/src/services/external/templates/template-fetcher.service.ts:0-0
Timestamp: 2025-07-03T14:40:49.886Z
Learning: In the TemplateFetcherService class in apps/api/src/services/external/templates/template-fetcher.service.ts, the error handling strategy should maintain process resilience by catching all errors and returning null rather than re-throwing critical errors, to avoid breaking the whole template fetching process.

apps/api/src/billing/services/stripe/stripe.service.spec.ts (6)

Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/no-jest-mock.mdc:0-0
Timestamp: 2025-07-21T08:24:24.269Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use jest.mock() to mock dependencies in test files. Instead, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test.

Learnt from: stalniy
PR: #1436
File: apps/api/src/provider/repositories/provider/provider.repository.ts:79-90
Timestamp: 2025-06-08T03:07:13.871Z
Learning: The getProvidersHostUriByAttributes method in apps/api/src/provider/repositories/provider/provider.repository.ts already has comprehensive test coverage in provider.repository.spec.ts, including tests for complex HAVING clause logic with COUNT(*) FILTER (WHERE ...) syntax, signature conditions (anyOf/allOf), and glob pattern matching.

Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : Use setup function instead of beforeEach in test files

Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : setup function must be at the bottom of the root describe block in test files

Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : setup function creates an object under test and returns it

Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use shared state in setup function

apps/deploy-web/src/utils/errorUtils.test.ts (4)

Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/query-by-in-tests.mdc:0-0
Timestamp: 2025-07-21T08:24:27.953Z
Learning: Applies to apps/{deploy-web,provider-console}/**/*.spec.tsx : Use queryBy methods instead of getBy methods in test expectations in .spec.tsx files

Learnt from: stalniy
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.

Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : Use setup function instead of beforeEach in test files

Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : setup function creates an object under test and returns it

apps/deploy-web/src/components/onboarding/steps/PaymentMethodsDisplay/PaymentMethodsDisplay.test.tsx (9)

Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/query-by-in-tests.mdc:0-0
Timestamp: 2025-07-21T08:24:27.953Z
Learning: Applies to apps/{deploy-web,provider-console}/**/*.spec.tsx : Use queryBy methods instead of getBy methods in test expectations in .spec.tsx files

Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : Use setup function instead of beforeEach in test files

Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : setup function creates an object under test and returns it

Learnt from: stalniy
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.

Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : setup function must be at the bottom of the root describe block in test files

Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/no-jest-mock.mdc:0-0
Timestamp: 2025-07-21T08:24:24.269Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use jest.mock() to mock dependencies in test files. Instead, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test.

Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : setup function should accept a single parameter with inline type definition

Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use shared state in setup function

Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't specify return type of setup function

apps/deploy-web/src/components/onboarding/steps/PaymentMethodsDisplay/PaymentMethodsDisplay.tsx (1)

Learnt from: baktun14
PR: #1432
File: apps/deploy-web/src/components/deployments/DeploymentAlerts/DeploymentCloseAlert.tsx:38-38
Timestamp: 2025-06-05T21:07:51.985Z
Learning: The ContactPointSelect component in apps/deploy-web/src/components/alerts/ContactPointSelectForm/ContactPointSelect.tsx uses the useFormContext hook internally to connect to React Hook Form, so it doesn't need to be wrapped in a FormField component.

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

Learnt from: jzsfkzm
PR: #1498
File: apps/api/src/services/external/templates/template-fetcher.service.ts:0-0
Timestamp: 2025-07-03T14:40:49.886Z
Learning: In the TemplateFetcherService class in apps/api/src/services/external/templates/template-fetcher.service.ts, the error handling strategy should maintain process resilience by catching all errors and returning null rather than re-throwing critical errors, to avoid breaking the whole template fetching process.

🧬 Code Graph Analysis (12)
apps/deploy-web/src/components/onboarding/steps/PaymentMethodStep/PaymentMethodStep.tsx (1)
apps/deploy-web/src/types/errors.ts (1)
  • AppError (26-26)
apps/api/src/billing/controllers/wallet/wallet.controller.ts (1)
apps/api/src/billing/services/stripe/stripe.service.ts (1)
  • hasDuplicateTrialAccount (442-453)
apps/deploy-web/src/components/onboarding/OnboardingPage.tsx (3)
apps/deploy-web/src/utils/urlUtils.ts (1)
  • UrlService (16-80)
apps/provider-console/src/utils/styleUtils.ts (1)
  • cn (4-6)
packages/ui/components/button.tsx (1)
  • buttonVariants (46-46)
apps/api/src/billing/model-schemas/payment-method/payment-method.schema.ts (1)
apps/api/src/user/model-schemas/user/user.schema.ts (1)
  • Users (8-28)
apps/api/src/billing/services/stripe/stripe.service.ts (1)
packages/http-sdk/src/stripe/stripe.types.ts (1)
  • PaymentMethod (34-44)
apps/api/src/billing/services/stripe-webhook/stripe-webhook.service.ts (2)
packages/logging/src/servicies/logger/logger.service.ts (1)
  • error (107-109)
apps/api/src/core/services/tx/tx.service.ts (1)
  • WithTransaction (33-45)
apps/deploy-web/src/context/WalletProvider/WalletProvider.tsx (2)
apps/deploy-web/src/types/errors.ts (1)
  • AppError (26-26)
apps/deploy-web/src/hooks/useManagedWallet.ts (1)
  • useManagedWallet (15-87)
apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx (1)
apps/deploy-web/src/types/errors.ts (1)
  • AppError (26-26)
apps/deploy-web/src/utils/errorUtils.test.ts (2)
apps/deploy-web/src/utils/errorUtils.ts (3)
  • extractErrorMessage (6-28)
  • isHttpErrorResponse (33-35)
  • extractErrorData (40-45)
apps/deploy-web/src/types/errors.ts (1)
  • AppError (26-26)
apps/deploy-web/src/components/onboarding/steps/PaymentMethodsDisplay/PaymentMethodsDisplay.test.tsx (2)
apps/deploy-web/src/types/errors.ts (1)
  • AppError (26-26)
apps/deploy-web/src/components/onboarding/steps/PaymentMethodsDisplay/PaymentMethodsDisplay.tsx (1)
  • PaymentMethodsDisplay (32-140)
apps/deploy-web/src/components/onboarding/steps/PaymentMethodsDisplay/PaymentMethodsDisplay.tsx (3)
apps/deploy-web/src/types/errors.ts (1)
  • AppError (26-26)
apps/deploy-web/src/utils/urlUtils.ts (1)
  • UrlService (16-80)
apps/deploy-web/src/utils/errorUtils.ts (1)
  • extractErrorMessage (6-28)
apps/deploy-web/src/utils/errorUtils.ts (1)
apps/deploy-web/src/types/errors.ts (2)
  • AppError (26-26)
  • ErrorResponse (4-10)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
🔇 Additional comments (69)
apps/deploy-web/src/components/onboarding/OnboardingPage.tsx (2)

2-5: LGTM! Clean imports with proper TypeScript types.

The new imports are well-organized and properly typed. The imports follow the established patterns in the codebase:

  • UI components from the design system package
  • Utility functions for styling
  • Icon from the iconoir-react library
  • Next.js Link component for navigation

No usage of any types, which aligns with the coding guidelines.


18-24: Well-implemented navigation element with good UX patterns.

The "Back to Console" link is properly implemented with:

  • Semantic HTML structure using Next.js Link
  • Appropriate styling with ghost button variant and proper spacing
  • Good accessibility with descriptive text and visual icon
  • Consistent use of utility classes and design system components
  • Proper navigation to home page using UrlService.home()

The centered layout and spacing (py-8) provides good visual separation from the onboarding content above.

apps/api/drizzle/meta/_journal.json (1)

124-130: LGTM! Migration journal entry is properly formatted.

The new migration entry follows the consistent structure of previous entries and correctly references the payment_methods table migration.

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

11-11: LGTM! Clean import addition.

The import follows the established pattern and integrates well with existing imports.


42-42: LGTM! Proper hook usage.

The destructuring of isTrialing from useWallet follows React best practices and is consistent with other hook usage in the component.


258-258: LGTM! Appropriate prop passing.

The isTrialing prop is correctly passed to the PaymentMethodsList component, enabling trial-specific UI behavior as intended.

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

11-11: LGTM! Proper barrel export addition.

The export statement follows the established pattern and correctly exposes the new error types for use throughout the application.

apps/api/src/billing/model-schemas/index.ts (1)

3-3: LGTM! Clean schema export addition.

The export statement properly follows the established pattern and makes the payment method schema accessible from the billing schemas index.

apps/api/src/billing/repositories/index.ts (1)

3-3: LGTM! Proper repository export addition.

The export statement correctly follows the established pattern and makes the PaymentMethodRepository accessible from the billing repositories index.

apps/deploy-web/src/hooks/useManagedWallet.ts (4)

21-21: LGTM!

Properly destructures the error state from the mutation hook with a clear, descriptive name.


83-86: LGTM!

Correctly exposes the error state in the return object and properly updates the dependency array to ensure the memoized result updates when the error state changes.


21-21: LGTM!

Properly extracts the error state from the mutation hook for downstream consumption.


83-86: LGTM!

Correctly exposes the createError and includes it in the dependency array for proper memoization.

apps/deploy-web/src/utils/stripeErrorHandler.ts (2)

1-2: LGTM!

Good refactoring to centralize the ErrorResponse type definition. This reduces code duplication and provides a single source of truth for error types across the application.


1-2: LGTM!

Good refactoring to use centralized type definitions. This reduces code duplication and improves maintainability.

apps/api/src/billing/controllers/stripe/stripe.controller.ts (2)

106-106: LGTM!

Proper implementation of trial restriction for payment method removal. The assertion is correctly placed, uses the appropriate HTTP status code (403), and provides a clear, actionable error message for users.


106-106: LGTM!

Proper implementation of trial restrictions for payment method removal. The assertion is well-placed, uses appropriate HTTP status code, and provides clear user guidance.

apps/deploy-web/src/context/WalletProvider/WalletProvider.tsx (8)

24-24: LGTM!

Correct import of the AppError type for error handling integration.


58-58: LGTM!

Properly adds the optional managed wallet error property to the context type interface with correct TypeScript typing.


88-88: LGTM!

Correctly destructures the error state from the managed wallet hook with descriptive renaming for clarity.


343-343: LGTM!

Properly exposes the managed wallet error through the context value, enabling downstream components to access and handle wallet creation errors.


24-24: LGTM!

Correctly imports the centralized AppError type for consistent error handling.


58-58: LGTM!

Proper addition of optional managedWalletError property to the context interface. The optional nature maintains backward compatibility.


88-88: LGTM!

Clean destructuring and renaming of the error state for better semantic clarity in the context.


343-343: LGTM!

Properly exposes the managed wallet error state through the context for downstream error handling.

apps/deploy-web/src/components/onboarding/steps/PaymentMethodStep/PaymentMethodStep.tsx (3)

8-8: LGTM: Clean import of error type.

The import of AppError type is correctly added to support the new error handling functionality.


20-20: LGTM: Proper optional prop addition.

The managedWalletError prop is correctly defined as optional with the appropriate AppError type, maintaining backward compatibility.


37-37: LGTM: Consistent error prop handling.

The error prop is properly destructured from the component parameters and correctly passed down to the PaymentMethodsDisplay component, maintaining the error propagation chain.

Also applies to: 56-56

apps/deploy-web/src/components/user/payment/PaymentMethodsList.tsx (3)

11-11: LGTM: Clear boolean prop addition.

The isTrialing boolean prop is appropriately added to control payment method removal during trial periods.


19-21: LGTM: Proper prop destructuring.

The isTrialing prop is correctly added to the component's parameter destructuring.


55-67: LGTM: Effective trial restriction implementation.

The conditional rendering of the Remove button based on !isTrialing properly prevents users from attempting payment method removal during trial periods, which aligns with the backend validation logic mentioned in the AI summary.

apps/api/src/billing/controllers/wallet/wallet.controller.ts (1)

48-49: LGTM: Robust duplicate payment method validation.

The addition of hasDuplicateTrialAccount validation effectively prevents abuse by detecting when the same payment method fingerprint is already associated with another trial account. The error message is clear and the 403 status code is appropriate for this security restriction.

apps/deploy-web/src/components/onboarding/steps/PaymentMethodContainer/PaymentMethodContainer.tsx (4)

8-8: LGTM: Proper error type integration.

The import and addition of managedWalletError to the props interface correctly incorporates error handling into the component's API.

Also applies to: 27-27


45-45: LGTM: Clean error state extraction.

The managedWalletError is properly extracted from the wallet context alongside other wallet-related state.


64-68: LGTM: Effective error state management.

This useEffect properly handles wallet connection errors by resetting the isConnectingWallet state when an error occurs, preventing the UI from being stuck in a loading state.


117-117: LGTM: Complete error propagation.

The error is correctly passed to children components, maintaining the error handling chain throughout the component tree.

apps/api/src/billing/model-schemas/payment-method/payment-method.schema.ts (2)

6-18: LGTM: Well-structured table schema.

The PaymentMethods table schema is properly defined with:

  • UUID primary key with auto-generation
  • Appropriate foreign key relationship to Users with cascade delete
  • Required fields properly marked as notNull()
  • Standard timestamp columns with sensible defaults

The cascade delete behavior is appropriate for payment methods that should be removed when a user is deleted.


20-25: LGTM: Proper ORM relations definition.

The relations definition correctly establishes the one-to-many relationship between Users and PaymentMethods, enabling proper ORM functionality for queries and joins.

apps/api/src/billing/services/stripe/stripe.service.ts (1)

7-7: LGTM: Dependencies added correctly

The new dependencies PaymentMethodRepository and UserWalletRepository are properly imported and injected into the constructor to support the duplicate payment method detection feature.

Also applies to: 33-34

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

1-34: LGTM: Well-structured error type definitions

The error type definitions are comprehensive and well-documented. The union type AppError effectively covers various error formats that can be encountered, and the interfaces provide good structure for consistent error handling across the application.

apps/api/src/billing/services/stripe/stripe.service.spec.ts (3)

4-4: LGTM: Proper import of new repository types

The new repository types are correctly imported to support the expanded test coverage.


702-794: LGTM: Comprehensive test coverage for hasDuplicateTrialAccount

The test suite provides excellent coverage for the new method with well-structured test cases:

  • Tests both positive and negative duplicate detection scenarios
  • Properly handles edge cases like missing fingerprints and empty arrays
  • Uses proper mocking with jest-mock-extended as per coding guidelines
  • Clear assertions and meaningful test data

801-802: LGTM: Setup function properly updated

The setup function correctly mocks the new dependencies and returns them for use in tests, following the established pattern.

Also applies to: 804-804, 852-854

apps/api/drizzle/0017_sloppy_morg.sql (1)

1-14: LGTM: Well-structured database migration

The migration creates a proper payment_methods table with:

  • Appropriate column types and constraints
  • UUID primary key with auto-generation
  • Foreign key constraint with cascade delete for data integrity
  • Proper exception handling to prevent duplicate constraint errors
  • Timestamp fields for audit trail

The table structure supports the payment method tracking functionality effectively.

apps/deploy-web/src/components/onboarding/steps/PaymentMethodsDisplay/PaymentMethodsDisplay.tsx (8)

3-3: LGTM: Clean imports for error handling functionality.

The new imports for WarningTriangle icon, AppError type, and extractErrorMessage utility are properly structured and support the enhanced error handling capabilities.

Also applies to: 6-7


26-29: LGTM: Well-designed props for error handling and dependency injection.

The optional managedWalletError prop is properly typed with AppError, and the dependency injection pattern for UrlService improves testability while maintaining backward compatibility.


37-39: LGTM: Consistent parameter destructuring.

The new props are properly destructured following the existing code patterns.


41-41: LGTM: Clean dependency injection pattern.

The fallback pattern dependencies?.UrlService || UrlService provides excellent testability while maintaining default functionality.


50-53: LGTM: Well-designed error message helper.

The getErrorMessage function provides appropriate context-specific fallback messaging while properly delegating to the shared extractErrorMessage utility.


58-58: LGTM: Good layout improvement.

Adding flex-shrink-0 prevents the success alert icon from shrinking, maintaining visual consistency.


103-113: LGTM: Consistent error alert implementation.

The error alert follows the same design patterns as the success alert, uses appropriate destructive styling with WarningTriangle icon, and properly extracts error messages using the helper function.


129-129: LGTM: Proper usage of injected URL service.

The component correctly uses the injected urlService instead of the static import, maintaining consistency with the dependency injection pattern while preserving functionality.

Also applies to: 133-133

apps/api/src/billing/services/stripe-webhook/stripe-webhook.service.ts (4)

5-5: LGTM: Proper dependency injection setup.

The PaymentMethodRepository import and constructor injection follow established patterns and are properly typed.

Also applies to: 21-22


34-58: LGTM: Improved event routing with better error handling.

The refactor from if-else to switch statement improves readability, and the try-catch wrapper provides comprehensive error logging while preserving error propagation. The new payment method event cases are properly integrated.


144-188: LGTM: Well-implemented webhook handler with comprehensive validation.

The method properly handles the payment method attachment with:

  • Transaction safety via @WithTransaction()
  • Comprehensive validation of customer ID, user existence, and fingerprint
  • Detailed error logging for debugging
  • Clean database operation

The validation logic and error handling are thorough and appropriate.


190-236: LGTM: Robust payment method detachment handler.

The method handles the complex detachment scenario effectively:

  • Properly considers both current and previous customer ID from the event
  • Uses appropriate warn level logging for potentially expected missing data
  • Transaction safety with @WithTransaction()
  • Clean deletion logic with result logging

The handling of event.data.previous_attributes?.customer is particularly well thought out for detachment events.

apps/deploy-web/src/utils/errorUtils.ts (3)

6-28: LGTM: Comprehensive error message extraction.

The function handles all the expected error formats with appropriate fallbacks. The logic flow is clear and the fallback messages are user-friendly. Consider using the isHttpErrorResponse type guard for consistency, but the current implementation is functionally correct.


33-35: LGTM: Well-implemented TypeScript type guard.

The type guard properly checks for HTTP error response structure and provides accurate type narrowing with a comprehensive return type.


40-45: LGTM: Clean error data extraction using type guard.

The function properly leverages the isHttpErrorResponse type guard for type safety and provides a clean interface for extracting structured error data.

apps/api/src/billing/repositories/payment-method/payment-method.repository.ts (4)

8-24: LGTM: Proper repository setup following established patterns.

The type definitions, dependency injection, and BaseRepository extension follow the established patterns in the codebase correctly.


26-31: LGTM: Well-implemented fingerprint deduplication query.

The method correctly uses inArray and ne operators to find payment methods with matching fingerprints from other users, with proper access control via whereAccessibleBy.


33-39: LGTM: Clean user payment methods query.

The method properly queries payment methods by user ID with appropriate access control and return type handling.


41-43: LGTM: Clean deletion wrapper method.

The method provides a clear interface for payment method deletion by fingerprint, properly delegating to the inherited deleteBy method.

apps/deploy-web/src/components/onboarding/steps/PaymentMethodsDisplay/PaymentMethodsDisplay.test.tsx (6)

1-41: LGTM: Well-structured test suite with proper organization.

The test structure uses logical describe blocks and follows testing best practices. The use of getBy methods for presence testing provides better debugging information as recommended.


43-84: LGTM: Comprehensive interaction testing.

The tests properly verify button interactions, disabled states, and edge cases with appropriate mock usage and element selection.


86-211: LGTM: Exceptionally comprehensive error handling test coverage.

The error handling tests cover all error types comprehensively:

  • HTTP error responses with nested data
  • JavaScript Error objects
  • Structured error objects
  • Edge cases (null, undefined, empty objects)
  • Complex nested error structures

The use of queryBy for non-existence testing follows established patterns correctly.


213-286: LGTM: Thorough edge case coverage.

The edge case tests properly handle scenarios like missing card details, mixed payment method types, and date formatting variations that are likely to occur in production.


288-311: LGTM: Complete loading state testing.

The tests properly verify loading button states and disabled interactions during both loading and removal operations.


313-380: LGTM: Excellent setup function following all established patterns.

The setup function correctly implements all the established testing patterns:

  • Positioned at bottom of root describe block
  • Uses inline parameter type definition
  • Avoids shared state
  • Uses jest.fn() for mocks instead of jest.mock()
  • Provides proper test isolation and mock management
  • Includes dependency injection testing

Copy link
Contributor

@stalniy stalniy left a comment

Choose a reason for hiding this comment

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

I have few questions which I'd like to clarify

stalniy pushed a commit that referenced this pull request Nov 20, 2025
* fix(billing): p tag child warning

* feat(billing): add back to console button in onboarding

* feat(billing): add payment method tracking

* feat(billing): show start trial error

* feat: add tests

* feat(billing): hide remove payment method when trial

* fix(billing): prevent removing payment method when in trial

* fix: pr fixes

* fix(billing): add indexes and pr fixes

* fix(billing): update error codes for wallet assertions to 400

* refactor(billing): integrate ServicesProvider for UrlService in PaymentMethodsDisplay
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments