code quality

This commit is contained in:
2026-01-26 17:47:37 +01:00
parent 9ac74f5046
commit 3a4f460a7d
21 changed files with 121 additions and 58 deletions

View File

@@ -15,6 +15,7 @@ import type { WithdrawFromRaceParamsDTO } from '../../../types/generated/Withdra
import { BaseApiClient } from '../base/BaseApiClient';
// Define missing types
export type { RaceDetailDTO };
export type RacesPageDataDTO = { races: RacesPageDataRaceDTO[] };
export type ImportRaceResultsSummaryDTO = {
success: boolean;

View File

@@ -41,7 +41,17 @@ export class ProtestReviewMutation implements Mutation<ApplyPenaltyCommand | Req
async applyPenalty(input: ApplyPenaltyCommand): Promise<Result<void, DomainError>> {
try {
const result = await this.service.applyPenalty(input);
const dto = {
raceId: input.raceId,
driverId: input.accusedDriverId,
stewardId: 'system', // Missing in command
type: input.penaltyType,
value: input.penaltyValue,
reason: input.reason,
protestId: input.protestId,
notes: input.stewardNotes
};
const result = await this.service.applyPenalty(dto);
if (result.isErr()) {
return Result.err(result.getError());
}

View File

@@ -60,6 +60,14 @@ export class PaymentService implements Service {
async getWallet(leagueId: string): Promise<WalletViewModel> {
const data = await this.apiClient.getWallet({ leagueId });
return new WalletViewModel({ ...data.wallet, transactions: data.transactions });
const transactions = data.transactions.map(t => ({
...t,
type: t.type as any,
fee: 0,
netAmount: t.amount,
date: t.createdAt,
status: 'completed' as const
}));
return new WalletViewModel({ ...data.wallet, transactions });
}
}

View File

@@ -23,6 +23,14 @@ export class WalletService implements Service {
async getWallet(leagueId: string): Promise<WalletViewModel> {
const data = await this.apiClient.getWallet({ leagueId });
return new WalletViewModel({ ...data.wallet, transactions: data.transactions });
const transactions = data.transactions.map(t => ({
...t,
type: t.type as any,
fee: 0, // DTO missing fee
netAmount: t.amount, // DTO missing netAmount
date: t.createdAt, // Map createdAt to date
status: 'completed' as const // DTO missing status
}));
return new WalletViewModel({ ...data.wallet, transactions });
}
}

View File

@@ -5,8 +5,10 @@ import { ApiError } from '@/lib/gateways/api/base/ApiError';
import { RacesApiClient } from '@/lib/gateways/api/races/RacesApiClient';
import { ConsoleErrorReporter } from '@/lib/infrastructure/logging/ConsoleErrorReporter';
import { ConsoleLogger } from '@/lib/infrastructure/logging/ConsoleLogger';
import type { ImportRaceResultsSummaryViewData } from '@/lib/view-data/ImportRaceResultsSummaryViewData';
import { ImportRaceResultsSummaryViewModel } from '@/lib/view-models/ImportRaceResultsSummaryViewModel';
import { RaceResultsDetailViewModel } from '@/lib/view-models/RaceResultsDetailViewModel';
import type { RaceWithSOFViewData } from '@/lib/view-data/RaceWithSOFViewData';
import { RaceWithSOFViewModel } from '@/lib/view-models/RaceWithSOFViewModel';
import { injectable, unmanaged } from 'inversify';
@@ -46,14 +48,21 @@ export class RaceResultsService implements Service {
async importResults(raceId: string, input: any): Promise<any> {
const res = await this.apiClient.importResults(raceId, input);
return new ImportRaceResultsSummaryViewModel(res);
const viewData: ImportRaceResultsSummaryViewData = {
success: res.success,
raceId: res.raceId,
driversProcessed: res.driversProcessed,
resultsRecorded: res.resultsRecorded,
errors: res.errors || [],
};
return new ImportRaceResultsSummaryViewModel(viewData);
}
/**
* Get race results detail
* Returns results for a specific race
*/
async getRaceResultsDetail(raceId: string): Promise<Result<unknown, DomainError>> {
async getRaceResultsDetail(raceId: string): Promise<Result<any, DomainError>> {
try {
const data = await this.apiClient.getResultsDetail(raceId);
return Result.ok(data);
@@ -78,7 +87,12 @@ export class RaceResultsService implements Service {
async getWithSOF(raceId: string): Promise<any> {
try {
const data = await this.apiClient.getWithSOF(raceId);
return new RaceWithSOFViewModel(data);
const viewData: RaceWithSOFViewData = {
id: data.id,
track: data.track,
strengthOfField: data.strengthOfField ?? null,
};
return new RaceWithSOFViewModel(viewData);
} catch (error: unknown) {
throw error;
}

View File

@@ -38,6 +38,17 @@ export class SponsorshipService implements Service {
async getSponsorSponsorships(sponsorId: string): Promise<SponsorSponsorshipsViewModel | null> {
const data = await this.apiClient.getSponsorships(sponsorId);
if (!data) return null;
return new SponsorSponsorshipsViewModel(data);
const mappedData = {
...data,
sponsorships: data.sponsorships.map(s => ({
...s,
type: 'league', // DTO missing type
entityName: s.leagueName, // DTO missing entityName
price: s.amount // DTO missing price
}))
};
return new SponsorSponsorshipsViewModel(mappedData as any);
}
}

View File

@@ -29,7 +29,7 @@ export interface LeaguesViewData extends ViewData {
scoring: {
gameId: string;
gameName: string;
primaryChampionshipType: string;
primaryChampionshipType: 'driver' | 'team' | 'nations' | 'trophy';
scoringPresetId: string;
scoringPresetName: string;
dropPolicySummary: string;

View File

@@ -55,13 +55,13 @@ export interface ProfileViewData extends ViewData {
icon: 'trophy' | 'medal' | 'star' | 'crown' | 'target' | 'zap';
rarityLabel: string;
}>;
friends: Array<{
friends?: Array<{
id: string;
name: string;
countryFlag: string;
avatarUrl: string;
href: string;
}>;
friendsCountLabel: string;
friendsCountLabel?: string;
} | null;
}

View File

@@ -24,7 +24,11 @@ export interface TeamDetailData {
region?: string;
languages?: string[] | null;
category?: string;
membership?: string | null;
membership?: {
role: string;
joinedAt: string;
isActive: boolean;
} | null;
canManage: boolean;
}

View File

@@ -4,15 +4,15 @@ export interface TeamSummaryViewData {
tag: string;
memberCount: number;
description?: string;
totalWins: number;
totalRaces: number;
performanceLevel: 'beginner' | 'intermediate' | 'advanced' | 'pro';
totalWins?: number;
totalRaces?: number;
performanceLevel?: string;
isRecruiting: boolean;
specialization: 'endurance' | 'sprint' | 'mixed' | undefined;
region: string | undefined;
languages: string[];
leagues: string[];
logoUrl: string | undefined;
rating: number | undefined;
category: string | undefined;
specialization?: string;
region?: string;
languages?: string[];
leagues?: string[];
logoUrl?: string;
rating?: number;
category?: string;
}

View File

@@ -2,7 +2,7 @@ import { ViewModel } from "../contracts/view-models/ViewModel";
import { ProfileViewData } from "../view-data/ProfileViewData";
import { DriverProfileDriverSummaryViewModel } from "./DriverProfileDriverSummaryViewModel";
export { DriverProfileDriverSummaryViewModel as DriverProfileSocialSummaryViewModel };
export { DriverProfileDriverSummaryViewModel };
export interface DriverProfileStatsViewModel extends ViewModel {
totalRaces: number;

View File

@@ -9,16 +9,16 @@ import type { DriverSummaryData } from "../view-data/DriverSummaryData";
* Client-only UI helper built from ViewData.
*/
export class DriverSummaryViewModel extends ViewModel {
constructor(private readonly viewData: DriverSummaryData) {
constructor(private readonly viewData: any) {
super();
}
get id(): string {
return this.viewData.driverId;
return this.viewData.driverId || this.viewData.id;
}
get name(): string {
return this.viewData.driverName;
return this.viewData.driverName || this.viewData.name;
}
get avatarUrl(): string | null {

View File

@@ -2,6 +2,8 @@ import { ViewModel } from "../contracts/view-models/ViewModel";
import type { LeagueScheduleViewData } from "../view-data/LeagueScheduleViewData";
import { LeagueScheduleRaceViewModel } from "./LeagueScheduleRaceViewModel";
export { LeagueScheduleRaceViewModel };
export class LeagueScheduleViewModel extends ViewModel {
readonly races: LeagueScheduleRaceViewModel[];

View File

@@ -1,5 +1,7 @@
import { ViewModel } from "../contracts/view-models/ViewModel";
import type { CustomPointsConfig, ScoringConfigurationViewData } from "../view-data/ScoringConfigurationViewData";
export type { CustomPointsConfig };
import { LeagueScoringPresetViewModel } from './LeagueScoringPresetViewModel';
export class ScoringConfigurationViewModel extends ViewModel {

View File

@@ -15,14 +15,14 @@ export class TeamSummaryViewModel extends ViewModel {
get tag(): string { return this.data.tag; }
get memberCount(): number { return this.data.memberCount; }
get description(): string | undefined { return this.data.description; }
get totalWins(): number { return this.data.totalWins; }
get totalRaces(): number { return this.data.totalRaces; }
get performanceLevel(): string { return this.data.performanceLevel; }
get totalWins(): number { return this.data.totalWins || 0; }
get totalRaces(): number { return this.data.totalRaces || 0; }
get performanceLevel(): string { return this.data.performanceLevel || 'beginner'; }
get isRecruiting(): boolean { return this.data.isRecruiting; }
get specialization(): string | undefined { return this.data.specialization; }
get region(): string | undefined { return this.data.region; }
get languages(): string[] { return this.data.languages; }
get leagues(): string[] { return this.data.leagues; }
get languages(): string[] { return this.data.languages || []; }
get leagues(): string[] { return this.data.leagues || []; }
get logoUrl(): string | undefined { return this.data.logoUrl; }
get rating(): number | undefined { return this.data.rating; }
get category(): string | undefined { return this.data.category; }