resolve manual DTOs
This commit is contained in:
18
apps/api/src/domain/dashboard/DashboardController.ts
Normal file
18
apps/api/src/domain/dashboard/DashboardController.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { Controller, Get, Query } from '@nestjs/common';
|
||||
import { ApiTags, ApiResponse, ApiOperation, ApiQuery } from '@nestjs/swagger';
|
||||
import { DashboardService } from './DashboardService';
|
||||
import { DashboardOverviewDTO } from './dtos/DashboardOverviewDTO';
|
||||
|
||||
@ApiTags('dashboard')
|
||||
@Controller('dashboard')
|
||||
export class DashboardController {
|
||||
constructor(private readonly dashboardService: DashboardService) {}
|
||||
|
||||
@Get('overview')
|
||||
@ApiOperation({ summary: 'Get dashboard overview' })
|
||||
@ApiQuery({ name: 'driverId', description: 'Driver ID' })
|
||||
@ApiResponse({ status: 200, description: 'Dashboard overview', type: DashboardOverviewDTO })
|
||||
async getDashboardOverview(@Query('driverId') driverId: string): Promise<DashboardOverviewDTO> {
|
||||
return this.dashboardService.getDashboardOverview(driverId);
|
||||
}
|
||||
}
|
||||
11
apps/api/src/domain/dashboard/DashboardModule.ts
Normal file
11
apps/api/src/domain/dashboard/DashboardModule.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { DashboardService } from './DashboardService';
|
||||
import { DashboardController } from './DashboardController';
|
||||
import { DashboardProviders } from './DashboardProviders';
|
||||
|
||||
@Module({
|
||||
controllers: [DashboardController],
|
||||
providers: DashboardProviders,
|
||||
exports: [DashboardService],
|
||||
})
|
||||
export class DashboardModule {}
|
||||
23
apps/api/src/domain/dashboard/DashboardProviders.ts
Normal file
23
apps/api/src/domain/dashboard/DashboardProviders.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { Provider } from '@nestjs/common';
|
||||
import { DashboardService } from './DashboardService';
|
||||
|
||||
// Import core interfaces
|
||||
import type { Logger } from '@core/shared/application/Logger';
|
||||
|
||||
// Import concrete implementations
|
||||
import { ConsoleLogger } from '@adapters/logging/ConsoleLogger';
|
||||
|
||||
// Import use cases
|
||||
import { DashboardOverviewUseCase } from '@core/racing/application/use-cases/DashboardOverviewUseCase';
|
||||
|
||||
// Define injection tokens
|
||||
export const LOGGER_TOKEN = 'Logger';
|
||||
|
||||
export const DashboardProviders: Provider[] = [
|
||||
DashboardService,
|
||||
{
|
||||
provide: LOGGER_TOKEN,
|
||||
useClass: ConsoleLogger,
|
||||
},
|
||||
DashboardOverviewUseCase,
|
||||
];
|
||||
28
apps/api/src/domain/dashboard/DashboardService.ts
Normal file
28
apps/api/src/domain/dashboard/DashboardService.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { Injectable, Inject } from '@nestjs/common';
|
||||
import { DashboardOverviewUseCase } from '@core/racing/application/use-cases/DashboardOverviewUseCase';
|
||||
|
||||
// Core imports
|
||||
import type { Logger } from '@core/shared/application/Logger';
|
||||
|
||||
// Tokens
|
||||
import { LOGGER_TOKEN } from './DashboardProviders';
|
||||
|
||||
@Injectable()
|
||||
export class DashboardService {
|
||||
constructor(
|
||||
private readonly dashboardOverviewUseCase: DashboardOverviewUseCase,
|
||||
@Inject(LOGGER_TOKEN) private readonly logger: Logger,
|
||||
) {}
|
||||
|
||||
async getDashboardOverview(driverId: string): Promise<any> {
|
||||
this.logger.debug('[DashboardService] Getting dashboard overview:', { driverId });
|
||||
|
||||
const result = await this.dashboardOverviewUseCase.execute({ driverId });
|
||||
|
||||
if (result.isErr()) {
|
||||
throw new Error(result.error.details.message || 'Failed to get dashboard overview');
|
||||
}
|
||||
|
||||
return result.value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsString, IsNumber, IsOptional } from 'class-validator';
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsString, IsOptional } from 'class-validator';
|
||||
|
||||
export type DashboardFeedItemType =
|
||||
| 'friend-joined-league'
|
||||
| 'friend-joined-team'
|
||||
| 'friend-finished-race'
|
||||
| 'friend-new-personal-best'
|
||||
| 'new-race-scheduled'
|
||||
| 'new-result-posted'
|
||||
| 'league-highlight';
|
||||
|
||||
export class DashboardFeedItemSummaryDTO {
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
id!: string;
|
||||
|
||||
@ApiProperty({
|
||||
enum: [
|
||||
'friend-joined-league',
|
||||
'friend-joined-team',
|
||||
'friend-finished-race',
|
||||
'friend-new-personal-best',
|
||||
'new-race-scheduled',
|
||||
'new-result-posted',
|
||||
'league-highlight',
|
||||
],
|
||||
})
|
||||
type!: DashboardFeedItemType;
|
||||
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
headline!: string;
|
||||
|
||||
@ApiProperty({ required: false })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
body?: string;
|
||||
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
timestamp!: string;
|
||||
|
||||
@ApiProperty({ required: false })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
ctaLabel?: string;
|
||||
|
||||
@ApiProperty({ required: false })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
ctaHref?: string;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsNumber } from 'class-validator';
|
||||
import { DashboardFeedItemSummaryDTO } from './DashboardFeedItemSummaryDTO';
|
||||
|
||||
export class DashboardFeedSummaryDTO {
|
||||
@ApiProperty()
|
||||
@IsNumber()
|
||||
notificationCount!: number;
|
||||
|
||||
@ApiProperty({ type: [DashboardFeedItemSummaryDTO] })
|
||||
items!: DashboardFeedItemSummaryDTO[];
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsString } from 'class-validator';
|
||||
|
||||
export class DashboardFriendSummaryDTO {
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
id!: string;
|
||||
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
name!: string;
|
||||
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
country!: string;
|
||||
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
avatarUrl!: string;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsString, IsNumber } from 'class-validator';
|
||||
|
||||
export class DashboardLeagueStandingSummaryDTO {
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
leagueId!: string;
|
||||
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
leagueName!: string;
|
||||
|
||||
@ApiProperty()
|
||||
@IsNumber()
|
||||
position!: number;
|
||||
|
||||
@ApiProperty()
|
||||
@IsNumber()
|
||||
totalDrivers!: number;
|
||||
|
||||
@ApiProperty()
|
||||
@IsNumber()
|
||||
points!: number;
|
||||
}
|
||||
41
apps/api/src/domain/dashboard/dtos/DashboardOverviewDTO.ts
Normal file
41
apps/api/src/domain/dashboard/dtos/DashboardOverviewDTO.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsNumber, IsOptional } from 'class-validator';
|
||||
import { DashboardDriverSummaryDTO } from '../../../race/dtos/DashboardDriverSummaryDTO';
|
||||
import { DashboardRaceSummaryDTO } from '../../../race/dtos/DashboardRaceSummaryDTO';
|
||||
import { DashboardRecentResultDTO } from '../../../race/dtos/DashboardRecentResultDTO';
|
||||
import { DashboardLeagueStandingSummaryDTO } from '../../../race/dtos/DashboardLeagueStandingSummaryDTO';
|
||||
import { DashboardFeedSummaryDTO } from '../../../race/dtos/DashboardFeedSummaryDTO';
|
||||
import { DashboardFriendSummaryDTO } from '../../../race/dtos/DashboardFriendSummaryDTO';
|
||||
|
||||
export class DashboardOverviewDTO {
|
||||
@ApiProperty({ nullable: true })
|
||||
currentDriver!: DashboardDriverSummaryDTO | null;
|
||||
|
||||
@ApiProperty({ type: [DashboardRaceSummaryDTO] })
|
||||
myUpcomingRaces!: DashboardRaceSummaryDTO[];
|
||||
|
||||
@ApiProperty({ type: [DashboardRaceSummaryDTO] })
|
||||
otherUpcomingRaces!: DashboardRaceSummaryDTO[];
|
||||
|
||||
@ApiProperty({ type: [DashboardRaceSummaryDTO] })
|
||||
upcomingRaces!: DashboardRaceSummaryDTO[];
|
||||
|
||||
@ApiProperty()
|
||||
@IsNumber()
|
||||
activeLeaguesCount!: number;
|
||||
|
||||
@ApiProperty({ nullable: true })
|
||||
nextRace!: DashboardRaceSummaryDTO | null;
|
||||
|
||||
@ApiProperty({ type: [DashboardRecentResultDTO] })
|
||||
recentResults!: DashboardRecentResultDTO[];
|
||||
|
||||
@ApiProperty({ type: [DashboardLeagueStandingSummaryDTO] })
|
||||
leagueStandingsSummaries!: DashboardLeagueStandingSummaryDTO[];
|
||||
|
||||
@ApiProperty()
|
||||
feedSummary!: DashboardFeedSummaryDTO;
|
||||
|
||||
@ApiProperty({ type: [DashboardFriendSummaryDTO] })
|
||||
friends!: DashboardFriendSummaryDTO[];
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsString, IsBoolean } from 'class-validator';
|
||||
|
||||
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({ enum: ['scheduled', 'running', 'completed', 'cancelled'] })
|
||||
@IsString()
|
||||
status!: 'scheduled' | 'running' | 'completed' | 'cancelled';
|
||||
|
||||
@ApiProperty()
|
||||
@IsBoolean()
|
||||
isMyLeague!: boolean;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsString, IsNumber } from 'class-validator';
|
||||
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user