HEX
Server: LiteSpeed
System: Linux s1049.use1.mysecurecloudhost.com 4.18.0-477.27.2.lve.el8.x86_64 #1 SMP Wed Oct 11 12:32:56 UTC 2023 x86_64
User: xedaptot (3356)
PHP: 8.3.31
Disabled: NONE
Upload Files
File: //home/xedaptot/ai.naniguide.com/database/seeders/Demo/DemoConfig.php
<?php

namespace Database\Seeders\Demo;

/**
 * DemoConfig — single source of truth for the demo seeder system.
 *
 * Anything that defines WHO the demo accounts are, HOW MUCH data they get,
 * and HOW the test bots / marketing video recorder log in lives in this file.
 *
 * Edit this file to tune the demo dataset; do not hardcode accounts elsewhere.
 *
 * Consumed by:
 *   - database/seeders/Demo/* (sub-seeders)
 *   - docs/DEMO_ACCOUNTS.json (regenerated by DemoSeeder on every run)
 *   - docs/e2e/_helpers.cjs (reads DEMO_ACCOUNTS.json)
 *   - docs/marketing/scripts/* (reads DEMO_ACCOUNTS.json)
 */
class DemoConfig
{
    /** Deterministic faker seed → reproducible dataset across runs. */
    public const FAKER_SEED = 20260408;

    /** Password for the two primary accounts (admin Michael + customer Emma). */
    public const PRIMARY_PASSWORD = '69dcf4f4c938d@';

    /** Cached customers array — ensures passwords are consistent across calls. */
    private static ?array $cachedCustomers = null;

    /** Generate a random password for non-primary demo users. */
    public static function randomPassword(): string
    {
        return bin2hex(random_bytes(8));
    }

    // ─── ADMINS ─────────────────────────────────────────────────────────────
    // Single admin account — no customer account attached.
    public static function admins(): array
    {
        return [
            [
                'key'        => 'super',
                'email'      => '[email protected]',
                'password'   => self::PRIMARY_PASSWORD,
                'first_name' => 'Michael',
                'last_name'  => 'Chen',
                'timezone'   => 'UTC',
                'group_id'   => 1, // Administrator
                'avatar'     => '[email protected]',
                'purpose'    => 'Admin only — no customer account',
            ],
        ];
    }

    // ─── CUSTOMERS ──────────────────────────────────────────────────────────
    // Primary customer (Emma) gets all sample data (lists, subscribers, campaigns).
    // Other customers are just accounts with avatars — no sample data.
    // `created_months_ago` spreads registrations across 10 months for the
    // Customer Growth chart (cumulative, last month = tallest bar).
    // Plan keys are distributed across all plans for the Plan Distribution pie.
    public static function customers(): array
    {
        if (self::$cachedCustomers !== null) {
            return self::$cachedCustomers;
        }

        return self::$cachedCustomers = [
            // ── Primary — all sample data goes here ──────────────────────────
            [
                'key'              => 'primary',
                'company'          => 'Awesome Solutions',
                'email'            => '[email protected]',
                'password'         => self::PRIMARY_PASSWORD,
                'first_name'       => 'Emma',
                'last_name'        => 'Tanaka',
                'plan_key'         => 'growth',
                'sub_status'       => 'active',
                'timezone'         => 'Asia/Tokyo',
                'avatar'           => '[email protected]',
                'created_months_ago' => 10,
                'lists'            => 8,
                'subscribers_total' => rand(70000, 72000),
                'campaigns'        => 10,
                'automations'      => 3,
                'forms'            => 3,
                'funnels'          => 2,
                'websites'         => 2,
                'purpose'          => 'Primary demo customer with all sample data.',
                // Additional team members on Awesome Solutions account.
                // Demonstrates multi-user / team-seat feature: same customer
                // workspace, separate User logins each with own avatar.
                'team_users'       => [
                    [
                        'email'      => '[email protected]',
                        'password'   => self::PRIMARY_PASSWORD,
                        'first_name' => 'Nina',
                        'last_name'  => 'Park',
                        'avatar'     => '[email protected]',
                    ],
                    [
                        'email'      => '[email protected]',
                        'password'   => self::PRIMARY_PASSWORD,
                        'first_name' => 'Jamal',
                        'last_name'  => 'Carter',
                        'avatar'     => '[email protected]',
                    ],
                    [
                        'email'      => '[email protected]',
                        'password'   => self::PRIMARY_PASSWORD,
                        'first_name' => 'Kenji',
                        'last_name'  => 'Nakamura',
                        'avatar'     => '[email protected]',
                    ],
                    [
                        'email'      => '[email protected]',
                        'password'   => self::PRIMARY_PASSWORD,
                        'first_name' => 'Alex',
                        'last_name'  => 'Romano',
                        'avatar'     => '[email protected]',
                    ],
                ],
            ],
            // ── Other customers — accounts only, no sample data ──────────────
            // Spread across last 10 months: 1,1,1,1,1,1,2,2,2,2 (increasing)
            [
                'key'        => 'sakura',
                'company'    => 'Synthetica AI',
                'email'      => '[email protected]',
                'password'   => self::randomPassword(),
                'first_name' => 'Sakura',
                'last_name'  => 'Hayashi',
                'plan_key'   => 'growth',
                'sub_status' => 'active',
                'timezone'   => 'Asia/Tokyo',
                'avatar'     => '[email protected]',
                'created_months_ago' => 9,
            ],
            [
                'key'        => 'mei',
                'company'    => 'DataPulse',
                'email'      => '[email protected]',
                'password'   => self::randomPassword(),
                'first_name' => 'Mei Lin',
                'last_name'  => 'Wang',
                'plan_key'   => 'pro',
                'sub_status' => 'active',
                'timezone'   => 'Asia/Shanghai',
                'avatar'     => '[email protected]',
                'created_months_ago' => 8,
            ],
            [
                'key'        => 'yuki',
                'company'    => 'ClearFlow Marketing',
                'email'      => '[email protected]',
                'password'   => self::randomPassword(),
                'first_name' => 'Yuki',
                'last_name'  => 'Sato',
                'plan_key'   => 'free',
                'sub_status' => 'active',
                'timezone'   => 'Asia/Tokyo',
                'avatar'     => '[email protected]',
                'created_months_ago' => 7,
            ],
            [
                'key'        => 'arjun',
                'company'    => 'NeuralStack',
                'email'      => '[email protected]',
                'password'   => self::randomPassword(),
                'first_name' => 'Arjun',
                'last_name'  => 'Patel',
                'plan_key'   => 'enterprise',
                'sub_status' => 'active',
                'timezone'   => 'Asia/Kolkata',
                'avatar'     => '[email protected]',
                'created_months_ago' => 7,
            ],
            [
                'key'        => 'daniel',
                'company'    => 'AdForge',
                'email'      => '[email protected]',
                'password'   => self::randomPassword(),
                'first_name' => 'Daniel',
                'last_name'  => 'Weber',
                'plan_key'   => 'growth',
                'sub_status' => 'active',
                'timezone'   => 'Europe/Berlin',
                'avatar'     => '[email protected]',
                'created_months_ago' => 6,
            ],
            [
                'key'        => 'ryan',
                'company'    => 'CloudReach AI',
                'email'      => '[email protected]',
                'password'   => self::randomPassword(),
                'first_name' => 'Ryan',
                'last_name'  => 'Mitchell',
                'plan_key'   => 'pro',
                'sub_status' => 'active',
                'timezone'   => 'America/New_York',
                'avatar'     => '[email protected]',
                'created_months_ago' => 5,
            ],
            [
                'key'        => 'sofia',
                'company'    => 'BrightSpark',
                'email'      => '[email protected]',
                'password'   => self::randomPassword(),
                'first_name' => 'Sofia',
                'last_name'  => 'Larsson',
                'plan_key'   => 'starter',
                'sub_status' => 'active',
                'timezone'   => 'Europe/Stockholm',
                'avatar'     => '[email protected]',
                'created_months_ago' => 4,
            ],
            [
                'key'        => 'hana',
                'company'    => 'PixelCraft AI',
                'email'      => '[email protected]',
                'password'   => self::randomPassword(),
                'first_name' => 'Hana',
                'last_name'  => 'Kim',
                'plan_key'   => 'enterprise',
                'sub_status' => 'active',
                'timezone'   => 'Asia/Seoul',
                'avatar'     => '[email protected]',
                'created_months_ago' => 4,
            ],
            [
                'key'        => 'marcus',
                'company'    => 'FlowStack',
                'email'      => '[email protected]',
                'password'   => self::randomPassword(),
                'first_name' => 'Marcus',
                'last_name'  => 'Johnson',
                'plan_key'   => 'free',
                'sub_status' => 'active',
                'timezone'   => 'America/Chicago',
                'avatar'     => '[email protected]',
                'created_months_ago' => 3,
            ],
            [
                'key'        => 'thomas',
                'company'    => 'InsightLoop AI',
                'email'      => '[email protected]',
                'password'   => self::randomPassword(),
                'first_name' => 'Thomas',
                'last_name'  => 'Berg',
                'plan_key'   => 'growth',
                'sub_status' => 'active',
                'timezone'   => 'Europe/Zurich',
                'avatar'     => '[email protected]',
                'created_months_ago' => 3,
            ],
            [
                'key'        => 'james',
                'company'    => 'StratosAI',
                'email'      => '[email protected]',
                'password'   => self::randomPassword(),
                'first_name' => 'James',
                'last_name'  => 'Crawford',
                'plan_key'   => 'pro',
                'sub_status' => 'active',
                'timezone'   => 'Europe/London',
                'avatar'     => '[email protected]',
                'created_months_ago' => 2,
            ],
            [
                'key'        => 'aiko',
                'company'    => 'Zenith Marketing',
                'email'      => '[email protected]',
                'password'   => self::randomPassword(),
                'first_name' => 'Aiko',
                'last_name'  => 'Nakamura',
                'plan_key'   => 'starter',
                'sub_status' => 'active',
                'timezone'   => 'Asia/Tokyo',
                'avatar'     => '[email protected]',
                'created_months_ago' => 2,
            ],
            [
                'key'        => 'mika',
                'company'    => 'Lumina Digital',
                'email'      => '[email protected]',
                'password'   => self::randomPassword(),
                'first_name' => 'Mika',
                'last_name'  => 'Fujimoto',
                'plan_key'   => 'starter',
                'sub_status' => 'active',
                'timezone'   => 'Asia/Tokyo',
                'avatar'     => '[email protected]',
                'created_months_ago' => 1,
            ],
            [
                'key'        => 'olivia',
                'company'    => 'Brooks Media',
                'email'      => '[email protected]',
                'password'   => self::randomPassword(),
                'first_name' => 'Olivia',
                'last_name'  => 'Brooks',
                'plan_key'   => 'free',
                'sub_status' => 'active',
                'timezone'   => 'Europe/London',
                'avatar'     => '[email protected]',
                'created_months_ago' => 8,
            ],
            [
                'key'        => 'ava',
                'company'    => 'Whitman & Co',
                'email'      => '[email protected]',
                'password'   => self::randomPassword(),
                'first_name' => 'Ava',
                'last_name'  => 'Whitman',
                'plan_key'   => 'starter',
                'sub_status' => 'active',
                'timezone'   => 'America/Los_Angeles',
                'avatar'     => '[email protected]',
                'created_months_ago' => 6,
            ],
            [
                'key'        => 'hiroshi',
                'company'    => 'Sato Strategies',
                'email'      => '[email protected]',
                'password'   => self::randomPassword(),
                'first_name' => 'Hiroshi',
                'last_name'  => 'Sato',
                'plan_key'   => 'enterprise',
                'sub_status' => 'active',
                'timezone'   => 'Asia/Tokyo',
                'avatar'     => '[email protected]',
                'created_months_ago' => 5,
            ],
            [
                'key'        => 'lila',
                'company'    => 'NorthBeam Labs',
                'email'      => '[email protected]',
                'password'   => self::randomPassword(),
                'first_name' => 'Lila',
                'last_name'  => 'Chen',
                'plan_key'   => 'pro',
                'sub_status' => 'active',
                'timezone'   => 'Asia/Singapore',
                'avatar'     => '[email protected]',
                'created_months_ago' => 1,
            ],
            [
                'key'        => 'riko',
                'company'    => 'NightOwl Mail',
                'email'      => '[email protected]',
                'password'   => self::randomPassword(),
                'first_name' => 'Riko',
                'last_name'  => 'Watanabe',
                'plan_key'   => 'growth',
                'sub_status' => 'active',
                'timezone'   => 'Asia/Tokyo',
                'avatar'     => '[email protected]',
                'created_months_ago' => 1,
            ],
        ];
    }

