# US-MGN006-004: Gestionar Feature Flags

## Identificacion

| Campo | Valor |
|-------|-------|
| **ID** | US-MGN006-004 |
| **Modulo** | MGN-006 Settings |
| **Sprint** | Sprint 4 |
| **Prioridad** | P1 - Alta |
| **Story Points** | 8 |
| **Estado** | Ready |
| **RF Relacionado** | RF-SETTINGS-004 |
| **Fecha** | 2025-12-05 |

---

## Historia de Usuario

**Como** administrador del sistema
**Quiero** controlar la disponibilidad de funcionalidades mediante feature flags
**Para** realizar despliegues graduales y controlar acceso a features

---

## Descripcion

Los feature flags permiten habilitar/deshabilitar funcionalidades sin despliegues. Soportan diferentes tipos: booleano, porcentaje (rollout gradual), y variantes (A/B testing). Pueden tener overrides por tenant o usuario.

### Contexto

- Control de funcionalidades en runtime
- Despliegues graduales (canary)
- Testing A/B
- Kill switches para emergencias

---

## Criterios de Aceptacion

### Escenario 1: Listar feature flags

```gherkin
Given un super administrador
When accede a GET /api/v1/admin/features
Then el sistema responde con status 200
  And retorna lista de flags con:
    | key, name, flagType, defaultValue, isActive, expiresAt |
```

### Escenario 2: Evaluar flag booleano

```gherkin
Given flag "feature.dark_mode" tipo boolean con defaultValue = true
When endpoint GET /api/v1/features/feature.dark_mode es llamado
Then retorna:
  | enabled | true |
  | source | "default" |
```

### Escenario 3: Evaluar flag con override de tenant

```gherkin
Given flag "feature.new_dashboard" defaultValue = false
  And override para tenant actual con value = true
When se evalua el flag
Then retorna:
  | enabled | true |
  | source | "tenant_override" |
```

### Escenario 4: Evaluar flag con override de usuario

```gherkin
Given flag "feature.beta_editor" con varios overrides
  And override para usuario actual = true
When se evalua el flag
Then retorna:
  | enabled | true |
  | source | "user_override" |
  And el override de usuario tiene precedencia sobre tenant
```

### Escenario 5: Flag tipo porcentaje

```gherkin
Given flag "feature.new_checkout" tipo percentage
  And rolloutConfig.percentage = 20
When 100 usuarios diferentes evaluan el flag
Then aproximadamente 20 usuarios obtienen enabled = true
  And la evaluacion es deterministica por userId
```

### Escenario 6: Flag tipo variante

```gherkin
Given flag "experiment.button_color" tipo variant
  And variantes: ["blue", "green", "red"] con pesos iguales
When usuario evalua el flag
Then retorna:
  | enabled | true |
  | variant | "green" |
  And el usuario siempre obtiene la misma variante
```

### Escenario 7: Flag expirado

```gherkin
Given flag "feature.holiday_sale" con expiresAt = ayer
When se evalua el flag
Then retorna:
  | enabled | false |
  | source | "expired" |
```

### Escenario 8: Crear override

```gherkin
Given flag "feature.advanced_reports"
  And super admin con permiso
When envia POST /api/v1/admin/features/feature.advanced_reports/overrides
  | level | "tenant" |
  | levelId | "tenant-uuid" |
  | value | true |
Then el override se crea
  And el tenant obtiene la feature habilitada
```

### Escenario 9: Evaluar multiples flags

```gherkin
Given varios flags activos
When envia POST /api/v1/features/evaluate
  | keys | ["feature.a", "feature.b", "feature.c"] |
Then retorna objeto con evaluacion de cada flag
  And es mas eficiente que evaluar uno por uno
```

### Escenario 10: Uso de @RequireFeature

```gherkin
Given endpoint protegido con @RequireFeature("feature.beta_api")
  And flag deshabilitado para usuario actual
When usuario accede al endpoint
Then el sistema responde con status 403
  And el mensaje indica "Feature not available"
```

---

## Mockup / Wireframe

