This commit is contained in:
2025-12-13 11:43:09 +01:00
parent 4b6fc668b5
commit bb0497f429
38 changed files with 3838 additions and 55 deletions

View File

@@ -138,6 +138,7 @@ import { GetDriversLeaderboardUseCase } from '@gridpilot/racing/application/use-
import { GetTeamsLeaderboardUseCase } from '@gridpilot/racing/application/use-cases/GetTeamsLeaderboardUseCase';
import { TransferLeagueOwnershipUseCase } from '@gridpilot/racing/application/use-cases/TransferLeagueOwnershipUseCase';
import { CancelRaceUseCase } from '@gridpilot/racing/application/use-cases/CancelRaceUseCase';
import { CompleteRaceUseCase } from '@gridpilot/racing/application/use-cases/CompleteRaceUseCase';
import { ImportRaceResultsUseCase } from '@gridpilot/racing/application/use-cases/ImportRaceResultsUseCase';
import { DriversLeaderboardPresenter } from './presenters/DriversLeaderboardPresenter';
import { RacesPagePresenter } from './presenters/RacesPagePresenter';
@@ -274,6 +275,21 @@ export function configureDIContainer(): void {
}
}
// For running races, add registrations (especially for league-5 demo)
const runningRaces = seedData.races.filter(r => r.status === 'running');
for (const race of runningRaces) {
// Add a good number of participants for running races
const participantCount = Math.floor(Math.random() * 8) + 12; // 12-20 participants
const shuffledDrivers = [...seedData.drivers].sort(() => Math.random() - 0.5).slice(0, participantCount);
for (const driver of shuffledDrivers) {
seedRaceRegistrations.push({
raceId: race.id,
driverId: driver.id,
registeredAt: new Date(Date.now() - Math.floor(Math.random() * 2) * 24 * 60 * 60 * 1000), // Recent registrations
});
}
}
container.registerInstance<IRaceRegistrationRepository>(
DI_TOKENS.RaceRegistrationRepository,
new InMemoryRaceRegistrationRepository(seedRaceRegistrations)
@@ -526,6 +542,22 @@ export function configureDIContainer(): void {
}
}
// Ensure driver-1 is an admin of league-5 (the demo league with running race)
const league5Membership = seededMemberships.find(
(m) => m.leagueId === 'league-5' && m.driverId === primaryDriverId,
);
if (league5Membership) {
league5Membership.role = 'admin';
} else {
seededMemberships.push({
leagueId: 'league-5',
driverId: primaryDriverId,
role: 'admin',
status: 'active',
joinedAt: new Date(),
});
}
// Ensure primary driver owns at least one league
const hasPrimaryOwnerMembership = seededMemberships.some(
(m) => m.driverId === primaryDriverId && m.role === 'owner',
@@ -606,6 +638,27 @@ export function configureDIContainer(): void {
});
}
// Ensure driver-1 is an admin of league-5 (the demo league with running race)
const league5 = seedData.leagues.find(l => l.id === 'league-5');
if (league5) {
const existing = seededMemberships.find(
(m) => m.leagueId === 'league-5' && m.driverId === primaryDriverId,
);
if (existing) {
if (existing.role !== 'owner') {
existing.role = 'admin';
}
} else {
seededMemberships.push({
leagueId: 'league-5',
driverId: primaryDriverId,
role: 'admin',
status: 'active',
joinedAt: new Date(),
});
}
}
// Seed pending join requests
const seededJoinRequests: JoinRequest[] = [];
const demoLeagues = seedData.leagues.slice(0, 6);
@@ -857,6 +910,17 @@ export function configureDIContainer(): void {
new CancelRaceUseCase(raceRepository)
);
container.registerInstance(
DI_TOKENS.CompleteRaceUseCase,
new CompleteRaceUseCase(
raceRepository,
raceRegistrationRepository,
resultRepository,
standingRepository,
driverRatingProvider
)
);
container.registerInstance(
DI_TOKENS.CreateLeagueWithSeasonAndScoringUseCase,
new CreateLeagueWithSeasonAndScoringUseCase(

View File

@@ -345,6 +345,11 @@ class DIContainer {
return getDIContainer().resolve<CancelRaceUseCase>(DI_TOKENS.CancelRaceUseCase);
}
get completeRaceUseCase(): import('@gridpilot/racing/application/use-cases/CompleteRaceUseCase').CompleteRaceUseCase {
this.ensureInitialized();
return getDIContainer().resolve<import('@gridpilot/racing/application/use-cases/CompleteRaceUseCase').CompleteRaceUseCase>(DI_TOKENS.CompleteRaceUseCase);
}
get importRaceResultsUseCase(): ImportRaceResultsUseCase {
this.ensureInitialized();
return getDIContainer().resolve<ImportRaceResultsUseCase>(DI_TOKENS.ImportRaceResultsUseCase);
@@ -702,6 +707,10 @@ export function getCancelRaceUseCase(): CancelRaceUseCase {
return DIContainer.getInstance().cancelRaceUseCase;
}
export function getCompleteRaceUseCase(): import('@gridpilot/racing/application/use-cases/CompleteRaceUseCase').CompleteRaceUseCase {
return DIContainer.getInstance().completeRaceUseCase;
}
export function getImportRaceResultsUseCase(): ImportRaceResultsUseCase {
return DIContainer.getInstance().importRaceResultsUseCase;
}

View File

@@ -44,6 +44,7 @@ export const DI_TOKENS = {
CreateLeagueWithSeasonAndScoringUseCase: Symbol.for('CreateLeagueWithSeasonAndScoringUseCase'),
TransferLeagueOwnershipUseCase: Symbol.for('TransferLeagueOwnershipUseCase'),
CancelRaceUseCase: Symbol.for('CancelRaceUseCase'),
CompleteRaceUseCase: Symbol.for('CompleteRaceUseCase'),
ImportRaceResultsUseCase: Symbol.for('ImportRaceResultsUseCase'),
// Queries - Dashboard