refactor: wire rooms/join invite path through shared invite utilities#143
Merged
Merged
Conversation
Replaces the stale inline invite validation in /api/rooms/join with validateInviteCode and incrementInviteUseCount from lib/groups/invite, so max_uses checks and use_count tracking are enforced consistently across both join endpoints. Also removes unused GenerateInviteOptions and InviteRecord interfaces from the invite utility. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Group Join via Invite Code API
Allows users to join groups using a unique invite code, with support for time-based and usage-based expiry.
New endpoints
POST /api/groups/:id/invite — Generate an invite code for a group
// Request body (all optional)
{ "expires_in": 86400, "max_uses": 10 }
// 201 Response
{
"success": true,
"invite": {
"code": "550e8400-e29b-41d4-a716-446655440000",
"group_id": "room_...",
"created_at": "...",
"expires_at": "...",
"max_uses": 10
}
}
POST /api/groups/join — Join a group via invite code
// Request body
{ "code": "550e8400-e29b-41d4-a716-446655440000" }
// 200 Response
{
"success": true,
"group": { "id": "room_...", "name": "..." },
"membership": { "user_id": "...", "group_id": "...", "joined_at": "..." }
}
What's included
UUID v4 invite codes generated server-side via Node's crypto module
Optional expires_in (seconds) for time-based expiry
Optional max_uses for usage-based expiry — enforced atomically via a PostgreSQL RPC to avoid race conditions
Shared validation utility (lib/groups/invite.ts) used by both /api/groups/join and /api/rooms/join — expiry and usage limits are enforced consistently regardless of which endpoint a client calls
Auth-gated on both ends; invite generation restricted to group creators and existing members
Clear error responses: 400 bad input, 401 unauthenticated, 403 not a member, 404 code not found, 410 expired or usage limit reached
Structured logging on every join attempt (success and failure)
DB migration
scripts/011_enhance_invites_for_group_join.sql — apply after existing migrations:
psql "$DATABASE_URL" -f scripts/011_enhance_invites_for_group_join.sql
Adds max_uses and use_count columns to public.invites, RLS policies for authenticated read/update, and the increment_invite_use_count SQL function.
closes #111