Files
gridpilot.gg/core/racing/application/use-cases/GetAllTeamsUseCase.ts
2026-01-16 19:46:49 +01:00

98 lines
3.3 KiB
TypeScript

import type { Logger } from '@core/shared/domain/Logger';
import { Result } from '@core/shared/domain/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import { Team } from '../../domain/entities/Team';
import { TeamMembershipRepository } from '../../domain/repositories/TeamMembershipRepository';
import { TeamRepository } from '../../domain/repositories/TeamRepository';
import { TeamStatsRepository } from '../../domain/repositories/TeamStatsRepository';
export interface GetAllTeamsInput {}
export type GetAllTeamsErrorCode = 'REPOSITORY_ERROR';
export interface EnrichedTeam {
team: Team;
memberCount: number;
totalWins: number;
totalRaces: number;
performanceLevel: 'beginner' | 'intermediate' | 'advanced' | 'pro';
specialization: 'endurance' | 'sprint' | 'mixed';
region: string;
languages: string[];
rating: number;
logoUrl: string | null;
description: string;
leagues: string[];
isRecruiting: boolean;
}
export interface GetAllTeamsResult {
teams: EnrichedTeam[];
totalCount: number;
}
export class GetAllTeamsUseCase {
constructor(
private readonly teamRepository: TeamRepository,
private readonly membershipRepository: TeamMembershipRepository,
private readonly statsRepository: TeamStatsRepository,
private readonly logger: Logger,
) {}
async execute(
_input: GetAllTeamsInput,
): Promise<Result<GetAllTeamsResult, ApplicationErrorCode<GetAllTeamsErrorCode, { message: string }>>> {
void _input;
this.logger.debug('GetAllTeamsUseCase: Fetching all teams');
try {
const teams = await this.teamRepository.findAll();
const enrichedTeams: EnrichedTeam[] = [];
for (const team of teams) {
// Get member count
const memberCount = await this.membershipRepository.countByTeamId(team.id.toString());
// Get team stats
const stats = await this.statsRepository.getTeamStats(team.id.toString());
// Resolve logo URL
let logoUrl: string | undefined;
if (team.logoRef) {
// For now, use a placeholder - in real implementation, MediaResolver would be used
logoUrl = `/media/teams/${team.id}/logo`;
}
enrichedTeams.push({
team,
memberCount,
totalWins: stats?.totalWins ?? 0,
totalRaces: stats?.totalRaces ?? 0,
performanceLevel: stats?.performanceLevel ?? 'intermediate',
specialization: stats?.specialization ?? 'mixed',
region: stats?.region ?? '',
languages: stats?.languages ?? [],
rating: stats?.rating ?? 0,
logoUrl: logoUrl ?? null,
description: team.description.toString(),
leagues: team.leagues.map((l) => l.toString()),
isRecruiting: team.isRecruiting,
});
}
this.logger.debug('Successfully retrieved and enriched all teams.');
return Result.ok({
teams: enrichedTeams,
totalCount: enrichedTeams.length
});
} catch (error: unknown) {
const message = error instanceof Error ? error.message : 'Failed to fetch all teams';
this.logger.error('GetAllTeamsUseCase: Error fetching teams', error instanceof Error ? error : new Error(message));
return Result.err({
code: 'REPOSITORY_ERROR',
details: { message },
});
}
}
}