Skip to content

fix(history): signal when the history fetch hit its row cap - #630

Merged
cristim merged 4 commits into
mainfrom
fix/history-truncation-signal
Oct 6, 2026
Merged

cristim merged 4 commits into
mainfrom
fix/history-truncation-signal

Conversation

@cristim

@cristim cristim commented Oct 6, 2026 •

Copy link
Copy Markdown
Member

Refs #248

Problem

GET /api/history fetches completed rows and non-completed executions at a cap (default 100) and applies the provider/account/date/scope filters afterwards, so rows beyond the cap are dropped silently. Pending approvals and summary totals can under-report with no UI hint.

Change

  • HistoryResponse gains truncated (bool) and limit (int); openapi.yaml updated. The response was already an envelope, so this is additive and backward compatible.
  • truncated is true when the completed fetch returned >= limit rows or the execution fetch returned >= DefaultListLimit rows.
  • Frontend: banner above the approval queue and the history table (history.ts, index.html, types.ts).
  • Tests: handler_history_truncation_test.go (at cap, under cap, custom limit, execution cap, scoped user). Mutating either >= to > fails them.

Scope interaction

The cap is applied BEFORE scope filtering (the store fetch is global), so a scoped user can lose their own rows behind other tenants' rows. truncated is judged on the raw fetch and exposed only as a boolean (no total), so no per-tenant counts leak; the scoped-user test asserts no total key. A scoped user may see the banner when the overflow is other tenants' rows. Summary totals are computed from the capped, filtered set, which the banner covers.

Decisions (alternatives)

  • truncated + limit instead of total: a correct total needs COUNT queries with the same SQL filters on two tables, and the executions side is filtered in Go, so a total would need scope-aware counting. Alternative: add COUNT queries plus a total.
  • Detect by len >= limit instead of fetching limit+1: avoids changing the store call arguments pinned by ~40 existing mock expectations. Cost: a false positive when exactly limit rows exist (documented in the field comment). Alternative: fetch limit+1 and trim.
  • Not done: paging, or pushing provider/account/date filters into the executions SQL query (the real fix for pending approvals falling outside the first page); follow-up.

Verification

go test -race -short ./... , go vet ./... , go vet -tags integration ./internal/..., openapi tests pass; errcheck -blank, shadow, misspell clean on changed lines. Frontend jest test added but NOT run locally (no node_modules offline); CI will run it.

Why partial: paging and the executions-side SQL filtering remain open, so this is Refs, not Closes.

Review follow-up

The history API capped completed rows and non-completed executions at the
row limit with no indication, so pending approvals and summary totals could
silently under-report. Add truncated and limit to the response and show a
banner above the approval queue and the history table.

Refs #248
@cristim cristim added severity/medium Moderate harm urgency/this-sprint Within the current sprint triaged Item has been triaged priority/p1 Next up; this sprint impact/many Affects most users effort/m Days type/bug Defect labels Oct 6, 2026
@coderabbitai

coderabbitai Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

  • Run on-demand review

This review includes 11 billable files and costs up to $2.75.

  • Ask an admin to make reviews automatic

Open in CodeRabbit

Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing.

Or wait 23 minutes for your next included review.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available. Your 68 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository: LeanerCloud/cloud-commitments-platform/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: 4519ab95-2a01-41f5-bc2d-b00a2ac75899
📥 Commits

Reviewing files that changed from the base of the PR and between fa10886 and 8e0033e.

📒 Files selected for processing (11)
  • frontend/src/__tests__/history-truncation-notice.test.ts
  • frontend/src/history.ts
  • frontend/src/index.html
  • frontend/src/types.ts
  • internal/api/handler_history.go
  • internal/api/handler_history_truncation_test.go
  • internal/api/openapi.yaml
  • internal/api/types.go
  • internal/config/store_postgres.go
  • internal/config/store_postgres_executions_by_statuses_integration_test.go
  • internal/config/store_postgres_pgxmock_test.go
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

Exclude clean completed executions in the store query and from the cap
count so mature tenants do not see a permanent banner. Report the fixed
executions_limit separately from limit, make the banner text accurate,
and clear it when a load fails.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/m Days impact/many Affects most users priority/p1 Next up; this sprint severity/medium Moderate harm triaged Item has been triaged type/bug Defect urgency/this-sprint Within the current sprint

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant