This commit is contained in:
2025-12-11 00:57:32 +01:00
parent 1303a14493
commit 6a427eab57
112 changed files with 6148 additions and 2272 deletions

View File

@@ -113,52 +113,66 @@ import {
AcceptSponsorshipRequestUseCase,
RejectSponsorshipRequestUseCase,
} from '@gridpilot/racing/application';
import { IsDriverRegisteredForRaceUseCase } from '@gridpilot/racing/application/use-cases/IsDriverRegisteredForRaceQuery';
import { GetRaceRegistrationsUseCase } from '@gridpilot/racing/application/use-cases/GetRaceRegistrationsQuery';
import { GetRaceWithSOFUseCase } from '@gridpilot/racing/application/use-cases/GetRaceWithSOFQuery';
import { GetRaceProtestsUseCase } from '@gridpilot/racing/application/use-cases/GetRaceProtestsQuery';
import { GetRacePenaltiesUseCase } from '@gridpilot/racing/application/use-cases/GetRacePenaltiesQuery';
import { GetLeagueStandingsUseCase } from '@gridpilot/racing/application/use-cases/GetLeagueStandingsQuery';
import { GetLeagueDriverSeasonStatsUseCase } from '@gridpilot/racing/application/use-cases/GetLeagueDriverSeasonStatsQuery';
import { GetAllLeaguesWithCapacityUseCase } from '@gridpilot/racing/application/use-cases/GetAllLeaguesWithCapacityQuery';
import { GetAllLeaguesWithCapacityAndScoringUseCase } from '@gridpilot/racing/application/use-cases/GetAllLeaguesWithCapacityAndScoringQuery';
import { ListLeagueScoringPresetsUseCase } from '@gridpilot/racing/application/use-cases/ListLeagueScoringPresetsQuery';
import { GetLeagueScoringConfigUseCase } from '@gridpilot/racing/application/use-cases/GetLeagueScoringConfigQuery';
import { GetLeagueFullConfigUseCase } from '@gridpilot/racing/application/use-cases/GetLeagueFullConfigQuery';
import { GetLeagueStatsUseCase } from '@gridpilot/racing/application/use-cases/GetLeagueStatsQuery';
import { GetDashboardOverviewUseCase } from '@gridpilot/racing/application/use-cases/GetDashboardOverviewUseCase';
import { GetProfileOverviewUseCase } from '@gridpilot/racing/application/use-cases/GetProfileOverviewUseCase';
import { UpdateDriverProfileUseCase } from '@gridpilot/racing/application/use-cases/UpdateDriverProfileUseCase';
import { IsDriverRegisteredForRaceUseCase } from '@gridpilot/racing/application/use-cases/IsDriverRegisteredForRaceUseCase';
import { GetRaceRegistrationsUseCase } from '@gridpilot/racing/application/use-cases/GetRaceRegistrationsUseCase';
import { GetRaceWithSOFUseCase } from '@gridpilot/racing/application/use-cases/GetRaceWithSOFUseCase';
import { GetRaceProtestsUseCase } from '@gridpilot/racing/application/use-cases/GetRaceProtestsUseCase';
import { GetRacePenaltiesUseCase } from '@gridpilot/racing/application/use-cases/GetRacePenaltiesUseCase';
import { GetLeagueStandingsUseCase } from '@gridpilot/racing/application/use-cases/GetLeagueStandingsUseCase';
import { GetLeagueDriverSeasonStatsUseCase } from '@gridpilot/racing/application/use-cases/GetLeagueDriverSeasonStatsUseCase';
import { GetAllLeaguesWithCapacityUseCase } from '@gridpilot/racing/application/use-cases/GetAllLeaguesWithCapacityUseCase';
import { GetAllLeaguesWithCapacityAndScoringUseCase } from '@gridpilot/racing/application/use-cases/GetAllLeaguesWithCapacityAndScoringUseCase';
import { ListLeagueScoringPresetsUseCase } from '@gridpilot/racing/application/use-cases/ListLeagueScoringPresetsUseCase';
import { GetLeagueScoringConfigUseCase } from '@gridpilot/racing/application/use-cases/GetLeagueScoringConfigUseCase';
import { GetLeagueFullConfigUseCase } from '@gridpilot/racing/application/use-cases/GetLeagueFullConfigUseCase';
import { GetLeagueStatsUseCase } from '@gridpilot/racing/application/use-cases/GetLeagueStatsUseCase';
import { GetRacesPageDataUseCase } from '@gridpilot/racing/application/use-cases/GetRacesPageDataUseCase';
import { GetRaceDetailUseCase } from '@gridpilot/racing/application/use-cases/GetRaceDetailUseCase';
import { GetRaceResultsDetailUseCase } from '@gridpilot/racing/application/use-cases/GetRaceResultsDetailUseCase';
import { GetAllRacesPageDataUseCase } from '@gridpilot/racing/application/use-cases/GetAllRacesPageDataUseCase';
import { GetDriversLeaderboardUseCase } from '@gridpilot/racing/application/use-cases/GetDriversLeaderboardUseCase';
import { GetTeamsLeaderboardUseCase } from '@gridpilot/racing/application/use-cases/GetTeamsLeaderboardUseCase';
import { TransferLeagueOwnershipUseCase } from '@gridpilot/racing/application/use-cases/TransferLeagueOwnershipUseCase';
import { DriversLeaderboardPresenter } from '../../lib/presenters/DriversLeaderboardPresenter';
import { TeamsLeaderboardPresenter } from '../../lib/presenters/TeamsLeaderboardPresenter';
import { RacesPagePresenter } from '../../lib/presenters/RacesPagePresenter';
import { AllTeamsPresenter } from '../../lib/presenters/AllTeamsPresenter';
import { TeamDetailsPresenter } from '../../lib/presenters/TeamDetailsPresenter';
import { TeamMembersPresenter } from '../../lib/presenters/TeamMembersPresenter';
import { TeamJoinRequestsPresenter } from '../../lib/presenters/TeamJoinRequestsPresenter';
import { DriverTeamPresenter } from '../../lib/presenters/DriverTeamPresenter';
import { AllLeaguesWithCapacityPresenter } from '../../lib/presenters/AllLeaguesWithCapacityPresenter';
import { AllLeaguesWithCapacityAndScoringPresenter } from '../../lib/presenters/AllLeaguesWithCapacityAndScoringPresenter';
import { LeagueStatsPresenter } from '../../lib/presenters/LeagueStatsPresenter';
import { LeagueScoringConfigPresenter } from '../../lib/presenters/LeagueScoringConfigPresenter';
import { LeagueFullConfigPresenter } from '../../lib/presenters/LeagueFullConfigPresenter';
import { LeagueDriverSeasonStatsPresenter } from '../../lib/presenters/LeagueDriverSeasonStatsPresenter';
import { LeagueStandingsPresenter } from '../../lib/presenters/LeagueStandingsPresenter';
import { LeagueScoringPresetsPresenter } from '../../lib/presenters/LeagueScoringPresetsPresenter';
import { RaceWithSOFPresenter } from '../../lib/presenters/RaceWithSOFPresenter';
import { RaceProtestsPresenter } from '../../lib/presenters/RaceProtestsPresenter';
import { RacePenaltiesPresenter } from '../../lib/presenters/RacePenaltiesPresenter';
import { RaceRegistrationsPresenter } from '../../lib/presenters/RaceRegistrationsPresenter';
import { DriverRegistrationStatusPresenter } from '../../lib/presenters/DriverRegistrationStatusPresenter';
import { CancelRaceUseCase } from '@gridpilot/racing/application/use-cases/CancelRaceUseCase';
import { ImportRaceResultsUseCase } from '@gridpilot/racing/application/use-cases/ImportRaceResultsUseCase';
import { DriversLeaderboardPresenter } from './presenters/DriversLeaderboardPresenter';
import { TeamsLeaderboardPresenter } from './presenters/TeamsLeaderboardPresenter';
import { RacesPagePresenter } from './presenters/RacesPagePresenter';
import { AllRacesPagePresenter } from './presenters/AllRacesPagePresenter';
import { AllTeamsPresenter } from './presenters/AllTeamsPresenter';
import { TeamDetailsPresenter } from './presenters/TeamDetailsPresenter';
import { TeamMembersPresenter } from './presenters/TeamMembersPresenter';
import { TeamJoinRequestsPresenter } from './presenters/TeamJoinRequestsPresenter';
import { DriverTeamPresenter } from './presenters/DriverTeamPresenter';
import { AllLeaguesWithCapacityPresenter } from './presenters/AllLeaguesWithCapacityPresenter';
import { AllLeaguesWithCapacityAndScoringPresenter } from './presenters/AllLeaguesWithCapacityAndScoringPresenter';
import { LeagueStatsPresenter } from './presenters/LeagueStatsPresenter';
import { LeagueScoringConfigPresenter } from './presenters/LeagueScoringConfigPresenter';
import { LeagueFullConfigPresenter } from './presenters/LeagueFullConfigPresenter';
import { LeagueDriverSeasonStatsPresenter } from './presenters/LeagueDriverSeasonStatsPresenter';
import { LeagueStandingsPresenter } from './presenters/LeagueStandingsPresenter';
import { LeagueScoringPresetsPresenter } from './presenters/LeagueScoringPresetsPresenter';
import { RaceWithSOFPresenter } from './presenters/RaceWithSOFPresenter';
import { RaceProtestsPresenter } from './presenters/RaceProtestsPresenter';
import { RacePenaltiesPresenter } from './presenters/RacePenaltiesPresenter';
import { RaceRegistrationsPresenter } from './presenters/RaceRegistrationsPresenter';
import { DriverRegistrationStatusPresenter } from './presenters/DriverRegistrationStatusPresenter';
import { RaceDetailPresenter } from './presenters/RaceDetailPresenter';
import { RaceResultsDetailPresenter } from './presenters/RaceResultsDetailPresenter';
import { ImportRaceResultsPresenter } from './presenters/ImportRaceResultsPresenter';
import type { DriverRatingProvider } from '@gridpilot/racing/application';
import type { LeagueScoringPresetProvider } from '@gridpilot/racing/application/ports/LeagueScoringPresetProvider';
import { PreviewLeagueScheduleUseCase } from '@gridpilot/racing/application';
import { SponsorDashboardPresenter } from '../../lib/presenters/SponsorDashboardPresenter';
import { SponsorSponsorshipsPresenter } from '../../lib/presenters/SponsorSponsorshipsPresenter';
import { PendingSponsorshipRequestsPresenter } from '../../lib/presenters/PendingSponsorshipRequestsPresenter';
import { EntitySponsorshipPricingPresenter } from '../../lib/presenters/EntitySponsorshipPricingPresenter';
import { LeagueSchedulePreviewPresenter } from '../../lib/presenters/LeagueSchedulePreviewPresenter';
import { SponsorDashboardPresenter } from './presenters/SponsorDashboardPresenter';
import { SponsorSponsorshipsPresenter } from './presenters/SponsorSponsorshipsPresenter';
import { PendingSponsorshipRequestsPresenter } from './presenters/PendingSponsorshipRequestsPresenter';
import { EntitySponsorshipPricingPresenter } from './presenters/EntitySponsorshipPricingPresenter';
import { LeagueSchedulePreviewPresenter } from './presenters/LeagueSchedulePreviewPresenter';
import { DashboardOverviewPresenter } from './presenters/DashboardOverviewPresenter';
import { ProfileOverviewPresenter } from './presenters/ProfileOverviewPresenter';
// Testing support
import {
@@ -759,6 +773,8 @@ export function configureDIContainer(): void {
const gameRepository = container.resolve<IGameRepository>(DI_TOKENS.GameRepository);
const notificationRepository = container.resolve<INotificationRepository>(DI_TOKENS.NotificationRepository);
const notificationPreferenceRepository = container.resolve<INotificationPreferenceRepository>(DI_TOKENS.NotificationPreferenceRepository);
const feedRepository = container.resolve<IFeedRepository>(DI_TOKENS.FeedRepository);
const socialRepository = container.resolve<ISocialGraphRepository>(DI_TOKENS.SocialRepository);
// Register use cases - Racing
container.registerInstance(
@@ -770,12 +786,17 @@ export function configureDIContainer(): void {
DI_TOKENS.RegisterForRaceUseCase,
new RegisterForRaceUseCase(raceRegistrationRepository, leagueMembershipRepository)
);
container.registerInstance(
DI_TOKENS.WithdrawFromRaceUseCase,
new WithdrawFromRaceUseCase(raceRegistrationRepository)
);
container.registerInstance(
DI_TOKENS.CancelRaceUseCase,
new CancelRaceUseCase(raceRepository)
);
container.registerInstance(
DI_TOKENS.CreateLeagueWithSeasonAndScoringUseCase,
new CreateLeagueWithSeasonAndScoringUseCase(
@@ -1004,6 +1025,53 @@ export function configureDIContainer(): void {
new GetRacesPageDataUseCase(raceRepository, leagueRepository, racesPresenter)
);
const allRacesPagePresenter = new AllRacesPagePresenter();
container.registerInstance(
DI_TOKENS.GetAllRacesPageDataUseCase,
new GetAllRacesPageDataUseCase(raceRepository, leagueRepository, allRacesPagePresenter)
);
const raceDetailPresenter = new RaceDetailPresenter();
container.registerInstance(
DI_TOKENS.GetRaceDetailUseCase,
new GetRaceDetailUseCase(
raceRepository,
leagueRepository,
driverRepository,
raceRegistrationRepository,
resultRepository,
leagueMembershipRepository,
driverRatingProvider,
imageService,
raceDetailPresenter
)
);
const raceResultsDetailPresenter = new RaceResultsDetailPresenter();
container.registerInstance(
DI_TOKENS.GetRaceResultsDetailUseCase,
new GetRaceResultsDetailUseCase(
raceRepository,
leagueRepository,
resultRepository,
driverRepository,
penaltyRepository,
raceResultsDetailPresenter
)
);
const importRaceResultsPresenter = new ImportRaceResultsPresenter();
container.registerInstance(
DI_TOKENS.ImportRaceResultsUseCase,
new ImportRaceResultsUseCase(
raceRepository,
leagueRepository,
resultRepository,
standingRepository,
importRaceResultsPresenter
)
);
// Create services for driver leaderboard query
const rankingService = {
getAllDriverRankings: () => {
@@ -1060,6 +1128,78 @@ export function configureDIContainer(): void {
)
);
const getDriverStatsForDashboard = (driverId: string) => {
const stats = getDIContainer().resolve<Record<string, any>>(DI_TOKENS.DriverStats);
const stat = stats[driverId];
if (!stat) return null;
return {
rating: stat.rating ?? null,
wins: stat.wins ?? 0,
podiums: stat.podiums ?? 0,
totalRaces: stat.totalRaces ?? 0,
overallRank: stat.overallRank ?? null,
consistency: stat.consistency ?? null,
};
};
const getDriverStatsForProfile = (driverId: string) => {
const stats = getDIContainer().resolve<Record<string, any>>(DI_TOKENS.DriverStats);
const stat = stats[driverId];
if (!stat) return null;
return {
rating: stat.rating ?? null,
wins: stat.wins ?? 0,
podiums: stat.podiums ?? 0,
dnfs: stat.dnfs ?? 0,
totalRaces: stat.totalRaces ?? 0,
avgFinish: stat.avgFinish ?? null,
bestFinish: stat.bestFinish ?? null,
worstFinish: stat.worstFinish ?? null,
overallRank: stat.overallRank ?? null,
consistency: stat.consistency ?? null,
percentile: stat.percentile ?? null,
};
};
const dashboardOverviewPresenter = new DashboardOverviewPresenter();
container.registerInstance(
DI_TOKENS.GetDashboardOverviewUseCase,
new GetDashboardOverviewUseCase(
driverRepository,
raceRepository,
resultRepository,
leagueRepository,
standingRepository,
leagueMembershipRepository,
raceRegistrationRepository,
feedRepository,
socialRepository,
imageService,
getDriverStatsForDashboard,
dashboardOverviewPresenter
)
);
const profileOverviewPresenter = new ProfileOverviewPresenter();
container.registerInstance(
DI_TOKENS.GetProfileOverviewUseCase,
new GetProfileOverviewUseCase(
driverRepository,
teamRepository,
teamMembershipRepository,
socialRepository,
imageService,
getDriverStatsForProfile,
rankingService.getAllDriverRankings,
profileOverviewPresenter
)
);
container.registerInstance(
DI_TOKENS.UpdateDriverProfileUseCase,
new UpdateDriverProfileUseCase(driverRepository)
);
// Register use cases - Teams (Query-like with Presenters)
const allTeamsPresenter = new AllTeamsPresenter();
container.registerInstance(