{"version":3,"file":"flag-lifecycle.mjs","sources":["../../../../src/lib/flags/advanced/flag-lifecycle.ts"],"sourcesContent":["/**\n * @fileoverview Feature flag lifecycle management.\n *\n * Provides comprehensive lifecycle handling:\n * - State transitions (draft -> active -> deprecated -> archived)\n * - Expiration and cleanup tracking\n * - Technical debt monitoring\n * - Audit logging\n * - Review reminders\n *\n * @module flags/advanced/flag-lifecycle\n *\n * @example\n * ```typescript\n * const manager = new LifecycleManager();\n *\n * // Activate a flag\n * const lifecycle = manager.activate(flag.lifecycle, 'user@example.com');\n *\n * // Check for stale flags\n * const staleFlags = manager.getStaleFlags(flags, 30);\n *\n * // Generate cleanup report\n * const report = manager.generateCleanupReport(flags);\n * ```\n */\n\nimport type {\n  FlagLifecycle,\n  FlagLifecycleState,\n  FeatureFlag,\n  FlagId,\n} from './types';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Options for state transitions.\n */\nexport interface TransitionOptions {\n  /** User making the change */\n  readonly user: string;\n  /** Reason for transition */\n  readonly reason?: string;\n  /** Scheduled date for next transition */\n  readonly scheduledDate?: Date;\n}\n\n/**\n * Lifecycle event.\n */\nexport interface LifecycleEvent {\n  readonly type: 'created' | 'activated' | 'paused' | 'deprecated' | 'archived';\n  readonly flagId: FlagId;\n  readonly previousState?: FlagLifecycleState;\n  readonly newState: FlagLifecycleState;\n  readonly timestamp: Date;\n  readonly user: string;\n  readonly reason?: string;\n}\n\n/**\n * Cleanup report for technical debt management.\n */\nexport interface CleanupReport {\n  /** Flags that are overdue for review */\n  readonly overdueForReview: FlagId[];\n  /** Flags that are deprecated and should be removed */\n  readonly readyForRemoval: FlagId[];\n  /** Flags that have been enabled for everyone (100% rollout) */\n  readonly fullyRolledOut: FlagId[];\n  /** Flags with no activity in specified period */\n  readonly dormant: FlagId[];\n  /** Flags approaching their deprecation date */\n  readonly approachingDeprecation: FlagId[];\n  /** Total technical debt score */\n  readonly technicalDebtScore: number;\n  /** Recommendations */\n  readonly recommendations: CleanupRecommendation[];\n}\n\n/**\n * A cleanup recommendation.\n */\nexport interface CleanupRecommendation {\n  readonly flagId: FlagId;\n  readonly action: 'remove' | 'review' | 'deprecate' | 'archive';\n  readonly reason: string;\n  readonly priority: 'high' | 'medium' | 'low';\n  readonly estimatedEffort: 'minimal' | 'moderate' | 'significant';\n}\n\n/**\n * Flag health status.\n */\nexport interface FlagHealth {\n  readonly flagId: FlagId;\n  readonly state: FlagLifecycleState;\n  readonly ageInDays: number;\n  readonly isOverdueForReview: boolean;\n  readonly isApproachingDeprecation: boolean;\n  readonly isStale: boolean;\n  readonly lastActivityDaysAgo?: number;\n  readonly healthScore: number; // 0-100\n  readonly issues: string[];\n}\n\n// ============================================================================\n// State Transition Rules\n// ============================================================================\n\n/**\n * Valid state transitions.\n */\nconst VALID_TRANSITIONS: Record<FlagLifecycleState, FlagLifecycleState[]> = {\n  draft: ['active', 'archived'],\n  active: ['paused', 'deprecated'],\n  paused: ['active', 'deprecated', 'archived'],\n  deprecated: ['archived'],\n  archived: [], // Terminal state\n};\n\n/**\n * Check if a state transition is valid.\n */\nexport function isValidTransition(\n  from: FlagLifecycleState,\n  to: FlagLifecycleState\n): boolean {\n  return VALID_TRANSITIONS[from]?.includes(to) ?? false;\n}\n\n// ============================================================================\n// Lifecycle Manager\n// ============================================================================\n\n/**\n * Manager for feature flag lifecycle operations.\n */\nexport class LifecycleManager {\n  private eventListeners: Array<(event: LifecycleEvent) => void> = [];\n  private activityLog = new Map<FlagId, Date>();\n\n  /**\n   * Create initial lifecycle metadata.\n   */\n  createLifecycle(createdBy: string, options?: {\n    ticketId?: string;\n    documentationUrl?: string;\n    owner?: string;\n    reviewDate?: Date;\n  }): FlagLifecycle {\n    const now = new Date();\n    return {\n      state: 'draft',\n      createdAt: now,\n      createdBy,\n      updatedAt: now,\n      updatedBy: createdBy,\n      ticketId: options?.ticketId,\n      documentationUrl: options?.documentationUrl,\n      owner: options?.owner,\n      reviewDate: options?.reviewDate ?? this.getDefaultReviewDate(now),\n    };\n  }\n\n  /**\n   * Activate a flag.\n   */\n  activate(\n    lifecycle: FlagLifecycle,\n    user: string,\n    reason?: string\n  ): FlagLifecycle {\n    this.validateTransition(lifecycle.state, 'active');\n\n    const updated: FlagLifecycle = {\n      ...lifecycle,\n      state: 'active',\n      updatedAt: new Date(),\n      updatedBy: user,\n      activatedAt: new Date(),\n    };\n\n    this.emitEvent({\n      type: 'activated',\n      flagId: '',\n      previousState: lifecycle.state,\n      newState: 'active',\n      timestamp: new Date(),\n      user,\n      reason,\n    });\n\n    return updated;\n  }\n\n  /**\n   * Pause a flag (temporarily disable).\n   */\n  pause(\n    lifecycle: FlagLifecycle,\n    user: string,\n    _reason?: string\n  ): FlagLifecycle {\n    this.validateTransition(lifecycle.state, 'paused');\n\n    return {\n      ...lifecycle,\n      state: 'paused',\n      updatedAt: new Date(),\n      updatedBy: user,\n    };\n  }\n\n  /**\n   * Deprecate a flag.\n   */\n  deprecate(\n    lifecycle: FlagLifecycle,\n    user: string,\n    options?: {\n      deprecationDate?: Date;\n      removalDate?: Date;\n      reason?: string;\n    }\n  ): FlagLifecycle {\n    this.validateTransition(lifecycle.state, 'deprecated');\n\n    const now = new Date();\n    return {\n      ...lifecycle,\n      state: 'deprecated',\n      updatedAt: now,\n      updatedBy: user,\n      deprecationDate: options?.deprecationDate ?? now,\n      removalDate: options?.removalDate ?? this.getDefaultRemovalDate(now),\n    };\n  }\n\n  /**\n   * Archive a flag.\n   */\n  archive(\n    lifecycle: FlagLifecycle,\n    user: string,\n    _reason?: string\n  ): FlagLifecycle {\n    this.validateTransition(lifecycle.state, 'archived');\n\n    return {\n      ...lifecycle,\n      state: 'archived',\n      updatedAt: new Date(),\n      updatedBy: user,\n    };\n  }\n\n  /**\n   * Update review date.\n   */\n  setReviewDate(\n    lifecycle: FlagLifecycle,\n    reviewDate: Date,\n    user: string\n  ): FlagLifecycle {\n    return {\n      ...lifecycle,\n      reviewDate,\n      updatedAt: new Date(),\n      updatedBy: user,\n    };\n  }\n\n  /**\n   * Update owner.\n   */\n  setOwner(\n    lifecycle: FlagLifecycle,\n    owner: string,\n    user: string\n  ): FlagLifecycle {\n    return {\n      ...lifecycle,\n      owner,\n      updatedAt: new Date(),\n      updatedBy: user,\n    };\n  }\n\n  /**\n   * Record activity for a flag.\n   */\n  recordActivity(flagId: FlagId): void {\n    this.activityLog.set(flagId, new Date());\n  }\n\n  /**\n   * Get last activity date for a flag.\n   */\n  getLastActivity(flagId: FlagId): Date | undefined {\n    return this.activityLog.get(flagId);\n  }\n\n  /**\n   * Get health status for a flag.\n   */\n  getFlagHealth(flag: FeatureFlag): FlagHealth {\n    const {lifecycle} = flag;\n    const now = new Date();\n    const issues: string[] = [];\n\n    const ageInDays = Math.floor(\n      (now.getTime() - lifecycle.createdAt.getTime()) / (1000 * 60 * 60 * 24)\n    );\n\n    const isOverdueForReview =\n      lifecycle.reviewDate != null && lifecycle.reviewDate < now;\n    const isApproachingDeprecation =\n      lifecycle.deprecationDate &&\n      lifecycle.deprecationDate > now &&\n      lifecycle.deprecationDate.getTime() - now.getTime() <\n        7 * 24 * 60 * 60 * 1000; // 7 days\n\n    const lastActivity = this.activityLog.get(flag.id);\n    const lastActivityDaysAgo = lastActivity\n      ? Math.floor(\n          (now.getTime() - lastActivity.getTime()) / (1000 * 60 * 60 * 24)\n        )\n      : undefined;\n    const isStale = lastActivityDaysAgo !== undefined && lastActivityDaysAgo > 30;\n\n    // Calculate health score\n    let healthScore = 100;\n\n    if (isOverdueForReview) {\n      healthScore -= 20;\n      issues.push('Overdue for review');\n    }\n\n    if (isStale) {\n      healthScore -= 15;\n      issues.push('No recent activity');\n    }\n\n    if (lifecycle.state === 'deprecated') {\n      healthScore -= 10;\n      issues.push('Flag is deprecated');\n    }\n\n    if (ageInDays > 180) {\n      healthScore -= 10;\n      issues.push('Flag is over 6 months old');\n    }\n\n    if (lifecycle.owner == null || lifecycle.owner === '') {\n      healthScore -= 10;\n      issues.push('No owner assigned');\n    }\n\n    if (lifecycle.documentationUrl == null || lifecycle.documentationUrl === '') {\n      healthScore -= 5;\n      issues.push('No documentation link');\n    }\n\n    if (lifecycle.ticketId == null || lifecycle.ticketId === '') {\n      healthScore -= 5;\n      issues.push('No ticket reference');\n    }\n\n    return {\n      flagId: flag.id,\n      state: lifecycle.state,\n      ageInDays,\n      isOverdueForReview: isOverdueForReview ?? false,\n      isApproachingDeprecation: isApproachingDeprecation ?? false,\n      isStale,\n      lastActivityDaysAgo,\n      healthScore: Math.max(0, healthScore),\n      issues,\n    };\n  }\n\n  // ==========================================================================\n  // Activity Tracking\n  // ==========================================================================\n\n  /**\n   * Get stale flags (no activity in specified days).\n   */\n  getStaleFlags(\n    flags: readonly FeatureFlag[],\n    staleDays: number = 30\n  ): FeatureFlag[] {\n    const now = new Date();\n    const cutoff = new Date(now.getTime() - staleDays * 24 * 60 * 60 * 1000);\n\n    return flags.filter((flag) => {\n      const lastActivity = this.activityLog.get(flag.id);\n      return (\n        flag.lifecycle.state === 'active' &&\n        (!lastActivity || lastActivity < cutoff)\n      );\n    });\n  }\n\n  /**\n   * Get flags that are overdue for review.\n   */\n  getOverdueFlags(flags: readonly FeatureFlag[]): FeatureFlag[] {\n    const now = new Date();\n    return flags.filter(\n      (flag) =>\n        flag.lifecycle.reviewDate != null &&\n        flag.lifecycle.reviewDate < now &&\n        flag.lifecycle.state !== 'archived'\n    );\n  }\n\n  // ==========================================================================\n  // Health & Analysis\n  // ==========================================================================\n\n  /**\n   * Get deprecated flags ready for removal.\n   */\n  getFlagsReadyForRemoval(flags: readonly FeatureFlag[]): FeatureFlag[] {\n    const now = new Date();\n    return flags.filter(\n      (flag) =>\n        flag.lifecycle.state === 'deprecated' &&\n        flag.lifecycle.removalDate != null &&\n        flag.lifecycle.removalDate < now\n    );\n  }\n\n  /**\n   * Generate a comprehensive cleanup report.\n   */\n  generateCleanupReport(flags: readonly FeatureFlag[]): CleanupReport {\n    const now = new Date();\n    const sevenDaysFromNow = new Date(\n      now.getTime() + 7 * 24 * 60 * 60 * 1000\n    );\n\n    const overdueForReview: FlagId[] = [];\n    const readyForRemoval: FlagId[] = [];\n    const fullyRolledOut: FlagId[] = [];\n    const dormant: FlagId[] = [];\n    const approachingDeprecation: FlagId[] = [];\n    const recommendations: CleanupRecommendation[] = [];\n\n    let technicalDebtScore = 0;\n\n    for (const flag of flags) {\n      const health = this.getFlagHealth(flag);\n\n      // Overdue for review\n      if (health.isOverdueForReview) {\n        overdueForReview.push(flag.id);\n        technicalDebtScore += 5;\n        recommendations.push({\n          flagId: flag.id,\n          action: 'review',\n          reason: 'Flag is overdue for scheduled review',\n          priority: 'medium',\n          estimatedEffort: 'minimal',\n        });\n      }\n\n      // Ready for removal\n      if (\n        flag.lifecycle.state === 'deprecated' &&\n        flag.lifecycle.removalDate &&\n        flag.lifecycle.removalDate < now\n      ) {\n        readyForRemoval.push(flag.id);\n        technicalDebtScore += 10;\n        recommendations.push({\n          flagId: flag.id,\n          action: 'remove',\n          reason: 'Deprecated flag past removal date',\n          priority: 'high',\n          estimatedEffort: 'moderate',\n        });\n      }\n\n      // Fully rolled out\n      if (\n        flag.rollout &&\n        'percentage' in flag.rollout &&\n        flag.rollout.percentage === 100\n      ) {\n        fullyRolledOut.push(flag.id);\n        technicalDebtScore += 3;\n        recommendations.push({\n          flagId: flag.id,\n          action: 'remove',\n          reason: 'Flag is at 100% rollout - consider removing',\n          priority: 'low',\n          estimatedEffort: 'moderate',\n        });\n      }\n\n      // Dormant\n      if (health.isStale && flag.lifecycle.state === 'active') {\n        dormant.push(flag.id);\n        technicalDebtScore += 2;\n        recommendations.push({\n          flagId: flag.id,\n          action: 'review',\n          reason: 'No activity in over 30 days',\n          priority: 'low',\n          estimatedEffort: 'minimal',\n        });\n      }\n\n      // Approaching deprecation\n      if (\n        flag.lifecycle.deprecationDate &&\n        flag.lifecycle.deprecationDate > now &&\n        flag.lifecycle.deprecationDate < sevenDaysFromNow\n      ) {\n        approachingDeprecation.push(flag.id);\n        recommendations.push({\n          flagId: flag.id,\n          action: 'deprecate',\n          reason: 'Deprecation date approaching',\n          priority: 'medium',\n          estimatedEffort: 'minimal',\n        });\n      }\n\n      // Old active flags\n      if (health.ageInDays > 180 && flag.lifecycle.state === 'active') {\n        technicalDebtScore += 3;\n        if (\n          !recommendations.some(\n            (r) => r.flagId === flag.id && r.action === 'review'\n          )\n        ) {\n          recommendations.push({\n            flagId: flag.id,\n            action: 'review',\n            reason: 'Flag has been active for over 6 months',\n            priority: 'medium',\n            estimatedEffort: 'minimal',\n          });\n        }\n      }\n    }\n\n    // Sort recommendations by priority\n    const priorityOrder = { high: 0, medium: 1, low: 2 };\n    recommendations.sort(\n      (a, b) => priorityOrder[a.priority] - priorityOrder[b.priority]\n    );\n\n    return {\n      overdueForReview,\n      readyForRemoval,\n      fullyRolledOut,\n      dormant,\n      approachingDeprecation,\n      technicalDebtScore,\n      recommendations,\n    };\n  }\n\n  /**\n   * Add event listener.\n   */\n  addEventListener(listener: (event: LifecycleEvent) => void): void {\n    this.eventListeners.push(listener);\n  }\n\n  /**\n   * Remove event listener.\n   */\n  removeEventListener(listener: (event: LifecycleEvent) => void): void {\n    const index = this.eventListeners.indexOf(listener);\n    if (index > -1) {\n      this.eventListeners.splice(index, 1);\n    }\n  }\n\n  private validateTransition(\n    from: FlagLifecycleState,\n    to: FlagLifecycleState\n  ): void {\n    if (!isValidTransition(from, to)) {\n      throw new Error(\n        `Invalid state transition from '${from}' to '${to}'`\n      );\n    }\n  }\n\n  // ==========================================================================\n  // Event Handling\n  // ==========================================================================\n\n  private getDefaultReviewDate(from: Date): Date {\n    const reviewDate = new Date(from);\n    reviewDate.setDate(reviewDate.getDate() + 30); // 30 days default\n    return reviewDate;\n  }\n\n  private getDefaultRemovalDate(from: Date): Date {\n    const removalDate = new Date(from);\n    removalDate.setDate(removalDate.getDate() + 90); // 90 days default\n    return removalDate;\n  }\n\n  private emitEvent(event: LifecycleEvent): void {\n    for (const listener of this.eventListeners) {\n      try {\n        listener(event);\n      } catch (error) {\n        console.error('Error in lifecycle event listener:', error);\n      }\n    }\n  }\n}\n\n// ============================================================================\n// Lifecycle Builder\n// ============================================================================\n\n/**\n * Mutable lifecycle type for builder.\n */\ntype MutableFlagLifecycle = {\n  -readonly [K in keyof FlagLifecycle]: FlagLifecycle[K];\n};\n\n/**\n * Fluent builder for creating lifecycle metadata.\n */\nexport class LifecycleBuilder {\n  private lifecycle: Partial<MutableFlagLifecycle> = {};\n\n  constructor(createdBy: string) {\n    const now = new Date();\n    this.lifecycle = {\n      state: 'draft',\n      createdAt: now,\n      createdBy,\n      updatedAt: now,\n      updatedBy: createdBy,\n    };\n  }\n\n  /**\n   * Set ticket/issue reference.\n   */\n  ticket(ticketId: string): this {\n    this.lifecycle.ticketId = ticketId;\n    return this;\n  }\n\n  /**\n   * Set documentation URL.\n   */\n  documentation(url: string): this {\n    this.lifecycle.documentationUrl = url;\n    return this;\n  }\n\n  /**\n   * Set owner.\n   */\n  owner(owner: string): this {\n    this.lifecycle.owner = owner;\n    return this;\n  }\n\n  /**\n   * Set review date.\n   */\n  reviewDate(date: Date): this {\n    this.lifecycle.reviewDate = date;\n    return this;\n  }\n\n  /**\n   * Set deprecation date.\n   */\n  deprecationDate(date: Date): this {\n    this.lifecycle.deprecationDate = date;\n    return this;\n  }\n\n  /**\n   * Set removal date.\n   */\n  removalDate(date: Date): this {\n    this.lifecycle.removalDate = date;\n    return this;\n  }\n\n  /**\n   * Build the lifecycle metadata.\n   */\n  build(): FlagLifecycle {\n    return {\n      state: this.lifecycle.state ?? 'draft',\n      createdAt: this.lifecycle.createdAt ?? new Date(),\n      createdBy: this.lifecycle.createdBy ?? 'unknown',\n      updatedAt: this.lifecycle.updatedAt ?? new Date(),\n      updatedBy: this.lifecycle.updatedBy ?? 'unknown',\n      ticketId: this.lifecycle.ticketId,\n      documentationUrl: this.lifecycle.documentationUrl,\n      owner: this.lifecycle.owner,\n      reviewDate: this.lifecycle.reviewDate,\n      deprecationDate: this.lifecycle.deprecationDate,\n      removalDate: this.lifecycle.removalDate,\n    };\n  }\n}\n\n/**\n * Create a lifecycle builder.\n */\nexport function createLifecycle(createdBy: string): LifecycleBuilder {\n  return new LifecycleBuilder(createdBy);\n}\n\n// ============================================================================\n// Singleton Instance\n// ============================================================================\n\nlet instance: LifecycleManager | null = null;\n\n/**\n * Get the singleton lifecycle manager instance.\n */\nexport function getLifecycleManager(): LifecycleManager {\n  instance ??= new LifecycleManager();\n  return instance;\n}\n\n/**\n * Reset the singleton instance.\n */\nexport function resetLifecycleManager(): void {\n  instance = null;\n}\n"],"names":["VALID_TRANSITIONS","isValidTransition","from","to","LifecycleManager","createdBy","options","now","lifecycle","user","reason","updated","_reason","reviewDate","owner","flagId","flag","issues","ageInDays","isOverdueForReview","isApproachingDeprecation","lastActivity","lastActivityDaysAgo","isStale","healthScore","flags","staleDays","cutoff","sevenDaysFromNow","overdueForReview","readyForRemoval","fullyRolledOut","dormant","approachingDeprecation","recommendations","technicalDebtScore","health","r","priorityOrder","b","listener","index","removalDate","event","error","LifecycleBuilder","ticketId","url","date","createLifecycle","instance","getLifecycleManager","resetLifecycleManager"],"mappings":"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"}