Skip to content

feat: migrate Invoicely to Cloudflare Workers - #86

Merged
legions-developer merged 2 commits into
mainfrom
gurbinder/cloudflare-workers-migration
Oct 3, 2026
Merged

legions-developer merged 2 commits into
mainfrom
gurbinder/cloudflare-workers-migration

Conversation

@legions-developer

@legions-developer legions-developer commented Oct 3, 2026 •

Copy link
Copy Markdown
Owner

Moves the existing Next.js application to Cloudflare Workers using OpenNext, with root-level build, preview, and deploy commands and a hosting guide. The migration keeps Neon, Better Auth, the existing R2 S3 client, and invoice/PDF behavior; production traffic moves only when the custom domain is attached.

  • Pin OpenNext 1.20.8 and Wrangler 4.147.0; update Next.js to the required 15.5.27 patch and require Node 22+.
  • Configure separate production/staging caches, background revalidation, image optimization, and immutable static assets. Remove Vercel Analytics and Vercel-specific Sentry monitor configuration.

Validation was performed on macOS and Ubuntu with Node 22, including 16 runtime checks. The Vercel preview also deployed successfully. Cloudflare Workers Builds handles deployment using the commands in the hosting guide.

Validation completed in an isolated checkout:

  • yarn install --immutable, yarn lint, and yarn build:cloudflare passed, including TypeScript checks.
  • Production and staging Wrangler dry runs passed; uncompressed upload is about 24.3 MiB, below Cloudflare's current 64 MiB limit.
  • 16/16 HTTP checks passed: pages/404s, anonymous session, denied protected APIs, OG PNG generation, 64×64 image transformation, PDF font assets, and immutable JavaScript caching.
  • Browser check saved a 26-item local invoice, restored it after reload, and rendered a two-page PDF preview.

Before production cutover: configure build/runtime secrets and cache buckets, then validate Google OAuth, authenticated Neon/R2 writes, Sentry delivery, and PDF/PNG exports on staging. Export-file verification was limited by the test browser blocking generated blob URL navigation; PDF preview rendering passed. The deployment guide includes these checks and rollback instructions.

@vercel

vercel Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
invoicely-web Ready Ready Preview Oct 3, 2026 12:54pm UTC

Request Review

@coderabbitai

coderabbitai Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a3e6bc4a-b858-4887-9bda-a4ca9e897ca9
📥 Commits

Reviewing files that changed from the base of the PR and between 6bb633f and 8be3d9e.

📒 Files selected for processing (4)
  • apps/web/package.json
  • docs/cloudflare.md
  • package.json
  • turbo.json
💤 Files with no reviewable changes (1)
  • turbo.json

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The web workspace adds Cloudflare Workers configuration and build, preview, and deployment tasks. The README and new deployment guide describe local setup, staging validation, production cutover, and rollback. The root Node.js minimum changes to version 22.

Changes

Cloudflare Workers deployment

Layer / File(s) Summary
Worker and app configuration
apps/web/open-next.config.ts, apps/web/wrangler.jsonc, apps/web/next.config.ts, apps/web/public/_headers, apps/web/tsconfig.json, apps/web/src/app/layout.tsx, apps/web/package.json
The app configures OpenNext and Wrangler for Cloudflare, including cache and queue bindings, staging resources, and static asset caching. It passes the Sentry token, removes Vercel Analytics, and excludes .open-next from TypeScript checks.
Cloudflare build and deployment commands
apps/web/package.json, package.json, turbo.json, apps/web/.dev.vars.example, apps/web/.gitignore
The workspace adds Cloudflare build, preview, and deploy commands, with corresponding Turbo tasks and OpenNext and Wrangler dependencies. The root Node.js minimum changes to 22. The example development variables and ignore rules support local Workers preview setup. The db:generate Turbo task is removed.
Local setup and deployment guide
README.md, docs/cloudflare.md
The README links to the Cloudflare guide and updates the documented Node.js minimum. The guide covers local setup, environment configuration, staging deployment and validation, production cutover, and rollback.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Feature

Merge Risk: ⚪ Minimal · up to 8be3d

The Cloudflare deployment guide retains staging validation and a Vercel rollback path. No actionable risk blocks merging.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 8be3d

