Repository navigation
Add Kit-backed waiting list to invite-gated signup - #728
Conversation
Replace the default /signup view with a first-name + email waiting list that upserts Kit subscribers and tags them waitlist::kody. Invite signup stays available behind an "I have a code" control.
Hold the form element across the await so reset() cannot throw and overwrite the success state with a false network error.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughChangesKit waiting-list signup
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant SignupUI
participant WaitingListAction
participant RateLimitD1
participant KitAPI
SignupUI->>WaitingListAction: POST /waiting-list
WaitingListAction->>RateLimitD1: Check client-IP limit
WaitingListAction->>KitAPI: Look up, create, or tag subscriber
KitAPI-->>WaitingListAction: Return subscriber result
WaitingListAction-->>SignupUI: Return signup result
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 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 |
|
🔎 Preview deployed: https://kody-pr-728.kody-a99.workers.dev Worker: Mocks:
|
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
.github/workflows/deploy.yml (1)
128-139: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winMake the production Kit secret contract consistent.
The production workflow permits
KIT_API_KEYto be absent, while the PR objective says production requires it; the setup manifest repeats the optional wording. Either make the sync mandatory and document that requirement, or explicitly define deployments without the secret as supported but unavailable.
.github/workflows/deploy.yml#L128-L139: replace--set-from-env-optional KIT_API_KEYwith mandatory synchronization if production must require the secret.docs/contributing/setup-manifest.md#L149-L153: document the secret as required for production and optional only for non-production environments.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/deploy.yml around lines 128 - 139, Make the production KIT_API_KEY contract mandatory: update the deployment command in .github/workflows/deploy.yml lines 128-139 to use required synchronization for KIT_API_KEY, and update docs/contributing/setup-manifest.md lines 149-153 to state that the secret is required in production but optional for non-production environments..github/workflows/preview.yml (1)
267-285: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy liftDo not send preview signups to the production Kit audience.
Every preview receives the repository
KIT_API_KEY, so/waiting-listcalls the live Kit API. Manual or E2E preview submissions can therefore create persistent production subscribers. Use an isolated preview key/audience, or leave the key unset and mock Kit in previews.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/preview.yml around lines 267 - 285, Update the preview workflow’s worker secret synchronization around KIT_API_KEY so previews cannot use the repository production Kit credentials. Configure an isolated preview Kit key/audience, or omit KIT_API_KEY and enable the existing preview/mock behavior, ensuring /waiting-list submissions never reach the production Kit API.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/worker/src/app/kit-waitlist.ts`:
- Around line 74-106: Add a deadline-driven AbortSignal to
subscribeToKitWaitlist and pass it to both Kit fetchImpl calls so slow requests
are cancelled. Detect timeout/abort failures and map them to the existing 502
response path, while preserving current handling for non-timeout Kit errors and
successful subscriber tagging.
- Around line 74-80: Update the waitlist submission flow around the
createResponse request to check whether the email already has a Kit subscriber
before creating it; avoid sending first_name or skip the create call for
existing subscribers so their CRM name is preserved. Add a regression test
covering an existing subscriber and confirming their name is not overwritten.
- Around line 83-114: Preserve Kit response status in subscribeToKitWaitlist()
by throwing a typed error that distinguishes 4xx client failures from 5xx
responses and network errors. In waiting-list.ts lines 30-33 and 157-159, update
the handler to refund the rate-limit slot only for network or transient 5xx
failures, never for Kit 4xx responses; add a regression test covering a 422
response and confirming the slot is not refunded.
---
Outside diff comments:
In @.github/workflows/deploy.yml:
- Around line 128-139: Make the production KIT_API_KEY contract mandatory:
update the deployment command in .github/workflows/deploy.yml lines 128-139 to
use required synchronization for KIT_API_KEY, and update
docs/contributing/setup-manifest.md lines 149-153 to state that the secret is
required in production but optional for non-production environments.
In @.github/workflows/preview.yml:
- Around line 267-285: Update the preview workflow’s worker secret
synchronization around KIT_API_KEY so previews cannot use the repository
production Kit credentials. Configure an isolated preview Kit key/audience, or
omit KIT_API_KEY and enable the existing preview/mock behavior, ensuring
/waiting-list submissions never reach the production Kit API.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 49c45b3f-3356-421c-9ed7-8849a88a8a79
📒 Files selected for processing (18)
.github/workflows/deploy.yml.github/workflows/preview.ymldocs/contributing/architecture/authentication.mddocs/contributing/architecture/primitives.yamldocs/contributing/environment-variables.mddocs/contributing/project-intent.mddocs/contributing/setup-manifest.mde2e/invite-signup-verification.spec.tse2e/waiting-list-signup.spec.tspackages/worker/.env.examplepackages/worker/client/routes/login.tsxpackages/worker/src/app/handlers/waiting-list.node.test.tspackages/worker/src/app/handlers/waiting-list.tspackages/worker/src/app/kit-waitlist.node.test.tspackages/worker/src/app/kit-waitlist.tspackages/worker/src/app/router.tspackages/worker/src/app/routes.tspackages/worker/src/env-schema.ts
Look up existing subscribers before create so public joins cannot overwrite CRM names, bound Kit fetches with a timeout, refund rate-limit slots only for transient failures, and keep preview deploys off the production Kit audience.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 3 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 6ecf26b. Configure here.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/worker/src/app/kit-waitlist.ts (1)
122-226: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider adding tests for timeout and server-error classification paths.
Current tests cover new subscriber creation, existing subscriber (no overwrite), and client 4xx classification. Missing: timeout/network failure (
kitFetchabort path →kind: 'network') and server 5xx classification (kind: 'server'). Adding these would round out coverage for the error paths that drive rate-limit refund behavior.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/worker/src/app/kit-waitlist.ts` around lines 122 - 226, The tests for subscribeToKitWaitlist should cover both error-classification paths mentioned: add a timeout/network-failure case exercising kitFetch’s abort path and asserting kind: 'network', and add a 5xx response case asserting kind: 'server'. Keep the existing creation, existing-subscriber, and 4xx classification tests unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/worker/src/app/kit-waitlist.ts`:
- Around line 122-226: The tests for subscribeToKitWaitlist should cover both
error-classification paths mentioned: add a timeout/network-failure case
exercising kitFetch’s abort path and asserting kind: 'network', and add a 5xx
response case asserting kind: 'server'. Keep the existing creation,
existing-subscriber, and 4xx classification tests unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 8f32f32c-c127-4413-8e00-9ab1651c0504
📒 Files selected for processing (8)
.github/workflows/preview.ymldocs/contributing/architecture/authentication.mddocs/contributing/environment-variables.mddocs/contributing/setup-manifest.mdpackages/worker/src/app/handlers/waiting-list.node.test.tspackages/worker/src/app/handlers/waiting-list.tspackages/worker/src/app/kit-waitlist.node.test.tspackages/worker/src/app/kit-waitlist.ts
✅ Files skipped from review due to trivial changes (4)
- docs/contributing/environment-variables.md
- docs/contributing/setup-manifest.md
- .github/workflows/preview.yml
- docs/contributing/architecture/authentication.md
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/worker/src/app/handlers/waiting-list.node.test.ts
- packages/worker/src/app/handlers/waiting-list.ts
Keep invite codes optional client-side for non-production open signup, prefill from ?code/?invite, and sync the invite panel when signup search params change.

Summary
Public
/signupnow defaults to a waiting-list form (first name + email). Submissions go toPOST /waiting-list, which looks up/creates a Kit subscriber and tags themwaitlist::kodywithout overwriting existing CRM names. An I have a code control reveals the existing invite signup form (?code/?invite/?panel=invitealso open it directly).Kit forms cannot be created via API; Kent’s existing waitlists use the
waitlist::…tag convention, so tagging is the integration surface. Tagwaitlist::kody(id21081721) was created in Kit for this.Production secret
Please add GitHub Actions secret
KIT_API_KEY(same value as KodykitApiKey). Production deploy syncs it when set; without it, waiting-list joins return 503 while the rest of the app still deploys. Preview deploys intentionally omit the key so preview/E2E joins do not write to the production Kit audience.System recap — extends existing primitives (medium risk)
Mode: recap · Base:
main@300ae007· Head: latest oncursor/waiting-list-signup-e777Classification: extends — signup onboarding now includes a public Kit-backed waiting list while invite-gated account creation remains available.
Primitives touched
app-sessions/signupwaiting list +POST /waiting-listKit tag join; invite signup unchanged behind revealapp-uid1-app-dbSystem map
Signup waiting-list joins flow from the Remix signup UI through a new auth handler into Kit; invite signup still uses the existing auth/invite path.
Legend: green = composes (wiring only) · amber = extended by this PR · red = new primitive · gray = context (unchanged, included only when an edge crosses it).
Change flow
Before / after
/signupwaitlist::kodyviaKIT_API_KEYInvariants
Per-user isolation unchanged — waiting-list joins are anonymous marketing contacts in Kit, not Kody user accounts.
Summary by CodeRabbit
/signupfor visitors without an invite code, including first name + email submission with validation and Kit-based joining./signupexperience, and enforces per-IP rate limiting with clear success/error messaging.KIT_API_KEY,KIT_WAITLIST_TAG_ID) and production vs preview behavior.