sed -n '1,220p' app/Http/Middleware/AuthenticatePlatformApi.php

<?php

namespace App\Http\Middleware;

use App\Enums\StoreUserRole;
use App\Models\PersonalAccessToken;
use App\Models\User;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class AuthenticatePlatformApi
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        $token = $this->tokenFromRequest($request);
        $user = $token?->tokenable;

        if (! $user instanceof User || ! $token instanceof PersonalAccessToken) {
            return response()->json(['message' => 'Unauthenticated.'], 401);
        }

        if (! $this->userCanManagePlatform($user) || ! $token->can('manage-platform')) {
            return response()->json(['message' => 'Forbidden.'], 403);
        }

        $token->forceFill(['last_used_at' => now()])->save();

        return $next($request);
    }

    private function userCanManagePlatform(User $user): bool
    {
        return $user->is_platform_admin === true;
    }

    private function tokenFromRequest(Request $request): ?PersonalAccessToken
    {
        $token = $request->attributes->get('sanctum_personal_access_token');

        if ($token instanceof PersonalAccessToken) {
            return $token;
        }

        $plainTextToken = $request->bearerToken();

        if (! is_string($plainTextToken) || $plainTextToken === '') {
            return null;
        }

        $token = PersonalAccessToken::query()
            ->with('tokenable')
            ->where('token', hash('sha256', $this->plainTokenForHashing($plainTextToken)))
            ->first();

        if (! $token instanceof PersonalAccessToken || $token->isExpired()) {
            return null;
        }

        $request->attributes->set('sanctum_personal_access_token', $token);
        app()->instance('sanctum_personal_access_token', $token);

        return $token;
    }

    private function plainTokenForHashing(string $plainTextToken): string
    {
        if (str_contains($plainTextToken, '|')) {
            return (string) str($plainTextToken)->after('|');
        }

        return $plainTextToken;
    }
}


/bin/zsh
-lc
sed -n '1,260p' routes/api.php

<?php

use App\Http\Controllers\Api\Admin\V1\AnalyticsSummaryController as AdminAnalyticsSummaryController;
use App\Http\Controllers\Api\Admin\V1\CollectionController as AdminCollectionController;
use App\Http\Controllers\Api\Admin\V1\CustomerController as AdminCustomerController;
use App\Http\Controllers\Api\Admin\V1\DiscountController as AdminDiscountController;
use App\Http\Controllers\Api\Admin\V1\OrderController as AdminOrderController;
use App\Http\Controllers\Api\Admin\V1\OrderExportController as AdminOrderExportController;
use App\Http\Controllers\Api\Admin\V1\OrderFulfillmentController as AdminOrderFulfillmentController;
use App\Http\Controllers\Api\Admin\V1\OrderRefundController as AdminOrderRefundController;
use App\Http\Controllers\Api\Admin\V1\PageController as AdminPageController;
use App\Http\Controllers\Api\Admin\V1\PlatformOrganizationController as AdminPlatformOrganizationController;
use App\Http\Controllers\Api\Admin\V1\PlatformStoreController as AdminPlatformStoreController;
use App\Http\Controllers\Api\Admin\V1\ProductController as AdminProductController;
use App\Http\Controllers\Api\Admin\V1\SearchIndexController as AdminSearchIndexController;
use App\Http\Controllers\Api\Admin\V1\ShippingRateController as AdminShippingRateController;
use App\Http\Controllers\Api\Admin\V1\ShippingZoneController as AdminShippingZoneController;
use App\Http\Controllers\Api\Admin\V1\StoreInviteController as AdminStoreInviteController;
use App\Http\Controllers\Api\Admin\V1\StoreMembershipController as AdminStoreMembershipController;
use App\Http\Controllers\Api\Admin\V1\StoreSettingsController as AdminStoreSettingsController;
use App\Http\Controllers\Api\Admin\V1\TaxSettingsController as AdminTaxSettingsController;
use App\Http\Controllers\Api\Admin\V1\ThemeController as AdminThemeController;
use App\Http\Controllers\Api\Admin\V1\ThemeSettingsController as AdminThemeSettingsController;
use App\Http\Controllers\Api\Apps\V1\DeferredEndpointController as DeferredAppEndpointController;
use App\Http\Controllers\Api\Storefront\V1\AnalyticsEventController as StorefrontAnalyticsEventController;
use App\Http\Controllers\Api\Storefront\V1\CartController;
use App\Http\Controllers\Api\Storefront\V1\CartLineController;
use App\Http\Controllers\Api\Storefront\V1\CheckoutController;
use App\Http\Controllers\Api\Storefront\V1\OrderController as StorefrontOrderController;
use App\Http\Controllers\Api\Storefront\V1\SearchController as StorefrontSearchController;
use Illuminate\Support\Facades\Route;

Route::middleware('store.resolve')
    ->prefix('storefront/v1')
    ->name('api.storefront.v1.')
    ->group(function (): void {
        Route::middleware('throttle:api.storefront')->group(function (): void {
            Route::post('carts', [CartController::class, 'store'])->name('carts.store');
            Route::get('carts/{cart}', [CartController::class, 'show'])->name('carts.show');
            Route::post('carts/{cart}/lines', [CartLineController::class, 'store'])->name('carts.lines.store');
            Route::put('carts/{cart}/lines/{cartLine}', [CartLineController::class, 'update'])->name('carts.lines.update');
            Route::delete('carts/{cart}/lines/{cartLine}', [CartLineController::class, 'destroy'])->name('carts.lines.destroy');
        });

        Route::middleware('throttle:search')->group(function (): void {
            Route::get('search', [StorefrontSearchController::class, 'index'])->name('search.index');
            Route::get('search/suggest', [StorefrontSearchController::class, 'suggest'])->name('search.suggest');
        });

        Route::middleware('throttle:analytics')->group(function (): void {
            Route::post('analytics/events', [StorefrontAnalyticsEventController::class, 'store'])->name('analytics.events.store');
        });

        Route::middleware('throttle:checkout')->group(function (): void {
            Route::post('checkouts', [CheckoutController::class, 'store'])->name('checkouts.store');
            Route::get('checkouts/{checkout}', [CheckoutController::class, 'show'])->name('checkouts.show');
            Route::put('checkouts/{checkout}/address', [CheckoutController::class, 'address'])->name('checkouts.address');
            Route::put('checkouts/{checkout}/shipping-method', [CheckoutController::class, 'shippingMethod'])->name('checkouts.shipping-method');
            Route::post('checkouts/{checkout}/apply-discount', [CheckoutController::class, 'applyDiscount'])->name('checkouts.apply-discount');
            Route::delete('checkouts/{checkout}/discount', [CheckoutController::class, 'destroyDiscount'])->name('checkouts.discount.destroy');
            Route::put('checkouts/{checkout}/payment-method', [CheckoutController::class, 'paymentMethod'])->name('checkouts.payment-method');
            Route::post('checkouts/{checkout}/pay', [CheckoutController::class, 'pay'])->name('checkouts.pay');
            Route::get('orders/{orderNumber}', [StorefrontOrderController::class, 'sh…2446 chars truncated…pi:write-collections')->group(function (): void {
            Route::post('collections', [AdminCollectionController::class, 'store'])->name('collections.store');
            Route::put('collections/{collection}', [AdminCollectionController::class, 'update'])->name('collections.update');
            Route::delete('collections/{collection}', [AdminCollectionController::class, 'destroy'])->name('collections.destroy');
        });

        Route::middleware('admin.api:read-discounts')->group(function (): void {
            Route::get('discounts', [AdminDiscountController::class, 'index'])->name('discounts.index');
        });

        Route::middleware('admin.api:write-discounts')->group(function (): void {
            Route::post('discounts', [AdminDiscountController::class, 'store'])->name('discounts.store');
            Route::put('discounts/{discount}', [AdminDiscountController::class, 'update'])->name('discounts.update');
            Route::delete('discounts/{discount}', [AdminDiscountController::class, 'destroy'])->name('discounts.destroy');
        });

        Route::middleware('admin.api:read-content')->group(function (): void {
            Route::get('pages', [AdminPageController::class, 'index'])->name('pages.index');
        });

        Route::middleware('admin.api:write-content')->group(function (): void {
            Route::post('pages', [AdminPageController::class, 'store'])->name('pages.store');
            Route::put('pages/{page}', [AdminPageController::class, 'update'])->name('pages.update');
            Route::delete('pages/{page}', [AdminPageController::class, 'destroy'])->name('pages.destroy');
        });

        Route::middleware('admin.api:read-settings')->group(function (): void {
            Route::get('search/status', [AdminSearchIndexController::class, 'status'])->name('search.status');
            Route::get('settings', [AdminStoreSettingsController::class, 'show'])->name('settings.show');
            Route::get('shipping/zones', [AdminShippingZoneController::class, 'index'])->name('shipping.zones.index');
            Route::get('tax/settings', [AdminTaxSettingsController::class, 'show'])->name('tax.settings.show');
        });

        Route::middleware('admin.api:write-settings')->group(function (): void {
            Route::post('search/reindex', [AdminSearchIndexController::class, 'reindex'])->name('search.reindex');
            Route::put('settings', [AdminStoreSettingsController::class, 'update'])->name('settings.update');
            Route::post('shipping/zones', [AdminShippingZoneController::class, 'store'])->name('shipping.zones.store');
            Route::put('shipping/zones/{shippingZone}', [AdminShippingZoneController::class, 'update'])->name('shipping.zones.update');
            Route::post('shipping/zones/{shippingZone}/rates', [AdminShippingRateController::class, 'store'])->name('shipping.zones.rates.store');
            Route::put('tax/settings', [AdminTaxSettingsController::class, 'update'])->name('tax.settings.update');
        });

        Route::middleware('admin.api:write-themes')->group(function (): void {
            Route::post('themes', [AdminThemeController::class, 'store'])->name('themes.store');
            Route::post('themes/{theme}/publish', [AdminThemeController::class, 'publish'])->name('themes.publish');
            Route::put('themes/{theme}/settings', [AdminThemeSettingsController::class, 'update'])->name('themes.settings.update');
        });

        Route::middleware('admin.api:read-analytics')->group(function (): void {
            Route::get('analytics/summary', [AdminAnalyticsSummaryController::class, 'show'])->name('analytics.summary');
        });

        Route::middleware('admin.api:read-orders')->group(function (): void {
            Route::post('exports/orders', [AdminOrderExportController::class, 'store'])->name('exports.orders.store');
            Route::get('exports/{dataExport}', [AdminOrderExportController::class, 'show'])->name('exports.show');
            Route::get('orders', [AdminOrderController::class, 'index'])->name('orders.index');
            Route::get('orders/{order}', [AdminOrderController::class, 'show'])->name('orders.show');
        });

        Route::middleware('admin.api:write-orders')->group(function (): void {
            Route::post('orders/{order}/fulfillments', [AdminOrderFulfillmentController::class, 'store'])->name('orders.fulfillments.store');
            Route::post('orders/{order}/refunds', [AdminOrderRefundController::class, 'store'])->name('orders.refunds.store');
        });
    });

Route::middleware('throttle:60,1')
    ->prefix('apps/v1/stores/{store}')
    ->name('api.apps.v1.')
    ->group(function (): void {
        Route::get('products', DeferredAppEndpointController::class)->name('products.index');
        Route::get('orders', DeferredAppEndpointController::class)->name('orders.index');
        Route::get('customers', DeferredAppEndpointController::class)->name('customers.index');
    });


/bin/zsh
-lc
sed -n '1,240p' tests/Pest.php

<?php

/*
|--------------------------------------------------------------------------
| Test Case
|--------------------------------------------------------------------------
|
| The closure you provide to your test functions is always bound to a specific PHPUnit test
| case class. By default, that class is "PHPUnit\Framework\TestCase". Of course, you may
| need to change it using the "pest()" function to bind a different classes or traits.
|
*/

pest()->extend(Tests\TestCase::class)
    ->in('Feature', 'Browser');

/*
|--------------------------------------------------------------------------
| Expectations
|--------------------------------------------------------------------------
|
| When you're writing tests, you often need to check that values meet certain conditions. The
| "expect()" function gives you access to a set of "expectations" methods that you can use
| to assert different things. Of course, you may extend the Expectation API at any time.
|
*/

expect()->extend('toBeOne', function () {
    return $this->toBe(1);
});

/*
|--------------------------------------------------------------------------
| Functions
|--------------------------------------------------------------------------
|
| While Pest is very powerful out-of-the-box, you may have some testing code specific to your
| project that you don't want to repeat in every file. Here you can also expose helpers as
| global functions to help you to reduce the number of lines of code in your test files.
|
*/

/**
 * @param  list<string>  $abilities
 */
function adminApiBearerToken(\App\Models\Store $store, array $abilities, ?\App\Models\User $user = null): string
{
    return adminApiToken($store, $abilities, $user)['plain_text'];
}

/**
 * @param  list<string>  $abilities
 * @return array{token: \App\Models\PersonalAccessToken, plain_text: string}
 */
function adminApiToken(\App\Models\Store $store, array $abilities, ?\App\Models\User $user = null): array
{
    $user ??= $store->users()->wherePivot('role', 'owner')->first()
        ?? $store->users()->first();

    if (! $user instanceof \App\Models\User) {
        $user = \App\Models\User::factory()->create(['email_verified_at' => now()]);
        $store->users()->attach($user->getKey(), [
            'role' => \App\Enums\StoreUserRole::Owner->value,
            'created_at' => now(),
        ]);
    }

    return app(\App\Services\WebhookService::class)
        ->createApiToken($store, 'Test API token', $abilities, $user);
}


Output:
Chunk ID: 8406f3
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 253
Output:
        });

        foreach ([
            OrderCreated::class,
            OrderPaid::class,
            OrderCancelled::class,
            OrderRefunded::class,
            CheckoutCompleted::class,
            FulfillmentCreated::class,
            FulfillmentShipped::class,
            FulfillmentDelivered::class,
            ProductCreated::class,
            ProductUpdated::class,
            ProductDeleted::class,
        ] as $event) {
            Event::listen($event, DispatchWebhooks::class);
        }
    }

    protected function configureLivewireMiddleware(): void
    {
        Livewire::addPersistentMiddleware([
            EnsureUserEmailIsVerified::class,
            ResolveStore::class,
            CheckStoreRole::class,
        ]);
    }

    private function plainTokenForHashing(string $plainTextToken): string
    {
        if (str_contains($plainTextToken, '|')) {
            return (string) str($plainTextToken)->after('|');
        }

        return $plainTextToken;
    }
}


