content:
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('organizations', function (Blueprint $table): void {
            $table->id();
            $table->string('name');
            $table->string('slug')->unique();
            $table->string('billing_email')->nullable()->index();
            $table->string('status')->default('active')->index();
            $table->timestamps();
        });

        Schema::create('stores', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('organization_id')->constrained()->cascadeOnDelete();
            $table->string('name');
            $table->string('handle')->unique();
            $table->string('status')->default('active')->index();
            $table->string('default_currency', 3)->default('EUR');
            $table->string('default_locale', 10)->default('en');
            $table->string('timezone')->default('UTC');
            $table->string('primary_domain')->nullable();
            $table->json('metadata')->nullable();
            $table->timestamps();
            $table->index(['organization_id', 'status']);
        });

        Schema::create('store_domains', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('store_id')->constrained()->cascadeOnDelete();
            $table->string('hostname')->unique();
            $table->string('type')->default('storefront');
            $table->boolean('is_primary')->default(false);
            $table->timestamps();
            $table->index(['store_id', 'is_primary']);
        });

        Schema::table('users', function (Blueprint $table): void {
            $table->string('status')->default('active')->index();
            $table->timestamp('last_login_at')->nullable();
        });

        Schema::create('store_users', function (Blueprint $table): void {
            $table->foreignId('store_id')->constrained()->cascadeOnDelete();
            $table->foreignId('user_id')->constrained()->cascadeOnDelete();
            $table->string('role')->default('staff');
            $table->timestamps();
            $table->primary(['store_id', 'user_id']);
            $table->index('user_id');
            $table->index(['store_id', 'role']);
        });

        Schema::create('store_settings', function (Blueprint $table): void {
            $table->foreignId('store_id')->primary()->constrained()->cascadeOnDelete();
            $table->json('general_json')->nullable();
            $table->json('checkout_json')->nullable();
            $table->json('notification_json')->nullable();
            $table->json('social_json')->nullable();
            $table->timestamps();
        });

        Schema::create('products', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('store_id')->constrained()->cascadeOnDelete();
            $table->string('title');
            $table->string('handle');
            $table->text('description')->nullable();
            $table->string('vendor')->nullable()->index();
            $table->string('product_type')->nullable()->index();
            $table->json('tags')->nullable();
            $table->string('status')->default('draft')->index();
            $table->timestamp('published_at')->nullable();
            $table->unsignedInteger('sales_count')->default(0);
            $table->json('metadata')->nullable();
            $table->timestamps();
            $table->unique(['store_id', 'handle']);
            $table->index(['store_id', 'status']);
            $table->index(['store_id', 'published_at']);
        });

        Schema::create('product_options', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('product_id')->constrained()->cascadeOnDelete();
            $table->string('name');
            $table->unsignedInteger('position')->default(0);
            $table->timestamps();
            $table->unique(['product_id', 'position']);
        });

        Schema::create('product_option_values', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('product_option_id')->constrained()->cascadeOnDelete();
            $table->string('value');
            $table->unsignedInteger('position')->default(0);
            $table->timestamps();
            $table->unique(['product_option_id', 'position']);
        });

        Schema::create('product_variants', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('product_id')->constrained()->cascadeOnDelete();
            $table->string('title')->default('Default');
            $table->string('sku')->nullable()->index();
            $table->string('barcode')->nullable()->index();
            $table->unsignedInteger('price_amount');
            $table->unsignedInteger('compare_at_amount')->nullable();
            $table->unsignedInteger('cost_amount')->nullable();
            $table->unsignedInteger('weight_grams')->default(0);
            $table->boolean('requires_shipping')->default(true);
            $table->boolean('is_default')->default(false);
            $table->unsignedInteger('position')->default(0);
            $table->json('metadata')->nullable();
            $table->timestamps();
            $table->index(['product_id', 'position']);
            $table->index(['product_id', 'is_default']);
        });

        Schema::create('variant_option_values', function (Blueprint $table): void {
            $table->foreignId('variant_id')->constrained('product_variants')->cascadeOnDelete();
            $table->foreignId('product_option_value_id')->constrained()->cascadeOnDelete();
            $table->primary(['variant_id', 'product_option_value_id']);
            $table->index('product_option_value_id');
        });

        Schema::create('inventory_items', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('store_id')->constrained()->cascadeOnDelete();
            $table->foreignId('variant_id')->unique()->constrained('product_variants')->cascadeOnDelete();
            $table->integer('quantity_on_hand')->default(0);
            $table->integer('quantity_reserved')->default(0);
            $table->string('policy')->default('deny');
            $table->timestamps();
            $table->index('store_id');
        });

        Schema::create('collections', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('store_id')->constrained()->cascadeOnDelete();
            $table->string('title');
            $table->string('handle');
            $table->text('description')->nullable();
            $table->string('status')->default('active')->index();
            $table->string('image_url')->nullable();
            $table->timestamps();
            $table->unique(['store_id', 'handle']);
            $table->index(['store_id', 'status']);
        });

        Schema::create('collection_products', function (Blueprint $table): void {
            $table->foreignId('collection_id')->constrained()->cascadeOnDelete();
            $table->foreignId('product_id')->constrained()->cascadeOnDelete();
            $table->unsignedInteger('position')->default(0);
            $table->primary(['collection_id', 'product_id']);
            $table->index('product_id');
            $table->index(['collection_id', 'position']);
        });

        Schema::create('product_media', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('product_id')->constrained()->cascadeOnDelete();
            $table->string('path');
            $table->string('url')->nullable();
            $table->string('alt_text')->nullable();
            $table->string('status')->default('ready');
            $table->unsignedInteger('position')->default(0);
            $table->json('metadata')->nullable();
            $table->timestamps();
            $table->index(['product_id', 'position']);
            $table->index('status');
        });

        Schema::create('themes', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('store_id')->constrained()->cascadeOnDelete();
            $table->string('name');
            $table->string('status')->default('draft')->index();
            $table->string('version')->default('1.0.0');
            $table->json('settings')->nullable();
            $table->timestamps();
            $table->index(['store_id', 'status']);
        });

        Schema::create('theme_files', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('theme_id')->constrained()->cascadeOnDelete();
            $table->string('path');
            $table->longText('content')->nullable();
            $table->timestamps();
            $table->unique(['theme_id', 'path']);
        });

        Schema::create('theme_settings', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('theme_id')->constrained()->cascadeOnDelete();
            $table->string('key');
            $table->json('value')->nullable();
            $table->timestamps();
            $table->unique(['theme_id', 'key']);
        });

        Schema::create('pages', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('store_id')->constrained()->cascadeOnDelete();
            $table->string('title');
            $table->string('handle');
            $table->longText('content')->nullable();
            $table->string('status')->default('draft')->index();
            $table->timestamp('published_at')->nullable();
            $table->timestamps();
            $table->unique(['store_id', 'handle']);
        });

        Schema::create('navigation_menus', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('store_id')->constrained()->cascadeOnDelete();
            $table->string('name');
            $table->string('handle');
            $table->timestamps();
            $table->unique(['store_id', 'handle']);
        });

        Schema::create('navigation_items', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('navigation_menu_id')->constrained('navigation_menus')->cascadeOnDelete();
            $table->string('label');
            $table->string('type')->default('link');
            $table->string('url')->nullable();
            $table->unsignedBigInteger('resource_id')->nullable();
            $table->unsignedInteger('position')->default(0);
            $table->foreignId('parent_id')->nullable()->constrained('navigation_items')->nullOnDelete();
            $table->timestamps();
            $table->index(['navigation_menu_id', 'position']);
        });

        Schema::create('search_settings', function (Blueprint $table): void {
            $table->foreignId('store_id')->primary()->constrained()->cascadeOnDelete();
            $table->json('synonyms')->nullable();
            $table->json('stopwords')->nullable();
            $table->boolean('enabled')->default(true);
            $table->timestamps();
        });

        Schema::create('search_queries', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('store_id')->constrained()->cascadeOnDelete();
            $table->string('query');
            $table->unsignedInteger('results_count')->default(0);
            $table->foreignId('customer_id')->nullable()->constrained()->nullOnDelete();
            $table->timestamps();
            $table->index(['store_id', 'created_at']);
            $table->index(['store_id', 'query']);
        });

        Schema::create('shipping_zones', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('store_id')->constrained()->cascadeOnDelete();
            $table->string('name');
            $table->json('countries_json')->nullable();
            $table->json('regions_json')->nullable();
            $table->timestamps();
            $table->index('store_id');
        });

        Schema::create('shipping_rates', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('shipping_zone_id')->constrained()->cascadeOnDelete();
            $table->string('name');
            $table->string('type')->default('flat');
            $table->unsignedInteger('price_amount')->default(0);
            $table->string('currency', 3)->default('EUR');
            $table->json('config_json')->nullable();
            $table->boolean('is_active')->default(true);
            $table->unsignedInteger('estimated_days_min')->nullable();
            $table->unsignedInteger('estimated_days_max')->nullable();
            $table->timestamps();
            $table->index(['shipping_zone_id', 'is_active']);
        });

        Schema::create('tax_settings', function (Blueprint $table): void {
            $table->foreignId('store_id')->primary()->constrained()->cascadeOnDelete();
            $table->string('mode')->default('manual');
            $table->unsignedInteger('default_rate_basis_points')->default(0);
            $table->json('rates_json')->nullable();
            $table->json('provider_config_json')->nullable();
            $table->timestamps();
        });

        Schema::create('discounts', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('store_id')->constrained()->cascadeOnDelete();
            $table->string('code')->nullable();
            $table->string('type')->default('code');
            $table->string('value_type')->default('percent');
            $table->unsignedInteger('value_amount')->default(0);
            $table->string('status')->default('active')->index();
            $table->unsignedInteger('usage_limit')->nullable();
            $table->unsignedInteger('usage_count')->default(0);
            $table->timestamp('starts_at')->nullable();
            $table->timestamp('ends_at')->nullable();
            $table->json('rules_json')->nullable();
            $table->timestamps();
            $table->unique(['store_id', 'code']);
            $table->index(['store_id', 'type']);
        });

        Schema::create('customers', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('store_id')->constrained()->cascadeOnDelete();
            $table->string('first_name');
            $table->string('last_name');
            $table->string('email');
            $table->string('password_hash')->nullable();
            $table->string('status')->default('active')->index();
            $table->timestamp('email_verified_at')->nullable();
            $table->timestamp('last_login_at')->nullable();
            $table->rememberToken();
            $table->json('metadata')->nullable();
            $table->timestamps();
            $table->unique(['store_id', 'email']);
            $table->index('store_id');
        });

        Schema::create('customer_addresses', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('customer_id')->constrained()->cascadeOnDelete();
            $table->string('label')->nullable();
            $table->json('address_json');
            $table->boolean('is_default')->default(false);
            $table->timestamps();
            $table->index(['customer_id', 'is_default']);
        });

        Schema::create('carts', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('store_id')->constrained()->cascadeOnDelete();
            $table->foreignId('customer_id')->nullable()->constrained()->nullOnDelete();
            $table->string('currency', 3)->default('EUR');
            $table->unsignedInteger('cart_version')->default(1);
            $table->string('status')->default('active')->index();
            $table->timestamps();
            $table->index('store_id');
            $table->index('customer_id');
        });

        Schema::create('cart_lines', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('cart_id')->constrained()->cascadeOnDelete();
            $table->foreignId('variant_id')->constrained('product_variants')->restrictOnDelete();
            $table->unsignedInteger('quantity');
            $table->unsignedInteger('unit_price_amount');
            $table->unsignedInteger('line_subtotal_amount');
            $table->unsignedInteger('line_discount_amount')->default(0);
            $table->unsignedInteger('line_total_amount');
            $table->timestamps();
            $table->unique(['cart_id', 'variant_id']);
            $table->index('cart_id');
        });

        Schema::create('checkouts', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('store_id')->constrained()->cascadeOnDelete();
            $table->foreignId('cart_id')->constrained()->restrictOnDelete();
            $table->foreignId('customer_id')->nullable()->constrained()->nullOnDelete();
            $table->string('status')->default('started')->index();
            $table->string('email');
            $table->json('shipping_address_json')->nullable();
            $table->json('billing_address_json')->nullable();
            $table->foreignId('shipping_rate_id')->nullable()->constrained('shipping_rates')->nullOnDelete();
            $table->string('discount_code')->nullable();
            $table->json('totals_json')->nullable();
            $table->json('tax_provider_snapshot_json')->nullable();
            $table->timestamp('expires_at')->nullable()->index();
            $table->timestamps();
            $table->index('cart_id');
            $table->index('customer_id');
        });

        Schema::create('orders', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('store_id')->constrained()->cascadeOnDelete();
            $table->foreignId('customer_id')->nullable()->constrained()->nullOnDelete();
            $table->foreignId('checkout_id')->nullable()->constrained()->nullOnDelete();
            $table->string('order_number');
            $table->string('currency', 3)->default('EUR');
            $table->string('status')->default('pending')->index();
            $table->string('financial_status')->default('pending')->index();
            $table->string('fulfillment_status')->default('unfulfilled')->index();
            $table->string('email');
            $table->json('shipping_address_json')->nullable();
            $table->json('billing_address_json')->nullable();
            $table->unsignedInteger('subtotal_amount')->default(0);
            $table->unsignedInteger('discount_amount')->default(0);
            $table->unsignedInteger('shipping_amount')->default(0);
            $table->unsignedInteger('tax_amount')->default(0);
            $table->unsignedInteger('total_amount')->default(0);
            $table->timestamp('placed_at')->nullable()->index();
            $table->json('metadata')->nullable();
            $table->timestamps();
            $table->unique(['store_id', 'order_number']);
            $table->index(['store_id', 'status']);
            $table->index(['store_id', 'financial_status']);
            $table->index(['store_id', 'fulfillment_status']);
        });

        Schema::create('order_lines', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('order_id')->constrained()->cascadeOnDelete();
            $table->foreignId('product_id')->nullable()->constrained()->nullOnDelete();
            $table->foreignId('variant_id')->nullable()->constrained('product_variants')->nullOnDelete();
            $table->string('product_title');
            $table->string('variant_title')->nullable();
            $table->string('sku')->nullable();
            $table->unsignedInteger('quantity');
            $table->unsignedInteger('unit_price_amount');
            $table->unsignedInteger('line_subtotal_amount');
            $table->unsignedInteger('line_discount_amount')->default(0);
            $table->unsignedInteger('line_total_amount');
            $table->json('tax_lines_json')->nullable();
            $table->json('discount_allocations_json')->nullable();
            $table->timestamps();
            $table->index('order_id');
        });

        Schema::create('payments', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('order_id')->constrained()->cascadeOnDelete();
            $table->string('provider')->default('mock');
            $table->string('provider_payment_id')->nullable();
            $table->string('method');
            $table->string('status')->default('pending')->index();
            $table->unsignedInteger('amount');
            $table->text('raw_json_encrypted')->nullable();
            $table->timestamps();
            $table->index(['provider', 'provider_payment_id']);
            $table->index('order_id');
        });

        Schema::create('refunds', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('order_id')->constrained()->cascadeOnDelete();
            $table->foreignId('payment_id')->nullable()->constrained()->nullOnDelete();
            $table->unsignedInteger('amount');
            $table->string('status')->default('pending');
            $table->text('reason')->nullable();
            $table->boolean('restock')->default(false);
            $table->timestamps();
            $table->index(['order_id', 'status']);
        });

        Schema::create('fulfillments', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('order_id')->constrained()->cascadeOnDelete();
            $table->string('status')->default('pending')->index();
            $table->string('tracking_company')->nullable();
            $table->string('tracking_number')->nullable();
            $table->text('tracking_url')->nullable();
            $table->timestamp('fulfilled_at')->nullable();
            $table->timestamps();
            $table->index(['tracking_company', 'tracking_number']);
        });

        Schema::create('fulfillment_lines', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('fulfillment_id')->constrained()->cascadeOnDelete();
            $table->foreignId('order_line_id')->constrained()->cascadeOnDelete();
            $table->unsignedInteger('quantity');
            $table->timestamps();
            $table->unique(['fulfillment_id', 'order_line_id']);
        });

        Schema::create('analytics_events', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('store_id')->constrained()->cascadeOnDelete();
            $table->string('type');
            $table->string('session_id')->nullable()->index();
            $table->foreignId('customer_id')->nullable()->constrained()->nullOnDelete();
            $table->string('client_event_id')->nullable();
            $table->json('payload')->nullable();
            $table->timestamps();
            $table->unique(['store_id', 'client_event_id']);
            $table->index(['store_id', 'type']);
            $table->index(['store_id', 'created_at']);
        });

        Schema::create('analytics_daily', function (Blueprint $table): void {
            $table->foreignId('store_id')->constrained()->cascadeOnDelete();
            $table->date('date');
            $table->unsignedInteger('orders_count')->default(0);
            $table->unsignedInteger('revenue_amount')->default(0);
            $table->unsignedInteger('aov_amount')->default(0);
            $table->unsignedInteger('visits_count')->default(0);
            $table->unsignedInteger('add_to_cart_count')->default(0);
            $table->unsignedInteger('checkout_started_count')->default(0);
            $table->primary(['store_id', 'date']);
        });

        Schema::create('apps', function (Blueprint $table): void {
            $table->id();
            $table->string('name');
            $table->string('slug')->unique();
            $table->text('description')->nullable();
            $table->string('status')->default('active');
            $table->json('scopes')->nullable();
            $table->timestamps();
        });

        Schema::create('app_installations', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('store_id')->constrained()->cascadeOnDelete();
            $table->foreignId('app_id')->constrained()->cascadeOnDelete();
            $table->string('status')->default('active');
            $table->json('config')->nullable();
            $table->timestamps();
            $table->unique(['store_id', 'app_id']);
        });

        Schema::create('oauth_clients', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('store_id')->constrained()->cascadeOnDelete();
            $table->string('name');
            $table->string('client_id')->unique();
            $table->text('client_secret_encrypted');
            $table->text('redirect_uris');
            $table->timestamps();
        });

        Schema::create('oauth_tokens', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('oauth_client_id')->constrained()->cascadeOnDelete();
            $table->foreignId('user_id')->nullable()->constrained()->nullOnDelete();
            $table->string('token_hash')->unique();
            $table->json('scopes')->nullable();
            $table->timestamp('expires_at')->nullable();
            $table->timestamp('revoked_at')->nullable();
            $table->timestamps();
        });

        Schema::create('webhook_subscriptions', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('store_id')->constrained()->cascadeOnDelete();
            $table->string('event');
            $table->text('target_url');
            $table->text('secret_encrypted');
            $table->string('status')->default('active');
            $table->unsignedInteger('consecutive_failures')->default(0);
            $table->timestamps();
            $table->index(['store_id', 'event']);
        });

        Schema::create('webhook_deliveries', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('webhook_subscription_id')->constrained()->cascadeOnDelete();
            $table->string('event');
            $table->json('payload');
            $table->unsignedInteger('attempts')->default(0);
            $table->unsignedSmallInteger('response_status')->nullable();
            $table->text('response_body')->nullable();
            $table->timestamp('delivered_at')->nullable();
            $table->timestamp('next_attempt_at')->nullable();
            $table->timestamps();
        });
    }

    public function down(): void
    {
        foreach ([
            'webhook_deliveries', 'webhook_subscriptions', 'oauth_tokens', 'oauth_clients',
            'app_installations', 'apps', 'analytics_daily', 'analytics_events',
            'fulfillment_lines', 'fulfillments', 'refunds', 'payments', 'order_lines', 'orders',
            'checkouts', 'cart_lines', 'carts', 'discounts', 'tax_settings', 'shipping_rates',
            'shipping_zones', 'search_queries', 'search_settings', 'navigation_items',
            'navigation_menus', 'pages', 'theme_settings', 'theme_files', 'themes',
            'product_media', 'collection_products', 'collections', 'inventory_items',
            'variant_option_values', 'product_variants', 'product_option_values', 'product_options',
            'products', 'customer_addresses', 'customers', 'store_settings', 'store_users',
            'store_domains', 'stores', 'organizations',
        ] as $table) {
            Schema::dropIfExists($table);
        }

        Schema::table('users', function (Blueprint $table): void {
            $table->dropColumn(['status', 'last_login_at']);
        });
    }
};

