Skip to content

fix(api): RL_PUBLIC binding + safety-net boundaries + dep upgrades#16

Merged
nathanialhenniges merged 4 commits intomainfrom
claude/epic-villani
Apr 15, 2026
Merged

fix(api): RL_PUBLIC binding + safety-net boundaries + dep upgrades#16
nathanialhenniges merged 4 commits intomainfrom
claude/epic-villani

Conversation

@nathanialhenniges
Copy link
Copy Markdown
Member

Summary

Three bundled commits on claude/epic-villani, plus a merge of latest main.

1. fix(api): bind RL_PUBLIC rate limiter to server worker (6fe4452)

POST /trpc/public.trackView and trackClick were 500'ing with
Cannot read properties of undefined (reading 'limit').

Root cause: the Hono cloudflareRateLimiter middleware mounted on
those two routes reads c.env.RL_PUBLIC and immediately calls
.limit() on it — but RL_PUBLIC was never declared in
packages/infra/alchemy.run.ts. Only rlAuth, rlStrict, and
rlUpload existed. The wrangler.jsonc file had RL_PUBLIC (ns 1004)
but Alchemy is the dev-time source of truth, so the binding was
silently missing in dev and prod.

Fix: declare rlPublic (ns 1004, 60 req / 60 s — matching the
wrangler.jsonc spec) and add it to the server worker's bindings
map. The Bindings type in apps/server/src/index.ts already
declared RL_PUBLIC: RateLimit, so no other code change was needed.

2. chore(web): add error/loading/not-found boundaries + align package pins (8213d43)

Safety-net pass on apps/web for Next.js 16 / React 19 conventions:

  • apps/web/src/app/error.tsx — root error boundary (client) with reset button
  • apps/web/src/app/not-found.tsx — branded 404 (server component)
  • apps/web/src/app/loading.tsx — root streaming UI matching the existing spinner pattern
  • apps/web/src/app/admin/error.tsx — admin-scoped error boundary keeping admin chrome visible
  • apps/web/src/app/admin/loading.tsx — skeleton for the 12-parallel-tRPC-query dashboard

Pin alignment (zero-risk, no version bumps):

  • next 16.1.6 -> 16.2.0 (apps/docs aligned with apps/web)
  • typescript ^5 -> ^5.9.3 (web, server, api, auth, db, ui, email, env, infra, validators)
  • @types/node ^25 -> ^25.5.0 (apps/web aligned with rest)

3. chore(deps): patch + minor upgrades across workspaces (a8b2e3d)

