Skip to content

Conversation

@ItzNotABug
Copy link
Member

@ItzNotABug ItzNotABug commented Jan 2, 2026

What does this PR do?

Was reusing the organization loaded from root which had outdated data and therefore none of the invalidates were working.

Test Plan

Manual.

Related PRs and Issues

N/A.

Have you read the Contributing Guidelines on issues?

Yes.

Summary by CodeRabbit

  • New Features

    • Enhanced payment method management with explicit primary and backup payment method tracking across billing pages.
    • Improved card replacement with country/state validation for payment method updates.
  • Bug Fixes

    • Fixed method naming in backup payment method removal flow to ensure correct operation.
  • Refactor

    • Streamlined internal component prop handling and state management for payment operations.

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

@ItzNotABug ItzNotABug self-assigned this Jan 2, 2026
@appwrite
Copy link

appwrite bot commented Jan 2, 2026

Console (appwrite/console)

Project ID: 688b7bf400350cbd60e9

Sites (1)
Site Status Logs Preview QR
 console-stage
688b7cf6003b1842c9dc
Ready Ready View Logs Preview URL QR Code

Tip

Build commands execute in runtime containers during deployment

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 2, 2026

Warning

Rate limit exceeded

@ItzNotABug has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 23 minutes and 5 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 4eda58b and fdc94a5.

📒 Files selected for processing (1)
  • src/routes/(console)/organization-[organization]/billing/replaceCard.svelte

Walkthrough

This pull request refactors payment management functionality across multiple components and pages. The changes include migrating component prop declarations from traditional export let statements to Svelte 5's $props() destructuring pattern in three components (editPaymentModal, replaceCard, and related files). Additionally, the payment method state management is reorganized by extracting primary and backup payment method identification logic into the page load layer, then passing these as explicit props to child components. The organization layout's checkPlatformAndRedirect function is updated to return void instead of an Organization object, with direct SDK fetching moved to the load function. API invalidation targets are adjusted from ORGANIZATION to PAYMENT_METHODS in certain flows.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title is vague and generic, using only 'Fix: payments not updating' without specifying which payments mechanism is being fixed or how. Consider a more descriptive title that specifies the root cause (e.g., 'Fix: invalidate payment methods by fetching fresh org data instead of reusing cached') or the specific component area being fixed.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
src/routes/(console)/organization-[organization]/+layout.ts (1)

90-111: Return statements in void function are misleading.

The function signature indicates it returns void (no explicit return type), but the function body contains return null (line 107) and return requestedOrg (line 111). While these returns are harmless since the caller no longer uses the return value, they're misleading and should be cleaned up for clarity.

🔎 Suggested cleanup
     // not found, load!
     if (!requestedOrg) {
         try {
             requestedOrg = (await sdk.forConsole.teams.get({
                 teamId: params.organization
             })) as Organization;
         } catch (e) {
-            return null;
+            return;
         }
     }

-    if (!isCloud) return requestedOrg;
+    if (!isCloud) return;

     if (requestedOrg && requestedOrg.platform !== Platform.Appwrite) {
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 11a42cf and 4eda58b.

📒 Files selected for processing (7)
  • src/routes/(console)/account/payments/editPaymentModal.svelte
  • src/routes/(console)/organization-[organization]/+layout.ts
  • src/routes/(console)/organization-[organization]/billing/+page.svelte
  • src/routes/(console)/organization-[organization]/billing/+page.ts
  • src/routes/(console)/organization-[organization]/billing/deleteOrgPayment.svelte
  • src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte
  • src/routes/(console)/organization-[organization]/billing/replaceCard.svelte
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx,js,jsx,svelte}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx,svelte}: Import reusable modules from the src/lib directory using the $lib alias
Use minimal comments in code; reserve comments for TODOs or complex logic explanations
Use $lib, $routes, and $themes aliases instead of relative paths for module imports

Files:

  • src/routes/(console)/organization-[organization]/billing/deleteOrgPayment.svelte
  • src/routes/(console)/organization-[organization]/+layout.ts
  • src/routes/(console)/account/payments/editPaymentModal.svelte
  • src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte
  • src/routes/(console)/organization-[organization]/billing/+page.ts
  • src/routes/(console)/organization-[organization]/billing/replaceCard.svelte
  • src/routes/(console)/organization-[organization]/billing/+page.svelte
src/routes/**/*.svelte

📄 CodeRabbit inference engine (AGENTS.md)

Use SvelteKit file conventions: +page.svelte for components, +page.ts for data loaders, +layout.svelte for wrappers, +error.svelte for error handling, and dynamic route params in square brackets like [param]

Files:

  • src/routes/(console)/organization-[organization]/billing/deleteOrgPayment.svelte
  • src/routes/(console)/account/payments/editPaymentModal.svelte
  • src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte
  • src/routes/(console)/organization-[organization]/billing/replaceCard.svelte
  • src/routes/(console)/organization-[organization]/billing/+page.svelte