stdout:
Success. Updated the following files:
A /Users/wesner/Herd/shop/database/migrations/2026_08_20_000000_create_shop_schema.php


text:
Script completed
Wall time 0.0 seconds
Output:


exec

status: completed

input:
const patch = "*** Begin Patch\n*** Add File: /Users/wesner/Herd/shop/app/Models/Scopes/StoreScope.php\n+<?php\n+\n+namespace App\\Models\\Scopes;\n+\n+use Illuminate\\Database\\Eloquent\\Builder;\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Scope;\n+\n+class StoreScope implements Scope\n+{\n+    public function apply(Builder $builder, Model $model): void\n+    {\n+        if (app()->bound('current_store')) {\n+            $builder->where($model->qualifyColumn('store_id'), app('current_store')->getKey());\n+        }\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/Concerns/BelongsToStore.php\n+<?php\n+\n+namespace App\\Models\\Concerns;\n+\n+use App\\Models\\Scopes\\StoreScope;\n+use App\\Models\\Store;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+\n+trait BelongsToStore\n+{\n+    protected static function bootBelongsToStore(): void\n+    {\n+        static::addGlobalScope(new StoreScope());\n+\n+        static::creating(function (self $model): void {\n+            if (app()->bound('current_store') && blank($model->store_id)) {\n+                $model->store_id = app('current_store')->getKey();\n+            }\n+        });\n+    }\n+\n+    public function store(): BelongsTo\n+    {\n+        return $this->belongsTo(Store::class);\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/Organization.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\HasMany;\n+\n+class Organization extends Model\n+{\n+    use HasFactory;\n+\n+    protected $fillable = ['name', 'slug', 'billing_email', 'status'];\n+\n+    public function stores(): HasMany\n+    {\n+        return $this->hasMany(Store::class);\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/Store.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use App\\Enums\\StoreStatus;\n+use Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\n+use Illuminate\\Database\\Eloquent\\Relations\\HasMany;\n+use Illuminate\\Database\\Eloquent\\Relations\\HasOne;\n+\n+class Store extends Model\n+{\n+    use HasFactory;\n+\n+    protected $fillable = ['organization_id', 'name', 'handle', 'status', 'default_currency', 'default_locale', 'timezone', 'primary_domain', 'metadata'];\n+\n+    protected function casts(): array\n+    {\n+        return ['status' => StoreStatus::class, 'metadata' => 'array'];\n+    }\n+\n+    public function organization(): BelongsTo\n+    {\n+        return $this->belongsTo(Organization::class);\n+    }\n+\n+    public function domains(): HasMany\n+    {\n+        return $this->hasMany(StoreDomain::class);\n+    }\n+\n+    public function users(): BelongsToMany\n+    {\n+        return $this->belongsToMany(User::class, 'store_users')->using(StoreUser::class)->withPivot('role')->withTimestamps();\n+    }\n+\n+    public function settings(): HasOne\n+    {\n+        return $this->hasOne(StoreSettings::class);\n+    }\n+\n+    public function isActive(): bool\n+    {\n+        return $this->status === StoreStatus::Active;\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/StoreDomain.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use App\\Enums\\StoreDomainType;\n+use Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+\n+class StoreDomain extends Model\n+{\n+    use HasFactory;\n+\n+    protected $fillable = ['store_id', 'hostname', 'type', 'is_primary'];\n+\n+    protected function casts(): array\n+    {\n+        return ['type' => StoreDomainType::class, 'is_primary' => 'boolean'];\n+    }\n+\n+    public function store(): BelongsTo\n+    {\n+        return $this->belongsTo(Store::class);\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/StoreUser.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use App\\Enums\\StoreUserRole;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+use Illuminate\\Database\\Eloquent\\Relations\\Pivot;\n+\n+class StoreUser extends Pivot\n+{\n+    public $incrementing = false;\n+\n+    protected $table = 'store_users';\n+\n+    protected $fillable = ['store_id', 'user_id', 'role'];\n+\n+    protected function casts(): array\n+    {\n+        return ['role' => StoreUserRole::class];\n+    }\n+\n+    public function store(): BelongsTo\n+    {\n+        return $this->belongsTo(Store::class);\n+    }\n+\n+    public function user(): BelongsTo\n+    {\n+        return $this->belongsTo(User::class);\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/StoreSettings.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+\n+class StoreSettings extends Model\n+{\n+    protected $primaryKey = 'store_id';\n+\n+    public $incrementing = false;\n+\n+    protected $keyType = 'int';\n+\n+    protected $fillable = ['store_id', 'general_json', 'checkout_json', 'notification_json', 'social_json'];\n+\n+    protected function casts(): array\n+    {\n+        return ['general_json' => 'array', 'checkout_json' => 'array', 'notification_json' => 'array', 'social_json' => 'array'];\n+    }\n+\n+    public function store(): BelongsTo\n+    {\n+        return $this->belongsTo(Store::class);\n+    }\n+}\n*** Update File: /Users/wesner/Herd/shop/app/Models/User.php\n@@\n namespace App\\Models;\n \n+use App\\Enums\\StoreUserRole;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\n@@\n     protected $fillable = [\n         'name',\n         'email',\n         'password',\n+        'status',\n+        'last_login_at',\n@@\n         return [\n             'email_verified_at' => 'datetime',\n             'password' => 'hashed',\n+            'last_login_at' => 'datetime',\n         ];\n     }\n+\n+    public function stores(): BelongsToMany\n+    {\n+        return $this->belongsToMany(Store::class, 'store_users')->using(StoreUser::class)->withPivot('role')->withTimestamps();\n+    }\n+\n+    public function roleForStore(Store $store): ?StoreUserRole\n+    {\n+        $pivot = $this->stores()->whereKey($store->getKey())->first()?->pivot;\n+\n+        return $pivot?->role instanceof StoreUserRole ? $pivot->role : ($pivot?->role ? StoreUserRole::tryFrom($pivot->role) : null);\n+    }\n+\n+    public function canManageStore(Store $store): bool\n+    {\n+        return in_array($this->roleForStore($store), [StoreUserRole::Owner, StoreUserRole::Admin], true);\n+    }\n*** End Patch";
text(await tools.apply_patch(patch));


