Skip to content

SSC-38: Cloudflare-native cutover (merged app Worker, no Vercel) - #261

Merged
Gizmotronn merged 24 commits into
mainfrom
ssc-edge-api-staging
Sep 30, 2026
Merged

Gizmotronn merged 24 commits into
mainfrom
ssc-edge-api-staging

Conversation

@Gizmotronn

Copy link
Copy Markdown
Member

Ships the merged static shell + app Worker (with /api/v1 routed in-Worker) to production.

Verified on staging: deploy, signed-in playtest and budget all green from GitHub Actions (run 36759369415). Staging's stale API zone route and Worker are already retired.

After merge: smoke-test production, then delete the two prod /api/v1/* zone routes and the starsailors-api Worker.

🤖 Generated with Claude Code

Gizmotronn and others added 24 commits September 19, 2026 15:59
…in Worker API on Workers Free

Replace OpenNext SSR with a Cloudflare-native build that fits the Free-plan
10 ms CPU budget:

- Pages are a static Next.js export (`yarn cf:build` -> out/) served by
  Workers Static Assets; page hits never invoke the Worker.
- workers/app runs the existing src/app/api route handlers directly with
  next/server, next/cache and @clerk/nextjs/server shims, mounts the SSC-35
  /api/v1 API, proxies /ingest to PostHog, and maps dynamic pages to their
  exported placeholder HTML. Clerk session JWTs (cookie or bearer) are
  verified locally; cookie mutations require an allowed Origin.
- Server actions become /api/actions/[name] with fetch-based client stubs;
  Clerk's internal server actions are stubbed for the export build only.
- Dynamic pages export one placeholder and read params from the URL;
  middleware redirects move to the browser.
- Remove OpenNext, Vercel deploy/cutover workflows and the standalone API
  Worker deploy; staging deploys on push to `staging` again.
- CI builds the export and bundles the Worker on every PR.
- SSC-38: per-response x-ssc-subrequests, measure-budget script and a
  dispatch workflow using wrangler tail for CPU, plus the cutover, rollback
  and smoke-test runbook with local workerd results.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Leu9r82ABhUyGAoFMEd8Y
…n and move notifications and analytics onto Cloudflare Queues

SSC-37: a cron trigger (every 10 min) computes the landing stats, sunspot
leaderboard, community activity and hub top profiles, and publishes them to
Workers KV as one versioned bundle. Public requests read only the snapshot
(0 subrequests) and report fresh/stale/missing through the response body,
headers, /api/public/status and the UI. A failed producer keeps its last good
data and records the error.

SSC-39: push notifications, server-side PostHog events and the daily
discovery-reminder fan-out run from a Cloudflare Queue. Handlers are
idempotent (PostHog uuid, KV receipts, per-day ids, retries only to failed
endpoints) and retry with backoff. Exhausted or invalid jobs are parked in KV
and can be replayed through /api/internal/jobs. Web Push now runs on
WebCrypto (verified against the RFC 8291 vector), and the notification
endpoints that were open now require a session or the operator token.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Leu9r82ABhUyGAoFMEd8Y
Production builds stay unchanged; only the staging deploy sets NEXT_PUBLIC_EDGE_API.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…from the edge Worker

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…the edge Worker

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…rough the edge Worker

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…et propagates

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…en on staging

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…he staging session

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…minted sessions reach the edge Worker

A token naming a foreign origin is still rejected (403); tokens without azp, such as sessions minted from a sign-in ticket, are accepted once issuer and signature verify, matching Clerk's own verifier.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…rker, snapshots and queues with the edge-API staging work

Takes the snapshot-backed community-activity route and regenerates the app Worker routes now that the staging playtest route lives in the API Worker.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…flows and legacy playtest route

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…oys to Cloudflare again

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…deploy and point the playtest at the merged Worker

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ide the 10 ms Free CPU cap and keep the Clerk secret after the playtest

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…d CPU has warm samples

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…orward production

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@Gizmotronn
Gizmotronn merged commit 2e45ba7 into main Sep 30, 2026
6 checks passed

This branch was successfully deployed

1 active deployment
production — 782cf27d Deployed Sep 30, 2026 by Gizmotronn via budget / measure #23
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.

2 participants