Move the two GSC dashboard cards onto the state boundary - #24
Merged
Conversation
Lane 2 of the migration. Both cards read the same free Search Console report, and both got their states subtly wrong in the same way Lane 1 did. **Project Keywords could report an absence it had not established.** The zero case printed "No search queries yet in this period" whenever `summary.ranking === 0` — a count taken from ONE capped pull. The card knew about the cap (it branched on `truncated` for its copy) but the branch was a hand-rolled boolean beside the sentence rather than evidence feeding the decision. It now passes `sampling` to `resolveQueryState`, so a truncated zero can only render "nothing in the rows we read", never a property-wide absence. The bespoke "Counted across the N queries..." paragraph is gone with it: the boundary's CappedPullNotice says the same thing, and two copies of one caveat is the drift the shared layer exists to remove. The two inner lists keep their own copy, deliberately — they are subsets that can be empty while the summary above has rows, so the card-level sentence would be wrong for them. **Search Performance had no empty state and should not have one.** Zero clicks on a connected property is a valid report, not an absence, so `rowCount` is the presence of the report object rather than the size of its numbers. Its four zeroes are the honest answer. Both cards keep their `DashboardCard` frame in every state, so the dashboard grid no longer changes shape between loading, error and ready. Project Keywords still renders nothing at all when disconnected — the Search Performance card directly above owns that state, and two connect prompts stacked on one dashboard read as two separate problems. Verified in the browser on the not-connected path: Search Performance renders its connect prompt, Project Keywords renders nothing, no error boundary, and a fresh dev server plus a fresh tab shows zero console errors. The ready and truncated-empty paths still need a connected GSC property, which this machine does not have. ci:check clean, 2,122 tests passing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
flyrocketseo | c741ffb | Jul 30 2026, 10:44 PM |
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.
Lane 2 of the state-boundary migration. Both cards read the same free Search
Console report, and both got their states subtly wrong in the same way Lane 1 did.
Project Keywords could report an absence it had not established
The zero case printed "No search queries yet in this period" whenever
summary.ranking === 0— a count taken from one capped pull.The card knew about the cap (it branched on
truncatedfor its copy), but thebranch was a hand-rolled boolean sitting beside the sentence rather than evidence
feeding the decision. It now passes
samplingintoresolveQueryState, so atruncated zero can only render "nothing in the rows we read" — never a
property-wide absence.
The bespoke "Counted across the N queries…" paragraph goes with it: the
boundary's
CappedPullNoticesays the same thing, and two copies of one caveatis exactly the drift the shared layer exists to remove.
The two inner lists keep their own copy, deliberately — they're subsets that
can be empty while the summary above has rows, so the card-level sentence would
be the wrong claim for them.
Search Performance had no empty state, and shouldn't have one
Zero clicks on a connected property is a valid report, not an absence. So
rowCountis the presence of the report object, never the size of its numbers— four zeroes are the honest answer.
Both
Each card keeps its
DashboardCardframe in every state, so the dashboard gridno longer changes shape between loading, error and ready.
Project Keywords still renders nothing when disconnected: the Search
Performance card directly above owns that state, and two connect prompts stacked
on one dashboard read as two separate problems.
Verification
Browser-checked on the not-connected path — Search Performance renders its
connect prompt, Project Keywords renders nothing, no error boundary. A fresh dev
server plus a fresh tab shows zero console errors (the first check showed
stale HMR errors from editing while the server was live; that trap has already
produced one false diagnosis in this project).
pnpm ci:checkclean, 2,122 tests passing.Not verified: the ready and truncated-empty paths need a connected GSC property,
which this machine doesn't have — the same gap noted for Lane 1.
🤖 Generated with Claude Code