type: FileChange

type: add

content:
<?php

namespace App\Models;

use App\Enums\StoreStatus;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;

class Store extends Model
{
    use HasFactory;

    protected $fillable = ['organization_id', 'name', 'handle', 'status', 'default_currency', 'default_locale', 'timezone', 'primary_domain', 'metadata'];

    protected function casts(): array
    {
        return ['status' => StoreStatus::class, 'metadata' => 'array'];
    }

    public function organization(): BelongsTo
    {
        return $this->belongsTo(Organization::class);
    }

    public function domains(): HasMany
    {
        return $this->hasMany(StoreDomain::class);
    }

    public function users(): BelongsToMany
    {
        return $this->belongsToMany(User::class, 'store_users')->using(StoreUser::class)->withPivot('role')->withTimestamps();
    }

    public function settings(): HasOne
    {
        return $this->hasOne(StoreSettings::class);
    }

    public function isActive(): bool
    {
        return $this->status === StoreStatus::Active;
    }
}

type: update

unified_diff:
@@ -4,2 +4,4 @@

+use App\Enums\StoreUserRole;
+use Illuminate\Database\Eloquent\Relations\BelongsToMany;
 // use Illuminate\Contracts\Auth\MustVerifyEmail;
@@ -25,2 +27,4 @@
         'password',
+        'status',
+        'last_login_at',
     ];
@@ -49,2 +53,3 @@
             'password' => 'hashed',
+            'last_login_at' => 'datetime',
         ];
@@ -52,2 +57,19 @@