**/*.{ts,tsx,js,jsx,svelte,json}

📄 CodeRabbit inference engine (AGENTS.md)

Use 4 spaces for indentation, single quotes, 100 character line width, and no trailing commas per Prettier configuration

Files:

  • src/routes/(console)/organization-[organization]/billing/deleteOrgPayment.svelte
  • src/routes/(console)/organization-[organization]/+layout.ts
  • src/routes/(console)/account/payments/editPaymentModal.svelte
  • src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte
  • src/routes/(console)/organization-[organization]/billing/+page.ts
  • src/routes/(console)/organization-[organization]/billing/replaceCard.svelte
  • src/routes/(console)/organization-[organization]/billing/+page.svelte
**/*.svelte

📄 CodeRabbit inference engine (AGENTS.md)

Use Svelte 5 + SvelteKit 2 syntax with TypeScript for component development

Files:

  • src/routes/(console)/organization-[organization]/billing/deleteOrgPayment.svelte
  • src/routes/(console)/account/payments/editPaymentModal.svelte
  • src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte
  • src/routes/(console)/organization-[organization]/billing/replaceCard.svelte
  • src/routes/(console)/organization-[organization]/billing/+page.svelte
src/routes/**

📄 CodeRabbit inference engine (AGENTS.md)

Configure dynamic routes using SvelteKit convention with [param] syntax in route directory names

Files:

  • src/routes/(console)/organization-[organization]/billing/deleteOrgPayment.svelte
  • src/routes/(console)/organization-[organization]/+layout.ts
  • src/routes/(console)/account/payments/editPaymentModal.svelte
  • src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte
  • src/routes/(console)/organization-[organization]/billing/+page.ts
  • src/routes/(console)/organization-[organization]/billing/replaceCard.svelte
  • src/routes/(console)/organization-[organization]/billing/+page.svelte
**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.ts: Define types inline or in .d.ts files, avoid creating separate .types.ts files
Use TypeScript in non-strict mode; any type is tolerated in this project

Files:

  • src/routes/(console)/organization-[organization]/+layout.ts
  • src/routes/(console)/organization-[organization]/billing/+page.ts
🧠 Learnings (6)
📚 Learning: 2025-12-05T09:24:15.846Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2670
File: src/routes/(console)/organization-[organization]/+layout.ts:134-150
Timestamp: 2025-12-05T09:24:15.846Z
Learning: In the Appwrite console codebase, `prefs.organization` is maintained to always reference an organization with Platform.Appwrite, so when using preferences.organization as a fallback in redirect logic, no additional platform validation is required.

Applied to files:

  • src/routes/(console)/organization-[organization]/+layout.ts
  • src/routes/(console)/organization-[organization]/billing/+page.svelte
📚 Learning: 2025-09-08T13:20:47.308Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2316
File: src/routes/(console)/project-[region]-[project]/functions/create-function/deploy/+page.svelte:29-29
Timestamp: 2025-09-08T13:20:47.308Z
Learning: The Form.svelte component in the Appwrite console creates a FormContext with isSubmitting as writable(false) and expects consumers to work with Svelte writable stores, not plain booleans.

Applied to files:

  • src/routes/(console)/account/payments/editPaymentModal.svelte
📚 Learning: 2025-11-25T03:15:27.539Z
Learnt from: CR
Repo: appwrite/console PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T03:15:27.539Z
Learning: Applies to src/routes/**/*.svelte : Use SvelteKit file conventions: +page.svelte for components, +page.ts for data loaders, +layout.svelte for wrappers, +error.svelte for error handling, and dynamic route params in square brackets like [param]

Applied to files:

  • src/routes/(console)/organization-[organization]/billing/+page.svelte
📚 Learning: 2025-10-13T05:16:07.656Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2413
File: src/routes/(console)/project-[region]-[project]/databases/database-[database]/header.svelte:54-58
Timestamp: 2025-10-13T05:16:07.656Z
Learning: In SvelteKit apps, shared layout components (like headers) that use `$derived(page.data.*)` should use optional chaining when accessing properties that may not be present on all routes. During page transitions, reactive statements can briefly evaluate with different page.data structures, so optional chaining prevents runtime errors when navigating between routes with different data shapes (e.g., between `/databases` and `/databases/database-[database]`).

Applied to files:

  • src/routes/(console)/organization-[organization]/billing/+page.svelte
📚 Learning: 2025-10-05T09:41:40.439Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2398
File: src/routes/(console)/verify-email/+page.svelte:48-51
Timestamp: 2025-10-05T09:41:40.439Z
Learning: In SvelteKit 5, `page` imported from `$app/state` is a reactive state object (using runes), not a store. It should be accessed as `page.data` without the `$` prefix, unlike the store-based `$page` from `$app/stores` in earlier versions.

Applied to files:

  • src/routes/(console)/organization-[organization]/billing/+page.svelte
