Builder

laravel-feature-builder

Builds complete features with CRUD, views, API, migrations, and tests

Overview

The laravel-feature-builder agent creates production-ready Laravel features. It generates all necessary components—models, controllers, views, migrations, tests—following Laravel conventions and best practices.

What It Creates

A complete feature includes all of these components:

Component Location What's Included
Model app/Models/ Fillable, casts, relationships, scopes, accessors
Migration database/migrations/ Schema with indexes, foreign keys, proper types
Controller app/Http/Controllers/ Resource methods, authorization, flash messages
Form Requests app/Http/Requests/ Store/Update validation with authorization
Views resources/views/ Index, create, edit, show Blade templates
Routes routes/web.php Resource routes with middleware
Factory database/factories/ Model factory with realistic fake data
Seeder database/seeders/ Database seeder using factory
Policy app/Policies/ Authorization policy (if auth requested)
Tests tests/Feature/ Pest PHP tests for all CRUD operations

Generation Process

  1. Analyze Requirements - Parse feature description and identify components
  2. Check Existing Code - Look for related models, avoid duplication
  3. Generate Schema - Create migration with appropriate columns and indexes
  4. Build Model - Add relationships based on schema analysis
  5. Create Controller - Generate CRUD methods with validation
  6. Generate Views - Create Blade templates matching your app's style
  7. Write Tests - Generate Pest tests covering all operations
  8. Register Routes - Add resource routes to web.php

Example Output

For a request like "Invoice management with line items and PDF export":

app/
├── Models/
│   ├── Invoice.php           # With hasMany(InvoiceLineItem::class)
│   └── InvoiceLineItem.php   # With belongsTo(Invoice::class)
├── Http/
│   ├── Controllers/
│   │   └── InvoiceController.php
│   └── Requests/
│       ├── StoreInvoiceRequest.php
│       └── UpdateInvoiceRequest.php
├── Services/
│   └── InvoicePdfService.php
database/
├── migrations/
│   ├── 2024_01_15_create_invoices_table.php
│   └── 2024_01_15_create_invoice_line_items_table.php
└── factories/
    └── InvoiceFactory.php
resources/views/invoices/
├── index.blade.php
├── create.blade.php
├── edit.blade.php
└── show.blade.php
tests/Feature/
└── InvoiceTest.php

Generated Model Example

<?php

namespace App\Models;

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

class Invoice extends Model
{
    use HasFactory, SoftDeletes;

    protected $fillable = [
        'customer_id',
        'invoice_number',
        'issued_at',
        'due_at',
        'status',
        'notes',
    ];

    protected $casts = [
        'issued_at' => 'date',
        'due_at' => 'date',
    ];

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

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

    // Accessors
    public function getTotalAttribute(): float
    {
        return $this->lineItems->sum(fn ($item) => $item->quantity * $item->unit_price);
    }

    // Scopes
    public function scopeOverdue($query)
    {
        return $query->where('due_at', '<', now())
                     ->where('status', '!=', 'paid');
    }

    public function scopePending($query)
    {
        return $query->where('status', 'pending');
    }
}

Generated Controller Example

<?php

namespace App\Http\Controllers;

use App\Http\Requests\StoreInvoiceRequest;
use App\Http\Requests\UpdateInvoiceRequest;
use App\Models\Invoice;

class InvoiceController extends Controller
{
    public function index()
    {
        $invoices = Invoice::with('customer')
            ->latest()
            ->paginate(15);

        return view('invoices.index', compact('invoices'));
    }

    public function create()
    {
        return view('invoices.create');
    }

    public function store(StoreInvoiceRequest $request)
    {
        $invoice = Invoice::create($request->validated());

        return redirect()
            ->route('invoices.show', $invoice)
            ->with('success', 'Invoice created successfully.');
    }

    public function show(Invoice $invoice)
    {
        $invoice->load('lineItems', 'customer');

        return view('invoices.show', compact('invoice'));
    }

    public function edit(Invoice $invoice)
    {
        return view('invoices.edit', compact('invoice'));
    }

    public function update(UpdateInvoiceRequest $request, Invoice $invoice)
    {
        $invoice->update($request->validated());

        return redirect()
            ->route('invoices.show', $invoice)
            ->with('success', 'Invoice updated successfully.');
    }

    public function destroy(Invoice $invoice)
    {
        $invoice->delete();

        return redirect()
            ->route('invoices.index')
            ->with('success', 'Invoice deleted successfully.');
    }
}

Customization Options

Include these in your request to customize output:

  • with soft deletes - Add SoftDeletes trait
  • with API - Also generate API controller and routes
  • with authorization - Generate policy and gates
  • without views - Skip Blade template generation
  • without tests - Skip test generation (not recommended)
  • with Livewire - Use Livewire components instead of Blade

Called By

Invoked By Commands

Package Integration

The feature builder automatically integrates with installed packages:

Package Integration
spatie/laravel-tags Adds HasTags trait to models
spatie/laravel-sluggable Configures slug generation on models
spatie/laravel-activitylog Adds LogsActivity trait for audit trails
spatie/laravel-medialibrary Configures media collections on models
laravel/cashier Adds Billable trait for subscriptions
maatwebsite/excel Creates Import/Export classes
barryvdh/laravel-dompdf Generates PDF service for exports

Post-Build Commands

After creating a feature, these commands are run:

# Required
composer dump-autoload

# If IDE Helper installed
php artisan ide-helper:models -N

# If Laravel Pint installed
vendor/bin/pint app/Features/<Name>/

# Run migrations
php artisan migrate:status
php artisan migrate --pretend
php artisan migrate

# Run tests
vendor/bin/pest --filter=<Name>

Guardrails

The feature builder enforces strict rules:

  • NEVER mass-assign created_for_id or created_by_id
  • NEVER skip tests
  • ALWAYS use strict types and return types
  • ALWAYS run migrations with safety checks first
  • ALWAYS register ServiceProvider in config/app.php

Output Format

The builder produces a standardized completion report:

## laravel-feature-builder Complete

### Summary
- **Type**: Feature
- **Name**: Invoices
- **Status**: Success

### Files Created
- app/Features/Invoices/InvoicesServiceProvider.php
- app/Features/Invoices/Domain/Models/Invoice.php
- app/Features/Invoices/Http/Controllers/InvoicesController.php
- ...

### Routes
- Web: /invoices (resource routes)
- API: /api/v1/invoices (delegated to api-builder)

### Permissions (Laratrust)
- read-invoices, create-invoices, update-invoices, delete-invoices

See Also