Repository navigation
fix: load activity and expense histories with infinite scrolling - #789
Conversation
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Pagination contract and server queries src/utils/pagination.ts, src/server/api/routers/expense.ts, src/tests/integration/pagination.integration.test.ts, src/utils/pagination.test.ts, src/tests/integration/{balances,expense}.integration.test.ts, docs/expense-pagination.md |
Shared utilities define page limits, date-and-ID cursors, page construction, flattening, and sequential collection. Expense history endpoints return bounded pages. Integration tests cover ordering, cursor traversal, deletion visibility, authorization, and page limits. |
Infinite history views src/components/InfiniteScroll.tsx, src/components/InfiniteScroll.test.tsx, src/pages/activity.tsx, src/pages/balances/[friendId].tsx, src/pages/groups/[groupId].tsx, src/components/Expense/ExpenseList.tsx, public/locales/en/common.json, tests/e2e/infinite-scroll.spec.ts, docs/expense-pagination.md |
Activity, friend, and group pages flatten loaded pages and use InfiniteScroll to load more. The control supports automatic loading, retry, and loading and error states. Group details supply the earliest qualifying expense date separately. |
Friend CSV export across pages src/components/Friend/Export.tsx, src/pages/balances/[friendId].tsx, src/utils/pagination.ts, tests/e2e/infinite-scroll.spec.ts, docs/expense-pagination.md |
Friend CSV export can fetch all expense pages through a callback. The export button tracks progress and reports failures. The end-to-end test checks export before scrolling through all visible pages. |
Estimated code review effort: 3 (Moderate) | ~25 minutes
Change: Bug fix · Severity of issue fixed: Medium
Sequence Diagram(s)
sequenceDiagram
actor User
participant InfiniteScroll
participant ActivityPage
participant expense.getAllExpenses
User->>InfiniteScroll: reach the observed sentinel
InfiniteScroll->>ActivityPage: request another page
ActivityPage->>expense.getAllExpenses: fetch with the next cursor
expense.getAllExpenses->>ActivityPage: return items and optional nextCursor
ActivityPage->>User: render flattened expense pages
Possibly related PRs
- oss-apps/split-pro#784: Adds offset-paginated expense listing procedures. This PR changes the same expense history procedures to cursor pagination and changes their response shape.
Suggested reviewers: kiwilmao
Merge Risk: 
Minimal · previous review 046e4
-
No actionable risk introduced by this change remains identified; it is ready to merge after normal checks.
Pre-merge checks: 
5
-
Full details: Title check
-
Explanation
The title "fix: load activity and expense histories with infinite scrolling" matches the main change. The PR adds cursor pagination and an InfiniteScroll control so activity, friend, and group expense histories load 50 rows at a time and fetch more as the user scrolls. The title names the primary change and uses a conventional prefix. It does not mention the server-side cursor pagination or CSV export changes, which is acceptable because the title does not need to cover every detail.
Full details: Linked Issues check
-
Explanation
Issue
#757requires responsive large expense histories through pagination or incremental loading. The PR adds cursor pagination with a default limit of 50 togetExpensesWithFriend,getGroupExpenses, andgetAllExpenses. Activity, friend, and group pages use infinite queries and load-more controls. Integration and end-to-end tests cover page limits, stable ordering, deleted cursors, authorization, termination, and incremental loading. CSV export still collects all pages through bounded requests.
Full details: Out of Scope Changes check
-
Explanation
The changes support the pagination objective in
#757. Shared pagination utilities, scroll-state translations and tests, CSV page collection, the separate earliest group expense query, and documentation address pagination behavior or preserve existing history features. No unrelated change is established by the provided scope evidence.
Full details: Docstring Coverage
-
Explanation
No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 0 functions across 15 files. (2 skipped: 2 unsupported.)
Full details: Description check
-
Explanation
The description clearly explains the change, testing performed, related issue, demo coverage, and known limitations. It does not include the template's Demo or Checklist headings, but the missing sections are non-critical because the description includes validation details and closes issue
#757.
-
Finishing Touches
-
Generate docstrings
-
- Commit to this branch
- Create a new PR
Generate unit tests (beta)
-
- Commit to this branch
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
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.
The review asked to reuse the cursor pagination from oss-apps#789 instead of a second offset-based scheme, to support receipt uploads so adding expenses via the API is complete, and to document the scope of the API. It also pointed out a misaligned input and generic model names in the docs UI. - Mount the app's paginated expense procedures directly and switch user.getOwnExpenses to the shared cursor helpers; drop api/pagination.ts - Accept ISO strings as cursor date and cursor[date]/cursor[id] params - Add POST /api/v1/upload (API key) sharing the handler with /api/upload - Configure the key limit via API_KEYS_MAX_PER_USER (default 10) - List procedures explicitly in apiRouter, removing the unsafe cast - Inline the ApiKeys handlers and align the create form inputs - Hide generator-named models in Scalar - Rename docs/api.md to docs/API.md; document rollout scope, uploads, health checks and the participant amount sign convention
Large expense histories currently load every row into a single response, causing multi-megabyte tRPC responses and slow activity, friend, and group pages. These pages now load 50 rows at a time and fetch the next page as the user scrolls.
Shared pagination helpers use date-and-ID cursors with stable ordering, including when expenses share a date or the cursor row is deleted. A reusable scroll control provides loading, manual load-more, and retry states. Future server-side search and filter criteria can extend query inputs while keeping pagination and cache handling intact.
CSV exports still include the full history, collected through bounded requests on demand. The group's first-expense statistic is fetched independently of the loaded pages.
Closes #757.
Validation
Rows are appended without virtualization. Scrolling through an entire large history can still create a large DOM; concurrent edits that change sort dates may move rows across page boundaries until refresh.
Summary by CodeRabbit