100 lines
3.7 KiB
TypeScript
100 lines
3.7 KiB
TypeScript
import { Result } from '@/lib/contracts/Result';
|
|
import { Service, type DomainError } from '@/lib/contracts/services/Service';
|
|
import { DriversApiClient } from '@/lib/gateways/api/drivers/DriversApiClient';
|
|
import { LeaguesApiClient } from '@/lib/gateways/api/leagues/LeaguesApiClient';
|
|
import { type LeagueSettingsApiDto } from '@/lib/types/tbd/LeagueSettingsApiDto';
|
|
import { LeagueSettingsViewModel } from '@/lib/view-models/LeagueSettingsViewModel';
|
|
import { injectable, unmanaged } from 'inversify';
|
|
|
|
@injectable()
|
|
export class LeagueSettingsService implements Service {
|
|
private static cachedMemberships = new Map<string, unknown[]>();
|
|
|
|
constructor(
|
|
@unmanaged() private readonly leaguesApiClient?: LeaguesApiClient,
|
|
@unmanaged() private readonly driversApiClient?: DriversApiClient,
|
|
) {}
|
|
|
|
async getLeagueSettings(leagueId: string): Promise<LeagueSettingsViewModel | null> {
|
|
if (!this.leaguesApiClient || !this.driversApiClient) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
const [leaguesRes, configRes, presetsRes, leaderboardRes, membershipsRes] = await Promise.all([
|
|
this.leaguesApiClient.getAllWithCapacity(),
|
|
this.leaguesApiClient.getLeagueConfig(leagueId),
|
|
this.leaguesApiClient.getScoringPresets(),
|
|
this.driversApiClient.getLeaderboard(),
|
|
this.leaguesApiClient.getMemberships(leagueId),
|
|
]);
|
|
|
|
const leaguesData = (leaguesRes as any).value || leaguesRes;
|
|
const configData = (configRes as any).value || configRes;
|
|
const presetsData = (presetsRes as any).value || presetsRes;
|
|
const leaderboardData = (leaderboardRes as any).value || leaderboardRes;
|
|
const membershipsData = (membershipsRes as any).value || membershipsRes;
|
|
|
|
const league = leaguesData.leagues.find((l: any) => l.id === leagueId);
|
|
if (!league) return null;
|
|
|
|
const ownerRes = await this.driversApiClient.getDriver(league.ownerId);
|
|
const owner = (ownerRes as any).value || ownerRes;
|
|
|
|
return new LeagueSettingsViewModel({
|
|
league,
|
|
config: configData.config || configData,
|
|
presets: presetsData.presets,
|
|
owner,
|
|
members: membershipsData.members,
|
|
drivers: leaderboardData.drivers,
|
|
} as any);
|
|
} catch (error) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
async transferOwnership(leagueId: string, currentOwnerId: string, newOwnerId: string): Promise<boolean> {
|
|
if (!this.leaguesApiClient) throw new Error('API client not initialized');
|
|
const res = await this.leaguesApiClient.transferOwnership(leagueId, currentOwnerId, newOwnerId);
|
|
const data = (res as any).value || res;
|
|
return data.success;
|
|
}
|
|
|
|
async getSettingsData(leagueId: string): Promise<Result<LeagueSettingsApiDto, DomainError>> {
|
|
// Mock data since backend not implemented
|
|
const mockData: LeagueSettingsApiDto = {
|
|
leagueId,
|
|
league: {
|
|
id: leagueId,
|
|
name: 'Mock League',
|
|
description: 'A mock league for demonstration',
|
|
visibility: 'public',
|
|
ownerId: 'owner-123',
|
|
createdAt: '2024-01-01T00:00:00Z',
|
|
updatedAt: '2024-01-01T00:00:00Z',
|
|
},
|
|
config: {
|
|
maxDrivers: 20,
|
|
scoringPresetId: 'preset-1',
|
|
allowLateJoin: true,
|
|
requireApproval: false,
|
|
},
|
|
presets: [],
|
|
owner: null,
|
|
members: [],
|
|
};
|
|
return Result.ok(mockData);
|
|
}
|
|
|
|
static getCachedMembershipsIterator(): IterableIterator<[string, unknown[]]> {
|
|
return this.cachedMemberships.entries();
|
|
}
|
|
|
|
static getMembership(leagueId: string, driverId: string): unknown | null {
|
|
const members = this.cachedMemberships.get(leagueId);
|
|
if (!members) return null;
|
|
return members.find((m: any) => m.driverId === driverId) || null;
|
|
}
|
|
}
|