Output:
Chunk ID: 3a4a37
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 756
Output:
<?php

namespace App\Observers;

use App\Models\Collection;
use App\Models\Discount;
use App\Models\Fulfillment;
use App\Models\NavigationMenu;
use App\Models\Order;
use App\Models\Page;
use App\Models\Product;
use App\Models\Refund;
use App\Models\ShippingZone;
use App\Models\StoreSettings;
use App\Models\TaxSettings;
use App\Models\Theme;
use App\Services\AuditLogger;
use Illuminate\Database\Eloquent\Model;

class AuditModelObserver
{
    /**
     * @var array<class-string<Model>, string>
     */
    private array $resourceTypes = [
        Product::class => 'product',
        Collection::class => 'collection',
        Discount::class => 'discount',
        Page::class => 'page',
        Theme::class => 'theme',
        Order::class => 'order',
        Fulfillment::class => 'fulfillment',
        Refund::class => 'refund',
        NavigationMenu::class => 'navigation_menu',
        ShippingZone::class => 'shipping_zone',
        StoreSettings::class => 'store_settings',
        TaxSettings::class => 'tax_setting',
    ];

    public function created(Model $model): void
    {
        $this->write($model, 'created');
    }

    public function updated(Model $model): void
    {
        $this->write($model, 'updated', $this->changes($model));
    }

    public function deleted(Model $model): void
    {
        $this->write($model, 'deleted');
    }

    public function restored(Model $model): void
    {
        $this->write($model, 'restored');
    }

    /**
     * @param  array<string, mixed>|null  $changes
     */
    private function write(Model $model, string $action, ?array $changes = null): void
    {
        $resourceType = $this->resourceTypes[$model::class] ?? null;

        if ($resourceType === null) {
            return;
        }

        app(AuditLogger::class)->log(
            event: $model instanceof StoreSettings && $action === 'updated'
                ? 'store.settings_changed'
                : "{$resourceType}.{$action}",
            userId: auth()->id(),
            storeId: $this->storeId($model),
            resourceType: $resourceType,
            resourceId: is_numeric($model->getKey()) ? (int) $model->getKey() : null,
            changes: $changes,
        );
    }

    /**
     * @return array<string, array{0: mixed, 1: mixed}>
     */
    private function changes(Model $model): array
    {
        return collect($model->getChanges())
            ->except(['updated_at'])
            ->mapWithKeys(fn (mixed $newValue, string $key): array => [
                $key => [$model->getOriginal($key), $newValue],
            ])
            ->all();
    }

    private function storeId(Model $model): ?int
    {
        $storeId = $model->getAttribute('store_id');

        if (is_numeric($storeId)) {
            return (int) $storeId;
        }

        if (app()->bound('current_store')) {
            $store = app('current_store');

            return $store instanceof \App\Models\Store ? $store->getKey() : null;
        }

        return null;
    }
}


Output:
Chunk ID: d619f0
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 569
Output:
<?php

namespace App\Http\Middleware;

use App\Enums\StoreUserRole;
use App\Models\PersonalAccessToken;
use App\Models\User;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class AuthenticatePlatformApi
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        $token = $this->tokenFromRequest($request);
        $user = $token?->tokenable;

        if (! $user instanceof User || ! $token instanceof PersonalAccessToken) {
            return response()->json(['message' => 'Unauthenticated.'], 401);
        }

        if (! $this->userCanManagePlatform($user) || ! $token->can('manage-platform')) {
            return response()->json(['message' => 'Forbidden.'], 403);
        }

        $token->forceFill(['last_used_at' => now()])->save();

        return $next($request);
    }

    private function userCanManagePlatform(User $user): bool
    {
        return $user->is_platform_admin === true;
    }

    private function tokenFromRequest(Request $request): ?PersonalAccessToken
    {
        $token = $request->attributes->get('sanctum_personal_access_token');

        if ($token instanceof PersonalAccessToken) {
            return $token;
        }

        $plainTextToken = $request->bearerToken();

        if (! is_string($plainTextToken) || $plainTextToken === '') {
            return null;
        }

        $token = PersonalAccessToken::query()
            ->with('tokenable')
            ->where('token', hash('sha256', $this->plainTokenForHashing($plainTextToken)))
            ->first();

        if (! $token instanceof PersonalAccessToken || $token->isExpired()) {
            return null;
        }

        $request->attributes->set('sanctum_personal_access_token', $token);
        app()->instance('sanctum_personal_access_token', $token);

        return $token;
    }

    private function plainTokenForHashing(string $plainTextToken): string
    {
        if (str_contains($plainTextToken, '|')) {
            return (string) str($plainTextToken)->after('|');
        }

        return $plainTextToken;
    }
}


Output:
Chunk ID: a2aa52
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 3112
Output:
<?php

