feat: /protocol UTC volume chart USD axis + Hourly/Daily/Monthly (#668) #1164

Merged
PlasticDigits merged 2 commits from feat/668-protocol-volume-chart into main 2026-08-26 08:19:25 +00:00
PlasticDigits commented 2026-08-26 07:06:44 +00:00 (Migrated from gitlab.com)

Closes #668

Summary

  • /protocol UTC volume chart now has a visible USD value axis, an in-document pointer + keyboard tooltip, and Hourly / Daily / Monthly grain tabs (default Daily). 7d / 30d is no longer the grain selector; trailing Last 24h / 7d / 30d tiles stay as-is (#576).
  • Indexer keeps GET /api/v1/protocol/volume/daily?days=7|30 as the #652 alias and adds grain=hourly|daily|monthly + capped limit. GET reads protocol_hourly_volume / protocol_daily_volume / protocol_monthly_volume only (60s cache). from/to, unknown grain, injection, and over-max limit return 400.
  • Bar count follows plot width (ResizeObserver, ~12px slot) and clamps to hourly 12–168, daily 7–90, monthly 6–24. Client allowlists grain/limit before fetch.

Invariants / docs

P668-1–P668-8 in skills/AGENTS_FRONTEND_PROTOCOL_STATS.md. P652-3/4/5 rewritten so daily prune ≥ 95d, grain selector, and days=7|30 alias stay explicit. Crosslinks: docs/frontend.md, docs/indexer-invariants.md, docs/runbooks/overview-global-stats-brin.md, AGENTS.md, skills/AGENTS_FRONTEND_TRAILING_WINDOW.md. Verify: make verify-issue-668.

Test plan

  • make verify-issue-668 (docs/invariants, allowlist grep, frontend vitest, indexer integration, e2e-smoke)
  • VERIFY_ISSUE_652_SKIP_E2E=1 VERIFY_ISSUE_652_SKIP_RELATED=1 make verify-issue-652 (days=7|30 alias still green)
  • Indexer indexer_protocol_volume integration (allowlist, idle/unpriced, cache, injection → 400)
  • Frontend vitest: grain/axis/tooltip, hide-on-404, XSS as text, width clamp helpers
  • Playwright e2e/protocol-page.spec.ts (5 workers) — grain tabs inside Global stats
  • make verify-issue-550 / 569 / 586 / 576 / 577 / 631 / 653 (not re-run in this MR; expected still green)
  • Manual Chrome: light + dark at 375px and 1280px (axis readable, bar counts differ, no overflow)
  • Coolify indexer migrate for protocol_hourly_volume / protocol_monthly_volume on deploy

Issue AC

  • Visible USD value axis (formatProtocolUsd ticks). Bars remain a UTC time series.
  • Hover and keyboard focus show UTC period + USD (unpriced → em-dash). Not SVG <title>-only.
  • Selector Hourly / Daily / Monthly (not 7d / 30d). Default Daily. Trailing tiles unchanged.
  • Bar count follows plot width and is clamped per grain.
  • GET grain + limit allowlisted; injection / missing / over-max → 400. days=7|30 without grain still #652 daily.
  • GET reads rollup tables only (60s cache). No swap_events SUM. No Llama. Idle "0"; unpriced null.
  • Hourly / monthly rollups refresh in the volume aggregator; GET does not backfill.
  • 404/501 hides chart; Global stats tiles still render. No PriceChart. No nested card-glass.
  • XSS strings in period / volume_usd render as text. Axis / tooltip never Infinity.
  • Skills + invariants + make verify-issue-668. verify-issue-652 still passes.
  • Light + dark; 375px and 1280px visual QA (tests cover RTL + e2e smoke; not a live Chrome pass).
  • Related ladder verify-issue-550 / 569 / 586 / 576 / 577 / 631 / 653 not re-run here.
Closes #668 ## Summary - `/protocol` UTC volume chart now has a visible USD value axis, an in-document pointer + keyboard tooltip, and **Hourly / Daily / Monthly** grain tabs (default Daily). `7d` / `30d` is no longer the grain selector; trailing Last 24h / 7d / 30d tiles stay as-is (#576). - Indexer keeps `GET /api/v1/protocol/volume/daily?days=7|30` as the #652 alias and adds `grain=hourly|daily|monthly` + capped `limit`. GET reads `protocol_hourly_volume` / `protocol_daily_volume` / `protocol_monthly_volume` only (60s cache). `from`/`to`, unknown grain, injection, and over-max limit return **400**. - Bar count follows plot width (`ResizeObserver`, ~12px slot) and clamps to hourly 12–168, daily 7–90, monthly 6–24. Client allowlists grain/limit before fetch. ## Invariants / docs **P668-1–P668-8** in [`skills/AGENTS_FRONTEND_PROTOCOL_STATS.md`](skills/AGENTS_FRONTEND_PROTOCOL_STATS.md). P652-3/4/5 rewritten so daily prune ≥ 95d, grain selector, and `days=7|30` alias stay explicit. Crosslinks: `docs/frontend.md`, `docs/indexer-invariants.md`, `docs/runbooks/overview-global-stats-brin.md`, `AGENTS.md`, [`skills/AGENTS_FRONTEND_TRAILING_WINDOW.md`](skills/AGENTS_FRONTEND_TRAILING_WINDOW.md). Verify: `make verify-issue-668`. ## Test plan - [x] `make verify-issue-668` (docs/invariants, allowlist grep, frontend vitest, indexer integration, e2e-smoke) - [x] `VERIFY_ISSUE_652_SKIP_E2E=1 VERIFY_ISSUE_652_SKIP_RELATED=1 make verify-issue-652` (`days=7|30` alias still green) - [x] Indexer `indexer_protocol_volume` integration (allowlist, idle/unpriced, cache, injection → 400) - [x] Frontend vitest: grain/axis/tooltip, hide-on-404, XSS as text, width clamp helpers - [x] Playwright `e2e/protocol-page.spec.ts` (5 workers) — grain tabs inside Global stats - [ ] `make verify-issue-550` / `569` / `586` / `576` / `577` / `631` / `653` (not re-run in this MR; expected still green) - [ ] Manual Chrome: light + dark at 375px and 1280px (axis readable, bar counts differ, no overflow) - [ ] Coolify indexer migrate for `protocol_hourly_volume` / `protocol_monthly_volume` on deploy ## Issue AC - [x] Visible USD value axis (`formatProtocolUsd` ticks). Bars remain a UTC time series. - [x] Hover and keyboard focus show UTC period + USD (unpriced → em-dash). Not SVG `<title>`-only. - [x] Selector Hourly / Daily / Monthly (not `7d` / `30d`). Default Daily. Trailing tiles unchanged. - [x] Bar count follows plot width and is clamped per grain. - [x] GET grain + limit allowlisted; injection / missing / over-max → 400. `days=7|30` without grain still #652 daily. - [x] GET reads rollup tables only (60s cache). No `swap_events` SUM. No Llama. Idle `"0"`; unpriced `null`. - [x] Hourly / monthly rollups refresh in the volume aggregator; GET does not backfill. - [x] 404/501 hides chart; Global stats tiles still render. No `PriceChart`. No nested `card-glass`. - [x] XSS strings in period / `volume_usd` render as text. Axis / tooltip never `Infinity`. - [x] Skills + invariants + `make verify-issue-668`. `verify-issue-652` still passes. - [ ] Light + dark; 375px and 1280px visual QA (tests cover RTL + e2e smoke; not a live Chrome pass). - [ ] Related ladder `verify-issue-550` / `569` / `586` / `576` / `577` / `631` / `653` not re-run here.
PlasticDigits commented 2026-08-26 07:07:09 +00:00 (Migrated from gitlab.com)

mentioned in issue #668

mentioned in issue #668
PlasticDigits commented 2026-08-26 08:19:07 +00:00 (Migrated from gitlab.com)

mentioned in commit c9cf7106b6

mentioned in commit c9cf7106b63dd27f2531fa01c9a29dc46f7c47f0
PlasticDigits commented 2026-08-26 08:19:08 +00:00 (Migrated from gitlab.com)

added 24 commits

  • 26586862...72071a10 - 23 commits from branch main
  • c9cf7106 - Merge origin/main into branch for !1164

Compare with previous version

added 24 commits <ul><li>26586862...72071a10 - 23 commits from branch <code>main</code></li><li>c9cf7106 - Merge origin/main into branch for !1164</li></ul> [Compare with previous version](/PlasticDigits/cl8y-dex-terraclassic/-/merge_requests/446/diffs?diff_id=1984446717&start_sha=26586862203cd595bbd5e6515288cf0fb13f8a77)
PlasticDigits commented 2026-08-26 08:19:25 +00:00 (Migrated from gitlab.com)

mentioned in commit eb0238d68e

mentioned in commit eb0238d68e756ab3b3cfeee332adb8902572a6ab
PlasticDigits (Migrated from gitlab.com) merged commit eb0238d68e into main 2026-08-26 08:19:25 +00:00
PlasticDigits commented 2026-08-26 09:31:37 +00:00 (Migrated from gitlab.com)

mentioned in issue #673

mentioned in issue #673
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
code/cl8y-dex-terraclassic!1164
No description provided.