/** * FeatureFlagService - Manages feature flags for both server and client * * Automatic Alpha Mode Integration: * When NEXT_PUBLIC_GRIDPILOT_MODE=alpha, all features are automatically enabled. * This eliminates the need to manually set FEATURE_FLAGS for alpha deployments. * * Server: Reads from process.env.FEATURE_FLAGS (comma-separated) * OR auto-enables all features if in alpha mode * Client: Reads from session context or provides mock implementation */ // Server-side implementation export class FeatureFlagService { private flags: Set; constructor(flags?: string[]) { if (flags) { this.flags = new Set(flags); } else { // Parse from environment variable const flagsEnv = process.env.FEATURE_FLAGS; this.flags = flagsEnv ? new Set(flagsEnv.split(',').map(f => f.trim())) : new Set(); } } /** * Check if a feature flag is enabled */ isEnabled(flag: string): boolean { return this.flags.has(flag); } /** * Get all enabled flags */ getEnabledFlags(): string[] { return Array.from(this.flags); } /** * Factory method to create service with environment flags * Automatically enables all features if in alpha mode * FEATURE_FLAGS can override alpha mode defaults */ static fromEnv(): FeatureFlagService { const mode = process.env.NEXT_PUBLIC_GRIDPILOT_MODE; const flagsEnv = process.env.FEATURE_FLAGS; // If FEATURE_FLAGS is explicitly set, use it (overrides alpha mode) if (flagsEnv) { return new FeatureFlagService(); } // If in alpha mode, automatically enable all features if (mode === 'alpha') { return new FeatureFlagService([ 'driver_profiles', 'team_profiles', 'wallets', 'sponsors', 'team_feature', 'alpha_features' ]); } // Otherwise, use FEATURE_FLAGS environment variable (empty if not set) return new FeatureFlagService(); } } // Client-side context interface export interface FeatureFlagContextType { isEnabled: (flag: string) => boolean; getEnabledFlags: () => string[]; } // Mock implementation for client-side when no context is available export class MockFeatureFlagService implements FeatureFlagContextType { private flags: Set; constructor(flags: string[] = []) { this.flags = new Set(flags); } isEnabled(flag: string): boolean { return this.flags.has(flag); } getEnabledFlags(): string[] { return Array.from(this.flags); } } // Default mock instance for client-side usage // Enables all features for development/demo mode export const mockFeatureFlags = new MockFeatureFlagService([ 'driver_profiles', 'team_profiles', 'wallets', 'sponsors', 'team_feature', 'alpha_features' ]);