/** * Infrastructure Adapter: InMemoryPenaltyRepository * * Simple in-memory implementation of IPenaltyRepository seeded with * a handful of demo penalties and bonuses for leagues/drivers. */ import type { Penalty } from '@gridpilot/racing/domain/entities/Penalty'; import type { IPenaltyRepository } from '@gridpilot/racing/domain/repositories/IPenaltyRepository'; export class InMemoryPenaltyRepository implements IPenaltyRepository { private readonly penalties: Penalty[]; constructor(seedPenalties?: Penalty[]) { this.penalties = seedPenalties ? [...seedPenalties] : InMemoryPenaltyRepository.createDefaultSeed(); } async findByLeagueId(leagueId: string): Promise { return this.penalties.filter((p) => p.leagueId === leagueId); } async findByLeagueIdAndDriverId(leagueId: string, driverId: string): Promise { return this.penalties.filter((p) => p.leagueId === leagueId && p.driverId === driverId); } async findAll(): Promise { return [...this.penalties]; } /** * Default demo seed with a mix of deductions and bonuses * across a couple of leagues and drivers. */ private static createDefaultSeed(): Penalty[] { const now = new Date(); const daysAgo = (n: number) => new Date(now.getTime() - n * 24 * 60 * 60 * 1000); return [ { id: 'pen-league-1-driver-1-main', leagueId: 'league-1', driverId: 'driver-1', type: 'points-deduction', pointsDelta: -3, reason: 'Incident points penalty', appliedAt: daysAgo(7), }, { id: 'pen-league-1-driver-2-bonus', leagueId: 'league-1', driverId: 'driver-2', type: 'points-bonus', pointsDelta: 2, reason: 'Fastest laps bonus', appliedAt: daysAgo(5), }, { id: 'pen-league-1-driver-3-bonus', leagueId: 'league-1', driverId: 'driver-3', type: 'points-bonus', pointsDelta: 1, reason: 'Pole position bonus', appliedAt: daysAgo(3), }, { id: 'pen-league-2-driver-4-main', leagueId: 'league-2', driverId: 'driver-4', type: 'points-deduction', pointsDelta: -5, reason: 'Post-race steward decision', appliedAt: daysAgo(10), }, { id: 'pen-league-2-driver-5-bonus', leagueId: 'league-2', driverId: 'driver-5', type: 'points-bonus', pointsDelta: 3, reason: 'Clean race awards', appliedAt: daysAgo(2), }, ]; } }