# Feature Flags

> **Note**: This document provides a comprehensive guide for implementing and managing feature flags
> in the Suno Android app using Statsig.

---

## Overview

The Suno Android app uses **Statsig** as its feature flagging and A/B testing platform. Feature
flags allow us to control feature releases, perform gradual rollouts, and conduct experiments
without requiring app updates.

## Architecture

### Core Components

- **`StatsigManager.kt`**: Interface for feature flag operations
- **`FeatureGates.kt`**: Central location for feature flag management

### Module Structure

```
common-gating/
 ├── src/main/java/com/suno/android/gating/
 │    ├── FeatureGate.kt          # Feature flag definitions
 │    ├── StatsigManager.kt       # Interface for Statsig operations
 │    ├── StatsigManagerImpl.kt   # Statsig SDK implementation
 │    └── di/                     # Dependency injection setup
 └── build.gradle.kts            # Statsig SDK dependency
```

# Implementation Guide

## 1. Create a Feature Flag in Statsig

### Android Template Setup

When creating a new feature flag in Statsig:

![create-feature-gate.png](create-feature-gate.png)

1. **Use the Android Template**: The template creates appropriate gates for:
    - Staff environment
    - Production environment
    - Mobot (QA service)
    - Other testing environments

![statsig-gates.png](statsig-gates.png)

2. **Gate Configuration**:
    - **Don't touch the top gate**: There's a legacy gate at the top that should remain unchanged
    - **Use the last gate**: This is your main release gate
    - **Set version targeting**: Specify the app version where the feature should be available
    - **Raise the gate**: Move to the second position in the list to enable the feature

## 2. Utilize the Feature Flag in code

#### Step 1: Add to FeatureGate Enum

Add your feature flag to `common-gating/src/main/java/com/suno/android/gating/FeatureGate.kt`:

```kotlin
enum class FeatureGate(
    val value: String,
) {
    // ... existing flags ...
    YOUR_NEW_FEATURE("android-your-new-feature"),
}
```

**Naming Convention:**

- Use descriptive, action-oriented names (e.g., `SHOW_DOWNLOADS`, `ENABLE_AUDIO_RECORDING`)
- Follow SCREAMING_SNAKE_CASE for enum constants
- Use `android-` prefix for the Statsig gate name

#### Step 2: Use the StatsigManager in VM

#### State Management Integration

For MVI architecture, include feature flags in your state:

```kotlin
data class YourScreenState(
    val isNewFeatureEnabled: Boolean = false,
    // ... other state properties
)
```

Inject `StatsigManager` and check the gate when initializing the state in the VM.

```kotlin
@HiltViewModel
class YourScreenVM @Inject constructor(
    processorFactory: MviProcessorFactory,
) : MviViewModel(
    processorFactory = processorFactory,
    initialState = YourScreenState(
        isNewFeatureEnabled = statsigManager.checkGate(FeatureGate.YOUR_NEW_FEATURE),
    ),
) {
    ...
}
```

#### Step 3: Use the state in the screen to render UI or adjust behavior accordingly.

```kotlin
@Composable
fun YourScreen() {
    ...
    if (state.isNewFeatureEnabled) {
        NewFeatureUi()
    } else {
        OldFeatureUi()
    }
    ...
}
```

---

## Best Practices

### 1. Flag Naming

- **Descriptive names**: Use clear, action-oriented names
- **Consistent prefix**: Always use `android-` prefix for Statsig gate names
- **Feature grouping**: Group related features with similar prefixes

### 2. Implementation Patterns

- **Fail-safe defaults**: Always provide sensible default behavior when flags are disabled
- **Graceful degradation**: Ensure the app works without new features
- **State consistency**: Include feature flags in relevant state objects

### 3. Testing

- **Unit testing**: Mock `StatsigManager` in tests
- **Integration testing**: Test both enabled and disabled flag states
- **UI testing**: Verify conditional rendering works correctly

### 4. Code Organization

- **Centralized flags**: Keep all flags in `FeatureGate.kt`
- **Consistent usage**: Use `statsigManager.checkGate()` pattern throughout
- **Documentation**: Comment complex flag logic
