'use client'; import type { LeagueMembership as DomainLeagueMembership, MembershipRole, MembershipStatus, } from '@gridpilot/racing/domain/entities/LeagueMembership'; /** * Lightweight league membership model mirroring the domain type but with * a stringified joinedAt for easier UI formatting. */ export interface LeagueMembership extends Omit { joinedAt: string; } const leagueMemberships = new Map(); /** * Initialize league memberships once from the in-memory league membership repository * that is seeded via the static racing seed in the DI container. * * This avoids depending on raw testing-support seed exports and keeps all demo * membership data flowing through the same in-memory repositories used elsewhere. */ (async function initializeLeagueMembershipsFromRepository() { if (leagueMemberships.size > 0) { return; } try { const { getLeagueRepository, getLeagueMembershipRepository } = await import('./di-container'); const leagueRepo = getLeagueRepository(); const membershipRepo = getLeagueMembershipRepository(); const allLeagues = await leagueRepo.findAll(); const byLeague = new Map(); for (const league of allLeagues) { const memberships = await membershipRepo.getLeagueMembers(league.id); const mapped: LeagueMembership[] = memberships.map((membership) => ({ id: membership.id, leagueId: membership.leagueId, driverId: membership.driverId, role: membership.role, status: membership.status, joinedAt: membership.joinedAt instanceof Date ? membership.joinedAt.toISOString() : new Date().toISOString(), })); byLeague.set(league.id, mapped); } for (const [leagueId, list] of byLeague.entries()) { leagueMemberships.set(leagueId, list); } } catch (error) { // In alpha/demo mode we tolerate failures here; callers will see empty memberships. // eslint-disable-next-line no-console console.error('Failed to initialize league memberships from repository', error); } })(); export function getMembership(leagueId: string, driverId: string): LeagueMembership | null { const list = leagueMemberships.get(leagueId); if (!list) return null; return list.find((m) => m.driverId === driverId) ?? null; } export function getLeagueMembers(leagueId: string): LeagueMembership[] { return [...(leagueMemberships.get(leagueId) ?? [])]; } /** * Derive a driver's primary league from in-memory league memberships. * Prefers any active membership and returns the first matching league. */ export function getPrimaryLeagueIdForDriver(driverId: string): string | null { for (const [leagueId, members] of leagueMemberships.entries()) { if (members.some((m) => m.driverId === driverId && m.status === 'active')) { return leagueId; } } return null; } export function isOwnerOrAdmin(leagueId: string, driverId: string): boolean { const membership = getMembership(leagueId, driverId); if (!membership) return false; return membership.role === 'owner' || membership.role === 'admin'; } export type { MembershipRole, MembershipStatus };