di usage in website

This commit is contained in:
2026-01-06 19:36:03 +01:00
parent 589b55a87e
commit e589c30bf8
191 changed files with 6367 additions and 4253 deletions

View File

@@ -1,8 +0,0 @@
import { describe, it, expect } from 'vitest';
import { ServiceFactory } from './ServiceFactory';
describe('ServiceFactory', () => {
it('should be defined', () => {
expect(ServiceFactory).toBeDefined();
});
});

View File

@@ -1,331 +0,0 @@
import { RacesApiClient } from '../api/races/RacesApiClient';
import { DriversApiClient } from '../api/drivers/DriversApiClient';
import { TeamsApiClient } from '../api/teams/TeamsApiClient';
import { LeaguesApiClient } from '../api/leagues/LeaguesApiClient';
import { SponsorsApiClient } from '../api/sponsors/SponsorsApiClient';
import { PaymentsApiClient } from '../api/payments/PaymentsApiClient';
import { WalletsApiClient } from '../api/wallets/WalletsApiClient';
import { AuthApiClient } from '../api/auth/AuthApiClient';
import { AnalyticsApiClient } from '../api/analytics/AnalyticsApiClient';
import { MediaApiClient } from '../api/media/MediaApiClient';
import { DashboardApiClient } from '../api/dashboard/DashboardApiClient';
import { PolicyApiClient } from '../api/policy/PolicyApiClient';
import { ProtestsApiClient } from '../api/protests/ProtestsApiClient';
import { PenaltiesApiClient } from '../api/penalties/PenaltiesApiClient';
import { getWebsiteApiBaseUrl } from '../config/apiBaseUrl';
import { PenaltyService } from './penalties/PenaltyService';
import { EnhancedErrorReporter } from '../infrastructure/EnhancedErrorReporter';
import { ConsoleLogger } from '../infrastructure/logging/ConsoleLogger';
import { LandingService } from './landing/LandingService';
// Services
import { RaceService } from './races/RaceService';
import { RaceResultsService } from './races/RaceResultsService';
import { RaceStewardingService } from './races/RaceStewardingService';
import { DriverService } from './drivers/DriverService';
import { DriverRegistrationService } from './drivers/DriverRegistrationService';
import { TeamService } from './teams/TeamService';
import { TeamJoinService } from './teams/TeamJoinService';
import { LeagueService } from './leagues/LeagueService';
import { LeagueMembershipService } from './leagues/LeagueMembershipService';
import { LeagueSettingsService } from './leagues/LeagueSettingsService';
import { LeagueStewardingService } from './leagues/LeagueStewardingService';
import { LeagueWalletService } from './leagues/LeagueWalletService';
import { SponsorService } from './sponsors/SponsorService';
import { SponsorshipService } from './sponsors/SponsorshipService';
import { PaymentService } from './payments/PaymentService';
import { AnalyticsService } from './analytics/AnalyticsService';
import { DashboardService as AnalyticsDashboardService } from './analytics/DashboardService';
import { DashboardService } from './dashboard/DashboardService';
import { MediaService } from './media/MediaService';
import { AvatarService } from './media/AvatarService';
import { WalletService } from './payments/WalletService';
import { MembershipFeeService } from './payments/MembershipFeeService';
import { AuthService } from './auth/AuthService';
import { SessionService } from './auth/SessionService';
import { ProtestService } from './protests/ProtestService';
import { PolicyService } from './policy/PolicyService';
import { OnboardingService } from './onboarding/OnboardingService';
/**
* ServiceFactory - Composition root for all services
*
* Centralizes service creation and dependency injection wiring.
* Each factory method creates fresh instances with proper dependencies.
* Services now directly instantiate View Models instead of using Presenters.
*/
export class ServiceFactory {
private readonly errorReporter = new EnhancedErrorReporter(new ConsoleLogger(), {
showUserNotifications: true,
logToConsole: true,
reportToExternal: process.env.NODE_ENV === 'production',
});
private readonly logger = new ConsoleLogger();
private readonly apiClients: {
races: RacesApiClient;
drivers: DriversApiClient;
teams: TeamsApiClient;
leagues: LeaguesApiClient;
sponsors: SponsorsApiClient;
payments: PaymentsApiClient;
wallets: WalletsApiClient;
auth: AuthApiClient;
analytics: AnalyticsApiClient;
media: MediaApiClient;
dashboard: DashboardApiClient;
policy: PolicyApiClient;
protests: ProtestsApiClient;
penalties: PenaltiesApiClient;
};
constructor(baseUrl: string) {
// Initialize API clients
this.apiClients = {
races: new RacesApiClient(baseUrl, this.errorReporter, this.logger),
drivers: new DriversApiClient(baseUrl, this.errorReporter, this.logger),
teams: new TeamsApiClient(baseUrl, this.errorReporter, this.logger),
leagues: new LeaguesApiClient(baseUrl, this.errorReporter, this.logger),
sponsors: new SponsorsApiClient(baseUrl, this.errorReporter, this.logger),
payments: new PaymentsApiClient(baseUrl, this.errorReporter, this.logger),
wallets: new WalletsApiClient(baseUrl, this.errorReporter, this.logger),
auth: new AuthApiClient(baseUrl, this.errorReporter, this.logger),
analytics: new AnalyticsApiClient(baseUrl, this.errorReporter, this.logger),
media: new MediaApiClient(baseUrl, this.errorReporter, this.logger),
dashboard: new DashboardApiClient(baseUrl, this.errorReporter, this.logger),
policy: new PolicyApiClient(baseUrl, this.errorReporter, this.logger),
protests: new ProtestsApiClient(baseUrl, this.errorReporter, this.logger),
penalties: new PenaltiesApiClient(baseUrl, this.errorReporter, this.logger),
};
}
/**
* Legacy compatibility: older pages/components were written against a static ServiceFactory.
* Prefer `useServices()` + react-query hooks.
*/
private static defaultInstance: ServiceFactory | null = null;
private static getDefaultInstance(): ServiceFactory {
if (!this.defaultInstance) {
this.defaultInstance = new ServiceFactory(getWebsiteApiBaseUrl());
}
return this.defaultInstance;
}
static getSponsorService(): SponsorService {
return this.getDefaultInstance().createSponsorService();
}
/**
* Create RaceService instance
*/
createRaceService(): RaceService {
return new RaceService(this.apiClients.races);
}
/**
* Create RaceResultsService instance
*/
createRaceResultsService(): RaceResultsService {
return new RaceResultsService(this.apiClients.races);
}
/**
* Create RaceStewardingService instance
*/
createRaceStewardingService(): RaceStewardingService {
return new RaceStewardingService(
this.apiClients.races,
this.apiClients.protests,
this.apiClients.penalties
);
}
/**
* Create DriverService instance
*/
createDriverService(): DriverService {
return new DriverService(this.apiClients.drivers);
}
/**
* Create DriverRegistrationService instance
*/
createDriverRegistrationService(): DriverRegistrationService {
return new DriverRegistrationService(this.apiClients.drivers);
}
/**
* Create TeamService instance
*/
createTeamService(): TeamService {
return new TeamService(this.apiClients.teams);
}
/**
* Create TeamJoinService instance
*/
createTeamJoinService(): TeamJoinService {
return new TeamJoinService(this.apiClients.teams);
}
/**
* Create LeagueService instance
*/
createLeagueService(): LeagueService {
return new LeagueService(this.apiClients.leagues, this.apiClients.drivers, this.apiClients.sponsors, this.apiClients.races);
}
/**
* Create LeagueMembershipService instance
*/
createLeagueMembershipService(): LeagueMembershipService {
return new LeagueMembershipService();
}
/**
* Create LeagueSettingsService instance
*/
createLeagueSettingsService(): LeagueSettingsService {
return new LeagueSettingsService(this.apiClients.leagues, this.apiClients.drivers);
}
/**
* Create LeagueStewardingService instance
*/
createLeagueStewardingService(): LeagueStewardingService {
return new LeagueStewardingService(
this.createRaceService(),
this.createProtestService(),
this.createPenaltyService(),
this.createDriverService(),
this.createLeagueMembershipService()
);
}
/**
* Create LeagueWalletService instance
*/
createLeagueWalletService(): LeagueWalletService {
return new LeagueWalletService(this.apiClients.wallets);
}
/**
* Create SponsorService instance
*/
createSponsorService(): SponsorService {
return new SponsorService(this.apiClients.sponsors);
}
/**
* Create SponsorshipService instance
*/
createSponsorshipService(): SponsorshipService {
return new SponsorshipService(this.apiClients.sponsors);
}
/**
* Create PaymentService instance
*/
createPaymentService(): PaymentService {
return new PaymentService(this.apiClients.payments);
}
/**
* Create AnalyticsService instance
*/
createAnalyticsService(): AnalyticsService {
return new AnalyticsService(this.apiClients.analytics);
}
/**
* Create Analytics DashboardService instance
*/
createAnalyticsDashboardService(): AnalyticsDashboardService {
return new AnalyticsDashboardService(this.apiClients.analytics);
}
/**
* Create PolicyService instance
*/
createPolicyService(): PolicyService {
return new PolicyService(this.apiClients.policy);
}
/**
* Create DashboardService instance
*/
createDashboardService(): DashboardService {
return new DashboardService(this.apiClients.dashboard);
}
/**
* Create MediaService instance
*/
createMediaService(): MediaService {
return new MediaService(this.apiClients.media);
}
/**
* Create AvatarService instance
*/
createAvatarService(): AvatarService {
return new AvatarService(this.apiClients.media);
}
/**
* Create WalletService instance
*/
createWalletService(): WalletService {
return new WalletService(this.apiClients.payments);
}
/**
* Create MembershipFeeService instance
*/
createMembershipFeeService(): MembershipFeeService {
return new MembershipFeeService(this.apiClients.payments);
}
/**
* Create AuthService instance
*/
createAuthService(): AuthService {
return new AuthService(this.apiClients.auth);
}
/**
* Create SessionService instance
*/
createSessionService(): SessionService {
return new SessionService(this.apiClients.auth);
}
/**
* Create ProtestService instance
*/
createProtestService(): ProtestService {
return new ProtestService(this.apiClients.protests);
}
/**
* Create PenaltyService instance
*/
createPenaltyService(): PenaltyService {
return new PenaltyService(this.apiClients.penalties);
}
/**
* Create OnboardingService instance
*/
createOnboardingService(): OnboardingService {
return new OnboardingService(this.apiClients.media, this.apiClients.drivers);
}
/**
* Create LandingService instance (used by server components)
*/
createLandingService(): LandingService {
return new LandingService(this.apiClients.races, this.apiClients.leagues, this.apiClients.teams, this.apiClients.auth);
}
}

