alpha wip
This commit is contained in:
187
apps/website/lib/di-container.ts
Normal file
187
apps/website/lib/di-container.ts
Normal file
@@ -0,0 +1,187 @@
|
||||
/**
|
||||
* Dependency Injection Container
|
||||
*
|
||||
* Initializes all in-memory repositories and provides accessor functions.
|
||||
* Allows easy swapping to persistent repositories later.
|
||||
*/
|
||||
|
||||
import { Driver } from '../domain/entities/Driver';
|
||||
import { League } from '../domain/entities/League';
|
||||
import { Race } from '../domain/entities/Race';
|
||||
import { Result } from '../domain/entities/Result';
|
||||
import { Standing } from '../domain/entities/Standing';
|
||||
|
||||
import { IDriverRepository } from '../application/ports/IDriverRepository';
|
||||
import { ILeagueRepository } from '../application/ports/ILeagueRepository';
|
||||
import { IRaceRepository } from '../application/ports/IRaceRepository';
|
||||
import { IResultRepository } from '../application/ports/IResultRepository';
|
||||
import { IStandingRepository } from '../application/ports/IStandingRepository';
|
||||
|
||||
import { InMemoryDriverRepository } from '../infrastructure/repositories/InMemoryDriverRepository';
|
||||
import { InMemoryLeagueRepository } from '../infrastructure/repositories/InMemoryLeagueRepository';
|
||||
import { InMemoryRaceRepository } from '../infrastructure/repositories/InMemoryRaceRepository';
|
||||
import { InMemoryResultRepository } from '../infrastructure/repositories/InMemoryResultRepository';
|
||||
import { InMemoryStandingRepository } from '../infrastructure/repositories/InMemoryStandingRepository';
|
||||
|
||||
/**
|
||||
* Seed data for development
|
||||
*/
|
||||
function createSeedData() {
|
||||
// Create a sample driver
|
||||
const driver1 = Driver.create({
|
||||
id: '550e8400-e29b-41d4-a716-446655440001',
|
||||
iracingId: '123456',
|
||||
name: 'Max Verstappen',
|
||||
country: 'NL',
|
||||
bio: 'Three-time world champion',
|
||||
joinedAt: new Date('2024-01-15'),
|
||||
});
|
||||
|
||||
// Create a sample league
|
||||
const league1 = League.create({
|
||||
id: '550e8400-e29b-41d4-a716-446655440002',
|
||||
name: 'European GT Championship',
|
||||
description: 'Weekly GT3 racing with professional drivers',
|
||||
ownerId: driver1.id,
|
||||
settings: {
|
||||
pointsSystem: 'f1-2024',
|
||||
sessionDuration: 60,
|
||||
qualifyingFormat: 'open',
|
||||
},
|
||||
createdAt: new Date('2024-01-20'),
|
||||
});
|
||||
|
||||
// Create sample races
|
||||
const race1 = Race.create({
|
||||
id: '550e8400-e29b-41d4-a716-446655440003',
|
||||
leagueId: league1.id,
|
||||
scheduledAt: new Date('2024-03-15T19:00:00Z'),
|
||||
track: 'Monza GP',
|
||||
car: 'Porsche 911 GT3 R',
|
||||
sessionType: 'race',
|
||||
status: 'completed',
|
||||
});
|
||||
|
||||
const race2 = Race.create({
|
||||
id: '550e8400-e29b-41d4-a716-446655440004',
|
||||
leagueId: league1.id,
|
||||
scheduledAt: new Date('2024-03-22T19:00:00Z'),
|
||||
track: 'Spa-Francorchamps',
|
||||
car: 'Porsche 911 GT3 R',
|
||||
sessionType: 'race',
|
||||
status: 'scheduled',
|
||||
});
|
||||
|
||||
return {
|
||||
drivers: [driver1],
|
||||
leagues: [league1],
|
||||
races: [race1, race2],
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* DI Container class
|
||||
*/
|
||||
class DIContainer {
|
||||
private static instance: DIContainer;
|
||||
|
||||
private _driverRepository: IDriverRepository;
|
||||
private _leagueRepository: ILeagueRepository;
|
||||
private _raceRepository: IRaceRepository;
|
||||
private _resultRepository: IResultRepository;
|
||||
private _standingRepository: IStandingRepository;
|
||||
|
||||
private constructor() {
|
||||
// Create seed data
|
||||
const seedData = createSeedData();
|
||||
|
||||
// Initialize repositories with seed data
|
||||
this._driverRepository = new InMemoryDriverRepository(seedData.drivers);
|
||||
this._leagueRepository = new InMemoryLeagueRepository(seedData.leagues);
|
||||
this._raceRepository = new InMemoryRaceRepository(seedData.races);
|
||||
|
||||
// Result repository needs race repository for league-based queries
|
||||
this._resultRepository = new InMemoryResultRepository(
|
||||
undefined,
|
||||
this._raceRepository
|
||||
);
|
||||
|
||||
// Standing repository needs all three for recalculation
|
||||
this._standingRepository = new InMemoryStandingRepository(
|
||||
undefined,
|
||||
this._resultRepository,
|
||||
this._raceRepository,
|
||||
this._leagueRepository
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get singleton instance
|
||||
*/
|
||||
static getInstance(): DIContainer {
|
||||
if (!DIContainer.instance) {
|
||||
DIContainer.instance = new DIContainer();
|
||||
}
|
||||
return DIContainer.instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the container (useful for testing)
|
||||
*/
|
||||
static reset(): void {
|
||||
DIContainer.instance = new DIContainer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Repository getters
|
||||
*/
|
||||
get driverRepository(): IDriverRepository {
|
||||
return this._driverRepository;
|
||||
}
|
||||
|
||||
get leagueRepository(): ILeagueRepository {
|
||||
return this._leagueRepository;
|
||||
}
|
||||
|
||||
get raceRepository(): IRaceRepository {
|
||||
return this._raceRepository;
|
||||
}
|
||||
|
||||
get resultRepository(): IResultRepository {
|
||||
return this._resultRepository;
|
||||
}
|
||||
|
||||
get standingRepository(): IStandingRepository {
|
||||
return this._standingRepository;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exported accessor functions
|
||||
*/
|
||||
export function getDriverRepository(): IDriverRepository {
|
||||
return DIContainer.getInstance().driverRepository;
|
||||
}
|
||||
|
||||
export function getLeagueRepository(): ILeagueRepository {
|
||||
return DIContainer.getInstance().leagueRepository;
|
||||
}
|
||||
|
||||
export function getRaceRepository(): IRaceRepository {
|
||||
return DIContainer.getInstance().raceRepository;
|
||||
}
|
||||
|
||||
export function getResultRepository(): IResultRepository {
|
||||
return DIContainer.getInstance().resultRepository;
|
||||
}
|
||||
|
||||
export function getStandingRepository(): IStandingRepository {
|
||||
return DIContainer.getInstance().standingRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset function for testing
|
||||
*/
|
||||
export function resetContainer(): void {
|
||||
DIContainer.reset();
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
/**
|
||||
* Mode detection system for GridPilot website
|
||||
*
|
||||
* Controls whether the site shows pre-launch content or full platform
|
||||
* Based on GRIDPILOT_MODE environment variable
|
||||
*
|
||||
* Controls whether the site shows pre-launch content or alpha platform
|
||||
* Based on NEXT_PUBLIC_GRIDPILOT_MODE environment variable
|
||||
*/
|
||||
|
||||
export type AppMode = 'pre-launch' | 'post-launch';
|
||||
export type AppMode = 'pre-launch' | 'alpha';
|
||||
|
||||
const VALID_MODES: readonly AppMode[] = ['pre-launch', 'post-launch'] as const;
|
||||
const VALID_MODES: readonly AppMode[] = ['pre-launch', 'alpha'] as const;
|
||||
|
||||
/**
|
||||
* Get the current application mode from environment variable
|
||||
@@ -17,7 +17,7 @@ const VALID_MODES: readonly AppMode[] = ['pre-launch', 'post-launch'] as const;
|
||||
* @returns {AppMode} The current application mode
|
||||
*/
|
||||
export function getAppMode(): AppMode {
|
||||
const mode = process.env.GRIDPILOT_MODE;
|
||||
const mode = process.env.NEXT_PUBLIC_GRIDPILOT_MODE;
|
||||
|
||||
if (!mode) {
|
||||
return 'pre-launch';
|
||||
@@ -25,7 +25,7 @@ export function getAppMode(): AppMode {
|
||||
|
||||
if (!isValidMode(mode)) {
|
||||
const validModes = VALID_MODES.join(', ');
|
||||
const error = `Invalid GRIDPILOT_MODE: "${mode}". Must be one of: ${validModes}`;
|
||||
const error = `Invalid NEXT_PUBLIC_GRIDPILOT_MODE: "${mode}". Must be one of: ${validModes}`;
|
||||
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
throw new Error(error);
|
||||
@@ -53,10 +53,10 @@ export function isPreLaunch(): boolean {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if currently in post-launch mode
|
||||
* Check if currently in alpha mode
|
||||
*/
|
||||
export function isPostLaunch(): boolean {
|
||||
return getAppMode() === 'post-launch';
|
||||
export function isAlpha(): boolean {
|
||||
return getAppMode() === 'alpha';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user