AI Skill Report Card
Building Laravel Applications
YAML--- name: building-laravel-applications description: Guides development of web applications and platforms using Laravel and MySQL, covering architecture decisions, database design, Eloquent modeling, API development, authentication, and performance optimization. Use when building new Laravel features, designing database schemas, writing migrations/models/controllers, debugging Laravel/MySQL issues, or reviewing Laravel code for best practices. ---
Quick Start14 / 15
When starting a new Laravel feature, follow this pattern:
Bash# 1. Create migration, model, controller, and resource together php artisan make:model Product -mcr --factory --seed # 2. Migration first - define schema with proper types and indexes php artisan make:migration create_products_table
PHP// database/migrations/xxxx_create_products_table.php Schema::create('products', function (Blueprint $table) { $table->id(); $table->foreignId('category_id')->constrained()->cascadeOnDelete(); $table->string('name'); $table->string('slug')->unique(); $table->decimal('price', 10, 2); $table->unsignedInteger('stock')->default(0); $table->timestamps(); $table->softDeletes(); $table->index(['category_id', 'created_at']); });
PHP// app/Models/Product.php class Product extends Model { use HasFactory, SoftDeletes; protected $fillable = ['category_id', 'name', 'slug', 'price', 'stock']; protected $casts = [ 'price' => 'decimal:2', ]; public function category(): BelongsTo { return $this->belongsTo(Category::class); } }
Recommendation▾
Standardize language—mixing Indonesian and English throughout (workflow checklist, best practices) reduces accessibility for a general skill; pick one language consistently
Workflow11 / 15
Progress checklist for building a new feature/module:
- Rancang skema database - tentukan tabel, relasi, index, dan constraint sebelum coding
- Buat migration - gunakan tipe data yang tepat, tambahkan foreign key & index
- Buat model + relasi - definisikan
$fillable/$guarded, casts, dan relasi Eloquent - Buat Form Request - validasi input di
app/Http/Requests, jangan validasi di controller - Buat Controller (resource/API resource) - logic tipis, delegasikan ke Service/Action class untuk business logic kompleks
- Buat Resource/Transformer - untuk API response yang konsisten
- Tulis Policy/Gate - untuk otorisasi, jangan cek role manual di controller
- Tambahkan Test - Feature test untuk endpoint, Unit test untuk logic penting
- Optimasi query - cek N+1 dengan
eager loading, review dengan Laravel Debugbar/Telescope - Cache jika perlu - untuk data yang jarang berubah tapi sering diakses
Recommendation▾
Workflow checklist labels are in Indonesian while rest of doc is English, which is inconsistent and could confuse non-Indonesian speaking users of the skill
Examples17 / 20
Example 1: Menghindari N+1 Query
Input:
PHP$orders = Order::all(); foreach ($orders as $order) { echo $order->user->name; }
Output:
PHP$orders = Order::with('user')->get(); foreach ($orders as $order) { echo $order->user->name; }
Example 2: Business logic di Service class, bukan Controller
Input:
PHPpublic function store(Request $request) { $order = Order::create($request->all()); // hitung diskon, update stok, kirim email, dst Mail::to($order->user)->send(new OrderCreated($order)); return response()->json($order); }
Output:
PHP// app/Http/Controllers/OrderController.php public function store(StoreOrderRequest $request, OrderService $service) { $order = $service->create($request->validated()); return new OrderResource($order); } // app/Services/OrderService.php class OrderService { public function create(array $data): Order { return DB::transaction(function () use ($data) { $order = Order::create($data); $this->reduceStock($order); $this->applyDiscount($order); Mail::to($order->user)->queue(new OrderCreated($order)); return $order; }); } }
Example 3: Desain schema dengan index yang tepat
Input: "Tabel transactions sering di-query berdasarkan user_id dan rentang tanggal, tapi query lambat."
Output:
PHPSchema::table('transactions', function (Blueprint $table) { $table->index(['user_id', 'created_at']); });
Gunakan composite index sesuai urutan kolom di WHERE/ORDER BY, dan cek dengan EXPLAIN di MySQL.
Recommendation▾
Add a 'bad outcome' example (e.g., what happens if N+1 or mass assignment is not fixed) to strengthen the good/bad contrast per grading criteria
Best Practices
- Fat models/services, skinny controllers - controller hanya orkestrasi, logic bisnis di Service/Action class.
- Selalu gunakan Form Request untuk validasi, bukan validasi manual di controller.
- Gunakan Eloquent Resource (
php artisan make:resource) untuk konsistensi response API. - Gunakan transaksi DB (
DB::transaction()) untuk operasi yang melibatkan banyak tabel. - Migration harus reversible - selalu isi method
down()dengan benar. - Gunakan
env()hanya di config file, akses config lewatconfig()helper di kode aplikasi. - Queue untuk tugas berat (email, export, notifikasi) - jangan blocking request.
- Gunakan UUID/ULID untuk primary key jika data akan diekspos publik atau perlu distributed system.
- Index foreign key & kolom yang sering di-filter/sort.
- Gunakan
chunk()ataucursor()saat memproses data dalam jumlah besar untuk hemat memori. - Pisahkan environment -
.envberbeda untuk local/staging/production, jangan commit.env. - Gunakan Laravel Pint/PHPStan untuk menjaga konsistensi code style dan static analysis.
Common Pitfalls
- Jangan taruh query kompleks langsung di Blade view atau Controller—pindahkan ke Model scope atau Repository.
- Jangan gunakan
$request->all()langsung kecreate()/update()tanpa validasi—rawan mass assignment vulnerability. - Jangan lupa
foreignId()->constrained()saat membuat relasi—integritas data penting di level database, bukan hanya aplikasi. - Jangan menyimpan file upload langsung di
public/tanpa symlink storage (php artisan storage:link). - Jangan mengandalkan
Model::all()untuk dataset besar—gunakan pagination (paginate()). - Jangan menaruh logic otorisasi (
if ($user->role == 'admin')) tersebar di banyak tempat—sentralisasi di Policy. - Jangan lupa index saat menambah kolom yang dipakai untuk filter/join, terutama di tabel besar—bisa menyebabkan full table scan.
- Jangan jalankan migration langsung di production tanpa backup dan testing di staging terlebih dahulu.