/** * Infrastructure Adapter: InMemoryLeagueMembershipRepository * * In-memory implementation of ILeagueMembershipRepository. * Stores memberships and join requests in maps keyed by league. */ import type { LeagueMembership, JoinRequest, } from '@gridpilot/racing/domain/entities/LeagueMembership'; import type { ILeagueMembershipRepository } from '@gridpilot/racing/domain/repositories/ILeagueMembershipRepository'; export class InMemoryLeagueMembershipRepository implements ILeagueMembershipRepository { private membershipsByLeague: Map; private joinRequestsByLeague: Map; constructor(seedMemberships?: LeagueMembership[], seedJoinRequests?: JoinRequest[]) { this.membershipsByLeague = new Map(); this.joinRequestsByLeague = new Map(); if (seedMemberships) { seedMemberships.forEach((membership) => { const list = this.membershipsByLeague.get(membership.leagueId) ?? []; list.push(membership); this.membershipsByLeague.set(membership.leagueId, list); }); } if (seedJoinRequests) { seedJoinRequests.forEach((request) => { const list = this.joinRequestsByLeague.get(request.leagueId) ?? []; list.push(request); this.joinRequestsByLeague.set(request.leagueId, list); }); } } async getMembership(leagueId: string, driverId: string): Promise { const list = this.membershipsByLeague.get(leagueId); if (!list) return null; return list.find((m) => m.driverId === driverId) ?? null; } async getLeagueMembers(leagueId: string): Promise { return [...(this.membershipsByLeague.get(leagueId) ?? [])]; } async getJoinRequests(leagueId: string): Promise { return [...(this.joinRequestsByLeague.get(leagueId) ?? [])]; } async saveMembership(membership: LeagueMembership): Promise { const list = this.membershipsByLeague.get(membership.leagueId) ?? []; const existingIndex = list.findIndex( (m) => m.leagueId === membership.leagueId && m.driverId === membership.driverId, ); if (existingIndex >= 0) { list[existingIndex] = membership; } else { list.push(membership); } this.membershipsByLeague.set(membership.leagueId, list); return membership; } async removeMembership(leagueId: string, driverId: string): Promise { const list = this.membershipsByLeague.get(leagueId); if (!list) return; const next = list.filter((m) => m.driverId !== driverId); this.membershipsByLeague.set(leagueId, next); } async saveJoinRequest(request: JoinRequest): Promise { const list = this.joinRequestsByLeague.get(request.leagueId) ?? []; const existingIndex = list.findIndex((r) => r.id === request.id); if (existingIndex >= 0) { list[existingIndex] = request; } else { list.push(request); } this.joinRequestsByLeague.set(request.leagueId, list); return request; } async removeJoinRequest(requestId: string): Promise { for (const [leagueId, requests] of this.joinRequestsByLeague.entries()) { const next = requests.filter((r) => r.id !== requestId); if (next.length !== requests.length) { this.joinRequestsByLeague.set(leagueId, next); break; } } } }