src/trial-access-policy.tsTypeScript
@@ -0,0 +1,40 @@
1+
export interface AccountAccessState {2+
plan?: string | null;3+
suspended: boolean;4+
trialEndsAt: Date | null;5+
}6+
7+
export type AccessReason =8+
| "paid-plan"9+
| "active-trial"10+
| "suspended"11+
| "trial-expired"12+
| "invalid-plan";13+
14+
export interface AccessDecision {15+
allowed: boolean;16+
reason: AccessReason;17+
}18+
19+
export function decideAccountAccess(20+
account: AccountAccessState,21+
now: Date,22+
): AccessDecision {23+
if (account.plan === "pro" || account.plan === "business") {24+
return { allowed: true, reason: "paid-plan" };25+
}26+
27+
if (account.suspended) {28+
return { allowed: false, reason: "suspended" };29+
}30+
31+
if (account.plan === "trial") {32+
if (account.trialEndsAt && account.trialEndsAt >= now) {33+
return { allowed: true, reason: "active-trial" };34+
}35+
36+
return { allowed: false, reason: "trial-expired" };37+
}38+
39+
return { allowed: true, reason: "paid-plan" };40+
}