Repository navigation
Dashboard redesign: React + shadcn/ui, live charts, history API, DLQ inspector - #10
Merged
Merged
Conversation
…HF + zod Full rewrite of the embedded dashboard from the minimal Svelte page to a proper product UI, still compiled into the binary PocketBase-style (ui/dist committed, go:embed, zero deployment): - App shell: slim sidebar navigation (Overview, Tables, Backfill, Dead letters with a live count badge), brand mark, streaming status with uptime in the footer, sticky page header with LSN and readiness badges, dark/light theme toggle (system default, no flash on load). - shadcn/ui component system (zinc theme, new-york style): button, badge, card, input, label, table, dialog, form, and sonner toasts, with Radix primitives underneath. - TanStack Table v9 (the new tree-shakable useTable/tableFeatures API) powers every table — sinks, table activity, backfill status, and the dead-letter queue — with click-to-sort headers and global filtering. - react-hook-form + zod drive the backfill trigger dialog (validated schema.table identifier or empty for all); zod also validates every API response so a Go/UI contract drift fails loudly instead of rendering NaNs. - TanStack Query polls /api/stats and /dlq every 2s with mutations and cache invalidation for retry/discard/retry-all/backfill actions, each confirmed by a toast; retry-all sits behind a confirm dialog that explains the stale-state caveat. - Overview: stat cards with a live emerald throughput sparkline (client-computed from counter deltas), WAL lag, in-flight, DLQ depth; per-sink delivery table with health dots and breaker badges. Tables page adds share-of-traffic bars; every page has a designed empty state. - Toolchain: Vite 7 + TypeScript strict + Tailwind v4; the CI dashboard job (npm ci && npm run build) now type-checks the UI too via tsc -b. Docs updated (README, CLAUDE.md, CONTRIBUTING.md, embed.go). Verified by driving all four pages in headless Chromium against a mock API (light + dark) with zero console errors. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019dEj24Ta2o9QxzW9ZrSPtb
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019dEj24Ta2o9QxzW9ZrSPtb
…cher stats The dashboard now tells the full pipeline story with real visualizations: Backend: - New /api/history endpoint backed by a server-side sampler: a ring buffer of throughput/WAL-lag/in-flight/DLQ samples (5s interval, 30min window) collected from the process's own metrics, so charts have data the moment the page opens and survive reloads. Started/stopped with the HTTP server. - /api/stats grew: build version, slot and publication names, a global operation mix (INSERT/UPDATE/DELETE/READ/TRUNCATE totals), per-sink error breakdown by type (timeout/circuit_open/other), and DLQ parked/retried all-time counters. Frontend: - recharts: throughput area chart (events/s derived from history deltas) and a replication-lag chart with an explanation of what sustained growth means, both themed for light/dark via a MutationObserver on the root class. - nivo: operation-mix donut with center total on the overview, and horizontal stacked bars of the busiest tables by operation on the Tables page, with a shared operation color legend. - New Instance panel: version, streaming/ready badges, uptime, LSN, slot, publication, tables observed, DLQ state. Dead-letters stat card now shows all-time parked/retried; sink failure counts carry an error-type breakdown on hover. - zod schemas extended for the new fields (with tolerant defaults so older gateways still render); vendor chunk splitting (react/charts/ data) keeps initial parse reasonable. Verified by driving every page in headless Chromium against a mock API in both themes with zero console errors; Go suite passes with -race. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019dEj24Ta2o9QxzW9ZrSPtb
…idebar - DLQ page gains an event inspector dialog showing the parked (already-transformed) payload plus sink/table/LSN/attempt metadata, so poison events can be diagnosed without redis-cli. - The shell shows a "Cannot reach GTC" banner when /api/stats polling fails, instead of silently freezing stale numbers. - Sidebar collapses to an icon rail below lg breakpoints (DLQ count becomes a red dot), and the document title follows the active page. - Remove the dead sparkline component and hook left over from the recharts migration; drop the empty manual "react" chunk from the Vite build. - Extend server tests: instance info + operations map + errors_by_type in /api/stats, /api/history sample shape, and the sampler ring-buffer cap. - README: add a dashboard screenshot (docs/dashboard.png). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019dEj24Ta2o9QxzW9ZrSPtb
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.
What does this PR do?
Rebuilds the embedded dashboard from scratch and enriches the server APIs that feed it.
UI rewrite (React 19 + TypeScript + Vite + Tailwind v4 + shadcn/ui):
Server-side:
/api/historyendpoint backed by a 5-second sampler with a 30-minute ring buffer, so charts have real data the moment the dashboard opens and survive page reloads./api/statsnow reports version/slot/publication, an aggregated per-operation counts map, per-sinkerrors_by_type, and DLQ parked/retried totals.--versionflag and version stamping via goreleaser ldflags.The built
ui/distis committed and embedded per the existing PocketBase-style setup, sogo buildstill needs no Node.Type of change
Checklist
go test ./...passes (including-race)gofmt/go vetare clean/api/statsnew fields,/api/historyshape, sampler ring-buffer cap)README.md/CLAUDE.mdupdated if env vars or behavior changed (dashboard section, screenshot atdocs/dashboard.png, UI build instructions)Notes for the reviewer
docs/dashboard.pngin the README is one of those captures.🤖 Generated with Claude Code
https://claude.ai/code/session_019dEj24Ta2o9QxzW9ZrSPtb
Generated by Claude Code