View File

@@ -1,8 +0,0 @@
import { describe, it, expect } from 'vitest';
import { ServiceProvider } from './ServiceProvider';
describe('ServiceProvider', () => {
it('should be defined', () => {
expect(ServiceProvider).toBeDefined();
});
});

View File

@@ -1,135 +0,0 @@
'use client';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { createContext, ReactNode, useContext, useMemo } from 'react';
import { getWebsiteApiBaseUrl } from '../config/apiBaseUrl';
import { ServiceFactory } from './ServiceFactory';
// Import all service types
import { AnalyticsService } from './analytics/AnalyticsService';
import { AuthService } from './auth/AuthService';
import { SessionService } from './auth/SessionService';
import { DashboardService } from './dashboard/DashboardService';
import { DriverRegistrationService } from './drivers/DriverRegistrationService';
import { DriverService } from './drivers/DriverService';
import { LeagueMembershipService } from './leagues/LeagueMembershipService';
import { LeagueService } from './leagues/LeagueService';
import { LeagueSettingsService } from './leagues/LeagueSettingsService';
import { LeagueStewardingService } from './leagues/LeagueStewardingService';
import { LeagueWalletService } from './leagues/LeagueWalletService';
import { AvatarService } from './media/AvatarService';
import { MediaService } from './media/MediaService';
import { MembershipFeeService } from './payments/MembershipFeeService';
import { PaymentService } from './payments/PaymentService';
import { WalletService } from './payments/WalletService';
import { PenaltyService } from './penalties/PenaltyService';
import { ProtestService } from './protests/ProtestService';
import { RaceResultsService } from './races/RaceResultsService';
import { RaceService } from './races/RaceService';
import { RaceStewardingService } from './races/RaceStewardingService';
import { SponsorService } from './sponsors/SponsorService';
import { SponsorshipService } from './sponsors/SponsorshipService';
import { TeamJoinService } from './teams/TeamJoinService';
import { TeamService } from './teams/TeamService';
import { OnboardingService } from './onboarding/OnboardingService';
import { PolicyService } from './policy/PolicyService';
import { LandingService } from './landing/LandingService';
export interface Services {
raceService: RaceService;
raceResultsService: RaceResultsService;
raceStewardingService: RaceStewardingService;
driverService: DriverService;
driverRegistrationService: DriverRegistrationService;
teamService: TeamService;
teamJoinService: TeamJoinService;
leagueService: LeagueService;
leagueMembershipService: LeagueMembershipService;
leagueSettingsService: LeagueSettingsService;
leagueStewardingService: LeagueStewardingService;
leagueWalletService: LeagueWalletService;
sponsorService: SponsorService;
sponsorshipService: SponsorshipService;
paymentService: PaymentService;
analyticsService: AnalyticsService;
dashboardService: DashboardService;
mediaService: MediaService;
avatarService: AvatarService;
walletService: WalletService;
membershipFeeService: MembershipFeeService;
authService: AuthService;
sessionService: SessionService;
protestService: ProtestService;
penaltyService: PenaltyService;
onboardingService: OnboardingService;
policyService: PolicyService;
landingService: LandingService;
}
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 5 * 60 * 1000, // 5 minutes
gcTime: 10 * 60 * 1000, // 10 minutes
},
},
});
const ServicesContext = createContext<Services | null>(null);
interface ServiceProviderProps {
children: ReactNode;
}
export function ServiceProvider({ children }: ServiceProviderProps) {
const services = useMemo(() => {
const serviceFactory = new ServiceFactory(getWebsiteApiBaseUrl());
return {
raceService: serviceFactory.createRaceService(),
raceResultsService: serviceFactory.createRaceResultsService(),
raceStewardingService: serviceFactory.createRaceStewardingService(),
driverService: serviceFactory.createDriverService(),
driverRegistrationService: serviceFactory.createDriverRegistrationService(),
teamService: serviceFactory.createTeamService(),
teamJoinService: serviceFactory.createTeamJoinService(),
leagueService: serviceFactory.createLeagueService(),
leagueMembershipService: serviceFactory.createLeagueMembershipService(),
leagueSettingsService: serviceFactory.createLeagueSettingsService(),
leagueStewardingService: serviceFactory.createLeagueStewardingService(),
leagueWalletService: serviceFactory.createLeagueWalletService(),
sponsorService: serviceFactory.createSponsorService(),
sponsorshipService: serviceFactory.createSponsorshipService(),
paymentService: serviceFactory.createPaymentService(),
analyticsService: serviceFactory.createAnalyticsService(),
dashboardService: serviceFactory.createDashboardService(),
mediaService: serviceFactory.createMediaService(),
avatarService: serviceFactory.createAvatarService(),
walletService: serviceFactory.createWalletService(),
membershipFeeService: serviceFactory.createMembershipFeeService(),
authService: serviceFactory.createAuthService(),
sessionService: serviceFactory.createSessionService(),
protestService: serviceFactory.createProtestService(),
penaltyService: serviceFactory.createPenaltyService(),
onboardingService: serviceFactory.createOnboardingService(),
policyService: serviceFactory.createPolicyService(),
landingService: serviceFactory.createLandingService(),
};
}, []);
return (
<QueryClientProvider client={queryClient}>
<ServicesContext.Provider value={services}>
{children}
</ServicesContext.Provider>
</QueryClientProvider>
);
}
// Before using this check for enhanced hooks that use react-query
export function useServices(): Services {
const services = useContext(ServicesContext);
if (!services) {
throw new Error('useServices must be used within a ServiceProvider');
}
return services;
}