- Deep dive into existing band invitation implementation - Identified gaps in current system (invite listing, revocation, user search) - Created detailed architecture analysis and design options - Documented comprehensive implementation plan with phases - Includes backend endpoints, frontend components, and testing strategy Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
8.5 KiB
Band Invitation System - Implementation Plan
🎯 Summary
The band invitation system already has a basic implementation but lacks key features for proper invite management. Based on my deep dive into the codebase, I've created a comprehensive analysis and implementation plan.
Status: ✅ Branch created: feature/band-invitation-system
📊 What Exists Today
Backend (API)
- ✅ Token-based invites with 72h expiry
- ✅
POST /bands/{id}/invites- Generate invite - ✅
POST /invites/{token}/accept- Accept invite - ✅
DELETE /bands/{id}/members/{mid}- Remove member
Frontend (Web)
- ✅
/invite/:token- Accept invite page - ✅ Copy-to-clipboard for invite links
- ✅ Basic invite generation UI
Database
- ✅
band_invitestable with proper schema - ✅ Relationships with
bandsandmembers
🔧 What's Missing (Gaps)
Critical (Blocker for Requirements)
| Gap | Impact | Priority |
|---|---|---|
| List pending invites | Admins can't see who they invited | High |
| Revoke pending invites | No way to cancel sent invites | High |
| Search users to invite | Can't find specific members | High |
Important (Nice to Have)
| Gap | Impact | Priority |
|---|---|---|
| Custom expiry times | Can't set longer/shorter expiry | Medium |
| Bulk invites | Invite multiple people at once | Medium |
| Invite details endpoint | Get info without accepting | Low |
🏗️ Implementation Strategy
Phase 1: MVP (1-2 weeks) - CRITICAL FOR REQUIREMENTS
Implement the missing critical features to meet the stated requirements.
Backend Tasks:
- ✅
GET /bands/{band_id}/invites- List pending invites - ✅
DELETE /invites/{invite_id}- Revoke invite - ✅
GET /invites/{token}/info- Get invite details - ✅ Update
BandRepositorywith new methods - ✅ Update
BandServicewith new logic - ✅ Update schemas for new return types
Frontend Tasks:
- ✅ Create
InviteManagementcomponent (list + revoke) - ✅ Update
BandPagewith invite management section - ✅ Update API wrappers (
web/src/api/invites.ts) - ✅ Add TypeScript interfaces for new endpoints
Tests:
- Unit tests for new repo methods
- Integration tests for new endpoints
- Permission tests (only admins can manage invites)
Phase 2: Enhanced UX (1 week)
Improve user experience based on feedback.
Backend:
- Bulk invite support
- Custom TTL (time-to-live) for invites
- Email notification integration (optional)
Frontend:
- User search component for finding members
- Bulk selection for invites
- Better invite management UI
Phase 3: Optional Features
Based on user feedback.
- Email notifications
- Invite analytics
- QR code generation
📋 Detailed Backend Changes
1. New Endpoint: List Invites
# File: api/src/rehearsalhub/routers/bands.py
@router.get("/{band_id}/invites", response_model=BandInviteList)
async def list_invites(
band_id: uuid.UUID,
session: AsyncSession = Depends(get_session),
current_member: Member = Depends(get_current_member),
):
"""List all pending invites for a band (admin only)"""
Returns: 200 OK with list of pending invites
invites: Array of invite objectstotal: Total countpending: Count of pending (not yet used or expired)
2. New Endpoint: Revoke Invite
# File: api/src/rehearsalhub/routers/bands.py
@router.delete("/invites/{invite_id}", status_code=status.HTTP_204_NO_CONTENT)
async def revoke_invite(
invite_id: uuid.UUID,
session: AsyncSession = Depends(get_session),
current_member: Member = Depends(get_current_member),
):
"""Revoke a pending invite (admin only)"""
Returns: 204 No Content on success
Checks: Only band admin can revoke
Validates: Invite must be pending (not used or expired)
3. New Endpoint: Get Invite Info
# File: api/src/rehearsalhub/routers/bands.py
@router.get("/invites/{token}/info", response_model=BandInviteRead)
async def get_invite_info(
token: str,
session: AsyncSession = Depends(get_session),
):
"""Get invite details without accepting"""
Returns: 200 OK with invite info or 404 Not Found
Use case: Show invite details before deciding to accept
4. Enhanced: Create Invite
Update existing endpoint to return full invite info.
🎨 Frontend Changes
New Components
1. InviteManagement.tsx
// Location: web/src/components/InviteManagement.tsx
// Purpose: Display and manage pending invites
interface InviteManagementProps {
bandId: string;
currentMemberId: string;
}
// Features:
// - List pending invites with details
// - Revoke button for each invite
// - Copy invite link
// - Show expiry timer
// - Refresh list
2. UserSearch.tsx
// Location: web/src/components/UserSearch.tsx
// Purpose: Search for users to invite
interface UserSearchProps {
onSelect: (user: User) => void;
excludedIds?: string[];
}
// Features:
// - Search by name/email
// - Show search results
// - Select users to invite
Updated Components
BandPage.tsx
Add two new sections:
- Invite Management Section (above existing "Members" section)
- Create Invite Section (above invite link display)
🧪 Testing Plan
Unit Tests (Backend)
# test_api_invites.py
test_list_invites_admin_only
test_list_invites_pending_only
test_revoke_invite_admin_only
test_revoke_invite_must_be_pending
test_get_invite_info_valid_token
test_get_invite_info_invalid_token
Integration Tests
# test_band_invites.py
test_create_invite_flow
test_accept_invite_flow
test_invite_expiry
test_invite_revocation
test_multiple_invites_same_band
E2E Tests (Frontend)
// inviteManagement.spec.ts
testInviteListLoadsCorrectly
testRevokeInviteButtonWorks
testCopyInviteLinkWorks
testErrorHandlingForExpiredInvite
⚠️ Important Questions
Before proceeding with implementation, I need clarification on:
-
"No link handling needed" requirement
- Does this mean NO email notifications should be implemented?
- Or that we should focus on the token-based system first?
- This affects whether we include email in MVP or Phase 2
-
Expected scale
- How many members per band?
- How many invites per band?
- This affects pagination decisions
-
External invites
- Should admins be able to invite people who aren't registered yet?
- Or only registered users?
-
Invite analytics
- Should we track who invited whom?
- Should we track invite acceptance rates?
🎯 Recommended Next Steps
Option A: Start Implementation (MVP)
If the requirements are clear and we can proceed with a token-based system:
- Implement Phase 1 backend (2-3 days)
- Add tests (2 days)
- Implement frontend (3-4 days)
- Test and review (2 days)
Total: ~1 week for MVP
Option B: Clarify Requirements First
If we need to decide on email notifications and other optional features:
- Discuss with stakeholders
- Finalize MVP scope
- Then proceed with implementation
📝 Files to Create/Modify
Backend (API)
# New/Modified Files:
api/src/rehearsalhub/routers/bands.py # Add 3 new endpoints
api/src/rehearsalhub/repositories/band.py # Add list/revoke methods
api/src/rehearsalhub/services/band.py # Add service methods
api/src/rehearsalhub/schemas/invite.py # Add new schemas
api/tests/integration/test_api_invites.py # New test file
Frontend (Web)
# New Files:
web/src/components/InviteManagement.tsx
web/src/components/UserSearch.tsx
web/src/api/invites.ts
web/src/types/invite.ts
# Modified Files:
web/src/pages/BandPage.tsx
web/src/pages/InvitePage.tsx
💭 My Recommendation
Based on the analysis:
- Proceed with MVP implementation (Phase 1) - it addresses the core requirements
- Start with token-based system (no email) - simpler, fewer dependencies
- Implement proper permissions - only band admins can manage invites
- Add comprehensive tests - ensure reliability
- Get feedback early - test with real users before adding complexity
The current system has a solid foundation. We just need to add the missing management features to make it production-ready.
🚀 Ready to Start?
I'm ready to begin implementation. Please clarify:
- Should we proceed with token-based MVP?
- Any priority changes to the task list?
- Are there additional requirements not captured?
Once confirmed, I can start with Phase 1 backend implementation immediately.