    // ─── PLANS ──────────────────────────────────────────────────────────────
    // 4-concept canonical structure: each plan returns base attrs (name/price/...)
    // plus 4 typed maps (credits/quotas/entitlements/rate_limit) consumed by
    // DatabaseInit::insertPlans which calls PlansService::setCredits/setQuotas/
    // setEntitlements/setRateLimit directly. Null values = unlimited; missing
    // entitlement keys default to false (not granted). Source of truth = enum
    // cases in app/Services/Plans/{Credits,Quotas,Entitlements,RateLimits}/.
    public static function plans(): array
    {
        // All 5 demo plans grant the full sending-server suite + SMTP. Factor
        // out the repeated map.
        $allSendingProviders = [
            \App\Services\Plans\Entitlements\EntitlementKey::ALLOW_SENDING_AMAZON->value       => true,
            \App\Services\Plans\Entitlements\EntitlementKey::ALLOW_SENDING_SENDGRID->value     => true,
            \App\Services\Plans\Entitlements\EntitlementKey::ALLOW_SENDING_MAILGUN->value      => true,
            \App\Services\Plans\Entitlements\EntitlementKey::ALLOW_SENDING_ELASTICEMAIL->value => true,
            \App\Services\Plans\Entitlements\EntitlementKey::ALLOW_SENDING_SPARKPOST->value    => true,
            \App\Services\Plans\Entitlements\EntitlementKey::ALLOW_SENDING_BLASTENGINE->value  => true,
            \App\Services\Plans\Entitlements\EntitlementKey::ALLOW_SENDING_SMTP->value         => true,
            \App\Services\Plans\Entitlements\EntitlementKey::ALLOW_SENDING_SENDMAIL->value     => true,
            \App\Services\Plans\Entitlements\EntitlementKey::ALLOW_SENDING_GMAIL_OAUTH->value  => true,
        ];

        return [
            'free' => [
                'name'        => 'Free Forever',
                'price'       => 0.00,
                'description' => 'Get started with email marketing — perfect for personal projects.',
                'trial_amount' => 0,
                'no_payment_required_when_free' => 0,
                'credits' => [
                    \App\Services\Plans\Credits\CreditKey::SEND_EMAIL->value => 2000,
                ],
                'quotas' => [
                    \App\Services\Plans\Quotas\QuotaKey::MAX_LISTS->value              => 3,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_SUBSCRIBERS->value        => 500,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_CONTACTS->value           => 500,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_SUBSCRIBERS_PER_LIST->value => 500,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_SEGMENTS_PER_LIST->value  => 3,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_CAMPAIGNS->value          => 10,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_AUTOMATIONS->value        => 2,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_SENDING_SERVERS->value    => 0,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_USERS->value              => 1,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_UPLOAD_SIZE_TOTAL->value  => 100 * 1024 * 1024, // 100 MB
                ],
                'entitlements' => $allSendingProviders + [
                    \App\Services\Plans\Entitlements\EntitlementKey::HAS_API_ACCESS->value  => true,
                    \App\Services\Plans\Entitlements\EntitlementKey::HAS_LIST_IMPORT->value => true,
                    \App\Services\Plans\Entitlements\EntitlementKey::HAS_LIST_EXPORT->value => true,
                ],
                'rate_limit' => ['amount' => 100, 'time_amount' => 1, 'time_unit' => 'hour'],
            ],
            'starter' => [
                'name'        => 'Starter',
                'price'       => 19.00,
                'description' => 'For small businesses sending occasional newsletters.',
                'credits' => [
                    \App\Services\Plans\Credits\CreditKey::SEND_EMAIL->value => 20000,
                ],
                'quotas' => [
                    \App\Services\Plans\Quotas\QuotaKey::MAX_LISTS->value              => 10,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_SUBSCRIBERS->value        => 5000,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_CONTACTS->value           => 5000,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_SUBSCRIBERS_PER_LIST->value => null, // unlimited
                    \App\Services\Plans\Quotas\QuotaKey::MAX_SEGMENTS_PER_LIST->value  => 10,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_CAMPAIGNS->value          => 50,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_AUTOMATIONS->value        => 5,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_SENDING_SERVERS->value    => 2,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_USERS->value              => 2,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_UPLOAD_SIZE_TOTAL->value  => 1024 * 1024 * 1024, // 1 GB
                ],
                'entitlements' => $allSendingProviders + [
                    \App\Services\Plans\Entitlements\EntitlementKey::HAS_API_ACCESS->value => true,
                ],
                'rate_limit' => ['amount' => 1000, 'time_amount' => 1, 'time_unit' => 'hour'],
            ],
            'growth' => [
                'name'        => 'Growth',
                'price'       => 49.00,
                'description' => 'For growing teams running regular campaigns and automations.',
                'trial_amount' => 0, // No trial — paid immediately. Used by Video #9 to record the Stripe checkout flow.
                'credits' => [
                    \App\Services\Plans\Credits\CreditKey::SEND_EMAIL->value => 100000,
                ],
                'quotas' => [
                    \App\Services\Plans\Quotas\QuotaKey::MAX_LISTS->value              => 50,
                    // Subscriber quota set above DemoSeeder's primary-customer
                    // seed size (70k under Emma) so opt-in / API / import
                    // scenarios in e2e-subscribers-opt-in-essentials.cjs don't
                    // hit a real-but-irrelevant quota gate.
                    \App\Services\Plans\Quotas\QuotaKey::MAX_SUBSCRIBERS->value        => 100000,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_CONTACTS->value           => 100000,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_SUBSCRIBERS_PER_LIST->value => null,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_SEGMENTS_PER_LIST->value  => 20,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_CAMPAIGNS->value          => 200,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_AUTOMATIONS->value        => 20,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_SENDING_SERVERS->value    => 5,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_USERS->value              => 5,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_UPLOAD_SIZE_TOTAL->value  => 10 * 1024 * 1024 * 1024, // 10 GB
                ],
                'entitlements' => $allSendingProviders + [
                    \App\Services\Plans\Entitlements\EntitlementKey::HAS_API_ACCESS->value                    => true,
                    \App\Services\Plans\Entitlements\EntitlementKey::HAS_OWN_SENDING_SERVER->value            => true,
                    \App\Services\Plans\Entitlements\EntitlementKey::HAS_OWN_EMAIL_VERIFICATION_SERVER->value => true,
                ],
                'rate_limit' => ['amount' => 5000, 'time_amount' => 1, 'time_unit' => 'hour'],
            ],
            'pro' => [
                'name'        => 'Pro',
                'price'       => 99.00,
                'description' => 'Advanced features for high-volume senders and agencies.',
                'trial_amount' => 0, // No trial — committed tier, requires payment method on signup.
                'credits' => [
                    \App\Services\Plans\Credits\CreditKey::SEND_EMAIL->value => 500000,
                ],
                'quotas' => [
                    \App\Services\Plans\Quotas\QuotaKey::MAX_LISTS->value              => 200,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_SUBSCRIBERS->value        => 100000,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_CONTACTS->value           => 100000,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_SUBSCRIBERS_PER_LIST->value => null,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_SEGMENTS_PER_LIST->value  => 50,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_CAMPAIGNS->value          => 1000,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_AUTOMATIONS->value        => 100,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_SENDING_SERVERS->value    => null,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_USERS->value              => 20,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_UPLOAD_SIZE_TOTAL->value  => 100 * 1024 * 1024 * 1024, // 100 GB
                ],
                'entitlements' => $allSendingProviders + [
                    \App\Services\Plans\Entitlements\EntitlementKey::HAS_API_ACCESS->value                    => true,
                    \App\Services\Plans\Entitlements\EntitlementKey::HAS_OWN_SENDING_SERVER->value            => true,
                    \App\Services\Plans\Entitlements\EntitlementKey::HAS_OWN_EMAIL_VERIFICATION_SERVER->value => true,
                ],
                'rate_limit' => ['amount' => 20000, 'time_amount' => 1, 'time_unit' => 'hour'],
            ],
            'enterprise' => [
                'name'        => 'Enterprise',
                'price'       => 299.00,
                'description' => 'Unlimited everything for large organizations and resellers.',
                'trial_amount' => 0, // No trial — enterprise tier, payment method required.
                'credits' => [
                    \App\Services\Plans\Credits\CreditKey::SEND_EMAIL->value => null, // unlimited
                ],
                'quotas' => [
                    \App\Services\Plans\Quotas\QuotaKey::MAX_LISTS->value              => null,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_SUBSCRIBERS->value        => null,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_CONTACTS->value           => null,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_SUBSCRIBERS_PER_LIST->value => null,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_SEGMENTS_PER_LIST->value  => 100,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_CAMPAIGNS->value          => null,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_AUTOMATIONS->value        => null,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_SENDING_SERVERS->value    => null,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_SENDING_DOMAINS->value    => null,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_EMAIL_VERIFICATION_SERVERS->value => null,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_USERS->value              => null,
                    \App\Services\Plans\Quotas\QuotaKey::MAX_UPLOAD_SIZE_TOTAL->value  => null,
                ],
                'entitlements' => $allSendingProviders + [
                    \App\Services\Plans\Entitlements\EntitlementKey::HAS_API_ACCESS->value                    => true,
                    \App\Services\Plans\Entitlements\EntitlementKey::HAS_LIST_IMPORT->value                   => true,
                    \App\Services\Plans\Entitlements\EntitlementKey::HAS_LIST_EXPORT->value                   => true,
                    \App\Services\Plans\Entitlements\EntitlementKey::HAS_OWN_SENDING_SERVER->value            => true,
                    \App\Services\Plans\Entitlements\EntitlementKey::HAS_OWN_EMAIL_VERIFICATION_SERVER->value => true,
                ],
                'rate_limit' => null, // null = no throttle (unlimited send rate)
            ],
        ];
    }

