import { ApiProperty } from '@nestjs/swagger'; import { IsString, IsNotEmpty, IsNumber, IsEnum, IsOptional, IsDate, IsBoolean } from 'class-validator'; export enum PaymentType { SPONSORSHIP = 'sponsorship', MEMBERSHIP_FEE = 'membership_fee', } export enum PayerType { SPONSOR = 'sponsor', DRIVER = 'driver', } export enum PaymentStatus { PENDING = 'pending', COMPLETED = 'completed', FAILED = 'failed', REFUNDED = 'refunded', } export class PaymentDto { @ApiProperty() @IsString() id: string; @ApiProperty({ enum: PaymentType }) @IsEnum(PaymentType) type: PaymentType; @ApiProperty() @IsNumber() amount: number; @ApiProperty() @IsNumber() platformFee: number; @ApiProperty() @IsNumber() netAmount: number; @ApiProperty() @IsString() payerId: string; @ApiProperty({ enum: PayerType }) @IsEnum(PayerType) payerType: PayerType; @ApiProperty() @IsString() leagueId: string; @ApiProperty({ required: false }) @IsOptional() @IsString() seasonId?: string; @ApiProperty({ enum: PaymentStatus }) @IsEnum(PaymentStatus) status: PaymentStatus; @ApiProperty() @IsDate() createdAt: Date; @ApiProperty({ required: false }) @IsOptional() @IsDate() completedAt?: Date; } export class CreatePaymentInput { @ApiProperty({ enum: PaymentType }) @IsEnum(PaymentType) type: PaymentType; @ApiProperty() @IsNumber() amount: number; @ApiProperty() @IsString() payerId: string; @ApiProperty({ enum: PayerType }) @IsEnum(PayerType) payerType: PayerType; @ApiProperty() @IsString() leagueId: string; @ApiProperty({ required: false }) @IsOptional() @IsString() seasonId?: string; } export class CreatePaymentOutput { @ApiProperty({ type: PaymentDto }) payment: PaymentDto; } export class UpdatePaymentStatusInput { @ApiProperty() @IsString() paymentId: string; @ApiProperty({ enum: PaymentStatus }) @IsEnum(PaymentStatus) status: PaymentStatus; } export class UpdatePaymentStatusOutput { @ApiProperty({ type: PaymentDto }) payment: PaymentDto; } export enum MembershipFeeType { SEASON = 'season', MONTHLY = 'monthly', PER_RACE = 'per_race', } export enum MemberPaymentStatus { PENDING = 'pending', PAID = 'paid', OVERDUE = 'overdue', } export class MembershipFeeDto { @ApiProperty() @IsString() id: string; @ApiProperty() @IsString() leagueId: string; @ApiProperty({ required: false }) @IsOptional() @IsString() seasonId?: string; @ApiProperty({ enum: MembershipFeeType }) @IsEnum(MembershipFeeType) type: MembershipFeeType; @ApiProperty() @IsNumber() amount: number; @ApiProperty() @IsBoolean() enabled: boolean; @ApiProperty() @IsDate() createdAt: Date; @ApiProperty() @IsDate() updatedAt: Date; } export class MemberPaymentDto { @ApiProperty() @IsString() id: string; @ApiProperty() @IsString() feeId: string; @ApiProperty() @IsString() driverId: string; @ApiProperty() @IsNumber() amount: number; @ApiProperty() @IsNumber() platformFee: number; @ApiProperty() @IsNumber() netAmount: number; @ApiProperty({ enum: MemberPaymentStatus }) @IsEnum(MemberPaymentStatus) status: MemberPaymentStatus; @ApiProperty() @IsDate() dueDate: Date; @ApiProperty({ required: false }) @IsOptional() @IsDate() paidAt?: Date; } export class GetMembershipFeesQuery { @ApiProperty() @IsString() leagueId: string; @ApiProperty({ required: false }) @IsOptional() @IsString() driverId?: string; } export class GetMembershipFeesOutput { @ApiProperty({ type: MembershipFeeDto, nullable: true }) fee: MembershipFeeDto | null; @ApiProperty({ type: [MemberPaymentDto] }) payments: MemberPaymentDto[]; } export class UpsertMembershipFeeInput { @ApiProperty() @IsString() leagueId: string; @ApiProperty({ required: false }) @IsOptional() @IsString() seasonId?: string; @ApiProperty({ enum: MembershipFeeType }) @IsEnum(MembershipFeeType) type: MembershipFeeType; @ApiProperty() @IsNumber() amount: number; } export class UpsertMembershipFeeOutput { @ApiProperty({ type: MembershipFeeDto }) fee: MembershipFeeDto; } export class UpdateMemberPaymentInput { @ApiProperty() @IsString() feeId: string; @ApiProperty() @IsString() driverId: string; @ApiProperty({ required: false, enum: MemberPaymentStatus }) @IsOptional() @IsEnum(MemberPaymentStatus) status?: MemberPaymentStatus; @ApiProperty({ required: false }) @IsOptional() @IsDate() paidAt?: Date | string; } export class UpdateMemberPaymentOutput { @ApiProperty({ type: MemberPaymentDto }) payment: MemberPaymentDto; } export class GetPaymentsQuery { @ApiProperty({ required: false }) @IsOptional() @IsString() leagueId?: string; @ApiProperty({ required: false }) @IsOptional() @IsString() payerId?: string; @ApiProperty({ required: false, enum: PaymentType }) @IsOptional() @IsEnum(PaymentType) type?: PaymentType; } export class GetPaymentsOutput { @ApiProperty({ type: [PaymentDto] }) payments: PaymentDto[]; } export enum PrizeType { CASH = 'cash', MERCHANDISE = 'merchandise', OTHER = 'other', } export class PrizeDto { @ApiProperty() @IsString() id: string; @ApiProperty() @IsString() leagueId: string; @ApiProperty() @IsString() seasonId: string; @ApiProperty() @IsNumber() position: number; @ApiProperty() @IsString() name: string; @ApiProperty() @IsNumber() amount: number; @ApiProperty({ enum: PrizeType }) @IsEnum(PrizeType) type: PrizeType; @ApiProperty({ required: false }) @IsOptional() @IsString() description?: string; @ApiProperty() @IsBoolean() awarded: boolean; @ApiProperty({ required: false }) @IsOptional() @IsString() awardedTo?: string; @ApiProperty({ required: false }) @IsOptional() @IsDate() awardedAt?: Date; @ApiProperty() @IsDate() createdAt: Date; } export class GetPrizesQuery { @ApiProperty() @IsString() leagueId?: string; @ApiProperty({ required: false }) @IsOptional() @IsString() seasonId?: string; } export class GetPrizesOutput { @ApiProperty({ type: [PrizeDto] }) prizes: PrizeDto[]; } export class CreatePrizeInput { @ApiProperty() @IsString() leagueId: string; @ApiProperty() @IsString() seasonId: string; @ApiProperty() @IsNumber() position: number; @ApiProperty() @IsString() name: string; @ApiProperty() @IsNumber() amount: number; @ApiProperty({ enum: PrizeType }) @IsEnum(PrizeType) type: PrizeType; @ApiProperty({ required: false }) @IsOptional() @IsString() description?: string; } export class CreatePrizeOutput { @ApiProperty({ type: PrizeDto }) prize: PrizeDto; } export class AwardPrizeInput { @ApiProperty() @IsString() prizeId: string; @ApiProperty() @IsString() driverId: string; } export class AwardPrizeOutput { @ApiProperty({ type: PrizeDto }) prize: PrizeDto; } export class DeletePrizeInput { @ApiProperty() @IsString() prizeId: string; } export class DeletePrizeOutput { @ApiProperty() @IsBoolean() success: boolean; } export enum TransactionType { DEPOSIT = 'deposit', WITHDRAWAL = 'withdrawal', PLATFORM_FEE = 'platform_fee', } export enum ReferenceType { SPONSORSHIP = 'sponsorship', MEMBERSHIP_FEE = 'membership_fee', PRIZE = 'prize', } export class WalletDto { @ApiProperty() @IsString() id: string; @ApiProperty() @IsString() leagueId: string; @ApiProperty() @IsNumber() balance: number; @ApiProperty() @IsNumber() totalRevenue: number; @ApiProperty() @IsNumber() totalPlatformFees: number; @ApiProperty() @IsNumber() totalWithdrawn: number; @ApiProperty() @IsDate() createdAt: Date; @ApiProperty() @IsString() currency: string; } export class TransactionDto { @ApiProperty() @IsString() id: string; @ApiProperty() @IsString() walletId: string; @ApiProperty({ enum: TransactionType }) @IsEnum(TransactionType) type: TransactionType; @ApiProperty() @IsNumber() amount: number; @ApiProperty() @IsString() description: string; @ApiProperty({ required: false }) @IsOptional() @IsString() referenceId?: string; @ApiProperty({ required: false, enum: ReferenceType }) @IsOptional() @IsEnum(ReferenceType) referenceType?: ReferenceType; @ApiProperty() @IsDate() createdAt: Date; } export class GetWalletQuery { @ApiProperty() @IsString() leagueId?: string; } export class GetWalletOutput { @ApiProperty({ type: WalletDto }) wallet: WalletDto; @ApiProperty({ type: [TransactionDto] }) transactions: TransactionDto[]; } export class ProcessWalletTransactionInput { @ApiProperty() @IsString() leagueId: string; @ApiProperty({ enum: TransactionType }) @IsEnum(TransactionType) type: TransactionType; @ApiProperty() @IsNumber() amount: number; @ApiProperty() @IsString() @IsNotEmpty() description: string; @ApiProperty({ required: false }) @IsOptional() @IsString() referenceId?: string; @ApiProperty({ required: false, enum: ReferenceType }) @IsOptional() @IsEnum(ReferenceType) referenceType?: ReferenceType; } export class ProcessWalletTransactionOutput { @ApiProperty({ type: WalletDto }) wallet: WalletDto; @ApiProperty({ type: TransactionDto }) transaction: TransactionDto; }