feat(dashboard): operational dashboard with reporting views and alerts - #5
Merged
Merged
Conversation
The reporting surface for Assessment 3. /api/stats and /api/count were built in Assessment 2 and had no consumer; this gives the measurements somewhere to be read. Structure: - lib/dashboard.ts collects everything in one pass, shared by the API route and the page. The alternative — the browser calling /api/health, /api/count and /api/stats and stitching them together — is three round trips that must agree with each other, which is three chances to render a panel that contradicts the panel beside it. - The page renders the first snapshot on the server, so the view arrives populated rather than empty-then-filled, and there is no loading state to design. The client component then polls every ten seconds. - The only effect subscribes to a timer. Changing the reporting window fetches from the click handler, because it is a user action, not a render concern. Views: health strip, rule-based alerts, operational totals, requests per feed, a feed status table, requests per endpoint and per client, response codes, stored content, and recent activity. Alerts have two levels rather than one. A warning says something is drifting; a critical says someone has to act. A single threshold only ever tells you once it is already too late. Two problems found by looking at the running page rather than by reasoning about it: - The dashboard polls /api/dashboard every ten seconds, and those polls were being logged. Within a minute it was the busiest endpoint on the server, pushing real traffic out of the recent-activity list and inflating the totals it was itself displaying. Monitoring endpoints are now excluded from the request log, the same treatment /api/metrics already had. - The page did not scroll. This shell keeps the header and footer fixed and scrolls the view body, so content needs the view-body scroll-area wrapper that every other long page uses. Verified in the browser at both light and dark themes, and against the API: after the fix, twelve generated requests report as exactly twelve. Co-Authored-By: Claude <noreply@anthropic.com>
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.
The Assessment 3 reporting surface —
/dashboard.Panels: health strip · rule-based alerts · operational totals (requests, unique clients, feed polls, items served, latency, error rate) · requests per feed · feed status table · requests per endpoint · requests per client · response codes · stored content · recent activity. Window selector (15m/1h/24h/7d) and a live/paused toggle.
Design notes
lib/dashboard.tscollects everything in one pass, shared by the route handler and the page — one point in time, so no two panels can disagree.useEffectsubscribes to a timer; the window switch fetches from the click handler where it belongs.Two bugs caught by actually opening the page
/api/dashboardwas the busiest endpoint and was inflating its own totals. Monitoring paths are now excluded from the request log.Verified in-browser (both themes) and via API: 12 generated requests report as exactly 12, with 2 distinct clients.
🤖 Generated with Claude Code