use App\Http\Controllers\Api\Admin\V1\AnalyticsSummaryController as AdminAnalyticsSummaryController;
use App\Http\Controllers\Api\Admin\V1\CollectionController as AdminCollectionController;
use App\Http\Controllers\Api\Admin\V1\CustomerController as AdminCustomerController;
use App\Http\Controllers\Api\Admin\V1\DiscountController as AdminDiscountController;
use App\Http\Controllers\Api\Admin\V1\OrderController as AdminOrderController;
use App\Http\Controllers\Api\Admin\V1\OrderExportController as AdminOrderExportController;
use App\Http\Controllers\Api\Admin\V1\OrderFulfillmentController as AdminOrderFulfillmentController;
use App\Http\Controllers\Api\Admin\V1\OrderRefundController as AdminOrderRefundController;
use App\Http\Controllers\Api\Admin\V1\PageController as AdminPageController;
use App\Http\Controllers\Api\Admin\V1\PlatformOrganizationController as AdminPlatformOrganizationController;
use App\Http\Controllers\Api\Admin\V1\PlatformStoreController as AdminPlatformStoreController;
use App\Http\Controllers\Api\Admin\V1\ProductController as AdminProductController;
use App\Http\Controllers\Api\Admin\V1\SearchIndexController as AdminSearchIndexController;
use App\Http\Controllers\Api\Admin\V1\ShippingRateController as AdminShippingRateController;
use App\Http\Controllers\Api\Admin\V1\ShippingZoneController as AdminShippingZoneController;
use App\Http\Controllers\Api\Admin\V1\StoreInviteController as AdminStoreInviteController;
use App\Http\Controllers\Api\Admin\V1\StoreMembershipController as AdminStoreMembershipController;
use App\Http\Controllers\Api\Admin\V1\StoreSettingsController as AdminStoreSettingsController;
use App\Http\Controllers\Api\Admin\V1\TaxSettingsController as AdminTaxSettingsController;
use App\Http\Controllers\Api\Admin\V1\ThemeController as AdminThemeController;
use App\Http\Controllers\Api\Admin\V1\ThemeSettingsController as AdminThemeSettingsController;
use App\Http\Controllers\Api\Apps\V1\DeferredEndpointController as DeferredAppEndpointController;
use App\Http\Controllers\Api\Storefront\V1\AnalyticsEventController as StorefrontAnalyticsEventController;
use App\Http\Controllers\Api\Storefront\V1\CartController;
use App\Http\Controllers\Api\Storefront\V1\CartLineController;
use App\Http\Controllers\Api\Storefront\V1\CheckoutController;
use App\Http\Controllers\Api\Storefront\V1\OrderController as StorefrontOrderController;
use App\Http\Controllers\Api\Storefront\V1\SearchController as StorefrontSearchController;
use Illuminate\Support\Facades\Route;

Route::middleware('store.resolve')
    ->prefix('storefront/v1')
    ->name('api.storefront.v1.')
    ->group(function (): void {
        Route::middleware('throttle:api.storefront')->group(function (): void {
            Route::post('carts', [CartController::class, 'store'])->name('carts.store');
            Route::get('carts/{cart}', [CartController::class, 'show'])->name('carts.show');
            Route::post('carts/{cart}/lines', [CartLineController::class, 'store'])->name('carts.lines.store');
            Route::put('carts/{cart}/lines/{cartLine}', [CartLineController::class, 'update'])->name('carts.lines.update');
            Route::delete('carts/{cart}/lines/{cartLine}', [CartLineController::class, 'destroy'])->name('carts.lines.destroy');
        });

        Route::middleware('throttle:search')->group(function (): void {
            Route::get('search', [StorefrontSearchController::class, 'index'])->name('search.index');
            Route::get('search/suggest', [StorefrontSearchController::class, 'suggest'])->name('search.suggest');
        });

        Route::middleware('throttle:analytics')->group(function (): void {
            Route::post('analytics/events', [StorefrontAnalyticsEventController::class, 'store'])->name('analytics.events.store');
        });

        Route::middleware('throttle:checkout')->group(function (): void {
            Route::post('checkouts', [CheckoutController::class, 'store'])->name('checkouts.store');
            Route::get('checkouts/{checkout}', [CheckoutController::class, 'show'])->name('checkouts.show');
            Route::put('checkouts/{checkout}/address', [CheckoutController::class, 'address'])->name('checkouts.address');
            Route::put('checkouts/{checkout}/shipping-method', [CheckoutController::class, 'shippingMethod'])->name('checkouts.shipping-method');
            Route::post('checkouts/{checkout}/apply-discount', [CheckoutController::class, 'applyDiscount'])->name('checkouts.apply-discount');
            Route::delete('checkouts/{checkout}/discount', [CheckoutController::class, 'destroyDiscount'])->name('checkouts.discount.destroy');
            Route::put('checkouts/{checkout}/payment-method', [CheckoutController::class, 'paymentMethod'])->name('checkouts.payment-method');
            Route::post('checkouts/{checkout}/pay', [CheckoutController::class, 'pay'])->name('checkouts.pay');
            Route::get('orders/{orderNumber}', [StorefrontOrderController::class, 'show'])->name('orders.show');
        });
    });

Route::prefix('admin/v1/platform')
    ->name('api.admin.v1.platform.')
    ->middleware(['auth:sanctum', 'throttle:api.admin', 'platform.api'])
    ->group(function (): void {
        Route::post('organizations', [AdminPlatformOrganizationController::class, 'store'])->name('organizations.store');
        Route::post('stores', [AdminPlatformStoreController::class, 'store'])->name('stores.store');
    });

Route::prefix('admin/v1/stores/{store}')
    ->name('api.admin.v1.')
    ->middleware(['auth:sanctum', 'throttle:api.admin'])
    ->group(function (): void {
        Route::middleware('admin.api')->group(function (): void {
            Route::get('me', [AdminStoreMembershipController::class, 'show'])->name('stores.me');
        });

        Route::middleware('admin.api:manage-platform')->group(function (): void {
            Route::post('invites', [AdminStoreInviteController::class, 'store'])->name('stores.invites.store');
        });

        Route::middleware('admin.api:read-products')->group(function (): void {
            Route::get('products', [AdminProductController::class, 'index'])->name('products.index');
            Route::get('products/{product}', [AdminProductController::class, 'show'])->name('products.show');
        });

        Route::middleware('admin.api:write-products')->group(function (): void {
            Route::post('products', [AdminProductController::class, 'store'])->name('products.store');
            Route::put('products/{product}', [AdminProductController::class, 'update'])->name('products.update');
            Route::delete('products/{product}', [AdminProductController::class, 'destroy'])->name('products.destroy');
            Route::post('products/{product}/media/presign-upload', [AdminProductController::class, 'presignUpload'])->name('products.media.presign-upload');
        });

        Route::middleware('admin.api:read-customers')->group(function (): void {
            Route::get('customers', [AdminCustomerController::class, 'index'])->name('customers.index');
            Route::get('customers/{customer}', [AdminCustomerController::class, 'show'])->name('customers.show');
        });

        Route::middleware('admin.api:read-collections')->group(function (): void {
            Route::get('collections', [AdminCollectionController::class, 'index'])->name('collections.index');
        });

        Route::middleware('admin.api:write-collections')->group(function (): void {
            Route::post('collections', [AdminCollectionController::class, 'store'])->name('collections.store');
            Route::put('collections/{collection}', [AdminCollectionController::class, 'update'])->name('collections.update');
            Route::delete('collections/{collection}', [AdminCollectionController::class, 'destroy'])->name('collections.destroy');
        });

        Route::middleware('admin.api:read-discounts')->group(function (): void {
            Route::get('discounts', [AdminDiscountController::class, 'index'])->name('discounts.index');
        });

        Route::middleware('admin.api:write-discounts')->group(function (): void {
            Route::post('discounts', [AdminDiscountController::class, 'store'])->name('discounts.store');
            Route::put('discounts/{discount}', [AdminDiscountController::class, 'update'])->name('discounts.update');
            Route::delete('discounts/{discount}', [AdminDiscountController::class, 'destroy'])->name('discounts.destroy');
        });

        Route::middleware('admin.api:read-content')->group(function (): void {
            Route::get('pages', [AdminPageController::class, 'index'])->name('pages.index');
        });

        Route::middleware('admin.api:write-content')->group(function (): void {
            Route::post('pages', [AdminPageController::class, 'store'])->name('pages.store');
            Route::put('pages/{page}', [AdminPageController::class, 'update'])->name('pages.update');
            Route::delete('pages/{page}', [AdminPageController::class, 'destroy'])->name('pages.destroy');
        });

        Route::middleware('admin.api:read-settings')->group(function (): void {
            Route::get('search/status', [AdminSearchIndexController::class, 'status'])->name('search.status');
            Route::get('settings', [AdminStoreSettingsController::class, 'show'])->name('settings.show');
            Route::get('shipping/zones', [AdminShippingZoneController::class, 'index'])->name('shipping.zones.index');
            Route::get('tax/settings', [AdminTaxSettingsController::class, 'show'])->name('tax.settings.show');
        });

        Route::middleware('admin.api:write-settings')->group(function (): void {
            Route::post('search/reindex', [AdminSearchIndexController::class, 'reindex'])->name('search.reindex');
            Route::put('settings', [AdminStoreSettingsController::class, 'update'])->name('settings.update');
            Route::post('shipping/zones', [AdminShippingZoneController::class, 'store'])->name('shipping.zones.store');
            Route::put('shipping/zones/{shippingZone}', [AdminShippingZoneController::class, 'update'])->name('shipping.zones.update');
            Route::post('shipping/zones/{shippingZone}/rates', [AdminShippingRateController::class, 'store'])->name('shipping.zones.rates.store');
            Route::put('tax/settings', [AdminTaxSettingsController::class, 'update'])->name('tax.settings.update');
        });

        Route::middleware('admin.api:write-themes')->group(function (): void {
            Route::post('themes', [AdminThemeController::class, 'store'])->name('themes.store');
            Route::post('themes/{theme}/publish', [AdminThemeController::class, 'publish'])->name('themes.publish');
            Route::put('themes/{theme}/settings', [AdminThemeSettingsController::class, 'update'])->name('themes.settings.update');
        });

        Route::middleware('admin.api:read-analytics')->group(function (): void {
            Route::get('analytics/summary', [AdminAnalyticsSummaryController::class, 'show'])->name('analytics.summary');
        });

        Route::middleware('admin.api:read-orders')->group(function (): void {
            Route::post('exports/orders', [AdminOrderExportController::class, 'store'])->name('exports.orders.store');
            Route::get('exports/{dataExport}', [AdminOrderExportController::class, 'show'])->name('exports.show');
            Route::get('orders', [AdminOrderController::class, 'index'])->name('orders.index');
            Route::get('orders/{order}', [AdminOrderController::class, 'show'])->name('orders.show');
        });

        Route::middleware('admin.api:write-orders')->group(function (): void {
            Route::post('orders/{order}/fulfillments', [AdminOrderFulfillmentController::class, 'store'])->name('orders.fulfillments.store');
            Route::post('orders/{order}/refunds', [AdminOrderRefundController::class, 'store'])->name('orders.refunds.store');
        });
    });

Route::middleware('throttle:60,1')
    ->prefix('apps/v1/stores/{store}')
    ->name('api.apps.v1.')
    ->group(function (): void {
        Route::get('products', DeferredAppEndpointController::class)->name('products.index');
        Route::get('orders', DeferredAppEndpointController::class)->name('orders.index');
        Route::get('customers', DeferredAppEndpointController::class)->name('customers.index');
    });


