This commit is contained in:
2025-12-12 01:11:36 +01:00
parent ec3ddc3a5c
commit 6a88fe93ab
125 changed files with 1513 additions and 803 deletions

View File

@@ -3,13 +3,14 @@ import type { Season } from '../../domain/entities/Season';
import type { LeagueScoringConfig } from '../../domain/entities/LeagueScoringConfig';
import type { Game } from '../../domain/entities/Game';
import type { LeagueScoringPresetDTO } from '../ports/LeagueScoringPresetProvider';
import type { Presenter } from '@gridpilot/shared/presentation';
export interface LeagueSummaryViewModel {
id: string;
name: string;
description: string;
ownerId: string;
createdAt: Date;
createdAt: string;
maxDrivers: number;
usedDriverSlots: number;
maxTeams?: number;
@@ -20,7 +21,7 @@ export interface LeagueSummaryViewModel {
scoring?: {
gameId: string;
gameName: string;
primaryChampionshipType: string;
primaryChampionshipType: 'driver' | 'team' | 'nations' | 'trophy';
scoringPresetId: string;
scoringPresetName: string;
dropPolicySummary: string;
@@ -42,6 +43,5 @@ export interface LeagueEnrichedData {
preset?: LeagueScoringPresetDTO;
}
export interface IAllLeaguesWithCapacityAndScoringPresenter {
present(enrichedLeagues: LeagueEnrichedData[]): AllLeaguesWithCapacityAndScoringViewModel;
}
export interface IAllLeaguesWithCapacityAndScoringPresenter
extends Presenter<LeagueEnrichedData[], AllLeaguesWithCapacityAndScoringViewModel> {}

View File

@@ -1,4 +1,5 @@
import type { League } from '../../domain/entities/League';
import type { Presenter } from '@gridpilot/shared/presentation';
export interface LeagueWithCapacityViewModel {
id: string;
@@ -24,9 +25,10 @@ export interface AllLeaguesWithCapacityViewModel {
totalCount: number;
}
export interface IAllLeaguesWithCapacityPresenter {
present(
leagues: League[],
memberCounts: Map<string, number>
): AllLeaguesWithCapacityViewModel;
}
export interface AllLeaguesWithCapacityResultDTO {
leagues: League[];
memberCounts: Map<string, number>;
}
export interface IAllLeaguesWithCapacityPresenter
extends Presenter<AllLeaguesWithCapacityResultDTO, AllLeaguesWithCapacityViewModel> {}

View File

@@ -1,3 +1,5 @@
import type { Presenter } from '@gridpilot/shared/presentation';
export type AllRacesStatus = 'scheduled' | 'running' | 'completed' | 'cancelled' | 'all';
export interface AllRacesListItemViewModel {
@@ -21,7 +23,7 @@ export interface AllRacesPageViewModel {
filters: AllRacesFilterOptionsViewModel;
}
export interface IAllRacesPagePresenter {
present(viewModel: AllRacesPageViewModel): void;
getViewModel(): AllRacesPageViewModel | null;
}
export type AllRacesPageResultDTO = AllRacesPageViewModel;
export interface IAllRacesPagePresenter
extends Presenter<AllRacesPageResultDTO, AllRacesPageViewModel> {}

View File

@@ -1,4 +1,3 @@
import type { Team } from '../../domain/entities/Team';
import type { Presenter } from '@gridpilot/shared/presentation';
export interface TeamListItemViewModel {
@@ -19,7 +18,16 @@ export interface AllTeamsViewModel {
}
export interface AllTeamsResultDTO {
teams: Array<Team & { memberCount: number }>;
teams: Array<{
id: string;
name: string;
tag: string;
description: string;
ownerId: string;
leagues: string[];
createdAt: Date;
memberCount: number;
}>;
}
export interface IAllTeamsPresenter

View File

@@ -1,3 +1,5 @@
import type { Presenter } from '@gridpilot/shared/presentation';
export interface DashboardDriverSummaryViewModel {
id: string;
name: string;
@@ -82,7 +84,7 @@ export interface DashboardOverviewViewModel {
friends: DashboardFriendSummaryViewModel[];
}
export interface IDashboardOverviewPresenter {
present(viewModel: DashboardOverviewViewModel): void;
getViewModel(): DashboardOverviewViewModel | null;
}
export type DashboardOverviewResultDTO = DashboardOverviewViewModel;
export interface IDashboardOverviewPresenter
extends Presenter<DashboardOverviewResultDTO, DashboardOverviewViewModel> {}

View File

@@ -1,5 +1,6 @@
import type { Driver } from '../../domain/entities/Driver';
import type { SkillLevel } from '../../domain/services/SkillLevelService';
import type { Presenter } from '@gridpilot/shared/presentation';
export type { SkillLevel };
@@ -24,13 +25,21 @@ export interface DriversLeaderboardViewModel {
activeCount: number;
}
export interface IDriversLeaderboardPresenter {
present(
drivers: Driver[],
rankings: Array<{ driverId: string; rating: number; overallRank: number }>,
stats: Record<string, { rating: number; wins: number; podiums: number; totalRaces: number; overallRank: number }>,
avatarUrls: Record<string, string>
): DriversLeaderboardViewModel;
export interface DriversLeaderboardResultDTO {
drivers: Driver[];
rankings: Array<{ driverId: string; rating: number; overallRank: number | null }>;
stats: Record<
string,
{
rating: number;
wins: number;
podiums: number;
totalRaces: number;
overallRank: number | null;
}
>;
avatarUrls: Record<string, string>;
}
getViewModel(): DriversLeaderboardViewModel;
}
export interface IDriversLeaderboardPresenter
extends Presenter<DriversLeaderboardResultDTO, DriversLeaderboardViewModel> {}

View File

@@ -1,3 +1,5 @@
import type { Presenter } from '@gridpilot/shared/presentation';
export interface LeagueDriverSeasonStatsItemViewModel {
leagueId: string;
driverId: string;
@@ -24,18 +26,18 @@ export interface LeagueDriverSeasonStatsViewModel {
stats: LeagueDriverSeasonStatsItemViewModel[];
}
export interface ILeagueDriverSeasonStatsPresenter {
present(
leagueId: string,
standings: Array<{
driverId: string;
position: number;
points: number;
racesCompleted: number;
}>,
penalties: Map<string, { baseDelta: number; bonusDelta: number }>,
driverResults: Map<string, Array<{ position: number }>>,
driverRatings: Map<string, { rating: number | null; ratingChange: number | null }>
): LeagueDriverSeasonStatsViewModel;
getViewModel(): LeagueDriverSeasonStatsViewModel;
}
export interface LeagueDriverSeasonStatsResultDTO {
leagueId: string;
standings: Array<{
driverId: string;
position: number;
points: number;
racesCompleted: number;
}>;
penalties: Map<string, { baseDelta: number; bonusDelta: number }>;
driverResults: Map<string, Array<{ position: number }>>;
driverRatings: Map<string, { rating: number | null; ratingChange: number | null }>;
}
export interface ILeagueDriverSeasonStatsPresenter
extends Presenter<LeagueDriverSeasonStatsResultDTO, LeagueDriverSeasonStatsViewModel> {}

View File

@@ -1,5 +1,6 @@
import type { ChampionshipConfig } from '../../domain/types/ChampionshipConfig';
import type { LeagueScoringPresetDTO } from '../ports/LeagueScoringPresetProvider';
import type { Presenter } from '@gridpilot/shared/presentation';
export interface LeagueScoringChampionshipViewModel {
id: string;
@@ -32,7 +33,5 @@ export interface LeagueScoringConfigData {
championships: ChampionshipConfig[];
}
export interface ILeagueScoringConfigPresenter {
present(data: LeagueScoringConfigData): LeagueScoringConfigViewModel;
getViewModel(): LeagueScoringConfigViewModel;
}
export interface ILeagueScoringConfigPresenter
extends Presenter<LeagueScoringConfigData, LeagueScoringConfigViewModel> {}

View File

@@ -1,4 +1,5 @@
import type { SessionType, RaceStatus } from '../../domain/entities/Race';
import type { Presenter } from '@gridpilot/shared/presentation';
export interface RaceDetailEntryViewModel {
id: string;
@@ -55,7 +56,5 @@ export interface RaceDetailViewModel {
error?: string;
}
export interface IRaceDetailPresenter {
present(viewModel: RaceDetailViewModel): RaceDetailViewModel;
getViewModel(): RaceDetailViewModel | null;
}
export interface IRaceDetailPresenter
extends Presenter<RaceDetailViewModel, RaceDetailViewModel> {}

View File

@@ -1,4 +1,4 @@
import type { PenaltyType, PenaltyStatus } from '../../domain/entities/Penalty';
import type { Penalty, PenaltyType, PenaltyStatus } from '../../domain/entities/Penalty';
import type { Presenter } from '@gridpilot/shared/presentation/Presenter';
export interface RacePenaltyViewModel {
@@ -24,21 +24,7 @@ export interface RacePenaltiesViewModel {
}
export interface RacePenaltiesResultDTO {
penalties: Array<{
id: string;
raceId: string;
driverId: string;
type: PenaltyType;
value?: number;
reason: string;
protestId?: string;
issuedBy: string;
status: PenaltyStatus;
issuedAt: Date;
appliedAt?: Date;
notes?: string;
getDescription(): string;
}>;
penalties: Penalty[];
driverMap: Map<string, string>;
}

View File

@@ -1,4 +1,4 @@
import type { ProtestStatus, ProtestIncident } from '../../domain/entities/Protest';
import type { Protest, ProtestStatus, ProtestIncident } from '../../domain/entities/Protest';
import type { Presenter } from '@gridpilot/shared/presentation/Presenter';
export interface RaceProtestViewModel {
@@ -24,20 +24,7 @@ export interface RaceProtestsViewModel {
}
export interface RaceProtestsResultDTO {
protests: Array<{
id: string;
raceId: string;
protestingDriverId: string;
accusedDriverId: string;
incident: ProtestIncident;
comment?: string;
proofVideoUrl?: string;
status: ProtestStatus;
reviewedBy?: string;
decisionNotes?: string;
filedAt: Date;
reviewedAt?: Date;
}>;
protests: Protest[];
driverMap: Map<string, string>;
}

View File

@@ -1,9 +1,13 @@
import type { Presenter } from '@gridpilot/shared/presentation';
export interface RaceRegistrationsViewModel {
registeredDriverIds: string[];
count: number;
}
export interface IRaceRegistrationsPresenter {
present(registeredDriverIds: string[]): RaceRegistrationsViewModel;
getViewModel(): RaceRegistrationsViewModel;
}
export interface RaceRegistrationsResultDTO {
registeredDriverIds: string[];
}
export interface IRaceRegistrationsPresenter
extends Presenter<RaceRegistrationsResultDTO, RaceRegistrationsViewModel> {}

View File

@@ -2,6 +2,7 @@ import type { RaceStatus } from '../../domain/entities/Race';
import type { Result } from '../../domain/entities/Result';
import type { Driver } from '../../domain/entities/Driver';
import type { PenaltyType } from '../../domain/entities/Penalty';
import type { Presenter } from '@gridpilot/shared/presentation';
export interface RaceResultsHeaderViewModel {
id: string;
@@ -28,13 +29,11 @@ export interface RaceResultsDetailViewModel {
results: Result[];
drivers: Driver[];
penalties: RaceResultsPenaltySummaryViewModel[];
pointsSystem: Record<number, number>;
pointsSystem?: Record<number, number>;
fastestLapTime?: number;
currentDriverId?: string;
error?: string;
}
export interface IRaceResultsDetailPresenter {
present(viewModel: RaceResultsDetailViewModel): RaceResultsDetailViewModel;
getViewModel(): RaceResultsDetailViewModel | null;
}
export interface IRaceResultsDetailPresenter
extends Presenter<RaceResultsDetailViewModel, RaceResultsDetailViewModel> {}

View File

@@ -1,3 +1,5 @@
import type { Presenter } from '@gridpilot/shared/presentation';
export interface RaceWithSOFViewModel {
id: string;
leagueId: string;
@@ -14,21 +16,21 @@ export interface RaceWithSOFViewModel {
participantCount: number;
}
export interface IRaceWithSOFPresenter {
present(
raceId: string,
leagueId: string,
scheduledAt: Date,
track: string,
trackId: string,
car: string,
carId: string,
sessionType: string,
status: string,
strengthOfField: number | null,
registeredCount: number,
maxParticipants: number,
participantCount: number
): RaceWithSOFViewModel;
getViewModel(): RaceWithSOFViewModel;
}
export interface RaceWithSOFResultDTO {
raceId: string;
leagueId: string;
scheduledAt: Date;
track: string;
trackId: string;
car: string;
carId: string;
sessionType: string;
status: string;
strengthOfField: number | null;
registeredCount: number;
maxParticipants: number;
participantCount: number;
}
export interface IRaceWithSOFPresenter
extends Presenter<RaceWithSOFResultDTO, RaceWithSOFViewModel> {}

View File

@@ -1,3 +1,5 @@
import type { Presenter } from '@gridpilot/shared/presentation';
export interface RaceListItemViewModel {
id: string;
track: string;
@@ -25,7 +27,9 @@ export interface RacesPageViewModel {
recentResults: RaceListItemViewModel[];
}
export interface IRacesPagePresenter {
present(races: any[]): void;
getViewModel(): RacesPageViewModel;
}
export interface RacesPageResultDTO {
races: any[];
}
export interface IRacesPagePresenter
extends Presenter<RacesPageResultDTO, RacesPageViewModel> {}

View File

@@ -1,5 +1,7 @@
import type { SponsoredLeagueDTO, SponsorDashboardDTO } from '../use-cases/GetSponsorDashboardUseCase';
import type { SponsorDashboardDTO } from '../use-cases/GetSponsorDashboardUseCase';
import type { Presenter } from '@gridpilot/shared/presentation';
export interface ISponsorDashboardPresenter {
present(data: SponsorDashboardDTO | null): void;
}
export type SponsorDashboardViewModel = SponsorDashboardDTO | null;
export interface ISponsorDashboardPresenter
extends Presenter<SponsorDashboardDTO | null, SponsorDashboardViewModel> {}

View File

@@ -1,5 +1,7 @@
import type { SponsorSponsorshipsDTO } from '../use-cases/GetSponsorSponsorshipsUseCase';
import type { Presenter } from '@gridpilot/shared/presentation';
export interface ISponsorSponsorshipsPresenter {
present(data: SponsorSponsorshipsDTO | null): void;
}
export type SponsorSponsorshipsViewModel = SponsorSponsorshipsDTO | null;
export interface ISponsorSponsorshipsPresenter
extends Presenter<SponsorSponsorshipsDTO | null, SponsorSponsorshipsViewModel> {}

View File

@@ -1,5 +1,6 @@
import type { Team } from '../../domain/entities/Team';
import type { TeamMembership } from '../../domain/types/TeamMembership';
import type { Presenter } from '@gridpilot/shared/presentation';
export interface TeamDetailsViewModel {
team: {
@@ -9,9 +10,7 @@ export interface TeamDetailsViewModel {
description: string;
ownerId: string;
leagues: string[];
specialization?: 'endurance' | 'sprint' | 'mixed';
region?: string;
languages?: string[];
createdAt: string;
};
membership: {
role: 'owner' | 'manager' | 'member';
@@ -21,10 +20,11 @@ export interface TeamDetailsViewModel {
canManage: boolean;
}
export interface ITeamDetailsPresenter {
present(
team: Team,
membership: TeamMembership | null,
driverId: string
): TeamDetailsViewModel;
}
export interface TeamDetailsResultDTO {
team: Team;
membership: TeamMembership | null;
driverId: string;
}
export interface ITeamDetailsPresenter
extends Presenter<TeamDetailsResultDTO, TeamDetailsViewModel> {}