wip
This commit is contained in:
@@ -1,85 +1,70 @@
|
||||
/**
|
||||
* Infrastructure Adapter: InMemoryPenaltyRepository
|
||||
*
|
||||
* Simple in-memory implementation of IPenaltyRepository seeded with
|
||||
* a handful of demo penalties and bonuses for leagues/drivers.
|
||||
* In-Memory Implementation: InMemoryPenaltyRepository
|
||||
*
|
||||
* Provides an in-memory storage implementation for penalties.
|
||||
*/
|
||||
import type { Penalty } from '@gridpilot/racing/domain/entities/Penalty';
|
||||
import type { IPenaltyRepository } from '@gridpilot/racing/domain/repositories/IPenaltyRepository';
|
||||
|
||||
import type { Penalty } from '../../domain/entities/Penalty';
|
||||
import type { IPenaltyRepository } from '../../domain/repositories/IPenaltyRepository';
|
||||
|
||||
export class InMemoryPenaltyRepository implements IPenaltyRepository {
|
||||
private readonly penalties: Penalty[];
|
||||
private penalties: Map<string, Penalty> = new Map();
|
||||
|
||||
constructor(seedPenalties?: Penalty[]) {
|
||||
this.penalties = seedPenalties ? [...seedPenalties] : InMemoryPenaltyRepository.createDefaultSeed();
|
||||
constructor(initialPenalties: Penalty[] = []) {
|
||||
initialPenalties.forEach(penalty => {
|
||||
this.penalties.set(penalty.id, penalty);
|
||||
});
|
||||
}
|
||||
|
||||
async findByLeagueId(leagueId: string): Promise<Penalty[]> {
|
||||
return this.penalties.filter((p) => p.leagueId === leagueId);
|
||||
async findById(id: string): Promise<Penalty | null> {
|
||||
return this.penalties.get(id) || null;
|
||||
}
|
||||
|
||||
async findByLeagueIdAndDriverId(leagueId: string, driverId: string): Promise<Penalty[]> {
|
||||
return this.penalties.filter((p) => p.leagueId === leagueId && p.driverId === driverId);
|
||||
async findByRaceId(raceId: string): Promise<Penalty[]> {
|
||||
return Array.from(this.penalties.values()).filter(
|
||||
penalty => penalty.raceId === raceId
|
||||
);
|
||||
}
|
||||
|
||||
async findAll(): Promise<Penalty[]> {
|
||||
return [...this.penalties];
|
||||
async findByDriverId(driverId: string): Promise<Penalty[]> {
|
||||
return Array.from(this.penalties.values()).filter(
|
||||
penalty => penalty.driverId === driverId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
async findByProtestId(protestId: string): Promise<Penalty[]> {
|
||||
return Array.from(this.penalties.values()).filter(
|
||||
penalty => penalty.protestId === protestId
|
||||
);
|
||||
}
|
||||
|
||||
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),
|
||||
},
|
||||
];
|
||||
async findPending(): Promise<Penalty[]> {
|
||||
return Array.from(this.penalties.values()).filter(
|
||||
penalty => penalty.isPending()
|
||||
);
|
||||
}
|
||||
|
||||
async findIssuedBy(stewardId: string): Promise<Penalty[]> {
|
||||
return Array.from(this.penalties.values()).filter(
|
||||
penalty => penalty.issuedBy === stewardId
|
||||
);
|
||||
}
|
||||
|
||||
async create(penalty: Penalty): Promise<void> {
|
||||
if (this.penalties.has(penalty.id)) {
|
||||
throw new Error(`Penalty with ID ${penalty.id} already exists`);
|
||||
}
|
||||
this.penalties.set(penalty.id, penalty);
|
||||
}
|
||||
|
||||
async update(penalty: Penalty): Promise<void> {
|
||||
if (!this.penalties.has(penalty.id)) {
|
||||
throw new Error(`Penalty with ID ${penalty.id} not found`);
|
||||
}
|
||||
this.penalties.set(penalty.id, penalty);
|
||||
}
|
||||
|
||||
async exists(id: string): Promise<boolean> {
|
||||
return this.penalties.has(id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* In-Memory Implementation: InMemoryProtestRepository
|
||||
*
|
||||
* Provides an in-memory storage implementation for protests.
|
||||
*/
|
||||
|
||||
import type { Protest } from '../../domain/entities/Protest';
|
||||
import type { IProtestRepository } from '../../domain/repositories/IProtestRepository';
|
||||
|
||||
export class InMemoryProtestRepository implements IProtestRepository {
|
||||
private protests: Map<string, Protest> = new Map();
|
||||
|
||||
constructor(initialProtests: Protest[] = []) {
|
||||
initialProtests.forEach(protest => {
|
||||
this.protests.set(protest.id, protest);
|
||||
});
|
||||
}
|
||||
|
||||
async findById(id: string): Promise<Protest | null> {
|
||||
return this.protests.get(id) || null;
|
||||
}
|
||||
|
||||
async findByRaceId(raceId: string): Promise<Protest[]> {
|
||||
return Array.from(this.protests.values()).filter(
|
||||
protest => protest.raceId === raceId
|
||||
);
|
||||
}
|
||||
|
||||
async findByProtestingDriverId(driverId: string): Promise<Protest[]> {
|
||||
return Array.from(this.protests.values()).filter(
|
||||
protest => protest.protestingDriverId === driverId
|
||||
);
|
||||
}
|
||||
|
||||
async findByAccusedDriverId(driverId: string): Promise<Protest[]> {
|
||||
return Array.from(this.protests.values()).filter(
|
||||
protest => protest.accusedDriverId === driverId
|
||||
);
|
||||
}
|
||||
|
||||
async findPending(): Promise<Protest[]> {
|
||||
return Array.from(this.protests.values()).filter(
|
||||
protest => protest.isPending()
|
||||
);
|
||||
}
|
||||
|
||||
async findUnderReviewBy(stewardId: string): Promise<Protest[]> {
|
||||
return Array.from(this.protests.values()).filter(
|
||||
protest => protest.reviewedBy === stewardId && protest.isUnderReview()
|
||||
);
|
||||
}
|
||||
|
||||
async create(protest: Protest): Promise<void> {
|
||||
if (this.protests.has(protest.id)) {
|
||||
throw new Error(`Protest with ID ${protest.id} already exists`);
|
||||
}
|
||||
this.protests.set(protest.id, protest);
|
||||
}
|
||||
|
||||
async update(protest: Protest): Promise<void> {
|
||||
if (!this.protests.has(protest.id)) {
|
||||
throw new Error(`Protest with ID ${protest.id} not found`);
|
||||
}
|
||||
this.protests.set(protest.id, protest);
|
||||
}
|
||||
|
||||
async exists(id: string): Promise<boolean> {
|
||||
return this.protests.has(id);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user