Output:
Chunk ID: 0e64dd
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 621
Output:
<?php

/*
|--------------------------------------------------------------------------
| Test Case
|--------------------------------------------------------------------------
|
| The closure you provide to your test functions is always bound to a specific PHPUnit test
| case class. By default, that class is "PHPUnit\Framework\TestCase". Of course, you may
| need to change it using the "pest()" function to bind a different classes or traits.
|
*/

pest()->extend(Tests\TestCase::class)
    ->in('Feature', 'Browser');

/*
|--------------------------------------------------------------------------
| Expectations
|--------------------------------------------------------------------------
|
| When you're writing tests, you often need to check that values meet certain conditions. The
| "expect()" function gives you access to a set of "expectations" methods that you can use
| to assert different things. Of course, you may extend the Expectation API at any time.
|
*/

expect()->extend('toBeOne', function () {
    return $this->toBe(1);
});

/*
|--------------------------------------------------------------------------
| Functions
|--------------------------------------------------------------------------
|
| While Pest is very powerful out-of-the-box, you may have some testing code specific to your
| project that you don't want to repeat in every file. Here you can also expose helpers as
| global functions to help you to reduce the number of lines of code in your test files.
|
*/

/**
 * @param  list<string>  $abilities
 */
function adminApiBearerToken(\App\Models\Store $store, array $abilities, ?\App\Models\User $user = null): string
{
    return adminApiToken($store, $abilities, $user)['plain_text'];
}

/**
 * @param  list<string>  $abilities
 * @return array{token: \App\Models\PersonalAccessToken, plain_text: string}
 */
function adminApiToken(\App\Models\Store $store, array $abilities, ?\App\Models\User $user = null): array
{
    $user ??= $store->users()->wherePivot('role', 'owner')->first()
        ?? $store->users()->first();

    if (! $user instanceof \App\Models\User) {
        $user = \App\Models\User::factory()->create(['email_verified_at' => now()]);
        $store->users()->attach($user->getKey(), [
            'role' => \App\Enums\StoreUserRole::Owner->value,
            'created_at' => now(),
        ]);
    }

    return app(\App\Services\WebhookService::class)
        ->createApiToken($store, 'Test API token', $abilities, $user);
}


rg -n "function adminApi(Token|BearerToken)|adminApiBearerToken|adminApiToken" tests app -g '*.php'

rg -n 'function adminApi(Token|BearerToken)|adminApiBearerToken|adminApiToken' tests app -g '*.php'

Question: function adminApi(Token|BearerToken)|adminApiBearerToken|adminApiToken

tests/Pest.php:46:function adminApiBearerToken(\App\Models\Store $store, array $abilities, ?\App\Models\User $user = null): string
tests/Pest.php:48:    return adminApiToken($store, $abilities, $user)['plain_text'];
tests/Pest.php:55:function adminApiToken(\App\Models\Store $store, array $abilities, ?\App\Models\User $user = null): array
tests/Feature/Security/HtmlSanitizationTest.php:187:    $createResponse = $this->withToken(adminApiBearerToken($store, ['write-products'], $user))
tests/Feature/Security/HtmlSanitizationTest.php:209:    $updateResponse = $this->withToken(adminApiBearerToken($store, ['write-products'], $user))
tests/Feature/Security/HtmlSanitizationTest.php:223:    $createResponse = $this->withToken(adminApiBearerToken($store, ['write-content'], $user))
tests/Feature/Security/HtmlSanitizationTest.php:237:    $updateResponse = $this->withToken(adminApiBearerToken($store, ['write-content'], $user))
tests/Feature/Security/HtmlSanitizationTest.php:251:    $createResponse = $this->withToken(adminApiBearerToken($store, ['write-collections'], $user))
tests/Feature/Security/HtmlSanitizationTest.php:266:    $updateResponse = $this->withToken(adminApiBearerToken($store, ['write-collections'], $user))
tests/Feature/Api/AdminSearchIndexApiTest.php:35:    return adminApiToken($store, $abilities);
tests/Feature/Api/AdminSearchIndexApiTest.php:52:    $this->withToken(adminApiBearerToken($store, ['read-settings'], adminSearchIndexApiUser()))
tests/Feature/Api/AdminSearchIndexApiTest.php:58:    $this->withToken(adminApiBearerToken($store, ['write-settings'], adminSearchIndexApiUser()))
tests/Feature/Api/AdminSearchIndexApiTest.php:67:    $this->withToken(adminApiBearerToken($store, ['read-settings'], adminSearchIndexApiUser()))
tests/Feature/Api/AdminAnalyticsSummaryApiTest.php:50:    return adminApiToken($store, $abilities);
tests/Feature/Api/AdminAnalyticsSummaryApiTest.php:105:    $this->withToken(adminApiBearerToken($store, ['read-analytics'], adminAnalyticsSummaryApiUser()))
tests/Feature/Api/AdminAnalyticsSummaryApiTest.php:151:    $this->withToken(adminApiBearerToken($store, ['read-analytics'], adminAnalyticsSummaryApiUser()))
tests/Feature/Api/AdminAnalyticsSummaryApiTest.php:156:    $this->withToken(adminApiBearerToken($store, ['read-analytics'], adminAnalyticsSummaryApiUser()))
tests/Feature/Api/AdminStoreSettingsApiTest.php:32:    return adminApiToken($store, $abilities);
tests/Feature/Api/AdminStoreSettingsApiTest.php:38:    $readToken = adminApiBearerToken($store, ['read-settings'], $user);
tests/Feature/Api/AdminStoreSettingsApiTest.php:39:    $writeToken = adminApiBearerToken($store, ['write-settings'], $user);
tests/Feature/Api/AdminStoreSettingsApiTest.php:121:    $this->withToken(adminApiBearerToken($store, ['write-settings'], adminStoreSettingsApiUser()))
tests/Feature/Api/AdminStoreSettingsApiTest.php:130:    $this->withToken(adminApiBearerToken($store, ['write-settings'], adminStoreSettingsApiUser()))
tests/Feature/Api/AdminStoreSettingsApiTest.php:137:    $this->withToken(adminApiBearerToken($store, ['write-settings'], adminStoreSettingsApiUser()))
tests/Feature/Api/AdminCatalogApiTest.php:40:    return adminApiToken($store, $abilities);
tests/Feature/Api/AdminCatalogApiTest.php:72:    $this->withToken(adminApiBearerToken($store, ['read-products'], $user))
tests/Feature/Api/AdminCatalogApiTest.php:80:    $this->withToken(adminApiBearerToken($store, ['read-products'], $user))
tests/Feature/Api/AdminCatalogApiTest.php:95:    $this->withToken(adminApiBearerToken($store, ['read-products'], $user))
tests/Feature/Api/AdminCatalogApiTest.php:109:    $writeToken = adminApiBearerToken($store, ['write-products'], $user);
tests/Feature/Api/AdminCatalogApiTest.php:223:    $this->withToken(adminApiBearerToken($store, ['write-products'], adminCatalogApiUser()))
tests/Feature/Api/AdminCatalogApiTest.php:264:    $this->withToken(adminApiBearerToken($store, ['read-customers'], adminCatalogApiUser()))
tests/Feature/Api/AdminCatalogApiTest.php:272:    $this->withToken(adminApiBearerToken($store, ['read-customers'], adminCatalogApiUser()))
tests/Feature/Api/AdminCatalogApiTest.php:346:    $this->withToken(adminApiBearerToken($store, ['read-products'], adminCatalogApiUser()))
tests/Feature/Api/AdminCatalogApiTest.php:350:    $this->withToken(adminApiBearerToken($store, ['read-customers'], adminCatalogApiUser()))
tests/Feature/Api/AdminPlatformApiTest.php:33:    return adminApiToken($store, $abilities);
tests/Feature/Api/AdminPlatformApiTest.php:39:    $token = adminApiBearerToken($store, ['manage-platform'], $user);
tests/Feature/Api/AdminPlatformApiTest.php:88:    $staffToken = adminApiBearerToken($store, ['manage-platform'], $staff);
tests/Feature/Api/AdminPlatformApiTest.php:134:    $userToken = adminApiBearerToken($store, ['*'], $user);
tests/Feature/Api/AdminPlatformApiTest.php:135:    $staffToken = adminApiBearerToken($store, ['manage-platform'], $staff);
tests/Feature/Api/AdminShippingSettingsApiTest.php:34:    return adminApiToken($store, $abilities);
tests/Feature/Api/AdminShippingSettingsApiTest.php:40:    $readToken = adminApiBearerToken($store, ['read-settings'], $user);
tests/Feature/Api/AdminShippingSettingsApiTest.php:41:    $writeToken = adminApiBearerToken($store, ['write-settings'], $user);
tests/Feature/Api/AdminShippingSettingsApiTest.php:132:    $this->withToken(adminApiBearerToken($store, ['write-settings'], adminShippingSettingsApiUser()))
tests/Feature/Api/AdminShippingSettingsApiTest.php:140:    $this->withToken(adminApiBearerToken($store, ['write-settings'], adminShippingSettingsApiUser()))
tests/Feature/Api/AdminCollectionApiTest.php:33:    return adminApiToken($store, $abilities);
tests/Feature/Api/AdminCollectionApiTest.php:47:    $readToken = adminApiBearerToken($store, ['read-collections'], $user);
tests/Feature/Api/AdminCollectionApiTest.php:48:    $writeToken = adminApiBearerToken($store, ['write-collections'], $user);
tests/Feature/Api/AdminCollectionApiTest.php:139:    $this->withToken(adminApiBearerToken($store, ['write-collections'], adminCollectionApiUser()))
tests/Feature/Api/AdminDiscountApiTest.php:35:    return adminApiToken($store, $abilities);
tests/Feature/Api/AdminDiscountApiTest.php:43:    $readToken = adminApiBearerToken($store, ['read-discounts'], $user);
tests/Feature/Api/AdminDiscountApiTest.php:44:    $writeToken = adminApiBearerToken($store, ['write-discounts'], $user);
tests/Feature/Api/AdminDiscountApiTest.php:136:    $this->withToken(adminApiBearerToken($store, ['write-discounts'], adminDiscountApiUser()))
tests/Feature/Api/AdminThemeApiTest.php:37:    return adminApiToken($store, $abilities);
tests/Feature/Api/AdminThemeApiTest.php:106:    $writeToken = adminApiBearerToken($store, ['write-themes'], $user);
tests/Feature/Api/AdminThemeApiTest.php:131:    $writeToken = adminApiBearerToken($store, ['write-themes'], adminThemeApiUser());
tests/Feature/Api/AdminThemeApiTest.php:192:    $this->withToken(adminApiBearerToken($store, ['write-themes'], adminThemeApiUser()))
tests/Feature/Api/AdminThemeApiTest.php:201:    $this->withToken(adminApiBearerToken($store, ['write-themes'], adminThemeApiUser()))
tests/Feature/Api/AdminThemeApiTest.php:208:    $this->withToken(adminApiBearerToken($store, ['write-themes'], adminThemeApiUser()))
tests/Feature/Api/AdminOrderExportApiTest.php:36:    return adminApiToken($store, $abilities);
tests/Feature/Api/AdminOrderExportApiTest.php:76:    $readToken = adminApiBearerToken($store, ['read-orders'], adminOrderExportApiUser());
tests/Feature/Api/AdminOrderExportApiTest.php:146:    $this->withToken(adminApiBearerToken($store, ['read-orders'], adminOrderExportApiUser()))
tests/Feature/Api/AdminOrderExportApiTest.php:154:    $this->withToken(adminApiBearerToken($store, ['read-orders'], adminOrderExportApiUser()))
tests/Feature/Api/AdminOrderApiTest.php:57:    return adminApiToken($store, $abilities);
tests/Feature/Api/AdminOrderApiTest.php:120:    $readToken = adminApiBearerToken($store, ['read-orders'], adminOrderApiUser());
tests/Feature/Api/AdminOrderApiTest.php:142:    $writeToken = adminApiBearerToken($store, ['write-orders'], $user);
tests/Feature/Api/AdminOrderApiTest.php:180:    $this->withToken(adminApiBearerToken($store, ['read-orders'], adminOrderApiUser()))
tests/Feature/Api/AdminOrderApiTest.php:233:    $staffWriteToken = adminApiBearerToken($store, ['write-orders'], $staff);
tests/Feature/Api/AdminPageApiTest.php:32:    return adminApiToken($store, $abilities);
tests/Feature/Api/AdminPageApiTest.php:49:    $readToken = adminApiBearerToken($store, ['read-content'], $user);
tests/Feature/Api/AdminPageApiTest.php:50:    $writeToken = adminApiBearerToken($store, ['write-content'], $user);
tests/Feature/Api/AdminPageApiTest.php:129:    $this->withToken(adminApiBearerToken($store, ['write-content'], adminPageApiUser()))
tests/Feature/Api/AdminPageApiTest.php:138:    $this->withToken(adminApiBearerToken($store, ['write-content'], adminPageApiUser()))
tests/Feature/Api/AdminTaxSettingsApiTest.php:33:    return adminApiToken($store, $abilities);
tests/Feature/Api/AdminTaxSettingsApiTest.php:39:    $readToken = adminApiBearerToken($store, ['read-settings'], $user);
tests/Feature/Api/AdminTaxSettingsApiTest.php:40:    $writeToken = adminApiBearerToken($store, ['write-settings'], $user);
tests/Feature/Api/AdminTaxSettingsApiTest.php:121:    $this->withToken(adminApiBearerToken($store, ['write-settings'], adminTaxSettingsApiUser()))
tests/Feature/Api/AdminTaxSettingsApiTest.php:130:    $this->withToken(adminApiBearerToken($store, ['write-settings'], adminTaxSettingsApiUser()))


