'tier.apollo', 'name' => 'Apollo Tier', 'description' => 'Access to Apollo tier features', 'category' => 'tier', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 1, ], [ 'code' => 'tier.hades', 'name' => 'Hades Tier', 'description' => 'Access to Hades tier features (developer tools)', 'category' => 'tier', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 2, ], // Lethean Network designations [ 'code' => 'tier.nyx', 'name' => 'Nyx Tier', 'description' => 'Demo/test account access (Lethean Network)', 'category' => 'tier', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 3, ], [ 'code' => 'tier.stygian', 'name' => 'Stygian Tier', 'description' => 'Standard user access (Lethean Network)', 'category' => 'tier', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 4, ], // Corporate Sponsors (Lethean Network) [ 'code' => 'tier.plouton', 'name' => 'Ploutōn Tier', 'description' => 'White label partner access (Lethean Network)', 'category' => 'tier', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 5, ], [ 'code' => 'tier.hermes', 'name' => 'Hermes Tier', 'description' => 'Founding patron access - seat in Elysia (Lethean Network)', 'category' => 'tier', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 6, ], // Service access gates (deny by default) [ 'code' => 'core.srv.social', 'name' => 'SocialHost Access', 'description' => 'Access to SocialHost social media management', 'category' => 'service', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 1, ], [ 'code' => 'core.srv.bio', 'name' => 'BioHost Access', 'description' => 'Access to BioHost link-in-bio pages', 'category' => 'service', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 2, ], [ 'code' => 'core.srv.analytics', 'name' => 'AnalyticsHost Access', 'description' => 'Access to AnalyticsHost privacy-focused analytics', 'category' => 'service', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 3, ], [ 'code' => 'core.srv.trust', 'name' => 'TrustHost Access', 'description' => 'Access to TrustHost social proof notifications', 'category' => 'service', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 4, ], [ 'code' => 'core.srv.notify', 'name' => 'NotifyHost Access', 'description' => 'Access to NotifyHost push notifications', 'category' => 'service', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 5, ], [ 'code' => 'core.srv.support', 'name' => 'SupportHost Access', 'description' => 'Access to SupportHost help desk', 'category' => 'service', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 6, ], [ 'code' => 'core.srv.web', 'name' => 'WebHost Access', 'description' => 'Access to WebHost site management', 'category' => 'service', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 7, ], [ 'code' => 'core.srv.commerce', 'name' => 'Commerce Access', 'description' => 'Access to Commerce store management', 'category' => 'service', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 8, ], [ 'code' => 'core.srv.hub', 'name' => 'Hub Access', 'description' => 'Access to Hub admin panel', 'category' => 'service', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 0, // Internal service ], [ 'code' => 'core.srv.agentic', 'name' => 'Agentic Access', 'description' => 'Access to AI agent services', 'category' => 'service', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 9, ], // Social features [ 'code' => 'social.accounts', 'name' => 'Social Accounts', 'description' => 'Number of connected social media accounts', 'category' => 'social', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 1, ], [ 'code' => 'social.posts.scheduled', 'name' => 'Scheduled Posts', 'description' => 'Number of scheduled posts per month', 'category' => 'social', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_MONTHLY, 'sort_order' => 2, ], [ 'code' => 'social.workspaces', 'name' => 'Social Workspaces', 'description' => 'Number of social workspaces', 'category' => 'social', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 3, ], [ 'code' => 'social.posts.bulk', 'name' => 'Bulk Post Upload', 'description' => 'Upload multiple posts via CSV/bulk import', 'category' => 'social', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 4, ], [ 'code' => 'social.analytics', 'name' => 'Social Analytics', 'description' => 'Access to social media analytics', 'category' => 'social', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 5, ], [ 'code' => 'social.analytics.advanced', 'name' => 'Advanced Analytics', 'description' => 'Advanced reporting and analytics features', 'category' => 'social', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 6, ], [ 'code' => 'social.team', 'name' => 'Team Collaboration', 'description' => 'Multi-user team features for social management', 'category' => 'social', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 7, ], [ 'code' => 'social.approval_workflow', 'name' => 'Approval Workflow', 'description' => 'Content approval workflow before posting', 'category' => 'social', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 8, ], [ 'code' => 'social.white_label', 'name' => 'White Label', 'description' => 'Remove SocialHost branding', 'category' => 'social', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 9, ], [ 'code' => 'social.api_access', 'name' => 'Social API Access', 'description' => 'Access to SocialHost API', 'category' => 'social', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 10, ], [ 'code' => 'social.templates', 'name' => 'Post Templates', 'description' => 'Number of saved post templates', 'category' => 'social', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 11, ], [ 'code' => 'social.hashtag_groups', 'name' => 'Hashtag Groups', 'description' => 'Number of saved hashtag groups', 'category' => 'social', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 12, ], [ 'code' => 'social.ai_suggestions', 'name' => 'AI Content Suggestions', 'description' => 'AI-powered caption generation and content improvement', 'category' => 'social', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 13, ], // AI features [ 'code' => 'ai.credits', 'name' => 'AI Credits', 'description' => 'AI generation credits per month', 'category' => 'ai', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_MONTHLY, 'sort_order' => 1, ], [ 'code' => 'ai.providers.claude', 'name' => 'Claude AI', 'description' => 'Access to Claude AI provider', 'category' => 'ai', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 2, ], [ 'code' => 'ai.providers.gemini', 'name' => 'Gemini AI', 'description' => 'Access to Gemini AI provider', 'category' => 'ai', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 3, ], // Team features [ 'code' => 'team.members', 'name' => 'Team Members', 'description' => 'Number of team members per workspace', 'category' => 'team', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 1, ], // API features [ 'code' => 'api.requests', 'name' => 'API Requests', 'description' => 'API requests per 30 days (rolling)', 'category' => 'api', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_ROLLING, 'rolling_window_days' => 30, 'sort_order' => 1, ], // MCP Quota features [ 'code' => 'mcp.monthly_tool_calls', 'name' => 'MCP Tool Calls', 'description' => 'Monthly limit for MCP tool calls', 'category' => 'mcp', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_MONTHLY, 'sort_order' => 1, ], [ 'code' => 'mcp.monthly_tokens', 'name' => 'MCP Tokens', 'description' => 'Monthly limit for MCP token consumption', 'category' => 'mcp', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_MONTHLY, 'sort_order' => 2, ], // Storage - Global pool [ 'code' => 'core.res.storage.total', 'name' => 'Total Storage', 'description' => 'Total storage across all services (MB)', 'category' => 'storage', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 1, ], // ───────────────────────────────────────────────────────────── // lt.hn Pricing Features (numeric - ordered by sort_order) // ───────────────────────────────────────────────────────────── [ 'code' => 'bio.pages', 'name' => 'Bio Pages', 'description' => 'Number of pages allowed', 'category' => 'web', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 10, ], [ 'code' => 'webpage.sub_pages', 'name' => 'Sub-Pages', 'description' => 'Additional pages under your main page', 'category' => 'web', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 20, ], [ 'code' => 'bio.blocks', 'name' => 'Page Blocks', 'description' => 'Number of blocks per page', 'category' => 'web', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 30, ], [ 'code' => 'bio.static_sites', 'name' => 'Static Websites', 'description' => 'Number of static websites allowed', 'category' => 'web', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 40, ], [ 'code' => 'bio.custom_domains', 'name' => 'Custom Domains', 'description' => 'Number of custom domains allowed', 'category' => 'web', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 50, ], [ 'code' => 'bio.web3_domains', 'name' => 'Web3 Domains', 'description' => 'Number of Web3 domains (ENS, etc.)', 'category' => 'web', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 60, ], [ 'code' => 'bio.vcard', 'name' => 'vCard', 'description' => 'Number of vCard downloads allowed', 'category' => 'web', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 70, ], [ 'code' => 'bio.events', 'name' => 'Events', 'description' => 'Number of event blocks allowed', 'category' => 'web', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 80, ], [ 'code' => 'bio.file_downloads', 'name' => 'File Downloads', 'description' => 'Number of file download blocks allowed', 'category' => 'web', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 90, ], [ 'code' => 'bio.splash_pages', 'name' => 'Splash Pages', 'description' => 'Number of splash/landing pages allowed', 'category' => 'web', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 100, ], [ 'code' => 'bio.shortened_links', 'name' => 'Shortened Links', 'description' => 'Number of shortened links allowed', 'category' => 'web', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 110, ], [ 'code' => 'bio.pixels', 'name' => 'Pixels', 'description' => 'Number of tracking pixels allowed', 'category' => 'web', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 120, ], [ 'code' => 'bio.qr_codes', 'name' => 'QR Codes', 'description' => 'Number of QR codes allowed', 'category' => 'web', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 130, ], // ───────────────────────────────────────────────────────────── // lt.hn Pricing Features (boolean - ordered by sort_order) // ───────────────────────────────────────────────────────────── [ 'code' => 'bio.analytics.basic', 'name' => 'Basic Analytics', 'description' => 'Basic analytics for pages', 'category' => 'web', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 200, ], [ 'code' => 'support.community', 'name' => 'Community Support', 'description' => 'Access to community support', 'category' => 'support', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 210, ], [ 'code' => 'support.host.uk.com', 'name' => 'Support', 'description' => 'Email support access', 'category' => 'support', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 211, ], [ 'code' => 'support.priority', 'name' => 'Priority Support', 'description' => 'Priority support access', 'category' => 'support', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 212, ], [ 'code' => 'bio.themes', 'name' => 'Themes', 'description' => 'Access to page themes', 'category' => 'web', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 220, ], // ───────────────────────────────────────────────────────────── // Legacy Bio features (internal use) // ───────────────────────────────────────────────────────────── [ 'code' => 'bio.shortlinks', 'name' => 'Short Links', 'description' => 'Number of short links allowed', 'category' => 'web', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 150, ], [ 'code' => 'bio.static', 'name' => 'Static Pages', 'description' => 'Number of static HTML pages allowed', 'category' => 'web', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 151, ], [ 'code' => 'bio.domains', 'name' => 'Custom Domains (Legacy)', 'description' => 'Number of custom domains allowed', 'category' => 'web', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 152, ], [ 'code' => 'bio.analytics_days', 'name' => 'Analytics Retention', 'description' => 'Days of analytics history retained', 'category' => 'web', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 5, ], [ 'code' => 'bio.tier.pro', 'name' => 'Pro Block Types', 'description' => 'Access to pro-tier block types', 'category' => 'web', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 6, ], [ 'code' => 'bio.tier.ultimate', 'name' => 'Ultimate Block Types', 'description' => 'Access to ultimate-tier block types', 'category' => 'web', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 7, ], [ 'code' => 'bio.tier.payment', 'name' => 'Payment Block Types', 'description' => 'Access to payment block types', 'category' => 'web', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 8, ], [ 'code' => 'web.themes.premium', 'name' => 'Premium Themes', 'description' => 'Access to premium page themes', 'category' => 'web', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 9, ], [ 'code' => 'bio.pwa', 'name' => 'Progressive Web App', 'description' => 'Turn pages into installable apps', 'category' => 'web', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 230, ], // Content features (native CMS) [ 'code' => 'content.mcp_access', 'name' => 'Content MCP Access', 'description' => 'Access to content management via MCP tools', 'category' => 'content', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 1, ], [ 'code' => 'content.items', 'name' => 'Content Items', 'description' => 'Number of content items (posts, pages)', 'category' => 'content', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 2, ], [ 'code' => 'content.ai_generation', 'name' => 'AI Content Generation', 'description' => 'Generate content using AI via MCP', 'category' => 'content', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 3, ], // Analytics features [ 'code' => 'analytics.sites', 'name' => 'Analytics Sites', 'description' => 'Number of sites to track', 'category' => 'analytics', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 1, ], [ 'code' => 'analytics.pageviews', 'name' => 'Monthly Pageviews', 'description' => 'Pageviews tracked per month', 'category' => 'analytics', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_MONTHLY, 'sort_order' => 2, ], // Support features [ 'code' => 'support.mailboxes', 'name' => 'Mailboxes', 'description' => 'Number of support mailboxes', 'category' => 'support', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 1, ], [ 'code' => 'support.agents', 'name' => 'Support Agents', 'description' => 'Number of support agents', 'category' => 'support', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 2, ], [ 'code' => 'support.conversations', 'name' => 'Conversations per Month', 'description' => 'Number of conversations per month', 'category' => 'support', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_MONTHLY, 'sort_order' => 3, ], [ 'code' => 'support.chat_widget', 'name' => 'Live Chat Widget', 'description' => 'Enable live chat widget', 'category' => 'support', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 4, ], [ 'code' => 'support.saved_replies', 'name' => 'Saved Replies', 'description' => 'Number of saved reply templates', 'category' => 'support', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 5, ], [ 'code' => 'support.custom_folders', 'name' => 'Custom Folders', 'description' => 'Enable custom folder organisation', 'category' => 'support', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 6, ], [ 'code' => 'support.api_access', 'name' => 'API Access', 'description' => 'Access to Support API endpoints', 'category' => 'support', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 7, ], [ 'code' => 'support.auto_reply', 'name' => 'Auto Reply', 'description' => 'Automatic reply to incoming messages', 'category' => 'support', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 8, ], [ 'code' => 'support.email_templates', 'name' => 'Email Templates', 'description' => 'Number of email templates', 'category' => 'support', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 9, ], [ 'code' => 'support.file_storage_mb', 'name' => 'File Storage (MB)', 'description' => 'File attachment storage in megabytes', 'category' => 'support', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 10, ], [ 'code' => 'support.retention_days', 'name' => 'Retention Days', 'description' => 'Number of days to retain conversation history', 'category' => 'support', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 11, ], // Tools features (utility tools access) [ 'code' => 'tool.mcp_access', 'name' => 'Tools MCP Access', 'description' => 'Access to utility tools via MCP API', 'category' => 'tools', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 1, ], [ 'code' => 'tool.url_shortener', 'name' => 'URL Shortener', 'description' => 'Create persistent short links with analytics', 'category' => 'tools', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 2, ], [ 'code' => 'tool.qr_generator', 'name' => 'QR Code Generator', 'description' => 'Create and save QR codes', 'category' => 'tools', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 3, ], [ 'code' => 'tool.dns_lookup', 'name' => 'DNS Lookup', 'description' => 'DNS record lookup tool', 'category' => 'tools', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 4, ], [ 'code' => 'tool.ssl_lookup', 'name' => 'SSL Lookup', 'description' => 'SSL certificate lookup tool', 'category' => 'tools', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 5, ], [ 'code' => 'tool.whois_lookup', 'name' => 'WHOIS Lookup', 'description' => 'Domain WHOIS lookup tool', 'category' => 'tools', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 6, ], [ 'code' => 'tool.ip_lookup', 'name' => 'IP Lookup', 'description' => 'IP address geolocation lookup', 'category' => 'tools', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 7, ], [ 'code' => 'tool.http_headers', 'name' => 'HTTP Headers', 'description' => 'HTTP header inspection tool', 'category' => 'tools', 'type' => Feature::TYPE_BOOLEAN, 'reset_type' => Feature::RESET_NONE, 'sort_order' => 8, ], ]; foreach ($features as $featureData) { Feature::updateOrCreate( ['code' => $featureData['code']], $featureData ); } // Create child features for storage pool $storageParent = Feature::where('code', 'core.res.storage.total')->first(); if ($storageParent) { $storageChildren = [ [ 'code' => 'core.res.cdn', 'name' => 'Main Site CDN', 'description' => 'CDN storage for main site (MB)', 'category' => 'storage', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'parent_feature_id' => $storageParent->id, 'sort_order' => 2, ], [ 'code' => 'bio.cdn', 'name' => 'Bio CDN', 'description' => 'CDN storage for bio pages (MB)', 'category' => 'storage', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'parent_feature_id' => $storageParent->id, 'sort_order' => 3, ], [ 'code' => 'social.cdn', 'name' => 'Social CDN', 'description' => 'CDN storage for social media (MB)', 'category' => 'storage', 'type' => Feature::TYPE_LIMIT, 'reset_type' => Feature::RESET_NONE, 'parent_feature_id' => $storageParent->id, 'sort_order' => 4, ], ]; foreach ($storageChildren as $childData) { Feature::updateOrCreate( ['code' => $childData['code']], $childData ); } } $this->command->info('Features seeded successfully.'); } }