export type PlanId = 'free' | 'pro'; export type Plan = { id: PlanId; name: string; price: number; /** Monthly included usage per metric. */ limits: { seats: number; apiCalls: number }; features: string[]; }; export const PLANS: Record = { free: { id: 'free', name: 'Free', price: 0, limits: { seats: 2, apiCalls: 1_000 }, features: ['Up to 2 members', '1,000 API calls / month', 'Community support'], }, pro: { id: 'pro', name: 'Pro', price: 29, limits: { seats: 25, apiCalls: 100_000 }, features: ['Up to 25 members', '100,000 API calls / month', 'Priority support'], }, }; export const PLAN_IDS: PlanId[] = ['free', 'pro']; export function isPlanId(value: unknown): value is PlanId { return value === 'free' || value === 'pro'; } export function getPlan(value: unknown): Plan { return isPlanId(value) ? PLANS[value] : PLANS.free; } export function withinLimit(plan: unknown, metric: keyof Plan['limits'], used: number): boolean { return used < getPlan(plan).limits[metric]; } export function formatCurrency(amount: number, currency = 'USD'): string { return new Intl.NumberFormat('en-US', { style: 'currency', currency }).format(amount); } export function formatDate(value: Date | string): string { const d = typeof value === 'string' ? new Date(value) : value; return new Intl.DateTimeFormat('en-US', { dateStyle: 'medium' }).format(d); } export function slugify(value: string): string { return value .toLowerCase() .trim() .replace(/[^a-z0-9]+/g, '-') .replace(/^-+|-+$/g, ''); }