Release: analytics for Plan Analyzer web app#223
Merged
erikdarlingdata merged 13 commits intomainfrom Apr 13, 2026
Merged
Conversation
…ed rows in FetchGroupedPlansAsync, the first root row is recursively expanded to the deepest level so the user immediately sees the full hierarchy. 2. Load child plans (LoadHighlightedPlan_Click / LoadSelected_Click / CollectLeafPlans): • "Load Plan" on a grouped row (QueryHash, PlanHash, or Module level) now recursively collects all descendant leaf plans where both PlanId > 0 and QueryId > 0 • Rows with PlanId == 0 or QueryId == 0 are never loaded • "Load Selected" does the same expansion for each selected row 3. Golden headers (ApplyGroupByHeaderColors): • When GroupBy=QueryHash: "Query Hash" and "Plan Hash" column headers get gold (#FFD700) foreground • When GroupBy=Module: "Module" and "Query Hash" column headers get gold • When GroupBy=None: all header colors are reset to default 4. Column reorder (ReorderColumnsForGroupBy): • QueryId and PlanId columns are now pushed after the GroupBy key columns • QueryHash mode: Expand → Checkbox → QueryHash → PlanHash → QueryId → PlanId → rest • Module mode: Expand → Checkbox → Module → QueryHash → QueryId → PlanId → rest • None mode: original column order is fully restored
…nts (query text and plan xml) after computations and top/bottom reduction
…ediate row, the code now picks the QueryText from the top representative leaf row (the one with IsTopRepresentative == true, falling back to the first available leaf) and assigns it to the parent's QueryStorePlan.QueryText. This is done at two levels: 1. Intermediate rows (PlanHash in QueryHash mode, QueryHash in Module mode): Gets the query text from the top representative leaf within that specific group. 2. Root rows (QueryHash level, Module level): Gets the query text from the top representative leaf across all leaves in that root group. No additional database queries are made — the text comes entirely from grouped.LeafRows which was already fetched.
…alongside GridLoadingOverlay.IsVisible = true at the start of every fetch, so any lingering empty message is dismissed before the next request. 2. FetchGroupedPlansAsync — When IntermediateRows.Count == 0 and the mode is Module: sets the message text to "No module found in the selected period", shows the overlay, and returns — without writing to StatusText. For QueryHash mode (or any other non-Module grouped mode) that still hits the empty case, the original status bar message is preserved.
…nger Feature/query store group by changer
… grouped fetches The Step 3 ranked CTEs in both FetchGroupedByQueryHashAsync and FetchGroupedByModuleAsync joined sys.query_store_query_text without using any of its columns — the actual text fetch happens in the Final select. Also fixes tab/space inconsistency in the doc comment blocks for both methods. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…leanup Remove unnecessary query_store_query_text joins in grouped fetches
- Add page_views table and POST /api/event endpoint for lightweight page view tracking (visitor hash from IP+UA+date, no PII stored) - Expand GET /api/stats to return traffic data (views, visitors, referrers) alongside sharing stats - Add analytics JS snippet to web app index.html - Add Plan Analyzer tab to stats dashboard (dashboard.html) - Auto-cleanup page views older than 90 days Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add built-in analytics to PlanShare and stats dashboard
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.
Summary
🤖 Generated with Claude Code