Skip to content

feat(mobile): owner-keyed credits, ledger paging, list freshness - #5468

Merged
iscekic merged 40 commits into
mainfrom
audit-w7b-data-contracts-dffd-s3
Aug 26, 2026
Merged

feat(mobile): owner-keyed credits, ledger paging, list freshness#5468
iscekic merged 40 commits into
mainfrom
audit-w7b-data-contracts-dffd-s3

Conversation

@iscekic

@iscekic iscekic commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Summary

  • The organization credit activity screen now loads in pages. A "Load more" button brings older activity, the screen keeps the rows it already shows if a later load fails, and it refreshes when you return to it.
  • The organization invoices screen now loads in pages the same way: a "Load more" button for older invoices, kept rows on a failed later load, and a refresh when you return.
  • The profile balance card always shows the balance of the account you are signed in as, never a different account's balance. If it cannot confirm the account, it shows a tap-to-retry message that re-checks the account and reloads the balance.
  • The code review list and the security findings list refresh when you come back to them.

The profile credits card now appends the signed-in user id to the query key of its three financial queries, getContextBalance, getCreditBlocks, and the org getCreditBlocks, 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 blanket keepPreviousData option 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, useOrgCreditTransactionsPage and useOrgInvoicesPage, page through creditTransactionsPage and invoicesPage with useInfiniteQuery, flatten the pages into a stable entries array, and expose hasMore. The next-page cursor comes from nextCursor whenever the last page reports hasMore. 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 the useMemo flattening; 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_FOUND error maps to the not-found state and FORBIDDEN or UNAUTHORIZED map 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 to useOrgCreditTransactionsPage; adds the four-state body, the error-variant mapping, the truncated load-more footer, the later-page retry footer, and useRouteForegroundRefresh.

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, or UNAUTHORIZED error, and it invalidates its organization queries when the route regains foreground freshness.

Files
  • apps/mobile/src/components/organization/invoices-screen.tsx — switches to useOrgInvoicesPage; adds the four-state body, the error-variant mapping, the truncated load-more footer, the later-page retry footer, and useRouteForegroundRefresh.

The review list and the security findings list now call useRouteForegroundRefresh so 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 the codeReviews prefix refresh.
  • apps/mobile/src/components/security-agent/finding-list-screen.tsx — adds the securityAgent prefix refresh.

The single useAgentSessions call moves from the agent-sessions section into HomeScreen, which now passes the four session fields plus activeSessionIds down 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 in HomeScreen.

Files
  • apps/mobile/src/components/home/home-screen.tsx — owns useAgentSessions, destructures activeSessionIds, and passes the session fields into the section and the gating helper.
  • apps/mobile/src/components/home/agent-sessions-section.tsx — drops its own useAgentSessions and 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 used label under the new-session section.

Files
  • apps/mobile/src/i18n/locales/en.json — adds the pagination strings, the GitLab and Bitbucket provider strings, and the recentlyUsed label.

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.

  1. audit-w7b-data-contracts-dffdrefactor(mobile): parse raw HTTP and infer review contracts #5460
  2. audit-w7b-data-contracts-dffd-s2feat(web): add org credit and invoice page procedures #5462
  3. audit-w7b-data-contracts-dffd-s3feat(mobile): owner-keyed credits, ledger paging, list freshness #5468 ← this PR
  4. audit-w7b-data-contracts-dffd-s4refactor: route-scoped registry and live custom mode #5472
  5. audit-w7b-data-contracts-dffd-s5feat(mobile): provider-aware new-session and layout extract #5479 (tip)

@iscekic iscekic self-assigned this Aug 25, 2026
@kilo-code-bot

kilo-code-bot Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

Incremental review of the parent merge (honest ledger/invoice cursors) confirmed this PR's infinite-query hooks already pass opaque nextCursor values and need no further changes.

Files Reviewed (5 files)
  • apps/web/src/lib/creditTransactions.ts
  • apps/web/src/lib/creditTransactions.page.test.ts
  • apps/web/src/lib/stripe/index.ts
  • apps/web/src/lib/stripe/index.test.ts
  • apps/web/src/routers/organizations/organization-router.ts
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 Summary

Incremental review confirmed later-page errors now use isFetchNextPageError and org security findings invalidate on the organizations.securityAgent prefix.

Files Reviewed (5 files)
  • apps/mobile/src/components/organization/credit-activity-screen.tsx
  • apps/mobile/src/components/organization/invoices-screen.tsx
  • apps/mobile/src/components/security-agent/finding-list-screen.tsx
  • apps/mobile/src/components/organization/credit-activity-screen.mounted.test.tsx
  • apps/mobile/src/components/organization/invoices-screen.mounted.test.tsx