+    public function stores(): BelongsToMany
+    {
+        return $this->belongsToMany(Store::class, 'store_users')->using(StoreUser::class)->withPivot('role')->withTimestamps();
+    }
+
+    public function roleForStore(Store $store): ?StoreUserRole
+    {
+        $pivot = $this->stores()->whereKey($store->getKey())->first()?->pivot;
+
+        return $pivot?->role instanceof StoreUserRole ? $pivot->role : ($pivot?->role ? StoreUserRole::tryFrom($pivot->role) : null);
+    }
+
+    public function canManageStore(Store $store): bool
+    {
+        return in_array($this->roleForStore($store), [StoreUserRole::Owner, StoreUserRole::Admin], true);
+    }
+
     /**

content:
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class StoreSettings extends Model
{
    protected $primaryKey = 'store_id';

    public $incrementing = false;

    protected $keyType = 'int';

    protected $fillable = ['store_id', 'general_json', 'checkout_json', 'notification_json', 'social_json'];

    protected function casts(): array
    {
        return ['general_json' => 'array', 'checkout_json' => 'array', 'notification_json' => 'array', 'social_json' => 'array'];
    }

    public function store(): BelongsTo
    {
        return $this->belongsTo(Store::class);
    }
}

content:
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Organization extends Model
{
    use HasFactory;

    protected $fillable = ['name', 'slug', 'billing_email', 'status'];

    public function stores(): HasMany
    {
        return $this->hasMany(Store::class);
    }
}

content:
<?php

namespace App\Models;

use App\Enums\StoreDomainType;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class StoreDomain extends Model
{
    use HasFactory;

    protected $fillable = ['store_id', 'hostname', 'type', 'is_primary'];

    protected function casts(): array
    {
        return ['type' => StoreDomainType::class, 'is_primary' => 'boolean'];
    }

    public function store(): BelongsTo
    {
        return $this->belongsTo(Store::class);
    }
}

content:
<?php

namespace App\Models;

use App\Enums\StoreUserRole;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\Pivot;

class StoreUser extends Pivot
{
    public $incrementing = false;

    protected $table = 'store_users';

    protected $fillable = ['store_id', 'user_id', 'role'];

    protected function casts(): array
    {
        return ['role' => StoreUserRole::class];
    }

    public function store(): BelongsTo
    {
        return $this->belongsTo(Store::class);
    }

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }
}

content:
<?php

namespace App\Models\Concerns;

use App\Models\Scopes\StoreScope;
use App\Models\Store;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

trait BelongsToStore
{
    protected static function bootBelongsToStore(): void
    {
        static::addGlobalScope(new StoreScope());

        static::creating(function (self $model): void {
            if (app()->bound('current_store') && blank($model->store_id)) {
                $model->store_id = app('current_store')->getKey();
            }
        });
    }

    public function store(): BelongsTo
    {
        return $this->belongsTo(Store::class);
    }
}

content:
<?php

namespace App\Models\Scopes;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;

class StoreScope implements Scope
{
    public function apply(Builder $builder, Model $model): void
    {
        if (app()->bound('current_store')) {
            $builder->where($model->qualifyColumn('store_id'), app('current_store')->getKey());
        }
    }
}

status: completed

stdout:
Success. Updated the following files:
A /Users/wesner/Herd/shop/app/Models/Scopes/StoreScope.php
A /Users/wesner/Herd/shop/app/Models/Concerns/BelongsToStore.php
A /Users/wesner/Herd/shop/app/Models/Organization.php
A /Users/wesner/Herd/shop/app/Models/Store.php
A /Users/wesner/Herd/shop/app/Models/StoreDomain.php
A /Users/wesner/Herd/shop/app/Models/StoreUser.php
A /Users/wesner/Herd/shop/app/Models/StoreSettings.php
M /Users/wesner/Herd/shop/app/Models/User.php


text:
Script completed
Wall time 0.0 seconds
Output:


status: completed

input:
const patch = "*** Begin Patch\n*** Add File: /Users/wesner/Herd/shop/app/Models/Product.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use App\\Enums\\ProductStatus;\n+use App\\Models\\Concerns\\BelongsToStore;\n+use Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\n+use Illuminate\\Database\\Eloquent\\Relations\\HasMany;\n+\n+class Product extends Model\n+{\n+    use BelongsToStore, HasFactory;\n+\n+    protected $fillable = ['store_id', 'title', 'handle', 'description', 'vendor', 'product_type', 'tags', 'status', 'published_at', 'sales_count', 'metadata'];\n+\n+    protected function casts(): array\n+    {\n+        return ['status' => ProductStatus::class, 'tags' => 'array', 'metadata' => 'array', 'published_at' => 'datetime'];\n+    }\n+\n+    public function variants(): HasMany\n+    {\n+        return $this->hasMany(ProductVariant::class)->orderBy('position');\n+    }\n+\n+    public function options(): HasMany\n+    {\n+        return $this->hasMany(ProductOption::class)->orderBy('position');\n+    }\n+\n+    public function media(): HasMany\n+    {\n+        return $this->hasMany(ProductMedia::class)->orderBy('position');\n+    }\n+\n+    public function collections(): BelongsToMany\n+    {\n+        return $this->belongsToMany(Collection::class, 'collection_products')->withPivot('position');\n+    }\n+\n+    public function scopePublished($query): void\n+    {\n+        $query->where('status', ProductStatus::Active)->whereNotNull('published_at')->where('published_at', '<=', now());\n+    }\n+\n+    public function defaultVariant(): ?ProductVariant\n+    {\n+        return $this->variants->firstWhere('is_default', true) ?? $this->variants->first();\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/ProductOption.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+use Illuminate\\Database\\Eloquent\\Relations\\HasMany;\n+\n+class ProductOption extends Model\n+{\n+    protected $fillable = ['product_id', 'name', 'position'];\n+\n+    public function product(): BelongsTo\n+    {\n+        return $this->belongsTo(Product::class);\n+    }\n+\n+    public function values(): HasMany\n+    {\n+        return $this->hasMany(ProductOptionValue::class)->orderBy('position');\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/ProductOptionValue.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\n+\n+class ProductOptionValue extends Model\n+{\n+    protected $fillable = ['product_option_id', 'value', 'position'];\n+\n+    public function option(): BelongsTo\n+    {\n+        return $this->belongsTo(ProductOption::class, 'product_option_id');\n+    }\n+\n+    public function variants(): BelongsToMany\n+    {\n+        return $this->belongsToMany(ProductVariant::class, 'variant_option_values');\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/ProductVariant.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\n+use Illuminate\\Database\\Eloquent\\Relations\\HasOne;\n+\n+class ProductVariant extends Model\n+{\n+    protected $fillable = ['product_id', 'title', 'sku', 'barcode', 'price_amount', 'compare_at_amount', 'cost_amount', 'weight_grams', 'requires_shipping', 'is_default', 'position', 'metadata'];\n+\n+    protected function casts(): array\n+    {\n+        return ['requires_shipping' => 'boolean', 'is_default' => 'boolean', 'metadata' => 'array'];\n+    }\n+\n+    public function product(): BelongsTo\n+    {\n+        return $this->belongsTo(Product::class);\n+    }\n+\n+    public function inventory(): HasOne\n+    {\n+        return $this->hasOne(InventoryItem::class, 'variant_id');\n+    }\n+\n+    public function optionValues(): BelongsToMany\n+    {\n+        return $this->belongsToMany(ProductOptionValue::class, 'variant_option_values');\n+    }\n+\n+    public function availableQuantity(): int\n+    {\n+        $inventory = $this->inventory;\n+\n+        return $inventory ? $inventory->availableQuantity() : 0;\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/InventoryItem.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use App\\Enums\\InventoryPolicy;\n+use App\\Models\\Concerns\\BelongsToStore;\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+\n+class InventoryItem extends Model\n+{\n+    use BelongsToStore;\n+\n+    protected $fillable = ['store_id', 'variant_id', 'quantity_on_hand', 'quantity_reserved', 'policy'];\n+\n+    protected function casts(): array\n+    {\n+        return ['policy' => InventoryPolicy::class];\n+    }\n+\n+    public function variant(): BelongsTo\n+    {\n+        return $this->belongsTo(ProductVariant::class, 'variant_id');\n+    }\n+\n+    public function availableQuantity(): int\n+    {\n+        return $this->quantity_on_hand - $this->quantity_reserved;\n+    }\n+\n+    public function canSell(int $quantity): bool\n+    {\n+        return $this->policy === InventoryPolicy::Continue || $this->availableQuantity() >= $quantity;\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/Collection.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use App\\Enums\\CollectionStatus;\n+use App\\Models\\Concerns\\BelongsToStore;\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\n+\n+class Collection extends Model\n+{\n+    use BelongsToStore;\n+\n+    protected $fillable = ['store_id', 'title', 'handle', 'description', 'status', 'image_url'];\n+\n+    protected function casts(): array\n+    {\n+        return ['status' => CollectionStatus::class];\n+    }\n+\n+    public function products(): BelongsToMany\n+    {\n+        return $this->belongsToMany(Product::class, 'collection_products')->withPivot('position')->orderBy('collection_products.position');\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/ProductMedia.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+\n+class ProductMedia extends Model\n+{\n+    protected $fillable = ['product_id', 'path', 'url', 'alt_text', 'status', 'position', 'metadata'];\n+\n+    protected function casts(): array\n+    {\n+        return ['metadata' => 'array'];\n+    }\n+\n+    public function product(): BelongsTo\n+    {\n+        return $this->belongsTo(Product::class);\n+    }\n+}\n*** End Patch";
text(await tools.apply_patch(patch));


content:
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class ProductMedia extends Model
{
    protected $fillable = ['product_id', 'path', 'url', 'alt_text', 'status', 'position', 'metadata'];

    protected function casts(): array
    {
        return ['metadata' => 'array'];
    }

    public function product(): BelongsTo
    {
        return $this->belongsTo(Product::class);
    }
}

content:
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasOne;

class ProductVariant extends Model
{
    protected $fillable = ['product_id', 'title', 'sku', 'barcode', 'price_amount', 'compare_at_amount', 'cost_amount', 'weight_grams', 'requires_shipping', 'is_default', 'position', 'metadata'];

    protected function casts(): array
    {
        return ['requires_shipping' => 'boolean', 'is_default' => 'boolean', 'metadata' => 'array'];
    }

    public function product(): BelongsTo
    {
        return $this->belongsTo(Product::class);
    }

    public function inventory(): HasOne
    {
        return $this->hasOne(InventoryItem::class, 'variant_id');
    }

    public function optionValues(): BelongsToMany
    {
        return $this->belongsToMany(ProductOptionValue::class, 'variant_option_values');
    }

    public function availableQuantity(): int
    {
        $inventory = $this->inventory;

        return $inventory ? $inventory->availableQuantity() : 0;
    }
}

content:
<?php

namespace App\Models;

use App\Enums\InventoryPolicy;
use App\Models\Concerns\BelongsToStore;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class InventoryItem extends Model
{
    use BelongsToStore;

    protected $fillable = ['store_id', 'variant_id', 'quantity_on_hand', 'quantity_reserved', 'policy'];

    protected function casts(): array
    {
        return ['policy' => InventoryPolicy::class];
    }

    public function variant(): BelongsTo
    {
        return $this->belongsTo(ProductVariant::class, 'variant_id');
    }

    public function availableQuantity(): int
    {
        return $this->quantity_on_hand - $this->quantity_reserved;
    }

    public function canSell(int $quantity): bool
    {
        return $this->policy === InventoryPolicy::Continue || $this->availableQuantity() >= $quantity;
    }
}

content:
<?php

namespace App\Models;

use App\Enums\ProductStatus;
use App\Models\Concerns\BelongsToStore;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Product extends Model
{
    use BelongsToStore, HasFactory;

    protected $fillable = ['store_id', 'title', 'handle', 'description', 'vendor', 'product_type', 'tags', 'status', 'published_at', 'sales_count', 'metadata'];

    protected function casts(): array
    {
        return ['status' => ProductStatus::class, 'tags' => 'array', 'metadata' => 'array', 'published_at' => 'datetime'];
    }

    public function variants(): HasMany
    {
        return $this->hasMany(ProductVariant::class)->orderBy('position');
    }

    public function options(): HasMany
    {
        return $this->hasMany(ProductOption::class)->orderBy('position');
    }

    public function media(): HasMany
    {
        return $this->hasMany(ProductMedia::class)->orderBy('position');
    }

    public function collections(): BelongsToMany
    {
        return $this->belongsToMany(Collection::class, 'collection_products')->withPivot('position');
    }

    public function scopePublished($query): void
    {
        $query->where('status', ProductStatus::Active)->whereNotNull('published_at')->where('published_at', '<=', now());
    }

    public function defaultVariant(): ?ProductVariant
    {
        return $this->variants->firstWhere('is_default', true) ?? $this->variants->first();
    }
}

content:
<?php

namespace App\Models;

use App\Enums\CollectionStatus;
use App\Models\Concerns\BelongsToStore;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class Collection extends Model
{
    use BelongsToStore;

    protected $fillable = ['store_id', 'title', 'handle', 'description', 'status', 'image_url'];

    protected function casts(): array
    {
        return ['status' => CollectionStatus::class];
    }

    public function products(): BelongsToMany
    {
        return $this->belongsToMany(Product::class, 'collection_products')->withPivot('position')->orderBy('collection_products.position');
    }
}

content:
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;

class ProductOption extends Model
{
    protected $fillable = ['product_id', 'name', 'position'];

    public function product(): BelongsTo
    {
        return $this->belongsTo(Product::class);
    }

    public function values(): HasMany
    {
        return $this->hasMany(ProductOptionValue::class)->orderBy('position');
    }
}

content:
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class ProductOptionValue extends Model
{
    protected $fillable = ['product_option_id', 'value', 'position'];

    public function option(): BelongsTo
    {
        return $this->belongsTo(ProductOption::class, 'product_option_id');
    }

    public function variants(): BelongsToMany
    {
        return $this->belongsToMany(ProductVariant::class, 'variant_option_values');
    }
}

stdout:
Success. Updated the following files:
A /Users/wesner/Herd/shop/app/Models/Product.php
A /Users/wesner/Herd/shop/app/Models/ProductOption.php
A /Users/wesner/Herd/shop/app/Models/ProductOptionValue.php
A /Users/wesner/Herd/shop/app/Models/ProductVariant.php
A /Users/wesner/Herd/shop/app/Models/InventoryItem.php
A /Users/wesner/Herd/shop/app/Models/Collection.php
A /Users/wesner/Herd/shop/app/Models/ProductMedia.php


text:
Script completed
Wall time 0.0 seconds
Output:


status: completed

input:
const patch = "*** Begin Patch\n*** Add File: /Users/wesner/Herd/shop/app/Models/Customer.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use App\\Models\\Concerns\\BelongsToStore;\n+use Illuminate\\Auth\\Authenticatable as AuthenticatableTrait;\n+use Illuminate\\Contracts\\Auth\\Authenticatable;\n+use Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Notifications\\Notifiable;\n+use Illuminate\\Database\\Eloquent\\Relations\\HasMany;\n+\n+class Customer extends Model implements Authenticatable\n+{\n+    use AuthenticatableTrait, BelongsToStore, HasFactory, Notifiable;\n+\n+    protected $fillable = ['store_id', 'first_name', 'last_name', 'email', 'password_hash', 'status', 'email_verified_at', 'metadata'];\n+\n+    protected $hidden = ['password_hash', 'remember_token'];\n+\n+    protected function casts(): array\n+    {\n+        return ['email_verified_at' => 'datetime', 'metadata' => 'array', 'password_hash' => 'hashed'];\n+    }\n+\n+    public function getAuthPasswordName(): string\n+    {\n+        return 'password_hash';\n+    }\n+\n+    public function getAuthPassword(): ?string\n+    {\n+        return $this->password_hash;\n+    }\n+\n+    public function getNameAttribute(): string\n+    {\n+        return trim($this->first_name.' '.$this->last_name);\n+    }\n+\n+    public function addresses(): HasMany\n+    {\n+        return $this->hasMany(CustomerAddress::class);\n+    }\n+\n+    public function orders(): HasMany\n+    {\n+        return $this->hasMany(Order::class);\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/CustomerAddress.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+\n+class CustomerAddress extends Model\n+{\n+    protected $fillable = ['customer_id', 'label', 'address_json', 'is_default'];\n+\n+    protected function casts(): array\n+    {\n+        return ['address_json' => 'array', 'is_default' => 'boolean'];\n+    }\n+\n+    public function customer(): BelongsTo\n+    {\n+        return $this->belongsTo(Customer::class);\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/Cart.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use App\\Enums\\CartStatus;\n+use App\\Models\\Concerns\\BelongsToStore;\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+use Illuminate\\Database\\Eloquent\\Relations\\HasMany;\n+\n+class Cart extends Model\n+{\n+    use BelongsToStore;\n+\n+    protected $fillable = ['store_id', 'customer_id', 'currency', 'cart_version', 'status'];\n+\n+    protected function casts(): array\n+    {\n+        return ['status' => CartStatus::class];\n+    }\n+\n+    public function customer(): BelongsTo\n+    {\n+        return $this->belongsTo(Customer::class);\n+    }\n+\n+    public function lines(): HasMany\n+    {\n+        return $this->hasMany(CartLine::class);\n+    }\n+\n+    public function subtotalAmount(): int\n+    {\n+        return (int) $this->lines->sum('line_total_amount');\n+    }\n+\n+    public function itemCount(): int\n+    {\n+        return (int) $this->lines->sum('quantity');\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/CartLine.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+\n+class CartLine extends Model\n+{\n+    protected $fillable = ['cart_id', 'variant_id', 'quantity', 'unit_price_amount', 'line_subtotal_amount', 'line_discount_amount', 'line_total_amount'];\n+\n+    public function cart(): BelongsTo\n+    {\n+        return $this->belongsTo(Cart::class);\n+    }\n+\n+    public function variant(): BelongsTo\n+    {\n+        return $this->belongsTo(ProductVariant::class, 'variant_id')->with(['product', 'inventory']);\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/Checkout.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use App\\Enums\\CheckoutStatus;\n+use App\\Models\\Concerns\\BelongsToStore;\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+\n+class Checkout extends Model\n+{\n+    use BelongsToStore;\n+\n+    protected $fillable = ['store_id', 'cart_id', 'customer_id', 'status', 'email', 'shipping_address_json', 'billing_address_json', 'shipping_rate_id', 'discount_code', 'totals_json', 'tax_provider_snapshot_json', 'expires_at'];\n+\n+    protected function casts(): array\n+    {\n+        return ['status' => CheckoutStatus::class, 'shipping_address_json' => 'array', 'billing_address_json' => 'array', 'totals_json' => 'array', 'tax_provider_snapshot_json' => 'array', 'expires_at' => 'datetime'];\n+    }\n+\n+    public function cart(): BelongsTo\n+    {\n+        return $this->belongsTo(Cart::class);\n+    }\n+\n+    public function customer(): BelongsTo\n+    {\n+        return $this->belongsTo(Customer::class);\n+    }\n+\n+    public function shippingRate(): BelongsTo\n+    {\n+        return $this->belongsTo(ShippingRate::class);\n+    }\n+\n+    public function isExpired(): bool\n+    {\n+        return $this->expires_at !== null && $this->expires_at->isPast();\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/ShippingZone.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use App\\Models\\Concerns\\BelongsToStore;\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\HasMany;\n+\n+class ShippingZone extends Model\n+{\n+    use BelongsToStore;\n+\n+    protected $fillable = ['store_id', 'name', 'countries_json', 'regions_json'];\n+\n+    protected function casts(): array\n+    {\n+        return ['countries_json' => 'array', 'regions_json' => 'array'];\n+    }\n+\n+    public function rates(): HasMany\n+    {\n+        return $this->hasMany(ShippingRate::class);\n+    }\n+\n+    public function matchesCountry(string $countryCode): bool\n+    {\n+        $countries = $this->countries_json ?? [];\n+\n+        return $countries === [] || in_array(strtoupper($countryCode), array_map('strtoupper', $countries), true);\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/ShippingRate.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+\n+class ShippingRate extends Model\n+{\n+    protected $fillable = ['shipping_zone_id', 'name', 'type', 'price_amount', 'currency', 'config_json', 'is_active', 'estimated_days_min', 'estimated_days_max'];\n+\n+    protected function casts(): array\n+    {\n+        return ['config_json' => 'array', 'is_active' => 'boolean'];\n+    }\n+\n+    public function zone(): BelongsTo\n+    {\n+        return $this->belongsTo(ShippingZone::class, 'shipping_zone_id');\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/TaxSettings.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use App\\Models\\Concerns\\BelongsToStore;\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+\n+class TaxSettings extends Model\n+{\n+    use BelongsToStore;\n+\n+    protected $primaryKey = 'store_id';\n+\n+    public $incrementing = false;\n+\n+    protected $fillable = ['store_id', 'mode', 'default_rate_basis_points', 'rates_json', 'provider_config_json'];\n+\n+    protected function casts(): array\n+    {\n+        return ['rates_json' => 'array', 'provider_config_json' => 'array'];\n+    }\n+\n+    public function store(): BelongsTo\n+    {\n+        return $this->belongsTo(Store::class);\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/Discount.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use App\\Enums\\DiscountType;\n+use App\\Enums\\DiscountValueType;\n+use App\\Models\\Concerns\\BelongsToStore;\n+use Illuminate\\Database\\Eloquent\\Model;\n+\n+class Discount extends Model\n+{\n+    use BelongsToStore;\n+\n+    protected $fillable = ['store_id', 'code', 'type', 'value_type', 'value_amount', 'status', 'usage_limit', 'usage_count', 'starts_at', 'ends_at', 'rules_json'];\n+\n+    protected function casts(): array\n+    {\n+        return ['type' => DiscountType::class, 'value_type' => DiscountValueType::class, 'starts_at' => 'datetime', 'ends_at' => 'datetime', 'rules_json' => 'array'];\n+    }\n+\n+    public function isAvailable(): bool\n+    {\n+        return $this->status === 'active'\n+            && ($this->starts_at === null || $this->starts_at->isPast())\n+            && ($this->ends_at === null || $this->ends_at->isFuture())\n+            && ($this->usage_limit === null || $this->usage_count < $this->usage_limit);\n+    }\n+}\n*** End Patch";
text(await tools.apply_patch(patch));


content:
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class CustomerAddress extends Model
{
    protected $fillable = ['customer_id', 'label', 'address_json', 'is_default'];

    protected function casts(): array
    {
        return ['address_json' => 'array', 'is_default' => 'boolean'];
    }

    public function customer(): BelongsTo
    {
        return $this->belongsTo(Customer::class);
    }
}

content:
<?php

namespace App\Models;

use App\Models\Concerns\BelongsToStore;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class ShippingZone extends Model
{
    use BelongsToStore;

    protected $fillable = ['store_id', 'name', 'countries_json', 'regions_json'];

    protected function casts(): array
    {
        return ['countries_json' => 'array', 'regions_json' => 'array'];
    }

    public function rates(): HasMany
    {
        return $this->hasMany(ShippingRate::class);
    }

    public function matchesCountry(string $countryCode): bool
    {
        $countries = $this->countries_json ?? [];

        return $countries === [] || in_array(strtoupper($countryCode), array_map('strtoupper', $countries), true);
    }
}

content:
<?php

namespace App\Models;

use App\Enums\DiscountType;
use App\Enums\DiscountValueType;
use App\Models\Concerns\BelongsToStore;
use Illuminate\Database\Eloquent\Model;

class Discount extends Model
{
    use BelongsToStore;

    protected $fillable = ['store_id', 'code', 'type', 'value_type', 'value_amount', 'status', 'usage_limit', 'usage_count', 'starts_at', 'ends_at', 'rules_json'];

    protected function casts(): array
    {
        return ['type' => DiscountType::class, 'value_type' => DiscountValueType::class, 'starts_at' => 'datetime', 'ends_at' => 'datetime', 'rules_json' => 'array'];
    }

    public function isAvailable(): bool
    {
        return $this->status === 'active'
            && ($this->starts_at === null || $this->starts_at->isPast())
            && ($this->ends_at === null || $this->ends_at->isFuture())
            && ($this->usage_limit === null || $this->usage_count < $this->usage_limit);
    }
}

content:
<?php

namespace App\Models;

use App\Models\Concerns\BelongsToStore;
use Illuminate\Auth\Authenticatable as AuthenticatableTrait;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Customer extends Model implements Authenticatable
{
    use AuthenticatableTrait, BelongsToStore, HasFactory, Notifiable;

    protected $fillable = ['store_id', 'first_name', 'last_name', 'email', 'password_hash', 'status', 'email_verified_at', 'metadata'];

    protected $hidden = ['password_hash', 'remember_token'];

    protected function casts(): array
    {
        return ['email_verified_at' => 'datetime', 'metadata' => 'array', 'password_hash' => 'hashed'];
    }

    public function getAuthPasswordName(): string
    {
        return 'password_hash';
    }

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

    public function getNameAttribute(): string
    {
        return trim($this->first_name.' '.$this->last_name);
    }

    public function addresses(): HasMany
    {
        return $this->hasMany(CustomerAddress::class);
    }

    public function orders(): HasMany
    {
        return $this->hasMany(Order::class);
    }
}

content:
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class CartLine extends Model
{
    protected $fillable = ['cart_id', 'variant_id', 'quantity', 'unit_price_amount', 'line_subtotal_amount', 'line_discount_amount', 'line_total_amount'];

    public function cart(): BelongsTo
    {
        return $this->belongsTo(Cart::class);
    }

    public function variant(): BelongsTo
    {
        return $this->belongsTo(ProductVariant::class, 'variant_id')->with(['product', 'inventory']);
    }
}

content:
<?php

namespace App\Models;

use App\Models\Concerns\BelongsToStore;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class TaxSettings extends Model
{
    use BelongsToStore;

    protected $primaryKey = 'store_id';

    public $incrementing = false;

    protected $fillable = ['store_id', 'mode', 'default_rate_basis_points', 'rates_json', 'provider_config_json'];

    protected function casts(): array
    {
        return ['rates_json' => 'array', 'provider_config_json' => 'array'];
    }

    public function store(): BelongsTo
    {
        return $this->belongsTo(Store::class);
    }
}

content:
<?php

namespace App\Models;

use App\Enums\CartStatus;
use App\Models\Concerns\BelongsToStore;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Cart extends Model
{
    use BelongsToStore;

    protected $fillable = ['store_id', 'customer_id', 'currency', 'cart_version', 'status'];

    protected function casts(): array
    {
        return ['status' => CartStatus::class];
    }

    public function customer(): BelongsTo
    {
        return $this->belongsTo(Customer::class);
    }

    public function lines(): HasMany
    {
        return $this->hasMany(CartLine::class);
    }

    public function subtotalAmount(): int
    {
        return (int) $this->lines->sum('line_total_amount');
    }

    public function itemCount(): int
    {
        return (int) $this->lines->sum('quantity');
    }
}

content:
<?php

namespace App\Models;

use App\Enums\CheckoutStatus;
use App\Models\Concerns\BelongsToStore;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Checkout extends Model
{
    use BelongsToStore;

    protected $fillable = ['store_id', 'cart_id', 'customer_id', 'status', 'email', 'shipping_address_json', 'billing_address_json', 'shipping_rate_id', 'discount_code', 'totals_json', 'tax_provider_snapshot_json', 'expires_at'];

    protected function casts(): array
    {
        return ['status' => CheckoutStatus::class, 'shipping_address_json' => 'array', 'billing_address_json' => 'array', 'totals_json' => 'array', 'tax_provider_snapshot_json' => 'array', 'expires_at' => 'datetime'];
    }

    public function cart(): BelongsTo
    {
        return $this->belongsTo(Cart::class);
    }

    public function customer(): BelongsTo
    {
        return $this->belongsTo(Customer::class);
    }

    public function shippingRate(): BelongsTo
    {
        return $this->belongsTo(ShippingRate::class);
    }

    public function isExpired(): bool
    {
        return $this->expires_at !== null && $this->expires_at->isPast();
    }
}

content:
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class ShippingRate extends Model
{
    protected $fillable = ['shipping_zone_id', 'name', 'type', 'price_amount', 'currency', 'config_json', 'is_active', 'estimated_days_min', 'estimated_days_max'];

    protected function casts(): array
    {
        return ['config_json' => 'array', 'is_active' => 'boolean'];
    }

    public function zone(): BelongsTo
    {
        return $this->belongsTo(ShippingZone::class, 'shipping_zone_id');
    }
}

stdout:
Success. Updated the following files:
A /Users/wesner/Herd/shop/app/Models/Customer.php
A /Users/wesner/Herd/shop/app/Models/CustomerAddress.php
A /Users/wesner/Herd/shop/app/Models/Cart.php
A /Users/wesner/Herd/shop/app/Models/CartLine.php
A /Users/wesner/Herd/shop/app/Models/Checkout.php
A /Users/wesner/Herd/shop/app/Models/ShippingZone.php
A /Users/wesner/Herd/shop/app/Models/ShippingRate.php
A /Users/wesner/Herd/shop/app/Models/TaxSettings.php
A /Users/wesner/Herd/shop/app/Models/Discount.php


text:
Script completed
Wall time 0.0 seconds
Output:


status: completed

input:
const patch = "*** Begin Patch\n*** Add File: /Users/wesner/Herd/shop/app/Models/Order.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use App\\Enums\\FinancialStatus;\n+use App\\Enums\\FulfillmentStatus;\n+use App\\Enums\\OrderStatus;\n+use App\\Models\\Concerns\\BelongsToStore;\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+use Illuminate\\Database\\Eloquent\\Relations\\HasMany;\n+\n+class Order extends Model\n+{\n+    use BelongsToStore;\n+\n+    protected $fillable = ['store_id', 'customer_id', 'checkout_id', 'order_number', 'currency', 'status', 'financial_status', 'fulfillment_status', 'email', 'shipping_address_json', 'billing_address_json', 'subtotal_amount', 'discount_amount', 'shipping_amount', 'tax_amount', 'total_amount', 'placed_at', 'metadata'];\n+\n+    protected function casts(): array\n+    {\n+        return ['status' => OrderStatus::class, 'financial_status' => FinancialStatus::class, 'fulfillment_status' => FulfillmentStatus::class, 'shipping_address_json' => 'array', 'billing_address_json' => 'array', 'placed_at' => 'datetime', 'metadata' => 'array'];\n+    }\n+\n+    public function customer(): BelongsTo\n+    {\n+        return $this->belongsTo(Customer::class);\n+    }\n+\n+    public function checkout(): BelongsTo\n+    {\n+        return $this->belongsTo(Checkout::class);\n+    }\n+\n+    public function lines(): HasMany\n+    {\n+        return $this->hasMany(OrderLine::class);\n+    }\n+\n+    public function payments(): HasMany\n+    {\n+        return $this->hasMany(Payment::class);\n+    }\n+\n+    public function refunds(): HasMany\n+    {\n+        return $this->hasMany(Refund::class);\n+    }\n+\n+    public function fulfillments(): HasMany\n+    {\n+        return $this->hasMany(Fulfillment::class);\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/OrderLine.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+\n+class OrderLine extends Model\n+{\n+    protected $fillable = ['order_id', 'product_id', 'variant_id', 'product_title', 'variant_title', 'sku', 'quantity', 'unit_price_amount', 'line_subtotal_amount', 'line_discount_amount', 'line_total_amount', 'tax_lines_json', 'discount_allocations_json'];\n+\n+    protected function casts(): array\n+    {\n+        return ['tax_lines_json' => 'array', 'discount_allocations_json' => 'array'];\n+    }\n+\n+    public function order(): BelongsTo\n+    {\n+        return $this->belongsTo(Order::class);\n+    }\n+\n+    public function product(): BelongsTo\n+    {\n+        return $this->belongsTo(Product::class);\n+    }\n+\n+    public function variant(): BelongsTo\n+    {\n+        return $this->belongsTo(ProductVariant::class, 'variant_id');\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/Payment.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use App\\Enums\\PaymentMethod;\n+use App\\Enums\\PaymentStatus;\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+\n+class Payment extends Model\n+{\n+    protected $fillable = ['order_id', 'provider', 'provider_payment_id', 'method', 'status', 'amount', 'raw_json_encrypted'];\n+\n+    protected $hidden = ['raw_json_encrypted'];\n+\n+    protected function casts(): array\n+    {\n+        return ['method' => PaymentMethod::class, 'status' => PaymentStatus::class, 'raw_json_encrypted' => 'encrypted'];\n+    }\n+\n+    public function order(): BelongsTo\n+    {\n+        return $this->belongsTo(Order::class);\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/Refund.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+\n+class Refund extends Model\n+{\n+    protected $fillable = ['order_id', 'payment_id', 'amount', 'status', 'reason', 'restock'];\n+\n+    protected function casts(): array\n+    {\n+        return ['restock' => 'boolean'];\n+    }\n+\n+    public function order(): BelongsTo\n+    {\n+        return $this->belongsTo(Order::class);\n+    }\n+\n+    public function payment(): BelongsTo\n+    {\n+        return $this->belongsTo(Payment::class);\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/Fulfillment.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+use Illuminate\\Database\\Eloquent\\Relations\\HasMany;\n+\n+class Fulfillment extends Model\n+{\n+    protected $fillable = ['order_id', 'status', 'tracking_company', 'tracking_number', 'tracking_url', 'fulfilled_at'];\n+\n+    protected function casts(): array\n+    {\n+        return ['fulfilled_at' => 'datetime'];\n+    }\n+\n+    public function order(): BelongsTo\n+    {\n+        return $this->belongsTo(Order::class);\n+    }\n+\n+    public function lines(): HasMany\n+    {\n+        return $this->hasMany(FulfillmentLine::class);\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/FulfillmentLine.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+\n+class FulfillmentLine extends Model\n+{\n+    protected $fillable = ['fulfillment_id', 'order_line_id', 'quantity'];\n+\n+    public function fulfillment(): BelongsTo\n+    {\n+        return $this->belongsTo(Fulfillment::class);\n+    }\n+\n+    public function orderLine(): BelongsTo\n+    {\n+        return $this->belongsTo(OrderLine::class);\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/Theme.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use App\\Enums\\ThemeStatus;\n+use App\\Models\\Concerns\\BelongsToStore;\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\HasMany;\n+\n+class Theme extends Model\n+{\n+    use BelongsToStore;\n+\n+    protected $fillable = ['store_id', 'name', 'status', 'version', 'settings'];\n+\n+    protected function casts(): array\n+    {\n+        return ['status' => ThemeStatus::class, 'settings' => 'array'];\n+    }\n+\n+    public function files(): HasMany\n+    {\n+        return $this->hasMany(ThemeFile::class);\n+    }\n+\n+    public function settingsRows(): HasMany\n+    {\n+        return $this->hasMany(ThemeSetting::class);\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/ThemeFile.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+\n+class ThemeFile extends Model\n+{\n+    protected $fillable = ['theme_id', 'path', 'content'];\n+\n+    public function theme(): BelongsTo\n+    {\n+        return $this->belongsTo(Theme::class);\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/ThemeSetting.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+\n+class ThemeSetting extends Model\n+{\n+    protected $fillable = ['theme_id', 'key', 'value'];\n+\n+    protected function casts(): array\n+    {\n+        return ['value' => 'array'];\n+    }\n+\n+    public function theme(): BelongsTo\n+    {\n+        return $this->belongsTo(Theme::class);\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/Page.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use App\\Enums\\PageStatus;\n+use App\\Models\\Concerns\\BelongsToStore;\n+use Illuminate\\Database\\Eloquent\\Model;\n+\n+class Page extends Model\n+{\n+    use BelongsToStore;\n+\n+    protected $fillable = ['store_id', 'title', 'handle', 'content', 'status', 'published_at'];\n+\n+    protected function casts(): array\n+    {\n+        return ['status' => PageStatus::class, 'published_at' => 'datetime'];\n+    }\n+}\n*** End Patch";
text(await tools.apply_patch(patch));


content:
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class FulfillmentLine extends Model
{
    protected $fillable = ['fulfillment_id', 'order_line_id', 'quantity'];

    public function fulfillment(): BelongsTo
    {
        return $this->belongsTo(Fulfillment::class);
    }

    public function orderLine(): BelongsTo
    {
        return $this->belongsTo(OrderLine::class);
    }
}

content:
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class OrderLine extends Model
{
    protected $fillable = ['order_id', 'product_id', 'variant_id', 'product_title', 'variant_title', 'sku', 'quantity', 'unit_price_amount', 'line_subtotal_amount', 'line_discount_amount', 'line_total_amount', 'tax_lines_json', 'discount_allocations_json'];

    protected function casts(): array
    {
        return ['tax_lines_json' => 'array', 'discount_allocations_json' => 'array'];
    }

    public function order(): BelongsTo
    {
        return $this->belongsTo(Order::class);
    }

    public function product(): BelongsTo
    {
        return $this->belongsTo(Product::class);
    }

    public function variant(): BelongsTo
    {
        return $this->belongsTo(ProductVariant::class, 'variant_id');
    }
}

content:
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class ThemeFile extends Model
{
    protected $fillable = ['theme_id', 'path', 'content'];

    public function theme(): BelongsTo
    {
        return $this->belongsTo(Theme::class);
    }
}

content:
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Fulfillment extends Model
{
    protected $fillable = ['order_id', 'status', 'tracking_company', 'tracking_number', 'tracking_url', 'fulfilled_at'];

    protected function casts(): array
    {
        return ['fulfilled_at' => 'datetime'];
    }

    public function order(): BelongsTo
    {
        return $this->belongsTo(Order::class);
    }

    public function lines(): HasMany
    {
        return $this->hasMany(FulfillmentLine::class);
    }
}

content:
<?php

namespace App\Models;

use App\Enums\FinancialStatus;
use App\Enums\FulfillmentStatus;
use App\Enums\OrderStatus;
use App\Models\Concerns\BelongsToStore;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Order extends Model
{
    use BelongsToStore;

    protected $fillable = ['store_id', 'customer_id', 'checkout_id', 'order_number', 'currency', 'status', 'financial_status', 'fulfillment_status', 'email', 'shipping_address_json', 'billing_address_json', 'subtotal_amount', 'discount_amount', 'shipping_amount', 'tax_amount', 'total_amount', 'placed_at', 'metadata'];

    protected function casts(): array
    {
        return ['status' => OrderStatus::class, 'financial_status' => FinancialStatus::class, 'fulfillment_status' => FulfillmentStatus::class, 'shipping_address_json' => 'array', 'billing_address_json' => 'array', 'placed_at' => 'datetime', 'metadata' => 'array'];
    }

    public function customer(): BelongsTo
    {
        return $this->belongsTo(Customer::class);
    }

    public function checkout(): BelongsTo
    {
        return $this->belongsTo(Checkout::class);
    }

    public function lines(): HasMany
    {
        return $this->hasMany(OrderLine::class);
    }

    public function payments(): HasMany
    {
        return $this->hasMany(Payment::class);
    }

    public function refunds(): HasMany
    {
        return $this->hasMany(Refund::class);
    }

    public function fulfillments(): HasMany
    {
        return $this->hasMany(Fulfillment::class);
    }
}

content:
<?php

namespace App\Models;

use App\Enums\PageStatus;
use App\Models\Concerns\BelongsToStore;
use Illuminate\Database\Eloquent\Model;

class Page extends Model
{
    use BelongsToStore;

    protected $fillable = ['store_id', 'title', 'handle', 'content', 'status', 'published_at'];

    protected function casts(): array
    {
        return ['status' => PageStatus::class, 'published_at' => 'datetime'];
    }
}

content:
<?php

namespace App\Models;

use App\Enums\PaymentMethod;
use App\Enums\PaymentStatus;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Payment extends Model
{
    protected $fillable = ['order_id', 'provider', 'provider_payment_id', 'method', 'status', 'amount', 'raw_json_encrypted'];

    protected $hidden = ['raw_json_encrypted'];

    protected function casts(): array
    {
        return ['method' => PaymentMethod::class, 'status' => PaymentStatus::class, 'raw_json_encrypted' => 'encrypted'];
    }

    public function order(): BelongsTo
    {
        return $this->belongsTo(Order::class);
    }
}

content:
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Refund extends Model
{
    protected $fillable = ['order_id', 'payment_id', 'amount', 'status', 'reason', 'restock'];

    protected function casts(): array
    {
        return ['restock' => 'boolean'];
    }

    public function order(): BelongsTo
    {
        return $this->belongsTo(Order::class);
    }

    public function payment(): BelongsTo
    {
        return $this->belongsTo(Payment::class);
    }
}

content:
<?php

namespace App\Models;

use App\Enums\ThemeStatus;
use App\Models\Concerns\BelongsToStore;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Theme extends Model
{
    use BelongsToStore;

    protected $fillable = ['store_id', 'name', 'status', 'version', 'settings'];

    protected function casts(): array
    {
        return ['status' => ThemeStatus::class, 'settings' => 'array'];
    }

    public function files(): HasMany
    {
        return $this->hasMany(ThemeFile::class);
    }

    public function settingsRows(): HasMany
    {
        return $this->hasMany(ThemeSetting::class);
    }
}

content:
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class ThemeSetting extends Model
{
    protected $fillable = ['theme_id', 'key', 'value'];

    protected function casts(): array
    {
        return ['value' => 'array'];
    }

    public function theme(): BelongsTo
    {
        return $this->belongsTo(Theme::class);
    }
}

stdout:
Success. Updated the following files:
A /Users/wesner/Herd/shop/app/Models/Order.php
A /Users/wesner/Herd/shop/app/Models/OrderLine.php
A /Users/wesner/Herd/shop/app/Models/Payment.php
A /Users/wesner/Herd/shop/app/Models/Refund.php
A /Users/wesner/Herd/shop/app/Models/Fulfillment.php
A /Users/wesner/Herd/shop/app/Models/FulfillmentLine.php
A /Users/wesner/Herd/shop/app/Models/Theme.php
A /Users/wesner/Herd/shop/app/Models/ThemeFile.php
A /Users/wesner/Herd/shop/app/Models/ThemeSetting.php
A /Users/wesner/Herd/shop/app/Models/Page.php


text:
Script completed
Wall time 0.0 seconds
Output:


status: completed

input:
const patch = "*** Begin Patch\n*** Add File: /Users/wesner/Herd/shop/app/Models/NavigationMenu.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use App\\Models\\Concerns\\BelongsToStore;\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\HasMany;\n+\n+class NavigationMenu extends Model\n+{\n+    use BelongsToStore;\n+\n+    protected $fillable = ['store_id', 'name', 'handle'];\n+\n+    public function items(): HasMany\n+    {\n+        return $this->hasMany(NavigationItem::class)->orderBy('position');\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/NavigationItem.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+\n+class NavigationItem extends Model\n+{\n+    protected $fillable = ['navigation_menu_id', 'label', 'type', 'url', 'resource_id', 'position', 'parent_id'];\n+\n+    public function menu(): BelongsTo\n+    {\n+        return $this->belongsTo(NavigationMenu::class, 'navigation_menu_id');\n+    }\n+\n+    public function parent(): BelongsTo\n+    {\n+        return $this->belongsTo(self::class, 'parent_id');\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/SearchSetting.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use App\\Models\\Concerns\\BelongsToStore;\n+use Illuminate\\Database\\Eloquent\\Model;\n+\n+class SearchSetting extends Model\n+{\n+    use BelongsToStore;\n+\n+    protected $primaryKey = 'store_id';\n+\n+    public $incrementing = false;\n+\n+    protected $fillable = ['store_id', 'synonyms', 'stopwords', 'enabled'];\n+\n+    protected function casts(): array\n+    {\n+        return ['synonyms' => 'array', 'stopwords' => 'array', 'enabled' => 'boolean'];\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/SearchQuery.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use App\\Models\\Concerns\\BelongsToStore;\n+use Illuminate\\Database\\Eloquent\\Model;\n+\n+class SearchQuery extends Model\n+{\n+    use BelongsToStore;\n+\n+    protected $fillable = ['store_id', 'query', 'results_count', 'customer_id'];\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/AnalyticsEvent.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use App\\Models\\Concerns\\BelongsToStore;\n+use Illuminate\\Database\\Eloquent\\Model;\n+\n+class AnalyticsEvent extends Model\n+{\n+    use BelongsToStore;\n+\n+    protected $fillable = ['store_id', 'type', 'session_id', 'customer_id', 'client_event_id', 'payload'];\n+\n+    protected function casts(): array\n+    {\n+        return ['payload' => 'array'];\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/AnalyticsDaily.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use App\\Models\\Concerns\\BelongsToStore;\n+use Illuminate\\Database\\Eloquent\\Model;\n+\n+class AnalyticsDaily extends Model\n+{\n+    use BelongsToStore;\n+\n+    protected $table = 'analytics_daily';\n+\n+    protected $fillable = ['store_id', 'date', 'orders_count', 'revenue_amount', 'aov_amount', 'visits_count', 'add_to_cart_count', 'checkout_started_count'];\n+\n+    public $incrementing = false;\n+\n+    protected function casts(): array\n+    {\n+        return ['date' => 'date'];\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/App.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\HasMany;\n+\n+class App extends Model\n+{\n+    protected $fillable = ['name', 'slug', 'description', 'status', 'scopes'];\n+\n+    protected function casts(): array\n+    {\n+        return ['scopes' => 'array'];\n+    }\n+\n+    public function installations(): HasMany\n+    {\n+        return $this->hasMany(AppInstallation::class);\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/AppInstallation.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use App\\Models\\Concerns\\BelongsToStore;\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+\n+class AppInstallation extends Model\n+{\n+    use BelongsToStore;\n+\n+    protected $fillable = ['store_id', 'app_id', 'status', 'config'];\n+\n+    protected function casts(): array\n+    {\n+        return ['config' => 'array'];\n+    }\n+\n+    public function app(): BelongsTo\n+    {\n+        return $this->belongsTo(App::class);\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/WebhookSubscription.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use App\\Models\\Concerns\\BelongsToStore;\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\HasMany;\n+\n+class WebhookSubscription extends Model\n+{\n+    use BelongsToStore;\n+\n+    protected $fillable = ['store_id', 'event', 'target_url', 'secret_encrypted', 'status', 'consecutive_failures'];\n+\n+    protected $hidden = ['secret_encrypted'];\n+\n+    protected function casts(): array\n+    {\n+        return ['secret_encrypted' => 'encrypted'];\n+    }\n+\n+    public function deliveries(): HasMany\n+    {\n+        return $this->hasMany(WebhookDelivery::class);\n+    }\n+}\n*** Add File: /Users/wesner/Herd/shop/app/Models/WebhookDelivery.php\n+<?php\n+\n+namespace App\\Models;\n+\n+use Illuminate\\Database\\Eloquent\\Model;\n+use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\n+\n+class WebhookDelivery extends Model\n+{\n+    protected $fillable = ['webhook_subscription_id', 'event', 'payload', 'attempts', 'response_status', 'response_body', 'delivered_at', 'next_attempt_at'];\n+\n+    protected function casts(): array\n+    {\n+        return ['payload' => 'array', 'delivered_at' => 'datetime', 'next_attempt_at' => 'datetime'];\n+    }\n+\n+    public function subscription(): BelongsTo\n+    {\n+        return $this->belongsTo(WebhookSubscription::class, 'webhook_subscription_id');\n+    }\n+}\n*** End Patch";
text(await tools.apply_patch(patch));


content:
<?php

namespace App\Models;

use App\Models\Concerns\BelongsToStore;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class WebhookSubscription extends Model
{
    use BelongsToStore;

    protected $fillable = ['store_id', 'event', 'target_url', 'secret_encrypted', 'status', 'consecutive_failures'];

    protected $hidden = ['secret_encrypted'];

    protected function casts(): array
    {
        return ['secret_encrypted' => 'encrypted'];
    }

    public function deliveries(): HasMany
    {
        return $this->hasMany(WebhookDelivery::class);
    }
}

content:
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class App extends Model
{
    protected $fillable = ['name', 'slug', 'description', 'status', 'scopes'];

    protected function casts(): array
    {
        return ['scopes' => 'array'];
    }

    public function installations(): HasMany
    {
        return $this->hasMany(AppInstallation::class);
    }
}

content:
<?php

namespace App\Models;

use App\Models\Concerns\BelongsToStore;
use Illuminate\Database\Eloquent\Model;

class SearchSetting extends Model
{
    use BelongsToStore;

    protected $primaryKey = 'store_id';

    public $incrementing = false;

    protected $fillable = ['store_id', 'synonyms', 'stopwords', 'enabled'];

    protected function casts(): array
    {
        return ['synonyms' => 'array', 'stopwords' => 'array', 'enabled' => 'boolean'];
    }
}

content:
<?php

namespace App\Models;

use App\Models\Concerns\BelongsToStore;
use Illuminate\Database\Eloquent\Model;

class AnalyticsDaily extends Model
{
    use BelongsToStore;

    protected $table = 'analytics_daily';

    protected $fillable = ['store_id', 'date', 'orders_count', 'revenue_amount', 'aov_amount', 'visits_count', 'add_to_cart_count', 'checkout_started_count'];

    public $incrementing = false;

    protected function casts(): array
    {
        return ['date' => 'date'];
    }
}

content:
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class WebhookDelivery extends Model
{
    protected $fillable = ['webhook_subscription_id', 'event', 'payload', 'attempts', 'response_status', 'response_body', 'delivered_at', 'next_attempt_at'];

    protected function casts(): array
    {
        return ['payload' => 'array', 'delivered_at' => 'datetime', 'next_attempt_at' => 'datetime'];
    }

    public function subscription(): BelongsTo
    {
        return $this->belongsTo(WebhookSubscription::class, 'webhook_subscription_id');
    }
}

content:
<?php

namespace App\Models;

use App\Models\Concerns\BelongsToStore;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class AppInstallation extends Model
{
    use BelongsToStore;

    protected $fillable = ['store_id', 'app_id', 'status', 'config'];

    protected function casts(): array
    {
        return ['config' => 'array'];
    }

    public function app(): BelongsTo
    {
        return $this->belongsTo(App::class);
    }
}

content:
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class NavigationItem extends Model
{
    protected $fillable = ['navigation_menu_id', 'label', 'type', 'url', 'resource_id', 'position', 'parent_id'];

    public function menu(): BelongsTo
    {
        return $this->belongsTo(NavigationMenu::class, 'navigation_menu_id');
    }

    public function parent(): BelongsTo
    {
        return $this->belongsTo(self::class, 'parent_id');
    }
}

content:
<?php

namespace App\Models;

use App\Models\Concerns\BelongsToStore;
use Illuminate\Database\Eloquent\Model;

class AnalyticsEvent extends Model
{
    use BelongsToStore;

    protected $fillable = ['store_id', 'type', 'session_id', 'customer_id', 'client_event_id', 'payload'];

    protected function casts(): array
    {
        return ['payload' => 'array'];
    }
}

content:
<?php

namespace App\Models;

use App\Models\Concerns\BelongsToStore;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class NavigationMenu extends Model
{
    use BelongsToStore;

    protected $fillable = ['store_id', 'name', 'handle'];

    public function items(): HasMany
    {
        return $this->hasMany(NavigationItem::class)->orderBy('position');
    }
}

content:
<?php

namespace App\Models;

use App\Models\Concerns\BelongsToStore;
use Illuminate\Database\Eloquent\Model;

class SearchQuery extends Model
{
    use BelongsToStore;

    protected $fillable = ['store_id', 'query', 'results_count', 'customer_id'];
}

stdout:
Success. Updated the following files:
A /Users/wesner/Herd/shop/app/Models/NavigationMenu.php
A /Users/wesner/Herd/shop/app/Models/NavigationItem.php
A /Users/wesner/Herd/shop/app/Models/SearchSetting.php
A /Users/wesner/Herd/shop/app/Models/SearchQuery.php
A /Users/wesner/Herd/shop/app/Models/AnalyticsEvent.php
A /Users/wesner/Herd/shop/app/Models/AnalyticsDaily.php
A /Users/wesner/Herd/shop/app/Models/App.php
A /Users/wesner/Herd/shop/app/Models/AppInstallation.php
A /Users/wesner/Herd/shop/app/Models/WebhookSubscription.php
A /Users/wesner/Herd/shop/app/Models/WebhookDelivery.php


text:
Script completed
Wall time 0.0 seconds
Output: