website refactor
This commit is contained in:
@@ -32,8 +32,6 @@ import { InMemoryDriverExtendedProfileProvider } from '@adapters/racing/ports/In
|
||||
import { InMemoryDriverRatingProvider } from '@adapters/racing/ports/InMemoryDriverRatingProvider';
|
||||
// Import new use cases
|
||||
// Import new repositories
|
||||
import { InMemoryDriverStatsRepository } from '@adapters/racing/persistence/inmemory/InMemoryDriverStatsRepository';
|
||||
import { InMemoryMediaRepository } from '@adapters/racing/persistence/media/InMemoryMediaRepository';
|
||||
// Import MediaResolverAdapter
|
||||
import { MediaResolverAdapter } from '@adapters/media/MediaResolverAdapter';
|
||||
// Import repository tokens
|
||||
@@ -67,7 +65,6 @@ import {
|
||||
IS_DRIVER_REGISTERED_FOR_RACE_USE_CASE_TOKEN,
|
||||
LIVERY_REPOSITORY_TOKEN,
|
||||
LOGGER_TOKEN,
|
||||
MEDIA_REPOSITORY_TOKEN,
|
||||
MEDIA_RESOLVER_TOKEN,
|
||||
NOTIFICATION_PREFERENCE_REPOSITORY_TOKEN,
|
||||
RACE_REGISTRATION_REPOSITORY_TOKEN,
|
||||
@@ -133,48 +130,25 @@ export const DriverProviders: Provider[] = createLoggedProviders([
|
||||
},
|
||||
|
||||
// Repositories (racing + social repos are provided by imported persistence modules)
|
||||
{
|
||||
provide: DRIVER_STATS_REPOSITORY_TOKEN,
|
||||
useFactory: (logger: Logger) => new InMemoryDriverStatsRepository(logger),
|
||||
inject: [LOGGER_TOKEN],
|
||||
},
|
||||
{
|
||||
provide: MEDIA_REPOSITORY_TOKEN,
|
||||
useFactory: (logger: Logger) => {
|
||||
const mediaRepo = new InMemoryMediaRepository(logger);
|
||||
|
||||
// Override getTeamLogo to provide fallback URLs
|
||||
const originalGetTeamLogo = mediaRepo.getTeamLogo.bind(mediaRepo);
|
||||
mediaRepo.getTeamLogo = async (teamId: string): Promise<string | null> => {
|
||||
const logo = await originalGetTeamLogo(teamId);
|
||||
if (logo) return logo;
|
||||
|
||||
// Fallback: generate deterministic team logo URL
|
||||
// Use path-only URL
|
||||
return `/media/teams/${teamId}/logo`;
|
||||
};
|
||||
|
||||
return mediaRepo;
|
||||
},
|
||||
inject: [LOGGER_TOKEN],
|
||||
},
|
||||
{
|
||||
provide: RANKING_SERVICE_TOKEN,
|
||||
useFactory: (
|
||||
standingRepo: StandingRepository,
|
||||
driverRepo: DriverRepository,
|
||||
driverStatsRepo: DriverStatsRepository,
|
||||
logger: Logger
|
||||
) => new RankingUseCase(standingRepo, driverRepo, logger),
|
||||
inject: ['IStandingRepository', DRIVER_REPOSITORY_TOKEN, LOGGER_TOKEN],
|
||||
) => new RankingUseCase(standingRepo, driverRepo, driverStatsRepo, logger),
|
||||
inject: ['IStandingRepository', DRIVER_REPOSITORY_TOKEN, DRIVER_STATS_REPOSITORY_TOKEN, LOGGER_TOKEN],
|
||||
},
|
||||
{
|
||||
provide: DRIVER_STATS_SERVICE_TOKEN,
|
||||
useFactory: (
|
||||
resultRepo: ResultRepository,
|
||||
standingRepo: StandingRepository,
|
||||
driverStatsRepo: DriverStatsRepository,
|
||||
logger: Logger
|
||||
) => new DriverStatsUseCase(resultRepo, standingRepo, logger),
|
||||
inject: ['IResultRepository', 'IStandingRepository', LOGGER_TOKEN],
|
||||
) => new DriverStatsUseCase(resultRepo, standingRepo, driverStatsRepo, logger),
|
||||
inject: ['IResultRepository', 'IStandingRepository', DRIVER_STATS_REPOSITORY_TOKEN, LOGGER_TOKEN],
|
||||
},
|
||||
{
|
||||
provide: DRIVER_RATING_PROVIDER_TOKEN,
|
||||
|
||||
@@ -88,6 +88,27 @@ describe('Team domain (HTTP, module-wiring)', () => {
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('returns leaderboard with non-zero ratings and wins', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.get('/teams/leaderboard')
|
||||
.expect(200);
|
||||
|
||||
expect(response.body).toBeDefined();
|
||||
expect(response.body.teams).toBeDefined();
|
||||
expect(Array.isArray(response.body.teams)).toBe(true);
|
||||
|
||||
// Verify that teams have non-zero ratings and wins
|
||||
if (response.body.teams.length > 0) {
|
||||
const team = response.body.teams[0];
|
||||
expect(team).toBeDefined();
|
||||
expect(team.rating).not.toBeNull();
|
||||
expect(typeof team.rating).toBe('number');
|
||||
expect(team.rating).toBeGreaterThan(0);
|
||||
expect(team.totalWins).toBeGreaterThan(0);
|
||||
expect(team.totalRaces).toBeGreaterThan(0);
|
||||
}
|
||||
});
|
||||
|
||||
it('rejects unauthenticated actor on create team (401)', async () => {
|
||||
await request(app.getHttpServer())
|
||||
.post('/teams')
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
TEAM_STATS_REPOSITORY_TOKEN,
|
||||
UPDATE_TEAM_USE_CASE_TOKEN,
|
||||
GET_TEAMS_LEADERBOARD_USE_CASE_TOKEN,
|
||||
DRIVER_STATS_REPOSITORY_TOKEN,
|
||||
} from './TeamTokens';
|
||||
|
||||
export {
|
||||
@@ -165,11 +166,15 @@ export const TeamProviders: Provider[] = [
|
||||
},
|
||||
{
|
||||
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);
|
||||
useFactory: async (teamRepo: TeamRepository, membershipRepo: TeamMembershipRepository, driverStatsRepo: DriverStatsRepository, logger: Logger) => {
|
||||
// Pre-fetch all driver stats for efficient lookup
|
||||
const allStats = await driverStatsRepo.getAllStats();
|
||||
|
||||
return new GetTeamsLeaderboardUseCase(teamRepo, membershipRepo, (driverId) => {
|
||||
const stats = allStats.get(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],
|
||||
}, logger);
|
||||
},
|
||||
inject: [TEAM_REPOSITORY_TOKEN, TEAM_MEMBERSHIP_REPOSITORY_TOKEN, DRIVER_STATS_REPOSITORY_TOKEN, LOGGER_TOKEN],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -7,6 +7,7 @@ export const TEAM_STATS_REPOSITORY_TOKEN = 'ITeamStatsRepository';
|
||||
export const MEDIA_REPOSITORY_TOKEN = 'IMediaRepository';
|
||||
export const MEDIA_RESOLVER_TOKEN = 'MediaResolverPort';
|
||||
export const RESULT_REPOSITORY_TOKEN = 'IResultRepository';
|
||||
export const DRIVER_STATS_REPOSITORY_TOKEN = 'IDriverStatsRepository';
|
||||
|
||||
export const GET_ALL_TEAMS_USE_CASE_TOKEN = Symbol('GET_ALL_TEAMS_USE_CASE_TOKEN');
|
||||
export const GET_TEAM_DETAILS_USE_CASE_TOKEN = Symbol('GET_TEAM_DETAILS_USE_CASE_TOKEN');
|
||||
|
||||
Reference in New Issue
Block a user