Files
gridpilot.gg/apps/website/lib/feature/FeatureFlagService.ts
2026-01-03 12:07:20 +01:00

106 lines
2.8 KiB
TypeScript

/**
* 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<string>;
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<string>;
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'
]);