/** * Infrastructure Adapter: InMemoryTeamRepository * * In-memory implementation of ITeamRepository. * Stores data in a Map structure. */ import { MediaReference } from '@core/domain/media/MediaReference'; import { Team } from '@core/racing/domain/entities/Team'; import type { TeamRepository } from '@core/racing/domain/repositories/TeamRepository'; import type { Logger } from '@core/shared/domain/Logger'; export class InMemoryTeamRepository implements TeamRepository { private teams: Map; private readonly logger: Logger; constructor(logger: Logger) { this.logger = logger; this.logger.info('InMemoryTeamRepository initialized.'); this.teams = new Map(); } async findById(id: string): Promise { this.logger.debug(`Finding team by id: ${id}`); try { const team = this.teams.get(id) ?? null; if (team) { this.logger.info(`Found team: ${id}.`); } else { this.logger.warn(`Team with id ${id} not found.`); } return team; } catch (error) { this.logger.error(`Error finding team by id ${id}:`, error instanceof Error ? error : new Error(String(error))); throw error; } } async findAll(): Promise { this.logger.debug('Finding all teams.'); try { const teams = Array.from(this.teams.values()); this.logger.info(`Found ${teams.length} teams.`); return teams; } catch (error) { this.logger.error('Error finding all teams:', error instanceof Error ? error : new Error(String(error))); throw error; } } async findByLeagueId(leagueId: string): Promise { this.logger.debug(`Finding teams by league id: ${leagueId}`); try { const teams = Array.from(this.teams.values()).filter((team) => team.leagues.some(league => league.toString() === leagueId), ); this.logger.info(`Found ${teams.length} teams for league id: ${leagueId}.`); return teams; } catch (error) { this.logger.error(`Error finding teams by league id ${leagueId}:`, error instanceof Error ? error : new Error(String(error))); throw error; } } async create(team: Team): Promise { this.logger.debug(`Creating team: ${team.id}`); try { if (await this.exists(team.id)) { this.logger.warn(`Team with ID ${team.id} already exists.`); throw new Error(`Team with ID ${team.id} already exists`); } this.teams.set(team.id, team); this.logger.info(`Team ${team.id} created successfully.`); return team; } catch (error) { this.logger.error(`Error creating team ${team.id}:`, error instanceof Error ? error : new Error(String(error))); throw error; } } async update(team: Team): Promise { this.logger.debug(`Updating team: ${team.id}`); try { if (!(await this.exists(team.id))) { this.logger.warn(`Team with ID ${team.id} not found for update.`); throw new Error(`Team with ID ${team.id} not found`); } this.teams.set(team.id, team); this.logger.info(`Team ${team.id} updated successfully.`); return team; } catch (error) { this.logger.error(`Error updating team ${team.id}:`, error instanceof Error ? error : new Error(String(error))); throw error; } } async delete(id: string): Promise { this.logger.debug(`Deleting team: ${id}`); try { if (!(await this.exists(id))) { this.logger.warn(`Team with ID ${id} not found for deletion.`); throw new Error(`Team with ID ${id} not found`); } this.teams.delete(id); this.logger.info(`Team ${id} deleted successfully.`); } catch (error) { this.logger.error(`Error deleting team ${id}:`, error instanceof Error ? error : new Error(String(error))); throw error; } } async exists(id: string): Promise { this.logger.debug(`Checking existence of team with id: ${id}`); try { const exists = this.teams.has(id); this.logger.debug(`Team ${id} exists: ${exists}.`); return exists; } catch (error) { this.logger.error(`Error checking existence of team with id ${id}:`, error instanceof Error ? error : new Error(String(error))); throw error; } } // Serialization methods for persistence serialize(team: Team): Record { return { id: team.id, name: team.name.toString(), tag: team.tag.toString(), description: team.description.toString(), ownerId: team.ownerId.toString(), leagues: team.leagues.map(l => l.toString()), category: team.category ?? null, isRecruiting: team.isRecruiting, createdAt: team.createdAt.toDate().toISOString(), logoRef: team.logoRef.toJSON(), }; } deserialize(data: Record): Team { const props: { id: string; name: string; tag: string; description: string; ownerId: string; leagues: string[]; category?: string; isRecruiting: boolean; createdAt: Date; logoRef?: MediaReference; } = { id: data.id as string, name: data.name as string, tag: data.tag as string, description: data.description as string, ownerId: data.ownerId as string, leagues: data.leagues as string[], isRecruiting: data.isRecruiting as boolean, createdAt: new Date(data.createdAt as string), }; if (data.category !== null && data.category !== undefined) { props.category = data.category as string; } if (data.logoRef !== null && data.logoRef !== undefined) { props.logoRef = MediaReference.fromJSON(data.logoRef as Record); } return Team.rehydrate(props); } }