refactor core presenters

This commit is contained in:
2025-12-19 19:42:19 +01:00
parent 8116fe888f
commit 94fc538f44
228 changed files with 2817 additions and 3097 deletions

View File

@@ -1,6 +1,8 @@
import { Injectable, Inject } from '@nestjs/common';
import { plainToClass } from 'class-transformer';
import { DashboardOverviewUseCase } from '@core/racing/application/use-cases/DashboardOverviewUseCase';
import type { DashboardOverviewViewModel } from '@core/racing/application/presenters/IDashboardOverviewPresenter';
import type { DashboardOverviewOutputPort } from '@core/racing/application/ports/output/DashboardOverviewOutputPort';
import { DashboardOverviewDTO } from './dtos/DashboardOverviewDTO';
// Core imports
import type { Logger } from '@core/shared/application/Logger';
@@ -62,7 +64,7 @@ export class DashboardService {
);
}
async getDashboardOverview(driverId: string): Promise<DashboardOverviewViewModel> {
async getDashboardOverview(driverId: string): Promise<DashboardOverviewDTO> {
this.logger.debug('[DashboardService] Getting dashboard overview:', { driverId });
const result = await this.dashboardOverviewUseCase.execute({ driverId });
@@ -71,6 +73,6 @@ export class DashboardService {
throw new Error(result.error?.message || 'Failed to get dashboard overview');
}
return result.value!;
return plainToClass(DashboardOverviewDTO, result.value);
}
}

View File

