Files
Starlight_Lancher_animation_up/apps/telemetry-dashboard/README.md

5.0 KiB

Starlight Telemetry Dashboard

Read-only administration UI for the existing axolotl-telemetry D1 database and axolotl-telemetry-errors R2 bucket. It does not share routes or code with the public telemetry collector.

Local development

Mock authentication is accepted only when NODE_ENV=development and TELEMETRY_ADMIN_MOCK_AUTH=true are both present.

Use the production D1 and R2 resources through Wrangler remote bindings while keeping authentication local to the development server:

$env:TELEMETRY_ADMIN_MOCK_AUTH='true'
$env:TELEMETRY_ADMIN_REMOTE_BINDINGS='true'
pnpm --filter @axolotl/telemetry-dashboard dev

Remote mode is read-only at the application layer: the Admin API issues only SELECT statements and a single registered-object R2 GET. It never exposes Cloudflare credentials to the browser.

For deterministic fixture scenarios, leave TELEMETRY_ADMIN_REMOTE_BINDINGS unset:

$env:TELEMETRY_ADMIN_MOCK_AUTH='true'
$env:TELEMETRY_ADMIN_MOCK_SCENARIO='normal'
pnpm --filter @axolotl/telemetry-dashboard dev

Supported deterministic scenarios are normal, empty, api-error, no-sample, budget-reached, unconfigured-auth, and forbidden. All mock values are synthetic fixtures.

Production deployment (Cloudflare Workers)

The dashboard runs on the axolotl-telemetry-dashboard Worker with the custom domain admin.axlmc.org. It uses the native D1 and R2 bindings declared in wrangler.toml; no data credentials are sent to the browser.

Do not deploy the dashboard until every item below is complete:

  1. Create a GitHub OAuth App controlled by the Axolotl-Launcher organization. Use https://admin.axlmc.org as its homepage and the callback URL shown by Cloudflare Zero Trust, normally https://<team-name>.cloudflareaccess.com/cdn-cgi/access/callback.
  2. Add GitHub as a Cloudflare Zero Trust identity provider using that Client ID and Client Secret. Keep the Client Secret only in GitHub and Cloudflare.
  3. Create a self-hosted Access application for admin.axlmc.org with an 8-hour session duration.
  4. Create one Allow policy with Include -> GitHub Organization -> Axolotl-Launcher. Do not add a bypass policy or a broader include rule.
  5. Keep the Worker custom domain admin.axlmc.org bound to axolotl-telemetry-dashboard. The DNS records for axlmc.org stay proxied through Cloudflare.

Build and deploy from apps/telemetry-dashboard:

pnpm --filter @axolotl/telemetry-dashboard build
pnpm --filter @axolotl/telemetry-dashboard exec wrangler deploy

nuxi build uses Nitro's cloudflare-module preset by default and emits .output/server/index.mjs plus .output/public, exactly what wrangler.toml references.

Automatic deployment

.github/workflows/deploy-telemetry-dashboard.yml deploys on every push to main that touches apps/telemetry-dashboard/**, and can also be triggered manually. It requires one repository secret:

  • CLOUDFLARE_API_TOKEN: an API token with Workers Scripts Edit and Workers Routes Edit permission for the account that owns axolotl-telemetry-dashboard.

Do not add [skip ci] to commits that should reach production: GitHub Actions skips all workflows for such commits, including this deployment.

Cloudflare account usage check

The system page reports account-wide Workers, D1, and R2 usage through the GraphQL Analytics API. Enable it once with two Worker secrets; secrets survive CI deploys because they live on the Worker, not in the repository:

  1. Create an API token at dash.cloudflare.com → My Profile → API Tokens with the Account Analytics: Read permission for the account that owns the telemetry resources.
  2. From apps/telemetry-dashboard, run pnpm exec wrangler secret put CLOUDFLARE_ANALYTICS_TOKEN and paste that token.
  3. Run pnpm exec wrangler secret put CLOUDFLARE_ACCOUNT_ID and paste the 32-character account ID.

The check stays fail-closed: without both values the row reports 尚未配置, and any dataset failure only degrades the row. The token is used server-side for three read-only GraphQL queries per system page load (Workers invocations 24h, D1 rows today, R2 operations 30d) and is never sent to the browser.

Unused Vercel target

An earlier Vercel project (axolotl-telemetry-dashboard) exists, but its admin.axlmc.org domain was never pointed at Vercel and traffic is served by the Cloudflare Worker. The Nitro vercel preset and server/utils/vercel-data-source.ts remain as an offline fallback and are not part of the production path. Do not enable both targets for the same hostname.

Verify an unauthenticated request is intercepted by Cloudflare Access, then verify /api/admin/session reports dataSource: production after authentication.

The server fails closed when Access or the remote data source configuration is absent. A production build ignores the mock provider even if a mock environment variable is present. All Admin API D1 operations are restricted to SELECT/WITH queries, and R2 reads require an object key previously registered in D1.