import { ApiProperty } from '@nestjs/swagger'; import { IsBoolean, IsDate, IsEnum, IsNotEmpty, IsNumber, IsOptional, IsString } 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; }