Output:
Chunk ID: 2f3d6f
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 2411
Output:
tests/Pest.php:46:function adminApiBearerToken(\App\Models\Store $store, array $abilities, ?\App\Models\User $user = null): string
tests/Pest.php:48:    return adminApiToken($store, $abilities, $user)['plain_text'];
tests/Pest.php:55:function adminApiToken(\App\Models\Store $store, array $abilities, ?\App\Models\User $user = null): array
tests/Feature/Security/HtmlSanitizationTest.php:187:    $createResponse = $this->withToken(adminApiBearerToken($store, ['write-products'], $user))
tests/Feature/Security/HtmlSanitizationTest.php:209:    $updateResponse = $this->withToken(adminApiBearerToken($store, ['write-products'], $user))
tests/Feature/Security/HtmlSanitizationTest.php:223:    $createResponse = $this->withToken(adminApiBearerToken($store, ['write-content'], $user))
tests/Feature/Security/HtmlSanitizationTest.php:237:    $updateResponse = $this->withToken(adminApiBearerToken($store, ['write-content'], $user))
tests/Feature/Security/HtmlSanitizationTest.php:251:    $createResponse = $this->withToken(adminApiBearerToken($store, ['write-collections'], $user))
tests/Feature/Security/HtmlSanitizationTest.php:266:    $updateResponse = $this->withToken(adminApiBearerToken($store, ['write-collections'], $user))
tests/Feature/Api/AdminSearchIndexApiTest.php:35:    return adminApiToken($store, $abilities);
tests/Feature/Api/AdminSearchIndexApiTest.php:52:    $this->withToken(adminApiBearerToken($store, ['read-settings'], adminSearchIndexApiUser()))
tests/Feature/Api/AdminSearchIndexApiTest.php:58:    $this->withToken(adminApiBearerToken($store, ['write-settings'], adminSearchIndexApiUser()))
tests/Feature/Api/AdminSearchIndexApiTest.php:67:    $this->withToken(adminApiBearerToken($store, ['read-settings'], adminSearchIndexApiUser()))
tests/Feature/Api/AdminAnalyticsSummaryApiTest.php:50:    return adminApiToken($store, $abilities);
tests/Feature/Api/AdminAnalyticsSummaryApiTest.php:105:    $this->withToken(adminApiBearerToken($store, ['read-analytics'], adminAnalyticsSummaryApiUser()))
tests/Feature/Api/AdminAnalyticsSummaryApiTest.php:151:    $this->withToken(adminApiBearerToken($store, ['read-analytics'], adminAnalyticsSummaryApiUser()))
tests/Feature/Api/AdminAnalyticsSummaryApiTest.php:156:    $this->withToken(adminApiBearerToken($store, ['read-analytics'], adminAnalyticsSummaryApiUser()))
tests/Feature/Api/AdminStoreSettingsApiTest.php:32:    return adminApiToken($store, $abilities);
tests/Feature/Api/AdminStoreSettingsApiTest.php:38:    $readToken = adminApiBearerToken($store, ['read-settings'], $user);
tests/Feature/Api/AdminStoreSettingsApiTest.php:39:    $writeToken = adminApiBearerToken($store, ['write-settings'], $user);
tests/Feature/Api/AdminStoreSettingsApiTest.php:121:    $this->withToken(adminApiBearerToken($store, ['write-settings'], adminStoreSettingsApiUser()))
tests/Feature/Api/AdminStoreSettingsApiTest.php:130:    $this->withToken(adminApiBearerToken($store, ['write-settings'], adminStoreSettingsApiUser()))
tests/Feature/Api/AdminStoreSettingsApiTest.php:137:    $this->withToken(adminApiBearerToken($store, ['write-settings'], adminStoreSettingsApiUser()))
tests/Feature/Api/AdminCatalogApiTest.php:40:    return adminApiToken($store, $abilities);
tests/Feature/Api/AdminCatalogApiTest.php:72:    $this->withToken(adminApiBearerToken($store, ['read-products'], $user))
tests/Feature/Api/AdminCatalogApiTest.php:80:    $this->withToken(adminApiBearerToken($store, ['read-products'], $user))
tests/Feature/Api/AdminCatalogApiTest.php:95:    $this->withToken(adminApiBearerToken($store, ['read-products'], $user))
tests/Feature/Api/AdminCatalogApiTest.php:109:    $writeToken = adminApiBearerToken($store, ['write-products'], $user);
tests/Feature/Api/AdminCatalogApiTest.php:223:    $this->withToken(adminApiBearerToken($store, ['write-products'], adminCatalogApiUser()))
tests/Feature/Api/AdminCatalogApiTest.php:264:    $this->withToken(adminApiBearerToken($store, ['read-customers'], adminCatalogApiUser()))
tests/Feature/Api/AdminCatalogApiTest.php:272:    $this->withToken(adminApiBearerToken($store, ['read-customers'], adminCatalogApiUser()))
tests/Feature/Api/AdminCatalogApiTest.php:346:    $this->withToken(adminApiBearerToken($store, ['read-products'], adminCatalogApiUser()))
tests/Feature/Api/AdminCatalogApiTest.php:350:    $this->withToken(adminApiBearerToken($store, ['read-customers'], adminCatalogApiUser()))
tests/Feature/Api/AdminPlatformApiTest.php:33:    return adminApiToken($store, $abilities);
tests/Feature/Api/AdminPlatformApiTest.php:39:    $token = adminApiBearerToken($store, ['manage-platform'], $user);
tests/Feature/Api/AdminPlatformApiTest.php:88:    $staffToken = adminApiBearerToken($store, ['manage-platform'], $staff);
tests/Feature/Api/AdminPlatformApiTest.php:134:    $userToken = adminApiBearerToken($store, ['*'], $user);
tests/Feature/Api/AdminPlatformApiTest.php:135:    $staffToken = adminApiBearerToken($store, ['manage-platform'], $staff);
tests/Feature/Api/AdminShippingSettingsApiTest.php:34:    return adminApiToken($store, $abilities);
tests/Feature/Api/AdminShippingSettingsApiTest.php:40:    $readToken = adminApiBearerToken($store, ['read-settings'], $user);
tests/Feature/Api/AdminShippingSettingsApiTest.php:41:    $writeToken = adminApiBearerToken($store, ['write-settings'], $user);
tests/Feature/Api/AdminShippingSettingsApiTest.php:132:    $this->withToken(adminApiBearerToken($store, ['write-settings'], adminShippingSettingsApiUser()))
tests/Feature/Api/AdminShippingSettingsApiTest.php:140:    $this->withToken(adminApiBearerToken($store, ['write-settings'], adminShippingSettingsApiUser()))
tests/Feature/Api/AdminCollectionApiTest.php:33:    return adminApiToken($store, $abilities);
tests/Feature/Api/AdminCollectionApiTest.php:47:    $readToken = adminApiBearerToken($store, ['read-collections'], $user);
tests/Feature/Api/AdminCollectionApiTest.php:48:    $writeToken = adminApiBearerToken($store, ['write-collections'], $user);
tests/Feature/Api/AdminCollectionApiTest.php:139:    $this->withToken(adminApiBearerToken($store, ['write-collections'], adminCollectionApiUser()))
tests/Feature/Api/AdminDiscountApiTest.php:35:    return adminApiToken($store, $abilities);
tests/Feature/Api/AdminDiscountApiTest.php:43:    $readToken = adminApiBearerToken($store, ['read-discounts'], $user);
tests/Feature/Api/AdminDiscountApiTest.php:44:    $writeToken = adminApiBearerToken($store, ['write-discounts'], $user);
tests/Feature/Api/AdminDiscountApiTest.php:136:    $this->withToken(adminApiBearerToken($store, ['write-discounts'], adminDiscountApiUser()))
tests/Feature/Api/AdminThemeApiTest.php:37:    return adminApiToken($store, $abilities);
tests/Feature/Api/AdminThemeApiTest.php:106:    $writeToken = adminApiBearerToken($store, ['write-themes'], $user);
tests/Feature/Api/AdminThemeApiTest.php:131:    $writeToken = adminApiBearerToken($store, ['write-themes'], adminThemeApiUser());
tests/Feature/Api/AdminThemeApiTest.php:192:    $this->withToken(adminApiBearerToken($store, ['write-themes'], adminThemeApiUser()))
tests/Feature/Api/AdminThemeApiTest.php:201:    $this->withToken(adminApiBearerToken($store, ['write-themes'], adminThemeApiUser()))
tests/Feature/Api/AdminThemeApiTest.php:208:    $this->withToken(adminApiBearerToken($store, ['write-themes'], adminThemeApiUser()))
tests/Feature/Api/AdminOrderExportApiTest.php:36:    return adminApiToken($store, $abilities);
tests/Feature/Api/AdminOrderExportApiTest.php:76:    $readToken = adminApiBearerToken($store, ['read-orders'], adminOrderExportApiUser());
tests/Feature/Api/AdminOrderExportApiTest.php:146:    $this->withToken(adminApiBearerToken($store, ['read-orders'], adminOrderExportApiUser()))
tests/Feature/Api/AdminOrderExportApiTest.php:154:    $this->withToken(adminApiBearerToken($store, ['read-orders'], adminOrderExportApiUser()))
tests/Feature/Api/AdminOrderApiTest.php:57:    return adminApiToken($store, $abilities);
tests/Feature/Api/AdminOrderApiTest.php:120:    $readToken = adminApiBearerToken($store, ['read-orders'], adminOrderApiUser());
tests/Feature/Api/AdminOrderApiTest.php:142:    $writeToken = adminApiBearerToken($store, ['write-orders'], $user);
tests/Feature/Api/AdminOrderApiTest.php:180:    $this->withToken(adminApiBearerToken($store, ['read-orders'], adminOrderApiUser()))
tests/Feature/Api/AdminOrderApiTest.php:233:    $staffWriteToken = adminApiBearerToken($store, ['write-orders'], $staff);
tests/Feature/Api/AdminPageApiTest.php:32:    return adminApiToken($store, $abilities);
tests/Feature/Api/AdminPageApiTest.php:49:    $readToken = adminApiBearerToken($store, ['read-content'], $user);
tests/Feature/Api/AdminPageApiTest.php:50:    $writeToken = adminApiBearerToken($store, ['write-content'], $user);
tests/Feature/Api/AdminPageApiTest.php:129:    $this->withToken(adminApiBearerToken($store, ['write-content'], adminPageApiUser()))
tests/Feature/Api/AdminPageApiTest.php:138:    $this->withToken(adminApiBearerToken($store, ['write-content'], adminPageApiUser()))
tests/Feature/Api/AdminTaxSettingsApiTest.php:33:    return adminApiToken($store, $abilities);
tests/Feature/Api/AdminTaxSettingsApiTest.php:39:    $readToken = adminApiBearerToken($store, ['read-settings'], $user);
tests/Feature/Api/AdminTaxSettingsApiTest.php:40:    $writeToken = adminApiBearerToken($store, ['write-settings'], $user);
tests/Feature/Api/AdminTaxSettingsApiTest.php:121:    $this->withToken(adminApiBearerToken($store, ['write-settings'], adminTaxSettingsApiUser()))
tests/Feature/Api/AdminTaxSettingsApiTest.php:130:    $this->withToken(adminApiBearerToken($store, ['write-settings'], adminTaxSettingsApiUser()))


