team rating
This commit is contained in:
@@ -65,6 +65,9 @@ export const BootstrapProviders: Provider[] = [
|
||||
sponsorRepository: RacingSeedDependencies['sponsorRepository'],
|
||||
feedRepository: RacingSeedDependencies['feedRepository'],
|
||||
socialGraphRepository: RacingSeedDependencies['socialGraphRepository'],
|
||||
driverStatsRepository: RacingSeedDependencies['driverStatsRepository'],
|
||||
teamStatsRepository: RacingSeedDependencies['teamStatsRepository'],
|
||||
mediaRepository: RacingSeedDependencies['mediaRepository'],
|
||||
): RacingSeedDependencies => ({
|
||||
driverRepository,
|
||||
leagueRepository,
|
||||
@@ -86,6 +89,9 @@ export const BootstrapProviders: Provider[] = [
|
||||
sponsorRepository,
|
||||
feedRepository,
|
||||
socialGraphRepository,
|
||||
driverStatsRepository,
|
||||
teamStatsRepository,
|
||||
mediaRepository,
|
||||
}),
|
||||
inject: [
|
||||
'IDriverRepository',
|
||||
@@ -108,6 +114,9 @@ export const BootstrapProviders: Provider[] = [
|
||||
'ISponsorRepository',
|
||||
SOCIAL_FEED_REPOSITORY_TOKEN,
|
||||
SOCIAL_GRAPH_REPOSITORY_TOKEN,
|
||||
'IDriverStatsRepository',
|
||||
'ITeamStatsRepository',
|
||||
'IMediaRepository',
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -6,10 +6,10 @@ import { IDriverRepository } from '@core/racing/domain/repositories/IDriverRepos
|
||||
import { IRaceRegistrationRepository } from '@core/racing/domain/repositories/IRaceRegistrationRepository';
|
||||
import type { ITeamMembershipRepository } from '@core/racing/domain/repositories/ITeamMembershipRepository';
|
||||
import type { ITeamRepository } from '@core/racing/domain/repositories/ITeamRepository';
|
||||
import { IDriverStatsService } from '@core/racing/domain/services/IDriverStatsService';
|
||||
import { IRankingService } from '@core/racing/domain/services/IRankingService';
|
||||
import type { Logger, UseCaseOutputPort } from '@core/shared/application';
|
||||
import type { ISocialGraphRepository } from '@core/social/domain/repositories/ISocialGraphRepository';
|
||||
import type { IResultRepository } from '@core/racing/domain/repositories/IResultRepository';
|
||||
import type { IStandingRepository } from '@core/racing/domain/repositories/IStandingRepository';
|
||||
|
||||
// Import use cases
|
||||
import { CompleteDriverOnboardingUseCase } from '@core/racing/application/use-cases/CompleteDriverOnboardingUseCase';
|
||||
@@ -25,9 +25,18 @@ import { InMemoryImageServiceAdapter } from '@adapters/media/ports/InMemoryImage
|
||||
import { InMemoryNotificationPreferenceRepository } from '@adapters/notifications/persistence/inmemory/InMemoryNotificationPreferenceRepository';
|
||||
import { InMemoryDriverExtendedProfileProvider } from '@adapters/racing/ports/InMemoryDriverExtendedProfileProvider';
|
||||
import { InMemoryDriverRatingProvider } from '@adapters/racing/ports/InMemoryDriverRatingProvider';
|
||||
import { InMemoryDriverStatsService } from '@adapters/racing/services/InMemoryDriverStatsService';
|
||||
import { InMemoryRankingService } from '@adapters/racing/services/InMemoryRankingService';
|
||||
import { IImageServicePort } from '@core/racing/application/ports/IImageServicePort';
|
||||
// Import new use cases
|
||||
import { RankingUseCase } from '@core/racing/application/use-cases/RankingUseCase';
|
||||
import { DriverStatsUseCase } from '@core/racing/application/use-cases/DriverStatsUseCase';
|
||||
// Import new repositories
|
||||
import { InMemoryDriverStatsRepository } from '@adapters/racing/persistence/inmemory/InMemoryDriverStatsRepository';
|
||||
import { InMemoryMediaRepository } from '@adapters/racing/persistence/media/InMemoryMediaRepository';
|
||||
// Import repository tokens
|
||||
import { IDriverStatsRepository } from '@core/racing/domain/repositories/IDriverStatsRepository';
|
||||
import { IMediaRepository } from '@core/racing/domain/repositories/IMediaRepository';
|
||||
// Import use case interfaces
|
||||
import type { IRankingUseCase } from '@core/racing/application/use-cases/IRankingUseCase';
|
||||
import type { IDriverStatsUseCase } from '@core/racing/application/use-cases/IDriverStatsUseCase';
|
||||
|
||||
// Import presenters
|
||||
import { CompleteOnboardingPresenter } from './presenters/CompleteOnboardingPresenter';
|
||||
@@ -39,8 +48,6 @@ import { DriverStatsPresenter } from './presenters/DriverStatsPresenter';
|
||||
|
||||
import {
|
||||
DRIVER_REPOSITORY_TOKEN,
|
||||
RANKING_SERVICE_TOKEN,
|
||||
DRIVER_STATS_SERVICE_TOKEN,
|
||||
DRIVER_RATING_PROVIDER_TOKEN,
|
||||
DRIVER_EXTENDED_PROFILE_PROVIDER_TOKEN,
|
||||
IMAGE_SERVICE_PORT_TOKEN,
|
||||
@@ -62,6 +69,10 @@ import {
|
||||
IS_DRIVER_REGISTERED_FOR_RACE_OUTPUT_PORT_TOKEN,
|
||||
UPDATE_DRIVER_PROFILE_OUTPUT_PORT_TOKEN,
|
||||
GET_PROFILE_OVERVIEW_OUTPUT_PORT_TOKEN,
|
||||
DRIVER_STATS_REPOSITORY_TOKEN,
|
||||
MEDIA_REPOSITORY_TOKEN,
|
||||
RANKING_SERVICE_TOKEN,
|
||||
DRIVER_STATS_SERVICE_TOKEN,
|
||||
} from './DriverTokens';
|
||||
|
||||
export * from './DriverTokens';
|
||||
@@ -73,7 +84,11 @@ export const DriverProviders: Provider[] = [
|
||||
DriverStatsPresenter,
|
||||
CompleteOnboardingPresenter,
|
||||
DriverRegistrationStatusPresenter,
|
||||
DriverPresenter,
|
||||
{
|
||||
provide: DriverPresenter,
|
||||
useFactory: (driverStatsRepository: IDriverStatsRepository) => new DriverPresenter(driverStatsRepository),
|
||||
inject: [DRIVER_STATS_REPOSITORY_TOKEN],
|
||||
},
|
||||
DriverProfilePresenter,
|
||||
|
||||
// Output ports (point to presenters)
|
||||
@@ -110,15 +125,33 @@ export const DriverProviders: Provider[] = [
|
||||
|
||||
// Repositories (racing + social repos are provided by imported persistence modules)
|
||||
{
|
||||
provide: RANKING_SERVICE_TOKEN,
|
||||
useFactory: (logger: Logger) => new InMemoryRankingService(logger),
|
||||
provide: DRIVER_STATS_REPOSITORY_TOKEN,
|
||||
useFactory: (logger: Logger) => new InMemoryDriverStatsRepository(logger),
|
||||
inject: [LOGGER_TOKEN],
|
||||
},
|
||||
{
|
||||
provide: DRIVER_STATS_SERVICE_TOKEN,
|
||||
useFactory: (logger: Logger) => new InMemoryDriverStatsService(logger),
|
||||
provide: MEDIA_REPOSITORY_TOKEN,
|
||||
useFactory: (logger: Logger) => new InMemoryMediaRepository(logger),
|
||||
inject: [LOGGER_TOKEN],
|
||||
},
|
||||
{
|
||||
provide: RANKING_SERVICE_TOKEN,
|
||||
useFactory: (
|
||||
standingRepo: IStandingRepository,
|
||||
driverRepo: IDriverRepository,
|
||||
logger: Logger
|
||||
) => new RankingUseCase(standingRepo, driverRepo, logger),
|
||||
inject: ['IStandingRepository', DRIVER_REPOSITORY_TOKEN, LOGGER_TOKEN],
|
||||
},
|
||||
{
|
||||
provide: DRIVER_STATS_SERVICE_TOKEN,
|
||||
useFactory: (
|
||||
resultRepo: IResultRepository,
|
||||
standingRepo: IStandingRepository,
|
||||
logger: Logger
|
||||
) => new DriverStatsUseCase(resultRepo, standingRepo, logger),
|
||||
inject: ['IResultRepository', 'IStandingRepository', LOGGER_TOKEN],
|
||||
},
|
||||
{
|
||||
provide: DRIVER_RATING_PROVIDER_TOKEN,
|
||||
useFactory: (logger: Logger) => new InMemoryDriverRatingProvider(logger),
|
||||
@@ -145,13 +178,23 @@ export const DriverProviders: Provider[] = [
|
||||
provide: GET_DRIVERS_LEADERBOARD_USE_CASE_TOKEN,
|
||||
useFactory: (
|
||||
driverRepo: IDriverRepository,
|
||||
rankingService: IRankingService,
|
||||
driverStatsService: IDriverStatsService,
|
||||
imageService: IImageServicePort,
|
||||
rankingUseCase: IRankingUseCase,
|
||||
driverStatsUseCase: IDriverStatsUseCase,
|
||||
mediaRepository: IMediaRepository,
|
||||
logger: Logger,
|
||||
output: UseCaseOutputPort<unknown>,
|
||||
) => new GetDriversLeaderboardUseCase(driverRepo, rankingService, driverStatsService, (driverId: string) => Promise.resolve(imageService.getDriverAvatar(driverId)), logger, output),
|
||||
inject: [DRIVER_REPOSITORY_TOKEN, RANKING_SERVICE_TOKEN, DRIVER_STATS_SERVICE_TOKEN, IMAGE_SERVICE_PORT_TOKEN, LOGGER_TOKEN, GET_DRIVERS_LEADERBOARD_OUTPUT_PORT_TOKEN],
|
||||
) => new GetDriversLeaderboardUseCase(
|
||||
driverRepo,
|
||||
rankingUseCase,
|
||||
driverStatsUseCase,
|
||||
async (driverId: string) => {
|
||||
const avatar = await mediaRepository.getDriverAvatar(driverId);
|
||||
return avatar ?? undefined;
|
||||
},
|
||||
logger,
|
||||
output
|
||||
),
|
||||
inject: [DRIVER_REPOSITORY_TOKEN, RANKING_SERVICE_TOKEN, DRIVER_STATS_SERVICE_TOKEN, MEDIA_REPOSITORY_TOKEN, LOGGER_TOKEN, GET_DRIVERS_LEADERBOARD_OUTPUT_PORT_TOKEN],
|
||||
},
|
||||
{
|
||||
provide: GET_TOTAL_DRIVERS_USE_CASE_TOKEN,
|
||||
@@ -183,8 +226,8 @@ export const DriverProviders: Provider[] = [
|
||||
teamMembershipRepository: ITeamMembershipRepository,
|
||||
socialRepository: ISocialGraphRepository,
|
||||
driverExtendedProfileProvider: DriverExtendedProfileProvider,
|
||||
driverStatsService: IDriverStatsService,
|
||||
rankingService: IRankingService,
|
||||
driverStatsUseCase: IDriverStatsUseCase,
|
||||
rankingUseCase: IRankingUseCase,
|
||||
output: UseCaseOutputPort<unknown>,
|
||||
) =>
|
||||
new GetProfileOverviewUseCase(
|
||||
@@ -193,32 +236,8 @@ export const DriverProviders: Provider[] = [
|
||||
teamMembershipRepository,
|
||||
socialRepository,
|
||||
driverExtendedProfileProvider,
|
||||
(driverId: string) => {
|
||||
const stats = driverStatsService.getDriverStats(driverId);
|
||||
if (!stats) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
rating: stats.rating,
|
||||
wins: stats.wins,
|
||||
podiums: stats.podiums,
|
||||
dnfs: (stats as { dnfs?: number }).dnfs ?? 0,
|
||||
totalRaces: stats.totalRaces,
|
||||
avgFinish: null,
|
||||
bestFinish: null,
|
||||
worstFinish: null,
|
||||
overallRank: stats.overallRank,
|
||||
consistency: null,
|
||||
percentile: null,
|
||||
};
|
||||
},
|
||||
() =>
|
||||
rankingService.getAllDriverRankings().map(ranking => ({
|
||||
driverId: ranking.driverId,
|
||||
rating: ranking.rating,
|
||||
overallRank: ranking.overallRank,
|
||||
})),
|
||||
driverStatsUseCase,
|
||||
rankingUseCase,
|
||||
output,
|
||||
),
|
||||
inject: [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export const DRIVER_REPOSITORY_TOKEN = 'IDriverRepository';
|
||||
export const RANKING_SERVICE_TOKEN = 'IRankingService';
|
||||
export const DRIVER_STATS_SERVICE_TOKEN = 'IDriverStatsService';
|
||||
export const RANKING_SERVICE_TOKEN = 'IRankingUseCase';
|
||||
export const DRIVER_STATS_SERVICE_TOKEN = 'IDriverStatsUseCase';
|
||||
export const DRIVER_RATING_PROVIDER_TOKEN = 'DriverRatingProvider';
|
||||
export const DRIVER_EXTENDED_PROFILE_PROVIDER_TOKEN = 'DriverExtendedProfileProvider';
|
||||
export const IMAGE_SERVICE_PORT_TOKEN = 'IImageServicePort';
|
||||
@@ -13,6 +13,10 @@ export const TEAM_MEMBERSHIP_REPOSITORY_TOKEN = 'ITeamMembershipRepository';
|
||||
export { SOCIAL_GRAPH_REPOSITORY_TOKEN };
|
||||
export const LOGGER_TOKEN = 'Logger';
|
||||
|
||||
// New tokens for clean architecture
|
||||
export const DRIVER_STATS_REPOSITORY_TOKEN = 'IDriverStatsRepository';
|
||||
export const MEDIA_REPOSITORY_TOKEN = 'IMediaRepository';
|
||||
|
||||
export const GET_DRIVERS_LEADERBOARD_USE_CASE_TOKEN = 'GetDriversLeaderboardUseCase';
|
||||
export const GET_TOTAL_DRIVERS_USE_CASE_TOKEN = 'GetTotalDriversUseCase';
|
||||
export const COMPLETE_DRIVER_ONBOARDING_USE_CASE_TOKEN = 'CompleteDriverOnboardingUseCase';
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
import { Result } from '@core/shared/application/Result';
|
||||
import type { Driver } from '@core/racing/domain/entities/Driver';
|
||||
import type { GetDriverOutputDTO } from '../dtos/GetDriverOutputDTO';
|
||||
import { DriverStatsStore } from '@adapters/racing/services/DriverStatsStore';
|
||||
import type { IDriverStatsRepository } from '@core/racing/domain/repositories/IDriverStatsRepository';
|
||||
|
||||
export class DriverPresenter {
|
||||
private responseModel: GetDriverOutputDTO | null = null;
|
||||
|
||||
constructor(
|
||||
private readonly driverStatsRepository: IDriverStatsRepository
|
||||
) {}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
present(result: Result<Driver | null, any>): void {
|
||||
if (result.isErr()) {
|
||||
@@ -19,9 +23,8 @@ export class DriverPresenter {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get stats from the store
|
||||
const statsStore = DriverStatsStore.getInstance();
|
||||
const stats = statsStore.getDriverStats(driver.id);
|
||||
// Get stats from repository (synchronously for now, could be async)
|
||||
const stats = this.driverStatsRepository.getDriverStatsSync(driver.id);
|
||||
|
||||
this.responseModel = {
|
||||
id: driver.id,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Provider } from '@nestjs/common';
|
||||
|
||||
import { IMAGE_SERVICE_TOKEN, LOGGER_TOKEN } from './TeamTokens';
|
||||
import { IMAGE_SERVICE_TOKEN, LOGGER_TOKEN, TEAM_STATS_REPOSITORY_TOKEN, MEDIA_REPOSITORY_TOKEN } from './TeamTokens';
|
||||
|
||||
export {
|
||||
TEAM_REPOSITORY_TOKEN,
|
||||
@@ -8,16 +8,22 @@ export {
|
||||
DRIVER_REPOSITORY_TOKEN,
|
||||
IMAGE_SERVICE_TOKEN,
|
||||
LOGGER_TOKEN,
|
||||
TEAM_STATS_REPOSITORY_TOKEN,
|
||||
MEDIA_REPOSITORY_TOKEN,
|
||||
} from './TeamTokens';
|
||||
|
||||
// Import core interfaces
|
||||
import type { Logger } from '@core/shared/application/Logger';
|
||||
import type { ITeamStatsRepository } from '@core/racing/domain/repositories/ITeamStatsRepository';
|
||||
|
||||
// Import concrete in-memory implementations
|
||||
import { InMemoryImageServiceAdapter } from '@adapters/media/ports/InMemoryImageServiceAdapter';
|
||||
import { ConsoleLogger } from '@adapters/logging/ConsoleLogger';
|
||||
import { InMemoryTeamStatsRepository } from '@adapters/racing/persistence/inmemory/InMemoryTeamStatsRepository';
|
||||
import { InMemoryMediaRepository } from '@adapters/racing/persistence/media/InMemoryMediaRepository';
|
||||
|
||||
// Use cases are imported and used directly in the service
|
||||
// Import presenters
|
||||
import { AllTeamsPresenter } from './presenters/AllTeamsPresenter';
|
||||
|
||||
export const TeamProviders: Provider[] = [
|
||||
{
|
||||
@@ -29,5 +35,19 @@ export const TeamProviders: Provider[] = [
|
||||
provide: LOGGER_TOKEN,
|
||||
useClass: ConsoleLogger,
|
||||
},
|
||||
// Use cases are created directly in the service
|
||||
{
|
||||
provide: TEAM_STATS_REPOSITORY_TOKEN,
|
||||
useFactory: (logger: Logger) => new InMemoryTeamStatsRepository(logger),
|
||||
inject: [LOGGER_TOKEN],
|
||||
},
|
||||
{
|
||||
provide: MEDIA_REPOSITORY_TOKEN,
|
||||
useFactory: (logger: Logger) => new InMemoryMediaRepository(logger),
|
||||
inject: [LOGGER_TOKEN],
|
||||
},
|
||||
{
|
||||
provide: AllTeamsPresenter,
|
||||
useFactory: (teamStatsRepository: ITeamStatsRepository) => new AllTeamsPresenter(teamStatsRepository),
|
||||
inject: [TEAM_STATS_REPOSITORY_TOKEN],
|
||||
},
|
||||
];
|
||||
@@ -111,7 +111,37 @@ describe('TeamService', () => {
|
||||
error: vi.fn(),
|
||||
} as unknown as Logger;
|
||||
|
||||
service = new TeamService(teamRepository as unknown as never, membershipRepository as unknown as never, driverRepository as unknown as never, logger);
|
||||
const teamStatsRepository = {
|
||||
getTeamStats: vi.fn(),
|
||||
getTeamStatsSync: vi.fn(),
|
||||
saveTeamStats: vi.fn(),
|
||||
getAllStats: vi.fn(),
|
||||
clear: vi.fn(),
|
||||
};
|
||||
|
||||
const mediaRepository = {
|
||||
getTeamAvatar: vi.fn(),
|
||||
saveTeamAvatar: vi.fn(),
|
||||
getDriverAvatar: vi.fn(),
|
||||
saveDriverAvatar: vi.fn(),
|
||||
};
|
||||
|
||||
const allTeamsPresenter = {
|
||||
reset: vi.fn(),
|
||||
present: vi.fn(),
|
||||
getResponseModel: vi.fn(() => ({ teams: [], totalCount: 0 })),
|
||||
responseModel: { teams: [], totalCount: 0 },
|
||||
};
|
||||
|
||||
service = new TeamService(
|
||||
teamRepository as unknown as never,
|
||||
membershipRepository as unknown as never,
|
||||
driverRepository as unknown as never,
|
||||
logger,
|
||||
teamStatsRepository as unknown as never,
|
||||
mediaRepository as unknown as never,
|
||||
allTeamsPresenter as unknown as never
|
||||
);
|
||||
});
|
||||
|
||||
it('getAll returns teams and totalCount on success', async () => {
|
||||
|
||||
@@ -37,7 +37,9 @@ import { CreateTeamPresenter } from './presenters/CreateTeamPresenter';
|
||||
import { UpdateTeamPresenter } from './presenters/UpdateTeamPresenter';
|
||||
|
||||
// Tokens
|
||||
import { TEAM_REPOSITORY_TOKEN, TEAM_MEMBERSHIP_REPOSITORY_TOKEN, DRIVER_REPOSITORY_TOKEN, LOGGER_TOKEN } from './TeamTokens';
|
||||
import { TEAM_REPOSITORY_TOKEN, TEAM_MEMBERSHIP_REPOSITORY_TOKEN, DRIVER_REPOSITORY_TOKEN, LOGGER_TOKEN, TEAM_STATS_REPOSITORY_TOKEN, MEDIA_REPOSITORY_TOKEN } from './TeamTokens';
|
||||
import type { ITeamStatsRepository } from '@core/racing/domain/repositories/ITeamStatsRepository';
|
||||
import type { IMediaRepository } from '@core/racing/domain/repositories/IMediaRepository';
|
||||
|
||||
@Injectable()
|
||||
export class TeamService {
|
||||
@@ -46,20 +48,29 @@ export class TeamService {
|
||||
@Inject(TEAM_MEMBERSHIP_REPOSITORY_TOKEN) private readonly membershipRepository: ITeamMembershipRepository,
|
||||
@Inject(DRIVER_REPOSITORY_TOKEN) private readonly driverRepository: IDriverRepository,
|
||||
@Inject(LOGGER_TOKEN) private readonly logger: Logger,
|
||||
@Inject(TEAM_STATS_REPOSITORY_TOKEN) private readonly teamStatsRepository: ITeamStatsRepository,
|
||||
@Inject(MEDIA_REPOSITORY_TOKEN) private readonly mediaRepository: IMediaRepository,
|
||||
private readonly allTeamsPresenter: AllTeamsPresenter,
|
||||
) {}
|
||||
|
||||
async getAll(): Promise<GetAllTeamsOutputDTO> {
|
||||
this.logger.debug('[TeamService] Fetching all teams.');
|
||||
|
||||
const presenter = new AllTeamsPresenter();
|
||||
const useCase = new GetAllTeamsUseCase(this.teamRepository, this.membershipRepository, this.logger, presenter);
|
||||
const useCase = new GetAllTeamsUseCase(
|
||||
this.teamRepository,
|
||||
this.membershipRepository,
|
||||
this.teamStatsRepository,
|
||||
this.mediaRepository,
|
||||
this.logger,
|
||||
this.allTeamsPresenter
|
||||
);
|
||||
const result = await useCase.execute();
|
||||
if (result.isErr()) {
|
||||
this.logger.error('Error fetching all teams', new Error(result.error?.details?.message || 'Unknown error'));
|
||||
return { teams: [], totalCount: 0 };
|
||||
}
|
||||
|
||||
return presenter.getResponseModel()!;
|
||||
return this.allTeamsPresenter.getResponseModel()!;
|
||||
}
|
||||
|
||||
async getDetails(teamId: string, userId?: string): Promise<GetTeamDetailsOutputDTO | null> {
|
||||
|
||||
@@ -2,4 +2,6 @@ export const TEAM_REPOSITORY_TOKEN = 'ITeamRepository';
|
||||
export const TEAM_MEMBERSHIP_REPOSITORY_TOKEN = 'ITeamMembershipRepository';
|
||||
export const DRIVER_REPOSITORY_TOKEN = 'IDriverRepository';
|
||||
export const IMAGE_SERVICE_TOKEN = 'IImageServicePort';
|
||||
export const LOGGER_TOKEN = 'Logger';
|
||||
export const LOGGER_TOKEN = 'Logger';
|
||||
export const TEAM_STATS_REPOSITORY_TOKEN = 'ITeamStatsRepository';
|
||||
export const MEDIA_REPOSITORY_TOKEN = 'IMediaRepository';
|
||||
@@ -1,21 +1,23 @@
|
||||
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
|
||||
import type { GetAllTeamsResult } from '@core/racing/application/use-cases/GetAllTeamsUseCase';
|
||||
import { GetAllTeamsOutputDTO } from '../dtos/GetAllTeamsOutputDTO';
|
||||
import { TeamStatsStore } from '@adapters/racing/services/TeamStatsStore';
|
||||
import type { ITeamStatsRepository } from '@core/racing/domain/repositories/ITeamStatsRepository';
|
||||
|
||||
export class AllTeamsPresenter implements UseCaseOutputPort<GetAllTeamsResult> {
|
||||
private model: GetAllTeamsOutputDTO | null = null;
|
||||
|
||||
constructor(
|
||||
private readonly teamStatsRepository: ITeamStatsRepository
|
||||
) {}
|
||||
|
||||
reset(): void {
|
||||
this.model = null;
|
||||
}
|
||||
|
||||
present(result: GetAllTeamsResult): void {
|
||||
const statsStore = TeamStatsStore.getInstance();
|
||||
|
||||
this.model = {
|
||||
teams: result.teams.map(team => {
|
||||
const stats = statsStore.getTeamStats(team.id.toString());
|
||||
const stats = this.teamStatsRepository.getTeamStatsSync(team.id.toString());
|
||||
|
||||
return {
|
||||
id: team.id,
|
||||
|
||||
@@ -24,6 +24,9 @@ import type { ISponsorshipPricingRepository } from '@core/racing/domain/reposito
|
||||
import type { ISponsorshipRequestRepository } from '@core/racing/domain/repositories/ISponsorshipRequestRepository';
|
||||
import type { ITeamRepository } from '@core/racing/domain/repositories/ITeamRepository';
|
||||
import type { ITeamMembershipRepository } from '@core/racing/domain/repositories/ITeamMembershipRepository';
|
||||
import type { IDriverStatsRepository } from '@core/racing/domain/repositories/IDriverStatsRepository';
|
||||
import type { ITeamStatsRepository } from '@core/racing/domain/repositories/ITeamStatsRepository';
|
||||
import type { IMediaRepository } from '@core/racing/domain/repositories/IMediaRepository';
|
||||
|
||||
import { getPointsSystems } from '@adapters/bootstrap/PointsSystems';
|
||||
|
||||
@@ -47,6 +50,9 @@ import { InMemoryTransactionRepository } from '@adapters/racing/persistence/inme
|
||||
import { InMemorySponsorRepository } from '@adapters/racing/persistence/inmemory/InMemorySponsorRepository';
|
||||
import { InMemorySponsorshipPricingRepository } from '@adapters/racing/persistence/inmemory/InMemorySponsorshipPricingRepository';
|
||||
import { InMemorySponsorshipRequestRepository } from '@adapters/racing/persistence/inmemory/InMemorySponsorshipRequestRepository';
|
||||
import { InMemoryDriverStatsRepository } from '@adapters/racing/persistence/inmemory/InMemoryDriverStatsRepository';
|
||||
import { InMemoryTeamStatsRepository } from '@adapters/racing/persistence/inmemory/InMemoryTeamStatsRepository';
|
||||
import { InMemoryMediaRepository } from '@adapters/racing/persistence/media/InMemoryMediaRepository';
|
||||
|
||||
export const DRIVER_REPOSITORY_TOKEN = 'IDriverRepository';
|
||||
export const LEAGUE_REPOSITORY_TOKEN = 'ILeagueRepository';
|
||||
@@ -68,6 +74,9 @@ export const TRANSACTION_REPOSITORY_TOKEN = 'ITransactionRepository';
|
||||
export const SPONSOR_REPOSITORY_TOKEN = 'ISponsorRepository';
|
||||
export const SPONSORSHIP_PRICING_REPOSITORY_TOKEN = 'ISponsorshipPricingRepository';
|
||||
export const SPONSORSHIP_REQUEST_REPOSITORY_TOKEN = 'ISponsorshipRequestRepository';
|
||||
export const DRIVER_STATS_REPOSITORY_TOKEN = 'IDriverStatsRepository';
|
||||
export const TEAM_STATS_REPOSITORY_TOKEN = 'ITeamStatsRepository';
|
||||
export const MEDIA_REPOSITORY_TOKEN = 'IMediaRepository';
|
||||
|
||||
@Module({
|
||||
imports: [LoggingModule],
|
||||
@@ -178,6 +187,21 @@ export const SPONSORSHIP_REQUEST_REPOSITORY_TOKEN = 'ISponsorshipRequestReposito
|
||||
useFactory: (logger: Logger): ISponsorshipRequestRepository => new InMemorySponsorshipRequestRepository(logger),
|
||||
inject: ['Logger'],
|
||||
},
|
||||
{
|
||||
provide: DRIVER_STATS_REPOSITORY_TOKEN,
|
||||
useFactory: (logger: Logger): IDriverStatsRepository => new InMemoryDriverStatsRepository(logger),
|
||||
inject: ['Logger'],
|
||||
},
|
||||
{
|
||||
provide: TEAM_STATS_REPOSITORY_TOKEN,
|
||||
useFactory: (logger: Logger): ITeamStatsRepository => new InMemoryTeamStatsRepository(logger),
|
||||
inject: ['Logger'],
|
||||
},
|
||||
{
|
||||
provide: MEDIA_REPOSITORY_TOKEN,
|
||||
useFactory: (logger: Logger): IMediaRepository => new InMemoryMediaRepository(logger),
|
||||
inject: ['Logger'],
|
||||
},
|
||||
],
|
||||
exports: [
|
||||
DRIVER_REPOSITORY_TOKEN,
|
||||
@@ -200,6 +224,9 @@ export const SPONSORSHIP_REQUEST_REPOSITORY_TOKEN = 'ISponsorshipRequestReposito
|
||||
SPONSOR_REPOSITORY_TOKEN,
|
||||
SPONSORSHIP_PRICING_REPOSITORY_TOKEN,
|
||||
SPONSORSHIP_REQUEST_REPOSITORY_TOKEN,
|
||||
DRIVER_STATS_REPOSITORY_TOKEN,
|
||||
TEAM_STATS_REPOSITORY_TOKEN,
|
||||
MEDIA_REPOSITORY_TOKEN,
|
||||
],
|
||||
})
|
||||
export class InMemoryRacingPersistenceModule {}
|
||||
@@ -25,6 +25,9 @@ import {
|
||||
TEAM_MEMBERSHIP_REPOSITORY_TOKEN,
|
||||
TEAM_REPOSITORY_TOKEN,
|
||||
TRANSACTION_REPOSITORY_TOKEN,
|
||||
DRIVER_STATS_REPOSITORY_TOKEN,
|
||||
TEAM_STATS_REPOSITORY_TOKEN,
|
||||
MEDIA_REPOSITORY_TOKEN,
|
||||
} from '../inmemory/InMemoryRacingPersistenceModule';
|
||||
|
||||
import { DriverOrmEntity } from '@adapters/racing/persistence/typeorm/entities/DriverOrmEntity';
|
||||
@@ -74,6 +77,11 @@ import {
|
||||
import { TypeOrmPenaltyRepository, TypeOrmProtestRepository } from '@adapters/racing/persistence/typeorm/repositories/StewardingTypeOrmRepositories';
|
||||
import { TypeOrmTeamMembershipRepository, TypeOrmTeamRepository } from '@adapters/racing/persistence/typeorm/repositories/TeamTypeOrmRepositories';
|
||||
|
||||
// Import in-memory implementations for new repositories (TypeORM versions not yet implemented)
|
||||
import { InMemoryDriverStatsRepository } from '@adapters/racing/persistence/inmemory/InMemoryDriverStatsRepository';
|
||||
import { InMemoryTeamStatsRepository } from '@adapters/racing/persistence/inmemory/InMemoryTeamStatsRepository';
|
||||
import { InMemoryMediaRepository } from '@adapters/racing/persistence/media/InMemoryMediaRepository';
|
||||
|
||||
import { DriverOrmMapper } from '@adapters/racing/persistence/typeorm/mappers/DriverOrmMapper';
|
||||
import { LeagueMembershipOrmMapper } from '@adapters/racing/persistence/typeorm/mappers/LeagueMembershipOrmMapper';
|
||||
import { LeagueOrmMapper } from '@adapters/racing/persistence/typeorm/mappers/LeagueOrmMapper';
|
||||
@@ -99,6 +107,7 @@ import { PenaltyOrmMapper, ProtestOrmMapper } from '@adapters/racing/persistence
|
||||
import { TeamMembershipOrmMapper, TeamOrmMapper } from '@adapters/racing/persistence/typeorm/mappers/TeamOrmMappers';
|
||||
|
||||
import { getPointsSystems } from '@adapters/bootstrap/PointsSystems';
|
||||
import type { Logger } from '@core/shared/application/Logger';
|
||||
|
||||
const RACING_POINTS_SYSTEMS_TOKEN = 'RACING_POINTS_SYSTEMS_TOKEN';
|
||||
|
||||
@@ -305,6 +314,21 @@ const typeOrmFeatureImports = [
|
||||
new TypeOrmSponsorshipRequestRepository(repo, mapper),
|
||||
inject: [getRepositoryToken(SponsorshipRequestOrmEntity), SponsorshipRequestOrmMapper],
|
||||
},
|
||||
{
|
||||
provide: DRIVER_STATS_REPOSITORY_TOKEN,
|
||||
useFactory: (logger: Logger) => new InMemoryDriverStatsRepository(logger),
|
||||
inject: ['Logger'],
|
||||
},
|
||||
{
|
||||
provide: TEAM_STATS_REPOSITORY_TOKEN,
|
||||
useFactory: (logger: Logger) => new InMemoryTeamStatsRepository(logger),
|
||||
inject: ['Logger'],
|
||||
},
|
||||
{
|
||||
provide: MEDIA_REPOSITORY_TOKEN,
|
||||
useFactory: (logger: Logger) => new InMemoryMediaRepository(logger),
|
||||
inject: ['Logger'],
|
||||
},
|
||||
],
|
||||
exports: [
|
||||
DRIVER_REPOSITORY_TOKEN,
|
||||
@@ -327,6 +351,9 @@ const typeOrmFeatureImports = [
|
||||
SPONSOR_REPOSITORY_TOKEN,
|
||||
SPONSORSHIP_PRICING_REPOSITORY_TOKEN,
|
||||
SPONSORSHIP_REQUEST_REPOSITORY_TOKEN,
|
||||
DRIVER_STATS_REPOSITORY_TOKEN,
|
||||
TEAM_STATS_REPOSITORY_TOKEN,
|
||||
MEDIA_REPOSITORY_TOKEN,
|
||||
],
|
||||
})
|
||||
export class PostgresRacingPersistenceModule {}
|
||||
Reference in New Issue
Block a user