refactor dtos to ports

This commit is contained in:
2025-12-19 14:08:27 +01:00
parent 2ab86ec9bd
commit 499562c456
106 changed files with 386 additions and 1009 deletions

View File

@@ -1,3 +0,0 @@
export interface DriverRatingPort {
getRating(driverId: string): { rating: number | null; ratingChange: number | null };
}

View File

@@ -1,20 +0,0 @@
/**
* Application Port: DriverRatingProvider
*
* Port for looking up driver ratings.
* Implemented by infrastructure adapters that connect to rating systems.
*/
export interface DriverRatingProvider {
/**
* Get the rating for a single driver
* Returns null if driver has no rating
*/
getRating(driverId: string): number | null;
/**
* Get ratings for multiple drivers
* Returns a map of driverId -> rating
*/
getRatings(driverIds: string[]): Map<string, number>;
}

View File

@@ -1,12 +0,0 @@
/**
* Application Port: IImageServicePort
*
* Abstraction used by racing application use cases to obtain image URLs
* for drivers, teams and leagues without depending on UI/media layers.
*/
export interface IImageServicePort {
getDriverAvatar(driverId: string): string;
getTeamLogo(teamId: string): string;
getLeagueCover(leagueId: string): string;
getLeagueLogo(leagueId: string): string;
}

View File

@@ -1,46 +0,0 @@
/**
* Application Port: ILiveryCompositor
*
* Defines interface for livery image composition.
* Infrastructure will provide image processing implementation.
*/
import type { LiveryDecal } from '../../domain/value-objects/LiveryDecal';
export interface CompositionResult {
success: boolean;
composedImageUrl?: string;
error?: string;
timestamp: Date;
}
export interface ILiveryCompositor {
/**
* Composite a livery by layering decals on base image
*/
composeLivery(
baseImageUrl: string,
decals: LiveryDecal[]
): Promise<CompositionResult>;
/**
* Generate a livery pack (.zip) for all drivers in a season
*/
generateLiveryPack(
seasonId: string,
liveryData: Array<{
driverId: string;
driverName: string;
carId: string;
composedImageUrl: string;
}>
): Promise<Buffer>;
/**
* Validate livery image (check for logos/text)
*/
validateLiveryImage(imageUrl: string): Promise<{
isValid: boolean;
violations?: string[];
}>;
}

View File

@@ -1,39 +0,0 @@
/**
* Application Port: ILiveryStorage
*
* Defines interface for livery image storage.
* Infrastructure will provide cloud storage adapter.
*/
export interface UploadResult {
success: boolean;
imageUrl?: string;
error?: string;
timestamp: Date;
}
export interface ILiveryStorage {
/**
* Upload a livery image
*/
upload(
imageData: Buffer | string,
fileName: string,
metadata?: Record<string, unknown>
): Promise<UploadResult>;
/**
* Download a livery image
*/
download(imageUrl: string): Promise<Buffer>;
/**
* Delete a livery image
*/
delete(imageUrl: string): Promise<void>;
/**
* Generate a signed URL for temporary access
*/
generateSignedUrl(imageUrl: string, expiresInSeconds: number): Promise<string>;
}

View File

@@ -1,48 +0,0 @@
/**
* Application Port: IPaymentGateway
*
* Defines interface for payment processing.
* Infrastructure will provide mock or real implementation.
*/
import type { Money } from '../../domain/value-objects/Money';
export interface PaymentResult {
success: boolean;
transactionId?: string;
error?: string;
timestamp: Date;
}
export interface RefundResult {
success: boolean;
refundId?: string;
error?: string;
timestamp: Date;
}
export interface IPaymentGateway {
/**
* Process a payment
*/
processPayment(
amount: Money,
payerId: string,
description: string,
metadata?: Record<string, unknown>
): Promise<PaymentResult>;
/**
* Refund a payment
*/
refund(
originalTransactionId: string,
amount: Money,
reason: string
): Promise<RefundResult>;
/**
* Verify payment status
*/
verifyPayment(transactionId: string): Promise<PaymentResult>;
}

View File

@@ -1,29 +0,0 @@
import type { LeagueScoringConfig } from '../../domain/entities/LeagueScoringConfig';
export type LeagueScoringPresetPrimaryChampionshipType =
| 'driver'
| 'team'
| 'nations'
| 'trophy';
export interface LeagueScoringPresetDTO {
id: string;
name: string;
description: string;
primaryChampionshipType: LeagueScoringPresetPrimaryChampionshipType;
sessionSummary: string;
bonusSummary: string;
dropPolicySummary: string;
}
/**
* Provider abstraction for league scoring presets used by application-layer queries.
*
* In-memory implementation is backed by the preset registry in
* InMemoryScoringRepositories.
*/
export interface LeagueScoringPresetProvider {
listPresets(): LeagueScoringPresetDTO[];
getPresetById(id: string): LeagueScoringPresetDTO | undefined;
createScoringConfigFromPreset(presetId: string, seasonId: string): LeagueScoringConfig;
}

View File

@@ -0,0 +1,3 @@
export interface GetDriverAvatarInputPort {
driverId: string;
}

View File

@@ -0,0 +1,3 @@
export interface GetDriverRatingInputPort {
driverId: string;
}

View File

@@ -0,0 +1,6 @@
import type { SponsorableEntityType } from '../../../domain/entities/SponsorshipRequest';
export interface GetEntitySponsorshipPricingInputPort {
entityType: SponsorableEntityType;
entityId: string;
}

View File

@@ -0,0 +1,3 @@
export interface GetLeagueCoverInputPort {
leagueId: string;
}

View File

@@ -0,0 +1,3 @@
export interface GetLeagueLogoInputPort {
leagueId: string;
}

View File

@@ -0,0 +1,3 @@
export interface GetLeagueScoringPresetByIdInputPort {
presetId: string;
}

View File

@@ -0,0 +1,3 @@
export interface GetTeamLogoInputPort {
teamId: string;
}

View File

@@ -0,0 +1,6 @@
/**
* League visibility/ranking mode.
* - 'ranked' (or legacy 'public'): Competitive, public, affects driver ratings. Min 10 drivers.
* - 'unranked' (or legacy 'private'): Casual with friends, no rating impact.
*/
export type LeagueVisibilityInputPort = 'ranked' | 'unranked' | 'public' | 'private';

View File

@@ -0,0 +1,3 @@
export interface ListLeagueScoringPresetsInputPort {
// Empty interface for query with no parameters
}

View File

@@ -0,0 +1,6 @@
export interface ProcessPaymentInputPort {
amount: number; // in cents
payerId: string;
description: string;
metadata?: Record<string, unknown>;
}

View File

@@ -0,0 +1,8 @@
export interface IsDriverRegisteredForRaceInputPort {
raceId: string;
driverId: string;
}
export interface GetRaceRegistrationsInputPort {
raceId: string;
}

View File

@@ -0,0 +1,7 @@
import type { Money } from '../../domain/value-objects/Money';
export interface RefundPaymentInputPort {
originalTransactionId: string;
amount: Money;
reason: string;
}

View File

@@ -0,0 +1,3 @@
export interface VerifyPaymentInputPort {
transactionId: string;
}

View File

@@ -0,0 +1,8 @@
export interface AcceptSponsorshipOutputPort {
requestId: string;
sponsorshipId: string;
status: 'accepted';
acceptedAt: Date;
platformFee: number;
netAmount: number;
}

View File

@@ -0,0 +1,5 @@
export interface ApplyForSponsorshipResultPort {
requestId: string;
status: 'pending';
createdAt: Date;
}

View File

@@ -0,0 +1,4 @@
export interface ApproveLeagueJoinRequestResultPort {
success: boolean;
message: string;
}

View File

@@ -0,0 +1,8 @@
import type { ChampionshipStandingsRowOutputPort } from './ChampionshipStandingsRowOutputPort';
export interface ChampionshipStandingsOutputPort {
seasonId: string;
championshipId: string;
championshipName: string;
rows: ChampionshipStandingsRowOutputPort[];
}

View File

@@ -0,0 +1,9 @@
import type { ParticipantRef } from '@core/racing/domain/types/ParticipantRef';
export interface ChampionshipStandingsRowOutputPort {
participant: ParticipantRef;
position: number;
totalPoints: number;
resultsCounted: number;
resultsDropped: number;
}

View File

@@ -0,0 +1,6 @@
export interface CreateLeagueWithSeasonAndScoringOutputPort {
leagueId: string;
seasonId: string;
scoringPresetId?: string;
scoringPresetName?: string;
}

View File

@@ -0,0 +1,10 @@
export interface CreateSponsorOutputPort {
sponsor: {
id: string;
name: string;
contactEmail: string;
websiteUrl?: string;
logoUrl?: string;
createdAt: Date;
};
}

View File

@@ -0,0 +1,5 @@
import type { Team } from '../../../domain/entities/Team';
export interface CreateTeamOutputPort {
team: Team;
}

View File

@@ -0,0 +1,8 @@
export interface DriverOutputPort {
id: string;
iracingId: string;
name: string;
country: string;
bio?: string;
joinedAt: string;
}

View File

@@ -0,0 +1,3 @@
import type { Team } from '../../../domain/entities/Team';
export type GetAllTeamsOutputPort = Team[];

View File

@@ -0,0 +1,3 @@
export interface GetDriverAvatarOutputPort {
avatarUrl: string;
}

View File

@@ -0,0 +1,4 @@
export interface GetDriverRatingOutputPort {
rating: number | null;
ratingChange: number | null;
}

View File

@@ -0,0 +1,7 @@
import type { Team } from '../../../domain/entities/Team';
import type { TeamMembership } from '../../../domain/types/TeamMembership';
export interface GetDriverTeamOutputPort {
team: Team;
membership: TeamMembership;
}

View File

@@ -0,0 +1,11 @@
import type { SponsorableEntityType } from '../../../domain/entities/SponsorshipRequest';
import type { SponsorshipSlotDTO } from './SponsorshipSlotOutputPort';
export interface GetEntitySponsorshipPricingOutputPort {
entityType: SponsorableEntityType;
entityId: string;
acceptingApplications: boolean;
customRequirements?: string;
mainSlot?: SponsorshipSlotDTO;
secondarySlot?: SponsorshipSlotDTO;
}

View File

@@ -0,0 +1,7 @@
export interface GetLeagueAdminOutputPort {
league: {
id: string;
ownerId: string;
};
// Additional data would be populated by combining multiple use cases
}

View File

@@ -0,0 +1,4 @@
export interface GetLeagueAdminPermissionsOutputPort {
canRemoveMember: boolean;
canUpdateRoles: boolean;
}

View File

@@ -0,0 +1,3 @@
export interface GetLeagueCoverOutputPort {
coverUrl: string;
}

View File

@@ -0,0 +1,13 @@
export interface GetLeagueJoinRequestsOutputPort {
joinRequests: Array<{
id: string;
leagueId: string;
driverId: string;
requestedAt: Date;
message?: string;
driver: {
id: string;
name: string;
};
}>;
}

View File

@@ -0,0 +1,3 @@
export interface GetLeagueLogoOutputPort {
logoUrl: string;
}

View File

@@ -0,0 +1,6 @@
import type { LeagueMembership } from '../../../domain/entities/LeagueMembership';
export interface GetLeagueMembershipsOutputPort {
memberships: LeagueMembership[];
drivers: { id: string; name: string }[];
}

View File

@@ -0,0 +1,3 @@
export interface GetLeagueOwnerSummaryOutputPort {
summary: { driver: { id: string; name: string }; rating: number; rank: number } | null;
}

View File

@@ -0,0 +1,18 @@
import type { ProtestOutputPort } from './ProtestOutputPort';
export interface RaceOutputPort {
id: string;
name: string;
date: string;
}
export interface DriverOutputPort {
id: string;
name: string;
}
export interface GetLeagueProtestsOutputPort {
protests: ProtestOutputPort[];
races: RaceOutputPort[];
drivers: DriverOutputPort[];
}

View File

@@ -0,0 +1,7 @@
export interface GetLeagueScheduleOutputPort {
races: Array<{
id: string;
name: string;
scheduledAt: Date;
}>;
}

View File

@@ -0,0 +1,7 @@
import type { Team } from '../../../domain/entities/Team';
import type { TeamMembership } from '../../../domain/types/TeamMembership';
export interface GetTeamDetailsOutputPort {
team: Team;
membership: TeamMembership | null;
}

View File

@@ -0,0 +1,3 @@
export interface GetTeamLogoOutputPort {
logoUrl: string;
}

View File

@@ -0,0 +1,20 @@
export interface LeagueDriverSeasonStatsOutputPort {
leagueId: string;
driverId: string;
position: number;
driverName: string;
teamId?: string;
teamName?: string;
totalPoints: number;
basePoints: number;
penaltyPoints: number;
bonusPoints: number;
pointsPerRace: number;
racesStarted: number;
racesFinished: number;
dnfs: number;
noShows: number;
avgFinish: number | null;
rating: number | null;
ratingChange: number | null;
}

View File

@@ -0,0 +1,20 @@
export interface LeagueOutputPort {
id: string;
name: string;
description: string;
ownerId: string;
settings: {
pointsSystem: 'f1-2024' | 'indycar' | 'custom';
sessionDuration?: number;
qualifyingFormat?: 'single-lap' | 'open';
customPoints?: Record<number, number>;
maxDrivers?: number;
};
createdAt: string;
socialLinks?: {
discordUrl?: string;
youtubeUrl?: string;
websiteUrl?: string;
};
usedSlots?: number;
}

