Skip to content

fix(billing): derive history pagination from totalCount - #3595

Merged
baktun14 merged 1 commit into
mainfrom
fix/billing-history-pagination-total-count
Aug 13, 2026
Merged

fix(billing): derive history pagination from totalCount#3595
baktun14 merged 1 commit into
mainfrom
fix/billing-history-pagination-total-count

Conversation

@baktun14

@baktun14 baktun14 commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Why

The billing History table pagination was broken in production. On load an account with ~2 pages of transactions showed ~4 pages; clicking page 2 collapsed the count to 2; clicking the phantom page 3/4 loaded an empty table.

The view fabricated its page numbers from the hasMore flag plus a hardcoded "render a literal page 3 + ellipsis while on the first page" block, and never used the stable totalCount the container (and backend COUNT(*)) already provided. So:

  • Page 1 (pageIndex 0): rendered 1, 2 (because hasMore), then the hardcoded 3 + + Next → looked like ~4 pages.
  • Click page 2: backend hasMore is now false and the first-page block is gone → collapsed to 1, 2.
  • Click the phantom 3 / Next: jumped to an offset past totalCount → empty "No billing history found".

What

  • Replaced the hand-rolled pagination in BillingView with the shared CustomPagination component already used by the alerts/providers/deployments tables, driven by Math.ceil(totalCount / pageSize).
  • Dropped the now-dead hasMore/hasPrevious props from BillingView and BillingContainer.
  • Updated the BillingView/BillingContainer specs and added regression cases: 15 rows → exactly 2 pages (no phantom page 3), 35 rows → 4 pages, clicking page 3 navigates to pageIndex: 2.

Minor UX change: page buttons no longer disable during a background refetch (CustomPagination has no fetching state, consistent with the other tables; keepPreviousData keeps rows visible meanwhile).

Verification: npm run test:unit -- BillingView BillingContainer (32 passed), npm run lint -- --quiet clean, npx tsc --noEmit no new errors in the changed files.

Summary by CodeRabbit

  • New Features

    • Added numbered pagination for billing usage views.
    • Added previous/next navigation and page-size selection.
    • Pagination now accurately reflects available pages and resets when the page size changes.
  • Tests

    • Expanded coverage for page navigation, total-page calculations, page-size changes, and preventing empty phantom pages.

The History table built its page numbers from hasMore plus a hardcoded
"page 3 + ellipsis on the first page" block and never used the stable
totalCount already provided by the container. On accounts with ~2 pages
this rendered phantom pages that collapsed after navigating and loaded
empty pages past the end.

Replace the hand-rolled pagination with the shared CustomPagination
component (used by the alerts/providers/deployments tables), driven by
ceil(totalCount / pageSize). Drop the now-dead hasMore/hasPrevious props
from the view and container.
@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b41f0e2a-5b6f-44c9-8c86-650a46028fbb

📥 Commits

Reviewing files that changed from the base of the PR and between 3cb2506 and 2a3d6f2.

📒 Files selected for processing (4)
  • apps/deploy-web/src/components/billing-usage/BillingContainer/BillingContainer.spec.tsx
  • apps/deploy-web/src/components/billing-usage/BillingContainer/BillingContainer.tsx
  • apps/deploy-web/src/components/billing-usage/BillingView/BillingView.spec.tsx
  • apps/deploy-web/src/components/billing-usage/BillingView/BillingView.tsx
💤 Files with no reviewable changes (2)
  • apps/deploy-web/src/components/billing-usage/BillingContainer/BillingContainer.spec.tsx
  • apps/deploy-web/src/components/billing-usage/BillingContainer/BillingContainer.tsx

📝 Walkthrough

Walkthrough

Billing usage pagination now uses CustomPagination with numbered pages. BillingView derives page counts from totalCount and pageSize. Cursor-based pagination flags were removed from the container and view contracts.

Changes

Billing Pagination

