Files
iddaai-be/src/modules/subscriptions/dto/subscription.dto.ts
T
2026-05-10 10:37:45 +03:00

179 lines
3.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import {
IsString,
IsOptional,
IsEnum,
IsDateString,
IsInt,
} from "class-validator";
import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
import { Exclude, Expose, Type } from "class-transformer";
export enum PlanType {
FREE = "free",
PLUS = "plus",
PREMIUM = "premium",
}
export enum BillingIntervalType {
MONTHLY = "monthly",
YEARLY = "yearly",
}
/**
* Plan feature limits configuration
*/
export const PLAN_LIMITS: Record<
PlanType,
{ maxAnalyses: number; maxCoupons: number }
> = {
[PlanType.FREE]: { maxAnalyses: 3, maxCoupons: 1 },
[PlanType.PLUS]: { maxAnalyses: 25, maxCoupons: 5 },
[PlanType.PREMIUM]: { maxAnalyses: 999, maxCoupons: 999 },
};
/**
* Plan display information
*/
export interface PlanInfo {
id: PlanType;
name: string;
description: string;
monthlyPrice: number;
yearlyPrice: number;
currency: string;
features: string[];
limits: { maxAnalyses: number; maxCoupons: number };
highlighted: boolean;
}
export const PLANS: readonly PlanInfo[] = [
{
id: PlanType.FREE,
name: "Free",
description: "Temel analiz özellikleri",
monthlyPrice: 0,
yearlyPrice: 0,
currency: "TRY",
features: ["Günlük 3 analiz", "Günlük 1 kupon", "Temel maç istatistikleri"],
limits: PLAN_LIMITS[PlanType.FREE],
highlighted: false,
},
{
id: PlanType.PLUS,
name: "Plus",
description: "Detaylı analiz ve daha fazla kupon",
monthlyPrice: 99,
yearlyPrice: 999,
currency: "TRY",
features: [
"Günlük 25 analiz",
"Günlük 5 kupon",
"AI detaylı analiz",
"H2H karşılaştırma",
"Reklamsız deneyim",
],
limits: PLAN_LIMITS[PlanType.PLUS],
highlighted: true,
},
{
id: PlanType.PREMIUM,
name: "Premium",
description: "Sınırsız erişim ve özel özellikler",
monthlyPrice: 249,
yearlyPrice: 2499,
currency: "TRY",
features: [
"Sınırsız analiz",
"Sınırsız kupon",
"AI detaylı analiz",
"H2H karşılaştırma",
"Kupon Builder",
"Spor Toto analiz",
"Reklamsız deneyim",
"Öncelikli destek",
],
limits: PLAN_LIMITS[PlanType.PREMIUM],
highlighted: false,
},
] as const;
// ── Response DTOs ──
@Exclude()
export class UsageLimitResponseDto {
@Expose()
analysisCount: number;
@Expose()
couponCount: number;
@Expose()
maxAnalyses: number;
@Expose()
maxCoupons: number;
}
@Exclude()
export class SubscriptionResponseDto {
@Expose()
id: string;
@Expose()
plan: string;
@Expose()
billingInterval: string | null;
@Expose()
currentPeriodStart: Date | null;
@Expose()
currentPeriodEnd: Date | null;
@Expose()
cancelledAt: Date | null;
@Expose()
cancelEffectiveDate: Date | null;
@Expose()
paddlePriceId: string | null;
@Expose()
createdAt: Date;
@Expose()
updatedAt: Date;
}
// ── Request DTOs ──
export class CreateCheckoutDto {
@ApiProperty({
enum: PlanType,
example: PlanType.PLUS,
description: "Target plan",
})
@IsEnum(PlanType)
plan: PlanType;
@ApiProperty({
enum: BillingIntervalType,
example: BillingIntervalType.MONTHLY,
description: "Billing interval",
})
@IsEnum(BillingIntervalType)
billingInterval: BillingIntervalType;
}
export class CancelSubscriptionDto {
@ApiPropertyOptional({
description: "Reason for cancellation",
example: "Too expensive",
})
@IsOptional()
@IsString()
reason?: string;
}