The migration has separate staging resources and a manual, reversible production cutover. No specific new security defect is established, but deployed permissions, alternate public endpoints, and authenticated staging behavior remain unverified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The migration places the web application and its selected database and invoice storage behind a new hosting runtime, with additional cache and queue resources. Deployment credentials add Cloudflare control-plane authority, but the maximum account, bucket, or service scope cannot be determined without their effective permissions.

Security Findings and Attack Paths

  • observed — The base build task already declared database, auth, OAuth, R2, and Sentry credentials. The Cloudflare build carries the same credential categories; this is inherited build authority, not evidence by itself of newly exposed secrets or an attacker-readable path.

Trust Boundaries and Controls

  • observed — The documented controls require staging credentials and storage, independent Worker configuration, environment validation, and authenticated staging checks. The guide explicitly says builds and dry runs do not establish that authenticated flows work on Cloudflare; deployed authorization and isolation remain unverified.

Resilience and Maintainability Implications

  • inferred — Retaining the existing origin, auth secret, database, and assets supports routing-based recovery without migrating application state. The rollback instructions address domain routing, not alternate endpoint fencing or cache recovery after partial deployment, so complete failure containment is not established.

Hardening Proposals

  • proposed — Use isolated build workspaces or verify artifact environment provenance before deployment, preventing interleaved local staging and production builds from substituting the shared output.
  • proposed — Before cutover, verify effective build/deployment permissions and every public Worker entrypoint. Extend rollback instructions to fence any alternate endpoint that would otherwise keep a failed production-backed Worker reachable.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 3 files. (4 skipped: 4 … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: migrating Invoicely to Cloudflare Workers.
Description check ✅ Passed The description explains the Cloudflare Workers migration, its configuration, validation, and production cutover requirements.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 3 files. (4 skipped: 4 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Warning

Some tools did not complete. Review the errors below.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

package.json

Oops! Something went wrong! :(

ESLint: 9.30.0

Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './library.js' is not defined by "exports" in /node_modules/@invoicely/eslint-config/package.json
Referenced from: /.eslintrc.js
at exportsNotFound (node:internal/modules/esm/resolve:310:10)
at packageExportsResolve (node:internal/modules/esm/resolve:658:9)
at resolveExports (node:internal/modules/cjs/loader:685:36)
at Module._findPath (node:internal/modules/cjs/loader:752:31)
at Module._resolveFilename (node:internal/modules/cjs/loader:1461:27)
at wrapResolveFilename (node:internal/modules/cjs/loader:1049:27)
at resolveForCJSWithHooks (node:internal/modules/cjs/loader:1094:12)
at require.resolve (node:internal/modules/helpers:171:31)
at Object.resolve (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2447:46)
at ConfigArrayFactory._loadExtendedShareableConfig (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3383:33)
(node:2) ESLintRCWarning: You are using an eslintrc configuration file, which is deprecated and support will be removed in v10.0.0. Please migrate to an eslint.config.js file. See https://eslint.org/docs/latest/use/configure/migration-guide for details. An eslintrc configuration file is used because you have the ESLINT_USE_FLAT_CONFIG environment variable set to false. If you want to use an eslint.config.js file, remove the environment variable. If you want to find the location of the eslintrc configuration file, use the --debug flag.
(Use node --trace-warnings ... to show where the warning was created)


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@legions-developer legions-developer changed the title feat(hosting): migrate Invoicely to Cloudflare Workers feat: migrate Invoicely to Cloudflare Workers Oct 3, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 95b00edb-ffec-409f-85a5-5066d6fca917
📥 Commits

Reviewing files that changed from the base of the PR and between fc14a4a and 6bb633f.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (15)
  • .github/workflows/cloudflare.yml
  • README.md
  • apps/web/.dev.vars.example
  • apps/web/.gitignore
  • apps/web/next.config.ts
  • apps/web/open-next.config.ts
  • apps/web/package.json
  • apps/web/public/_headers
  • apps/web/scripts/cloudflare-smoke.mjs
  • apps/web/src/app/layout.tsx
  • apps/web/tsconfig.json
  • apps/web/wrangler.jsonc
  • docs/cloudflare.md
  • package.json
  • turbo.json
💤 Files with no reviewable changes (1)
  • apps/web/src/app/layout.tsx

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 2 remain after this review.

Comment thread .github/workflows/cloudflare.yml Resolved
@legions-developer
legions-developer merged commit 11369bb into main Oct 3, 2026
1 check passed
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