Previous review (commit 914f82b)

Status: 3 Issues Found | Recommendation: Address before merge

Executive Summary

Paged 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

Severity Count
CRITICAL 0
WARNING 3
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
apps/mobile/src/components/organization/credit-activity-screen.tsx 184 isError && hasLoadedPages treats a failed refetch as a later-page error; Retry calls fetchNextPage() and can stick
apps/mobile/src/components/organization/invoices-screen.tsx 217 Same later-page vs refetch error conflation as credit activity
apps/mobile/src/components/security-agent/finding-list-screen.tsx 71 [['securityAgent']] does not match org keys [['organizations', 'securityAgent', …]]
Files Reviewed (10 files)
  • apps/mobile/src/components/organization/credit-activity-screen.tsx - 1 issue
  • apps/mobile/src/components/organization/invoices-screen.tsx - 1 issue
  • apps/mobile/src/components/security-agent/finding-list-screen.tsx - 1 issue
  • apps/mobile/src/components/profile-credits-card.tsx - 0 issues
  • apps/mobile/src/components/profile-credits-card.mounted.test.tsx - 0 issues
  • apps/mobile/src/lib/hooks/use-organization-queries.ts - 0 issues
  • apps/mobile/src/components/organization/credit-activity-screen.mounted.test.tsx - 0 issues
  • apps/mobile/src/components/organization/invoices-screen.mounted.test.tsx - 0 issues
  • apps/mobile/src/components/code-reviewer/review-list-screen.tsx - 0 issues
  • apps/mobile/src/i18n/locales/en.json - 0 issues

Fix these issues in Kilo Cloud

Previous review (commit a658149)

Status: 3 Issues Found | Recommendation: Address before merge

Executive Summary

Paged 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

Severity Count
CRITICAL 0
WARNING 3
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
apps/mobile/src/components/organization/credit-activity-screen.tsx 168 isError && hasLoadedPages treats a failed refetch as a later-page error; Retry calls fetchNextPage() and can stick
apps/mobile/src/components/organization/invoices-screen.tsx 213 Same later-page vs refetch error conflation as credit activity
apps/mobile/src/components/security-agent/finding-list-screen.tsx 71 [['securityAgent']] does not match org keys [['organizations', 'securityAgent', …]]
Files Reviewed (14 files)
  • apps/mobile/src/components/organization/credit-activity-screen.tsx - 1 issue
  • apps/mobile/src/components/organization/invoices-screen.tsx - 1 issue
  • apps/mobile/src/components/security-agent/finding-list-screen.tsx - 1 issue
  • apps/mobile/src/components/profile-credits-card.tsx - 0 issues
  • apps/mobile/src/components/profile-credits-card.mounted.test.tsx - 0 issues
  • apps/mobile/src/lib/hooks/use-organization-queries.ts - 0 issues
  • apps/mobile/src/components/organization/credit-activity-screen.mounted.test.tsx - 0 issues
  • apps/mobile/src/components/organization/invoices-screen.mounted.test.tsx - 0 issues
  • apps/mobile/src/components/home/home-screen.tsx - 0 issues
  • apps/mobile/src/components/home/agent-sessions-section.tsx - 0 issues
  • apps/mobile/src/components/home/agent-sessions-section.test.ts - 0 issues
  • apps/mobile/src/components/home/home-screen.mounted.test.tsx - 0 issues
  • apps/mobile/src/components/code-reviewer/review-list-screen.tsx - 0 issues
  • apps/mobile/src/i18n/locales/en.json - 0 issues

Fix these issues in Kilo Cloud


Reviewed by grok-4.6 · Input: 160.5K · Output: 8.7K · Cached: 253.3K

Review guidance: REVIEW.md from base branch audit-w7b-data-contracts-dffd-s2

iscekic added 15 commits August 25, 2026 22:29
…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
@iscekic
iscekic marked this pull request as ready for review August 26, 2026 13:32
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.
@iscekic
iscekic requested review from RSO and eshurakov and removed request for jeanduplessis August 26, 2026 15:18
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.
@iscekic iscekic closed this Aug 26, 2026
@iscekic iscekic reopened this Aug 26, 2026
@iscekic iscekic closed this Aug 26, 2026
@iscekic iscekic reopened this Aug 26, 2026
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
Base automatically changed from audit-w7b-data-contracts-dffd-s2 to main August 26, 2026 17:15
@iscekic
iscekic merged commit b73e53f into main Aug 26, 2026
18 checks passed
@iscekic
iscekic deleted the audit-w7b-data-contracts-dffd-s3 branch August 26, 2026 17:16
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