56 dependency bumps inside existing major versions. Highlights:

  • @trpc/* 11.12.0 -> 11.16.0
  • better-auth 1.5.5 -> 1.6.3
  • @tanstack/react-query 5.90.21 -> 5.99.0
  • @tanstack/react-form 1.28.5 -> 1.29.0
  • wrangler 4.72.0 -> 4.83.0
  • @cloudflare/workers-types 4.20260403.1 -> 4.20260415.1
  • @opennextjs/cloudflare 1.17.1 -> 1.19.1
  • @base-ui/react 1.3.0 -> 1.4.0
  • react / react-dom 19.2.4 -> 19.2.5
  • hono 4.12.7 -> 4.12.14
  • drizzle-orm 0.45.1 -> 0.45.2
  • dotenv 17.3.1 -> 17.4.2
  • shadcn 4.0.5 -> 4.2.0
  • recharts 3.8.0 -> 3.8.1
  • plus 40+ patch/minor bumps

Skipped (out of scope this round): typescript 5.9.3 -> 6.0.2, alchemy 0.89 -> 0.91, jsdom 28 -> 29 (all major / pre-1.0 minor).

@linkden/ui peerDependencies tightened: react / react-dom ^19.0.0 -> ^19.2.5 to match the rest of the monorepo.

4. Merge origin/main

Pulled d322087 fix: Add Social Network modal with URL validation (#13) into the branch. The only conflict was bun.lock, resolved by re-running bun install against the merged package.jsons.

Surfaced for follow-up (out of scope here)

  • Next.js 16.2 deprecation: the middleware.ts file convention is deprecated in favor of proxy.ts. apps/web/src/middleware.ts will need to be renamed/migrated separately.
  • Admin layout RSC refactor: apps/web/src/app/admin/layout.tsx is currently "use client", dragging the entire admin tree to the client. Deferred.
  • Server Actions migration: all admin forms still use React Query mutations. Deferred.
  • 'use cache' for the public page: Next 16 cache directive not yet exploited on app/page.tsx. Deferred.

Test plan

  • bun install — clean (390 packages installed)
  • bun run check-types — green (server, docs)
  • bunx tsc --noEmit (apps/web) — green
  • bun run build — green (web, docs, server) with placeholder env vars
  • Manual: restart bun dev so Alchemy registers the new RL_PUBLIC binding
  • Manual: open /, confirm POST /trpc/public.trackView?batch=1 returns 200 (was 500)
  • Manual: click any block, confirm POST /trpc/public.trackClick?batch=1 returns 200
  • Manual: spam trackView ~70× in a minute, confirm 429 on overflow (proves the rate limiter is wired and active)
  • Manual: trip an error in dev to confirm error.tsx renders (no white screen)
  • Manual: hit /totally-bogus to confirm not-found.tsx renders
  • Manual: sign into /admin/login and load /admin — confirm the new loading.tsx skeleton flashes briefly and all 12 tRPC queries return 200
  • Manual: load /admin/builder and confirm the dashboard works
  • Deploy: bun run deploy — left for the maintainer to run after review

🤖 Generated with Claude Code

nathanialhenniges and others added 4 commits April 15, 2026 04:49
trackView and trackClick mutations 500'd with `Cannot read properties
of undefined (reading 'limit')`. The Hono cloudflareRateLimiter
middleware on /trpc/public.trackView* and /trpc/public.trackClick*
reads c.env.RL_PUBLIC and immediately calls .limit() on it, but
RL_PUBLIC was never declared in alchemy.run.ts and never bound to the
server worker.

apps/server/wrangler.jsonc lists RL_PUBLIC (ns 1004) but Alchemy is
the dev-time source of truth -- the wrangler.jsonc drift is what made
the binding look wired on paper. Other public routes work because
they have no rate limiter (getPage) or use a binding that does exist
(submitContact -> RL_AUTH).

Fix: declare rlPublic alongside rlAuth/rlStrict/rlUpload (matching
the wrangler.jsonc namespace 1004 + 60 req/60s) and add it to the
server worker's bindings map. apps/server/src/index.ts already
declares RL_PUBLIC: RateLimit in its Bindings type, so no code-side
change is needed.

Restart bun dev after pulling so Alchemy registers the new binding.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Safety-net pass on apps/web for Next.js 16 / React 19 conventions:

  apps/web/src/app/error.tsx       Root error boundary (client). Catches
                                   uncaught errors anywhere under /, shows
                                   reset button + error digest.
  apps/web/src/app/not-found.tsx   Branded 404 page (server component).
  apps/web/src/app/loading.tsx     Streaming UI for the root layout's async
                                   fetchSettings() — matches the existing
                                   spinner pattern in app/page.tsx.
  apps/web/src/app/admin/error.tsx Admin-scoped error boundary (client).
                                   Keeps admin chrome visible.
  apps/web/src/app/admin/loading.tsx Skeleton matching the admin dashboard
                                   layout. Softens the wait while the 12
                                   parallel tRPC queries on /admin resolve.

Pin alignment (zero-risk, no version bumps):

  next             16.1.6  -> 16.2.0       (apps/docs aligns with apps/web)
  typescript       ^5      -> ^5.9.3       (web, server, api, auth, db, ui,
                                            email, env, infra, validators)
  @types/node      ^25     -> ^25.5.0      (apps/web aligns with rest)

bun.lock regenerated. apps/docs/next-env.d.ts regenerated by `next typegen`.

Verification:
  bun run check-types   green (server, docs)
  bunx tsc --noEmit     green (apps/web)

Out of scope this round (deferred): admin layout RSC refactor, Server
Actions migration, Next 16 'use cache' for the public page.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
56 dependency bumps inside existing major versions. No major bumps
this round (typescript 5.9.3->6.0.2, alchemy 0.89->0.91, jsdom 28->29
deferred — pre-1.0 alchemy minor counts as breaking).

Notable bumps:

  next:                   16.2.0  (already current)
  react / react-dom:      19.2.4  -> 19.2.5    (patch)
  @trpc/* (client/server/tanstack-react-query):
                          11.12.0 -> 11.16.0   (minor)
  better-auth:            1.5.5   -> 1.6.3     (minor)
  hono:                   4.12.7  -> 4.12.14   (patch)
  drizzle-orm:            0.45.1  -> 0.45.2    (patch)
  drizzle-kit:            0.31.9  -> 0.31.10   (patch)
  wrangler:               4.72.0  -> 4.83.0    (minor)
  @cloudflare/workers-types:
                          4.20260403.1 -> 4.20260415.1 (minor)
  @tanstack/react-query:  5.90.21 -> 5.99.0    (minor)
  @tanstack/react-form:   1.28.5  -> 1.29.0    (minor)
  @opennextjs/cloudflare: 1.17.1  -> 1.19.1    (minor)
  @base-ui/react:         1.3.0   -> 1.4.0     (minor)
  @headlessui/react:      2.2.9   -> 2.2.10    (patch)
  recharts:               3.8.0   -> 3.8.1     (patch)
  shadcn:                 4.0.5   -> 4.2.0     (minor)
  @react-email/components:1.0.9   -> 1.0.12    (patch)
  @react-email/render:    2.0.4   -> 2.0.6     (patch)
  postcss:                8.5.8   -> 8.5.9     (patch)
  dotenv:                 17.3.1  -> 17.4.2    (patch)
  turbo:                  2.9.3   -> 2.9.6     (patch)
  vitest:                 4.1.2   -> 4.1.4     (patch)
  tsdown:                 0.21.2  -> 0.21.8    (patch)
  @t3-oss/env-nextjs:     0.13.10 -> 0.13.11   (patch)
  @types/node:            25.5.0  -> 25.6.0    (minor)

@linkden/ui peerDependencies tightened: react / react-dom ^19.0.0 ->
^19.2.5 to match the rest of the monorepo.

Verification:
  bun install            green (390 packages installed clean)
  bun run check-types    green (server, docs)
  bunx tsc --noEmit      green (apps/web)
  bun run build          green (web, docs, server) with placeholder env

Surfaced for follow-up (out of scope this round):
  Next.js 16.2 deprecates the `middleware.ts` file convention in
  favor of `proxy.ts` — `apps/web/src/middleware.ts` will need to be
  renamed/migrated separately.

apps/web/next-env.d.ts regenerated by `next build`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 15, 2026

Warning

Rate limit exceeded

@nathanialhenniges has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 50 minutes and 32 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 50 minutes and 32 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6e2c297d-96e4-45e0-9778-cb3085ec34ad

📥 Commits

Reviewing files that changed from the base of the PR and between d3b5684 and 5be1683.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (20)
  • apps/docs/next-env.d.ts
  • apps/docs/package.json
  • apps/server/package.json
  • apps/web/next-env.d.ts
  • apps/web/package.json
  • apps/web/src/app/admin/error.tsx
  • apps/web/src/app/admin/loading.tsx
  • apps/web/src/app/error.tsx
  • apps/web/src/app/loading.tsx
  • apps/web/src/app/not-found.tsx
  • package.json
  • packages/api/package.json
  • packages/auth/package.json
  • packages/db/package.json
  • packages/email/package.json
  • packages/env/package.json
  • packages/infra/alchemy.run.ts
  • packages/infra/package.json
  • packages/ui/package.json
  • packages/validators/package.json
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/epic-villani

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 and usage tips.

@nathanialhenniges nathanialhenniges merged commit e06cb03 into main Apr 15, 2026
3 checks 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