fix issues
This commit is contained in:
225
docs/FEATURE_ARCHITECTURE.md
Normal file
225
docs/FEATURE_ARCHITECTURE.md
Normal file
@@ -0,0 +1,225 @@
|
||||
# Feature Architecture: Modes vs Feature Flags
|
||||
|
||||
## The Problem
|
||||
|
||||
Your current system has two overlapping concepts that conflict:
|
||||
- **Feature Flags** (`features.config.ts`) - Controls individual features
|
||||
- **App Modes** (`NEXT_PUBLIC_GRIDPILOT_MODE`) - Controls overall platform visibility
|
||||
|
||||
This creates confusion because:
|
||||
1. Development shows only landing page but feature config says everything is enabled
|
||||
2. It's unclear which system controls what
|
||||
3. Teams don't know when to use mode vs feature flag
|
||||
|
||||
## The Solution: Clear Separation
|
||||
|
||||
### **Two-Tier System**
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ APP MODE (Tier 1) │
|
||||
│ Controls WHAT the platform shows │
|
||||
│ - pre-launch: Landing page only │
|
||||
│ - alpha: Full platform access │
|
||||
│ - beta: Production-ready features │
|
||||
└─────────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────┐
|
||||
│ FEATURE FLAGS (Tier 2) │
|
||||
│ Controls WHICH features are enabled │
|
||||
│ - Individual feature toggles │
|
||||
│ - Rollout control │
|
||||
│ - A/B testing │
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### **Mode = Platform Scope**
|
||||
|
||||
**App Mode defines what the entire platform can do:**
|
||||
|
||||
- **`pre-launch`**: "We're not ready yet"
|
||||
- Shows: Landing page, Discord CTA, FAQ
|
||||
- Hides: All navigation, dashboard, leagues, teams, races
|
||||
- Purpose: Marketing/teaser phase
|
||||
|
||||
- **`alpha`**: "Early access for testers"
|
||||
- Shows: Everything + alpha badges
|
||||
- Purpose: Internal testing, early adopters
|
||||
- All features enabled by default
|
||||
|
||||
- **`beta`**: "Public beta"
|
||||
- Shows: Production features only
|
||||
- Purpose: Gradual rollout to real users
|
||||
- Features controlled individually
|
||||
|
||||
### **Feature Flags = Feature Control**
|
||||
|
||||
**Feature flags control individual features within a mode:**
|
||||
|
||||
```typescript
|
||||
// In alpha mode, all features are ON by default
|
||||
// But you can still disable specific ones for testing
|
||||
{
|
||||
"platform.dashboard": "enabled",
|
||||
"platform.leagues": "enabled",
|
||||
"platform.teams": "disabled", // Testing without teams
|
||||
"sponsors.portal": "enabled",
|
||||
"admin.dashboard": "enabled"
|
||||
}
|
||||
```
|
||||
|
||||
## Simple Mental Model
|
||||
|
||||
### **For Developers: "The Restaurant Analogy"**
|
||||
|
||||
```
|
||||
APP MODE = Restaurant State
|
||||
├── "Closed" (pre-launch) → Only show entrance/menu
|
||||
├── "Soft Opening" (alpha) → Full menu, everything available
|
||||
└── "Grand Opening" (beta) → Full menu, but some items may be 86'd
|
||||
|
||||
FEATURE FLAGS = Menu Items
|
||||
├── Each dish can be: Available / 86'd / Coming Soon
|
||||
├── Works within whatever restaurant state you're in
|
||||
└── Lets you control individual items precisely
|
||||
```
|
||||
|
||||
### **Decision Tree**
|
||||
|
||||
```
|
||||
Question: "What should I use?"
|
||||
│
|
||||
├─ "Is the platform ready for ANY users?"
|
||||
│ ├─ No → Use APP MODE = pre-launch
|
||||
│ └─ Yes → Continue...
|
||||
│
|
||||
├─ "Are we in testing or production?"
|
||||
│ ├─ Testing → Use APP MODE = alpha
|
||||
│ └─ Production → Use APP MODE = beta
|
||||
│
|
||||
└─ "Do I need to control a specific feature?"
|
||||
└─ Yes → Use FEATURE FLAGS (regardless of mode)
|
||||
```
|
||||
|
||||
## Implementation Rules
|
||||
|
||||
### **Rule 1: Mode Controls Visibility**
|
||||
```typescript
|
||||
// ❌ WRONG: Using feature flags to hide entire platform
|
||||
{
|
||||
"platform": {
|
||||
"dashboard": "disabled",
|
||||
"leagues": "disabled",
|
||||
"teams": "disabled"
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ CORRECT: Use mode for platform-wide visibility
|
||||
// NEXT_PUBLIC_GRIDPILOT_MODE=pre-launch
|
||||
```
|
||||
|
||||
### **Rule 2: Feature Flags Control Granularity**
|
||||
```typescript
|
||||
// ✅ CORRECT: Feature flags for fine-grained control
|
||||
{
|
||||
"platform": {
|
||||
"dashboard": "enabled",
|
||||
"leagues": "enabled",
|
||||
"teams": "enabled", // But specific team features...
|
||||
"teams.create": "disabled", // ...can be toggled
|
||||
"teams.delete": "coming_soon"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### **Rule 3: Alpha Mode = Auto-Enable**
|
||||
```typescript
|
||||
// In alpha mode, ALL features are enabled automatically
|
||||
// Feature flags can only DISABLE, not enable
|
||||
// This eliminates configuration complexity
|
||||
|
||||
// Feature flag service in alpha mode:
|
||||
if (mode === 'alpha') {
|
||||
return new FeatureFlagService([
|
||||
'all', 'features', 'enabled', 'by', 'default'
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
## Migration Path
|
||||
|
||||
### **Current State (Confusing)**
|
||||
```
|
||||
Development:
|
||||
- Mode: pre-launch (default)
|
||||
- Features: All enabled in config
|
||||
- Result: Shows landing page only ❌
|
||||
|
||||
Why? Because mode overrides feature config
|
||||
```
|
||||
|
||||
### **Target State (Clear)**
|
||||
```
|
||||
Development:
|
||||
- Mode: alpha (explicit)
|
||||
- Features: All auto-enabled
|
||||
- Result: Full platform with alpha badges ✅
|
||||
|
||||
Production:
|
||||
- Mode: beta
|
||||
- Features: Controlled individually
|
||||
- Result: Gradual rollout ✅
|
||||
```
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
### **Simple Mode Config**
|
||||
```typescript
|
||||
// apps/website/.env.development
|
||||
NEXT_PUBLIC_GRIDPILOT_MODE=alpha
|
||||
|
||||
// apps/website/.env.production
|
||||
NEXT_PUBLIC_GRIDPILOT_MODE=beta
|
||||
```
|
||||
|
||||
### **Feature Flags (Only When Needed)**
|
||||
```typescript
|
||||
// Only override defaults when necessary
|
||||
// apps/api/src/config/features.config.ts
|
||||
{
|
||||
production: {
|
||||
platform: {
|
||||
dashboard: 'enabled',
|
||||
leagues: 'enabled',
|
||||
teams: 'enabled',
|
||||
races: 'enabled',
|
||||
leaderboards: 'enabled'
|
||||
},
|
||||
sponsors: {
|
||||
portal: 'enabled',
|
||||
dashboard: 'enabled',
|
||||
management: 'disabled' // Not ready yet
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Benefits
|
||||
|
||||
1. **No Confusion**: Clear separation of concerns
|
||||
2. **Less Config**: Alpha mode needs zero feature config
|
||||
3. **Easy Onboarding**: New devs just set mode=alpha
|
||||
4. **Powerful Control**: Feature flags still available when needed
|
||||
5. **Backward Compatible**: Existing code works with new concept
|
||||
|
||||
## Quick Reference
|
||||
|
||||
| Scenario | Mode | Feature Flags | Result |
|
||||
|----------|------|---------------|--------|
|
||||
| Local dev | `alpha` | None needed | Full platform |
|
||||
| CI/CD tests | `alpha` | None needed | Full platform |
|
||||
| Staging | `beta` | Some disabled | Controlled rollout |
|
||||
| Production | `beta` | Gradual enable | Public launch |
|
||||
| Marketing site | `pre-launch` | N/A | Landing page only |
|
||||
|
||||
This eliminates the contradiction and gives you clear power: **Mode for scope, flags for granularity.**
|
||||
Reference in New Issue
Block a user