This commit is contained in:
2025-12-17 14:04:11 +01:00
parent 1ea9c9649f
commit daa4bb6576
238 changed files with 4263 additions and 1752 deletions

View File

@@ -90,4 +90,11 @@ export class TeamController {
async getDriverTeam(@Param('driverId') driverId: string): Promise<DriverTeamViewModel | null> {
return this.teamService.getDriverTeam({ teamId: '', driverId });
}
@Get('leaderboard')
@ApiOperation({ summary: 'Get teams leaderboard' })
@ApiResponse({ status: 200, description: 'Teams leaderboard' })
async getTeamsLeaderboard(): Promise<any> {
return this.teamService.getTeamsLeaderboard();
}
}

View File

@@ -24,11 +24,13 @@ import { CreateTeamUseCase } from '@core/racing/application/use-cases/CreateTeam
import { UpdateTeamUseCase } from '@core/racing/application/use-cases/UpdateTeamUseCase';
import { ApproveTeamJoinRequestUseCase } from '@core/racing/application/use-cases/ApproveTeamJoinRequestUseCase';
import { RejectTeamJoinRequestUseCase } from '@core/racing/application/use-cases/RejectTeamJoinRequestUseCase';
import { GetTeamsLeaderboardUseCase } from '@core/racing/application/use-cases/GetTeamsLeaderboardUseCase';
// Import presenters for use case initialization
import { DriverTeamPresenter } from './presenters/DriverTeamPresenter';
import { TeamMembersPresenter } from './presenters/TeamMembersPresenter';
import { TeamJoinRequestsPresenter } from './presenters/TeamJoinRequestsPresenter';
import { TeamsLeaderboardPresenter } from './presenters/TeamsLeaderboardPresenter';
// Tokens
export const TEAM_REPOSITORY_TOKEN = 'ITeamRepository';
@@ -44,6 +46,7 @@ export const TEAM_CREATE_USE_CASE_TOKEN = 'CreateTeamUseCase';
export const TEAM_UPDATE_USE_CASE_TOKEN = 'UpdateTeamUseCase';
export const TEAM_APPROVE_JOIN_REQUEST_USE_CASE_TOKEN = 'ApproveTeamJoinRequestUseCase';
export const TEAM_REJECT_JOIN_REQUEST_USE_CASE_TOKEN = 'RejectTeamJoinRequestUseCase';
export const TEAM_GET_LEADERBOARD_USE_CASE_TOKEN = 'GetTeamsLeaderboardUseCase';
export const TEAM_LOGGER_TOKEN = 'Logger';
// Simple image service implementation for team module
@@ -150,4 +153,14 @@ export const TeamProviders: Provider[] = [
new RejectTeamJoinRequestUseCase(membershipRepo),
inject: [TEAM_MEMBERSHIP_REPOSITORY_TOKEN],
},
{
provide: TEAM_GET_LEADERBOARD_USE_CASE_TOKEN,
useFactory: (
teamRepo: ITeamRepository,
membershipRepo: ITeamMembershipRepository,
driverRepo: IDriverRepository,
logger: Logger,
) => new GetTeamsLeaderboardUseCase(teamRepo, membershipRepo, driverRepo, () => null, logger),
inject: [TEAM_REPOSITORY_TOKEN, TEAM_MEMBERSHIP_REPOSITORY_TOKEN, DRIVER_REPOSITORY_TOKEN, TEAM_LOGGER_TOKEN],
},
];

View File

@@ -33,6 +33,7 @@ import {
TEAM_UPDATE_USE_CASE_TOKEN,
TEAM_APPROVE_JOIN_REQUEST_USE_CASE_TOKEN,
TEAM_REJECT_JOIN_REQUEST_USE_CASE_TOKEN,
TEAM_GET_LEADERBOARD_USE_CASE_TOKEN,
TEAM_LOGGER_TOKEN
} from './TeamProviders';
@@ -48,6 +49,7 @@ export class TeamService {
@Inject(TEAM_UPDATE_USE_CASE_TOKEN) private readonly updateTeamUseCase: UpdateTeamUseCase,
@Inject(TEAM_APPROVE_JOIN_REQUEST_USE_CASE_TOKEN) private readonly approveTeamJoinRequestUseCase: ApproveTeamJoinRequestUseCase,
@Inject(TEAM_REJECT_JOIN_REQUEST_USE_CASE_TOKEN) private readonly rejectTeamJoinRequestUseCase: RejectTeamJoinRequestUseCase,
@Inject(TEAM_GET_LEADERBOARD_USE_CASE_TOKEN) private readonly getTeamsLeaderboardUseCase: GetTeamsLeaderboardUseCase,
@Inject(TEAM_LOGGER_TOKEN) private readonly logger: Logger,
) {}
@@ -165,4 +167,15 @@ export class TeamService {
throw error;
}
}
async getTeamsLeaderboard(): Promise<any> {
this.logger.debug('[TeamService] Fetching teams leaderboard');
const result = await this.getTeamsLeaderboardUseCase.execute();
if (result.isErr()) {
this.logger.error(`Error fetching teams leaderboard: ${result.error}`);
throw new Error('Failed to fetch teams leaderboard');
}
return result.value;
}
}

View File

@@ -0,0 +1,32 @@
import { ITeamsLeaderboardPresenter, TeamsLeaderboardResultDTO, TeamsLeaderboardViewModel } from '@core/racing/application/presenters/ITeamsLeaderboardPresenter';
export class TeamsLeaderboardPresenter implements ITeamsLeaderboardPresenter {
private result: TeamsLeaderboardViewModel | null = null;
reset() {
this.result = null;
}
present(dto: TeamsLeaderboardResultDTO) {
this.result = {
teams: dto.teams as any, // Cast to match the view model
recruitingCount: dto.recruitingCount,
groupsBySkillLevel: {
beginner: [],
intermediate: [],
advanced: [],
pro: [],
},
topTeams: dto.teams.slice(0, 10) as any,
};
}
getViewModel(): TeamsLeaderboardViewModel | null {
return this.result;
}
get viewModel(): TeamsLeaderboardViewModel {
if (!this.result) throw new Error('Presenter not presented');
return this.result;
}
}