> ## Documentation Index
> Fetch the complete documentation index at: https://geni.masiting.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Spatie Laravel Query Builder

> Automatic query parameter documentation from Spatie Laravel Query Builder method chains.

## Overview

[Spatie Laravel Query Builder](https://spatie.be/docs/laravel-query-builder) (`spatie/laravel-query-builder`) allows building Eloquent queries directly from API request query parameters.

Geni statically inspects `QueryBuilder::for(...)` method chains in controller actions on GET operations and generates corresponding OpenAPI query parameters without booting the application or running queries.

## Example Controller Action

```php theme={null}
use App\Models\User;
use Spatie\QueryBuilder\AllowedFilter;
use Spatie\QueryBuilder\QueryBuilder;

class UserController
{
    public function index()
    {
        return QueryBuilder::for(User::class)
            ->allowedFilters([
                'name',
                AllowedFilter::exact('email'),
                AllowedFilter::scope('active'),
                AllowedFilter::trashed(),
            ])
            ->allowedSorts(['name', 'created_at'])
            ->defaultSort('-created_at')
            ->allowedIncludes(['posts', 'posts.comments'])
            ->allowedFields(['id', 'name', 'posts.title'])
            ->allowedAppends(['full_name'])
            ->get();
    }
}
```

## Generated OpenAPI Query Parameters

From this single controller action, Geni generates comprehensive OpenAPI parameters:

### 1. Filters (`filter[...]`)

| Parameter Name    | Type                                | Description                  |
| ----------------- | ----------------------------------- | ---------------------------- |
| `filter[name]`    | `string`                            | Filter by name               |
| `filter[email]`   | `string`                            | Exact match filter for email |
| `filter[active]`  | `string`                            | Scope filter for active      |
| `filter[trashed]` | `string` (enum: `['with', 'only']`) | Filter soft-deleted records  |

If the filtered property matches a column on the model table, Geni automatically assigns the database column type (e.g., `integer`, `boolean`, `string`) resolved from your migrations.

### 2. Sorts (`sort`)

Geni combines all `allowedSorts` into a single `sort` query parameter:

* **Name**: `sort`
* **In**: `query`
* **Type**: `string`
* **Enum**: `['name', '-name', 'created_at', '-created_at']`
* **Default**: `'-created_at'` (extracted from `defaultSort`)
* **Description**: `"Comma-separated list of fields to sort by. Prefix with '-' for descending order."`

### 3. Includes (`include`)

* **Name**: `include`
* **In**: `query`
* **Type**: `string`
* **Enum**: `['posts', 'posts.comments']`
* **Description**: `"Comma-separated list of relationships to include."`

### 4. Sparse Fieldsets (`fields[...]`)

* `fields[users]`: `type: string`, sparse fieldset for the primary model.
* `fields[posts]`: `type: string`, sparse fieldset for the related model.

### 5. Appends (`append`)

* **Name**: `append`
* **In**: `query`
* **Type**: `string`
* **Enum**: `['full_name']`
* **Description**: `"Comma-separated list of dynamic accessors or appends to include."`

## Handling Dynamic Arguments

If dynamic arguments or variables are passed to builder methods (e.g., `allowedFilters($dynamicFilters)`), Geni records a non-fatal `InferenceDiagnostic` entry and continues parsing the remaining literal configuration without failing.
