website refactor
This commit is contained in:
@@ -5,6 +5,7 @@ import { TeamService } from './TeamService';
|
||||
import { CreateTeamInputDTO } from './dtos/CreateTeamInputDTO';
|
||||
import { CreateTeamOutputDTO } from './dtos/CreateTeamOutputDTO';
|
||||
import { GetAllTeamsOutputDTO } from './dtos/GetAllTeamsOutputDTO';
|
||||
import { GetTeamsLeaderboardOutputDTO } from './dtos/GetTeamsLeaderboardOutputDTO';
|
||||
import { GetDriverTeamOutputDTO } from './dtos/GetDriverTeamOutputDTO';
|
||||
import { GetTeamDetailsOutputDTO } from './dtos/GetTeamDetailsOutputDTO';
|
||||
import { GetTeamJoinRequestsOutputDTO } from './dtos/GetTeamJoinRequestsOutputDTO';
|
||||
@@ -32,6 +33,14 @@ export class TeamController {
|
||||
return await this.teamService.getAll();
|
||||
}
|
||||
|
||||
@Public()
|
||||
@Get('leaderboard')
|
||||
@ApiOperation({ summary: 'Get teams leaderboard' })
|
||||
@ApiResponse({ status: 200, description: 'Teams leaderboard data', type: GetTeamsLeaderboardOutputDTO })
|
||||
async getLeaderboard(): Promise<GetTeamsLeaderboardOutputDTO> {
|
||||
return await this.teamService.getLeaderboard();
|
||||
}
|
||||
|
||||
@Public()
|
||||
@Get(':teamId')
|
||||
@ApiOperation({ summary: 'Get team details' })
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
TEAM_REPOSITORY_TOKEN,
|
||||
TEAM_STATS_REPOSITORY_TOKEN,
|
||||
UPDATE_TEAM_USE_CASE_TOKEN,
|
||||
GET_TEAMS_LEADERBOARD_USE_CASE_TOKEN,
|
||||
} from './TeamTokens';
|
||||
|
||||
export {
|
||||
@@ -34,6 +35,7 @@ import type { DriverRepository } from '@core/racing/domain/repositories/DriverRe
|
||||
import type { TeamMembershipRepository } from '@core/racing/domain/repositories/TeamMembershipRepository';
|
||||
import type { TeamRepository } from '@core/racing/domain/repositories/TeamRepository';
|
||||
import type { TeamStatsRepository } from '@core/racing/domain/repositories/TeamStatsRepository';
|
||||
import type { DriverStatsRepository } from '@core/racing/domain/repositories/DriverStatsRepository';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
|
||||
// Import concrete implementations
|
||||
@@ -52,9 +54,11 @@ import { GetTeamMembershipUseCase } from '@core/racing/application/use-cases/Get
|
||||
import { GetTeamMembersUseCase } from '@core/racing/application/use-cases/GetTeamMembersUseCase';
|
||||
import { JoinTeamUseCase } from '@core/racing/application/use-cases/JoinTeamUseCase';
|
||||
import { UpdateTeamUseCase } from '@core/racing/application/use-cases/UpdateTeamUseCase';
|
||||
import { GetTeamsLeaderboardUseCase } from '@core/racing/application/use-cases/GetTeamsLeaderboardUseCase';
|
||||
|
||||
// Import presenters
|
||||
import { AllTeamsPresenter } from './presenters/AllTeamsPresenter';
|
||||
import { TeamsLeaderboardPresenter } from './presenters/TeamsLeaderboardPresenter';
|
||||
|
||||
export const TeamProviders: Provider[] = [
|
||||
{
|
||||
@@ -100,6 +104,10 @@ export const TeamProviders: Provider[] = [
|
||||
},
|
||||
inject: [MEDIA_RESOLVER_TOKEN],
|
||||
},
|
||||
{
|
||||
provide: TeamsLeaderboardPresenter,
|
||||
useClass: TeamsLeaderboardPresenter,
|
||||
},
|
||||
// Use Cases
|
||||
{
|
||||
provide: GET_ALL_TEAMS_USE_CASE_TOKEN,
|
||||
@@ -155,4 +163,13 @@ export const TeamProviders: Provider[] = [
|
||||
new JoinTeamUseCase(teamRepo, membershipRepo, logger),
|
||||
inject: [TEAM_REPOSITORY_TOKEN, TEAM_MEMBERSHIP_REPOSITORY_TOKEN, LOGGER_TOKEN],
|
||||
},
|
||||
{
|
||||
provide: GET_TEAMS_LEADERBOARD_USE_CASE_TOKEN,
|
||||
useFactory: (teamRepo: TeamRepository, membershipRepo: TeamMembershipRepository, driverStatsRepo: DriverStatsRepository, logger: Logger) =>
|
||||
new GetTeamsLeaderboardUseCase(teamRepo, membershipRepo, (driverId) => {
|
||||
const stats = driverStatsRepo.getDriverStatsSync?.(driverId);
|
||||
return stats ? { rating: stats.rating, wins: stats.wins, totalRaces: stats.totalRaces } : null;
|
||||
}, logger),
|
||||
inject: [TEAM_REPOSITORY_TOKEN, TEAM_MEMBERSHIP_REPOSITORY_TOKEN, 'IDriverStatsRepository', LOGGER_TOKEN],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -134,6 +134,8 @@ describe('TeamService', () => {
|
||||
new GetDriverTeamUseCase(teamRepository as never, membershipRepository as never, logger),
|
||||
new GetTeamMembershipUseCase(membershipRepository as never, logger),
|
||||
{ execute: vi.fn() } as never, // joinTeamUseCase
|
||||
{ execute: vi.fn() } as never, // getTeamsLeaderboardUseCase
|
||||
{ reset: vi.fn(), present: vi.fn(), getViewModel: vi.fn() } as never, // teamsLeaderboardPresenter
|
||||
logger
|
||||
);
|
||||
});
|
||||
|
||||
@@ -7,6 +7,7 @@ import { GetTeamDetailsOutputDTO } from './dtos/GetTeamDetailsOutputDTO';
|
||||
import { GetTeamJoinRequestsOutputDTO } from './dtos/GetTeamJoinRequestsOutputDTO';
|
||||
import { GetTeamMembershipOutputDTO } from './dtos/GetTeamMembershipOutputDTO';
|
||||
import { GetTeamMembersOutputDTO } from './dtos/GetTeamMembersOutputDTO';
|
||||
import { GetTeamsLeaderboardOutputDTO } from './dtos/GetTeamsLeaderboardOutputDTO';
|
||||
import { UpdateTeamInputDTO } from './dtos/UpdateTeamInputDTO';
|
||||
import { UpdateTeamOutputDTO } from './dtos/UpdateTeamOutputDTO';
|
||||
|
||||
@@ -21,6 +22,7 @@ import { GetTeamDetailsUseCase } from '@core/racing/application/use-cases/GetTea
|
||||
import { GetTeamJoinRequestsUseCase } from '@core/racing/application/use-cases/GetTeamJoinRequestsUseCase';
|
||||
import { GetTeamMembershipUseCase } from '@core/racing/application/use-cases/GetTeamMembershipUseCase';
|
||||
import { GetTeamMembersUseCase } from '@core/racing/application/use-cases/GetTeamMembersUseCase';
|
||||
import { GetTeamsLeaderboardUseCase } from '@core/racing/application/use-cases/GetTeamsLeaderboardUseCase';
|
||||
import { JoinTeamUseCase } from '@core/racing/application/use-cases/JoinTeamUseCase';
|
||||
import { UpdateTeamInput, UpdateTeamUseCase } from '@core/racing/application/use-cases/UpdateTeamUseCase';
|
||||
|
||||
@@ -32,12 +34,15 @@ import {
|
||||
GET_TEAM_DETAILS_USE_CASE_TOKEN,
|
||||
GET_TEAM_JOIN_REQUESTS_USE_CASE_TOKEN,
|
||||
GET_TEAM_MEMBERS_USE_CASE_TOKEN,
|
||||
GET_TEAM_MEMBERSHIP_USE_CASE_TOKEN,
|
||||
GET_TEAM_MEMBERS_USE_CASE_TOKEN as GET_TEAM_MEMBERSHIP_USE_CASE_TOKEN,
|
||||
GET_TEAMS_LEADERBOARD_USE_CASE_TOKEN,
|
||||
JOIN_TEAM_USE_CASE_TOKEN,
|
||||
LOGGER_TOKEN,
|
||||
UPDATE_TEAM_USE_CASE_TOKEN,
|
||||
} from './TeamTokens';
|
||||
|
||||
import { TeamsLeaderboardPresenter } from './presenters/TeamsLeaderboardPresenter';
|
||||
|
||||
@Injectable()
|
||||
export class TeamService {
|
||||
constructor(
|
||||
@@ -50,6 +55,8 @@ export class TeamService {
|
||||
@Inject(GET_DRIVER_TEAM_USE_CASE_TOKEN) private readonly getDriverTeamUseCase: GetDriverTeamUseCase,
|
||||
@Inject(GET_TEAM_MEMBERSHIP_USE_CASE_TOKEN) private readonly getTeamMembershipUseCase: GetTeamMembershipUseCase,
|
||||
@Inject(JOIN_TEAM_USE_CASE_TOKEN) private readonly joinTeamUseCase: JoinTeamUseCase,
|
||||
@Inject(GET_TEAMS_LEADERBOARD_USE_CASE_TOKEN) private readonly getTeamsLeaderboardUseCase: GetTeamsLeaderboardUseCase,
|
||||
@Inject(TeamsLeaderboardPresenter) private readonly teamsLeaderboardPresenter: TeamsLeaderboardPresenter,
|
||||
@Inject(LOGGER_TOKEN) private readonly logger: Logger,
|
||||
) {}
|
||||
|
||||
@@ -85,6 +92,20 @@ export class TeamService {
|
||||
};
|
||||
}
|
||||
|
||||
async getLeaderboard(): Promise<GetTeamsLeaderboardOutputDTO> {
|
||||
this.logger.debug('[TeamService] Fetching teams leaderboard.');
|
||||
|
||||
const result = await this.getTeamsLeaderboardUseCase.execute({ leagueId: 'global' });
|
||||
if (result.isErr()) {
|
||||
this.logger.error('Error fetching teams leaderboard', new Error(result.unwrapErr().details?.message || 'Unknown error'));
|
||||
return { teams: [], recruitingCount: 0, groupsBySkillLevel: { beginner: [], intermediate: [], advanced: [], pro: [] }, topTeams: [] };
|
||||
}
|
||||
|
||||
this.teamsLeaderboardPresenter.reset();
|
||||
this.teamsLeaderboardPresenter.present(result.unwrap());
|
||||
return this.teamsLeaderboardPresenter.getViewModel()!;
|
||||
}
|
||||
|
||||
async getDetails(teamId: string, userId?: string): Promise<GetTeamDetailsOutputDTO | null> {
|
||||
this.logger.debug(`[TeamService] Fetching team details for teamId: ${teamId}, userId: ${userId}`);
|
||||
|
||||
|
||||
@@ -16,4 +16,5 @@ export const CREATE_TEAM_USE_CASE_TOKEN = Symbol('CREATE_TEAM_USE_CASE_TOKEN');
|
||||
export const UPDATE_TEAM_USE_CASE_TOKEN = Symbol('UPDATE_TEAM_USE_CASE_TOKEN');
|
||||
export const GET_DRIVER_TEAM_USE_CASE_TOKEN = Symbol('GET_DRIVER_TEAM_USE_CASE_TOKEN');
|
||||
export const GET_TEAM_MEMBERSHIP_USE_CASE_TOKEN = Symbol('GET_TEAM_MEMBERSHIP_USE_CASE_TOKEN');
|
||||
export const JOIN_TEAM_USE_CASE_TOKEN = Symbol('JOIN_TEAM_USE_CASE_TOKEN');
|
||||
export const JOIN_TEAM_USE_CASE_TOKEN = Symbol('JOIN_TEAM_USE_CASE_TOKEN');
|
||||
export const GET_TEAMS_LEADERBOARD_USE_CASE_TOKEN = Symbol('GET_TEAMS_LEADERBOARD_USE_CASE_TOKEN');
|
||||
|
||||
@@ -9,6 +9,12 @@ export class TeamLeaderboardItemDTO {
|
||||
@ApiProperty()
|
||||
name!: string;
|
||||
|
||||
@ApiProperty()
|
||||
tag!: string;
|
||||
|
||||
@ApiProperty({ nullable: true })
|
||||
logoUrl!: string | null;
|
||||
|
||||
@ApiProperty()
|
||||
memberCount!: number;
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@ export class TeamsLeaderboardPresenter implements UseCaseOutputPort<GetTeamsLead
|
||||
teams: result.items.map(item => ({
|
||||
id: item.team.id,
|
||||
name: item.team.name.toString(),
|
||||
tag: item.team.tag.toString(),
|
||||
logoUrl: null, // MediaResolver would be needed here
|
||||
memberCount: item.memberCount,
|
||||
rating: item.rating,
|
||||
totalWins: item.totalWins,
|
||||
@@ -28,6 +30,8 @@ export class TeamsLeaderboardPresenter implements UseCaseOutputPort<GetTeamsLead
|
||||
beginner: result.groupsBySkillLevel.beginner.map(item => ({
|
||||
id: item.team.id,
|
||||
name: item.team.name.toString(),
|
||||
tag: item.team.tag.toString(),
|
||||
logoUrl: null,
|
||||
memberCount: item.memberCount,
|
||||
rating: item.rating,
|
||||
totalWins: item.totalWins,
|
||||
@@ -40,6 +44,8 @@ export class TeamsLeaderboardPresenter implements UseCaseOutputPort<GetTeamsLead
|
||||
intermediate: result.groupsBySkillLevel.intermediate.map(item => ({
|
||||
id: item.team.id,
|
||||
name: item.team.name.toString(),
|
||||
tag: item.team.tag.toString(),
|
||||
logoUrl: null,
|
||||
memberCount: item.memberCount,
|
||||
rating: item.rating,
|
||||
totalWins: item.totalWins,
|
||||
@@ -52,6 +58,8 @@ export class TeamsLeaderboardPresenter implements UseCaseOutputPort<GetTeamsLead
|
||||
advanced: result.groupsBySkillLevel.advanced.map(item => ({
|
||||
id: item.team.id,
|
||||
name: item.team.name.toString(),
|
||||
tag: item.team.tag.toString(),
|
||||
logoUrl: null,
|
||||
memberCount: item.memberCount,
|
||||
rating: item.rating,
|
||||
totalWins: item.totalWins,
|
||||
@@ -64,6 +72,8 @@ export class TeamsLeaderboardPresenter implements UseCaseOutputPort<GetTeamsLead
|
||||
pro: result.groupsBySkillLevel.pro.map(item => ({
|
||||
id: item.team.id,
|
||||
name: item.team.name.toString(),
|
||||
tag: item.team.tag.toString(),
|
||||
logoUrl: null,
|
||||
memberCount: item.memberCount,
|
||||
rating: item.rating,
|
||||
totalWins: item.totalWins,
|
||||
@@ -77,6 +87,8 @@ export class TeamsLeaderboardPresenter implements UseCaseOutputPort<GetTeamsLead
|
||||
topTeams: result.topItems.map(item => ({
|
||||
id: item.team.id,
|
||||
name: item.team.name.toString(),
|
||||
tag: item.team.tag.toString(),
|
||||
logoUrl: null,
|
||||
memberCount: item.memberCount,
|
||||
rating: item.rating,
|
||||
totalWins: item.totalWins,
|
||||
|
||||
Reference in New Issue
Block a user