Files
gridpilot.gg/packages/racing/infrastructure/repositories/InMemoryTeamMembershipRepository.ts
2025-12-12 01:11:36 +01:00

140 lines
4.2 KiB
TypeScript

/**
* 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<string, TeamMembership[]>;
private joinRequestsByTeam: Map<string, TeamJoinRequest[]>;
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<TeamMembership | null> {
const list = this.membershipsByTeam.get(teamId);
if (!list) return null;
return list.find((m) => m.driverId === driverId) ?? null;
}
async getActiveMembershipForDriver(driverId: string): Promise<TeamMembership | null> {
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<TeamMembership[]> {
return [...(this.membershipsByTeam.get(teamId) ?? [])];
}
async countByTeamId(teamId: string): Promise<number> {
const list = this.membershipsByTeam.get(teamId) ?? [];
return list.filter((m) => m.status === 'active').length;
}
async saveMembership(membership: TeamMembership): Promise<TeamMembership> {
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<void> {
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<TeamJoinRequest[]> {
return [...(this.joinRequestsByTeam.get(teamId) ?? [])];
}
async saveJoinRequest(request: TeamJoinRequest): Promise<TeamJoinRequest> {
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<void> {
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;
}
}
}
}