fix(dashboard): count rank summary per keyword, not per device - #141
Open
shuvamk wants to merge 1 commit into
Open
fix(dashboard): count rank summary per keyword, not per device#141shuvamk wants to merge 1 commit into
shuvamk wants to merge 1 commit into
Conversation
getRankSummary incremented trackedKeywords once per keyword row but incremented top10/improved/declined once per device (desktop and mobile) for that same row. The counters and their denominator were on different bases, so a keyword ranking in the top 10 on both devices added 2 to top10 while adding 1 to trackedKeywords — the summary could report more top-10 keywords than tracked keywords. Extract a pure summarizeRankRows helper that classifies each keyword once by its best (lowest) position across devices, and use it in getRankSummary. The counts now share the per-keyword basis, so top10/improved/declined never exceed trackedKeywords. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
sorcerai
approved these changes
Jul 28, 2026
sorcerai
left a comment
There was a problem hiding this comment.
Reviewed exact current diff and tests. Summary counts each keyword once using its best device position, restoring top10 <= trackedKeywords.
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.
Problem
getRankSummarybuilds the dashboard rank scorecard. It counts the denominator per keyword but the numerators per device:Each row carries both a
desktopand amobileresult for the same keyword, so a keyword ranking in the top 10 on both devices adds 2 totop10but 1 totrackedKeywords. The summary can therefore report more top-10 keywords than tracked keywords (e.g. "2 in top 10 out of 1 tracked").improved/declinedhave the same cross-basis inflation.The tested sibling
computeScorecardscomputes these per keyword for a single device (it takes adeviceparam), confirming the intended unit is per-keyword — not both devices summed into a per-keyword denominator.Fix
Extract a pure
summarizeRankRowshelper that classifies each keyword once, using its best (lowest) position across devices, and use it ingetRankSummary. All four numbers now share the per-keyword basis, sotop10/improved/declinedcan never exceedtrackedKeywords.Semantic note for reviewers: I collapsed the two devices to the keyword's best position — the natural reading for an overview scorecard ("how many of my keywords rank in the top 10"). The existing null-handling is preserved (a keyword only counts toward improved/declined when it has both a current and a previous position). If you'd prefer a different aggregation (e.g. a fixed primary device, or counting "new"/"lost" like
computeScorecardsdoes), the helper is the single place to change it.Tests
New
rankSummary.test.ts: a both-device top-10 keyword counted once;top10never exceedingtrackedKeywords; best-device position used for the top-10 check; a null-current keyword ignored; empty input zeroed.Verification
pnpm test— 715 passed (88 files)pnpm ci:check— prettier, knip,tsc --noEmit(×2), and oxlint all green🤖 Generated with Claude Code