sed -n '1,220p' database/factories/UserFactory.php


sed -n '1,220p' database/seeders/UserSeeder.php


rg -n "current_store|admin" routes/web.php app/Http/Middleware resources/views -g '*.php'


rg -n "enum StoreUserRole|Support" app/Enums specs tests -g '*.php' -g '*.md'


sed -n '1,220p' database/seeders/UserSeeder.php

<?php

namespace Database\Seeders;

use App\Models\User;
use Illuminate\Database\Seeder;

class UserSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        User::query()->updateOrCreate(
            ['email' => 'admin@acme.test'],
            [
                'name' => 'Acme Admin',
                'password' => 'password',
                'status' => 'active',
                'is_platform_admin' => true,
                'email_verified_at' => now(),
                'last_login_at' => now()->subDay(),
            ],
        );
    }
}


sed -n '1,220p' database/factories/UserFactory.php

<?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
 */
class UserFactory extends Factory
{
    /**
     * The current password being used by the factory.
     */
    protected static ?string $password;

    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition(): array
    {
        return [
            'name' => fake()->name(),
            'email' => fake()->unique()->safeEmail(),
            'email_verified_at' => now(),
            'status' => 'active',
            'password' => static::$password ??= Hash::make('password'),
            'last_login_at' => fake()->dateTimeBetween('-30 days'),
            'remember_token' => Str::random(10),
            'two_factor_secret' => null,
            'two_factor_recovery_codes' => null,
            'two_factor_confirmed_at' => null,
        ];
    }

    /**
     * Indicate that the model's email address should be unverified.
     */
    public function unverified(): static
    {
        return $this->state(fn (array $attributes) => [
            'email_verified_at' => null,
        ]);
    }

    /**
     * Indicate that the model has two-factor authentication configured.
     */
    public function withTwoFactor(): static
    {
        return $this->state(fn (array $attributes) => [
            'two_factor_secret' => encrypt('secret'),
            'two_factor_recovery_codes' => encrypt(json_encode(['recovery-code-1'])),
            'two_factor_confirmed_at' => now(),
        ]);
    }

    public function disabled(): static
    {
        return $this->state(fn (array $attributes): array => [
            'status' => 'disabled',
        ]);
    }
}


Output:
Chunk ID: e72293
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 470
Output:
<?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
 */
class UserFactory extends Factory
{
    /**
     * The current password being used by the factory.
     */
    protected static ?string $password;

    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition(): array
    {
        return [
            'name' => fake()->name(),
            'email' => fake()->unique()->safeEmail(),
            'email_verified_at' => now(),
            'status' => 'active',
            'password' => static::$password ??= Hash::make('password'),
            'last_login_at' => fake()->dateTimeBetween('-30 days'),
            'remember_token' => Str::random(10),
            'two_factor_secret' => null,
            'two_factor_recovery_codes' => null,
            'two_factor_confirmed_at' => null,
        ];
    }

    /**
     * Indicate that the model's email address should be unverified.
     */
    public function unverified(): static
    {
        return $this->state(fn (array $attributes) => [
            'email_verified_at' => null,
        ]);
    }

    /**
     * Indicate that the model has two-factor authentication configured.
     */
    public function withTwoFactor(): static
    {
        return $this->state(fn (array $attributes) => [
            'two_factor_secret' => encrypt('secret'),
            'two_factor_recovery_codes' => encrypt(json_encode(['recovery-code-1'])),
            'two_factor_confirmed_at' => now(),
        ]);
    }

    public function disabled(): static
    {
        return $this->state(fn (array $attributes): array => [
            'status' => 'disabled',
        ]);
    }
}


Output:
Chunk ID: 3a56a3
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 151
Output:
<?php

namespace Database\Seeders;

use App\Models\User;
use Illuminate\Database\Seeder;

class UserSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        User::query()->updateOrCreate(
            ['email' => 'admin@acme.test'],
            [
                'name' => 'Acme Admin',
                'password' => 'password',
                'status' => 'active',
                'is_platform_admin' => true,
                'email_verified_at' => now(),
                'last_login_at' => now()->subDay(),
            ],
        );
    }
}


/bin/zsh
-lc
sed -n '1,220p' app/Models/User.php

<?php

namespace App\Models;

use App\Enums\StoreUserRole;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Laravel\Fortify\TwoFactorAuthenticatable;

class User extends Authenticatable implements MustVerifyEmail
{
    /** @use HasFactory<\Database\Factories\UserFactory> */
    use HasFactory, Notifiable, TwoFactorAuthenticatable;

    /**
     * The attributes that are mass assignable.
     *
     * @var list<string>
     */
    protected $fillable = [
        'name',
        'email',
        'status',
        'is_platform_admin',
        'password',
        'last_login_at',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var list<string>
     */
    protected $hidden = [
        'password_hash',
        'two_factor_secret',
        'two_factor_recovery_codes',
        'remember_token',
    ];

    /**
     * @return BelongsToMany<Store, $this>
     */
    public function stores(): BelongsToMany
    {
        return $this->belongsToMany(Store::class, 'store_users')
            ->using(StoreUser::class)
            ->withPivot('role');
    }

    public function roleForStore(Store $store): ?StoreUserRole
    {
        return $this->roleForStoreId($store->getKey());
    }

    public function roleForStoreId(int $storeId): ?StoreUserRole
    {
        $role = $this->stores()
            ->whereKey($storeId)
            ->first()
            ?->pivot
            ?->role;

        if ($role instanceof StoreUserRole) {
            return $role;
        }

        return is_string($role) ? StoreUserRole::tryFrom($role) : null;
    }

    public function getAuthPassword(): ?string
    {
        return $this->password_hash;
    }

    public function setPasswordAttribute(string $value): void
    {
        $this->attributes['password_hash'] = Hash::needsRehash($value) ? Hash::make($value) : $value;
    }

    public function getPasswordAttribute(): ?string
    {
        return $this->password_hash;
    }

    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'is_platform_admin' => 'boolean',
            'last_login_at' => 'datetime',
            'two_factor_confirmed_at' => 'datetime',
        ];
    }

    /**
     * Get the user's initials
     */
    public function initials(): string
    {
        return Str::of($this->name)
            ->explode(' ')
            ->take(2)
            ->map(fn ($word) => Str::substr($word, 0, 1))
            ->implode('');
    }
}