Layer / File(s) Summary
Pagination contract and wiring
apps/deploy-web/src/components/billing-usage/BillingContainer/BillingContainer.tsx, apps/deploy-web/src/components/billing-usage/BillingContainer/BillingContainer.spec.tsx, apps/deploy-web/src/components/billing-usage/BillingView/BillingView.tsx, apps/deploy-web/src/components/billing-usage/BillingView/BillingView.spec.tsx
Removed hasMore and hasPrevious from the render callback, public props, component registry, and test setup. Wired CustomPagination into BillingView.
Page-number pagination behavior
apps/deploy-web/src/components/billing-usage/BillingView/BillingView.tsx, apps/deploy-web/src/components/billing-usage/BillingView/BillingView.spec.tsx
Calculated total pages from totalCount and pageSize. Preserved page size during page navigation and reset the page index when page size changed. Added tests for navigation and phantom-page prevention.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Mergeability Score: ⚪ Minimal · up to 2a3d6

The change replaces fabricated billing-history page counts with pagination derived from total transaction count, preventing phantom pages and empty results; no actionable merge-blocking risk remains after normal checks and review.

Possibly related PRs

Suggested reviewers: ygrishajev

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/billing-history-pagination-total-count

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

apps/deploy-web/src/components/billing-usage/BillingView/BillingView.spec.tsx

ESLint skipped: missing config or dependency (missing-dependency). The ESLint configuration references a package that is not available in the sandbox.

apps/deploy-web/src/components/billing-usage/BillingView/BillingView.tsx

ESLint skipped: the ESLint configuration for this file references a package that is not available in the sandbox.


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

@codecov

codecov Bot commented Aug 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 76.20%. Comparing base (3cb2506) to head (2a3d6f2).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3595      +/-   ##
==========================================
- Coverage   77.02%   76.20%   -0.82%     
==========================================
  Files        1150     1057      -93     
  Lines       30026    27572    -2454     
  Branches     7492     7007     -485     
==========================================
- Hits        23127    21011    -2116     
+ Misses       6078     5770     -308     
+ Partials      821      791      -30     
Flag Coverage Δ *Carryforward flag
api 89.11% <ø> (ø) Carriedforward from 3cb2506
deploy-web 67.36% <ø> (-0.01%) ⬇️ Carriedforward from 3cb2506
log-collector ?
notifications 93.84% <ø> (ø) Carriedforward from 3cb2506
provider-console 81.38% <ø> (ø) Carriedforward from 3cb2506
provider-inventory ?
provider-proxy 88.17% <ø> (ø) Carriedforward from 3cb2506
tx-signer ?

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

Files with missing lines Coverage Δ
...illing-usage/BillingContainer/BillingContainer.tsx 68.75% <ø> (-0.95%) ⬇️
...mponents/billing-usage/BillingView/BillingView.tsx 95.31% <ø> (+4.06%) ⬆️

... and 93 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.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM — straightforward pagination fix that adopts an already-proven shared component.

Extended reasoning...

Overview

Four files in apps/deploy-web: BillingView.tsx/.spec.tsx and BillingContainer.tsx/.spec.tsx. The change removes a hand-rolled, buggy pagination block (relying on hasMore/hardcoded page-3 rendering) and replaces it with the shared CustomPagination component, deriving totalPageCount from the backend-provided totalCount via Math.ceil(totalCount / pageSize) (floored at 1). Dead hasMore/hasPrevious props are removed from both the view and its container.

Security risks

None. This is a pure UI pagination change with no auth, data access, or injection surface — it only affects how existing, already-fetched billing transaction data is paginated for display.

Level of scrutiny

Low-to-moderate is appropriate: this is a UI bug fix, not a critical path, and it replaces bespoke logic with a component (CustomPagination) already in production use in ProviderList, LeaseList, DeploymentList, AlertsListView, and NotificationChannelsListView. I verified CustomPagination's prop contract (pageIndex, pageSize, totalPageCount, setPageIndex, setPageSize) in packages/ui/components/custom-pagination.tsx and confirmed BillingView.tsx wires it correctly, including the pageIndex: 0 reset on page-size change.

Other factors

Test coverage is solid: new regression tests directly encode the reported bug (15 rows → exactly 2 pages, no phantom 3rd page; 35 rows → 4 pages; clicking page 3 navigates to pageIndex: 2), and the removed dead props are reflected in updated specs. The noted minor UX change (pagination buttons no longer disable during background refetch) is explicitly called out and consistent with how the other list views already behave with CustomPagination, so it's not a regression worth blocking on.

@baktun14
baktun14 merged commit bff1880 into main Aug 13, 2026
58 checks passed
@baktun14
baktun14 deleted the fix/billing-history-pagination-total-count branch August 13, 2026 19:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant