/** * @ai-summary Feature tier configuration and utilities * @ai-context Defines feature-to-tier mapping for gating premium features */ import { SubscriptionTier } from '../../features/user-profile/domain/user-profile.types'; // Tier hierarchy: higher number = higher access level export const TIER_LEVELS: Record = { free: 0, pro: 1, enterprise: 2, } as const; // Feature configuration interface export interface FeatureConfig { minTier: SubscriptionTier; name: string; upgradePrompt: string; } // Feature registry - add new gated features here export const FEATURE_TIERS: Record = { 'document.scanMaintenanceSchedule': { minTier: 'pro', name: 'Scan for Maintenance Schedule', upgradePrompt: 'Upgrade to Pro to automatically extract maintenance schedules from your vehicle manuals.', }, 'vehicle.vinDecode': { minTier: 'pro', name: 'VIN Decode', upgradePrompt: 'Upgrade to Pro to automatically decode VIN and populate vehicle details from the NHTSA database.', }, } as const; /** * Get numeric level for a subscription tier */ export function getTierLevel(tier: SubscriptionTier): number { return TIER_LEVELS[tier] ?? 0; } /** * Check if a user tier can access a feature * Higher tiers inherit access to all lower tier features */ export function canAccessFeature(userTier: SubscriptionTier, featureKey: string): boolean { const feature = FEATURE_TIERS[featureKey]; if (!feature) { // Unknown features are accessible by all (fail open for unlisted features) return true; } return getTierLevel(userTier) >= getTierLevel(feature.minTier); } /** * Get the minimum required tier for a feature * Returns null if feature is not gated */ export function getRequiredTier(featureKey: string): SubscriptionTier | null { const feature = FEATURE_TIERS[featureKey]; return feature?.minTier ?? null; } /** * Get full feature configuration * Returns undefined if feature is not registered */ export function getFeatureConfig(featureKey: string): FeatureConfig | undefined { return FEATURE_TIERS[featureKey]; } /** * Get all feature configurations (for API endpoint) */ export function getAllFeatureConfigs(): Record { return { ...FEATURE_TIERS }; } // Vehicle limits per tier // null indicates unlimited (enterprise tier) export const VEHICLE_LIMITS: Record = { free: 2, pro: 5, enterprise: null, } as const; /** * Vehicle limits vary by subscription tier and must be queryable * at runtime for both backend enforcement and frontend UI state. * * @param tier - User's subscription tier * @returns Maximum vehicles allowed, or null for unlimited (enterprise tier) */ export function getVehicleLimit(tier: SubscriptionTier): number | null { return VEHICLE_LIMITS[tier] ?? null; } /** * Check if a user can add another vehicle based on their tier and current count. * * @param tier - User's subscription tier * @param currentCount - Number of vehicles user currently has * @returns true if user can add another vehicle, false if at/over limit */ export function canAddVehicle(tier: SubscriptionTier, currentCount: number): boolean { const limit = getVehicleLimit(tier); // null limit means unlimited (enterprise) if (limit === null) { return true; } return currentCount < limit; } /** * Vehicle limit configuration with upgrade prompt. * Structure supports additional resource types in the future. */ export interface VehicleLimitConfig { limit: number | null; tier: SubscriptionTier; upgradePrompt: string; } /** * Get vehicle limit configuration with upgrade prompt for a tier. * * @param tier - User's subscription tier * @returns Configuration with limit and upgrade prompt */ export function getVehicleLimitConfig(tier: SubscriptionTier): VehicleLimitConfig { const limit = getVehicleLimit(tier); const defaultPrompt = 'Upgrade to access additional vehicles.'; let upgradePrompt: string; if (tier === 'free') { upgradePrompt = 'Free tier is limited to 2 vehicles. Upgrade to Pro for up to 5 vehicles, or Enterprise for unlimited.'; } else if (tier === 'pro') { upgradePrompt = 'Pro tier is limited to 5 vehicles. Upgrade to Enterprise for unlimited vehicles.'; } else { upgradePrompt = defaultPrompt; } return { limit, tier, upgradePrompt, }; }