233 lines
9.4 KiB
TypeScript
233 lines
9.4 KiB
TypeScript
/**
|
|
* Infrastructure Adapter: InMemoryTeamMembershipRepository
|
|
*
|
|
* In-memory implementation of ITeamMembershipRepository.
|
|
* Stores memberships and join requests in Map structures.
|
|
*/
|
|
|
|
import type {
|
|
TeamMembership,
|
|
TeamJoinRequest,
|
|
} from '@core/racing/domain/types/TeamMembership';
|
|
import type { ITeamMembershipRepository } from '@core/racing/domain/repositories/ITeamMembershipRepository';
|
|
import type { Logger } from '@core/shared/logging/Logger';
|
|
|
|
export class InMemoryTeamMembershipRepository implements ITeamMembershipRepository {
|
|
private membershipsByTeam: Map<string, TeamMembership[]>;
|
|
private joinRequestsByTeam: Map<string, TeamJoinRequest[]>;
|
|
private readonly logger: Logger;
|
|
|
|
constructor(logger: Logger, seedMemberships?: TeamMembership[], seedJoinRequests?: TeamJoinRequest[]) {
|
|
this.logger = logger;
|
|
this.logger.info('InMemoryTeamMembershipRepository initialized.');
|
|
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);
|
|
this.logger.debug(`Seeded membership for team ${membership.teamId}, driver ${membership.driverId}.`);
|
|
});
|
|
}
|
|
|
|
if (seedJoinRequests) {
|
|
seedJoinRequests.forEach((request) => {
|
|
const list = this.joinRequestsByTeam.get(request.teamId) ?? [];
|
|
list.push(request);
|
|
this.joinRequestsByTeam.set(request.teamId, list);
|
|
this.logger.debug(`Seeded join request for team ${request.teamId}, driver ${request.driverId}.`);
|
|
});
|
|
}
|
|
}
|
|
|
|
private getMembershipList(teamId: string): TeamMembership[] {
|
|
let list = this.membershipsByTeam.get(teamId);
|
|
if (!list) {
|
|
list = [];
|
|
this.membershipsByTeam.set(teamId, list);
|
|
this.logger.debug(`Created new membership list for team: ${teamId}`);
|
|
}
|
|
return list;
|
|
}
|
|
|
|
private getJoinRequestList(teamId: string): TeamJoinRequest[] {
|
|
let list = this.joinRequestsByTeam.get(teamId);
|
|
if (!list) {
|
|
list = [];
|
|
this.joinRequestsByTeam.set(teamId, list);
|
|
this.logger.debug(`Created new join request list for team: ${teamId}`);
|
|
}
|
|
return list;
|
|
}
|
|
|
|
async getMembership(teamId: string, driverId: string): Promise<TeamMembership | null> {
|
|
this.logger.debug(`[getMembership] Entry - teamId: ${teamId}, driverId: ${driverId}`);
|
|
try {
|
|
const list = this.membershipsByTeam.get(teamId);
|
|
if (!list) {
|
|
this.logger.warn(`[getMembership] No membership list found for team: ${teamId}. Returning null.`);
|
|
return null;
|
|
}
|
|
const membership = list.find((m) => m.driverId === driverId) ?? null;
|
|
if (membership) {
|
|
this.logger.info(`[getMembership] Success - found membership for team: ${teamId}, driver: ${driverId}.`);
|
|
} else {
|
|
this.logger.info(`[getMembership] Not found - membership for team: ${teamId}, driver: ${driverId}.`);
|
|
}
|
|
return membership;
|
|
} catch (error) {
|
|
this.logger.error(`[getMembership] Error getting membership for team ${teamId}, driver ${driverId}:`, error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async getActiveMembershipForDriver(driverId: string): Promise<TeamMembership | null> {
|
|
this.logger.debug(`[getActiveMembershipForDriver] Entry - driverId: ${driverId}`);
|
|
try {
|
|
for (const list of this.membershipsByTeam.values()) {
|
|
const membership = list.find(
|
|
(m) => m.driverId === driverId && m.status === 'active',
|
|
);
|
|
if (membership) {
|
|
this.logger.info(`[getActiveMembershipForDriver] Success - found active membership for driver: ${driverId}, team: ${membership.teamId}.`);
|
|
return membership;
|
|
}
|
|
}
|
|
this.logger.info(`[getActiveMembershipForDriver] Not found - no active membership for driver: ${driverId}.`);
|
|
return null;
|
|
} catch (error) {
|
|
this.logger.error(`[getActiveMembershipForDriver] Error getting active membership for driver ${driverId}:`, error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async getTeamMembers(teamId: string): Promise<TeamMembership[]> {
|
|
this.logger.debug(`[getTeamMembers] Entry - teamId: ${teamId}`);
|
|
try {
|
|
const members = [...(this.membershipsByTeam.get(teamId) ?? [])];
|
|
this.logger.info(`[getTeamMembers] Success - found ${members.length} members for team: ${teamId}.`);
|
|
return members;
|
|
} catch (error) {
|
|
this.logger.error(`[getTeamMembers] Error getting team members for team ${teamId}:`, error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async countByTeamId(teamId: string): Promise<number> {
|
|
this.logger.debug(`[countByTeamId] Entry - teamId: ${teamId}`);
|
|
try {
|
|
const list = this.membershipsByTeam.get(teamId) ?? [];
|
|
const count = list.filter((m) => m.status === 'active').length;
|
|
this.logger.info(`[countByTeamId] Success - counted ${count} active members for team: ${teamId}.`);
|
|
return count;
|
|
} catch (error) {
|
|
this.logger.error(`[countByTeamId] Error counting members for team ${teamId}:`, error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async saveMembership(membership: TeamMembership): Promise<TeamMembership> {
|
|
this.logger.debug(`[saveMembership] Entry - teamId: ${membership.teamId}, driverId: ${membership.driverId}`);
|
|
try {
|
|
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;
|
|
this.logger.info(`[saveMembership] Success - updated existing membership for team: ${membership.teamId}, driver: ${membership.driverId}.`);
|
|
} else {
|
|
list.push(membership);
|
|
this.logger.info(`[saveMembership] Success - created new membership for team: ${membership.teamId}, driver: ${membership.driverId}.`);
|
|
}
|
|
|
|
this.membershipsByTeam.set(membership.teamId, list);
|
|
return membership;
|
|
} catch (error) {
|
|
this.logger.error(`[saveMembership] Error saving membership for team ${membership.teamId}, driver ${membership.driverId}:`, error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async removeMembership(teamId: string, driverId: string): Promise<void> {
|
|
this.logger.debug(`[removeMembership] Entry - teamId: ${teamId}, driverId: ${driverId}`);
|
|
try {
|
|
const list = this.membershipsByTeam.get(teamId);
|
|
if (!list) {
|
|
this.logger.warn(`[removeMembership] No membership list found for team: ${teamId}. Cannot remove.`);
|
|
return;
|
|
}
|
|
const index = list.findIndex((m) => m.driverId === driverId);
|
|
if (index >= 0) {
|
|
list.splice(index, 1);
|
|
this.membershipsByTeam.set(teamId, list);
|
|
this.logger.info(`[removeMembership] Success - removed membership for team: ${teamId}, driver: ${driverId}.`);
|
|
} else {
|
|
this.logger.info(`[removeMembership] Not found - membership for team: ${teamId}, driver: ${driverId}. Cannot remove.`);
|
|
}
|
|
} catch (error) {
|
|
this.logger.error(`[removeMembership] Error removing membership for team ${teamId}, driver ${driverId}:`, error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async getJoinRequests(teamId: string): Promise<TeamJoinRequest[]> {
|
|
this.logger.debug(`[getJoinRequests] Entry - teamId: ${teamId}`);
|
|
try {
|
|
const requests = [...(this.joinRequestsByTeam.get(teamId) ?? [])];
|
|
this.logger.info(`[getJoinRequests] Success - found ${requests.length} join requests for team: ${teamId}.`);
|
|
return requests;
|
|
} catch (error) {
|
|
this.logger.error(`[getJoinRequests] Error getting join requests for team ${teamId}:`, error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async saveJoinRequest(request: TeamJoinRequest): Promise<TeamJoinRequest> {
|
|
this.logger.debug(`[saveJoinRequest] Entry - teamId: ${request.teamId}, driverId: ${request.driverId}, id: ${request.id}`);
|
|
try {
|
|
const list = this.getJoinRequestList(request.teamId);
|
|
const existingIndex = list.findIndex((r) => r.id === request.id);
|
|
|
|
if (existingIndex >= 0) {
|
|
list[existingIndex] = request;
|
|
this.logger.info(`[saveJoinRequest] Success - updated existing join request: ${request.id}.`);
|
|
} else {
|
|
list.push(request);
|
|
this.logger.info(`[saveJoinRequest] Success - created new join request: ${request.id}.`);
|
|
}
|
|
|
|
this.joinRequestsByTeam.set(request.teamId, list);
|
|
return request;
|
|
} catch (error) {
|
|
this.logger.error(`[saveJoinRequest] Error saving join request ${request.id}:`, error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async removeJoinRequest(requestId: string): Promise<void> {
|
|
this.logger.debug(`[removeJoinRequest] Entry - requestId: ${requestId}`);
|
|
try {
|
|
let removed = false;
|
|
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);
|
|
removed = true;
|
|
this.logger.info(`[removeJoinRequest] Success - removed join request ${requestId} from team ${teamId}.`);
|
|
break;
|
|
}
|
|
}
|
|
if (!removed) {
|
|
this.logger.warn(`[removeJoinRequest] Not found - join request with ID ${requestId} not found for removal.`);
|
|
}
|
|
} catch (error) {
|
|
this.logger.error(`[removeJoinRequest] Error removing join request ${requestId}:`, error);
|
|
throw error;
|
|
}
|
|
}
|
|
} |