Skip to content

Add a local gameplay analytics dashboard - #52

Merged
darrinm merged 1 commit into
mainfrom
analytics-dashboard
Sep 14, 2026
Merged

darrinm merged 1 commit into
mainfrom
analytics-dashboard

Conversation

@darrinm

@darrinm darrinm commented Sep 14, 2026

Copy link
Copy Markdown
Owner

Cloudflare's Dashboards section cannot chart gameplay analytics. Its dataset list offers Cloudflare's own telemetry: D1 Analytics, D1 Queries and D1 Storage report rows read, query latency and storage size for astrapool-analytics, and Workers Analytics Engine groups only by dataset name. None of them read rows out of the games table, so they cannot break racks down by mode, difficulty or room.

This adds a dashboard that runs the queries itself.

npm run analytics:dashboard                 # opens http://localhost:8788
npm run analytics:dashboard -- --port 9000 --local --no-open

One page holds the summary tiles, a daily starts chart split into finished, ended early and unfinished, game modes, winners, and all eight settings breakdowns, with buttons for the range (24 hours, 7, 30, 90 days) and the game mode. It serves the same report() output as npm run analytics, so the two always agree.

It listens on 127.0.0.1 only, and each refresh runs the fixed report queries through Wrangler's existing login. No analytics credential is published, stored in the browser, or added to the game, and the public Worker is unchanged.

tools/d1.mjs holds the Wrangler-backed database adapter the CLI already had, so both reports share one code path.

wrangler --json reports API failures as a JSON object on stdout, which neither caller read. A failed report printed Node's Command failed message with the full SQL attached, and said nothing about the cause. Both now print the API's own text, and when the failure is an authorization error while CF_API_TOKEN or CLOUDFLARE_API_TOKEN is set, they name the variable and the command to run without it:

A request to the Cloudflare API (...) failed. The given account is not valid or is not
authorized to access this service [code: 7403] Wrangler is using the API token in
CF_API_TOKEN. Give that token Account / D1 / Read, or run without it:
env -u CF_API_TOKEN npm run analytics:dashboard

Validation: 351 unit tests pass, including eight new ones covering the routes, filter validation, the report shape, query failures and that error message. Production build passes. Checked against the live astrapool-analytics database: the dashboard and npm run analytics -- --mode computer both report 26 started, 21 finished, 80.8% completed. Every table and the chart were checked for clipping and overflow at 360, 480, 800 and 1180 px.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PsSAuUXmXhyA173qE3Y3Fq

`npm run analytics:dashboard` serves the existing report as a page on
127.0.0.1:8788 and opens it: summary tiles, a daily starts chart split into
finished, ended early and unfinished, game modes, winners, and every settings
breakdown, with range and mode buttons. Each refresh runs the same fixed
queries as `npm run analytics` through Wrangler's own login, so no analytics
credential is published, stored in the browser, or added to the game.

Cloudflare's Dashboards section cannot chart this data. Its D1 datasets report
rows read, query latency and storage size, and its Workers Analytics Engine
dataset groups only by dataset name, so none of them can break gameplay down by
mode, difficulty or room.

Extract the Wrangler-backed database adapter the CLI already used into
tools/d1.mjs so both reports share one code path. `wrangler --json` reports API
failures as a JSON object on stdout, which neither caller read, so a failed
report printed Node's "Command failed" message with the full SQL attached.
Parse that envelope, and when the failure is an authorization error while
CF_API_TOKEN or CLOUDFLARE_API_TOKEN is set, name the variable and the command
to run without it.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01PsSAuUXmXhyA173qE3Y3Fq
@darrinm
darrinm merged commit 0b8991a into main Sep 14, 2026
1 check passed
@darrinm
darrinm deleted the analytics-dashboard branch September 14, 2026 15:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant