Skip to content

Add Phase 5 Svelte dashboard on Cloudflare Pages - #4

Merged
tbjers merged 11 commits into
mainfrom
feat/phase-5-dashboard
Jun 24, 2026
Merged

Add Phase 5 Svelte dashboard on Cloudflare Pages#4
tbjers merged 11 commits into
mainfrom
feat/phase-5-dashboard

Conversation

@tbjers

@tbjers tbjers commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Summary

  • SvelteKit 5 app in dashboard/ using @sveltejs/adapter-cloudflare for Cloudflare Pages deployment
  • All API calls are server-side (+page.server.ts load functions) — the Cf-Access-Jwt-Assertion header from the user's Access session is forwarded to the Worker API and never touches browser JS
  • uPlot sparklines on the overview cards (last 20 coverage data points per repo)
  • Full uPlot trend charts on the drill-in page (/[owner]/[repo]) with metric selector (coverage / complexity / duplication) and branch input
  • Clean build, no warnings; typecheck passes

Deployment

Cloudflare Pages build settings:

Setting Value
Root directory dashboard
Build command npm run build
Build output .svelte-kit/cloudflare
Environment variable WORKER_URL=https://coverage-tracker.yourdomain.com

Create a Cloudflare Access application protecting the Pages hostname (same identity provider and policy as the existing Worker Access app).

Test plan

  • cd dashboard && npm run typecheck — must pass clean
  • cd dashboard && npm run build — must complete without errors or warnings
  • Copy .env.example.env, set WORKER_URL, run npm run dev — verify project cards appear with sparklines and latest coverage %
  • Click a project card — verify drill-in page loads with trend chart
  • Switch metric tabs (coverage / complexity / duplication) — chart updates
  • Type a branch name and submit — chart reloads for that branch
  • Deploy to Cloudflare Pages, verify Access gate works end-to-end

🤖 Generated with Claude Code

tbjers and others added 10 commits June 24, 2026 15:03
SvelteKit 5 app in dashboard/ with SSR load functions that forward the
Cf-Access-Jwt-Assertion header server-side so the token never reaches
browser JS. uPlot sparklines on the overview cards, full trend charts
on the drill-in page with metric selector and branch input.

Cloudflare Pages build settings: root=dashboard, output=.svelte-kit/cloudflare.
Configure WORKER_URL env var in Pages dashboard before deploying.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- api.ts: add redirect:'manual' to all Worker fetch calls so that
  Cloudflare Access login redirects (302) surface as HTTP errors
  instead of silently returning HTML that breaks JSON.parse
- Add dashboard/wrangler.toml so the adapter-cloudflare dev server
  stops walking up to the root wrangler.jsonc (which was injecting
  the Worker's WORKER_URL env var into the dashboard process)
- Update .gitignore to cover .dev.vars; update .env.example to
  document both Vite (.env) and wrangler (.dev.vars) dev patterns

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Worker:
- src/types.ts: add optional DEV_BYPASS_SECRET to Bindings
- src/middleware/access.ts: if DEV_BYPASS_SECRET is set and the request
  carries a matching X-Dev-Bypass header, skip JWT verification; the
  guard is dead code in production where the env var is never set
- .dev.vars.example: document DEV_BYPASS_SECRET with a warning

Dashboard:
- api.ts: add optional extraHeaders param to fetchProjects/fetchTrend
- +page.server.ts (both routes): read DEV_BYPASS_SECRET from env and
  pass X-Dev-Bypass when set; no-op in production
- .env.example: document both WORKER_URL and DEV_BYPASS_SECRET

Docs:
- docs/plans/service-auth-token.md: future refactor to replace bypass +
  JWT forwarding with Cloudflare Access Service Tokens

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- test/seed-local.sql: inserts a test owner, project, and 15+4 metric
  data points for local development against wrangler d1 --local
- package.json: add db:seed:local script (npx wrangler d1 execute)
- docs/PROGRESS.md: update Phase 5 from "Not started" to "Implemented –
  pending Pages deployment", listing what's done vs. still outstanding

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- .github/workflows/deploy-dashboard.yml: builds and deploys the
  dashboard on push to main (production) and on PRs (preview branch),
  path-filtered to dashboard/** so unrelated changes don't trigger it
- dashboard/package.json: add wrangler ^4.104.0 as devDependency so
  the workflow resolves it from node_modules after npm ci

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Covers: Pages project creation, WORKER_URL secret, GitHub Actions
secrets, Access application, and the "run from dashboard/ dir" note
to avoid the wrangler pages_build_output_dir warning.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…issue

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The root .gitignore blanket-ignores wrangler.jsonc to protect the
Worker's secrets. Add !dashboard/wrangler.jsonc to allow the Pages
config to be committed. This suppresses the spurious "missing
pages_build_output_dir" warning on wrangler pages commands (wrangler
finds the .jsonc before walking up to the root wrangler.jsonc).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
SvelteKit uses node:async_hooks internally; without nodejs_compat the
Pages worker throws at runtime.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@sveltejs/adapter-cloudflare@4.x declares a peer dep on wrangler@^3;
having wrangler@^4 in devDependencies caused an ERESOLVE conflict on
npm ci. Remove it from package.json and install wrangler@^4 globally
as a dedicated CI step before the deploy, keeping peer deps clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@tbjers
tbjers merged commit 33d8f93 into main Jun 24, 2026
4 of 5 checks passed
@tbjers
tbjers deleted the feat/phase-5-dashboard branch June 24, 2026 22:31
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