/** * Infrastructure Adapter: InMemoryResultRepository * * In-memory implementation of IResultRepository. * Stores data in Map structure with UUID generation. */ import { v4 as uuidv4 } from 'uuid'; import { Result } from '../../domain/entities/Result'; import { IResultRepository } from '../../application/ports/IResultRepository'; import { IRaceRepository } from '../../application/ports/IRaceRepository'; export class InMemoryResultRepository implements IResultRepository { private results: Map; private raceRepository?: IRaceRepository; constructor(seedData?: Result[], raceRepository?: IRaceRepository) { this.results = new Map(); this.raceRepository = raceRepository; if (seedData) { seedData.forEach(result => { this.results.set(result.id, result); }); } } async findById(id: string): Promise { return this.results.get(id) ?? null; } async findAll(): Promise { return Array.from(this.results.values()); } async findByRaceId(raceId: string): Promise { return Array.from(this.results.values()) .filter(result => result.raceId === raceId) .sort((a, b) => a.position - b.position); } async findByDriverId(driverId: string): Promise { return Array.from(this.results.values()) .filter(result => result.driverId === driverId); } async findByDriverIdAndLeagueId(driverId: string, leagueId: string): Promise { if (!this.raceRepository) { return []; } const leagueRaces = await this.raceRepository.findByLeagueId(leagueId); const leagueRaceIds = new Set(leagueRaces.map(race => race.id)); return Array.from(this.results.values()) .filter(result => result.driverId === driverId && leagueRaceIds.has(result.raceId) ); } async create(result: Result): Promise { if (await this.exists(result.id)) { throw new Error(`Result with ID ${result.id} already exists`); } this.results.set(result.id, result); return result; } async createMany(results: Result[]): Promise { const created: Result[] = []; for (const result of results) { if (await this.exists(result.id)) { throw new Error(`Result with ID ${result.id} already exists`); } this.results.set(result.id, result); created.push(result); } return created; } async update(result: Result): Promise { if (!await this.exists(result.id)) { throw new Error(`Result with ID ${result.id} not found`); } this.results.set(result.id, result); return result; } async delete(id: string): Promise { if (!await this.exists(id)) { throw new Error(`Result with ID ${id} not found`); } this.results.delete(id); } async deleteByRaceId(raceId: string): Promise { const raceResults = await this.findByRaceId(raceId); raceResults.forEach(result => { this.results.delete(result.id); }); } async exists(id: string): Promise { return this.results.has(id); } async existsByRaceId(raceId: string): Promise { return Array.from(this.results.values()).some( result => result.raceId === raceId ); } /** * Utility method to generate a new UUID */ static generateId(): string { return uuidv4(); } }