'array', 'is_active' => 'boolean', ]; /** * Feature categories */ const CATEGORY_CORE = 'core'; const CATEGORY_ADVANCED = 'advanced'; const CATEGORY_PREMIUM = 'premium'; /** * Feature types */ const TYPE_BOOLEAN = 'boolean'; const TYPE_NUMERIC = 'numeric'; const TYPE_TOGGLE = 'toggle'; /** * Get plan feature limits for this feature */ public function planFeatureLimits(): HasMany { return $this->hasMany(PlanFeatureLimit::class); } /** * Get plan permissions for this feature */ public function planPermissions(): HasMany { return $this->hasMany(PlanPermission::class); } /** * Get usage tracking for this feature */ public function planUsages(): HasMany { return $this->hasMany(PlanUsage::class); } /** * Scope: Active features */ public function scopeActive($query) { return $query->where('is_active', true); } /** * Scope: By category */ public function scopeByCategory($query, string $category) { return $query->where('category', $category); } /** * Scope: Ordered by sort order */ public function scopeOrdered($query) { return $query->orderBy('sort_order')->orderBy('display_name'); } /** * Get feature metadata value */ public function getMetadata(?string $key = null, $default = null) { if ($key) { return data_get($this->metadata, $key, $default); } return $this->metadata; } /** * Set feature metadata value */ public function setMetadata(string $key, $value): void { $data = $this->metadata ?? []; data_set($data, $key, $value); $this->metadata = $data; } }