feat(dashboard): dashboard UI fixes and hybrid attribution in the simulator - #439
Open
AnkitKmrGupta wants to merge 5 commits into
Open
AnkitKmrGupta wants to merge 5 commits into
AnkitKmrGupta wants to merge 5 commits into
Conversation
jagan-jaya
requested changes
Sep 18, 2026
jagan-jaya
previously approved these changes
Sep 18, 2026
AnkitKmrGupta
force-pushed
the
feat-dashboard-simulator-enhancements
branch
from
September 19, 2026 09:05
f4dba94 to
28f8d7d
Compare
AnkitKmrGupta
force-pushed
the
feat-dashboard-simulator-enhancements
branch
from
September 19, 2026 09:28
28f8d7d to
3a86b94
Compare
jagan-jaya
approved these changes
Sep 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Dashboard polish plus two correctness fixes. On the Overview every card counted a single routing kind, so a merchant's hybrid traffic was invisible; in the Decision Simulator every hybrid decision was attributed to SR, including the ones the static rule made.
Overview — every card counted one routing kind
The page sends no
routing_kind, so the endpoint defaulted to multi-objective and a merchant's hybrid traffic never appeared. On a merchant doing 9,271 hybrid and 2,065 decide-gateway requests, Requests read 2,065, Gateway activity read "2,065 decisions across 2 gateways", and Auth rate was computed over the decide-gateway slice alone.Errors was separately wrong: it summed
top_errors, which the server caps at the five largest groups, so a merchant failing in more ways than the card lists saw a total smaller than the list under it.totalson the overview response —request_count,requests_by_route,error_count,auth_rate,gateway_volumes— counted across both decision flow types (ALL_DECISION_FLOW_TYPES). The Overview cards read from it.route_hitsstill scopes/update_gatewayto the payments one kind decided — counting the endpoint outright would print the same merchant-wide number on both tabs — whiletotals.requests_by_routecounts every call to it.error_summaries::load_totalruns the summary query's filters with noGROUP BYand noLIMIT, so a total and the list it sits above cannot disagree. TheErrorsKPI reads it too; it previously used a routing-kind-scoped count whiletop_errorswas not scoped, so one response could contradict itself./analytics/routing-stats: one analytics request instead of two, and every figure comes from one response.On the page:
auth_ratethe response already carried and nothing rendered. Its subtitle names the denominator as resolved outcomes — pending statuses are in neither the success nor the failure bucket, so it never matched the endpoint's call count and "reported" implied it did.humanizeAuditValue(already used by Decision Audit) rather than shouted.Simulator — hybrid decisions were all credited to SR
srBased = total - costWontreated anything that wasn't a cost override as SR-decided. On a hybrid run the rule answers whenever the dynamic half returns nothing, so a run whose Transaction Log was entirelyRULE_OUTPUTstill read 208 of 208 SR-based decisions.—. Both tooltips say what the denominator is.RULE_OUTPUTas raw text while the other approaches had badges. It is now a Rule Based badge, indigo — violet is stripe's connector colour on the same page, emerald is Cost Based, amber is Hedging, red is FAILURE. Label and badge come from oneroutingApproachDisplay()shared by the cell and the column filter, replacing a duplicated ternary chain.Hybrid routing (/routing/hybrid)is wider than the 170px field and a native select paints the overflow over its own arrow. The option text is now the label; the path moved to hover.Analytics header
Title, view tabs and the time range shared one row. The tab strip grows with every routing view added, so it squeezed the range pills until
Customwrapped onto a line of its own.SelectMenu, new) — one fixed-width trigger whatever the list holds, so a new routing view can never squeeze that row again.ANALYTICS_VIEW_TABSlist now drives theAnalyticsViewunion, the?view=values the URL accepts, release gating and the menu itself. Adding a routing view is one line plus its panel.unhandledView(view: never)closes the panel chain, so a view added without a panel is a build error instead of a tab that quietly renders the panel next to it.?view=.Other UI fixes
Customstops being stranded on its own line.:focusto:focus-visible. A mouse click used to leave a stuck halo on the clicked control; keyboard focus still rings. App-wide.padding-right: 12px, narrower than the native arrow, so "Member" ran underneath it.12 of 1,556on page 1 and page 4 alike. It now shows the page's slice:37–48 of 1,556.BASE_URL.Backend
update_gateway_score_skipped, stagescore_skipped) carrying the request and the reason it was skipped, so a skipped score appears in Decision Audit instead of vanishing. Both label maps resolve the new stage to "Update Gateway".read_effectivereported it off while the decider's own fallback kept routing on cost — a disable silently didn't stick. The toggle now writes the current key and clears the legacy entry.Verification
tsc --noEmitclean,vite buildgreen.cargo fmt --check,cargo clippyandcargo test --lib(510 passed) run locally. The single clippy warning is pre-existing, involume_commitment.rs.CHARGED+ 670FAILURE= the 10,432 the card reports.