template-saas/docs/01-modulos/SAAS-009-feature-flags.md
rckrdmrd 50a821a415
Some checks failed
CI / Backend CI (push) Has been cancelled
CI / Frontend CI (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / CI Summary (push) Has been cancelled
[SIMCO-V38] feat: Actualizar a SIMCO v3.8.0
- HERENCIA-SIMCO.md actualizado con directivas v3.7 y v3.8
- Actualizaciones de configuracion

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 08:53:08 -06:00

5.4 KiB

id title type status priority module version created_date updated_date
SAAS-009 Feature Flags Module Published P2 feature-flags 1.0.0 2026-01-07 2026-01-10

SAAS-009: Feature Flags

Metadata

  • Codigo: SAAS-009
  • Modulo: Feature Flags
  • Prioridad: P2
  • Estado: Completado
  • Fase: 4 - Advanced
  • Ultima Actualizacion: 2026-01-10

Descripcion

Sistema de feature flags para control granular de funcionalidades: flags globales, por tenant, por usuario, con porcentaje de rollout y A/B testing basico.

Objetivos

  1. Flags globales (sistema)
  2. Flags por tenant
  3. Flags por usuario
  4. Porcentaje de rollout
  5. A/B testing basico

Alcance

Incluido

  • Feature flags booleanos
  • Flags con valores (string/number)
  • Override por tenant
  • Override por usuario
  • Rollout gradual (%)
  • UI de administracion

Excluido

  • A/B testing avanzado - usar servicio dedicado
  • Analytics de experimentos
  • Machine learning para targeting

Modelo de Datos

Tablas (schema: features)

feature_flags

  • id, key (unique), name, description
  • type (boolean/string/number/json)
  • default_value, is_enabled
  • rollout_percentage (0-100)
  • targeting_rules (JSONB)
  • created_at, updated_at

tenant_feature_overrides

  • id, tenant_id, feature_key
  • value, enabled
  • expires_at

user_feature_overrides

  • id, user_id, feature_key
  • value, enabled
  • expires_at

Flags Predefinidos

Key Tipo Default Descripcion
new_dashboard boolean false Nuevo dashboard beta
ai_assistant boolean false Asistente IA
export_v2 boolean false Nueva exportacion
max_file_size_mb number 10 Limite archivo
theme string 'light' Tema default

Endpoints API

Metodo Endpoint Descripcion
GET /features Listar flags
GET /features/:key Obtener flag
POST /features Crear flag
PUT /features/:key Actualizar flag
DELETE /features/:key Eliminar flag
GET /features/evaluate Evaluar todos para usuario
POST /features/:key/override/tenant Override tenant
POST /features/:key/override/user Override usuario
DELETE /features/:key/override/tenant Quitar override

Implementacion

Servicio

interface FeatureFlagService {
  isEnabled(key: string, context?: EvaluationContext): Promise<boolean>;
  getValue<T>(key: string, context?: EvaluationContext): Promise<T>;
  getAllFlags(context?: EvaluationContext): Promise<Record<string, any>>;
}

interface EvaluationContext {
  tenantId?: string;
  userId?: string;
  attributes?: Record<string, any>;
}

Guard

@RequiresFeature('new_dashboard')
@Get('/dashboard/v2')
async getNewDashboard() {
  // Solo si feature habilitada
}

Condicional en Codigo

if (await this.features.isEnabled('ai_assistant')) {
  // Mostrar boton de IA
}

const maxSize = await this.features.getValue<number>('max_file_size_mb');

Logica de Evaluacion

1. Usuario solicita feature
2. Buscar override de usuario
3. Si existe, usar ese valor
4. Si no, buscar override de tenant
5. Si existe, usar ese valor
6. Si no, evaluar rollout %
7. Si pasa rollout, usar default_value
8. Si no pasa, feature deshabilitada

Rollout Deterministico

// Mismo usuario siempre obtiene mismo resultado
function shouldEnableForUser(userId: string, percentage: number): boolean {
  const hash = crypto.createHash('md5').update(userId).digest('hex');
  const value = parseInt(hash.substring(0, 8), 16) % 100;
  return value < percentage;
}

Targeting Rules

// Ejemplo de reglas avanzadas
{
  "rules": [
    {
      "condition": "plan",
      "operator": "in",
      "values": ["pro", "enterprise"],
      "enabled": true
    },
    {
      "condition": "country",
      "operator": "equals",
      "values": ["MX"],
      "enabled": true
    }
  ]
}

Frontend SDK

// React hook
function useFeatureFlag(key: string): boolean {
  const { flags } = useFeatureFlags();
  return flags[key] ?? false;
}

// Componente
function Dashboard() {
  const showNewDashboard = useFeatureFlag('new_dashboard');

  return showNewDashboard ? <NewDashboard /> : <OldDashboard />;
}

Entregables

Entregable Estado Archivo
feature-flags.module.ts Completado modules/feature-flags/
feature-flags.service.ts Completado services/
feature.guard.ts Completado guards/
DDL feature_flags schema Completado ddl/schemas/feature_flags/
Seeds flags default Completado seeds/prod/

Dependencias

Depende de

  • SAAS-001 (Auth)
  • SAAS-002 (Tenants)
  • SAAS-003 (Users)

Bloquea a

  • Rollouts graduales
  • Experimentos de producto

Criterios de Aceptacion

  • Flags booleanos funcionan
  • Override por tenant funciona
  • Override por usuario funciona
  • Rollout % es deterministico
  • UI admin permite gestion
  • Cache funciona correctamente

Caching

// Redis cache con invalidacion
const cacheKey = `features:${tenantId}:${userId}`;
const cached = await redis.get(cacheKey);
if (cached) return JSON.parse(cached);

const flags = await this.evaluateAllFlags(context);
await redis.setex(cacheKey, 300, JSON.stringify(flags)); // 5 min
return flags;

Ultima actualizacion: 2026-01-10