feat(mobile): owner-keyed credits, ledger paging, list freshness - #5468
Conversation
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Executive SummaryIncremental review of the parent merge (honest ledger/invoice cursors) confirmed this PR's infinite-query hooks already pass opaque Files Reviewed (5 files)
Previous Review Summaries (3 snapshots, latest commit 5fd5de0)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit 5fd5de0)Status: No Issues Found | Recommendation: Merge Executive SummaryIncremental review confirmed later-page errors now use Files Reviewed (5 files)
Previous review (commit 914f82b)Status: 3 Issues Found | Recommendation: Address before merge Executive SummaryPaged org ledger screens treat any post-load query error as a failed "Load more", and org-scoped security findings are not invalidated on route focus. Overview
Issue Details (click to expand)WARNING
Files Reviewed (10 files)
Fix these issues in Kilo Cloud Previous review (commit a658149)Status: 3 Issues Found | Recommendation: Address before merge Executive SummaryPaged org ledger screens treat any post-load query error as a failed "Load more", and org-scoped security findings are not invalidated on route focus. Overview
Issue Details (click to expand)WARNING
Files Reviewed (14 files)
Reviewed by grok-4.6 · Input: 160.5K · Output: 8.7K · Cached: 253.3K Review guidance: REVIEW.md from base branch |
…cts-dffd # Conflicts: # apps/mobile/src/lib/hooks/use-code-reviews.ts # apps/mobile/src/lib/pr-review/merge/merge-blocked-reasons.ts
…cts-dffd-s2 # Conflicts: # apps/mobile/src/lib/hooks/use-code-reviews.ts # apps/mobile/src/lib/pr-review/merge/merge-blocked-reasons.ts
…cts-dffd-s3 # Conflicts: # apps/mobile/src/i18n/locales/en.json # apps/mobile/src/lib/hooks/use-code-reviews.ts # apps/mobile/src/lib/pr-review/merge/merge-blocked-reasons.ts
…ontracts-dffd-s3 # Conflicts: # apps/mobile/src/components/home/agent-sessions-section.test.ts # apps/mobile/src/components/home/agent-sessions-section.tsx # apps/mobile/src/components/home/home-screen.tsx # apps/mobile/src/i18n/locales/am.json # apps/mobile/src/i18n/locales/id.json # apps/mobile/src/i18n/locales/lt.json # apps/mobile/src/i18n/locales/ta.json # apps/mobile/src/i18n/locales/te.json # apps/mobile/src/i18n/locales/tr.json
Read isFetchNextPageError on the org ledger screens so a failed background refetch keeps the rows and the Load more button instead of showing a Retry that calls fetchNextPage and can never clear. Match the org tRPC prefix in the security finding list, so an org-scoped screen actually invalidates its findings on focus.
Page the organization credit ledger by keyset ((created_at, id) of the last row) instead of by OFFSET. The ledger grows at the head, so a transaction inserted between two requests shifted every later page and page 2 repeated a row page 1 already showed. Return a Stripe invoice cursor only when Stripe reports has_more, so a full final page no longer advertises a next page that is always empty.
Page the organization credit ledger by keyset ((created_at, id) of the last row) instead of by OFFSET. The ledger grows at the head, so a transaction inserted between two requests shifted every later page and page 2 repeated a row page 1 already showed. Return a Stripe invoice cursor only when Stripe reports has_more, so a full final page no longer advertises a next page that is always empty.
…' into audit-w7b-data-contracts-dffd-s3 # Conflicts: # apps/mobile/src/app/(app)/pr-review/[owner]/[repo]/[number]/index.tsx
Summary
The profile credits card now appends the signed-in user id to the query key of its three financial queries,
getContextBalance,getCreditBlocks, and the orggetCreditBlocks, and its placeholder-data gate only reuses a cached value when that value was cached for the same user, so an account switch can no longer render another owner's balance as the current amount. A failed credential lookup now shares the balance error surface, shows the tap-to-retry message, and the retry re-resolves the owner id before re-fetching the balance. The blanketkeepPreviousDataoption is replaced by this per-owner placeholder gate.Files
apps/mobile/src/components/profile-credits-card.tsx— scopes the three balance and credit query keys by user id; gates placeholder reuse on that user id; folds a failed credential lookup into the balance error and its retry.Two new cursor-paged organization query hooks,
useOrgCreditTransactionsPageanduseOrgInvoicesPage, page throughcreditTransactionsPageandinvoicesPagewithuseInfiniteQuery, flatten the pages into a stableentriesarray, and exposehasMore. The next-page cursor comes fromnextCursorwhenever the last page reportshasMore. The existing unpaged hooks stay in place for the other callers.Files
apps/mobile/src/lib/hooks/use-organization-queries.ts— adds the two paged infinite-query hooks and theuseMemoflattening; keeps the legacy unpaged hooks.The credit activity screen now renders four states: loading skeleton, first-page error, empty, and list, on top of the paged query. A first-page
NOT_FOUNDerror maps to the not-found state andFORBIDDENorUNAUTHORIZEDmap to the permission state, both rendered without a retry button, while any other first-page error stays retryable. When a later page fails, the already-loaded rows are kept and an inline retry footer is shown, and the screen invalidates its organization queries when the route regains foreground freshness.Files
apps/mobile/src/components/organization/credit-activity-screen.tsx— switches touseOrgCreditTransactionsPage; adds the four-state body, the error-variant mapping, the truncated load-more footer, the later-page retry footer, anduseRouteForegroundRefresh.The invoices screen now renders the same four states — loading skeleton, first-page error, empty, and list — on the paged invoices query. Its first-page error mapping and later-page retry footer match the credit activity screen, each with no retry for a permanent
NOT_FOUND,FORBIDDEN, orUNAUTHORIZEDerror, and it invalidates its organization queries when the route regains foreground freshness.Files
apps/mobile/src/components/organization/invoices-screen.tsx— switches touseOrgInvoicesPage; adds the four-state body, the error-variant mapping, the truncated load-more footer, the later-page retry footer, anduseRouteForegroundRefresh.The review list and the security findings list now call
useRouteForegroundRefreshso their queries are invalidated when the route regains focus or the app returns active, keeping the lists fresh on return. The review list's existing 5-second in-flight review poll is left unchanged.Files
apps/mobile/src/components/code-reviewer/review-list-screen.tsx— adds thecodeReviewsprefix refresh.apps/mobile/src/components/security-agent/finding-list-screen.tsx— adds thesecurityAgentprefix refresh.The single
useAgentSessionscall moves from the agent-sessions section intoHomeScreen, which now passes the four session fields plusactiveSessionIdsdown to the section as props, so the home screen runs exactly one session query. The section becomes a presentational component over those props, and the compositing, error, and first-use promo gating logic stays inHomeScreen.Files
apps/mobile/src/components/home/home-screen.tsx— ownsuseAgentSessions, destructuresactiveSessionIds, and passes the session fields into the section and the gating helper.apps/mobile/src/components/home/agent-sessions-section.tsx— drops its ownuseAgentSessionsand takes the four session fields as props.The English locale adds the load-more, load-more-failure, and truncation strings for the credit-activity and invoices screens, and adds GitLab and Bitbucket connect, open, and connected strings plus a
Recently usedlabel under the new-session section.Files
apps/mobile/src/i18n/locales/en.json— adds the pagination strings, the GitLab and Bitbucket provider strings, and therecentlyUsedlabel.Tests: 5 test files changed (2 added, 3 updated).
Generated: none.
Verification
No manual tests were run for this level. Full E2E verification runs on the tip (level 5) PR.
Visual Changes
Visual Changes: N/A
Reviewer Notes
This is level 3 of a 5-level stack. Full E2E verification runs on the tip (level 5) PR.
Human steps: none.
Stacked PRs — merge bottom to top. Each level shows only its own diff.
Full verification (E2E, user advocacy, simplify, bot review) runs on the tip PR over every level.
A finding on a level is repaired on that level, then carried upward with stack.sh forward.
audit-w7b-data-contracts-dffd— refactor(mobile): parse raw HTTP and infer review contracts #5460audit-w7b-data-contracts-dffd-s2— feat(web): add org credit and invoice page procedures #5462audit-w7b-data-contracts-dffd-s3— feat(mobile): owner-keyed credits, ledger paging, list freshness #5468 ← this PRaudit-w7b-data-contracts-dffd-s4— refactor: route-scoped registry and live custom mode #5472audit-w7b-data-contracts-dffd-s5— feat(mobile): provider-aware new-session and layout extract #5479 (tip)