📚 Learning: 2025-10-13T05:13:54.542Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2413
File: src/routes/(console)/project-[region]-[project]/databases/table.svelte:33-39
Timestamp: 2025-10-13T05:13:54.542Z
Learning: In Svelte 5, `import { page } from '$app/state'` provides a reactive state proxy that can be accessed directly (e.g., `page.params`), unlike the older `import { page } from '$app/stores'` which returns a readable store requiring the `$page` syntax for auto-subscription in components.

Applied to files:

  • src/routes/(console)/organization-[organization]/billing/+page.svelte
🧬 Code graph analysis (2)
src/routes/(console)/organization-[organization]/+layout.ts (2)
src/lib/stores/sdk.ts (1)
  • sdk (173-196)
src/lib/stores/organization.ts (1)
  • Organization (16-41)
src/routes/(console)/organization-[organization]/billing/+page.ts (3)
src/lib/stores/organization.ts (2)
  • organization (65-65)
  • Organization (16-41)
src/lib/stores/billing.ts (1)
  • paymentMethods (73-73)
src/lib/sdk/billing.ts (2)
  • PaymentList (27-30)
  • PaymentMethodData (7-25)
🪛 GitHub Actions: Tests
src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte

[error] 314-314: Cannot use 'bind:' with this property. It is declared as non-bindable inside the component. To mark a property as bindable: 'let { show = $bindable() } = $props()' (ts).

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: e2e
🔇 Additional comments (15)
src/routes/(console)/organization-[organization]/+layout.ts (1)

27-27: LGTM - Organization now fetched fresh in Promise.all.

The change correctly addresses the root cause by always fetching the organization directly via sdk.forConsole.teams.get() in the Promise.all, rather than reusing potentially stale data from the parent layout. This ensures payment updates are reflected immediately after invalidation.

Also applies to: 49-56

src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte (2)

60-60: Correct invalidation target change.

Switching from Dependencies.ORGANIZATION to Dependencies.PAYMENT_METHODS is the right fix. This ensures payment method changes trigger the correct dependency invalidation without requiring a full organization reload.

Also applies to: 80-80


37-41: Props-based payment method data flow looks good.

Using explicit primaryMethod and backupMethod props instead of deriving them internally ensures the component receives fresh data after invalidation. The hasPaymentError aggregation and UI bindings are correctly updated to use these props.

Also applies to: 94-98, 124-124, 131-131, 163-163, 170-170

src/routes/(console)/organization-[organization]/billing/replaceCard.svelte (1)

84-84: Correct invalidation target.

Changing to Dependencies.PAYMENT_METHODS aligns with the PR's goal of fixing stale data issues.

src/routes/(console)/account/payments/editPaymentModal.svelte (3)

12-20: Svelte 5 props migration looks correct.

The show prop is properly declared with $bindable(false), allowing two-way binding from parent components. The type annotations are clear and the optional isLinked prop has a sensible default.


27-32: Clean month options generation.

The dynamic month array generation and $derived usage for options is idiomatic Svelte 5. This correctly replaces the previous reactive statement pattern.


41-43: Modal closes before invalidation completes.

Setting show = false before awaiting invalidate() provides better UX by closing the modal immediately. The invalidation still happens in the background.

src/routes/(console)/organization-[organization]/billing/+page.ts (2)

110-131: Clean helper function for extracting payment methods.

The getOrganizationPaymentMethods function efficiently iterates through payment methods once, with an early break when both primary and backup are found. The explicit return type and null initialization are correct.


86-86: Primary/backup methods now derived at load time.

Extracting payment methods in the page loader ensures components receive fresh data after invalidation, addressing the core issue of stale organization data.

Also applies to: 104-106

src/routes/(console)/organization-[organization]/billing/deleteOrgPayment.svelte (3)

28-28: Correct invalidation target for payment deletion.

Switching to Dependencies.PAYMENT_METHODS ensures the payment methods list is refreshed after deletion without requiring a full organization reload.

Also applies to: 48-48


37-37: Typo fix in function name.

Good catch fixing removeBackuptMethodremoveBackupMethod.


67-71: Improved Confirm component usage.

Binding error directly to the Confirm component and using onSubmit with a conditional handler based on isBackup is cleaner than the previous approach.

src/routes/(console)/organization-[organization]/billing/+page.svelte (3)

29-31: Dynamic URL resolution is correct.

Using resolve() from $app/paths with the route pattern and params object is the idiomatic SvelteKit approach for building URLs with dynamic segments.


110-110: Correctly uses loader-provided payment method data.

Accessing data.primaryPaymentMethod?.failed instead of a locally-derived value ensures the UI reflects the latest data after invalidation.


142-146: PaymentMethods props correctly passed.

The component now receives explicit primaryMethod and backupMethod props from the page data, which aligns with the changes in paymentMethods.svelte and ensures fresh data after invalidation.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants