refactor dtos to ports
This commit is contained in:
@@ -1,3 +0,0 @@
|
||||
export interface DriverRatingPort {
|
||||
getRating(driverId: string): { rating: number | null; ratingChange: number | null };
|
||||
}
|
||||
@@ -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>;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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[];
|
||||
}>;
|
||||
}
|
||||
@@ -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>;
|
||||
}
|
||||
@@ -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>;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export interface GetDriverAvatarInputPort {
|
||||
driverId: string;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export interface GetDriverRatingInputPort {
|
||||
driverId: string;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import type { SponsorableEntityType } from '../../../domain/entities/SponsorshipRequest';
|
||||
|
||||
export interface GetEntitySponsorshipPricingInputPort {
|
||||
entityType: SponsorableEntityType;
|
||||
entityId: string;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export interface GetLeagueCoverInputPort {
|
||||
leagueId: string;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export interface GetLeagueLogoInputPort {
|
||||
leagueId: string;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export interface GetLeagueScoringPresetByIdInputPort {
|
||||
presetId: string;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export interface GetTeamLogoInputPort {
|
||||
teamId: string;
|
||||
}
|
||||
@@ -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';
|
||||
@@ -0,0 +1,3 @@
|
||||
export interface ListLeagueScoringPresetsInputPort {
|
||||
// Empty interface for query with no parameters
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
export interface ProcessPaymentInputPort {
|
||||
amount: number; // in cents
|
||||
payerId: string;
|
||||
description: string;
|
||||
metadata?: Record<string, unknown>;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
export interface IsDriverRegisteredForRaceInputPort {
|
||||
raceId: string;
|
||||
driverId: string;
|
||||
}
|
||||
|
||||
export interface GetRaceRegistrationsInputPort {
|
||||
raceId: string;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import type { Money } from '../../domain/value-objects/Money';
|
||||
|
||||
export interface RefundPaymentInputPort {
|
||||
originalTransactionId: string;
|
||||
amount: Money;
|
||||
reason: string;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export interface VerifyPaymentInputPort {
|
||||
transactionId: string;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
export interface AcceptSponsorshipOutputPort {
|
||||
requestId: string;
|
||||
sponsorshipId: string;
|
||||
status: 'accepted';
|
||||
acceptedAt: Date;
|
||||
platformFee: number;
|
||||
netAmount: number;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export interface ApplyForSponsorshipResultPort {
|
||||
requestId: string;
|
||||
status: 'pending';
|
||||
createdAt: Date;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface ApproveLeagueJoinRequestResultPort {
|
||||
success: boolean;
|
||||
message: string;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import type { ChampionshipStandingsRowOutputPort } from './ChampionshipStandingsRowOutputPort';
|
||||
|
||||
export interface ChampionshipStandingsOutputPort {
|
||||
seasonId: string;
|
||||
championshipId: string;
|
||||
championshipName: string;
|
||||
rows: ChampionshipStandingsRowOutputPort[];
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
export interface CreateLeagueWithSeasonAndScoringOutputPort {
|
||||
leagueId: string;
|
||||
seasonId: string;
|
||||
scoringPresetId?: string;
|
||||
scoringPresetName?: string;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
export interface CreateSponsorOutputPort {
|
||||
sponsor: {
|
||||
id: string;
|
||||
name: string;
|
||||
contactEmail: string;
|
||||
websiteUrl?: string;
|
||||
logoUrl?: string;
|
||||
createdAt: Date;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import type { Team } from '../../../domain/entities/Team';
|
||||
|
||||
export interface CreateTeamOutputPort {
|
||||
team: Team;
|
||||
}
|
||||
8
core/racing/application/ports/output/DriverOutputPort.ts
Normal file
8
core/racing/application/ports/output/DriverOutputPort.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export interface DriverOutputPort {
|
||||
id: string;
|
||||
iracingId: string;
|
||||
name: string;
|
||||
country: string;
|
||||
bio?: string;
|
||||
joinedAt: string;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import type { Team } from '../../../domain/entities/Team';
|
||||
|
||||
export type GetAllTeamsOutputPort = Team[];
|
||||
@@ -0,0 +1,3 @@
|
||||
export interface GetDriverAvatarOutputPort {
|
||||
avatarUrl: string;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface GetDriverRatingOutputPort {
|
||||
rating: number | null;
|
||||
ratingChange: number | null;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export interface GetLeagueAdminOutputPort {
|
||||
league: {
|
||||
id: string;
|
||||
ownerId: string;
|
||||
};
|
||||
// Additional data would be populated by combining multiple use cases
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface GetLeagueAdminPermissionsOutputPort {
|
||||
canRemoveMember: boolean;
|
||||
canUpdateRoles: boolean;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export interface GetLeagueCoverOutputPort {
|
||||
coverUrl: string;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
export interface GetLeagueJoinRequestsOutputPort {
|
||||
joinRequests: Array<{
|
||||
id: string;
|
||||
leagueId: string;
|
||||
driverId: string;
|
||||
requestedAt: Date;
|
||||
message?: string;
|
||||
driver: {
|
||||
id: string;
|
||||
name: string;
|
||||
};
|
||||
}>;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export interface GetLeagueLogoOutputPort {
|
||||
logoUrl: string;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import type { LeagueMembership } from '../../../domain/entities/LeagueMembership';
|
||||
|
||||
export interface GetLeagueMembershipsOutputPort {
|
||||
memberships: LeagueMembership[];
|
||||
drivers: { id: string; name: string }[];
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export interface GetLeagueOwnerSummaryOutputPort {
|
||||
summary: { driver: { id: string; name: string }; rating: number; rank: number } | null;
|
||||
}
|
||||
@@ -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[];
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export interface GetLeagueScheduleOutputPort {
|
||||
races: Array<{
|
||||
id: string;
|
||||
name: string;
|
||||
scheduledAt: Date;
|
||||
}>;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export interface GetTeamLogoOutputPort {
|
||||
logoUrl: string;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
20
core/racing/application/ports/output/LeagueOutputPort.ts
Normal file
20
core/racing/application/ports/output/LeagueOutputPort.ts
Normal 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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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[];
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
export interface ProcessPaymentOutputPort {
|
||||
success: boolean;
|
||||
transactionId?: string;
|
||||
error?: string;
|
||||
timestamp: Date;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
export interface ProtestOutputPort {
|
||||
id: string;
|
||||
raceId: string;
|
||||
protestingDriverId: string;
|
||||
accusedDriverId: string;
|
||||
submittedAt: Date;
|
||||
description: string;
|
||||
status: string;
|
||||
}
|
||||
14
core/racing/application/ports/output/RaceOutputPort.ts
Normal file
14
core/racing/application/ports/output/RaceOutputPort.ts
Normal 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;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
export interface RefundPaymentOutputPort {
|
||||
success: boolean;
|
||||
refundId?: string;
|
||||
error?: string;
|
||||
timestamp: Date;
|
||||
}
|
||||
9
core/racing/application/ports/output/ResultOutputPort.ts
Normal file
9
core/racing/application/ports/output/ResultOutputPort.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export interface ResultOutputPort {
|
||||
id: string;
|
||||
raceId: string;
|
||||
driverId: string;
|
||||
position: number;
|
||||
fastestLap: number;
|
||||
incidents: number;
|
||||
startPosition: number;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
export interface StandingOutputPort {
|
||||
leagueId: string;
|
||||
driverId: string;
|
||||
points: number;
|
||||
wins: number;
|
||||
position: number;
|
||||
racesCompleted: number;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
export interface VerifyPaymentOutputPort {
|
||||
success: boolean;
|
||||
transactionId?: string;
|
||||
error?: string;
|
||||
timestamp: Date;
|
||||
}
|
||||
Reference in New Issue
Block a user