Problem
Group invite links validate and display correctly, but accepting an invite never actually adds the user to the group. The use_invite_token(token, user_id) RPC — the only thing that inserts a group_members row — is never called anywhere in the app.
Trace
- Someone clicks a group invite link → lands at
/?invite=<token> → RootContent (src/routes/__root.tsx) validates the token via useInviteValidation and renders InviteLandingPage ("You're Invited! Join Group").
- They sign up through
AuthDialog (magic link or OTP). useSignInWithOtpMutation (src/api/auth/useSignInWithOtpMutation.ts) stashes the invite token in user_metadata.invite_token and in the magic-link redirect URL (?invite=<token>), but that's all it does with it.
InviteLandingPage's onSignupSuccess prop is wired to a no-op — onSignupSuccess={() => {}} in src/routes/__root.tsx:108.
useInviteValidation.ts exposes an acceptInvite(userId) function that wraps useInviteMutation() (which calls the use_invite_token RPC) — but nothing in the codebase calls acceptInvite. Confirmed via full-repo search: only __root.tsx calls useInviteValidation(), and it destructures just { inviteValidation, isValidating, hasValidInvite }.
- There's no database trigger that consumes
invite_token from auth.users metadata either (checked supabase/migrations/*create_functions.sql — use_invite_token is designed to be called explicitly from the client, it's SECURITY DEFINER but not trigger-attached).
Net effect: a user can go through the entire "you're invited → sign up" flow and never end up in group_members. The invite is validated but never redeemed.
Fix
Wire onSignupSuccess (and the equivalent path for an existing user who clicks an invite link while logged out then logs in) to actually call acceptInvite(user.id) once a session exists, and surface success/failure (toast, redirect into the group, etc.). Needs to handle both:
- A brand-new user completing OTP verification inside
AuthDialog.
- The magic-link click landing back on
/?invite=<token> with a fresh session (no callback fires here — this needs an effect keyed on user + inviteToken becoming available).
Acceptance criteria
Context
Found while reviewing PR #267 (mutateAsync → mutate migration), which touched useInviteValidation.ts's acceptInvite (formerly useInvite) without being aware it had no caller.
Problem
Group invite links validate and display correctly, but accepting an invite never actually adds the user to the group. The
use_invite_token(token, user_id)RPC — the only thing that inserts agroup_membersrow — is never called anywhere in the app.Trace
/?invite=<token>→RootContent(src/routes/__root.tsx) validates the token viauseInviteValidationand rendersInviteLandingPage("You're Invited! Join Group").AuthDialog(magic link or OTP).useSignInWithOtpMutation(src/api/auth/useSignInWithOtpMutation.ts) stashes the invite token inuser_metadata.invite_tokenand in the magic-link redirect URL (?invite=<token>), but that's all it does with it.InviteLandingPage'sonSignupSuccessprop is wired to a no-op —onSignupSuccess={() => {}}insrc/routes/__root.tsx:108.useInviteValidation.tsexposes anacceptInvite(userId)function that wrapsuseInviteMutation()(which calls theuse_invite_tokenRPC) — but nothing in the codebase callsacceptInvite. Confirmed via full-repo search: only__root.tsxcallsuseInviteValidation(), and it destructures just{ inviteValidation, isValidating, hasValidInvite }.invite_tokenfromauth.usersmetadata either (checkedsupabase/migrations/*create_functions.sql—use_invite_tokenis designed to be called explicitly from the client, it'sSECURITY DEFINERbut not trigger-attached).Net effect: a user can go through the entire "you're invited → sign up" flow and never end up in
group_members. The invite is validated but never redeemed.Fix
Wire
onSignupSuccess(and the equivalent path for an existing user who clicks an invite link while logged out then logs in) to actually callacceptInvite(user.id)once a session exists, and surface success/failure (toast, redirect into the group, etc.). Needs to handle both:AuthDialog./?invite=<token>with a fresh session (no callback fires here — this needs an effect keyed onuser+inviteTokenbecoming available).Acceptance criteria
group_membersrow for that group after completing signup (magic link and OTP paths both work).use_invite_token, just needs to surface cleanly).InviteLandingPage"Invalid Invite" / expired / deactivated states are unaffected.Context
Found while reviewing PR #267 (
mutateAsync→mutatemigration), which toucheduseInviteValidation.ts'sacceptInvite(formerlyuseInvite) without being aware it had no caller.