    // ─── DATA VOLUME (subscribers + tracking logs) ──────────────────────────

    /** Tracking logs per "sent" campaign — sampled fraction of recipients. */
    public const TRACKING_OPEN_RATE_MIN = 0.18;
    public const TRACKING_OPEN_RATE_MAX = 0.55;
    public const TRACKING_CLICK_RATE_MIN = 0.04;
    public const TRACKING_CLICK_RATE_MAX = 0.18;
    public const TRACKING_BOUNCE_RATE_MIN = 0.01;
    public const TRACKING_BOUNCE_RATE_MAX = 0.05;
    /** Cap how many tracking_logs rows we generate per campaign (perf). */
    public const TRACKING_LOG_HARD_CAP = 4000;

    // ─── OUTPUT MANIFEST ────────────────────────────────────────────────────
    /** Where DemoSeeder writes the consumable account manifest. */
    public static function manifestPath(): string
    {
        return base_path('docs/demo/DEMO_ACCOUNTS.json');
    }

    /**
     * Find an admin entry by key.
     */
    public static function findAdmin(string $key): ?array
    {
        foreach (self::admins() as $a) {
            if ($a['key'] === $key) return $a;
        }
        return null;
    }

    /**
     * Absolute path to an avatar file in the seeders/Demo/avatars/ directory.
     */
    public static function avatarPath(string $filename): string
    {
        return __DIR__ . '/avatars/' . $filename;
    }
}