Output:
Chunk ID: 4d46b4
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 725
Output:
<?php

namespace App\Models;

use App\Enums\StoreUserRole;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Laravel\Fortify\TwoFactorAuthenticatable;

class User extends Authenticatable implements MustVerifyEmail
{
    /** @use HasFactory<\Database\Factories\UserFactory> */
    use HasFactory, Notifiable, TwoFactorAuthenticatable;

    /**
     * The attributes that are mass assignable.
     *
     * @var list<string>
     */
    protected $fillable = [
        'name',
        'email',
        'status',
        'is_platform_admin',
        'password',
        'last_login_at',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var list<string>
     */
    protected $hidden = [
        'password_hash',
        'two_factor_secret',
        'two_factor_recovery_codes',
        'remember_token',
    ];

    /**
     * @return BelongsToMany<Store, $this>
     */
    public function stores(): BelongsToMany
    {
        return $this->belongsToMany(Store::class, 'store_users')
            ->using(StoreUser::class)
            ->withPivot('role');
    }

    public function roleForStore(Store $store): ?StoreUserRole
    {
        return $this->roleForStoreId($store->getKey());
    }

    public function roleForStoreId(int $storeId): ?StoreUserRole
    {
        $role = $this->stores()
            ->whereKey($storeId)
            ->first()
            ?->pivot
            ?->role;

        if ($role instanceof StoreUserRole) {
            return $role;
        }

        return is_string($role) ? StoreUserRole::tryFrom($role) : null;
    }

    public function getAuthPassword(): ?string
    {
        return $this->password_hash;
    }

    public function setPasswordAttribute(string $value): void
    {
        $this->attributes['password_hash'] = Hash::needsRehash($value) ? Hash::make($value) : $value;
    }

    public function getPasswordAttribute(): ?string
    {
        return $this->password_hash;
    }

    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'is_platform_admin' => 'boolean',
            'last_login_at' => 'datetime',
            'two_factor_confirmed_at' => 'datetime',
        ];
    }

    /**
     * Get the user's initials
     */
    public function initials(): string
    {
        return Str::of($this->name)
            ->explode(' ')
            ->take(2)
            ->map(fn ($word) => Str::substr($word, 0, 1))
            ->implode('');
    }
}


rg -n "enum StoreUserRole|Support" app/Enums specs tests -g '*.php' -g '*.md'

rg -n 'enum StoreUserRole|Support' app/Enums specs tests -g '*.php' -g '*.md'

Question: enum StoreUserRole|Support

tests/Feature/Webhooks/WebhookDeliveryTest.php:19:use Illuminate\Support\Facades\Http;
tests/Feature/Webhooks/WebhookDeliveryTest.php:20:use Illuminate\Support\Facades\Queue;
specs/06-AUTH-AND-SECURITY.md:312:| Support | `'support'` | Read-only access to products, orders, and customers. For customer service agents. |
specs/06-AUTH-AND-SECURITY.md:326:| Resource | Action | Owner | Admin | Staff | Support |
specs/06-AUTH-AND-SECURITY.md:384:| AnyRole | Owner, Admin, Staff, Support | Read-only listing/viewing of products, orders, customers, collections, discounts |
specs/01-DATABASE-SCHEMA.md:39:- `idx_organizations_billing_email` on (`billing_email`) - Supports lookup by billing email
specs/02-API-ROUTES.md:1647:Update a product. Supports partial updates.
specs/02-API-ROUTES.md:1829:Same fields as POST (all optional). Supports partial updates. Use `product_ids` to replace the full product set, or `add_product_ids` / `remove_product_ids` for incremental changes.
specs/02-API-ROUTES.md:2079:Create a refund. Supports partial refunds by line or amount.
specs/02-API-ROUTES.md:2245:Update a discount. Supports partial updates.
specs/02-API-ROUTES.md:2682:Same fields as POST. Supports partial updates.
specs/09-IMPLEMENTATION-ROADMAP.md:150:| `StoreUserRole` | `Owner`, `Admin`, `Staff`, `Support` |
specs/09-IMPLEMENTATION-ROADMAP.md:225:| Permission | Owner | Admin | Staff | Support |
specs/09-IMPLEMENTATION-ROADMAP.md:317:**File to create:** `App\Support\HandleGenerator`
specs/09-IMPLEMENTATION-ROADMAP.md:2014:| Support classes | 2-3 |
specs/07-SEEDERS-AND-TEST-DATA.md:813:| support@acme.test | Support User | password | active | 1 day ago |
specs/07-SEEDERS-AND-TEST-DATA.md:2134:Support Login:
specs/04-STOREFRONT-UI.md:112:A visually hidden "Skip to main content" link is the first element in the body. It becomes visible on keyboard focus, positioned fixed at top-left with a clear visual treatment (solid background, shadow, focus ring). Supports dark mode.
specs/04-STOREFRONT-UI.md:144:| Main Navigation | Center | Horizontal nav with links sourced from the "main-menu" navigation menu. Supports one level of dropdown submenus (revealed on hover/focus) |
specs/03-ADMIN-UI.md:189:| Stacking | Supports multiple toasts |
tests/Feature/Orders/OrderServiceTest.php:29:use Illuminate\Support\Facades\Event;
app/Enums/StoreUserRole.php:5:enum StoreUserRole: string
app/Enums/StoreUserRole.php:10:    case Support = 'support';
tests/Feature/Orders/BankTransferOrderTest.php:22:use Illuminate\Support\Facades\Event;
tests/Feature/Orders/RefundServiceTest.php:18:use Illuminate\Support\Facades\Event;
specs/05-BUSINESS-LOGIC.md:88:| Permission | Owner | Admin | Staff | Support |
specs/05-BUSINESS-LOGIC.md:189:**Helper class:** `App\Support\HandleGenerator`
specs/05-BUSINESS-LOGIC.md:945:### 10.2 Supported Payment Methods
specs/05-BUSINESS-LOGIC.md:1351:**Supported event types:**
specs/05-BUSINESS-LOGIC.md:1656:| HandleGenerator | `App\Support` | Unique handle/slug generation |
specs/05-BUSINESS-LOGIC.md:1675:| StoreUserRole | Owner (`owner`), Admin (`admin`), Staff (`staff`), Support (`support`) |
tests/Feature/Orders/FulfillmentServiceTest.php:18:use Illuminate\Support\Facades\Event;
tests/Feature/Admin/OrderManagementTest.php:23:use Illuminate\Support\Facades\DB;
tests/Feature/Admin/OrderManagementTest.php:235:    $supportUser = adminOrderManagementUserWithRole($store, StoreUserRole::Support);
tests/Feature/Search/SearchServiceTest.php:10:use Illuminate\Support\Facades\DB;
tests/Feature/Admin/AppsDevelopersTest.php:12:use Illuminate\Support\Facades\DB;
tests/Feature/Admin/ContentManagementTest.php:21:use Illuminate\Support\Facades\Storage;
tests/Feature/Admin/ContentManagementTest.php:259:    $support = adminContentUserWithRole($store, StoreUserRole::Support);
tests/Feature/Foundation/TenancyTest.php:9:use Illuminate\Support\Facades\Schema;
tests/Feature/Settings/PasswordUpdateTest.php:5:use Illuminate\Support\Facades\Hash;
tests/Feature/Admin/AnalyticsDashboardTest.php:9:use Illuminate\Support\Facades\DB;
tests/Feature/Admin/AnalyticsDashboardTest.php:52:    $this->actingAs(adminAnalyticsUser(StoreUserRole::Support))
tests/Feature/Storefront/ThemeDataTest.php:15:use Illuminate\Support\Facades\Cache;
tests/Feature/Storefront/ThemeDataTest.php:16:use Illuminate\Support\Facades\Schema;
tests/Feature/Foundation/DatabaseConstraintTest.php:5:use Illuminate\Support\Facades\DB;
tests/Feature/Foundation/DatabaseConstraintTest.php:6:use Illuminate\Support\Facades\Schema;
tests/Feature/Api/AdminDiscountApiTest.php:10:use Illuminate\Support\Str;
tests/Feature/Api/AdminSearchIndexApiTest.php:10:use Illuminate\Support\Facades\DB;
tests/Feature/Auth/PasswordResetTest.php:5:use Illuminate\Support\Facades\Notification;
tests/Feature/Api/AdminThemeApiTest.php:12:use Illuminate\Support\Facades\Storage;
tests/Feature/Api/AdminAnalyticsSummaryApiTest.php:10:use Illuminate\Support\Carbon;
tests/Feature/Api/AdminAnalyticsSummaryApiTest.php:11:use Illuminate\Support\Facades\DB;
tests/Feature/Admin/DiscountManagementTest.php:41:function adminDiscountManagementSupportUser(Store $store): User
tests/Feature/Admin/DiscountManagementTest.php:45:        'role' => StoreUserRole::Support->value,
tests/Feature/Admin/DiscountManagementTest.php:187:    $supportUser = adminDiscountManagementSupportUser($store);
tests/Browser/Storefront/CustomerAccountTest.php:8:use Illuminate\Support\Collection;
tests/Feature/Api/AdminOrderExportApiTest.php:10:use Illuminate\Support\Facades\Storage;
tests/Feature/Api/AdminOrderExportApiTest.php:11:use Illuminate\Support\Str;
tests/Feature/Catalog/ProductServiceTest.php:12:use App\Support\HandleGenerator;
tests/Feature/Catalog/ProductServiceTest.php:14:use Illuminate\Support\Facades\Event;
tests/Feature/Auth/CustomerPasswordResetTest.php:11:use Illuminate\Support\Facades\Auth;
tests/Feature/Auth/CustomerPasswordResetTest.php:12:use Illuminate\Support\Facades\Cache;
tests/Feature/Auth/CustomerPasswordResetTest.php:13:use Illuminate\Support\Facades\DB;
tests/Feature/Auth/CustomerPasswordResetTest.php:14:use Illuminate\Support\Facades\Hash;
tests/Feature/Auth/CustomerPasswordResetTest.php:15:use Illuminate\Support\Facades\Notification;
tests/Feature/Api/AdminOrderApiTest.php:18:use Illuminate\Support\Facades\DB;
tests/Feature/Auth/EmailVerificationTest.php:5:use Illuminate\Support\Facades\Event;
tests/Feature/Auth/EmailVerificationTest.php:6:use Illuminate\Support\Facades\URL;
tests/Feature/Foundation/CustomerAuthTest.php:8:use Illuminate\Support\Facades\Auth;
tests/Feature/Api/AdminPlatformApiTest.php:8:use Illuminate\Support\Facades\DB;
tests/Feature/Admin/ProductMediaManagementTest.php:13:use Illuminate\Support\Facades\Queue;
tests/Feature/Admin/ProductMediaManagementTest.php:14:use Illuminate\Support\Facades\Storage;
tests/Feature/Catalog/CatalogFoundationTest.php:14:use Illuminate\Support\Facades\Schema;
tests/Feature/Catalog/MediaProcessingTest.php:9:use Illuminate\Support\Facades\Storage;
tests/Feature/Admin/SearchSettingsTest.php:11:use Illuminate\Support\Facades\DB;
tests/Feature/Admin/DashboardTest.php:12:use Illuminate\Support\Facades\DB;


