Skip to content

Latest-attempt filter, and the retry chains on the dashboard - #298

Merged
hamzahalq merged 2 commits into
releases/r10.0from
hamza/feature/latest-attempt-filter
Sep 10, 2026
Merged

Latest-attempt filter, and the retry chains on the dashboard#298
hamzahalq merged 2 commits into
releases/r10.0from
hamza/feature/latest-attempt-filter

Conversation

@hamzahalq

Copy link
Copy Markdown
Contributor

Follows #297. A retry chain is one piece of work however many attempts it took, which the UI had no way of saying — so a list of failures showed one problem as many rows, and the dashboard counted attempts where someone wants problems.

Latest attempt only — a filter on the exchanges list for where each chain actually got to. On local data that is 1,025 failed attempts against 149 real failures. One predicate in the shared filter code, so bulk retry gets it too: selecting all failures on one subscription went from 90 selected → 84 substitutions → 6 retries to 6 selected → 6 retried, nothing substituted. NOT EXISTS on the indexed RetryFor — the anti-join shape the still-running pill already uses there, for the reasons in that handler's comments.

Failures to act on — a dashboard tile counting problems rather than attempts. Its number comes from the search rather than from the dashboard's own 14-day row fetch, so the tile and the list it opens cannot disagree (the same approach "Pending auto-retries" already takes).

Chains that keep failing — a panel for the chains that are not getting better however often they are retried, worst first, each row opening its chain. Its description carries the retry success rate, because a 34-attempt chain only means "broken" where retries normally succeed — on local data, 3 of 189 did.

XchangeResult.AttemptNumber already stores chain depth, but only for failures a retry policy's group matched, so a hand-retried chain has none. Counted with a batched upward walk instead: one query per level for all candidates at once rather than a walk each, bounded to the 500 newest.

Tested: 3 new integration tests, 2 new e2e specs, and verified by hand against local data.

🤖 Generated with Claude Code

hamzahalq and others added 2 commits September 10, 2026 15:58
A chain is one piece of work however many attempts it took, so a list of
failures otherwise shows one problem as many rows. LatestOnly narrows it to
where each chain got to — an anti-join on the indexed RetryFor, shared with bulk
retry, which then has nothing left to substitute.

The dashboard's summary adds the two things a count of failures cannot say:
which chains keep failing however often they are retried, and whether retrying
achieves anything here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The "Failures to act on" tile counts problems where "failed today" counts
attempts, and reads its number from the search so it agrees with the list it
opens. The panel beside Latest failures says which chains are not getting
better, with the retry success rate as the context that makes a long chain
either bad luck or something to fix.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@hamzahalq
hamzahalq merged commit c14c0d9 into releases/r10.0 Sep 10, 2026
4 of 5 checks passed
@hamzahalq
hamzahalq deleted the hamza/feature/latest-attempt-filter branch September 10, 2026 13:01
@coderabbitai

coderabbitai Bot commented Sep 10, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: simplify9/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: e6db1569-36b2-4a68-8aad-1b8811cf301d

📥 Commits

Reviewing files that changed from the base of the PR and between 4791c6d and 9015d42.

📒 Files selected for processing (10)
  • SW.Bitween.Api/Resources/Dashboard/RetrySummary.cs
  • SW.Bitween.Api/Resources/Xchanges/XchangeFilters.cs
  • SW.Bitween.IntegrationTests/Tests/RetryChainTests.cs
  • SW.Bitween.Web/ClientApp/e2e/dashboard.spec.ts
  • SW.Bitween.Web/ClientApp/e2e/exchanges.spec.ts
  • SW.Bitween.Web/ClientApp/src/api/http/dashboard.ts
  • SW.Bitween.Web/ClientApp/src/api/http/exchanges.ts
  • SW.Bitween.Web/ClientApp/src/api/types.ts
  • SW.Bitween.Web/ClientApp/src/pages/dashboard/DashboardPage.tsx
  • SW.Bitween.Web/ClientApp/src/pages/exchanges/ExchangesPage.tsx

📝 Summary

Summary

  • Adds LatestOnly exchange filtering with NOT EXISTS over indexed RetryFor, including bulk retries.
  • Adds dashboard metrics for actionable failures and retry outcomes.
  • Adds a panel for retry chains that continue failing.
  • Computes chain depth with batched ancestor queries for up to 500 candidates.
  • Adds integration and end-to-end coverage for filtering, metrics, ranking, and navigation.

Risk: risk:medium

Security-sensitive areas: Dashboard permission checks and query exposure. The change adds database queries and user-controlled filtering, but does not change authentication or authorization models.

Test coverage: Adds 3 integration tests and 2 end-to-end specifications. Tests cover latest-attempt filtering, healed and superseded chains, retry metrics, dashboard counts, ranking, navigation, and URL persistence.

Operational concerns: No migration is required. Query performance depends on the indexed RetryFor field. Candidate, traversal, and result limits reduce query load and protect against cyclic retry data. Rollback requires reverting the API, client, and test changes together.

Walkthrough

Adds retry-chain metrics and failing-chain details to the dashboard. Adds a latest-attempt-only exchange filter across the API and web client. Extends integration and end-to-end tests for dashboard counts, chain ranking, filtering, navigation, and URL persistence.

Changes

Retry dashboard observability

Layer / File(s) Summary
Retry summary aggregation
SW.Bitween.Api/Resources/Dashboard/RetrySummary.cs
Adds an authorized dashboard handler that calculates seven-day retry metrics, identifies terminal failures, counts retry ancestors with bounded traversal, and returns the five longest failing chains.
Dashboard retry metrics and chains
SW.Bitween.Web/ClientApp/src/api/http/dashboard.ts, SW.Bitween.Web/ClientApp/src/api/types.ts, SW.Bitween.Web/ClientApp/src/pages/dashboard/DashboardPage.tsx, SW.Bitween.IntegrationTests/Tests/RetryChainTests.cs, SW.Bitween.Web/ClientApp/e2e/dashboard.spec.ts
Adds retry-summary types and loading, an actionable-failure count, retry metrics, failing-chain details, dashboard links, and coverage for counts and navigation.

Latest-attempt exchange filtering

Layer / File(s) Summary
Latest-attempt exchange filtering
SW.Bitween.Api/Resources/Xchanges/XchangeFilters.cs, SW.Bitween.Web/ClientApp/src/api/types.ts, SW.Bitween.Web/ClientApp/src/api/http/exchanges.ts, SW.Bitween.Web/ClientApp/src/pages/exchanges/ExchangesPage.tsx, SW.Bitween.IntegrationTests/Tests/RetryChainTests.cs, SW.Bitween.Web/ClientApp/e2e/exchanges.spec.ts
Adds LatestOnly filtering that excludes superseded exchanges. The web client exposes the filter through query state and a toggle, with integration and end-to-end coverage.

Estimated code review effort: 4 (Complex) | ~45 minutes

Suggested labels: database, risk:medium


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.

❤️ Share

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

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