@@ -1,23 +1,224 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsNumber } from 'class-validator';
import { DashboardDriverSummaryDTO } from './DashboardDriverSummaryDTO';
import { DashboardRaceSummaryDTO } from './DashboardRaceSummaryDTO';
import { DashboardRecentResultDTO } from './DashboardRecentResultDTO';
import { DashboardLeagueStandingSummaryDTO } from './DashboardLeagueStandingSummaryDTO';
import { DashboardFeedSummaryDTO } from './DashboardFeedSummaryDTO';
import { DashboardFriendSummaryDTO } from './DashboardFriendSummaryDTO';
import { IsString, IsNumber, IsOptional, IsBoolean, IsArray, ValidateNested } from 'class-validator';
import { Type } from 'class-transformer';
export class DashboardDriverSummaryDTO {
@ApiProperty()
@IsString()
id!: string;
@ApiProperty()
@IsString()
name!: string;
@ApiProperty()
@IsString()
country!: string;
@ApiProperty()
@IsString()
avatarUrl!: string;
@ApiProperty({ nullable: true })
@IsOptional()
@IsNumber()
rating?: number | null;
@ApiProperty({ nullable: true })
@IsOptional()
@IsNumber()
globalRank?: number | null;
@ApiProperty()
@IsNumber()
totalRaces!: number;
@ApiProperty()
@IsNumber()
wins!: number;
@ApiProperty()
@IsNumber()
podiums!: number;
@ApiProperty({ nullable: true })
@IsOptional()
@IsNumber()
consistency?: number | null;
}
export class DashboardRaceSummaryDTO {
@ApiProperty()
@IsString()
id!: string;
@ApiProperty()
@IsString()
leagueId!: string;
@ApiProperty()
@IsString()
leagueName!: string;
@ApiProperty()
@IsString()
track!: string;
@ApiProperty()
@IsString()
car!: string;
@ApiProperty()
@IsString()
scheduledAt!: string;
@ApiProperty()
@IsString()
status!: 'scheduled' | 'running' | 'completed' | 'cancelled';
@ApiProperty()
@IsBoolean()
isMyLeague!: boolean;
}
export class DashboardRecentResultDTO {
@ApiProperty()
@IsString()
raceId!: string;
@ApiProperty()
@IsString()
raceName!: string;
@ApiProperty()
@IsString()
leagueId!: string;
@ApiProperty()
@IsString()
leagueName!: string;
@ApiProperty()
@IsString()
finishedAt!: string;
@ApiProperty()
@IsNumber()
position!: number;
@ApiProperty()
@IsNumber()
incidents!: number;
}
export class DashboardLeagueStandingSummaryDTO {
@ApiProperty()
@IsString()
leagueId!: string;
@ApiProperty()
@IsString()
leagueName!: string;
@ApiProperty()
@IsNumber()
position!: number;
@ApiProperty()
@IsNumber()
totalDrivers!: number;
@ApiProperty()
@IsNumber()
points!: number;
}
export class DashboardFeedItemSummaryDTO {
@ApiProperty()
@IsString()
id!: string;
@ApiProperty()
@IsString()
type!: string;
@ApiProperty()
@IsString()
headline!: string;
@ApiProperty({ nullable: true })
@IsOptional()
@IsString()
body?: string;
@ApiProperty()
@IsString()
timestamp!: string;
@ApiProperty({ nullable: true })
@IsOptional()
@IsString()
ctaLabel?: string;
@ApiProperty({ nullable: true })
@IsOptional()
@IsString()
ctaHref?: string;
}
export class DashboardFeedSummaryDTO {
@ApiProperty()
@IsNumber()
notificationCount!: number;
@ApiProperty({ type: [DashboardFeedItemSummaryDTO] })
@IsArray()
@ValidateNested({ each: true })
@Type(() => DashboardFeedItemSummaryDTO)
items!: DashboardFeedItemSummaryDTO[];
}
export class DashboardFriendSummaryDTO {
@ApiProperty()
@IsString()
id!: string;
@ApiProperty()
@IsString()
name!: string;
@ApiProperty()
@IsString()
country!: string;
@ApiProperty()
@IsString()
avatarUrl!: string;
}
export class DashboardOverviewDTO {
@ApiProperty({ nullable: true })
currentDriver!: DashboardDriverSummaryDTO | null;
@IsOptional()
@ValidateNested()
@Type(() => DashboardDriverSummaryDTO)
currentDriver?: DashboardDriverSummaryDTO | null;
@ApiProperty({ type: [DashboardRaceSummaryDTO] })
@IsArray()
@ValidateNested({ each: true })
@Type(() => DashboardRaceSummaryDTO)
myUpcomingRaces!: DashboardRaceSummaryDTO[];
@ApiProperty({ type: [DashboardRaceSummaryDTO] })
@IsArray()
@ValidateNested({ each: true })
@Type(() => DashboardRaceSummaryDTO)
otherUpcomingRaces!: DashboardRaceSummaryDTO[];
@ApiProperty({ type: [DashboardRaceSummaryDTO] })
@IsArray()
@ValidateNested({ each: true })
@Type(() => DashboardRaceSummaryDTO)
upcomingRaces!: DashboardRaceSummaryDTO[];
@ApiProperty()
@@ -25,17 +226,31 @@ export class DashboardOverviewDTO {
activeLeaguesCount!: number;
@ApiProperty({ nullable: true })
nextRace!: DashboardRaceSummaryDTO | null;
@IsOptional()
@ValidateNested()
@Type(() => DashboardRaceSummaryDTO)
nextRace?: DashboardRaceSummaryDTO | null;
@ApiProperty({ type: [DashboardRecentResultDTO] })
@IsArray()
@ValidateNested({ each: true })
@Type(() => DashboardRecentResultDTO)
recentResults!: DashboardRecentResultDTO[];
@ApiProperty({ type: [DashboardLeagueStandingSummaryDTO] })
@IsArray()
@ValidateNested({ each: true })
@Type(() => DashboardLeagueStandingSummaryDTO)
leagueStandingsSummaries!: DashboardLeagueStandingSummaryDTO[];
@ApiProperty()
@ValidateNested()
@Type(() => DashboardFeedSummaryDTO)
feedSummary!: DashboardFeedSummaryDTO;
@ApiProperty({ type: [DashboardFriendSummaryDTO] })
@IsArray()
@ValidateNested({ each: true })
@Type(() => DashboardFriendSummaryDTO)
friends!: DashboardFriendSummaryDTO[];
}