/** * In-memory league membership data for alpha prototype */ export type MembershipRole = 'owner' | 'admin' | 'steward' | 'member'; export type MembershipStatus = 'active' | 'pending' | 'none'; export interface LeagueMembership { leagueId: string; driverId: string; role: MembershipRole; status: MembershipStatus; joinedAt: Date; } export interface JoinRequest { id: string; leagueId: string; driverId: string; requestedAt: Date; message?: string; } // In-memory storage let memberships: LeagueMembership[] = []; let joinRequests: JoinRequest[] = []; // Current driver ID (matches the one in di-container) const CURRENT_DRIVER_ID = 'driver-1'; // Initialize with seed data export function initializeMembershipData() { memberships = [ { leagueId: 'league-1', driverId: CURRENT_DRIVER_ID, role: 'owner', status: 'active', joinedAt: new Date('2024-01-15'), }, { leagueId: 'league-1', driverId: 'driver-2', role: 'member', status: 'active', joinedAt: new Date('2024-02-01'), }, { leagueId: 'league-1', driverId: 'driver-3', role: 'admin', status: 'active', joinedAt: new Date('2024-02-15'), }, ]; joinRequests = []; } // Get membership for a driver in a league export function getMembership(leagueId: string, driverId: string): LeagueMembership | null { return memberships.find(m => m.leagueId === leagueId && m.driverId === driverId) || null; } // Get all members for a league export function getLeagueMembers(leagueId: string): LeagueMembership[] { return memberships.filter(m => m.leagueId === leagueId && m.status === 'active'); } // Get pending join requests for a league export function getJoinRequests(leagueId: string): JoinRequest[] { return joinRequests.filter(r => r.leagueId === leagueId); } // Join a league export function joinLeague(leagueId: string, driverId: string): void { const existing = getMembership(leagueId, driverId); if (existing) { throw new Error('Already a member or have a pending request'); } memberships.push({ leagueId, driverId, role: 'member', status: 'active', joinedAt: new Date(), }); } // Request to join a league (for invite-only leagues) export function requestToJoin(leagueId: string, driverId: string, message?: string): void { const existing = getMembership(leagueId, driverId); if (existing) { throw new Error('Already a member or have a pending request'); } const existingRequest = joinRequests.find(r => r.leagueId === leagueId && r.driverId === driverId); if (existingRequest) { throw new Error('Join request already pending'); } joinRequests.push({ id: `request-${Date.now()}`, leagueId, driverId, requestedAt: new Date(), message, }); } // Leave a league export function leaveLeague(leagueId: string, driverId: string): void { const membership = getMembership(leagueId, driverId); if (!membership) { throw new Error('Not a member of this league'); } if (membership.role === 'owner') { throw new Error('League owner cannot leave. Transfer ownership first.'); } memberships = memberships.filter(m => !(m.leagueId === leagueId && m.driverId === driverId)); } // Approve join request export function approveJoinRequest(requestId: string): void { const request = joinRequests.find(r => r.id === requestId); if (!request) { throw new Error('Join request not found'); } memberships.push({ leagueId: request.leagueId, driverId: request.driverId, role: 'member', status: 'active', joinedAt: new Date(), }); joinRequests = joinRequests.filter(r => r.id !== requestId); } // Reject join request export function rejectJoinRequest(requestId: string): void { joinRequests = joinRequests.filter(r => r.id !== requestId); } // Remove member (admin action) export function removeMember(leagueId: string, driverId: string, removedBy: string): void { const removerMembership = getMembership(leagueId, removedBy); if (!removerMembership || (removerMembership.role !== 'owner' && removerMembership.role !== 'admin')) { throw new Error('Only owners and admins can remove members'); } const targetMembership = getMembership(leagueId, driverId); if (!targetMembership) { throw new Error('Member not found'); } if (targetMembership.role === 'owner') { throw new Error('Cannot remove league owner'); } memberships = memberships.filter(m => !(m.leagueId === leagueId && m.driverId === driverId)); } // Update member role export function updateMemberRole( leagueId: string, driverId: string, newRole: MembershipRole, updatedBy: string ): void { const updaterMembership = getMembership(leagueId, updatedBy); if (!updaterMembership || updaterMembership.role !== 'owner') { throw new Error('Only league owner can change roles'); } const targetMembership = getMembership(leagueId, driverId); if (!targetMembership) { throw new Error('Member not found'); } if (newRole === 'owner') { throw new Error('Use transfer ownership to change owner'); } memberships = memberships.map(m => m.leagueId === leagueId && m.driverId === driverId ? { ...m, role: newRole } : m ); } // Check if driver is owner or admin export function isOwnerOrAdmin(leagueId: string, driverId: string): boolean { const membership = getMembership(leagueId, driverId); return membership?.role === 'owner' || membership?.role === 'admin'; } // Get current driver ID export function getCurrentDriverId(): string { return CURRENT_DRIVER_ID; } // Initialize on module load initializeMembershipData();