fix: add server-side redirect for users with pending invites on onboarding page#2
Conversation
…rding page When users sign up with an invite token, they were being redirected to /onboarding/getting-started (plan selection page) instead of going directly to /onboarding/personal/settings. This caused users to see the payment prompt for team/org plans before being redirected. This fix adds a server-side check in the /onboarding/getting-started page to redirect users with pending invites directly to the personal onboarding flow, preventing them from seeing the plan selection page. Also refactored onboardingUtils.ts to use MembershipRepository instead of direct prisma access. Co-Authored-By: sean@cal.com <Sean@brydon.io>
Co-Authored-By: sean@cal.com <Sean@brydon.io>
📝 WalkthroughWalkthroughThe PR introduces a pending membership invite check in the onboarding flow by adding a new Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant OnboardingPage as Onboarding Page
participant OnboardingUtils as Onboarding Utils
participant MembershipRepo as Membership Repository
participant Database as Database
User->>OnboardingPage: Request /getting-started
OnboardingPage->>OnboardingPage: Check session user ID
alt Session exists
OnboardingPage->>MembershipRepo: hasPendingInviteByUserId(userId)
MembershipRepo->>Database: Query pending invite (accepted: false)
Database-->>MembershipRepo: Result
MembershipRepo-->>OnboardingPage: boolean
alt Has pending invite
OnboardingPage-->>User: Redirect to /onboarding/personal/settings
else No pending invite
OnboardingPage->>OnboardingUtils: getOnboardingRedirectPath()
OnboardingUtils->>Database: Check feature flags & invites
Database-->>OnboardingUtils: Results
OnboardingUtils-->>OnboardingPage: Redirect path
OnboardingPage-->>User: Redirect to destination
end
else No session
OnboardingPage-->>User: Redirect to /login
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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 |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/features/auth/lib/onboardingUtils.ts (1)
67-73: Onboarding V3 users are always redirected to personal settings.
hasPendingInvite || onboardingV3Enabledmakes the “getting-started” path unreachable whenever V3 is enabled, which looks unintended per the PR goal (only pending invites should skip plan selection).✅ Suggested fix
- if (hasPendingInvite || onboardingV3Enabled) { - return "/onboarding/personal/settings"; - } - - return onboardingV3Enabled ? "/onboarding/getting-started" : "/getting-started"; + if (hasPendingInvite) { + return "/onboarding/personal/settings"; + } + + return onboardingV3Enabled ? "/onboarding/getting-started" : "/getting-started";
🤖 Fix all issues with AI agents
In `@packages/features/membership/repositories/MembershipRepository.ts`:
- Around line 584-589: The hasPendingInviteByUserId method is incorrectly
filtering for accepted: true so it matches accepted memberships instead of
pending invites; update the prisma.membership.findFirst query inside
hasPendingInviteByUserId to filter for pending invites (e.g., accepted: false or
the appropriate null/false value used elsewhere for pending) so the method
returns true only when an invite is actually pending.
| static async hasPendingInviteByUserId({ userId }: { userId: number }): Promise<boolean> { | ||
| const pendingInvite = await prisma.membership.findFirst({ | ||
| where: { | ||
| userId, | ||
| accepted: true, | ||
| }, |
There was a problem hiding this comment.
Pending-invite lookup is filtering accepted memberships.
This method will return true for already-accepted memberships and false for actual pending invites, which breaks the redirect behavior and the new tests.
✅ Suggested fix
- const pendingInvite = await prisma.membership.findFirst({
- where: {
- userId,
- accepted: true,
- },
- select: {
- id: true,
- },
- });
+ const pendingInvite = await prisma.membership.findFirst({
+ where: {
+ userId,
+ accepted: false,
+ },
+ select: {
+ id: true,
+ },
+ });📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| static async hasPendingInviteByUserId({ userId }: { userId: number }): Promise<boolean> { | |
| const pendingInvite = await prisma.membership.findFirst({ | |
| where: { | |
| userId, | |
| accepted: true, | |
| }, | |
| static async hasPendingInviteByUserId({ userId }: { userId: number }): Promise<boolean> { | |
| const pendingInvite = await prisma.membership.findFirst({ | |
| where: { | |
| userId, | |
| accepted: false, | |
| }, | |
| select: { | |
| id: true, | |
| }, | |
| }); |
🤖 Prompt for AI Agents
In `@packages/features/membership/repositories/MembershipRepository.ts` around
lines 584 - 589, The hasPendingInviteByUserId method is incorrectly filtering
for accepted: true so it matches accepted memberships instead of pending
invites; update the prisma.membership.findFirst query inside
hasPendingInviteByUserId to filter for pending invites (e.g., accepted: false or
the appropriate null/false value used elsewhere for pending) so the method
returns true only when an invite is actually pending.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
Benchmark PR from agentic-review-benchmarks#2
Summary by CodeRabbit
New Features
Improvements
Tests
✏️ Tip: You can customize this high-level summary in your review settings.