Rebuild cors.sh on Cloudflare Workers (standalone SaaS)#171
Conversation
Delete the legacy AWS Lambda + API Gateway services, archived apps, and examples. The Cloudflare rebuild in the following commits replaces them.
Node 22 + wrangler; shadcn (Mira) UI components in @workspace/ui; new @workspace/emails package (react-email + Resend, dry-run aware) for transactional mail.
Origin-pinned KV auth (key public, Origin is the authenticator), CORS rewrite, streaming + byte metering, monthly quota, test_-key rate cap via a Durable Object, and a keyless anonymous tier (IP rate-limited) for legacy cors.sh/<url> callers. Pings the control plane for quota-notification emails.
…e billing, email Next 16 via @opennextjs/cloudflare with D1+KV bindings. Folds the control plane into /api/v1/* route handlers (account=user). Auth.js (NextAuth v5) email magic-link via Resend; gated console + login. Standalone Stripe billing (Checkout/Portal/webhook) drives users.tier and re-projects KV keys. Quota-notification rollup endpoint. D1 migrations 0001-0005.
Self-contained Playwright stack (web+proxy+mock+page); CORS correctness, auth gating, dashboard loop, proxy enforcement, full Stripe subscription lifecycle (signed webhook events) + opt-in live-checkout test. CI (build+e2e) and a manual deploy workflow. SPEC.md as the source of truth; DEVELOPMENT.md; GRAVEYARD.md.
Replace Prettier with oxfmt (the Oxc formatter): add .oxfmtrc.json, point format/format:check at oxfmt, drop the now-unused prettier devDep (eslint-config-prettier stays — it only disables stylistic ESLint rules). Ran a full format pass across the repo — mechanical, no logic changes; build is green and `oxfmt --check` is clean.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedToo many files! This PR contains 452 files, which is 302 over the limit of 150. To get a review, narrow the scope: Upgrade to a paid plan to raise the limit. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (34)
📒 Files selected for processing (452)
You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
The docs-cors-sh / cors Vercel projects were legacy integrations auto-deploying this repo; both disconnected (we deploy to Cloudflare). Empty commit to refresh PR checks off the stale docs-cors-sh status.
New 'checks' job runs oxfmt --check, eslint, and tsc --noEmit in parallel with build/e2e. Standardize check-types scripts across web/ui/emails to match the existing turbo task (was a no-op). Drop deprecated baseUrl from web/ui tsconfigs (TS6 TS5101) so tsc --noEmit passes — paths are already relative. Add the missing eslint devDep to @workspace/ui so its lint script actually runs.
AGENTS.md: concise agent/contributor guide — two-plane architecture, stack invariants (Node 22, Cloudflare-only, oxfmt, secrets runtime-only), commands, pre-commit gates, and gotchas; points to SPEC.md / DEVELOPMENT.md / GRAVEYARD.md as sources of truth. CLAUDE.md is a symlink to it. README: replace stale submodule clone instructions (no submodules) with real dev steps + doc links.
Summary
Reboots cors.sh from the frozen AWS Lambda + API Gateway stack onto Cloudflare Workers, as a standalone SaaS with its own accounts and billing. It's live in production — the full sign up → use → hit quota → pay → cancel loop is verified end-to-end against real Stripe.
The first commit removes the legacy AWS stack; the rest build the new service.
What's in it
Proxy data plane (
workers/proxy)Originheader is the real authenticatortest_key rate-cap via a Durable Objectcors.sh/<url>callers keep workingControl plane folded into the Next app (
web/, Next 16 via@opennextjs/cloudflare)/api/v1/*route handlers with D1 + KV bindings; account = userKeyRecordis the single contract between the planes — one builder, reused by project CRUD and billing re-projectionAuth — Auth.js v5 email magic-link via Resend; gated console +
/loginBilling — standalone Stripe (Checkout + Customer Portal + webhook). A subscription change flips
users.tierand re-projects the user's KV keys, so the proxy immediately enforces the new quota. Idempotent webhook ledger + dunning.Email —
@workspace/emails(react-email + Resend): magic-link, welcome, subscription lifecycle, dunning, quota warnings. Dry-run aware.Tooling — pnpm + turbo monorepo, shadcn UI, oxfmt formatter, Node 22.
Tests & CI
workflow_dispatchdeploys (D1 migrate → proxy → web).Status
Live on
cors.sh(app) +proxy.cors.sh(data plane). Verified with a real $4 purchase and cancellation: charge → checkout → webhook →tier:pro→ KV re-projection → proxy enforces; then cancel → refund →tier:free→ KV back to the free quota.Remaining work is hardening, not features — see
SPEC.md §8: observability/alerting, async metering off the hot-path D1 read, a restricted Stripe key, ToS/privacy, Billing Portal config, and cleanup.Notes
.dev.vars); none are committed.SPEC.mdis the source of truth for behavior;DEVELOPMENT.mdfor local setup;GRAVEYARD.mdrecords what was removed.