View File

@@ -0,0 +1,18 @@
import type { Weekday } from '../../../domain/types/Weekday';
export interface LeagueScheduleOutputPort {
seasonStartDate: string;
raceStartTime: string;
timezoneId: string;
recurrenceStrategy: 'weekly' | 'everyNWeeks' | 'monthlyNthWeekday';
intervalWeeks?: number;
weekdays?: Weekday[];
monthlyOrdinal?: 1 | 2 | 3 | 4;
monthlyWeekday?: Weekday;
plannedRounds: number;
}
export interface LeagueSchedulePreviewOutputPort {
rounds: Array<{ roundNumber: number; scheduledAt: string; timezoneId: string }>;
summary: string;
}

View File

@@ -0,0 +1,20 @@
export interface LeagueScoringChampionshipOutputPort {
id: string;
name: string;
type: 'driver' | 'team' | 'nations' | 'trophy';
sessionTypes: string[];
pointsPreview: Array<{ sessionType: string; position: number; points: number }>;
bonusSummary: string[];
dropPolicyDescription: string;
}
export interface LeagueScoringConfigOutputPort {
leagueId: string;
seasonId: string;
gameId: string;
gameName: string;
scoringPresetId?: string;
scoringPresetName?: string;
dropPolicySummary: string;
championships: LeagueScoringChampionshipOutputPort[];
}

View File

@@ -0,0 +1,15 @@
export type LeagueScoringPresetPrimaryChampionshipType =
| 'driver'
| 'team'
| 'nations'
| 'trophy';
export interface LeagueScoringPresetOutputPort {
id: string;
name: string;
description: string;
primaryChampionshipType: LeagueScoringPresetPrimaryChampionshipType;
sessionSummary: string;
bonusSummary: string;
dropPolicySummary: string;
}

View File

@@ -0,0 +1,25 @@
export interface LeagueSummaryScoringOutputPort {
gameId: string;
gameName: string;
primaryChampionshipType: 'driver' | 'team' | 'nations' | 'trophy';
scoringPresetId: string;
scoringPresetName: string;
dropPolicySummary: string;
scoringPatternSummary: string;
}
export interface LeagueSummaryOutputPort {
id: string;
name: string;
description?: string;
createdAt: Date;
ownerId: string;
maxDrivers?: number;
usedDriverSlots?: number;
maxTeams?: number;
usedTeamSlots?: number;
structureSummary?: string;
scoringPatternSummary?: string;
timingSummary?: string;
scoring?: LeagueSummaryScoringOutputPort;
}

View File

@@ -0,0 +1,6 @@
export interface ProcessPaymentOutputPort {
success: boolean;
transactionId?: string;
error?: string;
timestamp: Date;
}

View File

@@ -0,0 +1,9 @@
export interface ProtestOutputPort {
id: string;
raceId: string;
protestingDriverId: string;
accusedDriverId: string;
submittedAt: Date;
description: string;
status: string;
}

View File

@@ -0,0 +1,14 @@
export interface RaceOutputPort {
id: string;
leagueId: string;
scheduledAt: string;
track: string;
trackId?: string;
car: string;
carId?: string;
sessionType: 'practice' | 'qualifying' | 'race';
status: 'scheduled' | 'running' | 'completed' | 'cancelled';
strengthOfField?: number;
registeredCount?: number;
maxParticipants?: number;
}

View File

@@ -0,0 +1,6 @@
export interface RefundPaymentOutputPort {
success: boolean;
refundId?: string;
error?: string;
timestamp: Date;
}

View File

@@ -0,0 +1,9 @@
export interface ResultOutputPort {
id: string;
raceId: string;
driverId: string;
position: number;
fastestLap: number;
incidents: number;
startPosition: number;
}

View File

@@ -0,0 +1,13 @@
import type { SponsorshipTier } from '../../../domain/entities/SeasonSponsorship';
export interface SponsorshipSlotOutputPort {
tier: SponsorshipTier;
price: number;
currency: string;
formattedPrice: string;
benefits: string[];
available: boolean;
maxSlots: number;
filledSlots: number;
pendingRequests: number;
}

View File

@@ -0,0 +1,8 @@
export interface StandingOutputPort {
leagueId: string;
driverId: string;
points: number;
wins: number;
position: number;
racesCompleted: number;
}

View File

@@ -0,0 +1,6 @@
export interface VerifyPaymentOutputPort {
success: boolean;
transactionId?: string;
error?: string;
timestamp: Date;
}