[claude] benchmarks-website-v3: web UI (landing + chart pages)#7641
Merged
connortsui20 merged 2 commits intoct/benchmarks-v3from Apr 26, 2026
Merged
[claude] benchmarks-website-v3: web UI (landing + chart pages)#7641connortsui20 merged 2 commits intoct/benchmarks-v3from
connortsui20 merged 2 commits intoct/benchmarks-v3from
Conversation
Implements the alpha web UI for bench.vortex.dev v3 per
benchmarks-website/planning/components/web-ui.md. Replaces the
placeholder html.rs router with two real pages backed by Maud
templates and a vendored Chart.js bundle.
- GET / — landing page; lists every group + chart
link from /api/groups, rendered via maud.
- GET /chart/{slug} — chart page; chart payload fetched
server-side and embedded inline as a JSON
<script id="chart-data"> block, hydrated
by chart-init.js. No round-trip after load.
- GET /static/... — chart.umd.js (vendored, MIT, 4.4.4),
chart-init.js, style.css. Bundled via
include_bytes!.
Slugs are opaque: the handler echoes whatever /api/groups returned
into ChartKey::from_slug without parsing.
api::collect_groups and api::collect_chart are now pub(crate) so the
HTML handlers reuse the same row collectors as the JSON read routes.
Tests (tests/web_ui.rs):
- insta snapshots of / and /chart/{tpch-Q1 slug} after seeding three
envelopes via /api/ingest, exercising multi-series rendering.
- chart_page_round_trips_every_slug: every slug from /api/groups
resolves to a 200 with inline chart data.
- 404 for unknown slug, empty-DB landing page, static asset
content-types.
Stack inherits the server crate's existing pins (axum 0.8, maud 0.27,
duckdb 1.4); insta is added under [dev-dependencies] from the
workspace dep.
Verified locally:
- cargo build -p vortex-bench-server
- cargo test -p vortex-bench-server (10 ingest + 6 web-ui tests)
- cargo +nightly fmt -p vortex-bench-server -- --check
- cargo clippy -p vortex-bench-server --all-targets (clean)
- end-to-end curl smoke test against a running server: ingest two
envelopes with different commit shas, verify /, /chart/{slug},
static assets, and 404 path.
UI was not visually verified in a browser (sandbox has no display);
the rendered HTML and embedded JSON payload are covered by snapshot
tests.
Signed-off-by: Claude <noreply@anthropic.com>
`benchmarks-website/server/static/chart.umd.js` is a verbatim copy of the upstream Chart.js 4.4.4 UMD bundle. Its minified one-letter identifiers (Ba, Ot, ue, …) collide with typos's dictionary; we don't want to lint third-party vendored sources. Signed-off-by: Claude <noreply@anthropic.com>
connortsui20
added a commit
that referenced
this pull request
Apr 26, 2026
## Summary Implements the alpha web UI for `bench.vortex.dev` v3 per [`benchmarks-website/planning/components/web-ui.md`](../tree/claude/vortex-benchmarks-ui-v3-QxRCK/benchmarks-website/planning/components/web-ui.md). Replaces the placeholder `html.rs` router introduced in #7637 with two real pages backed by Maud templates and a vendored Chart.js bundle. - `GET /` — landing page that lists every group + chart link from `/api/groups`, rendered via `maud`. - `GET /chart/{slug}` — single Chart.js line chart. Payload is fetched server-side via the same `api::collect_chart` helper used by `/api/chart/:slug`, then embedded inline as a JSON `<script id="chart-data">` block. No client-side round-trip after page load. - `GET /static/...` — vendored `chart.umd.js` (Chart.js 4.4.4, MIT), `chart-init.js`, and `style.css`. All bundled into the binary via `include_bytes!`. Slugs are treated as opaque per [`02-contracts.md`](../tree/claude/vortex-benchmarks-ui-v3-QxRCK/benchmarks-website/planning/02-contracts.md): the chart handler echoes whatever `/api/groups` returned straight into `ChartKey::from_slug` without parsing or constructing them itself. `api::collect_groups` and `api::collect_chart` are now `pub(crate)` so the HTML handlers reuse the same row collectors that back the JSON read routes — no second SQL implementation. The chart-init script and the embedded JSON payload between them satisfy the "no network round-trip after page load" criterion. Inside the JSON `<script>` block, `</`, `<!--`, and `<script` are escaped via JSON-safe string escapes so that benign payload contents can never break out of the script element. ## Tests `tests/web_ui.rs` (new, 6 tests): - `landing_page_snapshot` — `insta` snapshot of `GET /` after seeding three envelopes with distinct `commit.sha` / `commit.timestamp` values. - `chart_page_snapshot` — `insta` snapshot of the rendered tpch-Q1 chart page; exercises multi-series rendering (`datafusion:vortex-file-compressed` + `duckdb:parquet`) and verifies both the inline `<script id="chart-data">` block and the `/static/chart.umd.js` reference. - `chart_page_round_trips_every_slug` — every slug returned by `/api/groups` resolves to a 200 chart page with inline data. - `unknown_slug_renders_404` — bogus slug → 404 HTML page. - `empty_landing_page_renders` — empty DB → "No data ingested yet." - `static_assets_are_served` — content-type checks for the three `/static/*` files. Pre-existing `tests/ingest.rs` still passes (10 tests). ## Stack inheritance Inherits the version pins set by #7637 in `benchmarks-website/server/Cargo.toml`. The only Cargo change is `insta = { workspace = true }` under `[dev-dependencies]`. ## Verified locally - `cargo build -p vortex-bench-server` - `cargo test -p vortex-bench-server` — 10 ingest + 6 web-ui tests pass. - `cargo +nightly fmt -p vortex-bench-server -- --check` — clean. - `cargo clippy -p vortex-bench-server --all-targets` — clean. - End-to-end smoke test against a running server: `INGEST_BEARER_TOKEN=test` + `cargo run`, POST two envelopes with different commit shas, verified `/`, `/chart/{slug}`, the three `/static/*` routes, and the invalid-slug 404 path with `curl`. ## Test plan - [ ] Reviewer runs `cargo test -p vortex-bench-server` locally. - [ ] Reviewer starts the server (`INGEST_BEARER_TOKEN=test cargo run -p vortex-bench-server`), POSTs `benchmarks-website/server/fixtures/envelope.json`, and visits `http://127.0.0.1:3000/` in a real browser to confirm the chart hydrates (this PR was developed in a headless sandbox so visual verification was not possible here). - [ ] CI green. ## Out of scope (deferred per `web-ui.md` + `deferred.md`) Per-commit page, filter UI, full-screen modal, deep links, LTTB downsampling, lookup-table-driven engine names / colours, chartjs-plugin-zoom, ratio rendering on compression-size charts, and geomean summary cards are explicitly deferred and not touched here. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- _Generated by [Claude Code](https://claude.ai/code/session_01UjgnLq5MCmcpyv6PXC5oLv)_ --------- Signed-off-by: Claude <noreply@anthropic.com> Co-authored-by: Claude <noreply@anthropic.com>
connortsui20
added a commit
that referenced
this pull request
Apr 26, 2026
## Summary Implements the alpha web UI for `bench.vortex.dev` v3 per [`benchmarks-website/planning/components/web-ui.md`](../tree/claude/vortex-benchmarks-ui-v3-QxRCK/benchmarks-website/planning/components/web-ui.md). Replaces the placeholder `html.rs` router introduced in #7637 with two real pages backed by Maud templates and a vendored Chart.js bundle. - `GET /` — landing page that lists every group + chart link from `/api/groups`, rendered via `maud`. - `GET /chart/{slug}` — single Chart.js line chart. Payload is fetched server-side via the same `api::collect_chart` helper used by `/api/chart/:slug`, then embedded inline as a JSON `<script id="chart-data">` block. No client-side round-trip after page load. - `GET /static/...` — vendored `chart.umd.js` (Chart.js 4.4.4, MIT), `chart-init.js`, and `style.css`. All bundled into the binary via `include_bytes!`. Slugs are treated as opaque per [`02-contracts.md`](../tree/claude/vortex-benchmarks-ui-v3-QxRCK/benchmarks-website/planning/02-contracts.md): the chart handler echoes whatever `/api/groups` returned straight into `ChartKey::from_slug` without parsing or constructing them itself. `api::collect_groups` and `api::collect_chart` are now `pub(crate)` so the HTML handlers reuse the same row collectors that back the JSON read routes — no second SQL implementation. The chart-init script and the embedded JSON payload between them satisfy the "no network round-trip after page load" criterion. Inside the JSON `<script>` block, `</`, `<!--`, and `<script` are escaped via JSON-safe string escapes so that benign payload contents can never break out of the script element. ## Tests `tests/web_ui.rs` (new, 6 tests): - `landing_page_snapshot` — `insta` snapshot of `GET /` after seeding three envelopes with distinct `commit.sha` / `commit.timestamp` values. - `chart_page_snapshot` — `insta` snapshot of the rendered tpch-Q1 chart page; exercises multi-series rendering (`datafusion:vortex-file-compressed` + `duckdb:parquet`) and verifies both the inline `<script id="chart-data">` block and the `/static/chart.umd.js` reference. - `chart_page_round_trips_every_slug` — every slug returned by `/api/groups` resolves to a 200 chart page with inline data. - `unknown_slug_renders_404` — bogus slug → 404 HTML page. - `empty_landing_page_renders` — empty DB → "No data ingested yet." - `static_assets_are_served` — content-type checks for the three `/static/*` files. Pre-existing `tests/ingest.rs` still passes (10 tests). ## Stack inheritance Inherits the version pins set by #7637 in `benchmarks-website/server/Cargo.toml`. The only Cargo change is `insta = { workspace = true }` under `[dev-dependencies]`. ## Verified locally - `cargo build -p vortex-bench-server` - `cargo test -p vortex-bench-server` — 10 ingest + 6 web-ui tests pass. - `cargo +nightly fmt -p vortex-bench-server -- --check` — clean. - `cargo clippy -p vortex-bench-server --all-targets` — clean. - End-to-end smoke test against a running server: `INGEST_BEARER_TOKEN=test` + `cargo run`, POST two envelopes with different commit shas, verified `/`, `/chart/{slug}`, the three `/static/*` routes, and the invalid-slug 404 path with `curl`. ## Test plan - [ ] Reviewer runs `cargo test -p vortex-bench-server` locally. - [ ] Reviewer starts the server (`INGEST_BEARER_TOKEN=test cargo run -p vortex-bench-server`), POSTs `benchmarks-website/server/fixtures/envelope.json`, and visits `http://127.0.0.1:3000/` in a real browser to confirm the chart hydrates (this PR was developed in a headless sandbox so visual verification was not possible here). - [ ] CI green. ## Out of scope (deferred per `web-ui.md` + `deferred.md`) Per-commit page, filter UI, full-screen modal, deep links, LTTB downsampling, lookup-table-driven engine names / colours, chartjs-plugin-zoom, ratio rendering on compression-size charts, and geomean summary cards are explicitly deferred and not touched here. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- _Generated by [Claude Code](https://claude.ai/code/session_01UjgnLq5MCmcpyv6PXC5oLv)_ --------- Signed-off-by: Claude <noreply@anthropic.com> Co-authored-by: Claude <noreply@anthropic.com> Signed-off-by: Connor Tsui <connor.tsui20@gmail.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.
Summary
Implements the alpha web UI for
bench.vortex.devv3 perbenchmarks-website/planning/components/web-ui.md.Replaces the placeholder
html.rsrouter introduced in #7637 with tworeal pages backed by Maud templates and a vendored Chart.js bundle.
GET /— landing page that lists every group + chart link from/api/groups, rendered viamaud.GET /chart/{slug}— single Chart.js line chart. Payload is fetchedserver-side via the same
api::collect_charthelper used by/api/chart/:slug, then embedded inline as a JSON<script id="chart-data">block. No client-side round-trip afterpage load.
GET /static/...— vendoredchart.umd.js(Chart.js 4.4.4, MIT),chart-init.js, andstyle.css. All bundled into the binary viainclude_bytes!.Slugs are treated as opaque per
02-contracts.md:the chart handler echoes whatever
/api/groupsreturned straight intoChartKey::from_slugwithout parsing or constructing them itself.api::collect_groupsandapi::collect_chartare nowpub(crate)sothe HTML handlers reuse the same row collectors that back the JSON
read routes — no second SQL implementation.
The chart-init script and the embedded JSON payload between them
satisfy the "no network round-trip after page load" criterion. Inside
the JSON
<script>block,</,<!--, and<scriptare escaped viaJSON-safe string escapes so that benign payload contents can never
break out of the script element.
Tests
tests/web_ui.rs(new, 6 tests):landing_page_snapshot—instasnapshot ofGET /after seedingthree envelopes with distinct
commit.sha/commit.timestampvalues.
chart_page_snapshot—instasnapshot of the rendered tpch-Q1chart page; exercises multi-series rendering
(
datafusion:vortex-file-compressed+duckdb:parquet) and verifiesboth the inline
<script id="chart-data">block and the/static/chart.umd.jsreference.chart_page_round_trips_every_slug— every slug returned by/api/groupsresolves to a 200 chart page with inline data.unknown_slug_renders_404— bogus slug → 404 HTML page.empty_landing_page_renders— empty DB → "No data ingested yet."static_assets_are_served— content-type checks for the three/static/*files.Pre-existing
tests/ingest.rsstill passes (10 tests).Stack inheritance
Inherits the version pins set by #7637 in
benchmarks-website/server/Cargo.toml. The only Cargo change isinsta = { workspace = true }under[dev-dependencies].Verified locally
cargo build -p vortex-bench-servercargo test -p vortex-bench-server— 10 ingest + 6 web-ui testspass.
cargo +nightly fmt -p vortex-bench-server -- --check— clean.cargo clippy -p vortex-bench-server --all-targets— clean.INGEST_BEARER_TOKEN=testcargo run, POST two envelopes with different commit shas,verified
/,/chart/{slug}, the three/static/*routes, and theinvalid-slug 404 path with
curl.Test plan
cargo test -p vortex-bench-serverlocally.INGEST_BEARER_TOKEN=test cargo run -p vortex-bench-server), POSTsbenchmarks-website/server/fixtures/envelope.json,and visits
http://127.0.0.1:3000/in a real browser toconfirm the chart hydrates (this PR was developed in a
headless sandbox so visual verification was not possible
here).
Out of scope (deferred per
web-ui.md+deferred.md)Per-commit page, filter UI, full-screen modal, deep links, LTTB
downsampling, lookup-table-driven engine names / colours,
chartjs-plugin-zoom, ratio rendering on compression-size charts, and
geomean summary cards are explicitly deferred and not touched here.
🤖 Generated with Claude Code
Generated by Claude Code