diff --git a/.cursor/mcp.json b/.cursor/mcp.json
new file mode 100644
index 0000000..565f7cb
--- /dev/null
+++ b/.cursor/mcp.json
@@ -0,0 +1,12 @@
+{
+ "mcpServers": {
+ "laravel-boost": {
+ "command": "/usr/bin/php8.4",
+ "args": [
+ "/data/Projects/ivplv2/artisan",
+ "mcp:start",
+ "laravel-boost"
+ ]
+ }
+ }
+}
diff --git a/.cursor/rules/laravel-boost.mdc b/.cursor/rules/laravel-boost.mdc
new file mode 100644
index 0000000..b25bd61
--- /dev/null
+++ b/.cursor/rules/laravel-boost.mdc
@@ -0,0 +1,396 @@
+---
+alwaysApply: true
+---
+
+=== foundation rules ===
+
+# Laravel Boost Guidelines
+
+The Laravel Boost guidelines are specifically curated by Laravel maintainers for this application. These guidelines should be followed closely to enhance the user's satisfaction building Laravel applications.
+
+## Foundational Context
+This application is a Laravel application and its main Laravel ecosystems package & versions are below. You are an expert with them all. Ensure you abide by these specific packages & versions.
+
+- php - 8.4.12
+- filament/filament (FILAMENT) - v4
+- laravel/framework (LARAVEL) - v12
+- laravel/prompts (PROMPTS) - v0
+- livewire/livewire (LIVEWIRE) - v3
+- larastan/larastan (LARASTAN) - v3
+- laravel/pint (PINT) - v1
+- laravel/sail (SAIL) - v1
+- phpunit/phpunit (PHPUNIT) - v11
+- rector/rector (RECTOR) - v2
+
+
+## Conventions
+- You must follow all existing code conventions used in this application. When creating or editing a file, check sibling files for the correct structure, approach, naming.
+- Use descriptive names for variables and methods. For example, `isRegisteredForDiscounts`, not `discount()`.
+- Check for existing components to reuse before writing a new one.
+
+## Verification Scripts
+- Do not create verification scripts or tinker when tests cover that functionality and prove it works. Unit and feature tests are more important.
+
+## Application Structure & Architecture
+- Stick to existing directory structure - don't create new base folders without approval.
+- Do not change the application's dependencies without approval.
+
+## Frontend Bundling
+- If the user doesn't see a frontend change reflected in the UI, it could mean they need to run `npm run build`, `npm run dev`, or `composer run dev`. Ask them.
+
+## Replies
+- Be concise in your explanations - focus on what's important rather than explaining obvious details.
+
+## Documentation Files
+- You must only create documentation files if explicitly requested by the user.
+
+
+=== boost rules ===
+
+## Laravel Boost
+- Laravel Boost is an MCP server that comes with powerful tools designed specifically for this application. Use them.
+
+## Artisan
+- Use the `list-artisan-commands` tool when you need to call an Artisan command to double check the available parameters.
+
+## URLs
+- Whenever you share a project URL with the user you should use the `get-absolute-url` tool to ensure you're using the correct scheme, domain / IP, and port.
+
+## Tinker / Debugging
+- You should use the `tinker` tool when you need to execute PHP to debug code or query Eloquent models directly.
+- Use the `database-query` tool when you only need to read from the database.
+
+## Reading Browser Logs With the `browser-logs` Tool
+- You can read browser logs, errors, and exceptions using the `browser-logs` tool from Boost.
+- Only recent browser logs will be useful - ignore old logs.
+
+## Searching Documentation (Critically Important)
+- Boost comes with a powerful `search-docs` tool you should use before any other approaches. This tool automatically passes a list of installed packages and their versions to the remote Boost API, so it returns only version-specific documentation specific for the user's circumstance. You should pass an array of packages to filter on if you know you need docs for particular packages.
+- The 'search-docs' tool is perfect for all Laravel related packages, including Laravel, Inertia, Livewire, Filament, Tailwind, Pest, Nova, Nightwatch, etc.
+- You must use this tool to search for Laravel-ecosystem documentation before falling back to other approaches.
+- Search the documentation before making code changes to ensure we are taking the correct approach.
+- Use multiple, broad, simple, topic based queries to start. For example: `['rate limiting', 'routing rate limiting', 'routing']`.
+- Do not add package names to queries - package information is already shared. For example, use `test resource table`, not `filament 4 test resource table`.
+
+### Available Search Syntax
+- You can and should pass multiple queries at once. The most relevant results will be returned first.
+
+1. Simple Word Searches with auto-stemming - query=authentication - finds 'authenticate' and 'auth'
+2. Multiple Words (AND Logic) - query=rate limit - finds knowledge containing both "rate" AND "limit"
+3. Quoted Phrases (Exact Position) - query="infinite scroll" - Words must be adjacent and in that order
+4. Mixed Queries - query=middleware "rate limit" - "middleware" AND exact phrase "rate limit"
+5. Multiple Queries - queries=["authentication", "middleware"] - ANY of these terms
+
+
+=== php rules ===
+
+## PHP
+
+- Always use curly braces for control structures, even if it has one line.
+
+### Constructors
+- Use PHP 8 constructor property promotion in `__construct()`.
+ - public function __construct(public GitHub $github) { }
+- Do not allow empty `__construct()` methods with zero parameters.
+
+### Type Declarations
+- Always use explicit return type declarations for methods and functions.
+- Use appropriate PHP type hints for method parameters.
+
+
+protected function isAccessible(User $user, ?string $path = null): bool
+{
+ ...
+}
+
+
+## Comments
+- Prefer PHPDoc blocks over comments. Never use comments within the code itself unless there is something _very_ complex going on.
+
+## PHPDoc Blocks
+- Add useful array shape type definitions for arrays when appropriate.
+
+## Enums
+- Typically, keys in an Enum should be TitleCase. For example: `FavoritePerson`, `BestLake`, `Monthly`.
+
+
+=== filament/core rules ===
+
+## Filament
+- Filament is used by this application, check how and where to follow existing application conventions.
+- Filament is a Server-Driven UI (SDUI) framework for Laravel. It allows developers to define user interfaces in PHP using structured configuration objects. It is built on top of Livewire, Alpine.js, and Tailwind CSS.
+- You can use the `search-docs` tool to get information from the official Filament documentation when needed. This is very useful for Artisan command arguments, specific code examples, testing functionality, relationship management, and ensuring you're following idiomatic practices.
+- Utilize static `make()` methods for consistent component initialization.
+
+### Artisan
+- You must use the Filament specific Artisan commands to create new files or components for Filament. You can find these with the `list-artisan-commands` tool, or with `php artisan` and the `--help` option.
+- Inspect the required options, always pass `--no-interaction`, and valid arguments for other options when applicable.
+
+### Filament's Core Features
+- Actions: Handle doing something within the application, often with a button or link. Actions encapsulate the UI, the interactive modal window, and the logic that should be executed when the modal window is submitted. They can be used anywhere in the UI and are commonly used to perform one-time actions like deleting a record, sending an email, or updating data in the database based on modal form input.
+- Forms: Dynamic forms rendered within other features, such as resources, action modals, table filters, and more.
+- Infolists: Read-only lists of data.
+- Notifications: Flash notifications displayed to users within the application.
+- Panels: The top-level container in Filament that can include all other features like pages, resources, forms, tables, notifications, actions, infolists, and widgets.
+- Resources: Static classes that are used to build CRUD interfaces for Eloquent models. Typically live in `app/Filament/Resources`.
+- Schemas: Represent components that define the structure and behavior of the UI, such as forms, tables, or lists.
+- Tables: Interactive tables with filtering, sorting, pagination, and more.
+- Widgets: Small component included within dashboards, often used for displaying data in charts, tables, or as a stat.
+
+### Relationships
+- Determine if you can use the `relationship()` method on form components when you need `options` for a select, checkbox, repeater, or when building a `Fieldset`:
+
+
+Forms\Components\Select::make('user_id')
+ ->label('Author')
+ ->relationship('author')
+ ->required(),
+
+
+
+## Testing
+- It's important to test Filament functionality for user satisfaction.
+- Ensure that you are authenticated to access the application within the test.
+- Filament uses Livewire, so start assertions with `livewire()` or `Livewire::test()`.
+
+### Example Tests
+
+
+ livewire(ListUsers::class)
+ ->assertCanSeeTableRecords($users)
+ ->searchTable($users->first()->name)
+ ->assertCanSeeTableRecords($users->take(1))
+ ->assertCanNotSeeTableRecords($users->skip(1))
+ ->searchTable($users->last()->email)
+ ->assertCanSeeTableRecords($users->take(-1))
+ ->assertCanNotSeeTableRecords($users->take($users->count() - 1));
+
+
+
+ livewire(CreateUser::class)
+ ->fillForm([
+ 'name' => 'Howdy',
+ 'email' => 'howdy@example.com',
+ ])
+ ->call('create')
+ ->assertNotified()
+ ->assertRedirect();
+
+ assertDatabaseHas(User::class, [
+ 'name' => 'Howdy',
+ 'email' => 'howdy@example.com',
+ ]);
+
+
+
+ use Filament\Facades\Filament;
+
+ Filament::setCurrentPanel('app');
+
+
+
+ livewire(EditInvoice::class, [
+ 'invoice' => $invoice,
+ ])->callAction('send');
+
+ expect($invoice->refresh())->isSent()->toBeTrue();
+
+
+
+=== filament/v4 rules ===
+
+## Filament 4
+
+### Important Version 4 Changes
+- File visibility is now `private` by default.
+- The `deferFilters` method from Filament v3 is now the default behavior in Filament v4, so users must click a button before the filters are applied to the table. To disable this behavior, you can use the `deferFilters(false)` method.
+- The `Grid`, `Section`, and `Fieldset` layout components no longer span all columns by default.
+- The `all` pagination page method is not available for tables by default.
+- All action classes extend `Filament\Actions\Action`. No action classes exist in `Filament\Tables\Actions`.
+- The `Form` & `Infolist` layout components have been moved to `Filament\Schemas\Components`, for example `Grid`, `Section`, `Fieldset`, `Tabs`, `Wizard`, etc.
+- A new `Repeater` component for Forms has been added.
+- Icons now use the `Filament\Support\Icons\Heroicon` Enum by default. Other options are available and documented.
+
+### Organize Component Classes Structure
+- Schema components: `Schemas/Components/`
+- Table columns: `Tables/Columns/`
+- Table filters: `Tables/Filters/`
+- Actions: `Actions/`
+
+
+=== laravel/core rules ===
+
+## Do Things the Laravel Way
+
+- Use `php artisan make:` commands to create new files (i.e. migrations, controllers, models, etc.). You can list available Artisan commands using the `list-artisan-commands` tool.
+- If you're creating a generic PHP class, use `artisan make:class`.
+- Pass `--no-interaction` to all Artisan commands to ensure they work without user input. You should also pass the correct `--options` to ensure correct behavior.
+
+### Database
+- Always use proper Eloquent relationship methods with return type hints. Prefer relationship methods over raw queries or manual joins.
+- Use Eloquent models and relationships before suggesting raw database queries
+- Avoid `DB::`; prefer `Model::query()`. Generate code that leverages Laravel's ORM capabilities rather than bypassing them.
+- Generate code that prevents N+1 query problems by using eager loading.
+- Use Laravel's query builder for very complex database operations.
+
+### Model Creation
+- When creating new models, create useful factories and seeders for them too. Ask the user if they need any other things, using `list-artisan-commands` to check the available options to `php artisan make:model`.
+
+### APIs & Eloquent Resources
+- For APIs, default to using Eloquent API Resources and API versioning unless existing API routes do not, then you should follow existing application convention.
+
+### Controllers & Validation
+- Always create Form Request classes for validation rather than inline validation in controllers. Include both validation rules and custom error messages.
+- Check sibling Form Requests to see if the application uses array or string based validation rules.
+
+### Queues
+- Use queued jobs for time-consuming operations with the `ShouldQueue` interface.
+
+### Authentication & Authorization
+- Use Laravel's built-in authentication and authorization features (gates, policies, Sanctum, etc.).
+
+### URL Generation
+- When generating links to other pages, prefer named routes and the `route()` function.
+
+### Configuration
+- Use environment variables only in configuration files - never use the `env()` function directly outside of config files. Always use `config('app.name')`, not `env('APP_NAME')`.
+
+### Testing
+- When creating models for tests, use the factories for the models. Check if the factory has custom states that can be used before manually setting up the model.
+- Faker: Use methods such as `$this->faker->word()` or `fake()->randomDigit()`. Follow existing conventions whether to use `$this->faker` or `fake()`.
+- When creating tests, make use of `php artisan make:test [options] ` to create a feature test, and pass `--unit` to create a unit test. Most tests should be feature tests.
+
+### Vite Error
+- If you receive an "Illuminate\Foundation\ViteException: Unable to locate file in Vite manifest" error, you can run `npm run build` or ask the user to run `npm run dev` or `composer run dev`.
+
+
+=== laravel/v12 rules ===
+
+## Laravel 12
+
+- Use the `search-docs` tool to get version specific documentation.
+- Since Laravel 11, Laravel has a new streamlined file structure which this project uses.
+
+### Laravel 12 Structure
+- No middleware files in `app/Http/Middleware/`.
+- `bootstrap/app.php` is the file to register middleware, exceptions, and routing files.
+- `bootstrap/providers.php` contains application specific service providers.
+- **No app\Console\Kernel.php** - use `bootstrap/app.php` or `routes/console.php` for console configuration.
+- **Commands auto-register** - files in `app/Console/Commands/` are automatically available and do not require manual registration.
+
+### Database
+- When modifying a column, the migration must include all of the attributes that were previously defined on the column. Otherwise, they will be dropped and lost.
+- Laravel 11 allows limiting eagerly loaded records natively, without external packages: `$query->latest()->limit(10);`.
+
+### Models
+- Casts can and likely should be set in a `casts()` method on a model rather than the `$casts` property. Follow existing conventions from other models.
+
+
+=== livewire/core rules ===
+
+## Livewire Core
+- Use the `search-docs` tool to find exact version specific documentation for how to write Livewire & Livewire tests.
+- Use the `php artisan make:livewire [Posts\\CreatePost]` artisan command to create new components
+- State should live on the server, with the UI reflecting it.
+- All Livewire requests hit the Laravel backend, they're like regular HTTP requests. Always validate form data, and run authorization checks in Livewire actions.
+
+## Livewire Best Practices
+- Livewire components require a single root element.
+- Use `wire:loading` and `wire:dirty` for delightful loading states.
+- Add `wire:key` in loops:
+
+ ```blade
+ @foreach ($items as $item)
+
+ {{ $item->name }}
+
+ @endforeach
+ ```
+
+- Prefer lifecycle hooks like `mount()`, `updatedFoo()`) for initialization and reactive side effects:
+
+
+ public function mount(User $user) { $this->user = $user; }
+ public function updatedSearch() { $this->resetPage(); }
+
+
+
+## Testing Livewire
+
+
+ Livewire::test(Counter::class)
+ ->assertSet('count', 0)
+ ->call('increment')
+ ->assertSet('count', 1)
+ ->assertSee(1)
+ ->assertStatus(200);
+
+
+
+
+ $this->get('/posts/create')
+ ->assertSeeLivewire(CreatePost::class);
+
+
+
+=== livewire/v3 rules ===
+
+## Livewire 3
+
+### Key Changes From Livewire 2
+- These things changed in Livewire 2, but may not have been updated in this application. Verify this application's setup to ensure you conform with application conventions.
+ - Use `wire:model.live` for real-time updates, `wire:model` is now deferred by default.
+ - Components now use the `App\Livewire` namespace (not `App\Http\Livewire`).
+ - Use `$this->dispatch()` to dispatch events (not `emit` or `dispatchBrowserEvent`).
+ - Use the `components.layouts.app` view as the typical layout path (not `layouts.app`).
+
+### New Directives
+- `wire:show`, `wire:transition`, `wire:cloak`, `wire:offline`, `wire:target` are available for use. Use the documentation to find usage examples.
+
+### Alpine
+- Alpine is now included with Livewire, don't manually include Alpine.js.
+- Plugins included with Alpine: persist, intersect, collapse, and focus.
+
+### Lifecycle Hooks
+- You can listen for `livewire:init` to hook into Livewire initialization, and `fail.status === 419` for the page expiring:
+
+
+document.addEventListener('livewire:init', function () {
+ Livewire.hook('request', ({ fail }) => {
+ if (fail && fail.status === 419) {
+ alert('Your session expired');
+ }
+ });
+
+ Livewire.hook('message.failed', (message, component) => {
+ console.error(message);
+ });
+});
+
+
+
+=== pint/core rules ===
+
+## Laravel Pint Code Formatter
+
+- You must run `vendor/bin/pint --dirty` before finalizing changes to ensure your code matches the project's expected style.
+- Do not run `vendor/bin/pint --test`, simply run `vendor/bin/pint` to fix any formatting issues.
+
+
+=== phpunit/core rules ===
+
+## PHPUnit Core
+
+- This application uses PHPUnit for testing. All tests must be written as PHPUnit classes. Use `php artisan make:test --phpunit ` to create a new test.
+- If you see a test using "Pest", convert it to PHPUnit.
+- Every time a test has been updated, run that singular test.
+- When the tests relating to your feature are passing, ask the user if they would like to also run the entire test suite to make sure everything is still passing.
+- Tests should test all of the happy paths, failure paths, and weird paths.
+- You must not remove any tests or test files from the tests directory without approval. These are not temporary or helper files, these are core to the application.
+
+### Running Tests
+- Run the minimal number of tests, using an appropriate filter, before finalizing.
+- To run all tests: `php artisan test`.
+- To run all tests in a file: `php artisan test tests/Feature/ExampleTest.php`.
+- To filter on a particular test name: `php artisan test --filter=testName` (recommended after making a change to a related file).
+
\ No newline at end of file
diff --git a/.env.ci.example b/.env.ci.example
new file mode 100644
index 0000000..929b6be
--- /dev/null
+++ b/.env.ci.example
@@ -0,0 +1,45 @@
+# App Environment
+APP_NAME=DropIt!
+APP_ENV=testing
+APP_KEY=
+APP_DEBUG=true
+APP_URL=http://localhost
+
+# Database
+DB_CONNECTION=mysql
+DB_HOST=127.0.0.1
+DB_PORT=3306
+DB_DATABASE=dropit_test
+DB_USERNAME=root
+DB_PASSWORD=root
+
+# Cache & Session
+CACHE_DRIVER=array
+SESSION_DRIVER=array
+
+# Queue
+QUEUE_CONNECTION=sync
+
+# Redis (optional, for code that references Redis)
+REDIS_CLIENT=phpredis
+REDIS_HOST=127.0.0.1
+REDIS_PASSWORD=null
+REDIS_PORT=6379
+REDIS_DB=1
+REDIS_CACHE_DB=2
+
+# Filesystem
+FILESYSTEM_DRIVER=local
+
+# Mail (optional, logs emails to storage)
+MAIL_MAILER=log
+MAIL_HOST=localhost
+MAIL_PORT=1025
+MAIL_USERNAME=null
+MAIL_PASSWORD=null
+MAIL_ENCRYPTION=null
+MAIL_FROM_ADDRESS=no-reply@example.com
+MAIL_FROM_NAME="${APP_NAME}"
+
+# Broadcasting (optional)
+BROADCAST_DRIVER=log
diff --git a/.env.example b/.env.example
index 35db1dd..394221f 100644
--- a/.env.example
+++ b/.env.example
@@ -1,8 +1,8 @@
-APP_NAME=Laravel
+APP_NAME="DropIt!"
APP_ENV=local
APP_KEY=
APP_DEBUG=true
-APP_URL=http://localhost
+APP_URL=http://dropit.test
APP_LOCALE=en
APP_FALLBACK_LOCALE=en
@@ -16,18 +16,18 @@ PHP_CLI_SERVER_WORKERS=4
BCRYPT_ROUNDS=12
LOG_CHANNEL=stack
-LOG_STACK=single
+LOG_STACK=daily
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
-DB_CONNECTION=sqlite
-# DB_HOST=127.0.0.1
-# DB_PORT=3306
-# DB_DATABASE=laravel
-# DB_USERNAME=root
-# DB_PASSWORD=
+DB_CONNECTION=mariadb
+DB_HOST=127.0.0.1
+DB_PORT=3306
+DB_DATABASE=dropit_db
+DB_USERNAME=root
+DB_PASSWORD=
-SESSION_DRIVER=database
+SESSION_DRIVER=redis
SESSION_LIFETIME=120
SESSION_ENCRYPT=false
SESSION_PATH=/
@@ -35,12 +35,10 @@ SESSION_DOMAIN=null
BROADCAST_CONNECTION=log
FILESYSTEM_DISK=local
-QUEUE_CONNECTION=database
+QUEUE_CONNECTION=redis
-CACHE_STORE=database
-# CACHE_PREFIX=
-
-MEMCACHED_HOST=127.0.0.1
+CACHE_STORE=redis
+CACHE_PREFIX=dropit
REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
new file mode 100644
index 0000000..32788ec
--- /dev/null
+++ b/.github/copilot-instructions.md
@@ -0,0 +1,587 @@
+# GitHub Copilot Instructions for DropIt!
+
+This document provides foundational context and architectural rules for the "DropIt!" Laravel application. Adhere
+strictly to these guidelines to ensure consistency, maintainability, and architectural integrity.
+
+---
+
+### **1. Project Overview & Philosophy**
+
+DropIt! is a multi-tenant Laravel application that acts as a **smart pipe** between e-commerce stores, suppliers, and
+fulfillment providers. The core philosophy is to orchestrate complex data flows with **minimal data storage** and *
+*comprehensive logging on failure**.
+
+* **Core Principle**: "Silent on success, log everything on failure."
+* **Idempotency**: All flows are idempotent, preventing duplicate processing of the same entity via a unique `reference`
+ key.
+
+---
+
+### **2. Core Architecture & Constraints**
+
+**Database Architecture:**
+
+* **No JSON columns**: All flexible data must be stored in key/value pair tables.
+* **No ENUM columns**: Use `string` columns with code-defined constants for status and types.
+* **No `readonly` properties**.
+
+**Domain Concepts:**
+
+* **Tenants**: Multi-tenant customers.
+* **Drops**: A tenant's complete business configuration.
+* **Flows**: An individual data movement from a source to a target connector.
+* **Connectors**: External services (e.g., Shopify, AliExpress).
+* **Entities**: Data objects (`orders`, `products`).
+
+**Canonical Data Model:**
+
+* All incoming payloads are transformed into a clean **canonical DTO**.
+
+---
+
+### **3. Design Patterns & Principles**
+
+* **Decorator Pattern**: Stackable HTTP behaviors (logging, rate limiting, exception handling) are implemented as
+ decorators that wrap the `ExternalApiClient`.
+* **Strategy Pattern + Laravel Pipelines**: Business logic (e.g., conditional flows, branching) is executed as a series
+ of strategies within a Laravel Pipeline.
+* **Composition**: API clients are composed of a `BaseApiClient` and specialized entity clients.
+* **Factory Pattern**: Used for dynamic creation of API clients based on tenant credentials.
+
+---
+
+### **4. Technology Stack & Tooling**
+
+* **Stack**: Laravel v12, Filament v4, Livewire v3, PHP v8.4.12.
+* **Testing**: PHPUnit v11. Prioritize **fakes** over mocks for testing API clients.
+* **Artisan**: Use `php artisan make:*` commands for all file creation.
+* **Tooling**: This project uses a Laravel Boost environment. Use the following tools when applicable:
+ * `search-docs`: For all Laravel-ecosystem documentation.
+ * `list-artisan-commands`: To find available artisan commands.
+ * `tinker`: For debugging Eloquent models.
+ * `database-query`: For read-only database queries.
+
+---
+
+### **5. Foundational Guiding Principles**
+
+* **Convention over Configuration**: Follow existing code conventions.
+* **Single Responsibility**: Each class, method, and component should have a single purpose.
+* **Test-Driven Development (TDD)**: Write tests before writing code.
+* **Readability**: Write clean, self-documenting code with clear variable and method names.
+* **Performance**: Use queued jobs for long-running tasks and eager loading to prevent N+1 query problems.
+* **Code Style**: Use Laravel Pint to format all code with `vendor/bin/pint --dirty`.
+* **PHPDoc**: Use PHPDoc blocks above functions for APIs, including the JSON structure.
+
+---
+
+### **6. Core Business Flow**
+
+1. **Ingestion**: A webhook from an origin (e.g., Shopify) is received by a controller and dispatches a
+ `ProcessWebhookJob`.
+2. **Transformation**: The `ProcessWebhookJob` uses a dedicated `Transformer` to convert the webhook payload into a
+ canonical DTO.
+3. **Orchestration**: The canonical DTO is passed to the `FlowExecutor`, which runs the configured business logic
+ pipeline.
+4. **API Call**: The final step in the pipeline calls a specific API client, which is wrapped in **decorators** for
+ logging, error handling, and rate limiting.
+5. **Reconciliation**: A scheduled `ReconciliationJob` periodically checks for missed or failed records and dispatches
+ `ReconcileRecordJob`s to catch them up.
+
+---
+
+
+=== foundation rules ===
+
+# Laravel Boost Guidelines
+
+The Laravel Boost guidelines are specifically curated by Laravel maintainers for this application. These guidelines
+should be followed closely to enhance the user's satisfaction building Laravel applications.
+
+## Foundational Context
+
+This application is a Laravel application and its main Laravel ecosystems package & versions are below. You are an
+expert with them all. Ensure you abide by these specific packages & versions.
+
+- php - 8.4.12
+- filament/filament (FILAMENT) - v4
+- laravel/framework (LARAVEL) - v12
+- laravel/prompts (PROMPTS) - v0
+- livewire/livewire (LIVEWIRE) - v3
+- larastan/larastan (LARASTAN) - v3
+- laravel/pint (PINT) - v1
+- laravel/sail (SAIL) - v1
+- phpunit/phpunit (PHPUNIT) - v11
+- rector/rector (RECTOR) - v2
+
+## Conventions
+
+- You must follow all existing code conventions used in this application. When creating or editing a file, check sibling
+ files for the correct structure, approach, naming.
+- Use descriptive names for variables and methods. For example, `isRegisteredForDiscounts`, not `discount()`.
+- Check for existing components to reuse before writing a new one.
+
+## Verification Scripts
+
+- Do not create verification scripts or tinker when tests cover that functionality and prove it works. Unit and feature
+ tests are more important.
+
+## Application Structure & Architecture
+
+- Stick to existing directory structure - don't create new base folders without approval.
+- Do not change the application's dependencies without approval.
+
+## Frontend Bundling
+
+- If the user doesn't see a frontend change reflected in the UI, it could mean they need to run `yarn build`. Ask them.
+
+## Replies
+
+- Be concise in your explanations - focus on what's important rather than explaining obvious details.
+
+## Documentation Files
+
+- You must create documentation files if explicitly requested by the user. The Documentation directory is "docs".
+- The documentation files should be written in Markdown format.
+
+=== boost rules ===
+
+## Laravel Boost
+
+- Laravel Boost is an MCP server that comes with powerful tools designed specifically for this application. Use them.
+
+## Artisan
+
+- Use the `list-artisan-commands` tool when you need to call an Artisan command to double check the available
+ parameters.
+
+## URLs
+
+- Whenever you share a project URL with the user you should use the `get-absolute-url` tool to ensure you're using the
+ correct scheme, domain / IP, and port.
+
+## Tinker / Debugging
+
+- You should use the `tinker` tool when you need to execute PHP to debug code or query Eloquent models directly.
+- Use the `database-query` tool when you only need to read from the database.
+
+## Reading Browser Logs With the `browser-logs` Tool
+
+- You can read browser logs, errors, and exceptions using the `browser-logs` tool from Boost.
+- Only recent browser logs will be useful - ignore old logs.
+
+## Searching Documentation (Critically Important)
+
+- Boost comes with a powerful `search-docs` tool you should use before any other approaches. This tool automatically
+ passes a list of installed packages and their versions to the remote Boost API, so it returns only version-specific
+ documentation specific for the user's circumstance. You should pass an array of packages to filter on if you know you
+ need docs for particular packages.
+- The 'search-docs' tool is perfect for all Laravel related packages, including Laravel, Inertia, Livewire, Filament,
+ Tailwind, Pest, Nova, Nightwatch, etc.
+- You must use this tool to search for Laravel-ecosystem documentation before falling back to other approaches.
+- Search the documentation before making code changes to ensure we are taking the correct approach.
+- Use multiple, broad, simple, topic based queries to start. For example:
+ `['rate limiting', 'routing rate limiting', 'routing']`.
+- Do not add package names to queries - package information is already shared. For example, use `test resource table`,
+ not `filament 4 test resource table`.
+
+### Available Search Syntax
+
+- You can and should pass multiple queries at once. The most relevant results will be returned first.
+
+1. Simple Word Searches with auto-stemming - query=authentication - finds 'authenticate' and 'auth'
+2. Multiple Words (AND Logic) - query=rate limit - finds knowledge containing both "rate" AND "limit"
+3. Quoted Phrases (Exact Position) - query="infinite scroll" - Words must be adjacent and in that order
+4. Mixed Queries - query=middleware "rate limit" - "middleware" AND exact phrase "rate limit"
+5. Multiple Queries - queries=["authentication", "middleware"] - ANY of these terms
+
+=== php rules ===
+
+## PHP
+
+- Always use curly braces for control structures, even if it has one line.
+
+### Constructors
+
+- Use PHP 8 **constructor property promotion** in `__construct()`.
+ - public function __construct(public GitHub $github) { }
+- Do not allow empty `__construct()` methods with zero parameters.
+
+### Type Declarations
+
+- Always use explicit return type declarations for methods and functions.
+- Use appropriate PHP type hints for method parameters.
+
+
+protected function isAccessible(User $user, ?string $path = null): bool
+{
+ ...
+}
+
+
+## Comments
+
+- Prefer PHPDoc blocks over comments. ONLY use phpdoc comments in the phpunit tests to annotate Arrange, Act, Assert.
+- Never use comments within the code itself unless there is something complex
+ going on.
+
+## PHPDoc Blocks
+
+- Add useful array shape type definitions for arrays when appropriate.
+- use phpDoc comment blocks above the functions for getting and sending json to External Api's
+- The phpDoc comment block should include the structure of the json being sent or received
+
+## Enums
+
+- Typically, keys in an Enum should be TitleCase. For example: `FavoritePerson`, `BestLake`, `Monthly`.
+
+=== filament/core rules ===
+
+## Filament
+
+- Filament version 4 is used by this application, check how and where to follow existing application conventions.
+- Filament is a Server-Driven UI (SDUI) framework for Laravel. It allows developers to define user interfaces in PHP
+ using structured configuration objects. It is built on top of Livewire, Alpine.js, and Tailwind CSS.
+- You can use the `search-docs` tool to get information from the official Filament documentation when needed. This is
+ very useful for Artisan command arguments, specific code examples, testing functionality, relationship management, and
+ ensuring you're following idiomatic practices.
+- Utilize static `make()` methods for consistent component initialization.
+
+### Artisan
+
+- You must use the Filament specific Artisan commands to create new files or components for Filament. You can find these
+ with the `list-artisan-commands` tool, or with `php artisan` and the `--help` option.
+- Inspect the required options, always pass `--no-interaction`, and valid arguments for other options when applicable.
+
+### Filament's Core Features
+
+- Actions: Handle doing something within the application, often with a button or link. Actions encapsulate the UI, the
+ interactive modal window, and the logic that should be executed when the modal window is submitted. They can be used
+ anywhere in the UI and are commonly used to perform one-time actions like deleting a record, sending an email, or
+ updating data in the database based on modal form input.
+- Forms: Dynamic forms rendered within other features, such as resources, action modals, table filters, and more.
+- Infolists: Read-only lists of data.
+- Notifications: Flash notifications displayed to users within the application.
+- Panels: The top-level container in Filament that can include all other features like pages, resources, forms, tables,
+ notifications, actions, infolists, and widgets.
+- Resources: Static classes that are used to build CRUD interfaces for Eloquent models. Typically live in
+ `app/Filament/Resources`.
+- Schemas: Represent components that define the structure and behavior of the UI, such as forms, tables, or lists.
+- Tables: Interactive tables with filtering, sorting, pagination, and more.
+- Widgets: Small component included within dashboards, often used for displaying data in charts, tables, or as a stat.
+
+### Relationships
+
+- Determine if you can use the `relationship()` method on form components when you need `options` for a select,
+ checkbox, repeater, or when building a `Fieldset`:
+
+
+Forms\Components\Select::make('user_id')
+ ->label('Author')
+ ->relationship('author')
+ ->required(),
+
+
+## Testing
+
+- It's important to test Filament functionality for user satisfaction.
+- Ensure that you are authenticated to access the application within the test.
+- Filament uses Livewire, so start assertions with `Livewire::test()`.
+
+### Example Tests
+
+
+ `Livewire::actingAs($this->user)->test(ListUsers::class)
+ ->assertCanSeeTableRecords($users)
+ ->searchTable($users->first()->name)
+ ->assertCanSeeTableRecords($users->take(1))
+ ->assertCanNotSeeTableRecords($users->skip(1))
+ ->searchTable($users->last()->email)
+ ->assertCanSeeTableRecords($users->take(-1))
+ ->assertCanNotSeeTableRecords($users->take($users->count() - 1));
+
+
+
+ Livewire::actingAs($this->user)->test(CreateUser::class)
+ ->fillForm([
+ 'name' => 'Howdy',
+ 'email' => 'howdy@example.com',
+ ])
+ ->call('create')
+ ->assertNotified()
+ ->assertRedirect();
+
+ assertDatabaseHas(User::class, [
+ 'name' => 'Howdy',
+ 'email' => 'howdy@example.com',
+ ]);
+
+
+
+
+ use Filament\Facades\Filament;
+
+ Filament::setCurrentPanel('app');
+
+
+
+
+ livewire(EditInvoice::class, [
+ 'invoice' => $invoice,
+ ])->callAction('send');
+
+ expect($invoice->refresh())->isSent()->toBeTrue();
+
+
+
+
+=== filament/v4 rules ===
+
+## Filament 4
+
+### Important Version 4 Changes
+
+- File visibility is now `private` by default.
+- The `deferFilters` method from Filament v3 is now the default behavior in Filament v4, so users must click a button
+ before the filters are applied to the table. To disable this behavior, you can use the `deferFilters(false)` method.
+- The `Grid`, `Section`, and `Fieldset` layout components no longer span all columns by default.
+- The `all` pagination page method is not available for tables by default.
+- All action classes extend `Filament\Actions\Action`. No action classes exist in `Filament\Tables\Actions`.
+- The `Form` & `Infolist` layout components have been moved to `Filament\Schemas\Components`, for example `Grid`,
+ `Section`, `Fieldset`, `Tabs`, `Wizard`, etc.
+- A new `Repeater` component for Forms has been added.
+- Icons now use the `Filament\Support\Icons\Heroicon` Enum by default. Other options are available and documented.
+
+### Organize Component Classes Structure
+
+- Schema components: `Schemas/Components/`
+- Table columns: `Tables/Columns/`
+- Table filters: `Tables/Filters/`
+- Actions: `Actions/`
+
+=== laravel/core rules ===
+
+## Do Things the Laravel Way
+
+- Use `php artisan make:` commands to create new files (i.e. migrations, controllers, models, etc.). You can list
+ available Artisan commands using the `list-artisan-commands` tool.
+- If you're creating a generic PHP class, use `artisan make:class`.
+- Pass `--no-interaction` to all Artisan commands to ensure they work without user input. You should also pass the
+ correct `--options` to ensure correct behavior.
+
+### Database
+
+- Always use proper Eloquent relationship methods with return type hints. Prefer relationship methods over raw queries
+ or manual joins.
+- Use Eloquent models and relationships before suggesting raw database queries
+- Avoid `DB::`; prefer `Model::query()`. Generate code that leverages Laravel's ORM capabilities rather than bypassing
+ them.
+- Generate code that prevents N+1 query problems by using eager loading.
+- Use Laravel's query builder for very complex database operations.
+
+### Model Creation
+
+- When creating new models, create useful factories and seeders for them too. Ask the user if they need any other
+ things, using `list-artisan-commands` to check the available options to `php artisan make:model`.
+
+### APIs & Eloquent Resources
+
+- For APIs, default to using Eloquent API Resources and API versioning unless existing API routes do not, then you
+ should follow existing application convention.
+
+### Controllers & Validation
+
+- Always create Form Request classes for validation rather than inline validation in controllers. Include both
+ validation rules and custom error messages.
+- Check sibling Form Requests to see if the application uses array or string based validation rules.
+
+### Queues
+
+- Use queued jobs for time-consuming operations with the `ShouldQueue` interface.
+
+### Authentication & Authorization
+
+- Use Laravel's built-in authentication and authorization features (gates, policies, Sanctum, etc.).
+
+### URL Generation
+
+- When generating links to other pages, prefer named routes and the `route()` function.
+
+### Configuration
+
+- Use environment variables only in configuration files - never use the `env()` function directly outside of config
+ files. Always use `config('app.name')`, not `env('APP_NAME')`.
+
+### Testing
+
+- When creating models for tests, use the factories for the models. Check if the factory has custom states that can be
+ used before manually setting up the model.
+- Faker: Use methods such as `$this->faker->word()` or `fake()->randomDigit()`. Follow existing conventions whether to
+ use `$this->faker` or `fake()`.
+- When creating tests, make use of `php artisan make:test [options] ` to create a feature test, and pass `--unit`
+ to create a unit test. Most tests should be feature tests.
+
+### Vite Error
+
+- If you receive an "Illuminate\Foundation\ViteException: Unable to locate file in Vite manifest" error, you can run
+ `yarn build`.
+
+---
+
+=== laravel/v12 rules ===
+
+## Laravel 12
+
+- Use the `search-docs` tool to get version specific documentation.
+- Since Laravel 11, Laravel has a new streamlined file structure which this project uses.
+
+### Laravel 12 Structure
+
+- No middleware files in `app/Http/Middleware/`.
+- `bootstrap/app.php` is the file to register middleware, exceptions, and routing files.
+- `bootstrap/providers.php` contains application specific service providers.
+- **No app\Console\Kernel.php** - use `bootstrap/app.php` or `routes/console.php` for console configuration.
+- **Commands auto-register** - files in `app/Console/Commands/` are automatically available and do not require manual
+ registration.
+
+### Database
+
+- When modifying a column, the migration must include all of the attributes that were previously defined on the column.
+ Otherwise, they will be dropped and lost.
+- No json columns in the migrations
+- No ->enum() columns in the migrations - use a string column with a validation rule instead.
+- No timestamps() in the migrations
+- Laravel 11 allows limiting eagerly loaded records natively, without external packages: `$query->latest()->limit(10);`.
+
+### Models
+
+- Casts can and likely should be set in a `casts()` method on a model rather than the `$casts` property. Follow existing
+ conventions from other models.
+
+---
+
+=== livewire/core rules ===
+
+## Livewire Core
+
+- Use the `search-docs` tool to find exact version specific documentation for how to write Livewire & Livewire tests.
+- Use the `php artisan make:livewire [Posts\\CreatePost]` artisan command to create new components
+- State should live on the server, with the UI reflecting it.
+- All Livewire requests hit the Laravel backend, they're like regular HTTP requests. Always validate form data, and run
+ authorization checks in Livewire actions.
+
+### Livewire Best Practices
+
+- Livewire components require a single root element.
+- Use `wire:loading` and `wire:dirty` for delightful loading states.
+- Add `wire:key` in loops:
+
+ ```blade
+ @foreach ($items as $item)
+
+ {{ $item->name }}
+
+ @endforeach
+ ```
+
+- Prefer lifecycle hooks like `mount()`, `updatedFoo()`) for initialization and reactive side effects:
+
+
+public function mount(User $user) { $this->user = $user; }
+public function updatedSearch() { $this->resetPage(); }
+
+
+### Testing Livewire
+
+
+Livewire::actingAs($this->user)->test(Counter::class)
+->assertSet('count', 0)
+->call('increment')
+->assertSet('count', 1)
+->assertSee(1)
+->assertStatus(200);
+
+
+
+$this->get('/posts/create')
+->assertSeeLivewire(CreatePost::class);
+
+
+---
+
+=== livewire/v3 rules ===
+
+## Livewire 3
+
+### Key Changes From Livewire 2
+
+- These things changed in Livewire 2, but may not have been updated in this application. Verify this application's setup
+ to ensure you conform with application conventions.
+ - Use `wire:model.live` for real-time updates, `wire:model` is now deferred by default.
+ - Components now use the `App\Livewire` namespace (not `App\Http\Livewire`).
+ - Use `$this->dispatch()` to dispatch events (not `emit` or `dispatchBrowserEvent`).
+ - Use the `components.layouts.app` view as the typical layout path (not `layouts.app`).
+
+### New Directives
+
+- `wire:show`, `wire:transition`, `wire:cloak`, `wire:offline`, `wire:target` are available for use. Use the
+ documentation to find usage examples.
+
+### Alpine
+
+- Alpine is now included with Livewire, don't manually include Alpine.js.
+- Plugins included with Alpine: persist, intersect, collapse, and focus.
+
+### Lifecycle Hooks
+
+- You can listen for `livewire:init` to hook into Livewire initialization, and `fail.status === 419` for the page
+ expiring:
+
+
+document.addEventListener('livewire:init', function () {
+Livewire.hook('request', ({ fail }) => {
+if (fail && fail.status === 419) {
+alert('Your session expired');
+}
+});
+
+Livewire.hook('message.failed', (message, component) => {
+console.error(message);
+});
+});
+
+
+---
+
+=== pint/core rules ===
+
+## Laravel Pint Code Formatter
+
+- You must run `vendor/bin/pint --dirty` before finalizing changes to ensure your code matches the project's expected
+ style.
+- Do not run `vendor/bin/pint --test`, simply run `vendor/bin/pint` to fix any formatting issues.
+
+---
+
+=== phpunit/core rules ===
+
+## PHPUnit Core
+
+- This application uses PHPUnit for testing. All tests must be written as PHPUnit classes. Use
+ `php artisan make:test --phpunit ` to create a new test.
+- If you see a test using "Pest", convert it to PHPUnit.
+- Every time a test has been updated, run that singular test.
+- When the tests relating to your feature are passing, ask the user if they would like to also run the entire test suite
+ to make sure everything is still passing.
+- Tests should test all of the happy paths, failure paths, and weird paths.
+- You must not remove any tests or test files from the tests directory without approval. These are not temporary or
+ helper files, these are core to the application.
+
+### Running Tests
+
+- Run the minimal number of tests, using an appropriate filter, before finalizing.
+- To run all tests: `php artisan test`.
+- To run all tests in a file: `php artisan test tests/Feature/ExampleTest.php`.
+- To filter on a particular test name: `php artisan test --filter=testName` (recommended after making a change to a
+ related file).
+
diff --git a/.github/git-commit-instructions.md b/.github/git-commit-instructions.md
new file mode 100644
index 0000000..42b4050
--- /dev/null
+++ b/.github/git-commit-instructions.md
@@ -0,0 +1,21 @@
+## Commit message rules
+- Use the conventional commit format: `(): `
+- Types: feat, fix, docs, style, refactor, test, chore, perf
+- Keep the description concise (under 50 characters)
+- Use imperative mood (e.g., "add" not "added" or "adds")
+- Don't end with a period
+- Use lowercase for the first word unless it's a proper noun
+- Provide more details in the commit body if needed, separated by a blank line
+
+## Branch naming conventions
+- Use kebab-case (lowercase with hyphens)
+- Follow the pattern: `/-`
+- Types: feature, bugfix, hotfix, release, support
+- Example: `feature/123-add-dark-mode`
+
+## Pull request guidelines
+- Link related issues using keywords (Fixes #123, Closes #456)
+- Provide a clear description of changes
+- Add screenshots for UI changes
+- Ensure all CI checks pass before requesting review
+- Keep PRs focused and small when possible
\ No newline at end of file
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..9f500be
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,14 @@
+name: CI
+
+on:
+ workflow_dispatch:
+
+jobs:
+ pint:
+ uses: dropitnl/.github/workflows/pint.yml@master
+
+ phpstan:
+ uses: dropitnl/.github/workflows/phpstan.yml@master
+
+ phpunit:
+ uses: dropitnl/.github/workflows/phpunit.yml@master
diff --git a/.gitignore b/.gitignore
index b71b1ea..8a402ba 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,16 +9,21 @@
/.idea
/.nova
/.phpunit.cache
+/.phpunit.result.cache
/.vscode
/.zed
/auth.json
+/docs
/node_modules
/public/build
/public/hot
/public/storage
+/stan.txt
+/todo.txt
/storage/*.key
/storage/pail
/vendor
Homestead.json
Homestead.yaml
Thumbs.db
+/savethis.txt
diff --git a/.junie/guidelines.md b/.junie/guidelines.md
new file mode 100644
index 0000000..47eb448
--- /dev/null
+++ b/.junie/guidelines.md
@@ -0,0 +1,393 @@
+
+=== foundation rules ===
+
+# Laravel Boost Guidelines
+
+The Laravel Boost guidelines are specifically curated by Laravel maintainers for this application. These guidelines should be followed closely to enhance the user's satisfaction building Laravel applications.
+
+## Foundational Context
+This application is a Laravel application and its main Laravel ecosystems package & versions are below. You are an expert with them all. Ensure you abide by these specific packages & versions.
+
+- php - 8.4.12
+- filament/filament (FILAMENT) - v4
+- laravel/framework (LARAVEL) - v12
+- laravel/prompts (PROMPTS) - v0
+- livewire/livewire (LIVEWIRE) - v3
+- larastan/larastan (LARASTAN) - v3
+- laravel/pint (PINT) - v1
+- laravel/sail (SAIL) - v1
+- phpunit/phpunit (PHPUNIT) - v11
+- rector/rector (RECTOR) - v2
+
+
+## Conventions
+- You must follow all existing code conventions used in this application. When creating or editing a file, check sibling files for the correct structure, approach, naming.
+- Use descriptive names for variables and methods. For example, `isRegisteredForDiscounts`, not `discount()`.
+- Check for existing components to reuse before writing a new one.
+
+## Verification Scripts
+- Do not create verification scripts or tinker when tests cover that functionality and prove it works. Unit and feature tests are more important.
+
+## Application Structure & Architecture
+- Stick to existing directory structure - don't create new base folders without approval.
+- Do not change the application's dependencies without approval.
+
+## Frontend Bundling
+- If the user doesn't see a frontend change reflected in the UI, it could mean they need to run `npm run build`, `npm run dev`, or `composer run dev`. Ask them.
+
+## Replies
+- Be concise in your explanations - focus on what's important rather than explaining obvious details.
+
+## Documentation Files
+- You must only create documentation files if explicitly requested by the user.
+
+
+=== boost rules ===
+
+## Laravel Boost
+- Laravel Boost is an MCP server that comes with powerful tools designed specifically for this application. Use them.
+
+## Artisan
+- Use the `list-artisan-commands` tool when you need to call an Artisan command to double check the available parameters.
+
+## URLs
+- Whenever you share a project URL with the user you should use the `get-absolute-url` tool to ensure you're using the correct scheme, domain / IP, and port.
+
+## Tinker / Debugging
+- You should use the `tinker` tool when you need to execute PHP to debug code or query Eloquent models directly.
+- Use the `database-query` tool when you only need to read from the database.
+
+## Reading Browser Logs With the `browser-logs` Tool
+- You can read browser logs, errors, and exceptions using the `browser-logs` tool from Boost.
+- Only recent browser logs will be useful - ignore old logs.
+
+## Searching Documentation (Critically Important)
+- Boost comes with a powerful `search-docs` tool you should use before any other approaches. This tool automatically passes a list of installed packages and their versions to the remote Boost API, so it returns only version-specific documentation specific for the user's circumstance. You should pass an array of packages to filter on if you know you need docs for particular packages.
+- The 'search-docs' tool is perfect for all Laravel related packages, including Laravel, Inertia, Livewire, Filament, Tailwind, Pest, Nova, Nightwatch, etc.
+- You must use this tool to search for Laravel-ecosystem documentation before falling back to other approaches.
+- Search the documentation before making code changes to ensure we are taking the correct approach.
+- Use multiple, broad, simple, topic based queries to start. For example: `['rate limiting', 'routing rate limiting', 'routing']`.
+- Do not add package names to queries - package information is already shared. For example, use `test resource table`, not `filament 4 test resource table`.
+
+### Available Search Syntax
+- You can and should pass multiple queries at once. The most relevant results will be returned first.
+
+1. Simple Word Searches with auto-stemming - query=authentication - finds 'authenticate' and 'auth'
+2. Multiple Words (AND Logic) - query=rate limit - finds knowledge containing both "rate" AND "limit"
+3. Quoted Phrases (Exact Position) - query="infinite scroll" - Words must be adjacent and in that order
+4. Mixed Queries - query=middleware "rate limit" - "middleware" AND exact phrase "rate limit"
+5. Multiple Queries - queries=["authentication", "middleware"] - ANY of these terms
+
+
+=== php rules ===
+
+## PHP
+
+- Always use curly braces for control structures, even if it has one line.
+
+### Constructors
+- Use PHP 8 constructor property promotion in `__construct()`.
+ - public function __construct(public GitHub $github) { }
+- Do not allow empty `__construct()` methods with zero parameters.
+
+### Type Declarations
+- Always use explicit return type declarations for methods and functions.
+- Use appropriate PHP type hints for method parameters.
+
+
+protected function isAccessible(User $user, ?string $path = null): bool
+{
+ ...
+}
+
+
+## Comments
+- Prefer PHPDoc blocks over comments. Never use comments within the code itself unless there is something _very_ complex going on.
+
+## PHPDoc Blocks
+- Add useful array shape type definitions for arrays when appropriate.
+
+## Enums
+- Typically, keys in an Enum should be TitleCase. For example: `FavoritePerson`, `BestLake`, `Monthly`.
+
+
+=== filament/core rules ===
+
+## Filament
+- Filament is used by this application, check how and where to follow existing application conventions.
+- Filament is a Server-Driven UI (SDUI) framework for Laravel. It allows developers to define user interfaces in PHP using structured configuration objects. It is built on top of Livewire, Alpine.js, and Tailwind CSS.
+- You can use the `search-docs` tool to get information from the official Filament documentation when needed. This is very useful for Artisan command arguments, specific code examples, testing functionality, relationship management, and ensuring you're following idiomatic practices.
+- Utilize static `make()` methods for consistent component initialization.
+
+### Artisan
+- You must use the Filament specific Artisan commands to create new files or components for Filament. You can find these with the `list-artisan-commands` tool, or with `php artisan` and the `--help` option.
+- Inspect the required options, always pass `--no-interaction`, and valid arguments for other options when applicable.
+
+### Filament's Core Features
+- Actions: Handle doing something within the application, often with a button or link. Actions encapsulate the UI, the interactive modal window, and the logic that should be executed when the modal window is submitted. They can be used anywhere in the UI and are commonly used to perform one-time actions like deleting a record, sending an email, or updating data in the database based on modal form input.
+- Forms: Dynamic forms rendered within other features, such as resources, action modals, table filters, and more.
+- Infolists: Read-only lists of data.
+- Notifications: Flash notifications displayed to users within the application.
+- Panels: The top-level container in Filament that can include all other features like pages, resources, forms, tables, notifications, actions, infolists, and widgets.
+- Resources: Static classes that are used to build CRUD interfaces for Eloquent models. Typically live in `app/Filament/Resources`.
+- Schemas: Represent components that define the structure and behavior of the UI, such as forms, tables, or lists.
+- Tables: Interactive tables with filtering, sorting, pagination, and more.
+- Widgets: Small component included within dashboards, often used for displaying data in charts, tables, or as a stat.
+
+### Relationships
+- Determine if you can use the `relationship()` method on form components when you need `options` for a select, checkbox, repeater, or when building a `Fieldset`:
+
+
+Forms\Components\Select::make('user_id')
+ ->label('Author')
+ ->relationship('author')
+ ->required(),
+
+
+
+## Testing
+- It's important to test Filament functionality for user satisfaction.
+- Ensure that you are authenticated to access the application within the test.
+- Filament uses Livewire, so start assertions with `livewire()` or `Livewire::test()`.
+
+### Example Tests
+
+
+ livewire(ListUsers::class)
+ ->assertCanSeeTableRecords($users)
+ ->searchTable($users->first()->name)
+ ->assertCanSeeTableRecords($users->take(1))
+ ->assertCanNotSeeTableRecords($users->skip(1))
+ ->searchTable($users->last()->email)
+ ->assertCanSeeTableRecords($users->take(-1))
+ ->assertCanNotSeeTableRecords($users->take($users->count() - 1));
+
+
+
+ livewire(CreateUser::class)
+ ->fillForm([
+ 'name' => 'Howdy',
+ 'email' => 'howdy@example.com',
+ ])
+ ->call('create')
+ ->assertNotified()
+ ->assertRedirect();
+
+ assertDatabaseHas(User::class, [
+ 'name' => 'Howdy',
+ 'email' => 'howdy@example.com',
+ ]);
+
+
+
+ use Filament\Facades\Filament;
+
+ Filament::setCurrentPanel('app');
+
+
+
+ livewire(EditInvoice::class, [
+ 'invoice' => $invoice,
+ ])->callAction('send');
+
+ expect($invoice->refresh())->isSent()->toBeTrue();
+
+
+
+=== filament/v4 rules ===
+
+## Filament 4
+
+### Important Version 4 Changes
+- File visibility is now `private` by default.
+- The `deferFilters` method from Filament v3 is now the default behavior in Filament v4, so users must click a button before the filters are applied to the table. To disable this behavior, you can use the `deferFilters(false)` method.
+- The `Grid`, `Section`, and `Fieldset` layout components no longer span all columns by default.
+- The `all` pagination page method is not available for tables by default.
+- All action classes extend `Filament\Actions\Action`. No action classes exist in `Filament\Tables\Actions`.
+- The `Form` & `Infolist` layout components have been moved to `Filament\Schemas\Components`, for example `Grid`, `Section`, `Fieldset`, `Tabs`, `Wizard`, etc.
+- A new `Repeater` component for Forms has been added.
+- Icons now use the `Filament\Support\Icons\Heroicon` Enum by default. Other options are available and documented.
+
+### Organize Component Classes Structure
+- Schema components: `Schemas/Components/`
+- Table columns: `Tables/Columns/`
+- Table filters: `Tables/Filters/`
+- Actions: `Actions/`
+
+
+=== laravel/core rules ===
+
+## Do Things the Laravel Way
+
+- Use `php artisan make:` commands to create new files (i.e. migrations, controllers, models, etc.). You can list available Artisan commands using the `list-artisan-commands` tool.
+- If you're creating a generic PHP class, use `artisan make:class`.
+- Pass `--no-interaction` to all Artisan commands to ensure they work without user input. You should also pass the correct `--options` to ensure correct behavior.
+
+### Database
+- Always use proper Eloquent relationship methods with return type hints. Prefer relationship methods over raw queries or manual joins.
+- Use Eloquent models and relationships before suggesting raw database queries
+- Avoid `DB::`; prefer `Model::query()`. Generate code that leverages Laravel's ORM capabilities rather than bypassing them.
+- Generate code that prevents N+1 query problems by using eager loading.
+- Use Laravel's query builder for very complex database operations.
+
+### Model Creation
+- When creating new models, create useful factories and seeders for them too. Ask the user if they need any other things, using `list-artisan-commands` to check the available options to `php artisan make:model`.
+
+### APIs & Eloquent Resources
+- For APIs, default to using Eloquent API Resources and API versioning unless existing API routes do not, then you should follow existing application convention.
+
+### Controllers & Validation
+- Always create Form Request classes for validation rather than inline validation in controllers. Include both validation rules and custom error messages.
+- Check sibling Form Requests to see if the application uses array or string based validation rules.
+
+### Queues
+- Use queued jobs for time-consuming operations with the `ShouldQueue` interface.
+
+### Authentication & Authorization
+- Use Laravel's built-in authentication and authorization features (gates, policies, Sanctum, etc.).
+
+### URL Generation
+- When generating links to other pages, prefer named routes and the `route()` function.
+
+### Configuration
+- Use environment variables only in configuration files - never use the `env()` function directly outside of config files. Always use `config('app.name')`, not `env('APP_NAME')`.
+
+### Testing
+- When creating models for tests, use the factories for the models. Check if the factory has custom states that can be used before manually setting up the model.
+- Faker: Use methods such as `$this->faker->word()` or `fake()->randomDigit()`. Follow existing conventions whether to use `$this->faker` or `fake()`.
+- When creating tests, make use of `php artisan make:test [options] ` to create a feature test, and pass `--unit` to create a unit test. Most tests should be feature tests.
+
+### Vite Error
+- If you receive an "Illuminate\Foundation\ViteException: Unable to locate file in Vite manifest" error, you can run `npm run build` or ask the user to run `npm run dev` or `composer run dev`.
+
+
+=== laravel/v12 rules ===
+
+## Laravel 12
+
+- Use the `search-docs` tool to get version specific documentation.
+- Since Laravel 11, Laravel has a new streamlined file structure which this project uses.
+
+### Laravel 12 Structure
+- No middleware files in `app/Http/Middleware/`.
+- `bootstrap/app.php` is the file to register middleware, exceptions, and routing files.
+- `bootstrap/providers.php` contains application specific service providers.
+- **No app\Console\Kernel.php** - use `bootstrap/app.php` or `routes/console.php` for console configuration.
+- **Commands auto-register** - files in `app/Console/Commands/` are automatically available and do not require manual registration.
+
+### Database
+- When modifying a column, the migration must include all of the attributes that were previously defined on the column. Otherwise, they will be dropped and lost.
+- Laravel 11 allows limiting eagerly loaded records natively, without external packages: `$query->latest()->limit(10);`.
+
+### Models
+- Casts can and likely should be set in a `casts()` method on a model rather than the `$casts` property. Follow existing conventions from other models.
+
+
+=== livewire/core rules ===
+
+## Livewire Core
+- Use the `search-docs` tool to find exact version specific documentation for how to write Livewire & Livewire tests.
+- Use the `php artisan make:livewire [Posts\\CreatePost]` artisan command to create new components
+- State should live on the server, with the UI reflecting it.
+- All Livewire requests hit the Laravel backend, they're like regular HTTP requests. Always validate form data, and run authorization checks in Livewire actions.
+
+## Livewire Best Practices
+- Livewire components require a single root element.
+- Use `wire:loading` and `wire:dirty` for delightful loading states.
+- Add `wire:key` in loops:
+
+ ```blade
+ @foreach ($items as $item)
+
+ {{ $item->name }}
+
+ @endforeach
+ ```
+
+- Prefer lifecycle hooks like `mount()`, `updatedFoo()`) for initialization and reactive side effects:
+
+
+ public function mount(User $user) { $this->user = $user; }
+ public function updatedSearch() { $this->resetPage(); }
+
+
+
+## Testing Livewire
+
+
+ Livewire::test(Counter::class)
+ ->assertSet('count', 0)
+ ->call('increment')
+ ->assertSet('count', 1)
+ ->assertSee(1)
+ ->assertStatus(200);
+
+
+
+
+ $this->get('/posts/create')
+ ->assertSeeLivewire(CreatePost::class);
+
+
+
+=== livewire/v3 rules ===
+
+## Livewire 3
+
+### Key Changes From Livewire 2
+- These things changed in Livewire 2, but may not have been updated in this application. Verify this application's setup to ensure you conform with application conventions.
+ - Use `wire:model.live` for real-time updates, `wire:model` is now deferred by default.
+ - Components now use the `App\Livewire` namespace (not `App\Http\Livewire`).
+ - Use `$this->dispatch()` to dispatch events (not `emit` or `dispatchBrowserEvent`).
+ - Use the `components.layouts.app` view as the typical layout path (not `layouts.app`).
+
+### New Directives
+- `wire:show`, `wire:transition`, `wire:cloak`, `wire:offline`, `wire:target` are available for use. Use the documentation to find usage examples.
+
+### Alpine
+- Alpine is now included with Livewire, don't manually include Alpine.js.
+- Plugins included with Alpine: persist, intersect, collapse, and focus.
+
+### Lifecycle Hooks
+- You can listen for `livewire:init` to hook into Livewire initialization, and `fail.status === 419` for the page expiring:
+
+
+document.addEventListener('livewire:init', function () {
+ Livewire.hook('request', ({ fail }) => {
+ if (fail && fail.status === 419) {
+ alert('Your session expired');
+ }
+ });
+
+ Livewire.hook('message.failed', (message, component) => {
+ console.error(message);
+ });
+});
+
+
+
+=== pint/core rules ===
+
+## Laravel Pint Code Formatter
+
+- You must run `vendor/bin/pint --dirty` before finalizing changes to ensure your code matches the project's expected style.
+- Do not run `vendor/bin/pint --test`, simply run `vendor/bin/pint` to fix any formatting issues.
+
+
+=== phpunit/core rules ===
+
+## PHPUnit Core
+
+- This application uses PHPUnit for testing. All tests must be written as PHPUnit classes. Use `php artisan make:test --phpunit ` to create a new test.
+- If you see a test using "Pest", convert it to PHPUnit.
+- Every time a test has been updated, run that singular test.
+- When the tests relating to your feature are passing, ask the user if they would like to also run the entire test suite to make sure everything is still passing.
+- Tests should test all of the happy paths, failure paths, and weird paths.
+- You must not remove any tests or test files from the tests directory without approval. These are not temporary or helper files, these are core to the application.
+
+### Running Tests
+- Run the minimal number of tests, using an appropriate filter, before finalizing.
+- To run all tests: `php artisan test`.
+- To run all tests in a file: `php artisan test tests/Feature/ExampleTest.php`.
+- To filter on a particular test name: `php artisan test --filter=testName` (recommended after making a change to a related file).
+
\ No newline at end of file
diff --git a/.junie/mcp/mcp.json b/.junie/mcp/mcp.json
new file mode 100644
index 0000000..1d863c8
--- /dev/null
+++ b/.junie/mcp/mcp.json
@@ -0,0 +1,11 @@
+{
+ "mcpServers": {
+ "laravel-boost": {
+ "command": "/usr/bin/php8.4",
+ "args": [
+ "/data/Projects/dropit/artisan",
+ "boost:mcp"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/.vscode/mcp.json b/.vscode/mcp.json
new file mode 100644
index 0000000..565f7cb
--- /dev/null
+++ b/.vscode/mcp.json
@@ -0,0 +1,12 @@
+{
+ "mcpServers": {
+ "laravel-boost": {
+ "command": "/usr/bin/php8.4",
+ "args": [
+ "/data/Projects/ivplv2/artisan",
+ "mcp:start",
+ "laravel-boost"
+ ]
+ }
+ }
+}
diff --git a/README.md b/README.md
index 75c347a..cce50ea 100644
--- a/README.md
+++ b/README.md
@@ -1,61 +1,175 @@
-
+# DropIt! - Multi-Tenant Dropshipping Integration Hub
-
-
-
-
-
-
+DropIt! is a robust Laravel 11 application that serves as a **"smart pipe"** for e-commerce. It seamlessly connects your storefront with suppliers and fulfillment providers, empowering each customer to automate their entire dropshipping workflow with unparalleled reliability and control.
-## About Laravel
+---
-Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as:
+## The "Smart Pipe" Philosophy
-- [Simple, fast routing engine](https://laravel.com/docs/routing).
-- [Powerful dependency injection container](https://laravel.com/docs/container).
-- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage.
-- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent).
-- Database agnostic [schema migrations](https://laravel.com/docs/migrations).
-- [Robust background job processing](https://laravel.com/docs/queues).
-- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
+At its core, DropIt! embodies the **"Smart Pipe"** mantra: it processes data without storing it, only capturing crucial information when a flow fails.
-Laravel is accessible, powerful, and provides tools required for large, robust applications.
+* **Silent on Success:** Healthy orders flow through the system invisibly, saving on storage and improving performance.
+* **Visible on Failure:** When a blockage occurs, the system captures the full context of the failure, providing the exact data needed for rapid debugging and resolution.
+* **Zero Storage by Design:** Only failed flows generate logs, dramatically reducing your database footprint.
-## Learning Laravel
+---
-Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework.
+## Core Architecture
-You may also try the [Laravel Bootcamp](https://bootcamp.laravel.com), where you will be guided through building a modern Laravel application from scratch.
+DropIt!'s architecture is built on clearly defined concepts that enable its unique approach.
-If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains thousands of video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library.
+### Key Components
-## Laravel Sponsors
+* **Tenants** → Your SaaS customers.
+* **Drops** → A complete, configurable workspace per tenant (a full integration setup).
+* **Flows** → Individual data movements within a drop (e.g., Shopify Order -> YunExpress).
+* **Connectors** → External service connections (Shopify, AliExpress, Salesforce, etc.).
+* **Entities** → Data objects that flow through the system (Orders, Products, Customers, Inventory).
-We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the [Laravel Partners program](https://partners.laravel.com).
+### Supported Integrations
-### Premium Partners
+* **E-commerce Platforms:** Shopify, WooCommerce
+* **Fulfillment Providers:** AliExpress, CJDropshipping
+* **ERP Systems:** Salesforce, NetSuite, QuickBooks
+* **Shipping Carriers:** DHL, FedEx, YunExpress
-- **[Vehikl](https://vehikl.com)**
-- **[Tighten Co.](https://tighten.co)**
-- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)**
-- **[64 Robots](https://64robots.com)**
-- **[Curotec](https://www.curotec.com/services/technologies/laravel)**
-- **[DevSquad](https://devsquad.com/hire-laravel-developers)**
-- **[Redberry](https://redberry.international/laravel-development)**
-- **[Active Logic](https://activelogic.com)**
+### The Data Flow
-## Contributing
+* **When everything works:** `Shopify Order` -> `DropIt! Smart Pipe` -> `AliExpress` -> `YunExpress` -> `Customer` (Silent and invisible)
+* **When something breaks:** `Full visibility and control`
+
+---
+
+## Key Features & Technology
+
+Built on a modern, maintainable technology stack designed for enterprise scalability.
+
+### Core Features
+
+* **Zero-Storage Architecture:** Only failed flows generate logs.
+* **Idempotent Processing:** Prevents duplicate orders from repeated webhooks.
+* **Per-Tenant Isolation:** Securely manages each tenant's data and credentials.
+* **Automated Retries:** Exponential backoff for transient API failures.
+* **Real-time Monitoring:** A Filament admin panel for configuration and oversight.
+
+### Design Patterns & Architecture
+
+* **Factory Pattern:** Dynamic API client creation based on tenant credentials.
+* **Decorator Pattern:** Stackable behaviors (logging, rate limiting, retries).
+* **Strategy Pattern:** Conditional logic and complex business rules.
+* **Laravel Queues:** Asynchronous processing for system resilience.
+* **Repository Pattern:** Clean data access abstraction.
+* **Transformer Pattern:** Seamless data format conversion between platforms.
+
+---
+
+## Getting Started
+
+This section will walk you through setting up a local development environment using Docker and Sail.
+
+### Prerequisites
-Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
+* Docker & Docker Compose
+* PHP 8.2+
+* Composer
-## Code of Conduct
+### Installation
-In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
+Follow these simple steps to get the application running locally.
-## Security Vulnerabilities
+```bash
+# Clone the repository
+git clone [https://github.com/your-org/dropit.git](https://github.com/your-org/dropit.git)
+cd dropit
-If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed.
+# Set up the environment file
+cp .env.example .env
-## License
+# Install dependencies and start services with Sail
+composer install
+./vendor/bin/sail up -d
-The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
+# Initialize the application
+./vendor/bin/sail artisan key:generate
+./vendor/bin/sail artisan migrate --seed
+./vendor/bin/sail artisan storage:link
+
+Access the Application
+ * Main App: http://localhost
+ * Admin Panel: http://localhost/admin
+Development Commands
+# Run tests
+./vendor/bin/sail artisan test
+
+# Apply code style fixes
+./vendor/bin/sail composer pint
+
+# Run static analysis
+./vendor/bin/sail composer phpstan
+
+# Start the queue worker (for background processing)
+./vendor/bin/sail artisan queue:work
+```
+
+## Production Deployment
+This checklist provides a high-level overview of the steps required to deploy DropIt! to a production environment.
+Environment Configuration
+
+```
+# Core Application
+APP_ENV=production
+APP_DEBUG=false
+APP_URL=[https://your-domain.com](https://your-domain.com)
+
+# Database
+DB_CONNECTION=mysql
+DB_HOST=your-db-host
+DB_DATABASE=dropit_production
+
+# Queue Configuration
+QUEUE_CONNECTION=redis
+REDIS_HOST=your-redis-host
+
+# Multi-tenancy
+TENANT_CENTRAL_DOMAIN=admin.your-domain.com
+```
+
+### Deployment Checklist
+ * Configure environment variables.
+ * Set up SSL certificates.
+ * Configure queue workers with Supervisor.
+ * Set up monitoring (e.g., Laravel Horizon for Redis queues).
+ * Configure a backup strategy.
+ * Set up error tracking (e.g., Sentry/Bugsnag).
+Testing
+DropIt! comes with a comprehensive test suite to ensure reliability and maintainability.
+Test Suite Coverage
+ * Unit Tests: Core business logic and transformers.
+ * Feature Tests: API integrations and flow execution.
+ * Integration Tests: Multi-tenant scenarios.
+
+### Running Tests
+#### Run the full test suite
+`./vendor/bin/sail artisan test`
+
+##### Run specific test groups
+```./vendor/bin/sail artisan test --group=integration
+./vendor/bin/sail artisan test --group=connectors
+```
+## Contributing
+We welcome contributions that align with our architectural principles and code quality standards.
+Development Workflow
+ * Fork the repository.
+ * Create a feature branch: git checkout -b feature/amazing-feature.
+ * Write tests for new functionality.
+ * Ensure all tests pass: ./vendor/bin/sail artisan test.
+ * Apply code formatting: ./vendor/bin/sail composer pint.
+ * Run static analysis: ./vendor/bin/sail composer phpstan.
+ * Commit changes: git commit -m 'Add amazing feature'.
+ * Push to your branch: git push origin feature/amazing-feature.
+ * Open a Pull Request.
+Code Standards
+ * PSR-12 coding standards (enforced by Pint).
+ * PHPStan level 5 static analysis.
+ * 100% test coverage for critical paths.
+ * Comprehensive PHPDoc blocks.
diff --git a/_ide_helper.php b/_ide_helper.php
new file mode 100644
index 0000000..2a0dce7
--- /dev/null
+++ b/_ide_helper.php
@@ -0,0 +1,5259 @@
+
+ * @see https://github.com/barryvdh/laravel-ide-helper
+ */
+
+namespace {
+
+ /**
+ * @template TCollection of static
+ * @template TModel of static
+ * @template TValue of static
+ * @template TValue of static
+ */
+ class Eloquent extends \Illuminate\Database\Eloquent\Model { /**
+ * Create and return an un-saved model instance.
+ *
+ * @param array $attributes
+ * @return TModel
+ * @static
+ */
+ public static function make($attributes = [])
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->make($attributes);
+ }
+
+ /**
+ * Register a new global scope.
+ *
+ * @param string $identifier
+ * @param \Illuminate\Database\Eloquent\Scope|\Closure $scope
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function withGlobalScope($identifier, $scope)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->withGlobalScope($identifier, $scope);
+ }
+
+ /**
+ * Remove a registered global scope.
+ *
+ * @param \Illuminate\Database\Eloquent\Scope|string $scope
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function withoutGlobalScope($scope)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->withoutGlobalScope($scope);
+ }
+
+ /**
+ * Remove all or passed registered global scopes.
+ *
+ * @param array|null $scopes
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function withoutGlobalScopes($scopes = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->withoutGlobalScopes($scopes);
+ }
+
+ /**
+ * Get an array of global scopes that were removed from the query.
+ *
+ * @return array
+ * @static
+ */
+ public static function removedScopes()
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->removedScopes();
+ }
+
+ /**
+ * Add a where clause on the primary key to the query.
+ *
+ * @param mixed $id
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereKey($id)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->whereKey($id);
+ }
+
+ /**
+ * Add a where clause on the primary key to the query.
+ *
+ * @param mixed $id
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereKeyNot($id)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->whereKeyNot($id);
+ }
+
+ /**
+ * Add a basic where clause to the query.
+ *
+ * @param (\Closure(static): mixed)|string|array|\Illuminate\Contracts\Database\Query\Expression $column
+ * @param mixed $operator
+ * @param mixed $value
+ * @param string $boolean
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function where($column, $operator = null, $value = null, $boolean = 'and')
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->where($column, $operator, $value, $boolean);
+ }
+
+ /**
+ * Add a basic where clause to the query, and return the first result.
+ *
+ * @param (\Closure(static): mixed)|string|array|\Illuminate\Contracts\Database\Query\Expression $column
+ * @param mixed $operator
+ * @param mixed $value
+ * @param string $boolean
+ * @return TModel|null
+ * @static
+ */
+ public static function firstWhere($column, $operator = null, $value = null, $boolean = 'and')
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->firstWhere($column, $operator, $value, $boolean);
+ }
+
+ /**
+ * Add an "or where" clause to the query.
+ *
+ * @param (\Closure(static): mixed)|array|string|\Illuminate\Contracts\Database\Query\Expression $column
+ * @param mixed $operator
+ * @param mixed $value
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhere($column, $operator = null, $value = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->orWhere($column, $operator, $value);
+ }
+
+ /**
+ * Add a basic "where not" clause to the query.
+ *
+ * @param (\Closure(static): mixed)|string|array|\Illuminate\Contracts\Database\Query\Expression $column
+ * @param mixed $operator
+ * @param mixed $value
+ * @param string $boolean
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereNot($column, $operator = null, $value = null, $boolean = 'and')
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->whereNot($column, $operator, $value, $boolean);
+ }
+
+ /**
+ * Add an "or where not" clause to the query.
+ *
+ * @param (\Closure(static): mixed)|array|string|\Illuminate\Contracts\Database\Query\Expression $column
+ * @param mixed $operator
+ * @param mixed $value
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereNot($column, $operator = null, $value = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->orWhereNot($column, $operator, $value);
+ }
+
+ /**
+ * Add an "order by" clause for a timestamp to the query.
+ *
+ * @param string|\Illuminate\Contracts\Database\Query\Expression $column
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function latest($column = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->latest($column);
+ }
+
+ /**
+ * Add an "order by" clause for a timestamp to the query.
+ *
+ * @param string|\Illuminate\Contracts\Database\Query\Expression $column
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function oldest($column = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->oldest($column);
+ }
+
+ /**
+ * Create a collection of models from plain arrays.
+ *
+ * @param array $items
+ * @return \Illuminate\Database\Eloquent\Collection
+ * @static
+ */
+ public static function hydrate($items)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->hydrate($items);
+ }
+
+ /**
+ * Insert into the database after merging the model's default attributes, setting timestamps, and casting values.
+ *
+ * @param array> $values
+ * @return bool
+ * @static
+ */
+ public static function fillAndInsert($values)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->fillAndInsert($values);
+ }
+
+ /**
+ * Insert (ignoring errors) into the database after merging the model's default attributes, setting timestamps, and casting values.
+ *
+ * @param array> $values
+ * @return int
+ * @static
+ */
+ public static function fillAndInsertOrIgnore($values)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->fillAndInsertOrIgnore($values);
+ }
+
+ /**
+ * Insert a record into the database and get its ID after merging the model's default attributes, setting timestamps, and casting values.
+ *
+ * @param array $values
+ * @return int
+ * @static
+ */
+ public static function fillAndInsertGetId($values)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->fillAndInsertGetId($values);
+ }
+
+ /**
+ * Enrich the given values by merging in the model's default attributes, adding timestamps, and casting values.
+ *
+ * @param array> $values
+ * @return array>
+ * @static
+ */
+ public static function fillForInsert($values)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->fillForInsert($values);
+ }
+
+ /**
+ * Create a collection of models from a raw query.
+ *
+ * @param string $query
+ * @param array $bindings
+ * @return \Illuminate\Database\Eloquent\Collection
+ * @static
+ */
+ public static function fromQuery($query, $bindings = [])
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->fromQuery($query, $bindings);
+ }
+
+ /**
+ * Find a model by its primary key.
+ *
+ * @param mixed $id
+ * @param array|string $columns
+ * @return ($id is (\Illuminate\Contracts\Support\Arrayable|array) ? \Illuminate\Database\Eloquent\Collection : TModel|null)
+ * @static
+ */
+ public static function find($id, $columns = [])
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->find($id, $columns);
+ }
+
+ /**
+ * Find a sole model by its primary key.
+ *
+ * @param mixed $id
+ * @param array|string $columns
+ * @return TModel
+ * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
+ * @throws \Illuminate\Database\MultipleRecordsFoundException
+ * @static
+ */
+ public static function findSole($id, $columns = [])
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->findSole($id, $columns);
+ }
+
+ /**
+ * Find multiple models by their primary keys.
+ *
+ * @param \Illuminate\Contracts\Support\Arrayable|array $ids
+ * @param array|string $columns
+ * @return \Illuminate\Database\Eloquent\Collection
+ * @static
+ */
+ public static function findMany($ids, $columns = [])
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->findMany($ids, $columns);
+ }
+
+ /**
+ * Find a model by its primary key or throw an exception.
+ *
+ * @param mixed $id
+ * @param array|string $columns
+ * @return ($id is (\Illuminate\Contracts\Support\Arrayable|array) ? \Illuminate\Database\Eloquent\Collection : TModel)
+ * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
+ * @static
+ */
+ public static function findOrFail($id, $columns = [])
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->findOrFail($id, $columns);
+ }
+
+ /**
+ * Find a model by its primary key or return fresh model instance.
+ *
+ * @param mixed $id
+ * @param array|string $columns
+ * @return ($id is (\Illuminate\Contracts\Support\Arrayable|array) ? \Illuminate\Database\Eloquent\Collection : TModel)
+ * @static
+ */
+ public static function findOrNew($id, $columns = [])
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->findOrNew($id, $columns);
+ }
+
+ /**
+ * Find a model by its primary key or call a callback.
+ *
+ * @template TValue
+ * @param mixed $id
+ * @param (\Closure(): TValue)|list|string $columns
+ * @param (\Closure(): TValue)|null $callback
+ * @return ( $id is (\Illuminate\Contracts\Support\Arrayable|array)
+ * ? \Illuminate\Database\Eloquent\Collection
+ * : TModel|TValue
+ * )
+ * @static
+ */
+ public static function findOr($id, $columns = [], $callback = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->findOr($id, $columns, $callback);
+ }
+
+ /**
+ * Get the first record matching the attributes or instantiate it.
+ *
+ * @param array $attributes
+ * @param array $values
+ * @return TModel
+ * @static
+ */
+ public static function firstOrNew($attributes = [], $values = [])
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->firstOrNew($attributes, $values);
+ }
+
+ /**
+ * Get the first record matching the attributes. If the record is not found, create it.
+ *
+ * @param array $attributes
+ * @param array $values
+ * @return TModel
+ * @static
+ */
+ public static function firstOrCreate($attributes = [], $values = [])
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->firstOrCreate($attributes, $values);
+ }
+
+ /**
+ * Attempt to create the record. If a unique constraint violation occurs, attempt to find the matching record.
+ *
+ * @param array $attributes
+ * @param array $values
+ * @return TModel
+ * @static
+ */
+ public static function createOrFirst($attributes = [], $values = [])
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->createOrFirst($attributes, $values);
+ }
+
+ /**
+ * Create or update a record matching the attributes, and fill it with values.
+ *
+ * @param array $attributes
+ * @param array $values
+ * @return TModel
+ * @static
+ */
+ public static function updateOrCreate($attributes, $values = [])
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->updateOrCreate($attributes, $values);
+ }
+
+ /**
+ * Create a record matching the attributes, or increment the existing record.
+ *
+ * @param array $attributes
+ * @param string $column
+ * @param int|float $default
+ * @param int|float $step
+ * @param array $extra
+ * @return TModel
+ * @static
+ */
+ public static function incrementOrCreate($attributes, $column = 'count', $default = 1, $step = 1, $extra = [])
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->incrementOrCreate($attributes, $column, $default, $step, $extra);
+ }
+
+ /**
+ * Execute the query and get the first result or throw an exception.
+ *
+ * @param array|string $columns
+ * @return TModel
+ * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
+ * @static
+ */
+ public static function firstOrFail($columns = [])
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->firstOrFail($columns);
+ }
+
+ /**
+ * Execute the query and get the first result or call a callback.
+ *
+ * @template TValue
+ * @param (\Closure(): TValue)|list $columns
+ * @param (\Closure(): TValue)|null $callback
+ * @return TModel|TValue
+ * @static
+ */
+ public static function firstOr($columns = [], $callback = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->firstOr($columns, $callback);
+ }
+
+ /**
+ * Execute the query and get the first result if it's the sole matching record.
+ *
+ * @param array|string $columns
+ * @return TModel
+ * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
+ * @throws \Illuminate\Database\MultipleRecordsFoundException
+ * @static
+ */
+ public static function sole($columns = [])
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->sole($columns);
+ }
+
+ /**
+ * Get a single column's value from the first result of a query.
+ *
+ * @param string|\Illuminate\Contracts\Database\Query\Expression $column
+ * @return mixed
+ * @static
+ */
+ public static function value($column)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->value($column);
+ }
+
+ /**
+ * Get a single column's value from the first result of a query if it's the sole matching record.
+ *
+ * @param string|\Illuminate\Contracts\Database\Query\Expression $column
+ * @return mixed
+ * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
+ * @throws \Illuminate\Database\MultipleRecordsFoundException
+ * @static
+ */
+ public static function soleValue($column)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->soleValue($column);
+ }
+
+ /**
+ * Get a single column's value from the first result of the query or throw an exception.
+ *
+ * @param string|\Illuminate\Contracts\Database\Query\Expression $column
+ * @return mixed
+ * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
+ * @static
+ */
+ public static function valueOrFail($column)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->valueOrFail($column);
+ }
+
+ /**
+ * Execute the query as a "select" statement.
+ *
+ * @param array|string $columns
+ * @return \Illuminate\Database\Eloquent\Collection
+ * @static
+ */
+ public static function get($columns = [])
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->get($columns);
+ }
+
+ /**
+ * Get the hydrated models without eager loading.
+ *
+ * @param array|string $columns
+ * @return array
+ * @static
+ */
+ public static function getModels($columns = [])
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->getModels($columns);
+ }
+
+ /**
+ * Eager load the relationships for the models.
+ *
+ * @param array $models
+ * @return array
+ * @static
+ */
+ public static function eagerLoadRelations($models)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->eagerLoadRelations($models);
+ }
+
+ /**
+ * Register a closure to be invoked after the query is executed.
+ *
+ * @param \Closure $callback
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function afterQuery($callback)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->afterQuery($callback);
+ }
+
+ /**
+ * Invoke the "after query" modification callbacks.
+ *
+ * @param mixed $result
+ * @return mixed
+ * @static
+ */
+ public static function applyAfterQueryCallbacks($result)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->applyAfterQueryCallbacks($result);
+ }
+
+ /**
+ * Get a lazy collection for the given query.
+ *
+ * @return \Illuminate\Support\LazyCollection
+ * @static
+ */
+ public static function cursor()
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->cursor();
+ }
+
+ /**
+ * Get a collection with the values of a given column.
+ *
+ * @param string|\Illuminate\Contracts\Database\Query\Expression $column
+ * @param string|null $key
+ * @return \Illuminate\Support\Collection
+ * @static
+ */
+ public static function pluck($column, $key = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->pluck($column, $key);
+ }
+
+ /**
+ * Paginate the given query.
+ *
+ * @param int|null|\Closure $perPage
+ * @param array|string $columns
+ * @param string $pageName
+ * @param int|null $page
+ * @param \Closure|int|null $total
+ * @return \Illuminate\Pagination\LengthAwarePaginator
+ * @throws \InvalidArgumentException
+ * @static
+ */
+ public static function paginate($perPage = null, $columns = [], $pageName = 'page', $page = null, $total = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->paginate($perPage, $columns, $pageName, $page, $total);
+ }
+
+ /**
+ * Paginate the given query into a simple paginator.
+ *
+ * @param int|null $perPage
+ * @param array|string $columns
+ * @param string $pageName
+ * @param int|null $page
+ * @return \Illuminate\Contracts\Pagination\Paginator
+ * @static
+ */
+ public static function simplePaginate($perPage = null, $columns = [], $pageName = 'page', $page = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->simplePaginate($perPage, $columns, $pageName, $page);
+ }
+
+ /**
+ * Paginate the given query into a cursor paginator.
+ *
+ * @param int|null $perPage
+ * @param array|string $columns
+ * @param string $cursorName
+ * @param \Illuminate\Pagination\Cursor|string|null $cursor
+ * @return \Illuminate\Contracts\Pagination\CursorPaginator
+ * @static
+ */
+ public static function cursorPaginate($perPage = null, $columns = [], $cursorName = 'cursor', $cursor = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->cursorPaginate($perPage, $columns, $cursorName, $cursor);
+ }
+
+ /**
+ * Save a new model and return the instance.
+ *
+ * @param array $attributes
+ * @return TModel
+ * @static
+ */
+ public static function create($attributes = [])
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->create($attributes);
+ }
+
+ /**
+ * Save a new model and return the instance without raising model events.
+ *
+ * @param array $attributes
+ * @return TModel
+ * @static
+ */
+ public static function createQuietly($attributes = [])
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->createQuietly($attributes);
+ }
+
+ /**
+ * Save a new model and return the instance. Allow mass-assignment.
+ *
+ * @param array $attributes
+ * @return TModel
+ * @static
+ */
+ public static function forceCreate($attributes)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->forceCreate($attributes);
+ }
+
+ /**
+ * Save a new model instance with mass assignment without raising model events.
+ *
+ * @param array $attributes
+ * @return TModel
+ * @static
+ */
+ public static function forceCreateQuietly($attributes = [])
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->forceCreateQuietly($attributes);
+ }
+
+ /**
+ * Insert new records or update the existing ones.
+ *
+ * @param array $values
+ * @param array|string $uniqueBy
+ * @param array|null $update
+ * @return int
+ * @static
+ */
+ public static function upsert($values, $uniqueBy, $update = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->upsert($values, $uniqueBy, $update);
+ }
+
+ /**
+ * Register a replacement for the default delete function.
+ *
+ * @param \Closure $callback
+ * @return void
+ * @static
+ */
+ public static function onDelete($callback)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ $instance->onDelete($callback);
+ }
+
+ /**
+ * Call the given local model scopes.
+ *
+ * @param array|string $scopes
+ * @return static|mixed
+ * @static
+ */
+ public static function scopes($scopes)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->scopes($scopes);
+ }
+
+ /**
+ * Apply the scopes to the Eloquent builder instance and return it.
+ *
+ * @return static
+ * @static
+ */
+ public static function applyScopes()
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->applyScopes();
+ }
+
+ /**
+ * Prevent the specified relations from being eager loaded.
+ *
+ * @param mixed $relations
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function without($relations)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->without($relations);
+ }
+
+ /**
+ * Set the relationships that should be eager loaded while removing any previously added eager loading specifications.
+ *
+ * @param array): mixed)|string>|string $relations
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function withOnly($relations)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->withOnly($relations);
+ }
+
+ /**
+ * Create a new instance of the model being queried.
+ *
+ * @param array $attributes
+ * @return TModel
+ * @static
+ */
+ public static function newModelInstance($attributes = [])
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->newModelInstance($attributes);
+ }
+
+ /**
+ * Specify attributes that should be added to any new models created by this builder.
+ *
+ * The given key / value pairs will also be added as where conditions to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|array|string $attributes
+ * @param mixed $value
+ * @param bool $asConditions
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function withAttributes($attributes, $value = null, $asConditions = true)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->withAttributes($attributes, $value, $asConditions);
+ }
+
+ /**
+ * Apply query-time casts to the model instance.
+ *
+ * @param array $casts
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function withCasts($casts)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->withCasts($casts);
+ }
+
+ /**
+ * Execute the given Closure within a transaction savepoint if needed.
+ *
+ * @template TModelValue
+ * @param \Closure(): TModelValue $scope
+ * @return TModelValue
+ * @static
+ */
+ public static function withSavepointIfNeeded($scope)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->withSavepointIfNeeded($scope);
+ }
+
+ /**
+ * Get the underlying query builder instance.
+ *
+ * @return \Illuminate\Database\Query\Builder
+ * @static
+ */
+ public static function getQuery()
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->getQuery();
+ }
+
+ /**
+ * Set the underlying query builder instance.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function setQuery($query)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->setQuery($query);
+ }
+
+ /**
+ * Get a base query builder instance.
+ *
+ * @return \Illuminate\Database\Query\Builder
+ * @static
+ */
+ public static function toBase()
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->toBase();
+ }
+
+ /**
+ * Get the relationships being eagerly loaded.
+ *
+ * @return array
+ * @static
+ */
+ public static function getEagerLoads()
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->getEagerLoads();
+ }
+
+ /**
+ * Set the relationships being eagerly loaded.
+ *
+ * @param array $eagerLoad
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function setEagerLoads($eagerLoad)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->setEagerLoads($eagerLoad);
+ }
+
+ /**
+ * Indicate that the given relationships should not be eagerly loaded.
+ *
+ * @param array $relations
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function withoutEagerLoad($relations)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->withoutEagerLoad($relations);
+ }
+
+ /**
+ * Flush the relationships being eagerly loaded.
+ *
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function withoutEagerLoads()
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->withoutEagerLoads();
+ }
+
+ /**
+ * Get the "limit" value from the query or null if it's not set.
+ *
+ * @return mixed
+ * @static
+ */
+ public static function getLimit()
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->getLimit();
+ }
+
+ /**
+ * Get the "offset" value from the query or null if it's not set.
+ *
+ * @return mixed
+ * @static
+ */
+ public static function getOffset()
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->getOffset();
+ }
+
+ /**
+ * Get the model instance being queried.
+ *
+ * @return TModel
+ * @static
+ */
+ public static function getModel()
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->getModel();
+ }
+
+ /**
+ * Set a model instance for the model being queried.
+ *
+ * @template TModelNew of \Illuminate\Database\Eloquent\Model
+ * @param TModelNew $model
+ * @return static
+ * @static
+ */
+ public static function setModel($model)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->setModel($model);
+ }
+
+ /**
+ * Get the given macro by name.
+ *
+ * @param string $name
+ * @return \Closure
+ * @static
+ */
+ public static function getMacro($name)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->getMacro($name);
+ }
+
+ /**
+ * Checks if a macro is registered.
+ *
+ * @param string $name
+ * @return bool
+ * @static
+ */
+ public static function hasMacro($name)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->hasMacro($name);
+ }
+
+ /**
+ * Get the given global macro by name.
+ *
+ * @param string $name
+ * @return \Closure
+ * @static
+ */
+ public static function getGlobalMacro($name)
+ {
+ return \Illuminate\Database\Eloquent\Builder::getGlobalMacro($name);
+ }
+
+ /**
+ * Checks if a global macro is registered.
+ *
+ * @param string $name
+ * @return bool
+ * @static
+ */
+ public static function hasGlobalMacro($name)
+ {
+ return \Illuminate\Database\Eloquent\Builder::hasGlobalMacro($name);
+ }
+
+ /**
+ * Clone the Eloquent query builder.
+ *
+ * @return static
+ * @static
+ */
+ public static function clone()
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->clone();
+ }
+
+ /**
+ * Register a closure to be invoked on a clone.
+ *
+ * @param \Closure $callback
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function onClone($callback)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->onClone($callback);
+ }
+
+ /**
+ * Chunk the results of the query.
+ *
+ * @param int $count
+ * @param callable(\Illuminate\Support\Collection, int): mixed $callback
+ * @return bool
+ * @static
+ */
+ public static function chunk($count, $callback)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->chunk($count, $callback);
+ }
+
+ /**
+ * Run a map over each item while chunking.
+ *
+ * @template TReturn
+ * @param callable(TValue): TReturn $callback
+ * @param int $count
+ * @return \Illuminate\Support\Collection
+ * @static
+ */
+ public static function chunkMap($callback, $count = 1000)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->chunkMap($callback, $count);
+ }
+
+ /**
+ * Execute a callback over each item while chunking.
+ *
+ * @param callable(TValue, int): mixed $callback
+ * @param int $count
+ * @return bool
+ * @throws \RuntimeException
+ * @static
+ */
+ public static function each($callback, $count = 1000)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->each($callback, $count);
+ }
+
+ /**
+ * Chunk the results of a query by comparing IDs.
+ *
+ * @param int $count
+ * @param callable(\Illuminate\Support\Collection, int): mixed $callback
+ * @param string|null $column
+ * @param string|null $alias
+ * @return bool
+ * @static
+ */
+ public static function chunkById($count, $callback, $column = null, $alias = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->chunkById($count, $callback, $column, $alias);
+ }
+
+ /**
+ * Chunk the results of a query by comparing IDs in descending order.
+ *
+ * @param int $count
+ * @param callable(\Illuminate\Support\Collection, int): mixed $callback
+ * @param string|null $column
+ * @param string|null $alias
+ * @return bool
+ * @static
+ */
+ public static function chunkByIdDesc($count, $callback, $column = null, $alias = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->chunkByIdDesc($count, $callback, $column, $alias);
+ }
+
+ /**
+ * Chunk the results of a query by comparing IDs in a given order.
+ *
+ * @param int $count
+ * @param callable(\Illuminate\Support\Collection, int): mixed $callback
+ * @param string|null $column
+ * @param string|null $alias
+ * @param bool $descending
+ * @return bool
+ * @throws \RuntimeException
+ * @static
+ */
+ public static function orderedChunkById($count, $callback, $column = null, $alias = null, $descending = false)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->orderedChunkById($count, $callback, $column, $alias, $descending);
+ }
+
+ /**
+ * Execute a callback over each item while chunking by ID.
+ *
+ * @param callable(TValue, int): mixed $callback
+ * @param int $count
+ * @param string|null $column
+ * @param string|null $alias
+ * @return bool
+ * @static
+ */
+ public static function eachById($callback, $count = 1000, $column = null, $alias = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->eachById($callback, $count, $column, $alias);
+ }
+
+ /**
+ * Query lazily, by chunks of the given size.
+ *
+ * @param int $chunkSize
+ * @return \Illuminate\Support\LazyCollection
+ * @throws \InvalidArgumentException
+ * @static
+ */
+ public static function lazy($chunkSize = 1000)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->lazy($chunkSize);
+ }
+
+ /**
+ * Query lazily, by chunking the results of a query by comparing IDs.
+ *
+ * @param int $chunkSize
+ * @param string|null $column
+ * @param string|null $alias
+ * @return \Illuminate\Support\LazyCollection
+ * @throws \InvalidArgumentException
+ * @static
+ */
+ public static function lazyById($chunkSize = 1000, $column = null, $alias = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->lazyById($chunkSize, $column, $alias);
+ }
+
+ /**
+ * Query lazily, by chunking the results of a query by comparing IDs in descending order.
+ *
+ * @param int $chunkSize
+ * @param string|null $column
+ * @param string|null $alias
+ * @return \Illuminate\Support\LazyCollection
+ * @throws \InvalidArgumentException
+ * @static
+ */
+ public static function lazyByIdDesc($chunkSize = 1000, $column = null, $alias = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->lazyByIdDesc($chunkSize, $column, $alias);
+ }
+
+ /**
+ * Execute the query and get the first result.
+ *
+ * @param array|string $columns
+ * @return TValue|null
+ * @static
+ */
+ public static function first($columns = [])
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->first($columns);
+ }
+
+ /**
+ * Execute the query and get the first result if it's the sole matching record.
+ *
+ * @param array|string $columns
+ * @return TValue
+ * @throws \Illuminate\Database\RecordsNotFoundException
+ * @throws \Illuminate\Database\MultipleRecordsFoundException
+ * @static
+ */
+ public static function baseSole($columns = [])
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->baseSole($columns);
+ }
+
+ /**
+ * Pass the query to a given callback and then return it.
+ *
+ * @param callable($this): mixed $callback
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function tap($callback)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->tap($callback);
+ }
+
+ /**
+ * Pass the query to a given callback and return the result.
+ *
+ * @template TReturn
+ * @param (callable($this): TReturn) $callback
+ * @return (TReturn is null|void ? $this : TReturn)
+ * @static
+ */
+ public static function pipe($callback)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->pipe($callback);
+ }
+
+ /**
+ * Apply the callback if the given "value" is (or resolves to) truthy.
+ *
+ * @template TWhenParameter
+ * @template TWhenReturnType
+ * @param (\Closure($this): TWhenParameter)|TWhenParameter|null $value
+ * @param (callable($this, TWhenParameter): TWhenReturnType)|null $callback
+ * @param (callable($this, TWhenParameter): TWhenReturnType)|null $default
+ * @return $this|TWhenReturnType
+ * @static
+ */
+ public static function when($value = null, $callback = null, $default = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->when($value, $callback, $default);
+ }
+
+ /**
+ * Apply the callback if the given "value" is (or resolves to) falsy.
+ *
+ * @template TUnlessParameter
+ * @template TUnlessReturnType
+ * @param (\Closure($this): TUnlessParameter)|TUnlessParameter|null $value
+ * @param (callable($this, TUnlessParameter): TUnlessReturnType)|null $callback
+ * @param (callable($this, TUnlessParameter): TUnlessReturnType)|null $default
+ * @return $this|TUnlessReturnType
+ * @static
+ */
+ public static function unless($value = null, $callback = null, $default = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->unless($value, $callback, $default);
+ }
+
+ /**
+ * Add a relationship count / exists condition to the query.
+ *
+ * @template TRelatedModel of \Illuminate\Database\Eloquent\Model
+ * @param \Illuminate\Database\Eloquent\Relations\Relation|string $relation
+ * @param string $operator
+ * @param int $count
+ * @param string $boolean
+ * @param (\Closure(\Illuminate\Database\Eloquent\Builder): mixed)|null $callback
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @throws \RuntimeException
+ * @static
+ */
+ public static function has($relation, $operator = '>=', $count = 1, $boolean = 'and', $callback = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->has($relation, $operator, $count, $boolean, $callback);
+ }
+
+ /**
+ * Add a relationship count / exists condition to the query with an "or".
+ *
+ * @param \Illuminate\Database\Eloquent\Relations\Relation<*, *, *>|string $relation
+ * @param string $operator
+ * @param int $count
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orHas($relation, $operator = '>=', $count = 1)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->orHas($relation, $operator, $count);
+ }
+
+ /**
+ * Add a relationship count / exists condition to the query.
+ *
+ * @template TRelatedModel of \Illuminate\Database\Eloquent\Model
+ * @param \Illuminate\Database\Eloquent\Relations\Relation|string $relation
+ * @param string $boolean
+ * @param (\Closure(\Illuminate\Database\Eloquent\Builder): mixed)|null $callback
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function doesntHave($relation, $boolean = 'and', $callback = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->doesntHave($relation, $boolean, $callback);
+ }
+
+ /**
+ * Add a relationship count / exists condition to the query with an "or".
+ *
+ * @param \Illuminate\Database\Eloquent\Relations\Relation<*, *, *>|string $relation
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orDoesntHave($relation)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->orDoesntHave($relation);
+ }
+
+ /**
+ * Add a relationship count / exists condition to the query with where clauses.
+ *
+ * @template TRelatedModel of \Illuminate\Database\Eloquent\Model
+ * @param \Illuminate\Database\Eloquent\Relations\Relation|string $relation
+ * @param (\Closure(\Illuminate\Database\Eloquent\Builder): mixed)|null $callback
+ * @param string $operator
+ * @param int $count
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereHas($relation, $callback = null, $operator = '>=', $count = 1)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->whereHas($relation, $callback, $operator, $count);
+ }
+
+ /**
+ * Add a relationship count / exists condition to the query with where clauses.
+ *
+ * Also load the relationship with the same condition.
+ *
+ * @param string $relation
+ * @param (\Closure(\Illuminate\Database\Eloquent\Builder<*>|\Illuminate\Database\Eloquent\Relations\Relation<*, *, *>): mixed)|null $callback
+ * @param string $operator
+ * @param int $count
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function withWhereHas($relation, $callback = null, $operator = '>=', $count = 1)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->withWhereHas($relation, $callback, $operator, $count);
+ }
+
+ /**
+ * Add a relationship count / exists condition to the query with where clauses and an "or".
+ *
+ * @template TRelatedModel of \Illuminate\Database\Eloquent\Model
+ * @param \Illuminate\Database\Eloquent\Relations\Relation|string $relation
+ * @param (\Closure(\Illuminate\Database\Eloquent\Builder): mixed)|null $callback
+ * @param string $operator
+ * @param int $count
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereHas($relation, $callback = null, $operator = '>=', $count = 1)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->orWhereHas($relation, $callback, $operator, $count);
+ }
+
+ /**
+ * Add a relationship count / exists condition to the query with where clauses.
+ *
+ * @template TRelatedModel of \Illuminate\Database\Eloquent\Model
+ * @param \Illuminate\Database\Eloquent\Relations\Relation|string $relation
+ * @param (\Closure(\Illuminate\Database\Eloquent\Builder): mixed)|null $callback
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereDoesntHave($relation, $callback = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->whereDoesntHave($relation, $callback);
+ }
+
+ /**
+ * Add a relationship count / exists condition to the query with where clauses and an "or".
+ *
+ * @template TRelatedModel of \Illuminate\Database\Eloquent\Model
+ * @param \Illuminate\Database\Eloquent\Relations\Relation|string $relation
+ * @param (\Closure(\Illuminate\Database\Eloquent\Builder): mixed)|null $callback
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereDoesntHave($relation, $callback = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->orWhereDoesntHave($relation, $callback);
+ }
+
+ /**
+ * Add a polymorphic relationship count / exists condition to the query.
+ *
+ * @template TRelatedModel of \Illuminate\Database\Eloquent\Model
+ * @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation
+ * @param string|array $types
+ * @param string $operator
+ * @param int $count
+ * @param string $boolean
+ * @param (\Closure(\Illuminate\Database\Eloquent\Builder, string): mixed)|null $callback
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function hasMorph($relation, $types, $operator = '>=', $count = 1, $boolean = 'and', $callback = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->hasMorph($relation, $types, $operator, $count, $boolean, $callback);
+ }
+
+ /**
+ * Add a polymorphic relationship count / exists condition to the query with an "or".
+ *
+ * @param \Illuminate\Database\Eloquent\Relations\MorphTo<*, *>|string $relation
+ * @param string|array $types
+ * @param string $operator
+ * @param int $count
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orHasMorph($relation, $types, $operator = '>=', $count = 1)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->orHasMorph($relation, $types, $operator, $count);
+ }
+
+ /**
+ * Add a polymorphic relationship count / exists condition to the query.
+ *
+ * @template TRelatedModel of \Illuminate\Database\Eloquent\Model
+ * @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation
+ * @param string|array $types
+ * @param string $boolean
+ * @param (\Closure(\Illuminate\Database\Eloquent\Builder, string): mixed)|null $callback
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function doesntHaveMorph($relation, $types, $boolean = 'and', $callback = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->doesntHaveMorph($relation, $types, $boolean, $callback);
+ }
+
+ /**
+ * Add a polymorphic relationship count / exists condition to the query with an "or".
+ *
+ * @param \Illuminate\Database\Eloquent\Relations\MorphTo<*, *>|string $relation
+ * @param string|array $types
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orDoesntHaveMorph($relation, $types)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->orDoesntHaveMorph($relation, $types);
+ }
+
+ /**
+ * Add a polymorphic relationship count / exists condition to the query with where clauses.
+ *
+ * @template TRelatedModel of \Illuminate\Database\Eloquent\Model
+ * @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation
+ * @param string|array $types
+ * @param (\Closure(\Illuminate\Database\Eloquent\Builder, string): mixed)|null $callback
+ * @param string $operator
+ * @param int $count
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereHasMorph($relation, $types, $callback = null, $operator = '>=', $count = 1)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->whereHasMorph($relation, $types, $callback, $operator, $count);
+ }
+
+ /**
+ * Add a polymorphic relationship count / exists condition to the query with where clauses and an "or".
+ *
+ * @template TRelatedModel of \Illuminate\Database\Eloquent\Model
+ * @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation
+ * @param string|array $types
+ * @param (\Closure(\Illuminate\Database\Eloquent\Builder, string): mixed)|null $callback
+ * @param string $operator
+ * @param int $count
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereHasMorph($relation, $types, $callback = null, $operator = '>=', $count = 1)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->orWhereHasMorph($relation, $types, $callback, $operator, $count);
+ }
+
+ /**
+ * Add a polymorphic relationship count / exists condition to the query with where clauses.
+ *
+ * @template TRelatedModel of \Illuminate\Database\Eloquent\Model
+ * @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation
+ * @param string|array $types
+ * @param (\Closure(\Illuminate\Database\Eloquent\Builder, string): mixed)|null $callback
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereDoesntHaveMorph($relation, $types, $callback = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->whereDoesntHaveMorph($relation, $types, $callback);
+ }
+
+ /**
+ * Add a polymorphic relationship count / exists condition to the query with where clauses and an "or".
+ *
+ * @template TRelatedModel of \Illuminate\Database\Eloquent\Model
+ * @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation
+ * @param string|array $types
+ * @param (\Closure(\Illuminate\Database\Eloquent\Builder, string): mixed)|null $callback
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereDoesntHaveMorph($relation, $types, $callback = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->orWhereDoesntHaveMorph($relation, $types, $callback);
+ }
+
+ /**
+ * Add a basic where clause to a relationship query.
+ *
+ * @template TRelatedModel of \Illuminate\Database\Eloquent\Model
+ * @param \Illuminate\Database\Eloquent\Relations\Relation|string $relation
+ * @param (\Closure(\Illuminate\Database\Eloquent\Builder): mixed)|string|array|\Illuminate\Contracts\Database\Query\Expression $column
+ * @param mixed $operator
+ * @param mixed $value
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereRelation($relation, $column, $operator = null, $value = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->whereRelation($relation, $column, $operator, $value);
+ }
+
+ /**
+ * Add a basic where clause to a relationship query and eager-load the relationship with the same conditions.
+ *
+ * @param \Illuminate\Database\Eloquent\Relations\Relation<*, *, *>|string $relation
+ * @param \Closure|string|array|\Illuminate\Contracts\Database\Query\Expression $column
+ * @param mixed $operator
+ * @param mixed $value
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function withWhereRelation($relation, $column, $operator = null, $value = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->withWhereRelation($relation, $column, $operator, $value);
+ }
+
+ /**
+ * Add an "or where" clause to a relationship query.
+ *
+ * @template TRelatedModel of \Illuminate\Database\Eloquent\Model
+ * @param \Illuminate\Database\Eloquent\Relations\Relation|string $relation
+ * @param (\Closure(\Illuminate\Database\Eloquent\Builder): mixed)|string|array|\Illuminate\Contracts\Database\Query\Expression $column
+ * @param mixed $operator
+ * @param mixed $value
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereRelation($relation, $column, $operator = null, $value = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->orWhereRelation($relation, $column, $operator, $value);
+ }
+
+ /**
+ * Add a basic count / exists condition to a relationship query.
+ *
+ * @template TRelatedModel of \Illuminate\Database\Eloquent\Model
+ * @param \Illuminate\Database\Eloquent\Relations\Relation|string $relation
+ * @param (\Closure(\Illuminate\Database\Eloquent\Builder): mixed)|string|array|\Illuminate\Contracts\Database\Query\Expression $column
+ * @param mixed $operator
+ * @param mixed $value
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereDoesntHaveRelation($relation, $column, $operator = null, $value = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->whereDoesntHaveRelation($relation, $column, $operator, $value);
+ }
+
+ /**
+ * Add an "or where" clause to a relationship query.
+ *
+ * @template TRelatedModel of \Illuminate\Database\Eloquent\Model
+ * @param \Illuminate\Database\Eloquent\Relations\Relation|string $relation
+ * @param (\Closure(\Illuminate\Database\Eloquent\Builder): mixed)|string|array|\Illuminate\Contracts\Database\Query\Expression $column
+ * @param mixed $operator
+ * @param mixed $value
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereDoesntHaveRelation($relation, $column, $operator = null, $value = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->orWhereDoesntHaveRelation($relation, $column, $operator, $value);
+ }
+
+ /**
+ * Add a polymorphic relationship condition to the query with a where clause.
+ *
+ * @template TRelatedModel of \Illuminate\Database\Eloquent\Model
+ * @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation
+ * @param string|array $types
+ * @param (\Closure(\Illuminate\Database\Eloquent\Builder): mixed)|string|array|\Illuminate\Contracts\Database\Query\Expression $column
+ * @param mixed $operator
+ * @param mixed $value
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereMorphRelation($relation, $types, $column, $operator = null, $value = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->whereMorphRelation($relation, $types, $column, $operator, $value);
+ }
+
+ /**
+ * Add a polymorphic relationship condition to the query with an "or where" clause.
+ *
+ * @template TRelatedModel of \Illuminate\Database\Eloquent\Model
+ * @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation
+ * @param string|array $types
+ * @param (\Closure(\Illuminate\Database\Eloquent\Builder): mixed)|string|array|\Illuminate\Contracts\Database\Query\Expression $column
+ * @param mixed $operator
+ * @param mixed $value
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereMorphRelation($relation, $types, $column, $operator = null, $value = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->orWhereMorphRelation($relation, $types, $column, $operator, $value);
+ }
+
+ /**
+ * Add a polymorphic relationship condition to the query with a doesn't have clause.
+ *
+ * @template TRelatedModel of \Illuminate\Database\Eloquent\Model
+ * @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation
+ * @param string|array $types
+ * @param (\Closure(\Illuminate\Database\Eloquent\Builder): mixed)|string|array|\Illuminate\Contracts\Database\Query\Expression $column
+ * @param mixed $operator
+ * @param mixed $value
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereMorphDoesntHaveRelation($relation, $types, $column, $operator = null, $value = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->whereMorphDoesntHaveRelation($relation, $types, $column, $operator, $value);
+ }
+
+ /**
+ * Add a polymorphic relationship condition to the query with an "or doesn't have" clause.
+ *
+ * @template TRelatedModel of \Illuminate\Database\Eloquent\Model
+ * @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation
+ * @param string|array $types
+ * @param (\Closure(\Illuminate\Database\Eloquent\Builder): mixed)|string|array|\Illuminate\Contracts\Database\Query\Expression $column
+ * @param mixed $operator
+ * @param mixed $value
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereMorphDoesntHaveRelation($relation, $types, $column, $operator = null, $value = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->orWhereMorphDoesntHaveRelation($relation, $types, $column, $operator, $value);
+ }
+
+ /**
+ * Add a morph-to relationship condition to the query.
+ *
+ * @param \Illuminate\Database\Eloquent\Relations\MorphTo<*, *>|string $relation
+ * @param \Illuminate\Database\Eloquent\Model|iterable|string|null $model
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereMorphedTo($relation, $model, $boolean = 'and')
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->whereMorphedTo($relation, $model, $boolean);
+ }
+
+ /**
+ * Add a not morph-to relationship condition to the query.
+ *
+ * @param \Illuminate\Database\Eloquent\Relations\MorphTo<*, *>|string $relation
+ * @param \Illuminate\Database\Eloquent\Model|iterable|string $model
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereNotMorphedTo($relation, $model, $boolean = 'and')
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->whereNotMorphedTo($relation, $model, $boolean);
+ }
+
+ /**
+ * Add a morph-to relationship condition to the query with an "or where" clause.
+ *
+ * @param \Illuminate\Database\Eloquent\Relations\MorphTo<*, *>|string $relation
+ * @param \Illuminate\Database\Eloquent\Model|iterable|string|null $model
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereMorphedTo($relation, $model)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->orWhereMorphedTo($relation, $model);
+ }
+
+ /**
+ * Add a not morph-to relationship condition to the query with an "or where" clause.
+ *
+ * @param \Illuminate\Database\Eloquent\Relations\MorphTo<*, *>|string $relation
+ * @param \Illuminate\Database\Eloquent\Model|iterable|string $model
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereNotMorphedTo($relation, $model)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->orWhereNotMorphedTo($relation, $model);
+ }
+
+ /**
+ * Add a "belongs to" relationship where clause to the query.
+ *
+ * @param \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection $related
+ * @param string|null $relationshipName
+ * @param string $boolean
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @throws \Illuminate\Database\Eloquent\RelationNotFoundException
+ * @static
+ */
+ public static function whereBelongsTo($related, $relationshipName = null, $boolean = 'and')
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->whereBelongsTo($related, $relationshipName, $boolean);
+ }
+
+ /**
+ * Add a "BelongsTo" relationship with an "or where" clause to the query.
+ *
+ * @param \Illuminate\Database\Eloquent\Model $related
+ * @param string|null $relationshipName
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @throws \RuntimeException
+ * @static
+ */
+ public static function orWhereBelongsTo($related, $relationshipName = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->orWhereBelongsTo($related, $relationshipName);
+ }
+
+ /**
+ * Add a "belongs to many" relationship where clause to the query.
+ *
+ * @param \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection $related
+ * @param string|null $relationshipName
+ * @param string $boolean
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @throws \Illuminate\Database\Eloquent\RelationNotFoundException
+ * @static
+ */
+ public static function whereAttachedTo($related, $relationshipName = null, $boolean = 'and')
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->whereAttachedTo($related, $relationshipName, $boolean);
+ }
+
+ /**
+ * Add a "belongs to many" relationship with an "or where" clause to the query.
+ *
+ * @param \Illuminate\Database\Eloquent\Model $related
+ * @param string|null $relationshipName
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @throws \RuntimeException
+ * @static
+ */
+ public static function orWhereAttachedTo($related, $relationshipName = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->orWhereAttachedTo($related, $relationshipName);
+ }
+
+ /**
+ * Add subselect queries to include an aggregate value for a relationship.
+ *
+ * @param mixed $relations
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @param string $function
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function withAggregate($relations, $column, $function = null)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->withAggregate($relations, $column, $function);
+ }
+
+ /**
+ * Add subselect queries to count the relations.
+ *
+ * @param mixed $relations
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function withCount($relations)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->withCount($relations);
+ }
+
+ /**
+ * Add subselect queries to include the max of the relation's column.
+ *
+ * @param string|array $relation
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function withMax($relation, $column)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->withMax($relation, $column);
+ }
+
+ /**
+ * Add subselect queries to include the min of the relation's column.
+ *
+ * @param string|array $relation
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function withMin($relation, $column)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->withMin($relation, $column);
+ }
+
+ /**
+ * Add subselect queries to include the sum of the relation's column.
+ *
+ * @param string|array $relation
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function withSum($relation, $column)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->withSum($relation, $column);
+ }
+
+ /**
+ * Add subselect queries to include the average of the relation's column.
+ *
+ * @param string|array $relation
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function withAvg($relation, $column)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->withAvg($relation, $column);
+ }
+
+ /**
+ * Add subselect queries to include the existence of related models.
+ *
+ * @param string|array $relation
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function withExists($relation)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->withExists($relation);
+ }
+
+ /**
+ * Merge the where constraints from another query to the current query.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder<*> $from
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function mergeConstraintsFrom($from)
+ {
+ /** @var \Illuminate\Database\Eloquent\Builder $instance */
+ return $instance->mergeConstraintsFrom($from);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::powerJoin()
+ * @param mixed $table
+ * @param mixed $first
+ * @param mixed $operator
+ * @param mixed $second
+ * @param mixed $type
+ * @param mixed $where
+ * @return static
+ * @static
+ */
+ public static function powerJoin($table, $first, $operator = null, $second = null, $type = 'inner', $where = false)
+ {
+ return \Illuminate\Database\Eloquent\Builder::powerJoin($table, $first, $operator, $second, $type, $where);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::leftPowerJoin()
+ * @param mixed $table
+ * @param mixed $first
+ * @param mixed $operator
+ * @param mixed $second
+ * @static
+ */
+ public static function leftPowerJoin($table, $first, $operator = null, $second = null)
+ {
+ return \Illuminate\Database\Eloquent\Builder::leftPowerJoin($table, $first, $operator, $second);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::rightPowerJoin()
+ * @param mixed $table
+ * @param mixed $first
+ * @param mixed $operator
+ * @param mixed $second
+ * @static
+ */
+ public static function rightPowerJoin($table, $first, $operator = null, $second = null)
+ {
+ return \Illuminate\Database\Eloquent\Builder::rightPowerJoin($table, $first, $operator, $second);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::newPowerJoinClause()
+ * @param \Illuminate\Database\Query\Builder $parentQuery
+ * @param string $type
+ * @param string $table
+ * @param \Illuminate\Database\Eloquent\Model|null $model
+ * @static
+ */
+ public static function newPowerJoinClause($parentQuery, $type, $table, $model = null)
+ {
+ return \Illuminate\Database\Eloquent\Builder::newPowerJoinClause($parentQuery, $type, $table, $model);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::joinRelationship()
+ * @param string $relationName
+ * @param \Closure|array|string|null $callback
+ * @param string $joinType
+ * @param bool $useAlias
+ * @param bool $disableExtraConditions
+ * @param string|null $morphable
+ * @static
+ */
+ public static function joinRelationship($relationName, $callback = null, $joinType = 'join', $useAlias = false, $disableExtraConditions = false, $morphable = null)
+ {
+ return \Illuminate\Database\Eloquent\Builder::joinRelationship($relationName, $callback, $joinType, $useAlias, $disableExtraConditions, $morphable);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::joinRelationshipUsingAlias()
+ * @param string $relationName
+ * @param \Closure|array|string|null $callback
+ * @param bool $disableExtraConditions
+ * @param string|null $morphable
+ * @static
+ */
+ public static function joinRelationshipUsingAlias($relationName, $callback = null, $disableExtraConditions = false, $morphable = null)
+ {
+ return \Illuminate\Database\Eloquent\Builder::joinRelationshipUsingAlias($relationName, $callback, $disableExtraConditions, $morphable);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::leftJoinRelationshipUsingAlias()
+ * @param string $relationName
+ * @param \Closure|array|string|null $callback
+ * @param bool $disableExtraConditions
+ * @param string|null $morphable
+ * @static
+ */
+ public static function leftJoinRelationshipUsingAlias($relationName, $callback = null, $disableExtraConditions = false, $morphable = null)
+ {
+ return \Illuminate\Database\Eloquent\Builder::leftJoinRelationshipUsingAlias($relationName, $callback, $disableExtraConditions, $morphable);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::rightJoinRelationshipUsingAlias()
+ * @param string $relationName
+ * @param \Closure|array|string|null $callback
+ * @param bool $disableExtraConditions
+ * @param string|null $morphable
+ * @static
+ */
+ public static function rightJoinRelationshipUsingAlias($relationName, $callback = null, $disableExtraConditions = false, $morphable = null)
+ {
+ return \Illuminate\Database\Eloquent\Builder::rightJoinRelationshipUsingAlias($relationName, $callback, $disableExtraConditions, $morphable);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::joinRelation()
+ * @param string $relationName
+ * @param \Closure|array|string|null $callback
+ * @param string $joinType
+ * @param bool $useAlias
+ * @param bool $disableExtraConditions
+ * @param string|null $morphable
+ * @static
+ */
+ public static function joinRelation($relationName, $callback = null, $joinType = 'join', $useAlias = false, $disableExtraConditions = false, $morphable = null)
+ {
+ return \Illuminate\Database\Eloquent\Builder::joinRelation($relationName, $callback, $joinType, $useAlias, $disableExtraConditions, $morphable);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::leftJoinRelationship()
+ * @param string $relationName
+ * @param \Closure|array|string|null $callback
+ * @param bool $useAlias
+ * @param bool $disableExtraConditions
+ * @param string|null $morphable
+ * @static
+ */
+ public static function leftJoinRelationship($relationName, $callback = null, $useAlias = false, $disableExtraConditions = false, $morphable = null)
+ {
+ return \Illuminate\Database\Eloquent\Builder::leftJoinRelationship($relationName, $callback, $useAlias, $disableExtraConditions, $morphable);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::leftJoinRelation()
+ * @param string $relation
+ * @param \Closure|array|string|null $callback
+ * @param bool $useAlias
+ * @param bool $disableExtraConditions
+ * @param string|null $morphable
+ * @static
+ */
+ public static function leftJoinRelation($relation, $callback = null, $useAlias = false, $disableExtraConditions = false, $morphable = null)
+ {
+ return \Illuminate\Database\Eloquent\Builder::leftJoinRelation($relation, $callback, $useAlias, $disableExtraConditions, $morphable);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::rightJoinRelationship()
+ * @param string $relation
+ * @param \Closure|array|string|null $callback
+ * @param bool $useAlias
+ * @param bool $disableExtraConditions
+ * @param string|null $morphable
+ * @static
+ */
+ public static function rightJoinRelationship($relation, $callback = null, $useAlias = false, $disableExtraConditions = false, $morphable = null)
+ {
+ return \Illuminate\Database\Eloquent\Builder::rightJoinRelationship($relation, $callback, $useAlias, $disableExtraConditions, $morphable);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::rightJoinRelation()
+ * @param string $relation
+ * @param \Closure|array|string|null $callback
+ * @param bool $useAlias
+ * @param bool $disableExtraConditions
+ * @param string|null $morphable
+ * @static
+ */
+ public static function rightJoinRelation($relation, $callback = null, $useAlias = false, $disableExtraConditions = false, $morphable = null)
+ {
+ return \Illuminate\Database\Eloquent\Builder::rightJoinRelation($relation, $callback, $useAlias, $disableExtraConditions, $morphable);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::joinNestedRelationship()
+ * @param string $relationships
+ * @param \Closure|array|string|null $callback
+ * @param string $joinType
+ * @param bool $useAlias
+ * @param bool $disableExtraConditions
+ * @param string|null $morphable
+ * @static
+ */
+ public static function joinNestedRelationship($relationships, $callback = null, $joinType = 'join', $useAlias = false, $disableExtraConditions = false, $morphable = null)
+ {
+ return \Illuminate\Database\Eloquent\Builder::joinNestedRelationship($relationships, $callback, $joinType, $useAlias, $disableExtraConditions, $morphable);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::orderByPowerJoins()
+ * @param array|string $sort
+ * @param string $direction
+ * @param string|null $aggregation
+ * @param string $joinType
+ * @param mixed $aliases
+ * @static
+ */
+ public static function orderByPowerJoins($sort, $direction = 'asc', $aggregation = null, $joinType = 'join', $aliases = null)
+ {
+ return \Illuminate\Database\Eloquent\Builder::orderByPowerJoins($sort, $direction, $aggregation, $joinType, $aliases);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::orderByLeftPowerJoins()
+ * @param array|string $sort
+ * @param string $direction
+ * @static
+ */
+ public static function orderByLeftPowerJoins($sort, $direction = 'asc')
+ {
+ return \Illuminate\Database\Eloquent\Builder::orderByLeftPowerJoins($sort, $direction);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::orderByPowerJoinsCount()
+ * @param array|string $sort
+ * @param string $direction
+ * @static
+ */
+ public static function orderByPowerJoinsCount($sort, $direction = 'asc')
+ {
+ return \Illuminate\Database\Eloquent\Builder::orderByPowerJoinsCount($sort, $direction);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::orderByLeftPowerJoinsCount()
+ * @param array|string $sort
+ * @param string $direction
+ * @static
+ */
+ public static function orderByLeftPowerJoinsCount($sort, $direction = 'asc')
+ {
+ return \Illuminate\Database\Eloquent\Builder::orderByLeftPowerJoinsCount($sort, $direction);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::orderByPowerJoinsSum()
+ * @param array|string $sort
+ * @param string $direction
+ * @static
+ */
+ public static function orderByPowerJoinsSum($sort, $direction = 'asc')
+ {
+ return \Illuminate\Database\Eloquent\Builder::orderByPowerJoinsSum($sort, $direction);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::orderByLeftPowerJoinsSum()
+ * @param array|string $sort
+ * @param string $direction
+ * @static
+ */
+ public static function orderByLeftPowerJoinsSum($sort, $direction = 'asc')
+ {
+ return \Illuminate\Database\Eloquent\Builder::orderByLeftPowerJoinsSum($sort, $direction);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::orderByPowerJoinsAvg()
+ * @param array|string $sort
+ * @param string $direction
+ * @static
+ */
+ public static function orderByPowerJoinsAvg($sort, $direction = 'asc')
+ {
+ return \Illuminate\Database\Eloquent\Builder::orderByPowerJoinsAvg($sort, $direction);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::orderByLeftPowerJoinsAvg()
+ * @param array|string $sort
+ * @param string $direction
+ * @static
+ */
+ public static function orderByLeftPowerJoinsAvg($sort, $direction = 'asc')
+ {
+ return \Illuminate\Database\Eloquent\Builder::orderByLeftPowerJoinsAvg($sort, $direction);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::orderByPowerJoinsMin()
+ * @param array|string $sort
+ * @param string $direction
+ * @static
+ */
+ public static function orderByPowerJoinsMin($sort, $direction = 'asc')
+ {
+ return \Illuminate\Database\Eloquent\Builder::orderByPowerJoinsMin($sort, $direction);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::orderByLeftPowerJoinsMin()
+ * @param array|string $sort
+ * @param string $direction
+ * @static
+ */
+ public static function orderByLeftPowerJoinsMin($sort, $direction = 'asc')
+ {
+ return \Illuminate\Database\Eloquent\Builder::orderByLeftPowerJoinsMin($sort, $direction);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::orderByPowerJoinsMax()
+ * @param array|string $sort
+ * @param string $direction
+ * @static
+ */
+ public static function orderByPowerJoinsMax($sort, $direction = 'asc')
+ {
+ return \Illuminate\Database\Eloquent\Builder::orderByPowerJoinsMax($sort, $direction);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::orderByLeftPowerJoinsMax()
+ * @param array|string $sort
+ * @param string $direction
+ * @static
+ */
+ public static function orderByLeftPowerJoinsMax($sort, $direction = 'asc')
+ {
+ return \Illuminate\Database\Eloquent\Builder::orderByLeftPowerJoinsMax($sort, $direction);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::powerJoinHas()
+ * @param string $relation
+ * @param string $operator
+ * @param int $count
+ * @param mixed $boolean
+ * @param \Closure|array|string|null $callback
+ * @param string|null $morphable
+ * @return static
+ * @static
+ */
+ public static function powerJoinHas($relation, $operator = '>=', $count = 1, $boolean = 'and', $callback = null, $morphable = null)
+ {
+ return \Illuminate\Database\Eloquent\Builder::powerJoinHas($relation, $operator, $count, $boolean, $callback, $morphable);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::hasNestedUsingJoins()
+ * @param string $relations
+ * @param string $operator
+ * @param int $count
+ * @param string $boolean
+ * @param \Closure|array|string|null $callback
+ * @return static
+ * @static
+ */
+ public static function hasNestedUsingJoins($relations, $operator = '>=', $count = 1, $boolean = 'and', $callback = null)
+ {
+ return \Illuminate\Database\Eloquent\Builder::hasNestedUsingJoins($relations, $operator, $count, $boolean, $callback);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::powerJoinDoesntHave()
+ * @param mixed $relation
+ * @param mixed $boolean
+ * @param \Closure|null $callback
+ * @static
+ */
+ public static function powerJoinDoesntHave($relation, $boolean = 'and', $callback = null)
+ {
+ return \Illuminate\Database\Eloquent\Builder::powerJoinDoesntHave($relation, $boolean, $callback);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\JoinRelationship::powerJoinWhereHas()
+ * @param mixed $relation
+ * @param mixed $callback
+ * @param mixed $operator
+ * @param mixed $count
+ * @static
+ */
+ public static function powerJoinWhereHas($relation, $callback = null, $operator = '>=', $count = 1)
+ {
+ return \Illuminate\Database\Eloquent\Builder::powerJoinWhereHas($relation, $callback, $operator, $count);
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\QueryRelationshipExistence::getGroupBy()
+ * @static
+ */
+ public static function getGroupBy()
+ {
+ return \Illuminate\Database\Eloquent\Builder::getGroupBy();
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\QueryRelationshipExistence::getScopes()
+ * @static
+ */
+ public static function getScopes()
+ {
+ return \Illuminate\Database\Eloquent\Builder::getScopes();
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\QueryRelationshipExistence::getSelect()
+ * @static
+ */
+ public static function getSelect()
+ {
+ return \Illuminate\Database\Eloquent\Builder::getSelect();
+ }
+
+ /**
+ * @see \Kirschbaum\PowerJoins\Mixins\QueryRelationshipExistence::getRelationWithoutConstraintsProxy()
+ * @param mixed $relation
+ * @static
+ */
+ public static function getRelationWithoutConstraintsProxy($relation)
+ {
+ return \Illuminate\Database\Eloquent\Builder::getRelationWithoutConstraintsProxy($relation);
+ }
+
+ /**
+ * Set the columns to be selected.
+ *
+ * @param mixed $columns
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function select($columns = [])
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->select($columns);
+ }
+
+ /**
+ * Add a subselect expression to the query.
+ *
+ * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder<*>|string $query
+ * @param string $as
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @throws \InvalidArgumentException
+ * @static
+ */
+ public static function selectSub($query, $as)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->selectSub($query, $as);
+ }
+
+ /**
+ * Add a new "raw" select expression to the query.
+ *
+ * @param string $expression
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function selectRaw($expression, $bindings = [])
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->selectRaw($expression, $bindings);
+ }
+
+ /**
+ * Makes "from" fetch from a subquery.
+ *
+ * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder<*>|string $query
+ * @param string $as
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @throws \InvalidArgumentException
+ * @static
+ */
+ public static function fromSub($query, $as)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->fromSub($query, $as);
+ }
+
+ /**
+ * Add a raw from clause to the query.
+ *
+ * @param string $expression
+ * @param mixed $bindings
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function fromRaw($expression, $bindings = [])
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->fromRaw($expression, $bindings);
+ }
+
+ /**
+ * Add a new select column to the query.
+ *
+ * @param mixed $column
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function addSelect($column)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->addSelect($column);
+ }
+
+ /**
+ * Force the query to only return distinct results.
+ *
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function distinct()
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->distinct();
+ }
+
+ /**
+ * Set the table which the query is targeting.
+ *
+ * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder<*>|\Illuminate\Contracts\Database\Query\Expression|string $table
+ * @param string|null $as
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function from($table, $as = null)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->from($table, $as);
+ }
+
+ /**
+ * Add an index hint to suggest a query index.
+ *
+ * @param string $index
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function useIndex($index)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->useIndex($index);
+ }
+
+ /**
+ * Add an index hint to force a query index.
+ *
+ * @param string $index
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function forceIndex($index)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->forceIndex($index);
+ }
+
+ /**
+ * Add an index hint to ignore a query index.
+ *
+ * @param string $index
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function ignoreIndex($index)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->ignoreIndex($index);
+ }
+
+ /**
+ * Add a join clause to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $table
+ * @param \Closure|\Illuminate\Contracts\Database\Query\Expression|string $first
+ * @param string|null $operator
+ * @param \Illuminate\Contracts\Database\Query\Expression|string|null $second
+ * @param string $type
+ * @param bool $where
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function join($table, $first, $operator = null, $second = null, $type = 'inner', $where = false)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->join($table, $first, $operator, $second, $type, $where);
+ }
+
+ /**
+ * Add a "join where" clause to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $table
+ * @param \Closure|\Illuminate\Contracts\Database\Query\Expression|string $first
+ * @param string $operator
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $second
+ * @param string $type
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function joinWhere($table, $first, $operator, $second, $type = 'inner')
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->joinWhere($table, $first, $operator, $second, $type);
+ }
+
+ /**
+ * Add a subquery join clause to the query.
+ *
+ * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder<*>|string $query
+ * @param string $as
+ * @param \Closure|\Illuminate\Contracts\Database\Query\Expression|string $first
+ * @param string|null $operator
+ * @param \Illuminate\Contracts\Database\Query\Expression|string|null $second
+ * @param string $type
+ * @param bool $where
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @throws \InvalidArgumentException
+ * @static
+ */
+ public static function joinSub($query, $as, $first, $operator = null, $second = null, $type = 'inner', $where = false)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->joinSub($query, $as, $first, $operator, $second, $type, $where);
+ }
+
+ /**
+ * Add a lateral join clause to the query.
+ *
+ * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder<*>|string $query
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function joinLateral($query, $as, $type = 'inner')
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->joinLateral($query, $as, $type);
+ }
+
+ /**
+ * Add a lateral left join to the query.
+ *
+ * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder<*>|string $query
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function leftJoinLateral($query, $as)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->leftJoinLateral($query, $as);
+ }
+
+ /**
+ * Add a left join to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $table
+ * @param \Closure|\Illuminate\Contracts\Database\Query\Expression|string $first
+ * @param string|null $operator
+ * @param \Illuminate\Contracts\Database\Query\Expression|string|null $second
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function leftJoin($table, $first, $operator = null, $second = null)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->leftJoin($table, $first, $operator, $second);
+ }
+
+ /**
+ * Add a "join where" clause to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $table
+ * @param \Closure|\Illuminate\Contracts\Database\Query\Expression|string $first
+ * @param string $operator
+ * @param \Illuminate\Contracts\Database\Query\Expression|string|null $second
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function leftJoinWhere($table, $first, $operator, $second)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->leftJoinWhere($table, $first, $operator, $second);
+ }
+
+ /**
+ * Add a subquery left join to the query.
+ *
+ * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder<*>|string $query
+ * @param string $as
+ * @param \Closure|\Illuminate\Contracts\Database\Query\Expression|string $first
+ * @param string|null $operator
+ * @param \Illuminate\Contracts\Database\Query\Expression|string|null $second
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function leftJoinSub($query, $as, $first, $operator = null, $second = null)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->leftJoinSub($query, $as, $first, $operator, $second);
+ }
+
+ /**
+ * Add a right join to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $table
+ * @param \Closure|string $first
+ * @param string|null $operator
+ * @param \Illuminate\Contracts\Database\Query\Expression|string|null $second
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function rightJoin($table, $first, $operator = null, $second = null)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->rightJoin($table, $first, $operator, $second);
+ }
+
+ /**
+ * Add a "right join where" clause to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $table
+ * @param \Closure|\Illuminate\Contracts\Database\Query\Expression|string $first
+ * @param string $operator
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $second
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function rightJoinWhere($table, $first, $operator, $second)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->rightJoinWhere($table, $first, $operator, $second);
+ }
+
+ /**
+ * Add a subquery right join to the query.
+ *
+ * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder<*>|string $query
+ * @param string $as
+ * @param \Closure|\Illuminate\Contracts\Database\Query\Expression|string $first
+ * @param string|null $operator
+ * @param \Illuminate\Contracts\Database\Query\Expression|string|null $second
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function rightJoinSub($query, $as, $first, $operator = null, $second = null)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->rightJoinSub($query, $as, $first, $operator, $second);
+ }
+
+ /**
+ * Add a "cross join" clause to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $table
+ * @param \Closure|\Illuminate\Contracts\Database\Query\Expression|string|null $first
+ * @param string|null $operator
+ * @param \Illuminate\Contracts\Database\Query\Expression|string|null $second
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function crossJoin($table, $first = null, $operator = null, $second = null)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->crossJoin($table, $first, $operator, $second);
+ }
+
+ /**
+ * Add a subquery cross join to the query.
+ *
+ * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder<*>|string $query
+ * @param string $as
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function crossJoinSub($query, $as)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->crossJoinSub($query, $as);
+ }
+
+ /**
+ * Merge an array of where clauses and bindings.
+ *
+ * @param array $wheres
+ * @param array $bindings
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function mergeWheres($wheres, $bindings)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->mergeWheres($wheres, $bindings);
+ }
+
+ /**
+ * Prepare the value and operator for a where clause.
+ *
+ * @param string $value
+ * @param string $operator
+ * @param bool $useDefault
+ * @return array
+ * @throws \InvalidArgumentException
+ * @static
+ */
+ public static function prepareValueAndOperator($value, $operator, $useDefault = false)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->prepareValueAndOperator($value, $operator, $useDefault);
+ }
+
+ /**
+ * Add a "where" clause comparing two columns to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string|array $first
+ * @param string|null $operator
+ * @param string|null $second
+ * @param string|null $boolean
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereColumn($first, $operator = null, $second = null, $boolean = 'and')
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereColumn($first, $operator, $second, $boolean);
+ }
+
+ /**
+ * Add an "or where" clause comparing two columns to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string|array $first
+ * @param string|null $operator
+ * @param string|null $second
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereColumn($first, $operator = null, $second = null)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereColumn($first, $operator, $second);
+ }
+
+ /**
+ * Add a raw where clause to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $sql
+ * @param mixed $bindings
+ * @param string $boolean
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereRaw($sql, $bindings = [], $boolean = 'and')
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereRaw($sql, $bindings, $boolean);
+ }
+
+ /**
+ * Add a raw or where clause to the query.
+ *
+ * @param string $sql
+ * @param mixed $bindings
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereRaw($sql, $bindings = [])
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereRaw($sql, $bindings);
+ }
+
+ /**
+ * Add a "where like" clause to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @param string $value
+ * @param bool $caseSensitive
+ * @param string $boolean
+ * @param bool $not
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereLike($column, $value, $caseSensitive = false, $boolean = 'and', $not = false)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereLike($column, $value, $caseSensitive, $boolean, $not);
+ }
+
+ /**
+ * Add an "or where like" clause to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @param string $value
+ * @param bool $caseSensitive
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereLike($column, $value, $caseSensitive = false)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereLike($column, $value, $caseSensitive);
+ }
+
+ /**
+ * Add a "where not like" clause to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @param string $value
+ * @param bool $caseSensitive
+ * @param string $boolean
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereNotLike($column, $value, $caseSensitive = false, $boolean = 'and')
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereNotLike($column, $value, $caseSensitive, $boolean);
+ }
+
+ /**
+ * Add an "or where not like" clause to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @param string $value
+ * @param bool $caseSensitive
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereNotLike($column, $value, $caseSensitive = false)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereNotLike($column, $value, $caseSensitive);
+ }
+
+ /**
+ * Add a "where in" clause to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @param mixed $values
+ * @param string $boolean
+ * @param bool $not
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereIn($column, $values, $boolean = 'and', $not = false)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereIn($column, $values, $boolean, $not);
+ }
+
+ /**
+ * Add an "or where in" clause to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @param mixed $values
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereIn($column, $values)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereIn($column, $values);
+ }
+
+ /**
+ * Add a "where not in" clause to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @param mixed $values
+ * @param string $boolean
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereNotIn($column, $values, $boolean = 'and')
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereNotIn($column, $values, $boolean);
+ }
+
+ /**
+ * Add an "or where not in" clause to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @param mixed $values
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereNotIn($column, $values)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereNotIn($column, $values);
+ }
+
+ /**
+ * Add a "where in raw" clause for integer values to the query.
+ *
+ * @param string $column
+ * @param \Illuminate\Contracts\Support\Arrayable|array $values
+ * @param string $boolean
+ * @param bool $not
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereIntegerInRaw($column, $values, $boolean = 'and', $not = false)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereIntegerInRaw($column, $values, $boolean, $not);
+ }
+
+ /**
+ * Add an "or where in raw" clause for integer values to the query.
+ *
+ * @param string $column
+ * @param \Illuminate\Contracts\Support\Arrayable|array $values
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereIntegerInRaw($column, $values)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereIntegerInRaw($column, $values);
+ }
+
+ /**
+ * Add a "where not in raw" clause for integer values to the query.
+ *
+ * @param string $column
+ * @param \Illuminate\Contracts\Support\Arrayable|array $values
+ * @param string $boolean
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereIntegerNotInRaw($column, $values, $boolean = 'and')
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereIntegerNotInRaw($column, $values, $boolean);
+ }
+
+ /**
+ * Add an "or where not in raw" clause for integer values to the query.
+ *
+ * @param string $column
+ * @param \Illuminate\Contracts\Support\Arrayable|array $values
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereIntegerNotInRaw($column, $values)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereIntegerNotInRaw($column, $values);
+ }
+
+ /**
+ * Add a "where null" clause to the query.
+ *
+ * @param string|array|\Illuminate\Contracts\Database\Query\Expression $columns
+ * @param string $boolean
+ * @param bool $not
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereNull($columns, $boolean = 'and', $not = false)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereNull($columns, $boolean, $not);
+ }
+
+ /**
+ * Add an "or where null" clause to the query.
+ *
+ * @param string|array|\Illuminate\Contracts\Database\Query\Expression $column
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereNull($column)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereNull($column);
+ }
+
+ /**
+ * Add a "where not null" clause to the query.
+ *
+ * @param string|array|\Illuminate\Contracts\Database\Query\Expression $columns
+ * @param string $boolean
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereNotNull($columns, $boolean = 'and')
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereNotNull($columns, $boolean);
+ }
+
+ /**
+ * Add a where between statement to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @param string $boolean
+ * @param bool $not
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereBetween($column, $values, $boolean = 'and', $not = false)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereBetween($column, $values, $boolean, $not);
+ }
+
+ /**
+ * Add a where between statement using columns to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @param string $boolean
+ * @param bool $not
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereBetweenColumns($column, $values, $boolean = 'and', $not = false)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereBetweenColumns($column, $values, $boolean, $not);
+ }
+
+ /**
+ * Add an or where between statement to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereBetween($column, $values)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereBetween($column, $values);
+ }
+
+ /**
+ * Add an or where between statement using columns to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereBetweenColumns($column, $values)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereBetweenColumns($column, $values);
+ }
+
+ /**
+ * Add a where not between statement to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @param string $boolean
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereNotBetween($column, $values, $boolean = 'and')
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereNotBetween($column, $values, $boolean);
+ }
+
+ /**
+ * Add a where not between statement using columns to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @param string $boolean
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereNotBetweenColumns($column, $values, $boolean = 'and')
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereNotBetweenColumns($column, $values, $boolean);
+ }
+
+ /**
+ * Add an or where not between statement to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereNotBetween($column, $values)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereNotBetween($column, $values);
+ }
+
+ /**
+ * Add an or where not between statement using columns to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereNotBetweenColumns($column, $values)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereNotBetweenColumns($column, $values);
+ }
+
+ /**
+ * Add a where between columns statement using a value to the query.
+ *
+ * @param mixed $value
+ * @param array{\Illuminate\Contracts\Database\Query\Expression|string, \Illuminate\Contracts\Database\Query\Expression|string} $columns
+ * @param string $boolean
+ * @param bool $not
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereValueBetween($value, $columns, $boolean = 'and', $not = false)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereValueBetween($value, $columns, $boolean, $not);
+ }
+
+ /**
+ * Add an or where between columns statement using a value to the query.
+ *
+ * @param mixed $value
+ * @param array{\Illuminate\Contracts\Database\Query\Expression|string, \Illuminate\Contracts\Database\Query\Expression|string} $columns
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereValueBetween($value, $columns)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereValueBetween($value, $columns);
+ }
+
+ /**
+ * Add a where not between columns statement using a value to the query.
+ *
+ * @param mixed $value
+ * @param array{\Illuminate\Contracts\Database\Query\Expression|string, \Illuminate\Contracts\Database\Query\Expression|string} $columns
+ * @param string $boolean
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereValueNotBetween($value, $columns, $boolean = 'and')
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereValueNotBetween($value, $columns, $boolean);
+ }
+
+ /**
+ * Add an or where not between columns statement using a value to the query.
+ *
+ * @param mixed $value
+ * @param array{\Illuminate\Contracts\Database\Query\Expression|string, \Illuminate\Contracts\Database\Query\Expression|string} $columns
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereValueNotBetween($value, $columns)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereValueNotBetween($value, $columns);
+ }
+
+ /**
+ * Add an "or where not null" clause to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereNotNull($column)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereNotNull($column);
+ }
+
+ /**
+ * Add a "where date" statement to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @param \DateTimeInterface|string|null $operator
+ * @param \DateTimeInterface|string|null $value
+ * @param string $boolean
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereDate($column, $operator, $value = null, $boolean = 'and')
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereDate($column, $operator, $value, $boolean);
+ }
+
+ /**
+ * Add an "or where date" statement to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @param \DateTimeInterface|string|null $operator
+ * @param \DateTimeInterface|string|null $value
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereDate($column, $operator, $value = null)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereDate($column, $operator, $value);
+ }
+
+ /**
+ * Add a "where time" statement to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @param \DateTimeInterface|string|null $operator
+ * @param \DateTimeInterface|string|null $value
+ * @param string $boolean
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereTime($column, $operator, $value = null, $boolean = 'and')
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereTime($column, $operator, $value, $boolean);
+ }
+
+ /**
+ * Add an "or where time" statement to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @param \DateTimeInterface|string|null $operator
+ * @param \DateTimeInterface|string|null $value
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereTime($column, $operator, $value = null)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereTime($column, $operator, $value);
+ }
+
+ /**
+ * Add a "where day" statement to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @param \DateTimeInterface|string|int|null $operator
+ * @param \DateTimeInterface|string|int|null $value
+ * @param string $boolean
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereDay($column, $operator, $value = null, $boolean = 'and')
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereDay($column, $operator, $value, $boolean);
+ }
+
+ /**
+ * Add an "or where day" statement to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @param \DateTimeInterface|string|int|null $operator
+ * @param \DateTimeInterface|string|int|null $value
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereDay($column, $operator, $value = null)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereDay($column, $operator, $value);
+ }
+
+ /**
+ * Add a "where month" statement to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @param \DateTimeInterface|string|int|null $operator
+ * @param \DateTimeInterface|string|int|null $value
+ * @param string $boolean
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereMonth($column, $operator, $value = null, $boolean = 'and')
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereMonth($column, $operator, $value, $boolean);
+ }
+
+ /**
+ * Add an "or where month" statement to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @param \DateTimeInterface|string|int|null $operator
+ * @param \DateTimeInterface|string|int|null $value
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereMonth($column, $operator, $value = null)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereMonth($column, $operator, $value);
+ }
+
+ /**
+ * Add a "where year" statement to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @param \DateTimeInterface|string|int|null $operator
+ * @param \DateTimeInterface|string|int|null $value
+ * @param string $boolean
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereYear($column, $operator, $value = null, $boolean = 'and')
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereYear($column, $operator, $value, $boolean);
+ }
+
+ /**
+ * Add an "or where year" statement to the query.
+ *
+ * @param \Illuminate\Contracts\Database\Query\Expression|string $column
+ * @param \DateTimeInterface|string|int|null $operator
+ * @param \DateTimeInterface|string|int|null $value
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereYear($column, $operator, $value = null)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereYear($column, $operator, $value);
+ }
+
+ /**
+ * Add a nested where statement to the query.
+ *
+ * @param string $boolean
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereNested($callback, $boolean = 'and')
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereNested($callback, $boolean);
+ }
+
+ /**
+ * Create a new query instance for nested where condition.
+ *
+ * @return \Illuminate\Database\Query\Builder
+ * @static
+ */
+ public static function forNestedWhere()
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->forNestedWhere();
+ }
+
+ /**
+ * Add another query builder as a nested where to the query builder.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param string $boolean
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function addNestedWhereQuery($query, $boolean = 'and')
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->addNestedWhereQuery($query, $boolean);
+ }
+
+ /**
+ * Add an exists clause to the query.
+ *
+ * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder<*> $callback
+ * @param string $boolean
+ * @param bool $not
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereExists($callback, $boolean = 'and', $not = false)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereExists($callback, $boolean, $not);
+ }
+
+ /**
+ * Add an or exists clause to the query.
+ *
+ * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder<*> $callback
+ * @param bool $not
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereExists($callback, $not = false)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereExists($callback, $not);
+ }
+
+ /**
+ * Add a where not exists clause to the query.
+ *
+ * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder<*> $callback
+ * @param string $boolean
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereNotExists($callback, $boolean = 'and')
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereNotExists($callback, $boolean);
+ }
+
+ /**
+ * Add a where not exists clause to the query.
+ *
+ * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder<*> $callback
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereNotExists($callback)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereNotExists($callback);
+ }
+
+ /**
+ * Add an exists clause to the query.
+ *
+ * @param string $boolean
+ * @param bool $not
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function addWhereExistsQuery($query, $boolean = 'and', $not = false)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->addWhereExistsQuery($query, $boolean, $not);
+ }
+
+ /**
+ * Adds a where condition using row values.
+ *
+ * @param array $columns
+ * @param string $operator
+ * @param array $values
+ * @param string $boolean
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @throws \InvalidArgumentException
+ * @static
+ */
+ public static function whereRowValues($columns, $operator, $values, $boolean = 'and')
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereRowValues($columns, $operator, $values, $boolean);
+ }
+
+ /**
+ * Adds an or where condition using row values.
+ *
+ * @param array $columns
+ * @param string $operator
+ * @param array $values
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereRowValues($columns, $operator, $values)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereRowValues($columns, $operator, $values);
+ }
+
+ /**
+ * Add a "where JSON contains" clause to the query.
+ *
+ * @param string $column
+ * @param mixed $value
+ * @param string $boolean
+ * @param bool $not
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereJsonContains($column, $value, $boolean = 'and', $not = false)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereJsonContains($column, $value, $boolean, $not);
+ }
+
+ /**
+ * Add an "or where JSON contains" clause to the query.
+ *
+ * @param string $column
+ * @param mixed $value
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereJsonContains($column, $value)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereJsonContains($column, $value);
+ }
+
+ /**
+ * Add a "where JSON not contains" clause to the query.
+ *
+ * @param string $column
+ * @param mixed $value
+ * @param string $boolean
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereJsonDoesntContain($column, $value, $boolean = 'and')
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereJsonDoesntContain($column, $value, $boolean);
+ }
+
+ /**
+ * Add an "or where JSON not contains" clause to the query.
+ *
+ * @param string $column
+ * @param mixed $value
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereJsonDoesntContain($column, $value)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereJsonDoesntContain($column, $value);
+ }
+
+ /**
+ * Add a "where JSON overlaps" clause to the query.
+ *
+ * @param string $column
+ * @param mixed $value
+ * @param string $boolean
+ * @param bool $not
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function whereJsonOverlaps($column, $value, $boolean = 'and', $not = false)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->whereJsonOverlaps($column, $value, $boolean, $not);
+ }
+
+ /**
+ * Add an "or where JSON overlaps" clause to the query.
+ *
+ * @param string $column
+ * @param mixed $value
+ * @return \Illuminate\Database\Eloquent\Builder
+ * @static
+ */
+ public static function orWhereJsonOverlaps($column, $value)
+ {
+ /** @var \Illuminate\Database\Query\Builder $instance */
+ return $instance->orWhereJsonOverlaps($column, $value);
+ }
+
+ /**
+ * Add a "where JSON not overlap" clause to the query.
+ *
+ * @param string $column
+ * @param mixed $value
+ * @param string $boolean
+ * @return \Illuminate\Database\Eloquent\Builder