team rating

This commit is contained in:
2025-12-30 12:25:45 +01:00
parent ccaa39c39c
commit 83371ea839
93 changed files with 10324 additions and 490 deletions

View File

@@ -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',
],
},
{

View File

@@ -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: [

View File

@@ -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';

View File

@@ -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,

View File

@@ -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],
},
];

View File

@@ -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 () => {

View File

@@ -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> {

View File

@@ -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';

View File

@@ -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,

View File

@@ -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 {}

View File

@@ -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 {}