/** * Infrastructure Adapter: InMemoryTeamMembershipRepository * * In-memory implementation of ITeamMembershipRepository. * Stores memberships and join requests in Map structures. */ import type { TeamMembership, TeamJoinRequest, } from '@gridpilot/racing/domain/types/TeamMembership'; import type { ITeamMembershipRepository } from '@gridpilot/racing/domain/repositories/ITeamMembershipRepository'; export class InMemoryTeamMembershipRepository implements ITeamMembershipRepository { private membershipsByTeam: Map; private joinRequestsByTeam: Map; constructor(seedMemberships?: TeamMembership[], seedJoinRequests?: TeamJoinRequest[]) { this.membershipsByTeam = new Map(); this.joinRequestsByTeam = new Map(); if (seedMemberships) { seedMemberships.forEach((membership) => { const list = this.membershipsByTeam.get(membership.teamId) ?? []; list.push(membership); this.membershipsByTeam.set(membership.teamId, list); }); } if (seedJoinRequests) { seedJoinRequests.forEach((request) => { const list = this.joinRequestsByTeam.get(request.teamId) ?? []; list.push(request); this.joinRequestsByTeam.set(request.teamId, list); }); } } private getMembershipList(teamId: string): TeamMembership[] { let list = this.membershipsByTeam.get(teamId); if (!list) { list = []; this.membershipsByTeam.set(teamId, list); } return list; } private getJoinRequestList(teamId: string): TeamJoinRequest[] { let list = this.joinRequestsByTeam.get(teamId); if (!list) { list = []; this.joinRequestsByTeam.set(teamId, list); } return list; } async getMembership(teamId: string, driverId: string): Promise { const list = this.membershipsByTeam.get(teamId); if (!list) return null; return list.find((m) => m.driverId === driverId) ?? null; } async getActiveMembershipForDriver(driverId: string): Promise { for (const list of this.membershipsByTeam.values()) { const membership = list.find( (m) => m.driverId === driverId && m.status === 'active', ); if (membership) { return membership; } } return null; } async getTeamMembers(teamId: string): Promise { return [...(this.membershipsByTeam.get(teamId) ?? [])]; } async countByTeamId(teamId: string): Promise { const list = this.membershipsByTeam.get(teamId) ?? []; return list.filter((m) => m.status === 'active').length; } async saveMembership(membership: TeamMembership): Promise { const list = this.getMembershipList(membership.teamId); const existingIndex = list.findIndex( (m) => m.teamId === membership.teamId && m.driverId === membership.driverId, ); if (existingIndex >= 0) { list[existingIndex] = membership; } else { list.push(membership); } this.membershipsByTeam.set(membership.teamId, list); return membership; } async removeMembership(teamId: string, driverId: string): Promise { const list = this.membershipsByTeam.get(teamId); if (!list) { return; } const index = list.findIndex((m) => m.driverId === driverId); if (index >= 0) { list.splice(index, 1); this.membershipsByTeam.set(teamId, list); } } async getJoinRequests(teamId: string): Promise { return [...(this.joinRequestsByTeam.get(teamId) ?? [])]; } async saveJoinRequest(request: TeamJoinRequest): Promise { const list = this.getJoinRequestList(request.teamId); const existingIndex = list.findIndex((r) => r.id === request.id); if (existingIndex >= 0) { list[existingIndex] = request; } else { list.push(request); } this.joinRequestsByTeam.set(request.teamId, list); return request; } async removeJoinRequest(requestId: string): Promise { for (const [teamId, list] of this.joinRequestsByTeam.entries()) { const index = list.findIndex((r) => r.id === requestId); if (index >= 0) { list.splice(index, 1); this.joinRequestsByTeam.set(teamId, list); return; } } } }