```
+------------------------------------------------------------------+
|  FEATURE FLAGS                                    [+ Nuevo Flag] |
+------------------------------------------------------------------+
| [Estado: Todos v]  [Tipo: Todos v]  [Buscar...]                  |
+------------------------------------------------------------------+

| FLAG              | NOMBRE             | TIPO    | ESTADO | VALOR |
+------------------------------------------------------------------+
| feature.dark_mode | Modo Oscuro        | boolean | ✓ Act  | true  |
| feature.new_dash  | Nuevo Dashboard    | boolean | ✓ Act  | false |
| feature.checkout  | Nuevo Checkout     | percent | ✓ Act  | 20%   |
| exp.button_color  | Experimento Boton  | variant | ✓ Act  | A/B/C |
| feature.sale      | Venta Especial     | boolean | ✗ Exp  | -     |
+------------------------------------------------------------------+

Detalle de Flag:
+------------------------------------------------------------------+
| feature.new_dashboard                                        [X] |
+------------------------------------------------------------------+
| Nombre: Nuevo Dashboard                                          |
| Tipo: boolean                                                    |
| Valor por defecto: false                                         |
| Expira: 2025-12-31                                              |
|                                                                  |
| OVERRIDES                                                        |
+------------------------------------------------------------------+
| NIVEL   | ID                  | VALOR | ACTIVO | ACCIONES        |
+------------------------------------------------------------------+
| Tenant  | Empresa ABC         | true  | ✓      | [Editar][Elim]  |
| Tenant  | Empresa XYZ         | true  | ✓      | [Editar][Elim]  |
| User    | admin@abc.com       | false | ✓      | [Editar][Elim]  |
+------------------------------------------------------------------+
                                              [+ Agregar Override]

| ESTADISTICAS                                                     |
+------------------------------------------------------------------+
| Evaluaciones hoy: 1,234                                          |
| Habilitado para: 45% de usuarios                                |
+------------------------------------------------------------------+
```

---

## Notas Tecnicas

### API Endpoints

| Metodo | Path | Descripcion |
|--------|------|-------------|
| GET | /features/:key | Evaluar flag |
| POST | /features/evaluate | Evaluar multiples |
| GET | /admin/features | Listar todos |
| POST | /admin/features | Crear flag |
| PATCH | /admin/features/:key | Actualizar |
| POST | /admin/features/:key/overrides | Crear override |
| DELETE | /admin/features/:key/overrides/:id | Eliminar override |

### Algoritmo de Evaluacion

```typescript
async function evaluate(key: string, context: Context): Promise<Result> {
  const flag = await getFlag(key);

  if (!flag || !flag.isActive) return { enabled: false, source: 'not_found' };
  if (flag.expiresAt && flag.expiresAt < new Date()) return { enabled: false, source: 'expired' };

  // Check user override
  if (context.userId) {
    const userOverride = await getOverride(flag.id, 'user', context.userId);
    if (userOverride) return { enabled: userOverride.value, source: 'user_override' };
  }

  // Check tenant override
  if (context.tenantId) {
    const tenantOverride = await getOverride(flag.id, 'tenant', context.tenantId);
    if (tenantOverride) return { enabled: tenantOverride.value, source: 'tenant_override' };
  }

  // Evaluate based on flag type
  return evaluateByType(flag, context);
}
```

---

## Definicion de Done

- [ ] CRUD feature flags
- [ ] Evaluacion por tipo (boolean, percentage, variant)
- [ ] Overrides por tenant y usuario
- [ ] Cache con invalidacion
- [ ] Guard @RequireFeature
- [ ] Evaluacion multiple
- [ ] UI de administracion
- [ ] Tests unitarios
- [ ] Documentacion Swagger

---

## Dependencias

### Requiere

| Item | Descripcion |
|------|-------------|
| Tabla feature_flags | Definiciones |
| Tabla feature_flag_overrides | Overrides |
| Cache Redis | Para evaluacion rapida |

### Bloquea

| Item | Descripcion |
|------|-------------|
| Cualquier feature | Puede ser controlada |
| Experimentos A/B | Variantes |

---

## Historial

| Version | Fecha | Autor | Cambios |
|---------|-------|-------|---------|
| 1.0 | 2025-12-05 | Requirements-Analyst | Creacion inicial |
