import { IsEmail, IsString, IsEnum, IsInt, IsBoolean, IsOptional, IsUUID, Min, IsDate } from 'class-validator'; import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { Plan } from '@prisma/client'; export class CreateUserDto { @ApiPropertyOptional({ description: 'Google OAuth UID for OAuth integration', example: 'google_123456789' }) @IsOptional() @IsString() googleUid?: string; @ApiProperty({ description: 'User email address', example: 'user@example.com' }) @IsEmail() email: string; @ApiProperty({ description: 'Hashed version of email for privacy', example: 'a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3' }) @IsString() emailHash: string; @ApiPropertyOptional({ description: 'User subscription plan', enum: Plan, default: Plan.BASIC }) @IsOptional() @IsEnum(Plan) plan?: Plan; @ApiPropertyOptional({ description: 'Remaining quota for current period', example: 50, minimum: 0 }) @IsOptional() @IsInt() @Min(0) quotaRemaining?: number; } export class UpdateUserDto { @ApiPropertyOptional({ description: 'User subscription plan', enum: Plan }) @IsOptional() @IsEnum(Plan) plan?: Plan; @ApiPropertyOptional({ description: 'Remaining quota for current period', minimum: 0 }) @IsOptional() @IsInt() @Min(0) quotaRemaining?: number; @ApiPropertyOptional({ description: 'Whether the user account is active' }) @IsOptional() @IsBoolean() isActive?: boolean; } export class UserResponseDto { @ApiProperty({ description: 'Unique user identifier', example: '550e8400-e29b-41d4-a716-446655440000' }) @IsUUID() id: string; @ApiPropertyOptional({ description: 'Google OAuth UID', example: 'google_123456789' }) @IsOptional() @IsString() googleUid?: string; @ApiProperty({ description: 'User email address', example: 'user@example.com' }) @IsEmail() email: string; @ApiProperty({ description: 'User subscription plan', enum: Plan }) @IsEnum(Plan) plan: Plan; @ApiProperty({ description: 'Remaining quota for current period', example: 50 }) @IsInt() @Min(0) quotaRemaining: number; @ApiProperty({ description: 'Date when quota resets' }) @IsDate() quotaResetDate: Date; @ApiProperty({ description: 'Whether the user account is active' }) @IsBoolean() isActive: boolean; @ApiProperty({ description: 'User creation timestamp' }) @IsDate() createdAt: Date; @ApiProperty({ description: 'User last update timestamp' }) @IsDate() updatedAt: Date; } export class UserStatsDto { @ApiProperty({ description: 'Total number of batches processed' }) @IsInt() @Min(0) totalBatches: number; @ApiProperty({ description: 'Total number of images processed' }) @IsInt() @Min(0) totalImages: number; @ApiProperty({ description: 'Current quota usage this period' }) @IsInt() @Min(0) quotaUsed: number; @ApiProperty({ description: 'Total quota for current plan' }) @IsInt() @Min(0) totalQuota: number; @ApiProperty({ description: 'Percentage of quota used' }) @IsInt() @Min(0) quotaUsagePercentage: number; } // Helper function to get quota limits by plan export function getQuotaLimitForPlan(plan: Plan): number { switch (plan) { case Plan.BASIC: return 50; case Plan.PRO: return 500; case Plan.MAX: return 1000; default: return 50; } } // Helper function to calculate quota reset date (monthly) export function calculateQuotaResetDate(): Date { const now = new Date(); const nextMonth = new Date(now.getFullYear(), now.getMonth() + 1, 1); return nextMonth; }