203 lines
3.8 KiB
TypeScript
203 lines
3.8 KiB
TypeScript
![]() |
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;
|
||
|
}
|