This commit is contained in:
2025-12-04 11:54:23 +01:00
parent c0fdae3d3c
commit 9d5caa87f3
83 changed files with 1579 additions and 2151 deletions

View File

@@ -1,27 +1,34 @@
/**
* Dependency Injection Container
*
*
* Initializes all in-memory repositories and provides accessor functions.
* Allows easy swapping to persistent repositories later.
*/
import { Driver } from '@gridpilot/racing-domain/entities/Driver';
import { League } from '@gridpilot/racing-domain/entities/League';
import { Race } from '@gridpilot/racing-domain/entities/Race';
import { Result } from '@gridpilot/racing-domain/entities/Result';
import { Standing } from '@gridpilot/racing-domain/entities/Standing';
import { Driver } from '@gridpilot/racing/domain/entities/Driver';
import { League } from '@gridpilot/racing/domain/entities/League';
import { Race } from '@gridpilot/racing/domain/entities/Race';
import { Result } from '@gridpilot/racing/domain/entities/Result';
import { Standing } from '@gridpilot/racing/domain/entities/Standing';
import type { IDriverRepository } from '@gridpilot/racing-domain/ports/IDriverRepository';
import type { ILeagueRepository } from '@gridpilot/racing-domain/ports/ILeagueRepository';
import type { IRaceRepository } from '@gridpilot/racing-domain/ports/IRaceRepository';
import type { IResultRepository } from '@gridpilot/racing-domain/ports/IResultRepository';
import type { IStandingRepository } from '@gridpilot/racing-domain/ports/IStandingRepository';
import type { IDriverRepository } from '@gridpilot/racing/domain/repositories/IDriverRepository';
import type { ILeagueRepository } from '@gridpilot/racing/domain/repositories/ILeagueRepository';
import type { IRaceRepository } from '@gridpilot/racing/domain/repositories/IRaceRepository';
import type { IResultRepository } from '@gridpilot/racing/domain/repositories/IResultRepository';
import type { IStandingRepository } from '@gridpilot/racing/domain/repositories/IStandingRepository';
import type { IFeedRepository } from '@gridpilot/social/domain/repositories/IFeedRepository';
import type { ISocialGraphRepository } from '@gridpilot/social/domain/repositories/ISocialGraphRepository';
import { InMemoryDriverRepository } from '@gridpilot/racing-infrastructure/repositories/InMemoryDriverRepository';
import { InMemoryLeagueRepository } from '@gridpilot/racing-infrastructure/repositories/InMemoryLeagueRepository';
import { InMemoryRaceRepository } from '@gridpilot/racing-infrastructure/repositories/InMemoryRaceRepository';
import { InMemoryResultRepository } from '@gridpilot/racing-infrastructure/repositories/InMemoryResultRepository';
import { InMemoryStandingRepository } from '@gridpilot/racing-infrastructure/repositories/InMemoryStandingRepository';
import { InMemoryDriverRepository } from '@gridpilot/racing/infrastructure/repositories/InMemoryDriverRepository';
import { InMemoryLeagueRepository } from '@gridpilot/racing/infrastructure/repositories/InMemoryLeagueRepository';
import { InMemoryRaceRepository } from '@gridpilot/racing/infrastructure/repositories/InMemoryRaceRepository';
import { InMemoryResultRepository } from '@gridpilot/racing/infrastructure/repositories/InMemoryResultRepository';
import { InMemoryStandingRepository } from '@gridpilot/racing/infrastructure/repositories/InMemoryStandingRepository';
import { createStaticRacingSeed, type RacingSeedData } from '@gridpilot/testing-support';
import {
InMemoryFeedRepository,
InMemorySocialGraphRepository,
} from '@gridpilot/social/infrastructure/inmemory/InMemorySocialAndFeed';
/**
* Seed data for development
@@ -49,193 +56,34 @@ export interface DriverStats {
*/
const driverStats: Record<string, DriverStats> = {};
function createSeedData() {
// Create sample drivers (matching membership-data.ts and team-data.ts)
const driver1 = Driver.create({
id: 'driver-1',
iracingId: '123456',
name: 'Max Verstappen',
country: 'NL',
bio: 'Three-time world champion and team owner of Apex Racing',
joinedAt: new Date('2024-01-15'),
function createSeedData(): RacingSeedData {
const seed = createStaticRacingSeed(42);
const { drivers } = seed;
drivers.forEach((driver, index) => {
const totalRaces = 40 + index * 5;
const wins = Math.max(0, Math.floor(totalRaces * 0.2) - index);
const podiums = Math.max(wins * 2, 0);
const dnfs = Math.max(0, Math.floor(index / 2));
const rating = 1500 + index * 25;
driverStats[driver.id] = {
driverId: driver.id,
rating,
totalRaces,
wins,
podiums,
dnfs,
avgFinish: 4,
bestFinish: 1,
worstFinish: 20,
consistency: 80,
overallRank: index + 1,
percentile: Math.max(0, 100 - index),
};
});
const driver2 = Driver.create({
id: 'driver-2',
iracingId: '234567',
name: 'Lewis Hamilton',
country: 'GB',
bio: 'Seven-time world champion leading Speed Demons',
joinedAt: new Date('2024-01-20'),
});
const driver3 = Driver.create({
id: 'driver-3',
iracingId: '345678',
name: 'Charles Leclerc',
country: 'MC',
bio: 'Ferrari race winner and Weekend Warriors team owner',
joinedAt: new Date('2024-02-01'),
});
const driver4 = Driver.create({
id: 'driver-4',
iracingId: '456789',
name: 'Lando Norris',
country: 'GB',
bio: 'Rising star in motorsport',
joinedAt: new Date('2024-02-15'),
});
// Initialize driver stats
driverStats['driver-1'] = {
driverId: 'driver-1',
rating: 3245,
totalRaces: 156,
wins: 45,
podiums: 89,
dnfs: 8,
avgFinish: 3.2,
bestFinish: 1,
worstFinish: 18,
consistency: 87,
overallRank: 1,
percentile: 99
};
driverStats['driver-2'] = {
driverId: 'driver-2',
rating: 3198,
totalRaces: 234,
wins: 78,
podiums: 145,
dnfs: 12,
avgFinish: 2.8,
bestFinish: 1,
worstFinish: 22,
consistency: 92,
overallRank: 2,
percentile: 98
};
driverStats['driver-3'] = {
driverId: 'driver-3',
rating: 2912,
totalRaces: 145,
wins: 34,
podiums: 67,
dnfs: 9,
avgFinish: 4.5,
bestFinish: 1,
worstFinish: 20,
consistency: 84,
overallRank: 3,
percentile: 96
};
driverStats['driver-4'] = {
driverId: 'driver-4',
rating: 2789,
totalRaces: 112,
wins: 23,
podiums: 56,
dnfs: 7,
avgFinish: 5.1,
bestFinish: 1,
worstFinish: 16,
consistency: 81,
overallRank: 5,
percentile: 93
};
// Create sample league (matching membership-data.ts)
const league1 = League.create({
id: 'league-1',
name: 'European GT Championship',
description: 'Weekly GT3 racing with professional drivers',
ownerId: driver1.id,
settings: {
pointsSystem: 'f1-2024',
sessionDuration: 60,
qualifyingFormat: 'open',
},
createdAt: new Date('2024-01-20'),
});
// Create sample races
const race1 = Race.create({
id: 'race-1',
leagueId: league1.id,
scheduledAt: new Date('2024-03-15T19:00:00Z'),
track: 'Monza GP',
car: 'Porsche 911 GT3 R',
sessionType: 'race',
status: 'completed',
});
const race2 = Race.create({
id: 'race-2',
leagueId: league1.id,
scheduledAt: new Date('2024-03-22T19:00:00Z'),
track: 'Spa-Francorchamps',
car: 'Porsche 911 GT3 R',
sessionType: 'race',
status: 'scheduled',
});
const race3 = Race.create({
id: 'race-3',
leagueId: league1.id,
scheduledAt: new Date('2024-04-05T19:00:00Z'),
track: 'Nürburgring GP',
car: 'Porsche 911 GT3 R',
sessionType: 'race',
status: 'scheduled',
});
// Create sample standings
const standing1 = Standing.create({
leagueId: league1.id,
driverId: driver1.id,
position: 1,
points: 25,
wins: 1,
racesCompleted: 1,
});
const standing2 = Standing.create({
leagueId: league1.id,
driverId: driver2.id,
position: 2,
points: 18,
wins: 0,
racesCompleted: 1,
});
const standing3 = Standing.create({
leagueId: league1.id,
driverId: driver3.id,
position: 3,
points: 15,
wins: 0,
racesCompleted: 1,
});
const standing4 = Standing.create({
leagueId: league1.id,
driverId: driver4.id,
position: 4,
points: 12,
wins: 0,
racesCompleted: 1,
});
return {
drivers: [driver1, driver2, driver3, driver4],
leagues: [league1],
races: [race1, race2, race3],
standings: [standing1, standing2, standing3, standing4],
};
return seed;
}
/**
@@ -249,6 +97,8 @@ class DIContainer {
private _raceRepository: IRaceRepository;
private _resultRepository: IResultRepository;
private _standingRepository: IStandingRepository;
private _feedRepository: IFeedRepository;
private _socialRepository: ISocialGraphRepository;
private constructor() {
// Create seed data
@@ -261,7 +111,7 @@ class DIContainer {
// Result repository needs race repository for league-based queries
this._resultRepository = new InMemoryResultRepository(
undefined,
seedData.results,
this._raceRepository
);
@@ -272,6 +122,10 @@ class DIContainer {
this._raceRepository,
this._leagueRepository
);
// Social and feed adapters backed by static seed
this._feedRepository = new InMemoryFeedRepository(seedData);
this._socialRepository = new InMemorySocialGraphRepository(seedData);
}
/**
@@ -313,6 +167,14 @@ class DIContainer {
get standingRepository(): IStandingRepository {
return this._standingRepository;
}
get feedRepository(): IFeedRepository {
return this._feedRepository;
}
get socialRepository(): ISocialGraphRepository {
return this._socialRepository;
}
}
/**
@@ -338,6 +200,14 @@ export function getStandingRepository(): IStandingRepository {
return DIContainer.getInstance().standingRepository;
}
export function getFeedRepository(): IFeedRepository {
return DIContainer.getInstance().feedRepository;
}
export function getSocialRepository(): ISocialGraphRepository {
return DIContainer.getInstance().socialRepository;
}
/**
* Reset function for testing
*/