rg -n "current_store|admin" routes/web.php app/Http/Middleware resources/views -g '*.php'

rg -n 'current_store|admin' routes/web.php app/Http/Middleware resources/views -g '*.php'

routes/web.php:93:Route::livewire('admin/login', AdminLogin::class)
routes/web.php:95:    ->name('admin.login');
routes/web.php:97:Route::get('admin/forgot-password', [FortifyPasswordResetLinkController::class, 'create'])
routes/web.php:99:    ->name('admin.password.request');
routes/web.php:101:Route::post('admin/forgot-password', [FortifyPasswordResetLinkController::class, 'store'])
routes/web.php:103:    ->name('admin.password.email');
routes/web.php:105:Route::get('admin/reset-password/{token}', [FortifyNewPasswordController::class, 'create'])
routes/web.php:107:    ->name('admin.password.reset');
routes/web.php:109:Route::post('admin/reset-password', [FortifyNewPasswordController::class, 'store'])
routes/web.php:111:    ->name('admin.password.update');
routes/web.php:113:Route::post('admin/logout', function () {
routes/web.php:119:    return redirect()->route('admin.login');
routes/web.php:120:})->middleware('auth')->name('admin.logout');
routes/web.php:129:Route::middleware(['auth', EnsureUserEmailIsVerified::class, 'admin'])->prefix('admin')->name('admin.')->group(function (): void {
routes/web.php:206:Route::redirect('dashboard', 'admin')
app/Http/Middleware/AuthenticatePlatformApi.php:39:        return $user->is_platform_admin === true;
app/Http/Middleware/ResolveStore.php:22:        $store = $request->is('admin*')
app/Http/Middleware/ResolveStore.php:28:        app()->instance('current_store', $store);
app/Http/Middleware/ResolveStore.php:30:        if (! $request->is('admin*') && $store->status === StoreStatus::Suspended) {
app/Http/Middleware/ResolveStore.php:34:        if ($request->is('admin*') && $store->status === StoreStatus::Suspended && ! $request->isMethodSafe()) {
app/Http/Middleware/ResolveStore.php:63:        $storeId = $request->session()->get('current_store_id');
app/Http/Middleware/ResolveStore.php:69:                $request->session()->put('current_store_id', $storeId);
app/Http/Middleware/CheckStoreRole.php:20:        $store = app()->bound('current_store') ? app('current_store') : null;
resources/views/components/desktop-user-menu.blade.php:1:@php($logoutRoute = request()->routeIs('admin.*') ? route('admin.logout') : route('logout'))
app/Http/Middleware/AuthenticateAdminApi.php:24:        app()->instance('current_store', $store);
resources/views/livewire/admin/apps/index.blade.php:19:
resources/views/livewire/admin/apps/index.blade.php:47:                        <flux:button :href="route('admin.apps.show', $installation)" wire:navigate size="sm" variant="filled">
resources/views/livewire/admin/collections/index.blade.php:8:        <flux:button :href="route('admin.collections.create')" wire:navigate variant="primary" icon="plus">
resources/views/livewire/admin/collections/index.blade.php:46:
getKey() }}">
resources/views/livewire/admin/collections/index.blade.php:48:
resources/views/livewire/admin/collections/index.blade.php:69:                                    <flux:button :href="route('admin.collections.create')" wire:navigate variant="primary">Create collection</flux:button>
resources/views/layouts/storefront.blade.php:7:        @php($store = app()->bound('current_store') ? app('current_store') : null)
resources/views/livewire/admin/themes/editor.blade.php:3:        <flux:button :href="route('admin.themes.index')" wire:navigate variant="filled" icon="arrow-left">Themes</flux:button>
resources/views/livewire/admin/pages/index.blade.php:9:            <flux:button :href="route('admin.pages.create')" wire:navigate variant="primary" icon="plus">
resources/views/livewire/admin/pages/index.blade.php:30:
getKey() }}">
resources/views/livewire/admin/pages/index.blade.php:32:
resources/views/livewire/admin/collections/form.blade.php:4:            <flux:breadcrumbs.item :href="route('admin.dashboard')" wire:navigate>Home</flux:breadcrumbs.item>
resources/views/livewire/admin/collections/form.blade.php:5:            <flux:breadcrumbs.item :href="route('admin.collections.index')" wire:navigate>Collections</flux:breadcrumbs.item>
resources/views/livewire/admin/collections/form.blade.php:87:                <flux:button :href="route('admin.collections.index')" wire:navigate variant="ghost">Discard</flux:button>
resources/views/livewire/admin/discounts/index.blade.php:9:            <flux:button :href="route('admin.discounts.create')" wire:navigate variant="primary" icon="plus">
resources/views/livewire/admin/dis…10613 chars truncated…taxes.blade.php:11:            <flux:button :href="route('admin.settings.taxes')" wire:navigate variant="primary">Taxes</flux:button>
resources/views/livewire/admin/settings/taxes.blade.php:12:            <flux:button :href="route('admin.settings.checkout')" wire:navigate variant="filled">Checkout</flux:button>
resources/views/livewire/admin/settings/taxes.blade.php:13:            <flux:button :href="route('admin.settings.notifications')" wire:navigate variant="filled">Notifications</flux:button>
resources/views/livewire/admin/customers/index.blade.php:25:
getKey() }}">
resources/views/livewire/admin/customers/index.blade.php:27:
resources/views/livewire/admin/products/form.blade.php:5:                <flux:breadcrumbs.item :href="route('admin.dashboard')" wire:navigate>Home</flux:breadcrumbs.item>
resources/views/livewire/admin/products/form.blade.php:6:                <flux:breadcrumbs.item :href="route('admin.products.index')" wire:navigate>Products</flux:breadcrumbs.item>
resources/views/livewire/admin/products/form.blade.php:213:                <flux:button :href="route('admin.products.index')" wire:navigate variant="ghost">Discard</flux:button>
resources/views/livewire/admin/inventory/index.blade.php:34:                                variant->product) }}" class="font-medium text-zinc-950 hover:underline dark:text-white" wire:navigate>
resources/views/livewire/admin/orders/index.blade.php:65:
getKey() }}">
resources/views/livewire/admin/orders/index.blade.php:67:
resources/views/livewire/admin/settings/notifications.blade.php:5:            <flux:text class="mt-1">Sender identity, customer emails, and admin alerts.</flux:text>
resources/views/livewire/admin/settings/notifications.blade.php:9:            <flux:button :href="route('admin.settings.index')" wire:navigate variant="filled">General</flux:button>
resources/views/livewire/admin/settings/notifications.blade.php:10:            <flux:button :href="route('admin.settings.shipping')" wire:navigate variant="filled">Shipping</flux:button>
resources/views/livewire/admin/settings/notifications.blade.php:11:            <flux:button :href="route('admin.settings.taxes')" wire:navigate variant="filled">Taxes</flux:button>
resources/views/livewire/admin/settings/notifications.blade.php:12:            <flux:button :href="route('admin.settings.checkout')" wire:navigate variant="filled">Checkout</flux:button>
resources/views/livewire/admin/settings/notifications.blade.php:13:            <flux:button :href="route('admin.settings.notifications')" wire:navigate variant="primary">Notifications</flux:button>
resources/views/livewire/admin/settings/notifications.blade.php:60:                    <flux:switch wire:model="adminOrderAlertsEnabled" label="New order alerts" align="left" />
resources/views/livewire/auth/reset-password.blade.php:8:        <form method="POST" action="{{ request()->routeIs('admin.password.reset') ? route('admin.password.update') : route('password.update') }}" class="flex flex-col gap-6">
resources/views/livewire/auth/forgot-password.blade.php:8:        <form method="POST" action="{{ request()->routeIs('admin.password.request') ? route('admin.password.email') : route('password.email') }}" class="flex flex-col gap-6">
resources/views/livewire/auth/forgot-password.blade.php:28:            <flux:link :href="request()->routeIs('admin.password.request') ? route('admin.login') : route('login')" wire:navigate>{{ __('log in') }}</flux:link>
resources/views/livewire/admin/settings/index.blade.php:9:            <flux:button :href="route('admin.settings.index')" wire:navigate variant="primary">General</flux:button>
resources/views/livewire/admin/settings/index.blade.php:10:            <flux:button :href="route('admin.settings.shipping')" wire:navigate variant="filled">Shipping</flux:button>
resources/views/livewire/admin/settings/index.blade.php:11:            <flux:button :href="route('admin.settings.taxes')" wire:navigate variant="filled">Taxes</flux:button>
resources/views/livewire/admin/settings/index.blade.php:12:            <flux:button :href="route('admin.settings.checkout')" wire:navigate variant="filled">Checkout</flux:button>
resources/views/livewire/admin/settings/index.blade.php:13:            <flux:button :href="route('admin.settings.notifications')" wire:navigate variant="filled">Notifications</flux:button>
resources/views/livewire/admin/settings/index.blade.php:100:                    <flux:select.option value="admin">Admin</flux:select.option>