{"id":43671235,"url":"https://github.com/dev-toolbelt/laravel-eloquent-plus","last_synced_at":"2026-02-13T00:58:40.685Z","repository":{"id":336447271,"uuid":"1148433018","full_name":"Dev-Toolbelt/laravel-eloquent-plus","owner":"Dev-Toolbelt","description":"An opinionated package that extends Eloquent with a reusable base model, custom casts, validation rules, and query scopes to solve common, real-world problems in Laravel applications.","archived":false,"fork":false,"pushed_at":"2026-02-04T22:25:04.000Z","size":161,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-05T00:30:05.113Z","etag":null,"topics":["audit","blamable","casting","laravel","laravel-framework","lifecycle-hooks","model","soft-deletes","uuid","validation"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Dev-Toolbelt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-03T00:43:02.000Z","updated_at":"2026-02-04T22:25:08.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Dev-Toolbelt/laravel-eloquent-plus","commit_stats":null,"previous_names":["dev-toolbelt/laravel-eloquent-plus"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/Dev-Toolbelt/laravel-eloquent-plus","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dev-Toolbelt%2Flaravel-eloquent-plus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dev-Toolbelt%2Flaravel-eloquent-plus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dev-Toolbelt%2Flaravel-eloquent-plus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dev-Toolbelt%2Flaravel-eloquent-plus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Dev-Toolbelt","download_url":"https://codeload.github.com/Dev-Toolbelt/laravel-eloquent-plus/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dev-Toolbelt%2Flaravel-eloquent-plus/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29208179,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-07T20:33:12.493Z","status":"ssl_error","status_checked_at":"2026-02-07T20:30:47.381Z","response_time":63,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["audit","blamable","casting","laravel","laravel-framework","lifecycle-hooks","model","soft-deletes","uuid","validation"],"created_at":"2026-02-05T00:04:56.740Z","updated_at":"2026-02-13T00:58:40.679Z","avatar_url":"https://github.com/Dev-Toolbelt.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Laravel Eloquent Plus\n\n[![CI](https://github.com/Dev-Toolbelt/laravel-eloquent-plus/actions/workflows/ci.yml/badge.svg)](https://github.com/Dev-Toolbelt/laravel-eloquent-plus/actions/workflows/ci.yml)\n[![codecov](https://codecov.io/gh/Dev-Toolbelt/laravel-eloquent-plus/branch/main/graph/badge.svg)](https://codecov.io/gh/Dev-Toolbelt/laravel-eloquent-plus)\n[![Latest Stable Version](https://poser.pugx.org/dev-toolbelt/laravel-eloquent-plus/v/stable)](https://packagist.org/packages/dev-toolbelt/laravel-eloquent-plus)\n[![Total Downloads](https://poser.pugx.org/dev-toolbelt/laravel-eloquent-plus/downloads)](https://packagist.org/packages/dev-toolbelt/laravel-eloquent-plus)\n[![License](https://poser.pugx.org/dev-toolbelt/laravel-eloquent-plus/license)](https://packagist.org/packages/dev-toolbelt/laravel-eloquent-plus)\n[![PHP Version](https://img.shields.io/badge/php-%5E8.3-blue)](https://php.net)\n\n**Supercharge your Laravel Eloquent models** with automatic validation, audit trails, external IDs, smart casting, and lifecycle hooks — all with zero boilerplate.\n\n---\n\n## Features\n\n| Feature | Description |\n|---------|-------------|\n| **Automatic Validation** | Validate model attributes before save using Laravel's validation rules |\n| **Audit Trail (Blamable)** | Automatically track `created_by`, `updated_by`, and `deleted_by` |\n| **External ID (UUID)** | Public-facing UUIDs while keeping internal integer IDs |\n| **Smart Auto-Casting** | Infer attribute casts from validation rules automatically |\n| **Date Formatting** | Control date output format (string or Carbon instance) |\n| **Lifecycle Hooks** | Execute custom logic at `beforeValidate`, `beforeSave`, `afterSave`, `beforeDelete`, `afterDelete` |\n| **Hidden Attributes** | Automatically hide sensitive fields like `deleted_at`, `deleted_by` |\n| **Custom Validators** | Built-in CPF/CNPJ (Brazilian documents) and Hex Color validators |\n| **Custom Casts** | `OnlyNumbers`, `RemoveSpecialCharacters`, `UuidToIdCast` |\n| **Cast Aliases** | Register short names for custom casts like Laravel's built-in types |\n\n---\n\n## Requirements\n\n- PHP ^8.3\n- Laravel ^11.0\n\n---\n\n## Installation\n\n```bash\ncomposer require dev-toolbelt/laravel-eloquent-plus\n```\n\nThe service provider is automatically registered via Laravel's package discovery.\n\n---\n\n## Quick Start\n\nExtend your models from `ModelBase` to unlock all features:\n\n```php\n\u003c?php\n\nnamespace App\\Models;\n\nuse DevToolbelt\\LaravelEloquentPlus\\ModelBase;\n\nclass Product extends ModelBase\n{\n    protected $fillable = ['name', 'price', 'sku'];\n\n    protected array $rules = [\n        'name' =\u003e ['required', 'string', 'max:255'],\n        'price' =\u003e ['required', 'numeric', 'min:0'],\n        'sku' =\u003e ['required', 'string', 'unique:products,sku'],\n    ];\n}\n```\n\nThat's it! Your model now has:\n- Automatic validation before create/update\n- Audit trail (`created_by`, `updated_by`, `deleted_by`)\n- Soft deletes with tracking\n- External UUID for public APIs\n- Smart type casting inferred from rules\n- Lifecycle hooks ready to use\n\n---\n\n## Available Traits\n\nUse traits individually if you don't want the full `ModelBase`:\n\n| Trait | Description |\n|-------|-------------|\n| `HasValidation` | Automatic validation with rules and auto-population of timestamps/blamable |\n| `HasBlamable` | Track who created, updated, and deleted records |\n| `HasExternalId` | UUID-based public identifiers |\n| `HasAutoCasting` | Infer casts from validation rules |\n| `HasDateFormatting` | Control date attribute output format |\n| `HasLifecycleHooks` | Model lifecycle callbacks |\n| `HasHiddenAttributes` | Auto-hide sensitive fields |\n| `HasCastAliases` | Register custom cast aliases |\n\n```php\nuse Illuminate\\Database\\Eloquent\\Model;\nuse DevToolbelt\\LaravelEloquentPlus\\Concerns\\HasValidation;\nuse DevToolbelt\\LaravelEloquentPlus\\Concerns\\HasBlamable;\n\nclass MyModel extends Model\n{\n    use HasValidation;\n    use HasBlamable;\n\n    // ...\n}\n```\n\n---\n\n## Validation\n\nDefine rules in your model and validation runs automatically:\n\n```php\nclass User extends ModelBase\n{\n    protected array $rules = [\n        'name' =\u003e ['required', 'string', 'max:255'],\n        'email' =\u003e ['required', 'email', 'unique:users,email'],\n        'document' =\u003e ['required', 'cpf_cnpj'], // Brazilian CPF/CNPJ\n        'theme_color' =\u003e ['nullable', 'hex_color'],\n    ];\n}\n```\n\n### Built-in Validators\n\n| Validator | Alias | Description |\n|-----------|-------|-------------|\n| `CpfCnpjValidator` | `cpf_cnpj` | Validates Brazilian CPF (11 digits) or CNPJ (14 digits) |\n| `CpfCnpjValidator` | `cpf` | Validates only CPF |\n| `CpfCnpjValidator` | `cnpj` | Validates only CNPJ |\n| `HexColor` | `hex_color` | Validates hex color codes (#FFF or #FFFFFF) |\n\n### Validation Exception\n\nWhen validation fails, a `ValidationException` is thrown with detailed error information:\n\n```php\nuse DevToolbelt\\LaravelEloquentPlus\\Exceptions\\ValidationException;\n\ntry {\n    $user-\u003esave();\n} catch (ValidationException $e) {\n    $e-\u003egetErrors();        // All errors as array\n    $e-\u003egetMessages();      // All error messages\n    $e-\u003ehasErrorFor('email'); // Check specific field\n    $e-\u003egetFirstMessageFor('email'); // Get first error message\n}\n```\n\n---\n\n## Audit Trail (Blamable)\n\nTrack who performed actions on your records. Blamable is **disabled by default** and must be explicitly enabled per model:\n\n```php\nclass Post extends ModelBase\n{\n    // Enable blamable audit tracking\n    protected bool $usesBlamable = true;\n\n    // These columns are automatically populated:\n    // - created_by: Set on create (authenticated user ID)\n    // - updated_by: Set on create and update\n    // - deleted_by: Set on soft delete\n}\n```\n\n### Database Migration\n\n```php\nSchema::create('posts', function (Blueprint $table) {\n    $table-\u003eid();\n    $table-\u003estring('title');\n    $table-\u003etimestamps();\n    $table-\u003esoftDeletes();\n\n    // Blamable columns\n    $table-\u003eforeignId('created_by')-\u003econstrained('users');\n    $table-\u003eforeignId('updated_by')-\u003enullable()-\u003econstrained('users');\n    $table-\u003eforeignId('deleted_by')-\u003enullable()-\u003econstrained('users');\n});\n```\n\n### Graceful Column Handling\n\nIf your table doesn't have blamable columns (`created_by`, `updated_by`, `deleted_by`), the trait will **silently skip** setting those columns. This allows you to enable blamable on models where only some audit columns exist:\n\n```php\nclass Comment extends ModelBase\n{\n    protected bool $usesBlamable = true;\n\n    // Even if the table only has created_by and updated_by (no deleted_by),\n    // blamable will work for the columns that exist and skip the rest.\n}\n```\n\nThe same graceful behavior applies to **timestamps** (`created_at`, `updated_at`). If a timestamp column doesn't exist on the table, it is silently skipped instead of causing an error.\n\nTo enforce that all expected columns exist, enable [Strict Mode](#strict-mode).\n\n### Customizing Column Names\n\nOverride the constants in your model:\n\n```php\nclass Post extends ModelBase\n{\n    public const string CREATED_BY = 'author_id';\n    public const string UPDATED_BY = 'editor_id';\n    public const string DELETED_BY = 'remover_id';\n}\n```\n\n---\n\n## External ID (UUID)\n\nExpose UUIDs publicly while keeping integer primary keys internally:\n\n```php\nclass Order extends ModelBase\n{\n    // Enable external ID (enabled by default)\n    public const bool USES_EXTERNAL_ID = true;\n    public const string EXTERNAL_ID_COLUMN = 'external_id';\n}\n```\n\n### Usage\n\n```php\n$order = Order::create(['total' =\u003e 99.99]);\n\n// Internal ID (hidden from serialization)\n$order-\u003eid; // 1\n\n// External UUID (exposed in API responses)\n$order-\u003egetExternalId(); // \"550e8400-e29b-41d4-a716-446655440000\"\n\n// Find by external ID\n$order = Order::findByExternalId('550e8400-e29b-41d4-a716-446655440000');\n$order = Order::findByExternalIdOrFail('550e8400-e29b-41d4-a716-446655440000');\n\n// API response automatically uses UUID as \"id\"\n$order-\u003etoArray(); // ['id' =\u003e '550e8400-e29b-41d4-a716-446655440000', ...]\n```\n\n### Database Migration\n\n```php\nSchema::create('orders', function (Blueprint $table) {\n    $table-\u003eid();\n    $table-\u003euuid('external_id')-\u003eunique();\n    $table-\u003edecimal('total', 10, 2);\n    $table-\u003etimestamps();\n});\n```\n\n---\n\n## Auto-Casting\n\nTypes are automatically inferred from validation rules:\n\n| Validation Rule | Inferred Cast |\n|-----------------|---------------|\n| `boolean` | `boolean` |\n| `integer` | `integer` |\n| `numeric` | `float` |\n| `array` | `array` |\n| `date` | `datetime` |\n| `date_format:Y-m-d` | `date:Y-m-d` |\n| `date_format:Y-m-d H:i:s` | `datetime` |\n| `Illuminate\\Validation\\Rules\\Enum` | Enum class |\n\n```php\nclass Product extends ModelBase\n{\n    protected array $rules = [\n        'active' =\u003e ['boolean'],      // Cast to boolean\n        'quantity' =\u003e ['integer'],    // Cast to integer\n        'price' =\u003e ['numeric'],       // Cast to float\n        'tags' =\u003e ['array'],          // Cast to array\n        'expires_at' =\u003e ['date'],     // Cast to datetime\n    ];\n\n    // No need to define $casts - it's automatic!\n}\n```\n\n---\n\n## Custom Casts\n\n### Built-in Casts\n\n| Cast | Alias | Description |\n|------|-------|-------------|\n| `OnlyNumbers` | `only_numbers` | Removes non-numeric characters |\n| `RemoveSpecialCharacters` | `remove_special_chars` | Removes special characters |\n| `UuidToIdCast` | `uuid_to_id` | Converts UUID to internal ID via lookup |\n\n### Using Casts\n\n```php\nclass Customer extends ModelBase\n{\n    protected $casts = [\n        // Using aliases (short names)\n        'phone' =\u003e 'only_numbers',\n        'name' =\u003e 'remove_special_chars',\n        'category_id' =\u003e 'uuid_to_id:categories,external_id',\n\n        // Or using full class names\n        'document' =\u003e \\DevToolbelt\\LaravelEloquentPlus\\Casts\\OnlyNumbers::class,\n    ];\n}\n```\n\n### UuidToIdCast\n\nConvert external UUIDs to internal IDs automatically:\n\n```php\n// When you receive a UUID from the API\n$order-\u003ecategory_id = '550e8400-e29b-41d4-a716-446655440000';\n\n// It's automatically converted to the internal ID\n$order-\u003ecategory_id; // 42 (the actual ID from categories table)\n```\n\n---\n\n## Lifecycle Hooks\n\nExecute custom logic at specific points:\n\n```php\nclass Invoice extends ModelBase\n{\n    protected function beforeValidate(): void\n    {\n        // Normalize data before validation\n        $this-\u003enumber = strtoupper($this-\u003enumber);\n    }\n\n    protected function beforeSave(): void\n    {\n        // Logic after validation, before database write\n        $this-\u003etotal = $this-\u003ecalculateTotal();\n    }\n\n    protected function afterSave(): void\n    {\n        // Logic after persisting to database\n        event(new InvoiceSaved($this));\n    }\n\n    protected function beforeDelete(): void\n    {\n        // Cleanup before deletion\n        $this-\u003eitems()-\u003edelete();\n    }\n\n    protected function afterDelete(): void\n    {\n        // Logic after deletion\n        Cache::forget(\"invoice:{$this-\u003eid}\");\n    }\n}\n```\n\n### Hook Execution Order\n\n**On Create:**\n```\nautoPopulateFields() → beforeValidate() → validation → beforeSave() → INSERT → afterSave()\n```\n\n**On Update:**\n```\nautoPopulateFields() → beforeValidate() → validation → beforeSave() → UPDATE → afterSave()\n```\n\n**On Delete:**\n```\nbeforeDelete() → DELETE → afterDelete()\n```\n\n---\n\n## Date Formatting\n\nControl how date attributes are returned:\n\n```php\nclass Event extends ModelBase\n{\n    // Return dates as formatted strings (default)\n    protected bool $carbonInstanceInFieldDates = false;\n\n    // Or return Carbon instances\n    protected bool $carbonInstanceInFieldDates = true;\n\n    protected array $rules = [\n        'starts_at' =\u003e ['required', 'date_format:Y-m-d H:i:s'],\n        'ends_at' =\u003e ['required', 'date_format:Y-m-d H:i:s'],\n    ];\n}\n```\n\n```php\n$event-\u003estarts_at; // \"2024-01-15 10:00:00\" (string, when $carbonInstanceInFieldDates = false)\n$event-\u003estarts_at; // Carbon instance (when $carbonInstanceInFieldDates = true)\n```\n\n---\n\n## Configuration\n\n### Publishing Configuration\n\nYou can publish the configuration file to customize package behavior:\n\n```bash\nphp artisan vendor:publish --tag=eloquent-plus-config\n```\n\nThis will create `config/devToolbelt/eloquent-plus.php` in your application.\n\n### Configuration Options\n\n| Option | Default | Description |\n|--------|---------|-------------|\n| `blamable_field_type` | `'integer'` | Type of blamable fields (`created_by`, `updated_by`, `deleted_by`) |\n| `blamable_field_value` | `null` | Callable to customize user identifier extraction (only for `string` type) |\n| `blamable_strict_mode` | `false` | Throw exception if blamable columns are missing on the model |\n| `timestamps_strict_mode` | `false` | Throw exception if timestamp columns are missing on the model |\n\n#### Blamable Field Type\n\nBy default, blamable fields (`created_by`, `updated_by`, `deleted_by`) are validated as integers with an `exists` rule to ensure the user ID exists in the database.\n\nIf your application uses string-based user identifiers (like UUIDs stored as strings), you can change this:\n\n```php\n// config/devToolbelt/eloquent-plus.php\nreturn [\n    'blamable_field_type' =\u003e 'string', // Use 'string' for UUID or other string identifiers\n];\n```\n\n**When set to `'integer'` (default):**\n- Validation rules: `['nullable', 'integer', 'exists:users,id']`\n- Ensures the user ID exists in the users table\n\n**When set to `'string'`:**\n- Validation rules: `['nullable', 'string']`\n- User ID is cast to string automatically\n- No existence check (useful for external user systems or UUIDs)\n\n#### Blamable Field Value (Custom User Identifier)\n\nWhen using `'string'` type, you can customize how the user identifier is retrieved using a callable:\n\n```php\n// config/devToolbelt/eloquent-plus.php\nreturn [\n    'blamable_field_type' =\u003e 'string',\n\n    // Use external_id instead of the default user ID\n    'blamable_field_value' =\u003e fn($user) =\u003e $user-\u003eexternal_id,\n];\n```\n\nThis is useful when:\n- Your users have UUID-based external IDs\n- You need to store a different identifier than the primary key\n- You're integrating with external authentication systems\n\n**Examples:**\n\n```php\n// Use external UUID\n'blamable_field_value' =\u003e fn($user) =\u003e $user-\u003eexternal_id,\n\n// Use email as identifier\n'blamable_field_value' =\u003e fn($user) =\u003e $user-\u003eemail,\n\n// Use a formatted string\n'blamable_field_value' =\u003e fn($user) =\u003e \"user:{$user-\u003eid}\",\n```\n\n#### Strict Mode\n\nBy default, missing blamable and timestamp columns are **silently skipped**. If you want to enforce that all expected columns exist on your models, enable strict mode:\n\n```php\n// config/devToolbelt/eloquent-plus.php\nreturn [\n    'blamable_strict_mode' =\u003e true,\n    'timestamps_strict_mode' =\u003e true,\n];\n```\n\nWhen strict mode is enabled, a `MissingModelPropertyException` is thrown if the model tries to set a column that doesn't exist:\n\n```php\nuse DevToolbelt\\LaravelEloquentPlus\\Exceptions\\MissingModelPropertyException;\n\n// With blamable_strict_mode = true\n// If the table is missing the 'created_by' column:\ntry {\n    $post-\u003esave();\n} catch (MissingModelPropertyException $e) {\n    // 'The property \"created_by\" is required in model \"App\\Models\\Post\". ...'\n}\n```\n\nThis is useful during development to catch missing migrations early. In production, you may prefer the default behavior (`false`) to avoid unexpected errors.\n\n### ModelBase Constants\n\n| Constant | Default | Description |\n|----------|---------|-------------|\n| `CREATED_AT` | `'created_at'` | Created timestamp column |\n| `UPDATED_AT` | `'updated_at'` | Updated timestamp column |\n| `DELETED_AT` | `'deleted_at'` | Soft delete timestamp column |\n| `CREATED_BY` | `'created_by'` | Created by user column |\n| `UPDATED_BY` | `'updated_by'` | Updated by user column |\n| `DELETED_BY` | `'deleted_by'` | Deleted by user column |\n| `USES_EXTERNAL_ID` | `true` | Enable/disable external UUID |\n| `EXTERNAL_ID_COLUMN` | `'external_id'` | External ID column name |\n\n### ModelBase Properties\n\n| Property | Default | Description |\n|----------|---------|-------------|\n| `$timestamps` | `true` | Enable timestamps |\n| `$dateFormat` | `'Y-m-d H:i:s.u'` | Database date format |\n| `$snakeAttributes` | `false` | Snake case in serialization |\n| `$carbonInstanceInFieldDates` | `false` | Return Carbon vs string for dates |\n| `$usesBlamable` | `false` | Enable audit trail (created_by, updated_by, deleted_by) |\n\n---\n\n## Full Example\n\n```php\n\u003c?php\n\nnamespace App\\Models;\n\nuse DevToolbelt\\LaravelEloquentPlus\\ModelBase;\nuse App\\Enums\\OrderStatus;\n\nclass Order extends ModelBase\n{\n    protected $fillable = [\n        'customer_id',\n        'status',\n        'total',\n        'notes',\n        'delivered_at',\n    ];\n\n    protected array $rules = [\n        'customer_id' =\u003e ['required', 'uuid', 'exists:customers,external_id'],\n        'status' =\u003e ['required', new \\Illuminate\\Validation\\Rules\\Enum(OrderStatus::class)],\n        'total' =\u003e ['required', 'numeric', 'min:0'],\n        'notes' =\u003e ['nullable', 'string', 'max:1000'],\n        'delivered_at' =\u003e ['nullable', 'date_format:Y-m-d H:i:s'],\n    ];\n\n    protected $casts = [\n        'customer_id' =\u003e 'uuid_to_id:customers,external_id',\n    ];\n\n    protected function beforeSave(): void\n    {\n        if ($this-\u003eisDirty('status') \u0026\u0026 $this-\u003estatus === OrderStatus::Delivered) {\n            $this-\u003edelivered_at = now();\n        }\n    }\n}\n```\n\n---\n\n## Development\n\n### Running Tests\n\n```bash\ncomposer test\n```\n\n### Running Tests with Coverage\n\n```bash\ncomposer test:coverage\n```\n\n### Code Style (PSR-12)\n\n```bash\ncomposer phpcs\ncomposer phpcs:fix\n```\n\n### Static Analysis (PHPStan)\n\n```bash\ncomposer phpstan\n```\n\n---\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add some amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n### Development Standards\n\n- Minimum **85% test coverage**\n- PSR-12 coding standards\n- PHPStan level 6 compliance\n\n---\n\n## License\n\nThis package is open-sourced software licensed under the [MIT license](LICENSE).\n\n---\n\n### Coverage Report\n\n- **Dashboard:** [Codecov](https://codecov.io/gh/dev-toolbelt/laravel-eloquent-plus)\n- **HTML Report:** [GitHub Pages](https://dev-toolbelt.github.io/laravel-eloquent-plus/)\n\n## Credits\n\n- [Kilderson Sena](https://github.com/dersonsena)\n- [All Contributors](../../contributors)\n\n---\n\nMade with by [Dev Toolbelt](https://github.com/Dev-Toolbelt)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdev-toolbelt%2Flaravel-eloquent-plus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdev-toolbelt%2Flaravel-eloquent-plus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdev-toolbelt%2Flaravel-eloquent-plus/lists"}